Add plugin lock-file sync - #6316
Conversation
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #6316 +/- ##
==========================================
+ Coverage 73.04% 73.11% +0.07%
==========================================
Files 745 747 +2
Lines 79208 79584 +376
==========================================
+ Hits 57857 58189 +332
+ Misses 17300 17282 -18
- Partials 4051 4113 +62 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
JAORMX
left a comment
There was a problem hiding this comment.
Panel review found one state-consistency bug plus missing CLI E2E coverage and a thin-wrapper boundary violation. Please address the inline findings before merge.
eb93233 to
735241d
Compare
735241d to
68fb269
Compare
68fb269 to
b820980
Compare
JAORMX
left a comment
There was a problem hiding this comment.
The adoption rollback and CLI E2E findings were addressed. The follow-up panel found a concurrency hole in adoption compensation and incomplete Claude Code registration health checks.
b820980 to
2ebd4a8
Compare
JAORMX
left a comment
There was a problem hiding this comment.
Two merge-blocking sync correctness issues remain in the current head.
a7bc74d to
c572121
Compare
c572121 to
880e12e
Compare
Restore project plugins from the lock file via thv ai-plugin sync and POST /plugins/sync, gated by TOOLHIVE_PLUGINS_LOCK_ENABLED. Signed-off-by: Samuele Verzi <samu@stacklok.com>
A failed DB update after writing the lock entry left the plugin untracked; remove the entry so the next sync can retry. Cover thv ai-plugin sync exit codes the same way skills lock does. Signed-off-by: Samuele Verzi <samu@stacklok.com>
Sync must not report a plugin current when a requested client is missing or marketplace registration is gone, and must refuse to adopt a local tag that cannot be restored later. Signed-off-by: Samuele Verzi <samu@stacklok.com>
Adoption must hold the per-plugin lock and put back the pre-existing entry if marking Managed fails. Signed-off-by: Samuele Verzi <samu@stacklok.com>
A stale lock/DB snapshot can resurrect uninstalls; default sync must also expand to newly detected clients. Signed-off-by: Samuele Verzi <samu@stacklok.com>
Default sync targets installed plugin clients, validates pinned canonical names before mutate, and drops context lock reentrancy. Signed-off-by: Samuele Verzi <samu@stacklok.com>
Sync already calls adoptLocked under the held mutex; remove the dead public wrapper and quiet installFromOCI gocyclo. Signed-off-by: Samuele Verzi <samu@stacklok.com>
A lone --clients all now matches the documented detected-client default instead of failing validation on every sync. Signed-off-by: Samuele Verzi <samu@stacklok.com>
Signed-off-by: Samuele Verzi <samu@stacklok.com>
880e12e to
a649e0a
Compare
Summary
plugins:.thv ai-plugin syncandPOST /plugins/syncrestore project plugins fromtoolhive.lock.yaml(--check/--adopt/--prune, confirmation gate, exit codes 0/2/3/4).buildPinnedReference— never re-resolved from source.SyncRestorebypasses the same-digest no-op so on-disk drift is repaired.--checkhashes every client's canonical plugin directory (contentDigest), notmarketplace.json.--adoptrecords unmanaged project-scope installs without requiring--allow-unsigned(plugin Sigstore is Stack 2).TOOLHIVE_PLUGINS_LOCK_ENABLED(403 when off). Upgrade is a 501 stub until the next stack PR.Part of #6300. Stack 4/5 — schema → lock-service → install-hooks → sync → upgrade.
Type of change
Test plan
./pkg/plugins/pluginsvcsync/pin tests and./pkg/api/v1sync endpoint tests, with the Taskfile race/ldflagsflags)task lint-fix)Does this introduce a user-facing change?
No by default — the feature is inert unless
TOOLHIVE_PLUGINS_LOCK_ENABLED=true. With the gate on,thv ai-plugin syncrestores project plugins fromtoolhive.lock.yaml.Special notes for reviewers
pin.gois copied fromskillsvcrather than extracted — agreed: reuse, don't extract.--allow-unsigned. Until Stack 2, lock validation allows an entry with neither provenance norunsigned. Requiring the flag here would make every plugin adopt fail.Upgradeon*serviceis a 501 stub soPluginLockServicetype-asserts for/sync. The next PR replaces it.cmd/thv/app/skill_confirm.goandexitcode.go.