Files
shared/skills/plugins-install/SKILL.md
T

213 lines
12 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.
---
name: plugins-install
description: 一次把 JSC 的四個 pluginjsc-codejsc-docjsc-personajsc-shared)安裝或更新到一個或多個 AI 助理,可同時處理 Claude Code、Codex、GitHub Copilot CLI、Antigravity 四家原生 plugin CLI 與 OpenCode(複製 skills 目錄);沒指定時偵測本機裝了哪些 CLI 並讓使用者多選,每個 plugin 先判斷已安裝或未安裝,未安裝就安裝、已安裝就更新到最新,最後以「助理 × plugin」的表格回報結果與版本。當使用者說要安裝所有 jsc plugin、一次更新全部 skill 套件、把 codedocpersonashared 都裝起來、要同時更新好幾個 CLI、換新機器要把 plugin 都補齊、或問怎麼一次更新所有 plugin 時觸發。不適用於:移除 plugin(用 /jsc-shared:plugins-uninstall)、只處理單一 plugin(直接照該 plugin README 的安裝章節)、安裝非 JSC 的第三方 plugin。
argument-hint: "[--assistant <助理清單,逗號分隔,或 all>] [--plugins code,doc,persona,shared] [--host <gitea 主機>] [--clone-dir <目錄>] [--yes]"
---
# plugins-install — 一次安裝/更新所有 JSC plugin
四階段 skill:先**決定助理與目標清單**,再**逐一判斷已安裝或未安裝**,接著**安裝或更新**,最後**回報結果並提醒重啟工作階段**。
| 階段 | 動作 |
| --- | --- |
| A. 前置設定 | 決定要操作哪些助理(`--assistant` 可帶多個或 all/偵測本機有哪些 CLI/多個就讓使用者多選)→ 決定 gitea 主機 → 決定 plugin 清單(預設 code、doc、persona、shared |
| B. 現況盤點 | 對每個 plugin 查詢 marketplace 與 plugin 是否已存在,決定「安裝」或「更新」 |
| C. 安裝/更新 | 依助理的原生指令逐一執行;Antigravity 與 OpenCode 走 clone/複製路徑 |
| D. 回報 | 以表格列出每個 plugin 的動作、結果與版本,並提醒重啟工作階段 |
---
## 共用規範(shared plugin,必要前置)
執行本 skill 前,先以 Skill 工具載入下列共用規範並全程遵守:
- `/jsc-shared:spec-output`:繁體中文(台灣用語)、UTF-8(不含 BOM)無亂碼、表格呈現。
- `/jsc-shared:spec-execution`:自動執行原則(必要決策才中斷)、不臆測/需人工確認。
- `/jsc-shared:spec-git-safety`AntigravityOpenCode 路徑會動到本機 clone,**工作區有未提交變更時不得強制更新**。
本 skill 特有補充:
- **不移除任何東西**。更新時就算需要「先移除再安裝」(Antigravity 沒有 update 子指令),也只針對該 plugin 自己,且移除後必須立刻重裝成功。
- **必要決策**(會中斷詢問):無法判斷目前是哪個助理、指定的助理 CLI 不存在、本機 clone 有未提交變更、安裝失敗且原因需要使用者裁示。
- **可處理 `jsc-shared` 自己**:但更新目前正在執行本 skill 的助理時,將 `shared` 放在該助理的最後處理,並在回報中提醒重啟工作階段。
---
## 參數
- `--assistant <清單>`:要操作的助理,**可以多個**,以逗號分隔(`claude,codex,copilot,agy,opencode`),或用 `all` 代表本機找得到的全部。**省略時**依階段 A1 判斷(只有一個就直接用,多個就讓使用者多選)。
- `--plugins code,doc,persona,shared`:要處理的 plugin(以逗號分隔,用 repo 短名)。**省略時預設四個全做**。
- `--host <gitea 主機>`gitea 主機,省略時預設 `gitea.jsc.idv.tw`
- `--clone-dir <目錄>`AntigravityOpenCode 的本機 clone 根目錄,**省略時預設 `~/plugins`**。
- `--yes`:全自動,不做確認式詢問(必要決策仍會中斷)。
---
## plugin 對照表(安裝識別的唯一依據)
| repo 短名 | plugin 名 | marketplace 名 | 安裝 token | repo 網址 |
| --- | --- | --- | --- | --- |
| `code` | `jsc-code` | `code` | `jsc-code@code` | `https://<host>/plugins/code.git` |
| `doc` | `jsc-doc` | `doc` | `jsc-doc@doc` | `https://<host>/plugins/doc.git` |
| `persona` | `jsc-persona` | `persona` | `jsc-persona@persona` | `https://<host>/plugins/persona.git` |
| `shared` | `jsc-shared` | `shared` | `jsc-shared@shared` | `https://<host>/plugins/shared.git` |
> 指令一律照這張表帶,不要用 repo 短名去猜;若 CLI 回報 marketplace 宣告名稱與表格不一致,先記錄差異,再用 CLI 實際接受的名稱完成同一個 plugin。
各 plugin 帶入的 skill 目錄(OpenCode 路徑會用到):
| repo 短名 | skill 目錄 |
| --- | --- |
| `code` | `action-composite``action-docker``action-node``image``issues``nuget``review-resolve``sync` |
| `doc` | `docker``funcs``issues-analyze``issues-analyze-to-file``issues-sync``worklog` |
| `persona` | `persona-anime``persona-chat``persona-create``persona-icon``persona-invite``persona-memory``persona-relation``persona-sleep``persona-status``persona-sync``persona-therapist``persona-transfer` |
| `shared` | `plugins-install``plugins-uninstall``spec-action-params``spec-doc-funcs-handoff``spec-dockerfile``spec-execution``spec-git-safety``spec-gitea``spec-output``spec-plugin-version``spec-project-board``spec-time-log` |
---
## 階段 A:前置設定
### A1. 決定助理(可以一次多個)
`--assistant` 收的是**清單**,不是單一值:`--assistant claude,codex,copilot`、或 `--assistant all`
最終得到的是一組助理,後面每個階段都對**這組的每一個**各跑一遍。
依序判斷,**第一個成立的就採用**:
1. 有帶 `--assistant` → 照它。`all` 代表「本機找得到的全部」(等同下面第 3 點的偵測結果)。
2. 沒帶 → 逐一檢查哪些 CLI 存在(`command -v claude codex copilot agy opencode`):
- 找到 **1 個** → 直接用它。
- 找到 **多個** → 列出來讓使用者**多選**(預設全選)。帶 `--yes` 時不問,直接全做。
3. 一個都沒有 → 回報「找不到任何支援的助理 CLI」並停止。
> 目前正在執行本 skill 的那個助理,如果也在清單裡,**放到最後處理**;該助理內若包含 `shared`,再把 `shared` 放在該助理的最後一個 plugin 處理——更新它自己會需要重啟工作階段。
### A2. 決定 gitea 主機與 clone 根目錄
- 主機:`--host``$GITEA_HOST` → 預設 `gitea.jsc.idv.tw`
- clone 根目錄(只有 `agy``opencode` 用得到):`--clone-dir` → 預設 `~/plugins`。目錄不存在就建立。
### A3. 決定 plugin 清單
`--plugins` 指定則照它,否則 `code,doc,persona,shared` 四個都做。清單中出現對照表以外的名稱 → 回報並略過該項,其餘照做。
---
## 階段 B:現況盤點
對清單中每個 plugin,先查現況再決定動作(**先查再做,不要盲目重裝**):
| 助理 | 查詢指令 | 判定 |
| --- | --- | --- |
| Claude Code | `claude plugin marketplace list``claude plugin list` | 兩者都有 → 更新;缺 marketplace → 先 add;缺 plugin → install |
| Codex | `codex plugin marketplace list``codex plugin list` | 同上 |
| GitHub Copilot CLI | `copilot plugin marketplace list``copilot plugin list` | 同上 |
| Antigravity | `agy plugin list`,並看 `<clone-dir>/<repo>` 是否存在 | 目錄在且已安裝 → 更新;否則安裝 |
| OpenCode | 看 `~/.config/opencode/skills/` 底下是否已有該 plugin 的 skill 目錄 | 有 → 更新(重新複製;注意不是覆蓋,見階段 C);沒有 → 安裝 |
盤點的迴圈是**助理 × plugin**:階段 A1 選定的每個助理,都要對每個 plugin 各判定一次,結果分開記。
指令不存在或子指令不被支援(舊版 CLI)時,**不要中斷整批**:記下那一格為「跳過(CLI 不支援)」,繼續下一個,最後在階段 D 一起回報。同一個助理連續失敗(例如 CLI 存在但每個子指令都不支援)就整個助理標記為跳過,換下一個助理,不要卡住整批。
---
## 階段 C:安裝/更新
以下 `<url>``<plugin>``<marketplace>``<token>` 一律取自對照表。
### Claude Code
```bash
# 安裝(marketplace 尚未加入)
claude plugin marketplace add <url>
claude plugin install <token>
# 更新(已安裝)
claude plugin marketplace update <marketplace>
claude plugin update <token>
```
### Codex
```bash
# 安裝
codex plugin marketplace add <url>
codex plugin add <token>
# 更新(重新抓取 marketplace 的 git 快照)
codex plugin marketplace upgrade <marketplace>
```
### GitHub Copilot CLI
```bash
# 安裝
copilot plugin marketplace add <url>
copilot plugin install <token>
# 更新
copilot plugin marketplace update <marketplace>
copilot plugin update <token>
```
### Antigravity`agy`
> `agy plugin install <url>` 目前只支援 github.comgitea 一律走「clone + 本地路徑」。`agy` 沒有 update 子指令,更新=`git pull` 後重裝。
```bash
# 取得或更新本機 clone(目錄已存在就 pull,不要無條件 clone)
if [ -d "<clone-dir>/<repo>/.git" ]; then
git -C <clone-dir>/<repo> pull --ff-only
else
git clone <url> <clone-dir>/<repo>
fi
# 安裝
agy plugin install <clone-dir>/<repo>
# 更新(agy 沒有 update 子指令,只能重裝)
agy plugin uninstall <plugin>
agy plugin install <clone-dir>/<repo>
```
- **不可無條件 `git clone`**:clone 目錄已經存在(很常見——開發者自己就 clone 在那裡)時,`git clone` 會以 `fatal: destination path already exists` 中止。階段 B 的判定只看「有沒有裝進 agy」,所以「目錄在、但 agy 沒裝」這個狀態會落進安裝分支,必須靠上面的 `if` 擋掉。
- `git pull --ff-only` 失敗(本機有未提交變更或分支分岔)→ **停在該 plugin**,回報現況讓使用者裁示,不得 `reset --hard``clean`,其餘 plugin 照常繼續。
- **先確認 clone 在哪個分支**:`git -C <clone-dir>/<repo> branch --show-current`。若不是發佈分支(`master`),代表要裝進去的是未合併的內容——先告訴使用者,由他決定要換分支還是照裝。預設的 `~/plugins` 很可能就是開發者自己的工作區。
### OpenCode
> OpenCode 的 plugin 是 npm 套件,不適用 skill 包;改用目錄安裝。OpenCode 只會帶入 `skills/`,安裝前要先告知使用者。
```bash
# 取得或更新本機 clone(同 Antigravity,不要無條件 clone
if [ -d "<clone-dir>/<repo>/.git" ]; then
git -C <clone-dir>/<repo> pull --ff-only
else
git clone <url> <clone-dir>/<repo>
fi
mkdir -p ~/.config/opencode/skills
cp -r <clone-dir>/<repo>/skills/* ~/.config/opencode/skills/
```
> **Windows PowerShell**`cp -r A B` → `Copy-Item A B -Recurse -Force`、`~` → `$HOME`。
- **`cp -r` 不是覆蓋,是合併**:同名檔案會更新,但**上游已經刪掉的檔案會原地留著**。所以 skill 改名或移除之後,OpenCode 端會同時留著新舊兩份。要乾淨更新就先刪該 plugin 帶入的目錄再複製一次(刪法見 `/jsc-shared:plugins-uninstall` 的 OpenCode 段)。回報時不要講「已覆蓋」,講「已複製,舊檔可能殘留」。
---
## 階段 D:回報
以表格回報,**一個「助理 × plugin」一列**:
| 助理 | plugin | 動作 | 結果 | 版本 |
| --- | --- | --- | --- | --- |
| Claude Code | `jsc-code` | 安裝/更新/跳過 | ✅ 成功/⚠ 需處理/❌ 失敗 | 例 `0.0.2` |
| Codex | `jsc-code` | 更新 | ✅ 成功 | 未知 |
只處理一個助理時可以省掉「助理」欄。**處理多個時一定要有**,否則使用者看不出哪一格出問題。
- 版本取自該 plugin 的 `plugin.json`。**只有 Antigravity 與 OpenCode 拿得到**(它們有本機 clone 可讀);ClaudeCodexCopilot 把 plugin 放在各自 CLI 自管的快取目錄,除非該 CLI 的 `plugin list` 印得出版本,否則一律寫「未知」,不要去猜。
- 有任何一列不是 ✅ → 在表格下方逐項說明原因與建議動作。
- 最後固定提醒:**安裝或更新後要重啟工作階段**才會生效;`jsc-persona` 在 Claude Code 還要用 `/hooks` 確認六個 hook 都在。