一次處理多個助理(使用者要求): - `--assistant` 從單一值改成清單,支援 `claude,codex,copilot` 與 `all`。 - 沒帶參數時偵測本機有哪些 CLI:只有一個就直接用,多個就讓使用者多選 (安裝預設全選;移除是不可逆的,預設不全選)。 - 盤點與執行的迴圈改成「助理 × plugin」,回報表格加上「助理」欄。 - 正在執行本 skill 的那個助理排到最後處理——更新它要重啟工作階段, 而移除它自己的 jsc-generic 之後,後面的助理就處理不到了。 闇影劍審 PR #30 找到的問題: - Antigravity 與 OpenCode 的安裝分支無條件 `git clone`,clone 目錄已存在時 會 fatal 中止(開發者自己就 clone 在預設的 ~/plugins)。改成先判斷 `.git` 存在與否,已存在就 `pull --ff-only`。 - 新增「先確認 clone 在哪個分支」:預設路徑很可能是開發者的工作區, 停在 develop 時裝進去的是未合併內容,要先告知使用者。 - OpenCode 的移除指令用 `{a,b,c}` brace expansion,有三種會靜默失效的情況 (逗號後有空格、單一元素、dash/sh 不支援),全都是「什麼都沒刪但結束碼 0」。 改成從本機 clone 的 skills/ 推導清單跑迴圈,退路是一行一個 rm。 - 硬編碼的 skill 目錄清單只是快照,plugin 新增 skill 後會殘留。改為優先從 clone 推導,用表時要註明「清單可能不完整」。 - `cp -r` 不是覆蓋是合併,上游刪掉的檔案會留著。移除「覆蓋複製」這個 不成立的說法。 - 階段 D 的版本欄只有 Antigravity 與 OpenCode 拿得到,其餘三家寫「未知」。 依 spec-plugin-version 升版 0.1.7(master 現行 0.1.6)。
11 KiB
name, description, argument-hint
| name | description | argument-hint |
|---|---|---|
| plugins-uninstall | 一次把 JSC 的四個 plugin(jsc-code/jsc-doc/jsc-persona/jsc-generic)從一個或多個 AI 助理移除,可同時處理 Claude Code、Codex、GitHub Copilot CLI、Antigravity 四家原生 plugin CLI 與 OpenCode(刪除先前複製進去的 skill 目錄);沒指定時偵測本機裝了哪些 CLI 並讓使用者多選;移除順序固定把 jsc-generic 放到最後(本 skill 就住在裡面,移除後即失效),並在動手前列出將被移除的項目與會受影響的本機資料讓使用者確認。當使用者說要移除所有 jsc plugin、把 skill 套件整組解除安裝、清掉 code/doc/persona/generic、重灌前先卸載、要同時從好幾個 CLI 移除、或問怎麼一次移除全部 plugin 時觸發。不適用於:安裝或更新(用 /jsc-generic:plugins-install)、只移除單一 plugin(直接照該 plugin README 的移除章節)、刪除人格資料或 Gitea 上的存取庫。 | [--assistant <助理清單,逗號分隔,或 all>] [--plugins code,doc,persona,generic] [--keep-marketplace] [--keep-clone] [--yes] |
plugins-uninstall — 一次移除所有 JSC plugin
四階段 skill:先決定助理與目標清單,再列出將被移除的項目並確認,接著依固定順序移除,最後回報結果與殘留物。
| 階段 | 動作 |
|---|---|
| A. 前置設定 | 決定要操作哪些助理(--assistant 可帶多個或 all/偵測本機有哪些 CLI/多個就讓使用者多選)→ 決定 plugin 清單(預設四個全移) |
| B. 盤點與確認 | 列出實際已安裝的項目、會一併移除的 marketplace 與本機 clone、以及不會被碰的資料,請使用者確認 |
| C. 移除 | 依 code → doc → persona → generic 的順序逐一移除 |
| D. 回報 | 表格回報每個 plugin 的結果,並列出刻意保留的殘留物 |
共用規範(generic plugin,必要前置)
執行本 skill 前,先以 Skill 工具載入下列共用規範並全程遵守:
/jsc-generic:spec-output:繁體中文(台灣用語)、UTF-8(不含 BOM)無亂碼、表格呈現。/jsc-generic:spec-execution:自動執行原則(必要決策才中斷)、不臆測/需人工確認。/jsc-generic:spec-git-safety:不破壞既有工作——本機 clone 只在使用者明確同意時刪除,且有未提交變更就一律保留。
本 skill 特有補充:
- 移除是不可逆的動作:階段 B 的確認是必要決策,除非帶
--yes,否則一定要問過才動手。 - 絕不刪除使用者資料:
~/.claude/personas/(人格倉庫)、~/.roles/、~/.memory/(角色與記憶)一律不動,Gitea 上的存取庫也不動。要清這些請使用者自己來。 - 順序不可調換:
jsc-generic一定最後移除。它是本 skill 的所在地,移除後本 skill 隨之失效,後面的步驟會執行不到。 - 多個助理時的順序:外層先跑完一個助理的四個 plugin,再換下一個助理。目前正在執行本 skill 的那個助理排到最後——不然它自己的
jsc-generic一沒,剩下的助理就處理不到了。
參數
--assistant <清單>:要操作的助理,可以多個,以逗號分隔(claude,codex,copilot,agy,opencode),或用all代表本機找得到的全部。省略時依階段 A1 判斷(只有一個就直接用,多個就讓使用者多選,且不預設全選)。--plugins code,doc,persona,generic:要移除的 plugin(以逗號分隔,用 repo 短名)。省略時預設四個全移。--keep-marketplace:只移除 plugin,保留 marketplace 登錄(之後要重裝比較快)。--keep-clone:保留 Antigravity/OpenCode 用的本機 clone 目錄(預設就是保留,此旗標僅用於明示)。要刪除本機 clone 必須由使用者在階段 B 明確同意。--yes:跳過階段 B 的確認(其他必要決策仍會中斷)。
plugin 對照表(移除識別的唯一依據)
| repo 短名 | plugin 名 | marketplace 名 | 移除 token |
|---|---|---|---|
code |
jsc-code |
code |
jsc-code@code |
doc |
jsc-doc |
doc |
jsc-doc@doc |
persona |
jsc-persona |
jsc-plugins |
jsc-persona@jsc-plugins |
generic |
jsc-generic |
generic |
jsc-generic@generic |
persona的 marketplace 名不是 repo 名(是jsc-plugins)。移除 marketplace 時特別注意別誤刪別的登錄。
各 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 |
generic |
role、plugins-install、plugins-uninstall、spec-action-params、spec-doc-funcs-handoff、spec-dockerfile、spec-execution、spec-gitea、spec-git-safety、spec-output、spec-plugin-version、spec-project-board、spec-time-log |
上表是寫下來當天的快照,plugin 之後新增 skill 它不會自己更新。所以 OpenCode 的刪除優先從本機 clone 的
skills/推導清單(見階段 C 的 OpenCode 段),clone 不在時才退回這張表,並在回報裡註明「清單可能不完整」。 兩種做法都不可用萬用字元一次掃掉整個skills/——那裡可能還有別處裝進去的 skill。
階段 A:前置設定
A1. 決定助理(可以一次多個)
--assistant 收的是清單,不是單一值:--assistant claude,codex,copilot、或 --assistant all。
最終得到的是一組助理,階段 B 到 D 都對這組的每一個各跑一遍。
依序判斷,第一個成立的就採用:
- 有帶
--assistant→ 照它。all代表「本機找得到的全部」(等同下面第 2 點的偵測結果)。 - 沒帶 → 逐一檢查哪些 CLI 存在(
command -v claude codex copilot agy opencode):- 找到 1 個 → 直接用它。
- 找到 多個 → 列出來讓使用者多選(移除是不可逆的,預設不全選,要他自己勾)。
- 一個都沒有 → 回報「找不到任何支援的助理 CLI」並停止。
目前正在執行本 skill 的那個助理,如果也在清單裡,放到最後處理——移掉它自己之後,本 skill 就不存在了。
A2. 決定 plugin 清單
--plugins 指定則照它,否則四個全做。無論使用者怎麼排,實際執行順序一律重排為 code → doc → persona → generic。
階段 B:盤點與確認
先查出實際狀態(claude plugin list/codex plugin list/copilot plugin list/agy plugin list,或 OpenCode 的 skills 目錄),再列出三張清單給使用者看:
- 會被移除:已安裝的 plugin、以及(未帶
--keep-marketplace時)對應的 marketplace 登錄。 - 本機 clone:
agy/opencode用的 clone 目錄路徑與是否有未提交變更;預設保留,要刪請使用者明確說。 - 不會被碰:
~/.claude/personas/(人格:身分、情緒、記憶、關係圖)、~/.roles/、~/.memory/、Gitea 上的所有存取庫。
清單裡沒有任何已安裝項目 → 直接回報「沒有可移除的項目」並結束。
未帶 --yes 時,在這裡停下來等使用者確認再進入階段 C。
階段 C:移除
以下 <plugin>、<marketplace>、<token> 一律取自對照表;帶 --keep-marketplace 時略過 marketplace remove 那行。
Claude Code
claude plugin uninstall <token>
claude plugin marketplace remove <marketplace>
- 移除後檢查
~/.claude/settings.json的enabledPlugins,清掉該 plugin 的殘留鍵(留著會讓下次安裝的狀態對不上)。
Codex
codex plugin remove <token>
codex plugin marketplace remove <marketplace>
GitHub Copilot CLI
copilot plugin uninstall <token>
copilot plugin marketplace remove <marketplace>
Antigravity(agy)
agy plugin uninstall <plugin>
- 本機 clone(
~/plugins/<repo>之類)預設保留;使用者在階段 B 明確同意才刪,且該目錄有未提交變更時一律保留並回報。
OpenCode
逐一刪除該 plugin 帶入的 skill 目錄。最可靠的做法是從本機 clone 推導清單,而不是照抄上表——上表是快照,plugin 新增 skill 之後就會漏:
# clone 還在:從來源目錄推導要刪哪些(唯一不會漏的做法)
for s in <clone-dir>/<repo>/skills/*/; do
rm -rf "$HOME/.config/opencode/skills/$(basename "$s")"
done
clone 已經不在時才退回上表,且一個一行分開刪:
rm -rf ~/.config/opencode/skills/docker
rm -rf ~/.config/opencode/skills/funcs
# …照上表逐行
不要用
{a,b,c}這種 brace expansion。它有三種會靜默失效的情況:逗號後有空格({a, b})不展開、只有一個元素({a})不展開、以及在dash/sh底下完全不支援。三種都是「什麼都沒刪,但-f讓結束碼還是 0」,回報會變成假的 ✅。
Windows PowerShell:
rm -rf X→Remove-Item X -Recurse -Force、~→$HOME。
jsc-generic 的收尾
移除 jsc-generic 是最後一步。動手前先在輸出裡寫清楚:
- 本 skill 與所有
spec-*共用規範會一起消失;jsc-code/jsc-doc的 skill 內文都會引用spec-*,若它們還留著,之後執行會載入不到共用規範。 - 要重新安裝,得直接照 generic 的 README(那時已經沒有
/jsc-generic:plugins-install可用了):claude plugin marketplace add https://gitea.jsc.idv.tw/plugins/generic.git→claude plugin install jsc-generic@generic。
階段 D:回報
以表格回報,一個「助理 × plugin」一列:
| 助理 | plugin | 動作 | 結果 | 備註 |
|---|---|---|---|---|
| Claude Code | jsc-code |
移除/跳過(未安裝) | ✅ 成功/⚠ 需處理/❌ 失敗 | 例:marketplace 已保留 |
| Codex | jsc-code |
跳過(未安裝) | ✅ | — |
只處理一個助理時可以省掉「助理」欄。處理多個時一定要有,否則使用者看不出哪一格出問題。
表格下方固定列出:
- 刻意保留的殘留物:本機 clone 路徑、marketplace 登錄(若帶了
--keep-marketplace)、人格倉庫與記憶目錄。 - 重啟提醒:移除後要重啟工作階段,指令與 skill 才會真正消失。