From 3e3e1e588ff1828bdb74d1cae616a08da7813a9a Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 24 Aug 2026 14:48:15 +0800 Subject: [PATCH 1/2] =?UTF-8?q?fix(marketplace):=20=E8=A3=9C=E9=BD=8A=20ca?= =?UTF-8?q?nonical=20marketplace=20=E7=BC=BA=E5=B0=91=E7=9A=84=E6=AC=84?= =?UTF-8?q?=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 的 canonical marketplace,補上每個套件缺少的 description 與頂層 owner 欄位。 Why: 兩份 marketplace.json 與 canonical 版本不同步,缺少的欄位會讓套件說明無法顯示,也不符合治理格式。 How: 逐一比對 canonical marketplace.json,把每個套件的 description 補齊,並在頂層加上 owner 欄位,內容與 canonical 一致。 Who: 全庫共用的 infra 修正,影響所有安裝這份 marketplace 的 CLI。 --- .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 5ae36119606ac1c9b97e1602096ed041e633d057 Mon Sep 17 00:00:00 2001 From: Jeffery Date: Mon, 24 Aug 2026 14:48:30 +0800 Subject: [PATCH 2/2] =?UTF-8?q?feat(pkg-update):=20=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E7=89=88=E6=9C=AC=E6=94=B9=E5=AF=AB=E5=B7=A5=E5=85=B7=E4=B8=A6?= =?UTF-8?q?=E6=94=B9=E7=94=A8=E5=B7=A5=E5=85=B7=E5=91=BC=E5=8F=AB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit What: 新增 tools/apply-version.sh,依 ecosystem 改寫專案的版本來源檔(package.json / requirements.txt / pyproject.toml / *.csproj),把指定套件釘選到指定版本;skills/pkg-update/SKILL.md 的改寫步驟改成呼叫這支工具;README.md 補上工具說明;plugin.json、.claude-plugin/plugin.json、.codex-plugin/plugin.json 版本號由 0.0.1 升到 0.0.2。 Why: jsc-meta:skill-check 稽核發現 SKILL.md 用文字描述改寫邏輯,不符合「邏輯放工具、SKILL.md 只放步驟」的準則,需要把改寫邏輯抽成獨立工具。 How: 依 tools/list-packages.sh 已支援的四種生態(nodejs 的 package.json、python 的 requirements.txt 或 pyproject.toml、dotnet 的 *.csproj)撰寫對應的 parse 與 rewrite 邏輯,找不到檔案時 exit 3、找不到套件時 exit 4;SKILL.md 步驟改成呼叫 `tools/apply-version.sh {ecosystem} {project dir} {name} {version}`;三份 manifest 版本號同步升級。 Who: jsc-pkg 套件更新流程,影響 pkg-update 技能與所有安裝 jsc-pkg 的使用者。 --- .claude-plugin/plugin.json | 2 +- .codex-plugin/plugin.json | 2 +- README.md | 1 + plugin.json | 2 +- skills/pkg-update/SKILL.md | 2 +- tools/apply-version.sh | 130 +++++++++++++++++++++++++++++++++++++ 6 files changed, 135 insertions(+), 4 deletions(-) create mode 100755 tools/apply-version.sh diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index 5352321..f860340 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-pkg", - "version": "0.0.1", + "version": "0.0.2", "description": "套件批次更新(nodejs/python/dotnet),失敗還原", "skills": "./skills", "author": { diff --git a/.codex-plugin/plugin.json b/.codex-plugin/plugin.json index 7df50c9..96a1b43 100644 --- a/.codex-plugin/plugin.json +++ b/.codex-plugin/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-pkg", - "version": "0.0.1", + "version": "0.0.2", "description": "套件批次更新(nodejs/python/dotnet),失敗還原", "skills": "./skills" } diff --git a/README.md b/README.md index 8336161..6d92674 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ Marketplace 統一為 `jsc`(https://gitea.jsc.idv.tw/plugins/jsc.git),安 | --- | --- | | `tools/list-packages.sh` | 偵測專案類型並列出所有外部套件與目前版本(TSV:ecosystem / name / current) | | `tools/latest-version.sh` | `latest-version.sh ` 查最新穩定版(npm / pypi / nuget),查無 exit 4 | +| `tools/apply-version.sh` | `apply-version.sh ` 改寫版本來源檔案,把套件釘選到指定版本 | ## Skills 目錄 diff --git a/plugin.json b/plugin.json index 0bb0358..31cbb33 100644 --- a/plugin.json +++ b/plugin.json @@ -1,6 +1,6 @@ { "name": "jsc-pkg", - "version": "0.0.1", + "version": "0.0.2", "description": "套件批次更新(nodejs/python/dotnet),失敗還原", "skills": "./skills/" } diff --git a/skills/pkg-update/SKILL.md b/skills/pkg-update/SKILL.md index 03a5a3a..839d2a5 100644 --- a/skills/pkg-update/SKILL.md +++ b/skills/pkg-update/SKILL.md @@ -11,7 +11,7 @@ description: Update every external package of a project to its latest stable ver 2. Confirm the working tree is clean: stop and report when uncommitted changes exist, so the revert cannot destroy them. 3. Update ecosystem by ecosystem. This step **MUST run as a sub agent** (one sub agent per ecosystem): 1. For every package, run `tools/latest-version.sh {ecosystem} {name}` to get the latest stable version. - 2. Rewrite the version source file (package.json / requirements.txt / pyproject.toml / *.csproj). + 2. Run `tools/apply-version.sh {ecosystem} {project dir} {name} {version}` to rewrite the version source file (package.json / requirements.txt / pyproject.toml / *.csproj). 3. Re-resolve and install (`npm install` / `pip install -r` / `dotnet restore`). 4. Run build and tests: - nodejs: `npm run build` (if present) plus `npm test` (if present). diff --git a/tools/apply-version.sh b/tools/apply-version.sh new file mode 100755 index 0000000..c519d8c --- /dev/null +++ b/tools/apply-version.sh @@ -0,0 +1,130 @@ +#!/usr/bin/env sh +# apply-version.sh — 改寫版本來源檔案,把套件釘選到指定版本。 +# 用法: apply-version.sh +# ecosystem: nodejs | python | dotnet +# 對應檔案(與 list-packages.sh 相同的解析邏輯): +# nodejs → package.json(dependencies / devDependencies) +# python → requirements.txt(優先)或 pyproject.toml 的 [project] dependencies +# dotnet → *.csproj 的 PackageReference +# 找不到對應檔案 exit 3;檔案中找不到該套件 exit 4 +set -u +eco="${1:?ecosystem required (nodejs|python|dotnet)}" +DIR="${2:?project dir required}" +name="${3:?package name required}" +version="${4:?version required}" + +case "$eco" in + nodejs) + [ -f "$DIR/package.json" ] || { echo "package.json not found in $DIR" >&2; exit 3; } + python3 - "$DIR/package.json" "$name" "$version" <<'EOF' +import json,sys +path,name,version=sys.argv[1],sys.argv[2],sys.argv[3] +d=json.load(open(path,encoding="utf-8")) +found=False +for k in ("dependencies","devDependencies"): + if name in (d.get(k) or {}): + d[k][name]=version + found=True +if not found: + sys.exit(4) +with open(path,"w",encoding="utf-8") as f: + json.dump(d,f,indent=2,ensure_ascii=False) + f.write("\n") +EOF + rc=$? + [ "$rc" -eq 0 ] || { echo "$name not found in $DIR/package.json" >&2; exit "$rc"; } + ;; + + python) + if [ -f "$DIR/requirements.txt" ]; then + python3 - "$DIR/requirements.txt" "$name" "$version" <<'EOF' +import re,sys +path,name,version=sys.argv[1],sys.argv[2],sys.argv[3] +pat=re.compile(r"([A-Za-z0-9_.\-\[\]]+)\s*(?:(?:==|>=|<=|~=|!=|>|<)\s*([^,;\s]+))?") +lname=name.split("[")[0].lower() +lines=open(path,encoding="utf-8").readlines() +out=[] +found=False +for line in lines: + body=line.split("#")[0].strip() + m=pat.match(body) + if m and m.group(1).split("[")[0].lower()==lname: + out.append(f"{m.group(1)}=={version}\n") + found=True + else: + out.append(line) +if not found: + sys.exit(4) +open(path,"w",encoding="utf-8").writelines(out) +EOF + rc=$? + [ "$rc" -eq 0 ] || { echo "$name not found in $DIR/requirements.txt" >&2; exit "$rc"; } + elif [ -f "$DIR/pyproject.toml" ]; then + python3 - "$DIR/pyproject.toml" "$name" "$version" <<'EOF' +import re,sys +path,name,version=sys.argv[1],sys.argv[2],sys.argv[3] +pat=re.compile(r"([A-Za-z0-9_.\-\[\]]+)\s*(?:(?:==|>=|<=|~=|!=|>|<)\s*([^,;\s\"']+))?") +lname=name.split("[")[0].lower() +lines=open(path,encoding="utf-8").readlines() +out=[] +found=False +for line in lines: + m=re.search(r'"([^"]+)"', line) + if m: + dep=m.group(1) + dm=pat.match(dep) + if dm and dm.group(1).split("[")[0].lower()==lname: + newdep=f"{dm.group(1)}=={version}" + line=line.replace(dep,newdep,1) + found=True + out.append(line) +if not found: + sys.exit(4) +open(path,"w",encoding="utf-8").writelines(out) +EOF + rc=$? + [ "$rc" -eq 0 ] || { echo "$name not found in $DIR/pyproject.toml" >&2; exit "$rc"; } + else + echo "requirements.txt or pyproject.toml not found in $DIR" >&2 + exit 3 + fi + ;; + + dotnet) + projs=$(find "$DIR" -maxdepth 3 -name '*.csproj' 2>/dev/null) + [ -n "$projs" ] || { echo "*.csproj not found in $DIR" >&2; exit 3; } + found=0 + for proj in $projs; do + python3 - "$proj" "$name" "$version" <<'EOF' +import re,sys +path,name,version=sys.argv[1],sys.argv[2],sys.argv[3] +text=open(path,encoding="utf-8").read() +hit=[False] +def repl(m): + tag=m.group(0) + inc=re.search(r'Include="([^"]+)"',tag) + if inc and inc.group(1)==name: + hit[0]=True + if re.search(r'Version="[^"]*"',tag): + tag=re.sub(r'Version="[^"]*"', 'Version="%s"'%version, tag) + elif tag.endswith("/>"): + tag=tag[:-2]+' Version="%s" />'%version + else: + tag=tag[:-1]+' Version="%s">'%version + return tag +new_text=re.sub(r"]*>", repl, text) +if not hit[0]: + sys.exit(4) +open(path,"w",encoding="utf-8").write(new_text) +EOF + if [ $? -eq 0 ]; then + found=1 + break + fi + done + [ "$found" -eq 1 ] || { echo "PackageReference $name not found under $DIR" >&2; exit 4; } + ;; + + *) echo "unknown ecosystem: $eco" >&2; exit 2 ;; +esac +exit 0 -- 2.53.0