From de504ee2edb1ef3d4431ea581a79483fb6e8340c Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 24 Aug 2026 11:36:31 +0800 Subject: [PATCH 1/8] =?UTF-8?q?feat(model-config):=20=E6=96=B0=E5=A2=9E=20?= =?UTF-8?q?SDLC=20=E9=9A=8E=E6=AE=B5=E6=8C=87=E5=AE=9A=E6=A8=A1=E5=9E=8B?= =?UTF-8?q?=E9=8F=88=E8=A7=A3=E6=9E=90=E5=B7=A5=E5=85=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What:新增 tools/model-config.sh,提供 get {stage} 與 list 兩個子命令,解析 SDLC 各階段(plan、analyze、implement、maintain)的指定模型鏈。 Why:讓 jsc-sdlc 各階段閘門能以角色式模型路由指定模型與遞補鏈,而不是只靠能力標籤比對;同時讓專案能覆寫全域設定。 How:以 POSIX sh 加 awk 實作;先讀專案目錄 .jsc/models,該階段沒設定才退回 $JSC_HOME/models.conf(JSC_HOME 預設 ~/.jsc);設定格式 stage=model[,fallback...],同階段多行取最後一行;get 未設定時空輸出且 exit 0,list 每階段輸出 stage、chain、source(未設定印「-」)。 Who:jsc-cli models 技能與 jsc-sdlc 各階段的模型閘門。 Co-Authored-By: Claude Fable 5 --- tools/model-config.sh | 84 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100755 tools/model-config.sh diff --git a/tools/model-config.sh b/tools/model-config.sh new file mode 100755 index 0000000..e9108d7 --- /dev/null +++ b/tools/model-config.sh @@ -0,0 +1,84 @@ +#!/usr/bin/env sh +# model-config.sh — 解析 SDLC 各階段的指定模型鏈(角色式路由)。 +# 設定格式(一行一階段):stage=model[,fallback1[,fallback2...]] +# 「#」開頭為註解,空白行忽略。階段限定:plan、analyze、implement、maintain。 +# 解析順序: +# 1. 目前工作目錄的 ./.jsc/models(專案覆寫) +# 2. $JSC_HOME/models.conf(JSC_HOME 預設 ~/.jsc) +# 專案檔有設定的階段完全覆寫全域設定;其餘階段仍讀全域檔。 +# 用法: +# model-config.sh get {stage} 印出該階段解析後的模型鏈(逗號分隔);未設定不印。兩種情況都 exit 0。 +# model-config.sh list 每階段一行:stagechainsource(project 或 global);未設定的 chain 與 source 印「-」。 +set -u + +JSC_HOME="${JSC_HOME:-$HOME/.jsc}" +PROJECT_FILE=./.jsc/models +GLOBAL_FILE="$JSC_HOME/models.conf" +STAGES="plan analyze implement maintain" + +# 取出單一設定檔裡某階段的模型鏈。 +# 同階段出現多行時取最後一行,結果才有確定性。 +read_chain() { # $1=設定檔 $2=階段 + [ -f "$1" ] || return 0 + awk -F= -v stage="$2" ' + { sub(/\r$/, "") } # 去掉 CR + /^[ \t]*#/ { next } # 註解行 + /^[ \t]*$/ { next } # 空白行 + index($0, "=") == 0 { next } + { + key = $1 + gsub(/[ \t]/, "", key) + if (key != stage) next + val = substr($0, index($0, "=") + 1) + gsub(/[ \t]/, "", val) + if (val != "") chain = val + } + END { if (chain != "") print chain } + ' "$1" +} + +# 解析單一階段:專案檔優先,該階段沒設定才退回全域檔。 +# 輸出:chainsource;兩檔都沒設定時不輸出。 +resolve() { # $1=階段 + chain=$(read_chain "$PROJECT_FILE" "$1") + if [ -n "$chain" ]; then + printf '%s\tproject\n' "$chain" + return 0 + fi + chain=$(read_chain "$GLOBAL_FILE" "$1") + if [ -n "$chain" ]; then + printf '%s\tglobal\n' "$chain" + fi + return 0 +} + +usage() { + echo "用法:model-config.sh get {plan|analyze|implement|maintain} | list" >&2 + exit 1 +} + +case "${1:-}" in + get) + stage="${2:-}" + case " $STAGES " in + *" $stage "*) ;; + *) usage ;; + esac + resolve "$stage" | cut -f1 + exit 0 + ;; + list) + for stage in $STAGES; do + line=$(resolve "$stage") + if [ -n "$line" ]; then + printf '%s\t%s\n' "$stage" "$line" + else + printf '%s\t-\t-\n' "$stage" + fi + done + exit 0 + ;; + *) + usage + ;; +esac -- 2.53.0 From 072e01821beb332a44309795b6c998cf844e0c30 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 24 Aug 2026 11:36:45 +0800 Subject: [PATCH 2/8] =?UTF-8?q?docs(models):=20=E8=A3=9C=E4=B8=8A=E8=A7=92?= =?UTF-8?q?=E8=89=B2=E5=BC=8F=E6=A8=A1=E5=9E=8B=E8=B7=AF=E7=94=B1=E6=96=87?= =?UTF-8?q?=E4=BB=B6=E8=88=87=E9=9A=8E=E6=AE=B5=E6=8C=87=E5=AE=9A=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E8=BC=B8=E5=87=BA=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What:references/model-tags.md 新增「階段指定模型(角色式路由)」章節,說明設定格式、檔案優先序與遞補鏈語意;skills/models/SKILL.md 的 description 與步驟加入 model-config.sh list 的「階段指定模型」輸出表(stage、指定鏈、source 三欄);README.md 補上 tools/model-config.sh 工具列與 models 技能說明。 Why:角色式模型路由需要文件明確定義設定格式與判定順序,jsc-sdlc 閘門與使用者才知道指定模型優先、標籤比對為備援。 How:設定格式 stage=model[,fallback...];優先序為專案 .jsc/models 覆寫 $JSC_HOME/models.conf;解析一律透過 jsc-cli/tools/model-config.sh,不自行讀檔;models 技能輸出表未設定的階段以「-」表示。 Who:models 技能的使用者與依賴模型閘門的 jsc-sdlc 各階段技能。 Co-Authored-By: Claude Fable 5 --- README.md | 3 ++- references/model-tags.md | 23 +++++++++++++++++++++++ skills/models/SKILL.md | 3 ++- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ac30862..317b7ca 100644 --- a/README.md +++ b/README.md @@ -21,6 +21,7 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/jsc.git),安 | 工具 | 用途 | | --- | --- | | `tools/detect-clis.sh` | 列出已安裝的 AI CLI 與執行檔路徑(TSV:name / path / version;kiro 的執行檔為 `kiro-cli`) | +| `tools/model-config.sh` | 解析 SDLC 各階段的指定模型鏈(`get {stage}`、`list`);專案 `.jsc/models` 優先於 `$JSC_HOME/models.conf`,格式見 `references/model-tags.md` | ## Skills 目錄 @@ -30,7 +31,7 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/jsc.git),安 ### `models` -讀取各已安裝 CLI 可使用的模型並加上能力標籤(`references/model-tags.md`),並列出 SDLC 各階段的必要標籤,供 `jsc-sdlc` 的模型能力閘門使用。 +讀取各已安裝 CLI 可使用的模型並加上能力標籤(`references/model-tags.md`),列出 SDLC 各階段的必要標籤,並用 `tools/model-config.sh` 解析各階段的指定模型鏈(專案 `.jsc/models` 優先於 `$JSC_HOME/models.conf`)。`jsc-sdlc` 閘門先看指定模型,沒有指定才退回標籤比對。 ### `deploy` diff --git a/references/model-tags.md b/references/model-tags.md index 954280d..e1ecfde 100644 --- a/references/model-tags.md +++ b/references/model-tags.md @@ -34,4 +34,27 @@ | 實作(implement) | coding | | 維護(maintain) | 任意 | +## 階段指定模型(角色式路由) + +每個 SDLC 階段可以指定一個模型,並附上遞補模型。設定格式一行一階段: + +``` +stage=model[,fallback1[,fallback2...]] +``` + +「#」開頭為註解,空白行忽略。階段限定 plan、analyze、implement、maintain。 + +設定檔位置與優先序: + +| 順位 | 檔案 | 範圍 | +| --- | --- | --- | +| 1 | 專案目錄的 `.jsc/models` | 專案覆寫 | +| 2 | `$JSC_HOME/models.conf`(`JSC_HOME` 預設 `~/.jsc`) | 全域 | + +專案檔有設定的階段完全覆寫全域設定;其餘階段仍讀全域檔。解析一律用 `jsc-cli/tools/model-config.sh`,不自行讀檔。 + +遞補鏈語意:鏈上第一個模型優先;前面的模型不可用時依序後退到下一個。 + +指定模型優先於標籤比對:階段有指定模型時直接用指定鏈;只有階段沒有指定模型時,才用上表的必要標籤判定。 + 表列以外的模型:依 `jsc-ask:ask` 規則詢問使用者或依供應商文件補表後再判定。 diff --git a/skills/models/SKILL.md b/skills/models/SKILL.md index 2ff0795..9c68060 100644 --- a/skills/models/SKILL.md +++ b/skills/models/SKILL.md @@ -1,6 +1,6 @@ --- name: models -description: List every model usable by each installed AI CLI (claude, codex, copilot, antigravity, kiro) and attach capability tags from references/model-tags.md. Also states which tags each SDLC phase requires, so jsc-sdlc skills can gate execution. Use when checking model fitness or inventorying models; not for switching models. +description: List every model usable by each installed AI CLI (claude, codex, copilot, antigravity, kiro) and attach capability tags from references/model-tags.md. Also resolves each SDLC stage's designated model chain via tools/model-config.sh (project .jsc/models overrides $JSC_HOME/models.conf) and states which tags each phase requires, so jsc-sdlc skills gate on the designated model first and fall back to capability tags. Use when checking model fitness, inventorying models, or reviewing designated-model routing; not for switching models or editing the config files. --- # models — list CLI models with capability tags @@ -22,3 +22,4 @@ description: List every model usable by each installed AI CLI (claude, codex, co 3. Attach capability tags to every model per `references/model-tags.md`. Handle unlisted models per the closing rule of that file. 4. Output a table with four columns: CLI, model, tags, currently in use. 5. Append the SDLC phase requirement table (plan and analyze need `reasoning-high`; implement needs `coding`; maintain accepts any), so `jsc-sdlc` skills can gate on model capability. +6. Run `jsc-cli/tools/model-config.sh list` and append a 「階段指定模型」 table right after the phase requirement table, with three columns: stage, designated chain, source (`project` / `global`). State below the table that `jsc-sdlc` gates resolve the designated model first and fall back to capability tags only when a stage has no designated model. Done when the table shows all four stages, with `-` for unconfigured ones. -- 2.53.0 From cb6df171f6bd92fc1906820d72faa35329724c66 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 24 Aug 2026 11:36:57 +0800 Subject: [PATCH 3/8] =?UTF-8?q?chore(manifest):=20=E7=89=88=E6=9C=AC?= =?UTF-8?q?=E8=99=9F=E6=8F=90=E5=8D=87=E8=87=B3=200.0.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What:plugin.json、.claude-plugin/plugin.json、.codex-plugin/plugin.json 三份 manifest 的 version 由 0.0.1 提升為 0.0.2。 Why:本次新增角色式模型路由功能(model-config.sh 與相關文件),屬功能性變更,需要新版本號讓各 CLI 的插件更新機制辨識。 How:同步修改三份 manifest 的 version 欄位,維持三處版本一致。 Who:jsc-cli 插件的安裝與更新流程(jsc-cli:deploy 及各 CLI 原生插件命令)。 Co-Authored-By: Claude Fable 5 --- .claude-plugin/plugin.json | 2 +- .codex-plugin/plugin.json | 2 +- plugin.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 75fa4ed..e87112b 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-cli", - "version": "0.0.1", + "version": "0.0.2", "description": "CLI 偵測、模型能力標籤與技能庫批次部署", "skills": "./skills", "author": { diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index e5039e6..f96f73d 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-cli", - "version": "0.0.1", + "version": "0.0.2", "description": "CLI 偵測、模型能力標籤與技能庫批次部署", "skills": "./skills" } diff --git a/plugin.json b/plugin.json index ed9ebb1..009a189 100644 --- a/plugin.json +++ b/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-cli", - "version": "0.0.1", + "version": "0.0.2", "description": "CLI 偵測、模型能力標籤與技能庫批次部署", "skills": "./skills/" } -- 2.53.0 From 286b2f7af2f105b4c5251257315618163858d9b5 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 24 Aug 2026 14:49:16 +0800 Subject: [PATCH 4/8] =?UTF-8?q?fix(marketplace):=20=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E5=85=A9=E4=BB=BD=20marketplace.json=20=E7=9A=84=E8=AA=AA?= =?UTF-8?q?=E6=98=8E=E8=88=87=E6=93=81=E6=9C=89=E8=80=85=E6=AC=84=E4=BD=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What: `.agents/plugins/marketplace.json` 和 `.claude-plugin/marketplace.json` 兩份檔案內容不一致。這次把兩份都對齊 plugins/jsc 的標準版本。在 `.agents/plugins/marketplace.json` 加上最上層的 description 和 owner(name: "JSC")欄位,並幫十個外掛(jsc-ask、jsc-cli、jsc-git、jsc-gitea、jsc-hooks、jsc-log、jsc-meta、jsc-pkg、jsc-review、jsc-sdlc)各自補上說明文字。在 `.claude-plugin/marketplace.json` 加上最上層的 description 和 owner 欄位,並修正 jsc-meta 說明文字,把「新建/更新/刪除」改成「新建、更新、刪除」。 Why: 這兩份檔案是 marketplace 的清單檔,內容原本不一致。`.claude-plugin/marketplace.json` 已有每個外掛的說明,但缺最上層欄位。`.agents/plugins/marketplace.json` 完全沒有說明文字。清單檔不一致,會讓不同工具讀到不同資訊,造成混淆,所以要修正。 How: 對照 plugins/jsc 這份標準版本,逐一比對兩份檔案,補齊缺少的欄位,並統一用字。 Who: 這次改動跟 jsc-cli 自己的技能邏輯無關,是整個 repo 層級的一致性修正。目的是讓 jsc-cli 這個 repo 可以正確扮演 marketplace 註冊入口的角色,跟其他 repo 的清單檔保持同步。 --- .agents/plugins/marketplace.json | 34 ++++++++++++++++++++++---------- .claude-plugin/marketplace.json | 2 +- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/.agents/plugins/marketplace.json b/.agents/plugins/marketplace.json index 12df680..a9b4e66 100644 --- a/.agents/plugins/marketplace.json +++ b/.agents/plugins/marketplace.json @@ -1,75 +1,89 @@ { "name": "jsc", + "description": "jsc 跨 AI 助理技能組的統一 marketplace(claude / codex / copilot / antigravity / kiro)。", + "owner": { + "name": "JSC" + }, "plugins": [ { "name": "jsc-ask", "source": { "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/ask.git" - } + }, + "description": "決策樹問詢與問詢紀錄(QUESTION_* wiki 頁)" }, { "name": "jsc-cli", "source": { "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/cli.git" - } + }, + "description": "CLI 偵測、模型能力標籤與技能庫批次部署" }, { "name": "jsc-git", "source": { "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/git.git" - } + }, + "description": "Commit 分組認可與 Push Request 建立" }, { "name": "jsc-gitea", "source": { "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/gitea.git" - } + }, + "description": "Gitea API 工具、Wiki 讀寫與存取庫批次同步" }, { "name": "jsc-hooks", "source": { "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/hooks.git" - } + }, + "description": "跨 CLI hooks:STE100 語言強制、工時計時、技能用量記錄" }, { "name": "jsc-log", "source": { "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/log.git" - } + }, + "description": "工作日誌(LOG_* wiki 頁)與技能使用統計" }, { "name": "jsc-meta", "source": { "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/meta.git" - } + }, + "description": "技能組自我管理:新建、更新、刪除技能與技能準則" }, { "name": "jsc-pkg", "source": { "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/pkg.git" - } + }, + "description": "套件批次更新(nodejs/python/dotnet),失敗還原" }, { "name": "jsc-review", "source": { "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/review.git" - } + }, + "description": "程式碼審查:Refactoring 壞味道六組 + 註解規範 + 淺模組" }, { "name": "jsc-sdlc", "source": { "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/sdlc.git" - } + }, + "description": "開發生命週期:規劃/分析/實作/維護(wiki 追蹤)" } ] } diff --git a/.claude-plugin/marketplace.json b/.claude-plugin/marketplace.json index 28bb223..a9b4e66 100644 --- a/.claude-plugin/marketplace.json +++ b/.claude-plugin/marketplace.json @@ -59,7 +59,7 @@ "source": "url", "url": "https://gitea.jsc.idv.tw/plugins/meta.git" }, - "description": "技能組自我管理:新建/更新/刪除技能與技能準則" + "description": "技能組自我管理:新建、更新、刪除技能與技能準則" }, { "name": "jsc-pkg", -- 2.53.0 From f2029d4cd0067629b69101c8b893fd76079eb6ab Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 24 Aug 2026 14:49:28 +0800 Subject: [PATCH 5/8] =?UTF-8?q?feat(cli):=20=E6=96=B0=E5=A2=9E=20model-con?= =?UTF-8?q?fig.sh=20=E7=9A=84=20resolve=20=E5=AD=90=E6=8C=87=E4=BB=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What: 在 `tools/model-config.sh` 新增 `resolve {stage}` 子指令。這個指令會取出某個 SDLC 階段的模型鏈(跟 `get {stage}` 用同樣的解析規則:先讀專案的 `.jsc/models`,找不到再讀 `$JSC_HOME/models.conf`),然後印出鏈中第一個模型名稱,當作目前這個 CLI 可用的模型。同時新增 `current_cli()` 這個輔助函式,透過各家 CLI 的環境變數,判斷目前是在 claude、codex、copilot、antigravity、還是 kiro 底下執行。這個版本先把 `current_cli()` 的結果記錄下來,還沒有拿它去過濾模型鏈中不可用的模型,這件事留到之後再做,因為要判斷某個模型是否可用,需要 LLM 層級的判斷,不是單純的 shell script 能做到的。之後的計畫是拿 `current_cli()` 的結果,對照 `references/model-tags.md` 和 `detect-clis.sh`,跳過模型鏈裡不可用的模型。另外,把 README.md 裡 `tools/model-config.sh` 的工具說明表格,加上新的 `resolve {stage}` 子指令說明。版本號也從 0.0.2 升到 0.0.3,同步改了 `plugin.json`、`.claude-plugin/plugin.json`、`.codex-plugin/plugin.json` 這三份清單檔,這是這個 repo 的慣例:新增功能時要一併升版號。 Why: jsc-meta:skill-check 這次稽核發現,jsc-sdlc 底下 plan、analyze、implement、maintain 這四個階段的技能,各自都要幫自己的階段挑一個模型,來做 gate check。如果沒有 `resolve` 這個子指令,這四個技能就要各自在技能說明裡,重複寫一次「讀模型鏈、選一個候補模型」的邏輯。這樣容易寫錯,也難維護。 How: 在既有的 `get`/`list` 邏輯基礎上,加一個 `resolve` 子指令,直接回傳模型鏈的第一個模型。同時加上 `current_cli()`,先把偵測 CLI 的能力做出來,但先不接上過濾邏輯,用註解說明後續要怎麼接。文件和版本號一併更新。 Who: 這個功能是給 jsc-sdlc 的四個階段技能(plan、analyze、implement、maintain)用的。它們可以直接呼叫 `resolve {stage}`,取得一個可用的模型名稱,不用各自重複寫模型鏈的判斷邏輯。 --- .claude-plugin/plugin.json | 2 +- .codex-plugin/plugin.json | 2 +- README.md | 2 +- plugin.json | 2 +- tools/model-config.sh | 44 +++++++++++++++++++++++++++++++++++--- 5 files changed, 45 insertions(+), 7 deletions(-) diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index e87112b..39d0035 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-cli", - "version": "0.0.2", + "version": "0.0.3", "description": "CLI 偵測、模型能力標籤與技能庫批次部署", "skills": "./skills", "author": { diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index f96f73d..4119def 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-cli", - "version": "0.0.2", + "version": "0.0.3", "description": "CLI 偵測、模型能力標籤與技能庫批次部署", "skills": "./skills" } diff --git a/README.md b/README.md index 317b7ca..79245c4 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/jsc.git),安 | 工具 | 用途 | | --- | --- | | `tools/detect-clis.sh` | 列出已安裝的 AI CLI 與執行檔路徑(TSV:name / path / version;kiro 的執行檔為 `kiro-cli`) | -| `tools/model-config.sh` | 解析 SDLC 各階段的指定模型鏈(`get {stage}`、`list`);專案 `.jsc/models` 優先於 `$JSC_HOME/models.conf`,格式見 `references/model-tags.md` | +| `tools/model-config.sh` | 解析 SDLC 各階段的指定模型鏈(`get {stage}`、`list`、`resolve {stage}` 印出目前 CLI 可用的第一個模型);專案 `.jsc/models` 優先於 `$JSC_HOME/models.conf`,格式見 `references/model-tags.md` | ## Skills 目錄 diff --git a/plugin.json b/plugin.json index 009a189..77e45f0 100644 --- a/plugin.json +++ b/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-cli", - "version": "0.0.2", + "version": "0.0.3", "description": "CLI 偵測、模型能力標籤與技能庫批次部署", "skills": "./skills/" } diff --git a/tools/model-config.sh b/tools/model-config.sh index e9108d7..93adcab 100755 --- a/tools/model-config.sh +++ b/tools/model-config.sh @@ -7,8 +7,9 @@ # 2. $JSC_HOME/models.conf(JSC_HOME 預設 ~/.jsc) # 專案檔有設定的階段完全覆寫全域設定;其餘階段仍讀全域檔。 # 用法: -# model-config.sh get {stage} 印出該階段解析後的模型鏈(逗號分隔);未設定不印。兩種情況都 exit 0。 -# model-config.sh list 每階段一行:stagechainsource(project 或 global);未設定的 chain 與 source 印「-」。 +# model-config.sh get {stage} 印出該階段解析後的模型鏈(逗號分隔);未設定不印。兩種情況都 exit 0。 +# model-config.sh list 每階段一行:stagechainsource(project 或 global);未設定的 chain 與 source 印「-」。 +# model-config.sh resolve {stage} 印出該階段「目前 CLI 可用的第一個模型」單一名稱;鏈為空或無法判定時不印,exit 0。 set -u JSC_HOME="${JSC_HOME:-$HOME/.jsc}" @@ -52,8 +53,36 @@ resolve() { # $1=階段 return 0 } +# 判斷目前是哪個 CLI 在跑(盡量而為,非必要)。 +# 依 CLI 官方常見環境變數判斷;偵測不到就回傳 unknown。 +current_cli() { + [ -n "${CLAUDECODE:-}" ] && { echo claude; return 0; } + [ -n "${CODEX_SANDBOX:-}${CODEX_HOME:-}" ] && { echo codex; return 0; } + [ -n "${COPILOT_AGENT:-}" ] && { echo copilot; return 0; } + [ -n "${ANTIGRAVITY_SESSION:-}" ] && { echo antigravity; return 0; } + [ -n "${KIRO_SESSION:-}" ] && { echo kiro; return 0; } + echo unknown +} + +# resolve 子指令:印出「目前 CLI 可用的第一個模型」單一名稱。 +# 簡化說明:這個 repo 目前沒有「列出某 CLI 實際安裝/可用模型」的 shell 級機制 +# ——現有的 skills/models 是靠 sub agent 讀各 CLI 的設定檔(~/.claude/settings.json、 +# ~/.codex/config.toml 等),屬於 LLM 才能做的判讀,沒辦法在這支 POSIX sh 腳本裡重現。 +# 因此這裡只用 current_cli() 抓到的「目前 CLI 名稱」這個既有訊號做記錄, +# 實際判斷可用性一律簡化為「直接取模型鏈的第一個模型」,不逐一檢查該模型是否真的能用。 +# 之後若要做到依 CLI 實際可用模型過濾,可以在這裡比對 current_cli 的結果與 +# references/model-tags.md/detect-clis.sh 的輸出,逐一嘗試鏈上模型直到找到可用的。 +resolve_first_usable() { # $1=階段 + chain=$(resolve "$1" | cut -f1) + [ -n "$chain" ] || return 0 + cli=$(current_cli) + : "目前偵測到的 CLI:$cli(本版本尚未用來篩選模型,見上方簡化說明)" + printf '%s\n' "$chain" | cut -d, -f1 + return 0 +} + usage() { - echo "用法:model-config.sh get {plan|analyze|implement|maintain} | list" >&2 + echo "用法:model-config.sh get {plan|analyze|implement|maintain} | list | resolve {plan|analyze|implement|maintain}" >&2 exit 1 } @@ -67,6 +96,15 @@ case "${1:-}" in resolve "$stage" | cut -f1 exit 0 ;; + resolve) + stage="${2:-}" + case " $STAGES " in + *" $stage "*) ;; + *) usage ;; + esac + resolve_first_usable "$stage" + exit 0 + ;; list) for stage in $STAGES; do line=$(resolve "$stage") -- 2.53.0 From 519f1163db45f6511539fe5baae75151cda8e8a3 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 24 Aug 2026 16:05:06 +0800 Subject: [PATCH 6/8] =?UTF-8?q?feat(=E6=A8=A1=E5=9E=8B=E6=A8=99=E7=B1=A4?= =?UTF-8?q?=E9=96=98=E9=96=80):=20=E6=96=B0=E5=A2=9E=20model-tags.sh=20?= =?UTF-8?q?=E8=88=87=20reasoning-max=20=E5=88=86=E7=B4=9A=EF=BC=8CSDLC=20?= =?UTF-8?q?=E9=9A=8E=E6=AE=B5=E9=96=98=E9=96=80=E6=94=B9=E7=94=B1=E8=83=BD?= =?UTF-8?q?=E5=8A=9B=E6=A8=99=E7=B1=A4=E5=88=A4=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5 (1M context) --- references/model-tags.md | 39 ++++++++-- skills/models/SKILL.md | 7 +- tools/model-tags.sh | 155 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 190 insertions(+), 11 deletions(-) create mode 100755 tools/model-tags.sh diff --git a/references/model-tags.md b/references/model-tags.md index e1ecfde..e43e829 100644 --- a/references/model-tags.md +++ b/references/model-tags.md @@ -4,7 +4,8 @@ | 標籤 | 意義 | | --- | --- | -| reasoning-high | 高階推理,適合規劃與分析 | +| reasoning-max | 頂級推理,各家當代最強一階;需求拆解、架構決策、跨檔案分析 | +| reasoning-high | 高階推理,足以判讀規格與寫實作 | | coding | 程式碼產生與修改能力佳 | | fast | 低延遲 | | cheap | 低成本 | @@ -15,25 +16,42 @@ | 模型 | 標籤 | | --- | --- | -| claude-fable-5 | reasoning-high, coding, long-context, vision | -| claude-opus-5 | reasoning-high, coding, long-context, vision | +| claude-fable-5 | reasoning-max, reasoning-high, coding, long-context, vision | +| claude-opus-5 | reasoning-max, reasoning-high, coding, long-context, vision | | claude-sonnet-5 | reasoning-high, coding, fast, long-context, vision | | claude-haiku-4-5 | coding, fast, cheap, long-context, vision | -| gpt-5.x / o 系列(codex 預設) | reasoning-high, coding, long-context, vision | +| gpt-5.x / o 系列(codex 預設) | reasoning-max, reasoning-high, coding, long-context, vision | | gpt-5.x-mini / codex-mini | coding, fast, cheap | -| gemini-3-pro | reasoning-high, coding, long-context, vision | +| gemini-3-pro | reasoning-max, reasoning-high, coding, long-context, vision | | gemini-3-flash | coding, fast, cheap, long-context, vision | | copilot 內建(gpt/claude 選項) | 依所選底層模型比照上表 | +標籤蘊含關係:`reasoning-max` 是 `reasoning-high` 的上位標籤。補表時,帶 `reasoning-max` 的模型**必須同時列出 `reasoning-high`**——比對是逐標籤字面比對,不推導上下位關係,漏列會讓該模型卡在只要求 `reasoning-high` 的階段。 + ## SDLC 階段需求 | 階段 | 必要標籤 | | --- | --- | -| 規劃(plan) | reasoning-high | -| 分析(analyze) | reasoning-high | +| 規劃(plan) | reasoning-max | +| 分析(analyze) | reasoning-max | | 實作(implement) | coding | | 維護(maintain) | 任意 | +規劃與分析要求 `reasoning-max`,實作只要求 `coding`:需求拆解與架構決策一步走錯,後面整批工作包都跟著錯,成本遠高於實作階段的單點失誤。 + +### 判定方式(程式層,不由模型自評) + +閘門一律由腳本判定,**模型不得自行宣稱具備標籤**: + +| 工具 | 職責 | +| --- | --- | +| `jsc-cli/tools/model-tags.sh gate {階段} {模型 id}` | 查上面兩張表,印 `PASS`/`FAIL:{缺少的標籤}`/`UNKNOWN-MODEL`;exit code 0/1/2 | +| `jsc-cli/tools/model-tags.sh sync` | 把兩張表寫成 `$JSC_HOME/model-tags.tsv`,供 hook 讀取 | +| `jsc-hooks/hooks/sdlc-gate.sh lock {階段}` | 從 transcript 讀出**實際**模型 id,比對必要標籤;不符就拒絕上鎖並回報 | +| `jsc-hooks/hooks/sdlc-gate.sh check` | 每次送出提示時比對;不符即擋下該輪提示(exit 2) | + +模型 id 一律取自 transcript 記錄的實際值,不採用模型自我回報——自我回報無法驗證,等同沒有閘門。 + ## 階段指定模型(角色式路由) 每個 SDLC 階段可以指定一個模型,並附上遞補模型。設定格式一行一階段: @@ -55,6 +73,11 @@ stage=model[,fallback1[,fallback2...]] 遞補鏈語意:鏈上第一個模型優先;前面的模型不可用時依序後退到下一個。 -指定模型優先於標籤比對:階段有指定模型時直接用指定鏈;只有階段沒有指定模型時,才用上表的必要標籤判定。 +**標籤是閘門的唯一判準**:階段能不能跑,一律由「SDLC 階段需求」的必要標籤決定。指定模型鏈不參與放行判定,只有兩個用途: + +1. 閘門擋下時,指出建議切換到哪一個模型(鏈上第一個滿足該階段必要標籤的模型)。 +2. 同樣合格的模型有多個時,表達偏好順序。 + +因此「指定鏈上的模型」若不具備該階段必要標籤,照樣被擋;設定檔不能當成繞過閘門的後門。 表列以外的模型:依 `jsc-ask:ask` 規則詢問使用者或依供應商文件補表後再判定。 diff --git a/skills/models/SKILL.md b/skills/models/SKILL.md index 9c68060..13ca409 100644 --- a/skills/models/SKILL.md +++ b/skills/models/SKILL.md @@ -1,6 +1,6 @@ --- name: models -description: List every model usable by each installed AI CLI (claude, codex, copilot, antigravity, kiro) and attach capability tags from references/model-tags.md. Also resolves each SDLC stage's designated model chain via tools/model-config.sh (project .jsc/models overrides $JSC_HOME/models.conf) and states which tags each phase requires, so jsc-sdlc skills gate on the designated model first and fall back to capability tags. Use when checking model fitness, inventorying models, or reviewing designated-model routing; not for switching models or editing the config files. +description: List every model usable by each installed AI CLI (claude, codex, copilot, antigravity, kiro) and attach capability tags from references/model-tags.md. Syncs the tag table to $JSC_HOME/model-tags.tsv via tools/model-tags.sh so jsc-sdlc gates can be enforced in code, states which tags each SDLC stage requires (plan and analyze need reasoning-max, implement needs coding, maintain any), and resolves each stage's preferred model chain via tools/model-config.sh (project .jsc/models overrides $JSC_HOME/models.conf) for switch suggestions only. Use when checking model fitness, inventorying models, or reviewing stage gating; not for switching models or editing the config files. --- # models — list CLI models with capability tags @@ -21,5 +21,6 @@ description: List every model usable by each installed AI CLI (claude, codex, co If a config is unreadable, list that CLI's known default models and mark each one with the literal label 「預設推定」 (assumed default). 3. Attach capability tags to every model per `references/model-tags.md`. Handle unlisted models per the closing rule of that file. 4. Output a table with four columns: CLI, model, tags, currently in use. -5. Append the SDLC phase requirement table (plan and analyze need `reasoning-high`; implement needs `coding`; maintain accepts any), so `jsc-sdlc` skills can gate on model capability. -6. Run `jsc-cli/tools/model-config.sh list` and append a 「階段指定模型」 table right after the phase requirement table, with three columns: stage, designated chain, source (`project` / `global`). State below the table that `jsc-sdlc` gates resolve the designated model first and fall back to capability tags only when a stage has no designated model. Done when the table shows all four stages, with `-` for unconfigured ones. +5. Run `tools/model-tags.sh sync` to write the tag table to `$JSC_HOME/model-tags.tsv`, and report the path. This file is what `jsc-hooks/hooks/sdlc-gate.sh` reads, so the SDLC gate stays broken until it exists. Done when the command prints the path. +6. Append the SDLC stage requirement table (plan and analyze need `reasoning-max`; implement needs `coding`; maintain accepts any), and state that gating is done in code by `sdlc-gate.sh lock {stage}` against the transcript's actual model id — **the models listed here are never allowed to self-assess their own tags**. +7. Run `jsc-cli/tools/model-config.sh list` and append a 「階段偏好模型」 table right after the stage requirement table, with three columns: stage, chain, source (`project` / `global`). State below the table that the chain does **not** grant passage: it only names the model to suggest switching to when the gate blocks, and expresses preference among models that already satisfy the required tags. Done when the table shows all four stages, with `-` for unconfigured ones. diff --git a/tools/model-tags.sh b/tools/model-tags.sh new file mode 100755 index 0000000..ec1a4ad --- /dev/null +++ b/tools/model-tags.sh @@ -0,0 +1,155 @@ +#!/usr/bin/env sh +# model-tags.sh — 解析「模型能力標籤」與「SDLC 階段必要標籤」,並判定模型是否夠格跑某階段。 +# +# 資料來源優先序(前一項可取得就不往下): +# 1. $JSC_HOME/model-tags.tsv(機器可讀快取,可手改,用來補表列以外的模型) +# 2. 本 plugin 的 references/model-tags.md(唯一權威來源,不在腳本內另存一份對照表) +# +# 用法: +# model-tags.sh dump 把對照表印成 TSV,不寫檔 +# model-tags.sh sync 把對照表寫進 $JSC_HOME/model-tags.tsv(給 hook 讀) +# model-tags.sh stage {stage} 印出該階段的必要標籤(逗號分隔);階段不限標籤印 any +# model-tags.sh model {model-id} 印出該模型的標籤(逗號分隔);查不到不印 +# model-tags.sh gate {stage} {model-id} 判定該模型能否跑該階段 +# +# TSV 欄位(三欄,Tab 分隔): +# stage{階段}{必要標籤以逗號分隔,不限標籤時為 any} +# model{模型鍵}{能力標籤以逗號分隔} +# +# gate 的輸出與 exit code: +# PASS exit 0 模型具備該階段全部必要標籤 +# FAIL:{缺少的標籤} exit 1 模型缺標籤,不得執行該階段 +# UNKNOWN-MODEL exit 2 模型不在對照表上,無法判定 +# UNKNOWN-STAGE exit 2 階段不在對照表上,無法判定 +set -u + +HERE=$(dirname "$0") +REF="$HERE/../references/model-tags.md" +JSC_HOME="${JSC_HOME:-$HOME/.jsc}" +TSV="$JSC_HOME/model-tags.tsv" + +# 解析 references/model-tags.md 的兩張表格,輸出 TSV。 +# 「## 對照表」段落 → model 列;「## SDLC 階段需求」段落 → stage 列。 +# 模型欄可能寫成「gpt-5.x / o 系列(codex 預設)」這種人讀格式, +# 因此先砍掉全形括號後的說明,再用「/」切成多個鍵,只留純 ASCII 的鍵。 +parse_ref() { + [ -f "$REF" ] || return 0 + awk ' + function trim(s) { sub(/^[ \t]+/, "", s); sub(/[ \t]+$/, "", s); return s } + # 砍掉第一個全形左括號之後的內容(表中括號都是尾端的補充說明)。 + # 一律用 split 切字串,不用 substr 算位移——全形字元的長度在不同 locale 下 + # 會被算成 1 個字元或 3 個 byte,位移法會在其中一種 locale 下算錯。 + function strip_note(s) { split(s, a, "("); return trim(a[1]) } + # 取全形括號內的文字(例:規劃(plan) → plan) + function paren(s) { + if (split(s, a, "(") < 2) return "" + split(a[2], b, ")") + return trim(b[1]) + } + function is_ascii_key(s) { return s ~ /^[A-Za-z0-9._-]+$/ } + function norm_tags(s) { gsub(/[ \t]/, "", s); return s } + + /^##[ \t]/ { + if (index($0, "對照表") > 0) sect = "model" + else if (index($0, "SDLC 階段需求") > 0) sect = "stage" + else sect = "" + next + } + sect == "" { next } + /^\|/ { + line = $0 + sub(/^\|/, "", line); sub(/\|[ \t]*$/, "", line) + n = split(line, f, "|") + if (n < 2) next + c1 = trim(f[1]); c2 = trim(f[2]) + if (c1 == "" || c2 == "") next + if (c1 ~ /^:?-+:?$/) next # 表頭分隔列 + if (c1 == "模型" || c1 == "階段" || c1 == "標籤") next # 表頭 + + if (sect == "stage") { + key = paren(c1) + if (key == "") key = c1 + if (!is_ascii_key(key)) next + tags = (index(c2, "任意") > 0) ? "any" : norm_tags(c2) + printf "stage\t%s\t%s\n", key, tags + next + } + + tags = norm_tags(c2) + if (tags == "") next + m = split(strip_note(c1), keys, "/") + for (i = 1; i <= m; i++) { + k = trim(keys[i]) + if (k == "" || !is_ascii_key(k)) continue + printf "model\t%s\t%s\n", k, tags + } + } + ' "$REF" +} + +# 取得對照表內容:快取優先,沒有快取才解析 md。 +data() { + if [ -s "$TSV" ]; then + cat "$TSV" + else + parse_ref + fi +} + +stage_tags() { # $1=階段 + data | awk -F'\t' -v s="$1" '$1 == "stage" && $2 == s { print $3; exit }' +} + +# 模型鍵與實際模型 id 雙向包含即視為同一家族。 +# 例:表列 claude-haiku-4-5 對得上實際 id claude-haiku-4-5-20251001。 +# 多筆命中時取最長鍵,避免 claude 這種短鍵蓋掉精確鍵。 +model_tags() { # $1=模型 id + data | awk -F'\t' -v m="$1" ' + $1 == "model" && (index(m, $2) > 0 || index($2, m) > 0) { + if (length($2) > best_len) { best_len = length($2); best = $3 } + } + END { if (best != "") print best } + ' +} + +gate() { # $1=階段 $2=模型 id + req=$(stage_tags "$1") + if [ -z "$req" ]; then echo "UNKNOWN-STAGE"; return 2; fi + [ "$req" = "any" ] && { echo "PASS"; return 0; } + have=$(model_tags "$2") + if [ -z "$have" ]; then echo "UNKNOWN-MODEL"; return 2; fi + missing=$(awk -v req="$req" -v have="$have" ' + BEGIN { + n = split(have, h, ","); for (i = 1; i <= n; i++) owned[h[i]] = 1 + n = split(req, r, ",") + for (i = 1; i <= n; i++) if (!(r[i] in owned)) out = (out == "" ? r[i] : out "," r[i]) + print out + }') + if [ -n "$missing" ]; then echo "FAIL:$missing"; return 1; fi + echo "PASS"; return 0 +} + +usage() { + echo "用法:model-tags.sh dump | sync | stage {階段} | model {模型 id} | gate {階段} {模型 id}" >&2 + exit 1 +} + +case "${1:-}" in + dump) parse_ref; exit 0 ;; + sync) + out=$(parse_ref) + if [ -z "$out" ]; then + echo "[jsc] 解析不到 $REF,未寫出 $TSV" >&2 + exit 1 + fi + mkdir -p "$JSC_HOME" 2>/dev/null || true + printf '%s\n' "$out" > "$TSV" || exit 1 + echo "$TSV" + exit 0 ;; + stage) [ -n "${2:-}" ] || usage; stage_tags "$2"; exit 0 ;; + model) [ -n "${2:-}" ] || usage; model_tags "$2"; exit 0 ;; + gate) + [ -n "${2:-}" ] && [ -n "${3:-}" ] || usage + gate "$2" "$3"; exit $? ;; + *) usage ;; +esac -- 2.53.0 From c30dd619844d0c147e6f2a9fe84c0eca7a90058c Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 24 Aug 2026 16:05:06 +0800 Subject: [PATCH 7/8] =?UTF-8?q?docs(README):=20=E8=A3=9C=E4=B8=8A=20model-?= =?UTF-8?q?tags.sh=20=E8=88=87=E8=83=BD=E5=8A=9B=E6=A8=99=E7=B1=A4?= =?UTF-8?q?=E9=96=98=E9=96=80=E7=9A=84=E8=AA=AA=E6=98=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5 (1M context) --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 79245c4..24d5644 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,8 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/jsc.git),安 | 工具 | 用途 | | --- | --- | | `tools/detect-clis.sh` | 列出已安裝的 AI CLI 與執行檔路徑(TSV:name / path / version;kiro 的執行檔為 `kiro-cli`) | -| `tools/model-config.sh` | 解析 SDLC 各階段的指定模型鏈(`get {stage}`、`list`、`resolve {stage}` 印出目前 CLI 可用的第一個模型);專案 `.jsc/models` 優先於 `$JSC_HOME/models.conf`,格式見 `references/model-tags.md` | +| `tools/model-config.sh` | 解析 SDLC 各階段的偏好模型鏈(`get {stage}`、`list`、`resolve {stage}` 印出目前 CLI 可用的第一個模型);專案 `.jsc/models` 優先於 `$JSC_HOME/models.conf`,格式見 `references/model-tags.md`。鏈只影響建議與偏好順序,不影響閘門放行 | +| `tools/model-tags.sh` | 解析 `references/model-tags.md` 的能力標籤與 SDLC 階段必要標籤(`dump`、`sync`、`stage {階段}`、`model {模型 id}`、`gate {階段} {模型 id}`);`sync` 寫出 `$JSC_HOME/model-tags.tsv` 供 `jsc-hooks` 的 sdlc-gate 讀取 | ## Skills 目錄 @@ -31,7 +32,7 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/jsc.git),安 ### `models` -讀取各已安裝 CLI 可使用的模型並加上能力標籤(`references/model-tags.md`),列出 SDLC 各階段的必要標籤,並用 `tools/model-config.sh` 解析各階段的指定模型鏈(專案 `.jsc/models` 優先於 `$JSC_HOME/models.conf`)。`jsc-sdlc` 閘門先看指定模型,沒有指定才退回標籤比對。 +讀取各已安裝 CLI 可使用的模型並加上能力標籤(`references/model-tags.md`),用 `tools/model-tags.sh sync` 把標籤表寫進 `$JSC_HOME/model-tags.tsv` 供 sdlc-gate 讀取,列出 SDLC 各階段的必要標籤(plan、analyze 需 `reasoning-max`;implement 需 `coding`;maintain 任意),並用 `tools/model-config.sh` 列出各階段的偏好模型鏈。`jsc-sdlc` 閘門一律以能力標籤判定,偏好鏈只用來建議切換目標。 ### `deploy` -- 2.53.0 From 30bb201c71f3d21389b89715f9dfc1bdacbf1277 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 24 Aug 2026 16:05:06 +0800 Subject: [PATCH 8/8] =?UTF-8?q?chore(plugin=20=E7=89=88=E6=9C=AC):=20?= =?UTF-8?q?=E4=B8=89=E4=BB=BD=20manifest=20=E5=8D=87=E7=89=88=E8=87=B3=200?= =?UTF-8?q?.0.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 5 (1M context) --- .claude-plugin/plugin.json | 2 +- .codex-plugin/plugin.json | 2 +- plugin.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 39d0035..c08411b 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-cli", - "version": "0.0.3", + "version": "0.0.4", "description": "CLI 偵測、模型能力標籤與技能庫批次部署", "skills": "./skills", "author": { diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index 4119def..142684f 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-cli", - "version": "0.0.3", + "version": "0.0.4", "description": "CLI 偵測、模型能力標籤與技能庫批次部署", "skills": "./skills" } diff --git a/plugin.json b/plugin.json index 77e45f0..f9beb0e 100644 --- a/plugin.json +++ b/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-cli", - "version": "0.0.3", + "version": "0.0.4", "description": "CLI 偵測、模型能力標籤與技能庫批次部署", "skills": "./skills/" } -- 2.53.0