Files
code/README.md
T

295 lines
29 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# jsc — 跨 AI 助理程式碼工作流 Plugin
一個可同時被 **Claude Code、Codex、Antigravity、OpenCode、GitHub Copilot** 使用的 plugin,提供一組以 **程式碼工作流** 為核心的 skills
**Gitea AI review findings 修復、分類提交、push 與 PR 建立流程**、**Gitea 議題 TODO 彙整與逐項實作流程**、**C# / .NET NuGet 套件更新流程**、**Gitea 專案批次同步**,以及 **action / Dockerfile 標準化流程**
核心是以 [Agent Skills`SKILL.md`](https://agentskills.io) 標準撰寫的共用 skills(唯一真實來源放在 `skills/`),
搭配各助理各自的 plugin manifest,讓**同一個 repo** 可用各家**原生 plugin CLI** 安裝。
plugin 名為 `jsc`,在 Claude Code 與 Antigravity 中 skill 以 **`/jsc:` 前綴**呼叫(例如 `/jsc:code-issues`)。
---
## 前綴與呼叫方式
| 助理 | 安裝方式 | 呼叫 | `/jsc:` 前綴 |
| --- | --- | --- | --- |
| Claude Code | `claude plugin`marketplace | `/jsc:<name>` 或自動觸發 | ✅ |
| Codex | `codex plugin`marketplace | `$<name>``/skills` 選單 | ❌(用 `$name` |
| Antigravity | `agy plugin install` | `/jsc:<name>` 或自動觸發 | ✅ |
| OpenCode | skills 目錄(複製/clone) | 描述需求自動觸發 | ❌(依名稱) |
| GitHub Copilot | repository instructions`AGENTS.md` / `.github/copilot-instructions.md` | 描述需求並要求讀取對應 `SKILL.md` | ❌(依指示檔) |
> Codex 不支援自訂前綴(skill 以 `$name` 呼叫);OpenCode 與 Copilot 由模型依描述與指示檔觸發。三者皆**不強制**前綴。
---
## 目錄結構
同一個 repo 同時帶四種 manifest,彼此以路徑隔離、互不干擾;四家都讀同一份 `skills/`
```
code/
├── .claude-plugin/
│ ├── plugin.json # Claude 外掛定義(name: "jsc"
│ └── marketplace.json # Claude marketplacename: "code"source 指向本 repo
├── .codex-plugin/
│ └── plugin.json # Codex 外掛定義(name: "jsc"skills: "./skills"
├── .agents/plugins/
│ └── marketplace.json # Codex marketplacename: "code"url source 指向本 repo
├── plugin.json # Antigravity 外掛定義(name: "jsc"skills: "./skills/"
├── skills/ # ★ 唯一真實來源:所有 skills
│ ├── code-review-resolve/ # 解決 findings.json + 分類提交 + push + 發 PR
│ ├── code-issues/ # 彙整議題 TODO(影響範圍小→大)+ 逐項實作 + 留言進度
│ ├── code-nuget/ # C# / .NET NuGet 套件更新 + build 驗證
│ ├── code-sync/ # 依擁有者批次 clone/更新 Gitea 專案
│ ├── code-action-docker/ # action 容器化(Node 主程式)+ 串接 doc-funcs
│ ├── code-action-composite/ # composite action 標準化 + 串接 doc-funcs
│ ├── code-action-node/ # NodeJSaction 標準化(ncc 打包)+ 串接 doc-funcs
│ └── code-image/ # Dockerfile 整理成六步流程 + 串接 doc-funcs
├── AGENTS.md # 跨助理共用指引
└── README.md
```
---
## 安裝 / 更新 / 移除(各助理)
> 指令中的 repo 網址換成你的:`https://gitea.jsc.idv.tw/plugins/code.git`
>
> **Claude / Codex 從 git URL 安裝(會 clone 遠端),請先把本 repo `push` 到 gitea。**
> **Antigravity 的 `agy plugin install <url>` 目前只支援 github.com**gitea 請改用「clone + 本地路徑」(見 Antigravity 節)。
> 本機/離線:Claude 可用本地路徑加 marketplaceAntigravity 用本地路徑安裝。
### Claude Code
```bash
# 安裝
claude plugin marketplace add https://gitea.jsc.idv.tw/plugins/code.git
claude plugin install jsc@code
# 更新
claude plugin marketplace update code
claude plugin update jsc@code
# 移除
claude plugin uninstall jsc@code
claude plugin marketplace remove code
```
- 工作階段內 slash 版(等價):把 `claude plugin` 換成 `/plugin`
- 本機開發(免 push):`claude plugin marketplace add C:\Users\h3285\source\repos.plugins\code`(本地路徑)後再 install。
- **呼叫**`/jsc:<name>`(例 `/jsc:code-issues`)。
### Codex
```bash
# 安裝
codex plugin marketplace add https://gitea.jsc.idv.tw/plugins/code.git
codex plugin add jsc@code
# 更新(重新抓取 marketplace 的 git 快照)
codex plugin marketplace upgrade code
# 移除
codex plugin remove jsc@code
codex plugin marketplace remove code
```
- 安裝 token `jsc@code` = plugin 名(`.codex-plugin/plugin.json``name`@ marketplace 名(`.agents/plugins/marketplace.json``name`)。
- 本 repo 的 Codex marketplace 以 `url` 來源指向自己,故 Codex **一律從 gitea 安裝**(需先 push);安裝後重啟 Codex。
- **呼叫**`$<name>`(例 `$code-issues`),或用 `/skills` 選單。
### Antigravity`agy`
> `agy plugin install <url>` 目前**只支援 github.com**gitea 等自架 git 不支援 URL 安裝,請先 `git clone` 再用**本地路徑**安裝。
```bash
# 安裝:clone 後用本地路徑
git clone https://gitea.jsc.idv.tw/plugins/code.git ~/plugins/code
agy plugin install ~/plugins/code
# 更新(agy 無 update 子指令 → git pull 後重裝)
git -C ~/plugins/code pull
agy plugin uninstall jsc
agy plugin install ~/plugins/code
# 移除
agy plugin uninstall jsc
```
- 若把 skills 放到 GitHub,則可直接 `agy plugin install https://github.com/<owner>/<repo>`
- 其他:`agy plugin list``agy plugin enable jsc` / `disable jsc``agy plugin validate <path>`。安裝後重啟工作階段。
- **呼叫**`/jsc:<name>`(例 `/jsc:code-issues`)或依描述自動觸發。
### OpenCode
OpenCode 的「plugin」是 TypeScript/npm 套件,不適用於 skill 包;skills 改用**目錄安裝**。
OpenCode 會讀 `~/.config/opencode/skills/`(也會讀 `~/.claude/skills/``~/.agents/skills/`)。
```bash
# 安裝
git clone https://gitea.jsc.idv.tw/plugins/code.git ~/jsc-plugin
mkdir -p ~/.config/opencode/skills
cp -r ~/jsc-plugin/skills/* ~/.config/opencode/skills/
# 更新
git -C ~/jsc-plugin pull
cp -r ~/jsc-plugin/skills/* ~/.config/opencode/skills/
# 移除
rm -rf ~/.config/opencode/skills/{code-review-resolve,code-issues,code-nuget,code-sync,code-action-docker,code-action-composite,code-action-node,code-image}
```
> **Windows PowerShell**`cp -r A B` → `Copy-Item A B -Recurse -Force`、`rm -rf X` → `Remove-Item X -Recurse -Force`、`~` → `$HOME`。
- **呼叫**:直接描述需求,模型會依 skill 描述自動透過 skill 工具呼叫。
### GitHub Copilot
GitHub Copilot 目前不是這類 `SKILL.md` plugin 的原生執行環境;安裝方式是把本 repo 作為 repository instructions 的來源,讓 Copilot 讀 `AGENTS.md` 與對應 `SKILL.md`
```bash
# 安裝到目標 repo(把 code plugin vendored 進 .github/jsc-plugins/code
git clone https://gitea.jsc.idv.tw/plugins/code.git .github/jsc-plugins/code
cp .github/jsc-plugins/code/AGENTS.md AGENTS.md
# 更新
git -C .github/jsc-plugins/code pull
cp .github/jsc-plugins/code/AGENTS.md AGENTS.md
# 移除
git rm -r .github/jsc-plugins/code
# 若 AGENTS.md 只供此 plugin 使用,再移除;若已有其他內容,請只刪除 JSC code 相關段落
# git rm AGENTS.md
```
- 也可把既有 `.github/copilot-instructions.md` 改成引用 `AGENTS.md``.github/jsc-plugins/code/skills/<skill>/SKILL.md`
- **呼叫**:在 Copilot ChatCoding Agent 任務中描述需求,例如「請依 `.github/jsc-plugins/code/skills/code-issues/SKILL.md` 處理議題」。
---
## 用 CLI 直接執行 skillheadless / 一次性)
安裝好之後,不必進互動介面,一行指令就能叫某個 skill 跑完並印出結果:
| 助理 | headless 指令 | 執行 `code-issues` skill |
| --- | --- | --- |
| Claude Code | `claude -p "<prompt>"` | `claude -p "/jsc:code-issues --tool api --repo plugins/code --issues 12,15 --yes"` |
| Codex | `codex exec "<prompt>"` | `codex exec '$code-issues --tool api --repo plugins/code --issues 12,15 --yes'` |
| Antigravity | `agy -p "<prompt>"` | `agy -p "/jsc:code-issues --tool api --repo plugins/code --issues 12,15 --yes"` |
| OpenCode | `opencode run "<message>"` | `opencode run "讀 plugins/code 的 12、15 號議題,整理 TODO 並逐項實作、留言進度"` |
| GitHub Copilot | Copilot Chat / Coding Agent 任務 | `請依 .github/jsc-plugins/code/skills/code-issues/SKILL.md 處理 plugins/code 的 12、15 號議題` |
- Claude / Antigravity 支援 `/jsc:` 前綴,直接 `-p "/jsc:<name>"` 即可。
- Codex 以 `$<name>` 觸發;在 shell 請用**單引號**避免 `$` 被展開:`codex exec '$code-issues …'`
- OpenCode 與 Copilot 沒有前綴,用自然語言描述需求;Copilot 任務中請明確指出要讀取的 `SKILL.md`
- 帶引數就接在後面,例如 `claude -p "/jsc:code-issues --issues 12"``codex exec '$code-issues --issues 12'`
---
## Skills 目錄
> 此區塊列出本 plugin 內含的所有 skills(名稱/描述/使用方法)。
> 新增或修改 skill 後,請同步手動更新標記之間的內容。
<!-- JSC-SKILLS:START -->
### `code-review-resolve`
五階段:**(A Git 同步)** 先 `fetch`,務必檢查目前分支的線上分支是否存在;存在則留在目前分支更新到最新,不存在則依序切換到遠端 `develop``master` 並更新到最新,找不到後備分支則停止;pull 發生衝突時告知並嘗試安全解衝突;只有來源分支與 PR 目標分支相同時,才必須從該分支建立新的工作分支,後續修復、commit、push 與 PR `head` 都使用新分支。**(B 解決)** 讀工作目錄 `.gitea/ai-review/findings.json`Gitea AI review 產出的問題清單),依嚴重等級 **🔴 嚴重 → 🟠 高 → 🟡 中 → 🔵 低** 由高到低**逐條修復**程式碼問題或登記誤報(無法安全自動修復者標「待人工處理」不硬改),已解決或已登記誤報者才自 `findings.json` 移除。**(C 提交)** 分析工作區**所有**變更,依異動內容歸類為 `feat`/`fix`/`docs`/`style`/`refactor`/`perf`/`test`/`chore`/`revert`**每個 type 各自一個 commit**,訊息為「`type(範圍): 一句總結`」格式,**括號內的範圍須對應實際異動的功能/模組**(例 `feat(使用者登入): 新增帳密登入流程``perf(物件查詢): 改用批次查詢降低 DB 往返`,而非 `feat(新增功能)` 這類重述 type 的詞)。**(D 推送)** push 當前分支:先用**認證管理器**、失敗改用 **token**、再失敗**詢問使用者**。**(E 開 PR)** 用 token 透過 **Gitea API** 對目標分支發 PR(**目標分支不明必須詢問、不可猜測**),PR 描述可選**完整版**(重新分析 `git diff` 總結)/**簡單版**(逐條列 commit 訊息)/**使用者輸入**;完成後因內文可能含 gitea token,**提醒並清除 AI 助理對話內文**。除非遇到必要決策,否則依自動執行原則直接處理;token 一律由環境變數(如 `GITEA_TOKEN`)提供,全程不明文輸出。
參數:`[--findings <findings.json 路徑>] [--target <目標分支>] [--pr-desc <full|simple|自訂文字>] [--no-commit] [--no-pr] [--yes]`findings 省略時預設 `.gitea/ai-review/findings.json``--target` 省略且需要開 PR 時必問;`--no-commit` 只修復不提交;`--no-pr` 推送但不開 PR`--yes` 略過確認)。
- **Claude Code / Antigravity**`/jsc:code-review-resolve`,或 `/jsc:code-review-resolve --target develop --pr-desc full --yes``/jsc:code-review-resolve --no-pr``/jsc:code-review-resolve --no-commit`
- **Codex**`$code-review-resolve`,或 `$code-review-resolve --target develop --pr-desc simple --yes`,或用 `/skills` 選單
- **OpenCode**:描述需求(如「讀 .gitea/ai-review/findings.json 依嚴重度逐條修好、清空該檔,把工作區變更依 conventional commit 分類提交,push 後對 develop 發 PR(完整版描述)」)自動觸發
### `code-issues`
處理一或多個 Gitea 議題的實作流程,五階段:**(A 工具選擇)** 檢查 `tea``GITEA_TOKEN`,詢問要用 `tea` 或 Gitea REST API**已選定則跳過**);**(B 確認專案)** 詢問議題所在專案 owner/repo,可用目前 repo 的 origin 當預設(**已知則跳過**);**(C 選擇議題)** 列出開啟中議題後詢問要處理的議題編號,**一個或多個**(**已提供則跳過**);**(D 彙整 TODO)** 讀取議題描述與所有留言、彙整需求,盤點既有 checklist 後整理 TODO 列表並依**影響範圍由小到大**(XS→XL)排序,既有 TODO **不足以達成議題需求時補上新 TODO 並附加到議題描述**的 `## TODO` 區塊;**(E 逐項實作)** 依排序實作每項 TODO 並驗證,**每完成一項就勾選描述 checkbox 並留言進度到議題**,全部完成後留下總結留言。**全程不建立任何草稿檔**(中間成果一律保存到議題描述或留言),輸出與留言**盡量使用表格與 Mermaid 圖**commitpush/PR 不在自動範圍,由使用者另行指示。
參數:`[--tool <tea|api>] [--repo <owner/repo>] [--issues <編號,以逗號分隔>] [--host <gitea 主機>] [--yes]`(帶 `--tool``--repo``--issues` 時跳過對應詢問;`--yes` 略過一般確認)。
- **Claude Code / Antigravity**`/jsc:code-issues`,或 `/jsc:code-issues --tool api --repo plugins/code --issues 12,15 --yes`
- **Codex**`$code-issues`,或 `$code-issues --tool tea --repo plugins/code --issues 12`,或用 `/skills` 選單
- **OpenCode**:描述需求(如「讀 plugins/code 的 12、15 號議題,整理需求成 TODO 依影響範圍小到大排序、缺的補進議題描述,逐項實作、每完成一項留言進度」)自動觸發
### `code-nuget`
將 C# / .NET 專案的 NuGet 套件更新到最新可用版本。流程會先探測 `.sln` / `.slnx` / `.csproj``dotnet` 工具,執行 baseline `restore` / `build`,再**依專案分組列出所有 direct / transitive 套件**與目前版本、最新版本、參考來源。接著建立 `ProjectReference` graph:若當前專案所參考的上層專案已 direct reference 相同 NuGet 套件,且該套件會透過專案參考安全傳遞,便逐一移除重複 `PackageReference`;每移除一筆都立刻 `restore` / `build` 驗證,失敗即回復。最後逐一更新 direct 套件版本(支援 Central Package Management / `Directory.Packages.props`),**每更新一個套件就 restore/build 確認專案可正常編譯**;若最新版本編譯失敗,改從目前版本之後的最小可用版本逐版升級,直到遇到第一個編譯失敗版本,保留最後一個可編譯版本並記錄失敗點。
參數:`[<solution-or-project>] [--include-prerelease] [--no-dedupe] [--build <command>] [--yes]`(目標可為 `.sln``.slnx``.csproj``--include-prerelease` 允許 prerelease`--no-dedupe` 略過重複參考清理;`--build` 覆寫驗證指令;`--yes` 略過一般確認但不略過必要決策)。
- **Claude Code / Antigravity**`/jsc:code-nuget`,或 `/jsc:code-nuget MySolution.sln --include-prerelease`
- **Codex**`$code-nuget`,或 `$code-nuget src/App/App.csproj --build "dotnet build App.sln -c Release"`,或用 `/skills` 選單
- **OpenCode**:描述需求(如「把這個 .NET solution 的 NuGet 都更新到最新,先清掉 ProjectReference 已提供的重複套件,每更新一包就 build」)自動觸發
### `code-sync`
透過 `GITEA_TOKEN` 把使用者有讀取權限的 Gitea 專案批次 clone 到本機並依擁有者分類。流程會先確認 token、決定 gitea 主機與目標根目錄(預設家目錄),再以 token 分頁呼叫 `GET /api/v1/user/repos` 取回**所有有讀取權限**的專案、依 `owner` 分組(預設排除 fork);接著列出所有擁有者讓使用者**多選**(帶 `--owner` 則跳過詢問),列出選定擁有者底下的專案後,於 `<根目錄>/<擁有者>/<專案名>` 逐一處理:**不存在則 clone**HTTPStokenclone 後還原乾淨 origin;或 `--ssh`),**已存在則 `fetch` → 切到 develop(再退而 master)→ `pull --ff-only` 更新到最新**。全程唯讀(不 push、不改遠端),工作區有未提交變更的專案會略過而非強制覆蓋;token 一律由環境變數提供、不寫死也不印出。
參數:`[--target-dir <根目錄>] [--owner <擁有者,以逗號分隔>] [--host <gitea 主機>] [--include-forks] [--ssh] [--yes]`(根目錄預設家目錄;`--owner` 預先指定擁有者並跳過多選;`--host` 指定 gitea 主機;`--include-forks` 納入 fork`--ssh` 改用 SSH clone`--yes` 略過一般確認但不略過擁有者多選)。
- **Claude Code / Antigravity**`/jsc:code-sync`,或 `/jsc:code-sync --owner plugins --target-dir ~/work``/jsc:code-sync --include-forks --ssh`
- **Codex**`$code-sync`,或 `$code-sync --owner plugins --target-dir ~/work`,或用 `/skills` 選單
- **OpenCode**:描述需求(如「用 GITEA_TOKEN 取得我有讀取權限的所有 Gitea 專案,依擁有者分組讓我多選,把選定擁有者的專案 clone 到家目錄;已存在的切到 develop/master 更新到最新」)自動觸發
### `code-action-docker`
把 GiteaGitHub「Docker 容器 action」專案標準化為 **Node 主程式+容器化**,再串接文件化流程。五階段:(A) 找出 action 專案、讀 `action.yml``action.yaml``name``description`、判斷主程式語言;(B) 主程式**非 Node 則保守改寫為 Node**(高風險,先以 AskUserQuestion 確認,保留對外行為),並把**主程式依賴鏈**的 `.js` 集中到 **`src/`**(工具設定檔與測試目錄不搬)、同步更新 `require``import` 路徑、`package.json``action.yml``runs` 只設 `using: docker``image: Dockerfile`**不設相對路徑的 `entrypoint`**,入口由 Dockerfile 的絕對路徑 `ENTRYPOINT` 決定);(C) 產生 `entrypoint.sh`**啟動 node 前先輸出 action 名稱/用途/更新時間**Asia/Taipei `yyyy/MM/dd HH:mm:ss`)再 `exec node`;(D) 依**六步流程**(參數處理 → 安裝套件 → 複製檔案 → 執行程序 → 縮小映像檔 → 設定入口)產生**使用最新 LTS node 版本(固定 major tag**的 `Dockerfile`**每步內容依主程式(`src/`)實作量身決定**(先盤點相依/是否需 build/OS 層相依/入口檔並產生 `.dockerignore`,再填對應步驟,用不到的不硬塞),預設 build 基底為當前 LTS(如 `node:22`)、runtime 對應 `-slim`(如 `node:22-slim`),**多階段建置逐項明列必要產物**(不整包 COPY)縮小映像,`ENTRYPOINT` 指向 `entrypoint.sh`(絕對路徑);(E) 對整個專案**完整執行 `/jsc:doc-funcs`**function 文件、`entrypoint.sh``Dockerfile` 逐行註解、重建 README)。開發中需要新參數時依**參數來源優先序**處理:優先取用 runner 注入容器的 `GITHUB_*``GITEA_*` 執行期環境變數(即 `gitea.*``github.*` context 的同源資訊;docker action 的 `action.yml` 幾乎只有 `inputs``env` context 可用),無法取得才經使用者同意**新增 `inputs`**(容器內讀 `INPUT_*`);`secrets``vars` context 在 docker action 內**一律視為不可用**(GitHub 官方文件僅記載 `inputs` context、runner 不注入 secretsGitea 行為無保證),需要時宣告為 `inputs` 由呼叫端 workflow 以 `with:` 傳入,未經同意不擅改 `inputs``outputs` 契約。目錄沒有 `action.yml` 時可走**問答式從零建立**(收集名稱/輸入輸出/執行目標後產生 docker `action.yml``src/index.js` 骨架,再接後續階段)。skill 各檔的「更新時間」於最終階段(doc-funcs 完成後)**統一同步為同一時間戳**。
參數:`[--action-dir <action 根目錄>] [--node-version <node tag>] [--main <主程式檔>]`(根目錄預設目前工作目錄;node 版本預設最新;主程式自動判斷)。
- **Claude Code / Antigravity**`/jsc:code-action-docker`,或 `/jsc:code-action-docker --action-dir ~/work/my-action --node-version 22`
- **Codex**`$code-action-docker`,或 `$code-action-docker --action-dir ~/work/my-action`,或用 `/skills` 選單
- **OpenCode**:描述需求(如「把這個 action 主程式改成 node、主程式相關 js 收進 src/,產生會先輸出 action 名稱/用途/更新時間再啟動 node 的 entrypoint.sh、用最新 LTS node 版本的 Dockerfile,最後跑 doc-funcs 補文件並重建 README」)自動觸發
### `code-action-composite`
把 GiteaGitHub「composite action」專案標準化,再串接文件化流程。四階段:(A) 找出 action 專案、讀 `action.yml``action.yaml``name``description``runs`、判斷是否為 composite(B) **已是 composite 則保留既有 `steps`**,非 compositeJSDocker)則**保守確認後對齊**為 composite(高風險先以 AskUserQuestion 確認;JS action 轉換須補 `INPUT_*` env 映射與 `outputs.value` 轉接以保留 `inputs``outputs` 契約;Docker 行為無法等價塞入時標「需人工確認」並建議改用 `code-action-docker`);(C) 在 `runs.steps` **最前面注入啟動橫幅 step**,輸出 action **名稱/用途/更新時間**Asia/Taipei `yyyy/MM/dd HH:mm:ss`,固定字串),並於 `action.yml` 開頭補用途/更新時間註解區塊(既有橫幅 step 則更新而非重插);(D) 對整個專案**完整執行 `/jsc:doc-funcs`**`action.yml` 與被引用腳本逐行註解、function 文件、重建 README)。開發中需要新參數時依**參數來源優先序**處理:優先取用 `${{ gitea.* }}``${{ github.* }}` contextGitea 中兩者互為別名,composite step 內可直接使用、`run` 腳本內可讀同源 `$GITHUB_*` 環境變數),無法取得才經使用者同意**新增 `inputs`**`secrets``vars` context 在 composite action 內**一律視為不可用**GitHub 官方明文限制;Gitea act_runner 未嚴格檢查 context 可用性、行為無保證),需要時宣告為 `inputs` 由呼叫端 workflow 以 `with:` 傳入,未經同意不擅改 `inputs``outputs` 契約。目錄沒有 `action.yml` 時可走**問答式從零建立**(收集名稱/輸入輸出/執行目標後產生 composite `action.yml` 並實作 steps,再接後續階段)。skill 各檔的「更新時間」於最終階段(doc-funcs 完成後)**統一同步為同一時間戳**。
參數:`[--action-dir <action 根目錄>] [--manifest <action.yml 路徑>]`(根目錄預設目前工作目錄;manifest 自動尋找 `action.yml``action.yaml`)。
- **Claude Code / Antigravity**`/jsc:code-action-composite`,或 `/jsc:code-action-composite --action-dir ~/work/my-action`
- **Codex**`$code-action-composite`,或 `$code-action-composite --action-dir ~/work/my-action`,或用 `/skills` 選單
- **OpenCode**:描述需求(如「把這個 composite action 標準化,在 steps 最前面加一個會輸出 action 名稱/用途/更新時間的 step,最後跑 doc-funcs 補文件並重建 README」)自動觸發
### `code-action-node`
把 GiteaGitHub「NodeJavaScriptaction」專案標準化,再串接文件化流程。node action 由 **runner 內建 Node 直接執行 `runs.main`**(不需 Docker、啟動比 docker action 快),但 **runner 不會自動 `npm install`**——這是與 docker/composite 最大的差異。五階段:(A) 找出 action 專案、讀 `action.yml``action.yaml``name``description`、判斷主程式語言(無 manifest 可**問答式從零建立**);(B) 主程式**非 Node 則保守改寫為 Node**(高風險,先以 AskUserQuestion 確認,保留對外行為),並把**主程式依賴鏈**的 `.js` 集中到 **`src/`**(工具設定檔與測試目錄不搬)、同步更新 `require``import` 路徑、`package.json``action.yml`(C) 對齊 `runs` 為 node action`using: node24` + `main``--node-version` 可覆寫、runner 太舊退 `node20`),**`outputs` 去除 `value`**node 只需 `description`,值於執行時寫入 `$GITHUB_OUTPUT`)、**`inputs` 由 runner 自動注入 `INPUT_*`**(不像 composite 需手動映射),並在**主程式入口最前面**以 `console.log` 輸出 action 名稱/用途/更新時間(Asia/Taipei `yyyy/MM/dd HH:mm:ss`node action 無 `entrypoint.sh`,橫幅改在 JS 輸出);(D) 相依處理——**零相依**則 `main` 直接指 `src/index.js`**有相依**則以 [`@vercel/ncc`](https://github.com/vercel/ncc) 打包成 `dist/index.js``main` 改指 `dist/index.js` 並**把 `dist/` commit 進 repo**(確認 `.gitignore` 未忽略);(E) 對整個專案**完整執行 `/jsc:doc-funcs`**function 文件、`src/` 主程式與 `action.yml` 註解、重建 README)。開發中需要新參數時依**參數來源優先序**處理:主程式優先取 runner 注入的 `GITHUB_*``GITEA_*` 執行期環境變數,既有 `inputs``process.env.INPUT_*`(或 `core.getInput`)取用,無法取得才經使用者同意**新增 `inputs`**`secrets``vars` **一律視為不可用**,需要時宣告為 `inputs` 由呼叫端 workflow 以 `with:` 傳入,未經同意不擅改 `inputs``outputs` 契約。skill 各檔的「更新時間」於最終階段(doc-funcs 完成後)**統一同步為同一時間戳**。
參數:`[--action-dir <action 根目錄>] [--node-version <node runtime>] [--main <主程式檔>]`(根目錄預設目前工作目錄;node 版本預設 `node24`;主程式自動判斷)。
- **Claude Code / Antigravity**`/jsc:code-action-node`,或 `/jsc:code-action-node --action-dir ~/work/my-action --node-version node24`
- **Codex**`$code-action-node`,或 `$code-action-node --action-dir ~/work/my-action`,或用 `/skills` 選單
- **OpenCode**:描述需求(如「把這個 action 主程式改成 node、主程式相關 js 收進 src/,對齊 action.yml 為 node action、在主程式最前面輸出 action 名稱/用途/更新時間,有相依就用 ncc 打包成 dist 並 commit,最後跑 doc-funcs 補文件並重建 README」)自動觸發
### `code-image`
把專案既有的 `Dockerfile` **整理成固定六步流程**,再串接文件化流程。三階段:(A) 找出專案根目錄、定位目標 `Dockerfile`(找不到則詢問、**不臆造**;要產生全新 action 容器請改用 `code-action-docker`),讀現有指令、判斷語言/生態與既有 base image/建置流程;(B) 在**保留建置行為**前提下,把指令重整/歸位為**六步流程**(參數處理 → 安裝套件 → 複製檔案 → 執行程序 → 縮小映像檔 → 設定入口):可調參數集中於檔首 `ARG`、相依描述先 `COPY` 以利 layer 快取、**多階段建置**讓 runtime 改用較小基底(`*-slim``*-alpine``distroless` 等)只帶執行所需產物;`ENTRYPOINT``CMD``EXPOSE``ENV` 等對外契約不動,**無法保證等價的重整先以 AskUserQuestion 確認**(可選最小重排或只補註解);(C) 對整個專案**完整執行 `/jsc:doc-funcs`**`Dockerfile` 等指令檔逐行註解、function 文件、重建 README)。
參數:`[--project-dir <專案根目錄>] [--dockerfile <Dockerfile 路徑>] [--yes]`(專案根目錄預設目前工作目錄;Dockerfile 自動定位、多個時詢問;`--yes` 略過一般確認,但「重整無法保證行為等價」與 doc-funcs 的實作詢問仍會中斷)。
- **Claude Code / Antigravity**`/jsc:code-image`,或 `/jsc:code-image --project-dir ~/work/my-app --dockerfile build/Dockerfile`
- **Codex**`$code-image`,或 `$code-image --dockerfile docker/Dockerfile`,或用 `/skills` 選單
- **OpenCode**:描述需求(如「把這個專案的 Dockerfile 整理成參數處理→安裝套件→複製檔案→執行程序→縮小映像檔→設定入口六步、用多階段建置縮小映像,最後跑 doc-funcs 補文件並重建 README」)自動觸發
<!-- JSC-SKILLS:END -->
---
## 新增一個 skill
1. 複製既有 skill 作範本:`cp -r skills/code-issues skills/<your-skill-name>`
2. 編輯 `skills/<your-skill-name>/SKILL.md` 的 frontmatter
- `name`:小寫、數字、連字號(`-`),最長 64 字元。**這就是 Claude Code / Antigravity 的 `/jsc:<name>`**。
- `description`:第三人稱,寫清楚「何時用、何時不用」與觸發關鍵字 — 這是各助理自動載入的唯一依據。
3. 在內文寫下 skill 的具體步驟。
4. 手動把這個 skill 補進上方「Skills 目錄」區塊。
5. **bump 版本並 push**:四家都以 git 內容/版本判斷更新,請把 `.claude-plugin/plugin.json``.codex-plugin/plugin.json``plugin.json` 三個 manifest 的 `version` 一起 bumpcommit 後 push 到 gitea。
6. 讓各助理更新:
- Claude`claude plugin update jsc@code`
- Codex`codex plugin marketplace upgrade code`
- Antigravity`git -C ~/jsc-plugin pull && agy plugin uninstall jsc && agy plugin install ~/jsc-plugin`
- OpenCode`git pull` 後重新複製 `skills/`
- GitHub Copilot:更新 `.github/jsc-plugins/code` 後同步 `AGENTS.md``.github/copilot-instructions.md`