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

upgrade

Guide users through `pulp upgrade` — discover new CLI releases, interpret migration notes for the hop they're performing, and apply breaking-change fixes (CMake macro renames, API surface changes, config file moves). Handles "upgrade pulp", "what's new", "migrate my project", "show breaking changes", and the `/upgrade` slash command. Pairs with the embedded migration index shipped in the CLI binary.

インストール方法を見る

含まれるファイル(1)

  • SKILL.md18.8 KB

SKILL.md(原文)

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

upgrade

When this skill applies

  • User asks to upgrade, update, or bump the Pulp CLI.
  • User runs /upgrade in Claude Code.
  • User asks "what changed", "what's new", "what breaks", or "how do I migrate" after bumping an SDK / CLI version.
  • A pulp doctor --versions run surfaces CLI-vs-SDK skew the user wants to resolve.

This skill does NOT cover:

  • Pinning the project's SDK version — that's the cli-maintenance skill + pulp project pin.
  • Bumping the Pulp framework/source checkout version — that's pulp version bump plus the release workflow.
  • Shipping a PR from a dev branch — that's the ci skill via pulp pr.
  • Updating the Shipyard pin — that's the Dependency Update Workflow in CLAUDE.md (runs through tools/deps/audit.py).

Mental model

Four independently-versioned surfaces, two of which this skill acts on directly and one of which it may hand off to pulp project pin:

SurfaceSource of truthHow to upgrade
Pulp CLI / SDK~/.pulp/bin/pulp (installed binary)pulp upgrade
Consumer project SDK pinproject pulp.toml sdk_version + find_package(Pulp X.Y.Z ...)pulp project pin
Pulp source checkout versionPulp repo CMakeLists.txt / release metadatapulp version bump + release workflow
Claude plugin.claude-plugin/plugin.json/plugin install pulp in Claude Code
Shipyard pintools/install-shipyard.shDependency Update Workflow (out of scope)

pulp upgrade downloads the new CLI binary and replaces the installed one. After the Phase 8 Rust cutover, release archives are dual-binary: Rust pulp is the user-facing CLI and sibling pulp-cpp is installed as the C++ fallthrough delegate. A healthy install has both ~/.pulp/bin/pulp and ~/.pulp/bin/pulp-cpp; use PULP_USE_CPP=1 pulp <args> or direct pulp-cpp <args> only for rollback/debug comparisons. Do not hand-swap binaries in user/system locations. The C++ cmd_upgrade.cpp path still matters for pre-cutover users upgrading into a Rust release: it must copy the archive's sibling payloads, including pulp-cpp, before replacing the running pulp binary.

Darwin releases at or above the control-broker floor also carry sibling pulp-control-broker. The running CLI verifies the staged broker before any binary replacement, retains the prior broker until the health-only LaunchAgent reaches reachable-unverified, and rolls the binary, plist, and service back together on failure. The first broker-bearing release has one transition exception: an older CLI cannot preserve an archive member it does not know. The replacement CLI therefore performs one bounded exact-version recovery on its next invocation when the canonical sibling is missing, records the result, and does not retry a hard failure on every command. This recovery never claims trusted identity, consent, admission, or operation authority; retry explicitly with pulp upgrade --install --to <current-version> after correcting a reported failure. Custom install roots require explicit first-install acceptance rather than being activated merely because PULP_INSTALL_DIR was set.

pulp upgrade --notes prints migration notes for the hop without downloading anything. pulp upgrade --notes --json emits the same data as a stable-shape JSON document for agent consumption (the /upgrade slash command is the primary consumer).

Agent pre-flight on an SDK pin change (inherit breaks before you hit them)

When you (an agent) are about to work in a project whose pinned Pulp SDK version has moved — or you are the one moving it — run this FIRST, before editing or building code against the new pin:

pulp upgrade --notes --json --from <OLD> --to <NEW>

The top-level has_breaking (bool) and breaking_count (int) are the signal to branch on without parsing every entry:

  • has_breaking: false → nothing to inherit; proceed normally.
  • has_breaking: true → read each breaking: true entry's body and adapt the code (renamed CMake macros, changed APIs, moved config) BEFORE building, instead of waiting to hit the break as a compile error.

pulp project bump already prints these notes after a pin change and, when the hop crosses a breaking note, shows a banner pointing here. The banner is on by default; a user can silence it with pulp config set upgrade.breaking_notes false or PULP_NO_BREAKING_NOTES=1. The JSON has_breaking / breaking_count fields are always present regardless of that setting — only breaking = true notes raise them, so a normal feature release is silent (low-noise by design).

Use pulp project pin only after deciding a consumer project should move its SDK pin. It operates on the active project or the registry (--all); it does not upgrade the global CLI and it refuses to treat the Pulp source checkout as a consumer project.

pulp upgrade updates BOTH CLI and SDK by default

Older pulp upgrade releases only swapped the CLI binary. Users who ran them then built a project that still resolved its months-old SDK and silently missed framework fixes. Current behavior:

  • Default: fetch latest CLI binary + run pulp sdk install --version <new> immediately after the swap, so the matching SDK lands at ~/.pulp/sdk/<new>/ in the same invocation.
  • --cli-only flag keeps the CLI-only behavior for the rare case where a user wants the new CLI paired with their current SDK.
  • The SDK install is best-effort: a transient network failure logs a warning and tells the user to retry with pulp sdk install. The CLI swap is not rolled back — the user can always retry SDK install.
  • When run from inside a project whose pulp.toml pins an explicit SDK version, the SDK install happens (so the new version is available globally) but the project's pin is left ALONE. A clear notice prints — "Project X stays on pinned SDK Y.Y.Y; latest available is Z.Z.Z — pulp project unpin to start tracking latest." Pinning is sacred when the user has explicitly pinned.

pulp project pin <version> is the new primary name for what pulp project bump did. bump survives as a deprecated alias for one minor release. New docs and skill examples should use pin. pulp project unpin (new) flips a project back to floating mode (sdk_version = "latest" in pulp.toml).

New projects created via pulp create default to floating mode (sdk_version = "latest"), so they pick up framework fixes automatically. pulp create --pin writes the exact version instead for users who want reproducibility from day one.

Discovery workflow (pulp on PATH is assumed)

The skill shells out to pulp — no hardcoded paths, no env-var requirement. If pulp is not on PATH, tell the user to install first (curl -fsSL https://www.generouscorp.com/pulp/install.sh | sh) and stop.

Note: a successful pulp upgrade now self-heals PATH — after the binary swap it appends the CLI's own directory to the user's shell profile when it isn't already on $PATH (honoring PULP_NO_MODIFY_PATH). This closes the gap where a CLI first installed via a source / SDK-prefix install (cmake --install --prefix ~/pulp-sdk → ~/pulp-sdk/bin/pulp) could upgrade successfully yet still be "command not found" in a fresh shell. So after an upgrade the user may need to restart their shell or source the named profile, but no longer has to add PATH by hand. See the cli-maintenance skill for the implementation (upgrade_install::ensure_dir_on_path).

Plugin ↔ CLI skew banner

Before running any pulp command, source the shared skew-check helper so the user sees a single-line hint when the installed CLI is older than the plugin's declared min_cli_version:

source "$(git rev-parse --show-toplevel 2>/dev/null || echo .)/tools/scripts/cli_version_check.sh"
pulp_cli_version_check   # no-ops silently if already checked this session

Behaviour:

  • Banner (stderr, at most once per session): [pulp] Claude plugin requires CLI >= v<MIN> but installed CLI is v<HAVE>. Run \pulp upgrade` or `/upgrade` in Claude Code.`
  • Silent when CLI ≥ min, when the plugin manifest omits min_cli_version (older plugin builds), or when either version is non-numeric (dev builds).
  • Overrides: PULP_SKEW_CHECK_DISABLE=1 turns it off; PULP_SKEW_CHECK_CACHE overrides the session-marker directory.

The same skew logic is surfaced by pulp doctor --versions inline, so users who prefer running the diagnostic directly see the finding there too — the helper is a convenience for skill authors, not a second source of truth.

  1. Identify the active plugin directory (so the skill can resolve docs/migrations/ for full-body lookups):

    pulp doctor --versions --json
    

    The JSON output contains plugin_json_path — walk up two levels (dirname $(dirname $plugin_json_path)) to reach the plugin root.

  2. Report the version skew at a glance so the user sees where they are before deciding what to do. The JSON response also includes cli, plugin, project_sdk, and findings[] — surface those in a compact table.

  3. Fetch applicable migration notes for the current hop.

    Important: user-invoked pulp upgrade and pulp upgrade --install force a synchronous release refresh instead of trusting the 24h cache. This is deliberate: v0.78.3 showed that a cache written minutes before a release can make a just-published version invisible. pulp upgrade --check-only remains the lightweight cache-aware probe; if you need release-fresh notes, capture the Latest: value from a refreshed/default pulp upgrade run and forward it as --to "$LATEST".

    In CI / sandbox lanes, PULP_UPDATE_CHECK_DISABLED=1 makes --check-only network-free. If the cache is empty in that mode, the command reports the installed CLI version plus an explicit disabled/not-queried latest line instead of querying GitHub Releases.

    pulp upgrade --notes --json                  # defaults: from = installed CLI, to = cached latest
    pulp upgrade --notes --json --to "$LATEST"   # recommended — use value captured from refreshed upgrade check
    pulp upgrade --notes --json --from X --to Y  # explicit hop
    

Release verification gotcha

When verifying a newly published release, test from the previously published CLI with a deliberately fresh cache that still names the old release:

PULP_HOME="$(mktemp -d)" pulp upgrade --check-only --json
# seed/update-cache.json to latest_version=<previous> with a current timestamp
pulp upgrade

The default pulp upgrade path must refresh through GitHub and report the new tag immediately. Then run pulp upgrade --install --to X.Y.Z in an isolated install directory and confirm a follow-up pulp upgrade reports both Installed and Latest as the new version. This catches stale release-cache failures before the release is announced.

Stable-shape output (do NOT rename these keys — they are a public surface the skill depends on, see tools/cli/migration_index.hpp):

{
  "from": "0.27.0",
  "to":   "0.30.0",
  "entries": [
    {
      "version":   "0.28.0",
      "breaking":  false,
      "summary":   "…",
      "applies_if":"cli_version_from < 0.28.0 && cli_version_to >= 0.28.0",
      "body":      "…"
    }
  ]
}
  1. Render the notes inline in the chat. For each entry:
    • If breaking == true, prefix with a loud tag (e.g. "BREAKING").
    • Print the summary on the first line.
    • Include the body verbatim — it's already Markdown.

Interpreting migration notes

Each note describes one release's visible behaviour shift. Read them like a pro-developer changelog, not a marketing blurb.

Rendering-only notes still need an old/new proof

A non-breaking SDK hop can legitimately change pixels without changing an API. In particular, the v0.773.1 Skia update corrected interpolation toward a fully transparent gradient stop, so snapshots containing fades, washes, or vignettes can change while opaque-to-opaque gradients remain identical. Do not bless or re-record those baselines from the digest alone: amplify the image diff, confirm it is confined to the gradient, and render the same source against the preceding SDK when available. The applicable migration note under docs/migrations/ carries the expected-value probe and the exact scope.

Breaking vs non-breaking

  • breaking: true — requires user action: code change, config edit, habit change. Do not skip. Offer to grep the project for the affected symbols as a follow-up.
  • breaking: false — informational. The upgrade works without intervention, but something worth knowing has changed.

applies_if expressions

The filter runs in the CLI — by the time the skill receives JSON, non-applicable entries are already stripped. You'll only see entries whose applies_if matched the hop. Still: print the expression alongside the note so a curious user can verify why it applied.

Grammar: Boolean combinations (&&, ||, parentheses) over comparisons of cli_version_from / cli_version_to against a literal semver. Six operators: <, <=, >, >=, ==, !=. See docs/migrations/README.md for full details.

Common breaking-change patterns

These are the patterns that have shown up in Pulp migration notes. When you spot one, suggest the exact grep / replacement to the user instead of leaving them to figure it out from a prose paragraph.

CMake macro renames

Pattern. A pulp_add_* function in tools/cmake/Pulp*.cmake is renamed, folded into pulp_add_plugin(FORMATS ...), or split out of one macro into several.

What to do.

# Find every call site.
grep -rn "pulp_add_ios_auv3\|pulp_add_auv3\|pulp_add_vst3_only" .

Propose the replacement form explicitly; do NOT rewrite the user's CMakeLists.txt without confirmation. For unified-form migrations, show a diff like:

- pulp_add_ios_auv3(MyPlugin …)
+ pulp_add_plugin(MyPlugin FORMATS AUv3 …)

API surface changes

Pattern. A public C++ header under core/*/include/pulp/** adds, removes, or renames a symbol that processors / view code use.

What to do.

# Find call sites of the old symbol.
grep -rn "OldProcessorAPI\|deprecated_function_name" .

Read the migration body for the replacement signature. If the change is a deprecation (old API still works, emits a warning), flag that — teams may want to migrate at their own pace.

VisualizationBridge polling ownership (0.807.0)

VisualizationBridge::process() no longer performs FFT/waveform analysis or publishes those snapshots. When upgrading a consumer that reads spectrum or waveform data, find the bridge reads and ensure exactly one non-audio-thread owner calls poll() first:

rg -n "VisualizationBridge|read_spectrum|read_waveform" .

The usual owner is the editor frame clock. Keep read_spectrum() and read_waveform() as cheap snapshot reads; do not move poll() onto the audio callback or call it concurrently from multiple UI/worker paths. Treat configure() and reset() as quiescent control-thread operations.

Config file / path moves

Pattern. A file Pulp reads (e.g. ~/.pulp/config.toml, pulp.toml, .pulp/projects.json) changes location or key shape.

What to do. Most config moves are handled by the CLI on first run (it migrates the old location to the new one and prints a one-line notice). The note tells you whether manual action is needed. If it is, quote the exact pulp config set / pulp config unset commands from the body.

CLI flag / subcommand changes

Pattern. A subcommand is renamed (e.g. pulp check → pulp doctor), a flag changes shape (--sign-key → --ed25519-key), or an exit code semantic changes (for example, silent-success → loud-failure).

What to do. If the user has CI scripts (ci/, .github/workflows, tools/local-ci/, team-specific shell scripts), grep those for the old invocation first — those are the scripts that'll silently break.

grep -rn "pulp <old-command>\|--<old-flag>" ci/ .github/ tools/ || true

Bypass trailers

This flow does not add new bypass trailers, but users will ask about trailers around upgrade-triggered PRs, so keep the syntax handy (full table in CLAUDE.md → "Versioning & Skill-Sync Policy"):

GateTrailer (tip commit only, NEVER PR body)
Version bumpVersion-Bump: <surface>=<patch|minor|major|skip> reason="..."
Skill updateSkill-Update: skip skill=<name> reason="..."
Auto-releaseRelease: skip reason="..."

Trailer blocks must be contiguous — no blank lines between trailers, or git interpret-trailers --parse stops reading. When amending, rewrite the whole block, don't append.

Decision tree (used by the /upgrade slash command)

pulp doctor --versions --json   → parse cli / plugin / project_sdk / findings
pulp upgrade --notes --json     → parse entries[]

present table:  CLI   vX.Y.Z → vA.B.C    (<hop>)
                plugin vP.Q.R → vP'.Q'.R' (if drift)
                project SDK vS.T.U  (skew warn from findings)

list applicable notes (inline, breaking flagged)

ask via AskUserQuestion:
  - "Upgrade CLI + pin project SDK" → `pulp upgrade` + `pulp project pin` in the active project
  - "Upgrade CLI only"            → `pulp upgrade`
  - "Pin project SDK only"        → `pulp project pin` in the active project or `--all` when explicitly requested
  - "Dismiss"                     → no action, remind user they can re-run `/upgrade`

Testing the slash command

The /upgrade command shells out to pulp upgrade --notes --json. A regression test lives in test/test_cli_shellout.cpp (the [issue-549] tag) — it asserts that a synthetic hop produces the keys the slash command depends on. If you add or rename a key in render_notes_json (tools/cli/migration_runtime.cpp), update this skill AND the slash command AND the test in the same PR.

References

  • Design: planning/release-discovery-ux-design-2026-04-20.md Section C
  • CLI surface: tools/cli/cmd_upgrade.cpp, tools/cli/migration_index.hpp
  • Migration doc schema: docs/migrations/README.md
  • Diagnostics: pulp doctor --versions
  • Update check: pulp upgrade --check-only
  • Migration index: pulp upgrade --notes --json
  • Plugin ↔ CLI skew: min_cli_version, tools/scripts/cli_version_check.sh, and the plugin_min_cli JSON field

レビュー

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

同じリポジトリのスキル

概要と使いどころ

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 のスキルをすべて見る

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