本文へ移動
cccskills
無料GitHub で公開

packages

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.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md24.0 KB

SKILL.md(原文)

インストールする前に、エージェントに与えられる指示の中身を確認できます。

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:

./build/pulp search "<query>"
./build/pulp search "<query>" --refresh
./build/pulp suggest --description "<what the user needs>"
./build/pulp suggest --description "<what the user needs>" --include-license-gated

pulp suggest hides packages that require license review or a commercial override by default. Add --include-license-gated only when the user explicitly wants to inspect those candidates; otherwise prefer permissive defaults.

Or read the registry directly for full details:

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

Package Categories

CategoryPackagesWhat They Provide
dspaubio, btrack, cycfi-q, daisysp, essentia, fftw, fluidsynth, freeverb, kfr, kissfft, libpd, pffft, rnnoise, rubber-band, signalsmith-dsp, signalsmith-stretch, soundtouch, speexdsp, stk, tinysoundfontPitch/time stretch, filters, FFT, pitch detection, physical modeling, noise reduction, synthesis
audio-ioalac, dr-libs, fdk-aac, lame, libflac, libsamplerate, libsndfile, libvorbis, miniaudio, oboe, opus, r8brain-free-srcFile codecs, sample-rate conversion, device/audio I/O
music-theorymts-esp, sst-tuning-libraryOptional microtuning client integration, direct Scala SCL/KBM file parsing
mlrtneuralReal-time neural network inference
uifontaudioAudio icon font
utilitieslibremidi, rtmidiMIDI I/O helpers

Custom design-import controls (P8)

A package that provides a custom control for the design importer declares it under the optional design_controls array on its registry entry (registry-schema.json → design-control). Each entry is FLAT — a Figma identity (component_set_key — authoritative — or name_prefix — fallback) at the top level alongside factory_id (NOT nested under a match object). This shape is in lockstep with the TS DesignControlEntry (library-registry.ts) and the flat library-manifest.json convention; the schema's anyOf requires at least one identity field. Each entry maps that identity to a factory_id the package's pulp::view::View registers at host startup via register_design_control_factory (see the import-design skill, P7 Tier-3).

End-to-end the importer consumes these fragments automatically: when it resolves a design, it discovers the project's packages.lock.json + registry.json, gathers each installed package's design_controls into the recognition merge layer (RecognitionResolver::add_source, one source per package), and when an imported node's identity matches, emits a kind=custom interactive element carrying that factory_id. DesignFrameView::build_overlays then builds the package's control; an unregistered factory renders inert + diagnoses (never a silent knob). With no custom-control package installed, nothing is gathered and import behavior is unchanged. The TS resolver customControlFactoryId in library-registry.ts mirrors the same flat-entry shape for the in-Figma plugin lane. This is the "give-back" path's long tail: an obvious common control is promoted into core pulp::view + the shipped library-manifest.json instead.

Adding a Package

./build/pulp add <package-id>

This will:

  1. Check license compatibility and require explicit review for restricted licenses
  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)

Source-backed FetchContent packages

Registry entries can describe packages where upstream does not export the exact CMake target Pulp wants. Use cmake.sources for source files that should be compiled into a generated static target after FetchContent populates the source tree. Keep cmake.include_dir rooted at the fetched source directory and make the generated target position-independent so plugins can link it safely.

mts-esp is the reference pattern: it fetches ODDSound's source, compiles Client/libMTSClient.cpp into mts_esp_client, links ${CMAKE_DL_LIBS} when needed, and stays opt-in. When adding another source-backed package, update the registry schema, package-command generation tests, dependency manifest, DEPENDENCIES.md, NOTICE.md, and docs/reference/licensing.md together.

Header-only packages whose upstream CMake builds tools/tests instead of a consumer-ready target can set cmake.add_subdirectory=false; the generated pulp-packages.cmake uses FetchContent_MakeAvailable() with an inert SOURCE_SUBDIR so the source tree is populated without adding upstream tools/tests, then creates the declared interface target. sst-tuning-library is the reference pattern for source-only SCL/KBM parsing.

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

The hand-written guide set covers the original curated packages. The registry is larger, so use pulp search <query> or inspect tools/packages/registry.json for the full inventory:

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

MIT/BSD/Apache/ISC/zlib/BSL/public-domain packages install without prompts. MPL-2.0 and other unlisted licenses require manual review. GPL/LGPL/AGPL packages are restricted: the CLI blocks until the user explicitly accepts the package SPDX with --accept-license <SPDX> or declares a commercial-license basis with --license-override commercial. SSPL and proprietary packages are blocked by default, but the current CLI also accepts --license-override commercial for them, records a compliance warning, and leaves distribution responsibility with the project. Prefer permissive alternatives from the registry when available.

Attribution Audit

tools/deps/audit.py runs four invariants; the first two are --strict, the last two also need --verify-licenses (both are in gates.sh):

  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.
  3. Truthfulness — the attribution text must match the license actually on disk: no NOTICE entry may reproduce a truncated permission notice, and no checked-out tree may offer a copyleft alternative while the manifest declares something permissive.
  4. Offline fetch — an entry marked "offline_fetch": {"cache_name": ...} (WebGPU-distribution today) must download only through FetchContent_Declare, never a raw file(DOWNLOAD): changed-surface bounded runs configure their base with FETCHCONTENT_FULLY_DISCONNECTED=ON, which governs nothing else. Its tree is found as <cache_name>-<pin>... in the shared FetchContent cache.

Checks 1 and 2 only ask whether a dep is named in each file. That is why both of these passed a green --strict run for months: NOTICE.md reproduced MIT without its warranty disclaimer for 21 entries, and the VST3 SDK was labeled MIT on all four surfaces while the pinned tree (v3.7.12) was "Steinberg VST3 License OR GPLv3". A name being present says nothing about the text being right — when a license claim matters, read the tree.

Writing a NOTICE entry

Copy the license verbatim from the dependency's own tree or pinned upstream ref — never paste a template. MIT looks like boilerplate but is not uniform in practice: of 21 deps audited, mkdocs-material writes NON-INFRINGEMENT where the rest write NONINFRINGEMENT, and Catch2's Boost license has a materially different disclaimer ("TITLE AND NON-INFRINGEMENT", "ANYONE DISTRIBUTING THE SOFTWARE"). The entry must carry the whole notice — permission grant, inclusion condition, and warranty disclaimer.

Traps when extending the checks:

  • Match on flattened text. License prose is hard-wrapped, so a phrase spans a newline as often as not ("to deal\nin the Software"). Raw matching reports entries as missing clauses they plainly contain — use audit.flatten().
  • Boost opens with MIT's line. Both start "Permission is hereby granted", so identify a family by a phrase unique to it, and note the conditions are worded differently ("shall" vs "must be included in all copies").
  • Never grep a bare GPL. It false-positives on identifiers such as gPluginFactory. Match "General Public License" — and note v3.7.12 words it "General Public License (GPL) Version 3", never "GNU General Public License".
  • A dep's license lives in LICENSE files, not source headers, which only reference the nearest LICENSE.
  • external/ before the FetchContent cache. external/<dep> is what the build compiles; the cache accumulates every ref ever fetched, so a stale cache dir can shadow the real tree and get the audit verifying a version the repo does not use. A cache hit must match the pinned version.

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.

An independently redistributed runtime is different from a nested toolchain component. The pinned three.js payload is fetched or supplied through PULP_THREEJS_RUNTIME_DIR when PULP_ENABLE_THREEJS_RUNTIME=ON (the default with GPU support) and is staged under share/pulp/threejs for installed-SDK consumers. Treat a change to that install boundary as a dependency-inventory change: keep tools/deps/manifest.json, DEPENDENCIES.md, NOTICE.md, and docs/reference/licensing.md truthful together, even when the revision and license themselves do not change.

Same rule for Skia modules (e.g. skottie/sksg, linked only when the opt-in PULP_LOTTIE CMake option is enabled): they ship inside the existing Skia prebuilt under the same Skia BSD-3-Clause entry — clarify their use in the Skia row of DEPENDENCIES.md, do not add a separate dependency/NOTICE entry.

A prebuilt's slices are not interchangeable — record what differs

One manifest row can cover several published binaries of the same dependency, and they are not required to have the same contents. The Skia wasm slice is the live example: it is Ganesh on WebGL2 (no Dawn, no Graphite) and it excludes skottie/sksg, so Lottie is simply unavailable there even though the same DEPENDENCIES.md row says the modules exist. Note per-slice divergences in the row rather than letting a reader generalize from the native slice — the alternative is someone enabling PULP_LOTTIE for wasm and getting an undefined-skjson link failure with no explanation.

Toolchains that consume a prebuilt are pins too

A prebuilt binary is only reproducible against the toolchain it was validated with. The Skia wasm slice is verified against a specific Emscripten and wasi-sdk version, recorded as determinism.web_toolchain in tools/deps/manifest.json and mirrored in the Skia row of DEPENDENCIES.md. This is not bookkeeping: .github/workflows/web-plugins.yml reads the slice's URL + sha256 out of the manifest and keys its cache on the manifest hash, so the audit and the CI lane physically cannot disagree about which binary is in use — and a pin bump self-invalidates the cache. When you bump either the slice or the toolchain, bump them in the manifest, never by editing a URL into a workflow.

The Skia toolchain itself is pinned at chrome/m153 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.

Skia/Dawn and V8 are independently consumable prebuilts. If Skia advances while the complete matched V8 release is unavailable, keep V8's structured paired_skia / paired_dawn fields describing the V8 artifact that was actually built; record the newer active Skia/Dawn provider and temporary mixed selection in the human-readable dependency notes. Never relabel old V8 bytes as matched to the new Skia milestone.

iOS-specific layout gotcha: 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-m153-15.3.76.5-26cef0256b0e 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 source and artifact evidence when the V8 pin bumps; the m153 assets do not carry a separate third-party manifest, so absence of that file is not evidence of an empty bundled dependency set. iOS publishes an actual jitless simulator V8.framework marked library: false: Pulp validates its provenance and headers but has no device/AUv3 runtime acceptance or packaging contract, so QuickJS remains the default and JSC remains opt-in. 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. .gitignore has an !/external/fonts/ exception; before it existed the tracked fonts had all been git add -f'd past /external/*/, so a new one looked ignored while its siblings were tracked.
  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.

bundled_blobs() in core/canvas/src/bundled_fonts.cpp is an std::array<BundledBlob, N> — grow N, and bump the bundled_font_count() expectation in test/test_canvas_fonts.cpp, which exists to catch an accidental drop.

Bundling a face does not make it PAINT. There are two resolution paths and they are bridged separately. FontResolver (measurement, and make_font) sees the bundled faces; SkParagraph — which is what fill_text actually draws through — resolves from a FontCollection built in core/canvas/src/text_font_context.cpp. Until 2026-08-02 that collection only learned the bundled faces when the platform had no font database of its own, so on macOS a bundled family measured correctly and painted as a system fallback. The symptom is silent and looks like anything but a font bug: correct advances, correct wrap points, one universal painted face. If you add a font and the render does not change, measure the painted ink per family rather than trusting the resolver — four families that measure four widths and paint one is the signature.

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.

Managed tools must declare an update/override path

tools/packages/validate_registry.py also validates tool-registry.json: its validate_tool_registry rule fails if any managed_by_pulp tool ships without a non-empty pinned_version. That pin is the anchor for pulp tool update and for the user version override (--version / PULP_TOOL_<ID>_VERSION / $PULP_HOME/tool-overrides.json), so a managed tool without it would be one users can't update or override. When you add a managed_by_pulp entry, include its pinned_version in the same change. Rule + rationale: extending-pulp.md. The check runs anywhere validate_registry.py runs (its test_package_validation_tools.py unit suite covers the new rule).

For python_pip tools, the managed venv manifest is also the installed-version authority. pulp tool install may reuse an existing venv only when its wrapper exists and manifest.json records the current registry pin; a missing or stale manifest must reinstall. Never report the registry pin as the installed version without checking that manifest, or a pin bump can leave users running old code while the CLI claims they are current.

Related extend surfaces

packages, kits, content, and installable-tools are Pulp's four ways to extend a project or machine, and they share one lifecycle contract: add is validated, remove is confirmed + confined to the surface's own area + names what it deleted, and both add and remove ship tests. Pick the right surface and read the shared contract in extending-pulp.md.

  • packages — third-party audio DSP libraries → a project
  • kits — reusable Pulp code/UI/templates → a project
  • content — data-only packs (presets/samples) → an installed plugin
  • installable-tools — machine-level dev/agent tooling under ~/.pulp/tools/, plus the shared validate-and-uninstall-from-outside-a-checkout bar

JS-engine attribution in the dependency inventory

DEPENDENCIES.md, NOTICE.md, and tools/deps/manifest.json describe which JS engine a build actually links, so their wording is an attribution claim rather than a description. Keep them on the real contract: QuickJS is the default, JSC is opt-in on Apple (PULP_JS_ENGINE=jsc) and is a system framework that must never be implied by "Apple" alone, and V8 is an optional sealed prebuilt that is unavailable on iOS because JIT is forbidden there. Phrasing such as "default is QuickJS, JSC on Apple" or "iOS is JSC-only" overstates what is linked and misattributes a framework the build may not use at all. When the engine contract changes, update all three together; python3 tools/deps/audit.py --strict checks pins and notice coverage, not whether the prose matches the build.

Prebuilt platform slices

When a prebuilt Skia release gains a Windows platform slice, keep the exact asset URL and SHA-256 in tools/deps/manifest.json and mirror the digest in external/skia-build/VERSION.md; a dependency inventory entry alone is not a complete platform publication.

レビュー

まだレビューはありません。使ってみた感想をお寄せください。

同じリポジトリのスキル

概要と使いどころ

aax

無料

Optional AAX support for Pulp, including developer-supplied Avid SDK setup, CMake enablement, DigiShell/AAX Validator workflows, and local AAX builds on macOS or Windows.

日本語の概要は準備中です。原文の説明を表示しています。

Generous-Corp/pulp222026年10月10日 更新

Configure, implement, and test Pulp's optional desktop Ableton Link tempo-sync adapter while preserving the developer-supplied SDK, licensing, realtime, latency-compensation, and no-install boundaries.

日本語の概要は準備中です。原文の説明を表示しています。

Generous-Corp/pulp222026年10月10日 更新

Maintain Pulp's installed design-time agent capability manifest and public-surface ledger. Use when adding, removing, renaming, or materially changing public audio, MIDI, signal, timebase, or sequence APIs; registering a new algorithm for generators; changing capability support or deprecation state; or repairing agent-capabilities freshness, schema, fingerprint, tombstone, or installed-SDK tests.

日本語の概要は準備中です。原文の説明を表示しています。

Generous-Corp/pulp222026年10月10日 更新

android

無料

Android platform development for Pulp — NDK cross-compilation, Oboe audio, Dawn/Skia GPU rendering, JNI bridge, touch interaction, emulator workflows, and end-to-end smoke validation. Covers build, deploy, debug, and the gotchas discovered during bringup.

日本語の概要は準備中です。原文の説明を表示しています。

Generous-Corp/pulp222026年10月10日 更新

ara

無料

Optional ARA support for Pulp, including developer-supplied ARA SDK setup, CMake enablement, adapter companion APIs, validation, and ARA-aware plugin implementation guidance.

日本語の概要は準備中です。原文の説明を表示しています。

Generous-Corp/pulp222026年10月10日 更新

The measurement surface for ALL Pulp DSP and audio-pipeline work — read it BEFORE writing or gating DSP, not only when something already sounds wrong. Covers the C++ harness (signal generators, metrics, assertions, RenderScenario, contracts), the offline Audio Doctor (magnitude/frequency response, THD/THD+N, phase/group delay), and their Python sibling the Audio Quality Lab (tools/audio/quality-lab — null residual + alignment, LTAS log-spectral distance, spectral flux/centroid, HNR, Theil-Sen drift slope, Kaiser-sinc resampling, license-guarded corpus, regression-net ratchet). TRIGGER on AUTHORING work — "build/design an oscillator/filter/synth/effect", "add a DSP module", "what should the acceptance gate be", "how do I measure aliasing / anti-aliasing / alias floor", "null against a reference", "is this DSP correct", "choose a tolerance", "golden/regression corpus for audio", "measure drift or jitter", "A/B two renders" — AND on DEBUGGING work — "is there sound / no audio / I hear nothing", "does this filter/compressor/synth/delay produce the right signal", "prove the DSP / prove the contract", "measure the frequency response", "what's the THD / is it distorting", "what's the group delay / phase response / measured latency", "magnitude response curve", "render a test tone and assert", "audio regression", "64-frame works but 128 is silent", "sample-rate change pitch-shifted it", "describe what's in this buffer", "audio doctor", "compare before/after a DSP refactor". Reach for this BEFORE hand-rolling any FFT, null test, alias measurement, pitch tracker, or golden-render script — most of it already exists in one of the two lanes. Test/tool layer over HeadlessHost — deterministic, no audio device, no speakers. Off the realtime thread entirely.

日本語の概要は準備中です。原文の説明を表示しています。

Generous-Corp/pulp222026年10月10日 更新

Generous-Corp のスキルをすべて見る

このスキルの問題を報告する