From 49cd4d3ee493276adf7ef89b77f3db5964c2dff1 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Wed, 26 Aug 2026 11:30:18 +0800 Subject: [PATCH] =?UTF-8?q?fix(deploy):=20=E4=BF=AE=E6=AD=A3=20domain=20?= =?UTF-8?q?=E5=89=8D=E7=B6=B4=E6=AD=A7=E7=BE=A9=E8=88=87=20kiro-cli=20?= =?UTF-8?q?=E6=8E=A2=E6=B8=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What: deploy.sh 收到帶 jsc- 前綴的 domain 名時自動去掉前綴再組 jsc-{domain}@jsc;deploy_kiro 先探測這個版本的 kiro-cli 認不認得 plugin 子指令,不認得就整批直接走本地複製退路。 Why: marketplace.json 的 plugins[].name 本身就帶 jsc- 前綴,SKILL.md 只寫「domain 名單來自 marketplace」沒講清楚要不要去前綴,實際執行時餵進去兜成 jsc-jsc-ask@jsc 雙重前綴,claude、copilot、antigravity、kiro 四支 CLI 的更新全部第一輪失敗。另外 kiro-cli 2.18.1 這個版本已經完全沒有 plugin 子指令,逐一嘗試再退回複製會先洗出一長串看似失敗、實則設計內的錯誤訊息。 How: 腳本層正規化 domain 參數(去前綴),比只改文件更可靠——不管呼叫端傳哪種格式都對。kiro 的探測用 kiro-cli --help-all 抓子指令清單,一次性判斷,不逐一撞錯誤才退回;探測本身不算部署動作,不印 cmd/exit。SKILL.md 同步補上前綴說明。 Who: jsc-cli:deploy 的執行正確性與輸出可讀性。 --- .claude-plugin/plugin.json | 2 +- .codex-plugin/plugin.json | 2 +- plugin.json | 2 +- skills/deploy/SKILL.md | 2 +- tools/deploy.sh | 67 +++++++++++++++++++++++++++++--------- 5 files changed, 55 insertions(+), 20 deletions(-) diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 55bb34c..1f86fb4 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-cli", - "version": "0.1.2", + "version": "0.1.3", "description": "CLI 偵測、模型能力標籤、子代理派工與技能庫批次部署", "skills": "./skills", "author": { diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index 879441f..b8ddfe7 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-cli", - "version": "0.1.2", + "version": "0.1.3", "description": "CLI 偵測、模型能力標籤、子代理派工與技能庫批次部署", "skills": "./skills" } diff --git a/plugin.json b/plugin.json index 23af6d1..16a31c7 100644 --- a/plugin.json +++ b/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-cli", - "version": "0.1.2", + "version": "0.1.3", "description": "CLI 偵測、模型能力標籤、子代理派工與技能庫批次部署", "skills": "./skills/" } diff --git a/skills/deploy/SKILL.md b/skills/deploy/SKILL.md index d898d38..657ae63 100644 --- a/skills/deploy/SKILL.md +++ b/skills/deploy/SKILL.md @@ -20,7 +20,7 @@ description: Batch install, update, or uninstall the whole jsc skill set on ever 3. Ask the user for the mode per the `jsc-ask:ask` rules: `install` / `update` / `uninstall`. Every option states its impact scope: which CLIs it touches and which configs it writes. Done when the user has named exactly one of `install`, `update` or `uninstall`. 4. Get the domain list (**never hardcode it**; this skill follows automatically when domains are added or removed): read `plugins[].name` from the unified marketplace via `jsc-gitea/tools/gitea.sh api GET /repos/plugins/meta/raw/.claude-plugin/marketplace.json`. - The marketplace is unified as `jsc`; the install token is `jsc-{domain}@jsc`. Done when the domain list comes from that response and holds at least one name. + The marketplace is unified as `jsc`; the install token is `jsc-{domain}@jsc`. Each `plugins[].name` already carries the `jsc-` prefix (e.g. `jsc-ask`) — pass it to `tools/deploy.sh` as-is, prefixed or not; the script normalizes it. Done when the domain list comes from that response and holds at least one name. 5. Run `tools/deploy.sh {mode} {cli} {domain}...` once per detected CLI, passing the whole domain list in one call so the marketplace command runs only once. This step **MUST run as a sub agent** (one sub agent per CLI). The script prints `cmd` and `exit` lines for every command, then one `result` line; `-n` prints the commands without running them. Antigravity cannot install from a Gitea URL, so the script clones each domain into the local plugin directory (`JSC_LOCAL_PLUGINS`, default `$JSC_HOME/plugins`) and installs from that path — keep that clone, because update pulls the same one. That default deliberately avoids a development checkout: when the directory holds uncommitted changes or unpushed commits, the script prints a `skip` line, leaves the tree untouched, and installs the on-disk content. Done when every detected CLI has reported an exit status for every command it ran. 6. After install or update, call `jsc-hooks:hooks-install` to rewire the hooks. Done when hooks-install reports a wiring result for each detected CLI. 7. Report the result and any failure reason for every CLI × mode, plus every `skip` line and every CLI that could not be version-checked in step 2. Done when every detected CLI appears in the report with its `result` status. diff --git a/tools/deploy.sh b/tools/deploy.sh index dcb6578..62e2dc5 100755 --- a/tools/deploy.sh +++ b/tools/deploy.sh @@ -3,16 +3,21 @@ # 用法: # deploy.sh [-n] {install|update|uninstall} {claude|codex|copilot|antigravity|kiro} {domain} [domain...] # -n 或 --dry-run(或 JSC_DEPLOY_DRYRUN=1):只印指令,不執行。 +# {domain} 裸名或帶 jsc- 前綴皆可(例:ask 或 jsc-ask),腳本會自動去掉前綴再組 +# jsc-{domain}@jsc;marketplace.json 的 plugins[].name 本身就帶前綴,不必事先剝掉。 # 輸出(TSV,一行一筆): # cmd{指令} 即將執行的指令 # exit{結束碼}{指令} 該指令的結束碼;dry-run 時結束碼印「-」 # skip{domain}{原因} 本地 clone 是開發中的樹,略過 git pull +# note{cli}{原因} 非逐指令的說明(例:kiro 整批改走複製退路的理由) # result{cli}{mode}{domain 清單}{ok|fail} -# 結束碼:全部指令成功 0;任一指令失敗 1;參數錯誤 2。skip 不算失敗,但呼叫端要據實回報。 +# 結束碼:全部指令成功 0;任一指令失敗 1;參數錯誤 2。skip、note 不算失敗,但呼叫端要據實回報。 # marketplace 指令一輪只跑一次:install 與 update 先跑,uninstall 最後跑。 # 各 CLI 的細節都收在這裡,SKILL.md 只描述何時呼叫與參數: # antigravity 不接受 gitea URL,先 clone 到本地再從路徑安裝,更新時 pull 同一份。 -# kiro 的執行檔是 kiro-cli;plugin 指令失敗時退回複製 skills 目錄。 +# kiro 的執行檔是 kiro-cli;先探測這個版本認不認得 plugin 子指令(部分版本已經完全 +# 移除,例:2.18.1),認得才逐一嘗試、失敗才退回複製,不認得就整批直接走複製, +# 不逐一撞一次「unrecognized subcommand」才退回。 # 環境變數: # GITEA_HOST Gitea 站台,可省略 scheme(預設 https://gitea.jsc.idv.tw) # JSC_GITEA_OWNER 存取庫的 owner(預設 plugins) @@ -171,23 +176,41 @@ kiro_copy() { # $1=domain run cp -R "$LOCAL_DIR/$1/skills/." "$KIRO_SKILLS/jsc-$1/" } +# kiro-cli 是否認得 plugin 子指令:一次性偵測,探測本身不印 cmd/exit(不是部署動作, +# 印出來只會讓人誤以為那也是一次失敗的部署嘗試)。部分版本(例:2.18.1)完全沒有這個 +# 子指令,逐一嘗試再退回複製,會先洗出一長串看似失敗、實則設計內的錯誤訊息。 +kiro_has_plugin_cmd() { + "$bin" --help-all 2>/dev/null | grep -qE '^ plugin( |$)' +} + deploy_kiro() { bin=$(cli_bin kiro) - case "$MODE" in - install) run_soft "$bin" plugin marketplace add "$MKT" ;; - update) run_soft "$bin" plugin marketplace update jsc ;; - esac + if kiro_has_plugin_cmd; then + case "$MODE" in + install) run_soft "$bin" plugin marketplace add "$MKT" ;; + update) run_soft "$bin" plugin marketplace update jsc ;; + esac + for d in $DOMAINS; do + case "$MODE" in + install) + run_soft "$bin" plugin install "jsc-$d@jsc" || kiro_copy "$d" + ;; + update) + run_soft "$bin" plugin update "jsc-$d@jsc" || kiro_copy "$d" + ;; + uninstall) + run_soft "$bin" plugin uninstall "jsc-$d@jsc" || run rm -rf "$KIRO_SKILLS/jsc-$d" + ;; + esac + done + return 0 + fi + + printf 'note\tkiro\t%s\n' "此版本 kiro-cli 沒有 plugin 子指令,改走本地複製(git pull 或 clone 後複製 skills 目錄)" for d in $DOMAINS; do case "$MODE" in - install) - run_soft "$bin" plugin install "jsc-$d@jsc" || kiro_copy "$d" - ;; - update) - run_soft "$bin" plugin update "jsc-$d@jsc" || kiro_copy "$d" - ;; - uninstall) - run_soft "$bin" plugin uninstall "jsc-$d@jsc" || run rm -rf "$KIRO_SKILLS/jsc-$d" - ;; + install|update) kiro_copy "$d" ;; + uninstall) run rm -rf "$KIRO_SKILLS/jsc-$d" ;; esac done [ "$MODE" = uninstall ] && run_soft "$bin" plugin marketplace remove jsc @@ -202,7 +225,19 @@ esac MODE=$1 CLI=$2 shift 2 -DOMAINS="$*" + +# 每個 domain 一律去掉開頭的 jsc-:往下每處都自己組 jsc-$d@jsc,收到已帶前綴的名字 +# (marketplace.json 的 plugins[].name 就是這樣,例如 jsc-ask)會兜成 jsc-jsc-ask@jsc, +# 讓 claude/copilot/antigravity/kiro 全部裝不上、更新不了。這裡正規化一次, +# 呼叫端不管傳哪種格式都能正常動作,不必每個呼叫端各自記得先去前綴。 +_domains="" +for _d in "$@"; do + case "$_d" in + jsc-*) _d="${_d#jsc-}" ;; + esac + _domains="$_domains $_d" +done +DOMAINS="${_domains# }" case "$MODE" in install|update|uninstall) ;;