chore(marketplace 正本): 正本移至 plugins/meta(升版 0.0.3) #5
@@ -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 追蹤)"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@
|
||||
"source": "url",
|
||||
"url": "https://gitea.jsc.idv.tw/plugins/meta.git"
|
||||
},
|
||||
"description": "技能組自我管理:新建/更新/刪除技能與技能準則"
|
||||
"description": "技能組自我管理:新建、更新、刪除技能與技能準則"
|
||||
},
|
||||
{
|
||||
"name": "jsc-pkg",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jsc-pkg",
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.2",
|
||||
"description": "套件批次更新(nodejs/python/dotnet),失敗還原",
|
||||
"skills": "./skills",
|
||||
"author": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jsc-pkg",
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.2",
|
||||
"description": "套件批次更新(nodejs/python/dotnet),失敗還原",
|
||||
"skills": "./skills"
|
||||
}
|
||||
|
||||
@@ -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 <ecosystem> <name>` 查最新穩定版(npm / pypi / nuget),查無 exit 4 |
|
||||
| `tools/apply-version.sh` | `apply-version.sh <ecosystem> <project dir> <name> <version>` 改寫版本來源檔案,把套件釘選到指定版本 |
|
||||
|
||||
## Skills 目錄
|
||||
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "jsc-pkg",
|
||||
"version": "0.0.1",
|
||||
"version": "0.0.2",
|
||||
"description": "套件批次更新(nodejs/python/dotnet),失敗還原",
|
||||
"skills": "./skills/"
|
||||
}
|
||||
|
||||
@@ -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).
|
||||
|
||||
Executable
+130
@@ -0,0 +1,130 @@
|
||||
#!/usr/bin/env sh
|
||||
# apply-version.sh — 改寫版本來源檔案,把套件釘選到指定版本。
|
||||
# 用法: apply-version.sh <ecosystem> <project-dir> <name> <version>
|
||||
# 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"<PackageReference\b[^>]*>", 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
|
||||
Reference in New Issue
Block a user