lockfile-sync
Model package.json'a bir dependency ekler, yalnız o dosyayı commit'ler ve lockfile geride kalır. Sonraki npm ci CI'da düşer, ya da bir takım arkadaşın senin denediğinden farklı bir sürüm kurar. Bu mod, bir commit bir manifest'in dependency'lerini değiştirip lockfile'ını değiştirmediğinde bunu modele söyler. Modelin çalıştırdığı her git commit'ten sonra, commit'in lockfile'ını dışarıda bıraktığı manifest'leri commit'in sonucuna ekler. Commit'in kendisi hiçbir zaman durdurulmaz.
Ne yapar
Mod Bash tool'unu izler.
git commitçalıştıran bir komut kontrol edilir;git -C <dizin> commitya da önünde git'in global flag'leri olan biçimleri de.--dry-run,--helpya da-htaşıyanlar kontrol edilmez.Komut çalışmadan önce repository kökünü session'ın dizininden, commit'ten önceki son
cd'den ve commit'ingit -C'sinden bulur veHEAD'i kaydeder.HEAD'i ilerleten başarılı bir komuttan sonra commit'in eklediği ve değiştirdiği dosyalarıgit show --name-status HEADile listeler ve her manifest'i lockfile'ıyla eşleştirir:Manifest Lockfile package.jsonpackage-lock.json,yarn.lock,pnpm-lock.yaml,bun.lock,bun.lockbcomposer.jsoncomposer.lockCargo.tomlCargo.lockgo.modgo.sumpyproject.tomlpoetry.lock,uv.lock,pdm.lockPipfilePipfile.lockGemfileGemfile.lockpubspec.yamlpubspec.lockmix.exsmix.lockLockfile, manifest'in dizininden repository köküne doğru diskte bulunan ilk lockfile'dır; yani bir workspace package'i kökteki lockfile ile eşleşir. Diskte lockfile'ı olmayan bir manifest'e dokunulmaz: proje bir tane tutmuyordur.
Commit o lockfile'ı dışarıda bıraktıysa mod önce lockfile'ın kendi package manager'ına, lockfile'ın manifest'e hâlâ uyup uymadığını sorar. Kontrolü argv ile, lockfile'ın dizininde, 60 sn sınırla çalıştırır:
Lockfile Kontrol Geride sayıldığı durum Cargo.lockcargo metadata --locked --format-version 1 --manifest-path <manifest>cannot update the lock filepackage-lock.jsonnpm ci --dry-run --ignore-scriptshata metninde are in syncpnpm-lock.yamlpnpm install --frozen-lockfile --lockfile-only --ignore-pnpmfile --ignore-scriptsdon't match specifiersbun.lock,bun.lockbbun install --frozen-lockfile --dry-run --ignore-scriptslockfile had changesyarn.lock(v1)yarn checkLockfile does not contain patterncomposer.lockcomposer validate --no-check-all --no-check-publish --check-lock --no-pluginslock file is not up to datego.sumgo mod tidy -diffdiff'te bir go.sumhunk'ı varuv.lockuv lock --checkneeds to be updatedpoetry.lockpoetry check --lockchanged significantlypdm.lockpdm lock --checksatisfy the project requirementsPipfile.lockpipenv verifyout-of-dateGemfile.lockbundle lock --printyazdırılan lockfile, platformlar ve Bundler sürümü dışında farklı pubspec.lockdart pub get --enforce-lockfile --dry-runUnable to satisfymix.lockmix deps.get --check-locked,MIX_DEPS_PATH$TMPDIR/lockfile-syncaltındamix.lock is out of dateHer kontrolün repository'ye hiçbir şey yazmadığı ölçüldü. Geçen bir kontrol lockfile'ın uyduğunu söyler ve bulgu açılmaz:
Cargo.toml'da yeni bir crate getirmeyen birfeaturesdeğişikliği bir şey açmaz,serde_derive'ı getiren birfeatures = ["derive"]açar. Lockfile'ın geride olduğunu söyleyen bir hata bulguyu açar. Diğer her cevap hiçbir şey kanıtlamaz: araç kurulu değildir, sınırı aşmıştır, başka bir nedenle başarısız olmuştur, lockfile bir Yarn 2+yarn.lock'udur, ya da manifest veya lockfile working tree'deHEAD'den farklıdır. Kontrol working tree'yi okur, bulgu ise commit'ten söz eder; yazılmış ama commit'e girmemiş bir lockfile uyumlu okunurdu. Başlayamayan bir araç bir kez yazılır:lockfile-sync: cargo did not run: <reason>; the manifest's diff decidesArdından mod manifest'in diff'ini okur (
git show --unified=20 HEAD -- <manifest>) ve değişen satırların nerede durduğuna bakar. Yalnız lockfile'ı değiştirebilecek bir değişiklik sayılır:Manifest Sayılır Sayılmaz package.json,composer.jsondependencies,devDependencies,peerDependencies,optionalDependencies,overrides,resolutions,require,require-devve benzerleriscripts,version, diğer key'lerCargo.toml,pyproject.toml,Pipfile[dependencies],[dev-dependencies],[target.*.dependencies],[project],[tool.poetry.dependencies],[packages]ve benzerleri[package],[tool.ruff], diğer table'largo.modrequire,replace,excludesatırları ve bloklarıgo 1.22,moduleGemfilegem,source,gemspec,groupsatırlarıyorumlar pubspec.yamldependencies,dev_dependencies,dependency_overridesdiğer key'ler mix.exsher değişiklik Değişen bir satırın section'ı diff'in kendi 20 satırlık context'inden değil, manifest'in tamamından (
git show HEAD:<manifest>) okunur: birpackage.json'ın 40. satırındaki bir değişiklik hunk içinde kök{'a hiç ulaşmaz ve kök seviyesindeki her key dependency gibi okunurdu. Manifest'in kendisinin bir yere koymadığı bir key ya da table sayılır; yani okunamayan bir dosya da notu alır.Model commit'in sonucundan sonra şu notu okur:
lockfile-sync: this commit changes package.json but not package-lock.json · go.mod but not go.sum. Run the package manager's install so the lockfile matches, and commit it.Aynı anda transcript'e tek bir satır düşer, böylece modele ne söylendiğini görürsün. Satırda talimat yoktur, yalnız çiftler vardır:
lockfile-sync: this commit changes package.json but not package-lock.json · go.mod but not go.sumNot ile satır ayrı kanallardır: model satırı, sen de notu hiç okumazsın.
sidebar açıksa bu çiftler transcript yerine onun stream'ine bir kayıt olarak gider, her çift bir satırda (lockfile kırmızı,
but notsoluk); transcript temiz kalır. Kayıt, yenileri onu pane'den itene kadar durur. Sidebar kapalıysa ya da kurulu değilse satır yukarıdaki gibi transcript'e düşer.Bir lockfile'ı dışarıda bırakan her commit, manifest'lerine göre key'lenmiş kendi sidebar kaydıyla kendi bulgusunu açar. Sonraki bir commit bulgusunu açık olanların yanına ekler ve hiçbirinin üstüne yazmaz; açık bir bulgunun zaten saydığı bir çift ikinci kez açılmaz. Her bulgu kendi ölçümüyle kapanır.
Mod bulguyu bellekteki eski cevaba göre tutmaz. Her ölçüm, sonraki her commit'ten sonra, her ana loop turn'ünün sonunda ve
denymodunda korunan bir git komutundan önce git'e ve package manager'a yeniden sorar; bu yüzden bulgu üç yoldan kapanır:- lockfile yazılmıştır: sonraki bir commit onu değiştirmiştir, ya da
git status --porcelainonu working tree'de değişmiş gösterir; - package manager lockfile'ı manifest'le uyumlu okur (4. adımdaki kontrol);
- kontrol hiçbir şey kanıtlamaz ve manifest artık lockfile değişikliği istemez:
git log -1 -- <lockfile>lockfile'ı en son yazan commit'i bulur, manifest'in o commit'e göre diff'i hiçbir dependency'ye dokunmaz. Geri alınan bir değişiklik böyle okunur. Package manager'ın geride okuduğu bir lockfile, diff ne derse desin açık kalır.
Kayıt silinir ve yeşil yeni bir kayıt bunlardan hangisi olduğunu söyler:
lockfile-sync: a later change brought the lockfiles along: package-lock.json lockfile-sync: cargo reads Cargo.lock as in step with Cargo.toml lockfile-sync: the dependencies match the lockfile again: package.jsonSidebar kapalıysa aynı metin tek bir transcript satırıdır. Model bunların hiçbirini okumaz: bulgu kendi yaptığı işle kapandı, bir not ancak az önce yaptığını tekrarlardı.
- lockfile yazılmıştır: sonraki bir commit onu değiştirmiştir, ya da
Modelin kapatmadığı bir bulgu her ana loop turn'ünün sonunda yeniden ölçülür; geriye kalan, bir sonraki prompt'unla birlikte modele tek bir not olarak gider:
lockfile-sync: 1 lockfile(s) are still behind their manifest: package-lock.json behind package.json. Run the package manager's install so the lockfile is written, or take the dependency change back.Not her prompt'ta değil, her turn'de bir kez gelir. Bu not olmasa model bulguyu yalnız commit anında bir kez duyar ve sonra unuturdu; bulgu da pane'de öylece dururdu. Sana yeni bir satır düşmez, çünkü pane aynı bulguyu zaten gösteriyor.
denymodunda bir lockfile geride kaldıkça modgit commit,git pushvegit merge'ü de durdurur. Durdurmadan önce iki ölçümü de çalıştırır; böylece package manager'ın az önce yazdığı bir lockfile da, geri alınmış bir dependency değişikliği de gate'i kendiliğinden açar.git commityalnız kendi dosyalarından sorumludur: mod index'i okur (git diff --cached --name-only -z), commit açık manifest'lerin hiçbirini içermiyorsa geçmesine izin verir ve kaç tanesinin hâlâ durduğunu tek satırla söyler.pushvemergeiçin okunacak bir index yoktur, orada bütün çiftler geçerlidir. Gate'i aşmanın yolu yoktur; kapatmak yalnız sana kalır,/lockfile-sync mode noteile. Varsayılannotemodudur ve hiçbir şeyi durdurmaz.
Bir git hatası sarı bir kayıt olarak yazılır (sidebar kapalıysa transcript'e). Kayıt farklı bir hata gelene kadar bir kez yazılır ve commit'in sonucu olduğu gibi kalır.
Canlı denemede model bir package.json dependency'sini yükseltti, yalnız o dosyayı commit'ledi ve notu kelimesi kelimesine aktardı.
Komut
/lockfile-sync açık mı kapalı mı, mod ve hâlâ geride olan lockfile'lar
/lockfile-sync on | off varsayılan açık
/lockfile-sync mode note yalnız not verir; varsayılan budur
/lockfile-sync mode deny bir lockfile geride kaldıkça commit, push ve merge de durur
Kurulum
claude plugin marketplace add KilimcininKorOglu/claude-code-mods
claude plugin install lockfile-sync@kilimcininkoroglu-mods
Function hook'lar henüz early access aşamasında. Claude Code 2.1.288 ve üzerinde varsayılan olarak yüklenir, açılacak bir ayar yok.
Kurulumdan sonra
- Claude Code'u yeniden başlat.
Nereye uzanır
Claude Code 2.1.283 üzerinde claude plugin validate ile doğrulandı:
❯ ./register.ts hooks: session.start, command.run{command=lockfile-sync}, turn.complete, prompt.submit, tool.call{tool=Bash}
❯ ./register.ts calls: $.command.register, $.env.get (via tmpDir), $.fs.exists (via lockOnDisk), $.fs.read (via treeText), $.process.run (via git, lockVerdict), $.session.cwd (via beforeCommit), $.sidebar.clear (via dropEntry), $.sidebar.set (via toPerson), $.store.get (via readSettings), $.store.set (via runCommand, setMode), $.ui.log (via denyFor, toPerson, toolFailed)
Reach L3: network'e çıkan process'ler çalıştırır.
1. Okur: Bash komut metnini; repository'de lockfile'ların olup olmadığını; açık her bulgunun manifest'ini ve lockfile'ını working tree'de; git üzerinden commit'in dosya listesini, manifest diff'lerini ve HEAD'deki her manifest'i; TMPDIR'i
2. Çalıştırır: salt okunur git rev-parse, git show, git status, git log ve git diff; argv ile; ve 4. adımdaki lockfile package manager kontrolünü, commit anında lockfile'ı olmayan her manifest için bir kez ve her ölçümde açık her çift için bir kez, turn sonunda da
3. Gönderir: commit'in sonucundan sonra modele bir not, bulgu durdukça sonraki prompt'la bir not daha ve transcript'e bir satır; package manager çözümlediği paket metadata'sı için registry'sine sorabilir
4. Saklar: $.store içinde açık/kapalı ayarını ve modu; package manager'lar kendi cache'lerini tutar, mix de $TMPDIR/lockfile-sync/mix-deps altına indirir
5. Düşman girdi: dizin komut metninden gelir ve git'e ve package manager'a yalnız çalışma dizini olarak ulaşır, hiçbir zaman shell üzerinden değil; manifest path'leri onlara tek bir argv girdisi olarak ulaşır. Kontrol projenin tuttuğu kodu çalıştırır: Gemfile Ruby'dir, mix.exs Elixir'dir ve ikisi de değerlendirilir. npm, pnpm ve bun --ignore-scripts ile, pnpm --ignore-pnpmfile ile, composer --no-plugins ile çalışır; böylece projenin script'leri ve plugin'leri çalışmaz
Sınırlar
- Package manager kontrolünün hiçbir şey kanıtlamadığı yerde mod yalnız dosya adlarını ve diff section'larını karşılaştırır; lockfile'ın içeriğinin manifest'e uyduğunu kontrol etmez.
- Karar package manager'ın kendisinindir:
npm cikök paketinversion'ını karşılaştırmaz,yarn checkde kaldırılmış bir dependency'yi hâlâ listeleyen bir lockfile'ı uyumlu okur. - Yarn 2+
yarn.lock'un burada kontrolü yoktur:yarn install --immutablenode_modules'ı projeye bağlar,--mode=update-lockfilede--immutableile birlikte kullanılamaz. - Bir bulgu durdukça kontrolü her ana loop turn'ünün sonunda yeniden çalışır, çift başına 60 sn'ye kadar.
- Hiçbir commit'in yazmadığı bir lockfile'da manifest'i karşılaştıracak bir şey yoktur; bulgusunu yalnız ilk ölçüm kapatabilir.
- Aynı dizinde aynı manager'a ait iki lockfile (bir
package-lock.json'ın yanında biryarn.lock) tablodaki ilkiyle eşleşir. git commit'i gizleyen bir script ya da alias üzerinden yapılan commit görülmez.- Dizinini shell'in genişlettiği bir
cdya dagit -C(cd $D,cd ~/x, bir backquote) mod'a gerçek dizini söylemez. O commit kontrol edilmez ve sarı satır bu kelimeyi gösterir, örneğinthe commit's directory is not known: cd $D. Tek tırnak içindeki bir kelime olduğu gibi kalır. - Bir merge commit'inin birleşik diff'i okunmaz.
denymodunu aşmanın yolu yoktur. Bir bulgu düzeltilemiyorsa gate'i/lockfile-sync mode noteile sen kapatırsın.- Gate, lockfile'daki working tree değişikliğini düzeltme sayar; değişikliğin içeriğine bakmaz.
git commit -a,-amve--sonrasında pathspec verilen commit index'e göre daraltılmaz, çünkü index'te henüz olmayan dosyaları da commit'ler. Bunlarda açık çiftlerin hepsi geçerlidir.
Geliştirme
make install # eslint, typescript-eslint, typescript
make lint # complexity sınırı 10; aşılırsa build kırılır
make typecheck # /plugin-types çıktısı olan .claude/types/ gerekir
make validate
make test # claude plugin test