Dependensi Plugin Claude Code dan Batasan Versinya

Pakai entri objek di array dependencies pada manifest plugin-nya, dengan name dan rentang semver, misalnya rentang tilde yang hanya mengizinkan pembaruan patch. Tanpa rentang, dependensinya mengikuti versi apa pun yang saat itu disediakan marketplace-nya, jadi rilis upstream bisa mengubahnya di bawah Anda tanpa peringatan.
Batasan diselesaikan terhadap tag git di repository yang menampung dependensinya, dinamai dengan nama plugin, dua strip, huruf v, lalu versinya. Kalau upstream-nya tidak pernah menandai rilis, tidak ada tag yang memenuhi rentangnya dan install-nya gagal dengan error no-matching-tag. Untuk source npm, archive dan command, rentangnya hanya diperiksa saat pemuatan, tidak pernah dipakai memilih versi.
Sebuah perintah yang membuat tag git rilis yang dibutuhkan Claude Code untuk menyelesaikan batasan versi. Jalankan dari direktori plugin-nya dan ia menurunkan tag-nya dari manifest serta entri marketplace, menolak kecuali plugin-nya lolos validasi, kedua versinya sepakat, working tree-nya bersih, dan tag-nya belum ada. Tambahkan flag push untuk mendorongnya ke origin.
Bisa. Selain name yang wajib, manifest plugin boleh hanya berisi array dependencies, jadi memasangnya memasang setiap plugin yang didaftarkannya. Tim platform memakai ini untuk menerbitkan set standar per peran, dan menambahkan tool nanti berarti menerbitkan versi bundle baru ketimbang menyuruh semua orang memasang sesuatu.
Jalankan perintah plugin prune, yang mendaftar dependensi terpasang-otomatis yang tak lagi dibutuhkan plugin mana pun lalu menghapusnya setelah konfirmasi. Plugin yang Anda pasang sendiri tidak pernah di-prune. Anda juga bisa memberi flag prune ke sebuah uninstall supaya pembersihannya terjadi di langkah yang sama, dan flag dry-run menunjukkan apa yang akan hilang tanpa menghapus apa pun.

Ringkasan Utama
Sebuah plugin Claude Code bisa bergantung pada plugin lain, dan secara bawaan dependensinya mengikuti versi terbaru yang tersedia, jadi sebuah rilis upstream bisa mengubahnya di bawah Anda tanpa peringatan. Rentang semver menahannya di versi yang sudah diuji, diselesaikan terhadap tag git bernama nama-plugin dua-strip v versi di repository yang menampung dependensi itu.
Seseorang di tim platform mengganti nama sebuah tool di dalam MCP server, menandai sebuah rilis, dan menjelang makan siang tiga pipeline deploy gagal dengan error yang menyebut tool yang tak seorang pun sentuh. Tidak ada yang salah dengan kedua plugin itu. Dependensi di antara keduanya tidak punya batasan versi, jadi sebuah rilis upstream bergeser di bawah setiap engineer sekaligus.
Kegagalan itu punya perbaikan satu baris dan seperangkat mekanika yang layak dipelajari benar, karena separuhnya tak terlihat sampai ia salah tembak. Tulisan ini membahas apa yang dilakukan batasan, cara mendeklarasikannya, konvensi tag git yang membuat resolusinya bekerja sama sekali, membundel satu set terkurasi di balik satu install, melintasi batas marketplace, bagaimana beberapa batasan pada dependensi yang sama bergabung, dan empat error yang benar-benar akan Anda temui.
Bayangkan sebuah marketplace internal dengan dua tim di dalamnya. Tim platform memelihara secrets-vault, sebuah MCP server yang membungkus backend rahasia. Tim deploy memelihara deploy-kit, yang memanggilnya saat deploy dan diuji terhadap versi 2.1.0. Tanpa batasan, rilis berikutnya yang mengganti nama sebuah tool menggeser secrets-vault semua orang dan merusak deploy-kit di mana-mana pada saat yang sama.
Dengan batasan, deploy-kit menyatakan ia butuh rentang 2.1.x dan para engineer tetap di patch tertinggi yang cocok. Tim deploy lalu naik versi sesuai jadwalnya sendiri dengan menerbitkan rilis deploy-kit berentang lebih lebar. Intinya bukan bahwa upgrade itu buruk — melainkan bahwa tim yang harus memperbaiki kerusakannya seharusnya tim yang memilih waktunya.
Dependensi tinggal di array dependencies di manifest plugin itu sendiri, atau di entri marketplace-nya. Sebuah entri bisa berupa string polos, artinya versi apa pun yang disediakan marketplace plugin itu, atau sebuah objek dengan name, rentang semver opsional, dan marketplace opsional ketika nama plugin yang sama ada di lebih dari satu katalog.
// .claude-plugin/plugin.json
{
"name": "deploy-kit",
"version": "3.1.0",
"dependencies": [
"audit-logger", // any version
{ "name": "secrets-vault", "version": "~2.1.0" },
{ "name": "shared-utils", "marketplace": "acme-shared" }
]
}
// Ranges are npm semver:
// 1.2.3 exactly that
// ~2.1.0 2.1.0 up to 2.1.x
// ^2.1.0 2.1.0 up to 2.x.x
// >=1.4 anything at or above
// * anything
// Pre-releases are EXCLUDED unless the range opts in: ^2.0.0-0Batasannya mengendalikan versi mana yang diambil hanya untuk source berbasis git. Untuk source npm, archive atau command ia justru diperiksa saat pemuatan, dan plugin yang bergantung dinonaktifkan dengan dependency-version-unsatisfied ketika versi terpasangnya jatuh di luar rentang. Ada satu sisi tajam di situ: dependensi bersource command yang plugin.json-nya tidak menyetel version tidak memenuhi batasan apa pun, jadi setel versinya sebelum Anda membatasinya.
Ini bagian yang orang lewatkan, dan tanpanya batasan diam-diam tidak berbuat apa-apa yang berguna. Claude Code menyelesaikan sebuah rentang terhadap tag git di repository yang menampung dependensinya — repository milik plugin itu sendiri untuk source github, url dan git-subdir, atau repository marketplace-nya untuk plugin yang dirujuk lewat path relatif. Nama tag-nya konvensi tetap, dan ada perintah yang membuatnya benar untuk Anda.
# Constraints resolve against GIT TAGS on the repository that
# hosts the dependency. The convention is not optional:
#
# {plugin-name}--v{version}
#
# From the plugin directory:
claude plugin tag --push
claude plugin tag --dry-run # what would be tagged
claude plugin tag --remote upstream # push somewhere else
# It refuses to tag unless:
# - the plugin contents validate
# - plugin.json and the marketplace entry agree on the version
# - the working tree under the plugin directory is clean
# - the tag does not already exist
# Success looks like:
# Created tag secrets-vault--v2.1.0
# Pushed to origin
# No matching tag, and the install fails with:
# Dependency "secrets-vault@acme-tools" has no git tag
# satisfying ~2.1.0Selain name yang wajib, sebuah manifest boleh hanya berisi dependencies — yang mengubah sebuah plugin menjadi bundle. Tim platform bisa menerbitkan set per peran supaya engineer baru menjalankan satu install ketimbang lima, dan menambahkan tool ke set standar nanti menjadi rilis bundle baru ketimbang pesan yang menyuruh semua orang memasang sesuatu.
// A manifest can be nothing but a name and a dependency list.
// Installing it installs all four.
{
"name": "backend-standard",
"version": "1.0.0",
"description": "Standard plugin set for backend engineers",
"dependencies": [
"secrets-vault",
"deploy-kit",
{ "name": "db-migrate", "version": "^3.0" },
"oncall-runbook"
]
}
# Disabling a dependency something else needs is refused, and the
# error hands you the command that works:
# secrets-vault is still required by deploy-kit. Disable that
# plugin first, or disable everything together:
# claude plugin disable deploy-kit@acme-tools && \
# claude plugin disable secrets-vault@acme-tools
# Auto-installed dependencies outlive the plugins that pulled them.
claude plugin prune --dry-run
claude plugin uninstall deploy-kit --pruneAuto-update mati secara bawaan untuk marketplace non-Anthropic, jadi versi bundle baru tidak datang sendiri. Entah nyalakan auto-update untuk marketplace-nya, atau suruh orang menjalankan update lalu memuat ulang plugin — pemuatan ulang itulah yang memasang dependensi yang ditambahkan versi barunya. Untuk sebuah organisasi, taruh bundle-nya di enabledPlugins dalam managed settings dan lewati acara menyuruh-nyuruhnya sama sekali.
Secara bawaan Claude Code menolak memasang otomatis dependensi yang tinggal di marketplace berbeda dari plugin yang mendeklarasikannya, yang mencegah satu katalog diam-diam menarik plugin dari sumber yang tak pernah Anda tinjau. Untuk mengizinkannya, pemelihara marketplace akar — yang menampung plugin yang sedang dipasang — mendaftarkan marketplace tujuannya di allowCrossMarketplaceDependenciesOn.
Hanya allowlist marketplace akar yang dikonsultasikan, jadi kepercayaan tidak berantai lewat katalog perantara. Tanpa field itu, install-nya gagal dengan error cross-marketplace yang menyebut persis apa yang harus disetel. Pengguna masih bisa memasang dependensinya lebih dulu dengan tangan, yang memenuhi batasannya tanpa siapa pun menyunting allowlist — berguna sekali, dan kebiasaan buruk sebagai kebijakan.
Claude Code mengiriskan rentang setiap plugin terpasang lalu menyelesaikannya ke versi tertinggi yang memenuhi semuanya. Dua sifat mengikutinya yang layak dinyatakan terang-terangan: auto-update tetap memperbarui dependensi terbatasi di dalam rentang yang diizinkannya ketimbang membekukannya, dan mencopot plugin terakhir yang membatasi sesuatu melepaskan tahanannya pada pembaruan berikutnya.
Bagaimana kombinasi umum diselesaikan:
| Batasan yang berlaku | Yang terjadi |
|---|---|
| Caret 2.0 dan minimal 2.1 | Satu pemasangan di tag 2.x tertinggi pada atau di atas 2.1.0. Kedua plugin dimuat |
| Tilde 2.1 dan tilde 3.0 | Pemasangan kedua gagal dengan range-conflict. Plugin pertama dan dependensinya dibiarkan persis seperti semula |
| Satu pin persis, tidak ada lainnya | Dependensinya tetap di versi itu dan auto-update melewati yang lebih baru selama plugin yang mengunci masih terpasang |
| Tidak ada tag yang memenuhi semua rentang | Auto-update melewati dependensi itu dan mencatat pelewatannya di tab Errors plugin, menyebut plugin yang membatasinya |
Aturan siklus hidupnya ketat dengan cara yang mudah dijalani begitu Anda tahu:
Dua kebiasaan menjaga ini rapi. Jalankan perintah prune dengan flag dry-run-nya sesekali untuk melihat dependensi mana yang tidak lagi dibutuhkan siapa pun — plugin yang Anda pasang sendiri tidak pernah disentuh, hanya yang datang lewat array dependencies. Dan ketika Anda tahu sebuah plugin pergi untuk selamanya, copot ia dengan flag prune supaya pembersihannya terjadi di langkah yang sama.
Batasi dependensi yang benar-benar Anda andalkan ketimbang semuanya, karena tiap rentang yang Anda tulis adalah rentang yang akhirnya harus dilebarkan seseorang. Tandai rilis Anda dengan perintahnya ketimbang dengan tangan, karena ia memeriksa bahwa manifest dan entri marketplace-nya sepakat sebelum menulis apa pun. Dan kalau Anda memelihara plugin yang tim lain gantungkan, terbitkan rilis bertag bahkan ketika belum ada yang minta — upstream tanpa tag membuat setiap batasan hilir tidak bisa ditegakkan.
Sumber & bacaan lanjutan