fix: 升级以往正式发布的 skill,安装脚本先装 CLI 并输出单行 JSON - #12
Merged
Merged
Conversation
…r result
Rerunning the installer is the documented upgrade path, but any existing
skill that differed from the embedded one was a conflict, and both
installers ran skill setup before moving the CLI into place, so a stale
official skill also blocked the CLI upgrade.
- The build lists the SKILL.md digest of every released v* tag; setup
replaces those atomically (status updated) and only unknown content
conflicts. Tag builds fail when earlier tags are missing; CI and release
checkouts fetch full history.
- install.sh / install.ps1 move the CLI first, then run skill setup with
it. Progress goes to stderr; success prints one JSON line with cli
{path, version, previous_version} and per-host skills; failures print a
JSON error, and a skill conflict names --replace-skill / -ReplaceSkill.
- skill setup --agent is repeatable (installers also accept comma lists);
data becomes {skills: [...]}, and a conflict on any host writes none.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SyjxHtzc5bneQgSH85QULN
Windows CI reported the installer's path in long form (C:\Users\runneradmin\...) while the test built it from Node's 8.3 temp path (C:\Users\RUNNER~1\...). Both name the same file; compare realpaths. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SyjxHtzc5bneQgSH85QULN
…l conflict wording - install.sh: macOS sh (bash 3.2) under a UTF-8 locale read the fullwidth parenthesis after an unbraced $agent as part of the name, so set -u aborted with "unbound variable" instead of the JSON validation failure. - cli.ts: JSON failure lines always carry code; errors without a specific one get their kind's generic code (unexpected errors: unexpected_error). - skill_conflict message and agent-setup.md no longer call unknown content unofficial; it may also be a newer release. - Tests: unsupported agent through the installer under en_US.UTF-8 (exit 3 on sh), validation and unexpected CLI failures carry a code. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SyjxHtzc5bneQgSH85QULN
- install.sh 缺 HOME 时 kind 与 code 对齐为 config / config_error - install.ps1 去掉 ValidateSet,非法 -Scope 也输出约定的失败 JSON Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01SyjxHtzc5bneQgSH85QULN
This was referenced Sep 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
问题与证据
2026-09-13 复现:先用 0.1.3 安装 skill(
npx @hiq-ai/cortex-org-wiki-cli@0.1.3 skill setup --agent claude-code --scope project),再用 0.1.4 执行同一命令,返回{"ok":false,"kind":"config","code":"skill_conflict"},退出码 2。文档给出的升级路径(docs/agent-setup.md、SKILL.md)是"版本过低时重新运行安装脚本",但:src/skill.ts把任何内容不同的已有文件都当成冲突,旧的官方 skill 也不例外,所以按文档升级必然冲突。scripts/install.sh在set -eu下先执行skill setup(原第 53 行),之后才把 CLI 移到位(原第 60 行);install.ps1同样(原第 33–34 行)。skill 一冲突,CLI 升级也跟着中止。已核实:每个
v*tag 的skills/cortex-org-wiki/SKILL.mdblob 摘要与 npm 上 0.1.1–0.1.4 及 v0.1.0 Release tarball 内嵌 skill 的摘要逐一相同(v0.1.0–v0.1.24873e530…,v0.1.38d049e2b…,v0.1.4f45580ba…,即当前内容),因此以 tag 内容作为"以往正式发布"的判据成立。变更
scripts/generate-assets.mjs在生成SKILL_SHA256的同时,对每个v*tag 读取当时的 SKILL.md(该 tag 没有此文件则跳过),输出PREVIOUS_OFFICIAL_SKILL_SHA256(不含当前摘要)。src/skill.ts判定:与当前摘要相同为unchanged;属于以往官方摘要时原子替换并返回updated;只有未知内容才报skill_conflict,提示用--replace。GITHUB_REF_TYPE=tag)看不到任何更早的v*tag 时生成脚本直接失败;本地无 tag 的开发构建只是列表为空。CI 和 release 中需要构建或跑升级测试的 checkout(ci、package、binaries、verify-install)改为fetch-depth: 0。install.sh/install.ps1先把 CLI 放到位,再用已安装的 CLI 执行 skill setup(--skill-only仍用临时二进制)。进度全部写 stderr。成功时 stdout 只有一行 JSON:{"ok":true,"tool":"install","data":{"cli":{"path","version","previous_version"},"skills":[...]}};previous_version取安装前同位置 CLI 的version输出,没有则为null;--skill-only时cli为null,--cli-only时skills为[]。失败时 stderr 输出{"ok":false,"kind","code","message"}并以非零退出;skill_conflict的提示改为--replace-skill/-ReplaceSkill,此时 CLI 已经升级。throw而不是exit:本机 pwsh 实测,[scriptblock]::Create方式调用时exit会直接结束调用方会话。代价是 JSON 行之后还有 PowerShell 的错误渲染,退出码固定为 1。Write-Host在子进程里会写到 stdout,所以进度改用[Console]::Error。skill setup --agent可重复(yargs array);安装脚本接受重复或逗号分隔(PowerShell 为-Agent codex,claude-code)。每个宿主写入同一份内容并有各自的status。所有宿主先检查,任一冲突则整条命令非零退出,且所有宿主都不写入,确认后用 replace 重跑即可。仍不自动探测宿主。tests/cli.test.ts对每个以往 tag 的 SKILL.md 验证updated;未知内容仍冲突;多宿主安装;一个宿主冲突时不写入任何宿主。tests/native.test.ts验证安装脚本 stdout 恰为一行可解析 JSON、stderr 带进度;重跑时previous_version与以往官方 skill 升级;自定义内容冲突时 CLI 仍已升级并提示 replace 参数,replace 后updated;CLI-only / skill-only 的cli、skills形状;校验失败返回checksum_mismatch。docs/agent-setup.md新增"升级"和"安装后检查"两节,说明 JSON 行、升级行为和多宿主用法;README、docs/release.md同步。SKILL.md 没有引用旧输出,未改动,内嵌 skill 摘要不变。说明:Windows 上
cli.path为长路径形式(首轮 CI 中测试从 Node 的 8.3 临时路径RUNNER~1拼出期望值,而 PowerShell 返回runneradmin,两者是同一文件);测试改为比较 realpath,安装脚本行为未改。评审修正
install.sh不支持的 agent 报错:macOS 默认/bin/sh(bash 3.2.57)在 UTF-8 locale 下把未加花括号的$agent后面的全角(读成变量名的一部分,set -u直接中止(line 39: agent�: unbound variable,退出码 1,stderr 没有 JSON)。本机已复现,改为${agent}。脚本中没有其他未加花括号且后跟多字节字符的展开。dash 不受影响,所以 Ubuntu CI 发现不了。code:非CortexClientError错误(例如只读目录的EACCES)和 yargs 参数错误原来没有code,安装脚本原样转出,与文档里"按code报告"不符。现在src/cli.ts统一补上该 kind 的通用 code:unknown→unexpected_error,validation→invalid_argument,config/transport/upstream→config_error/transport_error/upstream_error;已有的具体 code 保持不变。字段顺序统一为ok, kind, code, message。--base-url遇到新 skill)。提示改为"已有与本版本不同且不在以往正式发布版本中的 skill 内容(本地修改、较新版本或来源不明)",docs/agent-setup.md措辞同步。共享接口影响
skill setup --json的data由单个对象改为{"skills":[...]},每个宿主一项,字段与原来相同。已在本机cortex(desktop/nomad/deck)和cortex-skills中检索skill setup的输出消费者,未找到;Cortex Cowork 市场安装由 Host 使用市场产物的metadata.cli,不调用skill setup。verify-install已改为解析这一行。--json失败行现在总有code(原来可能缺失),字段顺序变化不影响 JSON 解析。验证
npm test(含 tsc 构建)bun build src/cli.ts --compile后npm run test:bin,sh为 macOS 默认sh指向 dash(与 Ubuntu 一致)-File和 scriptblock 两种方式运行install.ps1,本地 HTTP 下载源previous_version、unchanged)、冲突(CLI 已落地,提示-ReplaceSkill,非零退出且后续语句不执行)、-ReplaceSkill、-SkillOnly、-CliOnly均符合预期GITHUB_REF_TYPE=tag时报错失败npm testvalidation/invalid_argument,项目路径是文件时为unknown/unexpected_error,退出码 1bun build --compile+npm run test:bin(macOSsh= bash 3.2)LC_ALL=en_US.UTF-8)"用例在修复前失败并报agent�: unbound variable,修复后通过(退出码 3)/bin/sh、/bin/bash、/bin/dash×en_US.UTF-8、zh_CN.UTF-8运行--agent codex,cortex{"ok":false,"kind":"validation","code":"invalid_argument",…}skill setup --json{"ok":false,"kind":"unknown","code":"unexpected_error","message":"EACCES…"},退出码 1fetch-depth: 0,npm test + 编译后的 native 测试)install.ps1的单行 JSON、升级、冲突、模式形状全部由 pwsh 7 实跑上线
合并后按
docs/release.md发布 v0.1.5(bumppackage.json并打 tag),然后更新 cortex-skills 中的配对版本。安装脚本和二进制通过同一次 release 推到 CDN;新的install.sh依赖新 CLI 的skill setup输出形状,遇到旧二进制时会以unexpected_output明确失败,不会输出无效 JSON。未验证
New-Object Text.UTF8Encoding、2>&1区分 ErrorRecord、控制台 UTF-8 编码临时切换)未实测,含中文路径时的编码也未实测。verify-install验证。🤖 Generated with Claude Code
https://claude.ai/code/session_01SyjxHtzc5bneQgSH85QULN