tools-sync: 修复会删掉宿主自装 skill 的 registry 对账缺陷
本次同步实跑触发了数据丢失:orca-cli 的物理副本在 ~\.agents\skills(Orca 就是 这样装的——真目录放 .agents,再把每个工具链过去,本机 8 个工具全指向它), 而主副本里的同名条目本身是指向它的 junction。对账循环从不检查"主副本条目是不是 链接",于是 fingerprint 比对经链接解析到同一份内容判为"identical",删掉 registry 副本并建 junction → 主副本与 registry 互指成环,唯一的真副本没了。 orchestration 走 INGEST 分支,则把 Orca 的布局反了过来。 两者均已用 `orca skills install --skill <name>` 恢复为 Orca 自己的布局。 修复三处: - 对账循环:主副本条目本身是链接时,判定该 skill 归宿主所有,计入 foreign 跳过。 - INGEST:新增 Get-SkillDirLinkers,若 ~\.* 下其他工具的 skills 目录有链接指向 这个目录,说明它是宿主自装 skill 的物理家,不搬进主副本。 - 镜像阶段:跳过本身是链接的主副本条目,否则 Codex 会把同一 skill 注册两遍 (.agents 与 .codex 都在扫)。 回归测试新增 hostowned 夹具(真目录在 registry、主副本是链接):在修复前的脚本上 以"real dir was collapsed into a link"失败,修复后通过。 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01438Zbcx49e4o46uSA71mFF
This commit is contained in:
@@ -27,6 +27,12 @@ try {
|
||||
# A link into the other registry rather than the primary: the drift case.
|
||||
New-Item -ItemType Junction -Path (Join-Path $codex "shared") -Target (Join-Path $agents "shared") | Out-Null
|
||||
|
||||
# Host-installed shape: the real directory lives in a registry and the PRIMARY is the link
|
||||
# (Orca installs this way). Collapsing the registry copy here would make the link point at
|
||||
# itself and delete the only copy - the reconciler must recognise it and keep its hands off.
|
||||
New-Skill (Join-Path $agents "hostowned") "installed by the host"
|
||||
New-Item -ItemType Junction -Path (Join-Path $primary "hostowned") -Target (Join-Path $agents "hostowned") | Out-Null
|
||||
|
||||
# A local bare repo stands in for origin so Phase 1 completes and Phase 2 actually runs.
|
||||
$origin = Join-Path $root "origin.git"
|
||||
& git init --quiet --bare $origin
|
||||
@@ -57,6 +63,15 @@ try {
|
||||
if ((Get-Content -Raw (Join-Path $primary "forked\SKILL.md")) -notmatch 'primary body') { throw "primary was overwritten by a conflict`n$output" }
|
||||
|
||||
if ($output -notmatch 'not a skill dir') { throw "directory without SKILL.md not reported`n$output" }
|
||||
|
||||
# The host-installed skill must survive intact, with the primary still a link at the registry.
|
||||
$hostReal = Get-Item -Force (Join-Path $agents "hostowned")
|
||||
if ($hostReal.LinkType -eq "Junction") { throw "host-installed skill's real dir was collapsed into a link`n$output" }
|
||||
if ((Get-Content -Raw (Join-Path $agents "hostowned\SKILL.md")) -notmatch 'installed by the host') { throw "host-installed skill's content was lost`n$output" }
|
||||
$hostPrimary = Get-Item -Force (Join-Path $primary "hostowned")
|
||||
if (($hostPrimary.Target | Select-Object -First 1) -ne (Join-Path $agents "hostowned")) { throw "primary link to the host-installed skill was repointed`n$output" }
|
||||
# Mirroring it into the registry Codex scans would register the same skill twice.
|
||||
if (Test-Path (Join-Path $codex "hostowned")) { throw "host-installed skill was mirrored, double-registering it`n$output" }
|
||||
# Mirror registry must expose every primary skill, including the freshly ingested one.
|
||||
foreach ($name in @("shared", "forked", "codexborn")) {
|
||||
if (-not (Test-Path (Join-Path $codex "$name\SKILL.md"))) { throw "mirror missing $name`n$output" }
|
||||
|
||||
Reference in New Issue
Block a user