feat(plugins-install): 非指令助理改為先讀設定就地更新 #38

Merged
admin merged 4 commits from develop into master 2026-08-03 05:34:06 +00:00
6 changed files with 69 additions and 18 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "jsc-shared", "name": "jsc-shared",
"version": "0.0.4", "version": "0.0.5",
"description": "JSC 跨 AI 助理共用規範 pluginClaude Code / Codex / GitHub Copilot CLI / Antigravity / OpenCode),並提供整組 plugin 的安裝/更新/移除管理(plugins-install 一次安裝或更新 jsc-codejsc-docjsc-personajsc-sharedplugins-uninstall 一次移除四個 JSC plugin)。安裝與更新一律以 Gitea 遠端 repo 的 README 與檔案為準,不依賴既有本機存取庫;所有 skills 以 SKILL.md 為共通標準;於 Claude Code 以 /jsc-shared: 前綴呼叫。", "description": "JSC 跨 AI 助理共用規範 pluginClaude Code / Codex / GitHub Copilot CLI / Antigravity / OpenCode),並提供整組 plugin 的安裝/更新/移除管理(plugins-install 一次安裝或更新 jsc-codejsc-docjsc-personajsc-sharedplugins-uninstall 一次移除四個 JSC plugin)。安裝與更新一律以 Gitea 遠端 repo 的 README 與檔案為準,不依賴既有本機存取庫;所有 skills 以 SKILL.md 為共通標準;於 Claude Code 以 /jsc-shared: 前綴呼叫。",
"skills": "./skills", "skills": "./skills",
"author": { "author": {
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "jsc-shared", "name": "jsc-shared",
"version": "0.0.4", "version": "0.0.5",
"description": "JSC 跨 AI 助理共用規範 skills plugin`skills/` 為唯一真實來源,並提供整組 plugin 的安裝/更新/移除管理(plugins-install 一次安裝或更新 jsc-codejsc-docjsc-personajsc-sharedplugins-uninstall 一次移除四個 JSC plugin)。安裝與更新一律以 Gitea 遠端 repo 的 README 與檔案為準,不依賴既有本機存取庫;所有 skills 以 SKILL.md 為共通標準。", "description": "JSC 跨 AI 助理共用規範 skills plugin`skills/` 為唯一真實來源,並提供整組 plugin 的安裝/更新/移除管理(plugins-install 一次安裝或更新 jsc-codejsc-docjsc-personajsc-sharedplugins-uninstall 一次移除四個 JSC plugin)。安裝與更新一律以 Gitea 遠端 repo 的 README 與檔案為準,不依賴既有本機存取庫;所有 skills 以 SKILL.md 為共通標準。",
"skills": "./skills/" "skills": "./skills/"
} }
+1 -1
View File
@@ -214,7 +214,7 @@ copilot plugin marketplace remove shared
| Skill | 用途 | 使用方法 | | Skill | 用途 | 使用方法 |
| --- | --- | --- | | --- | --- | --- |
| `plugins-install` | 一次**安裝或更新** `jsc-code``jsc-doc``jsc-persona``jsc-shared`:先盤點每個 plugin 已安裝或未安裝,未安裝就安裝、已安裝就更新到最新,最後以表格回報動作、結果與版本。`agy``opencode` 先從 Gitea 遠端抓取 README 與技能檔到暫存目錄,再依 README 指示安裝或複製 | `/jsc-shared:plugins-install`;可帶 `--assistant claude\|codex\|copilot\|agy\|opencode``--plugins code,doc,persona,shared``--host <gitea 主機>``--temp-dir <目錄>``--yes` | | `plugins-install` | 一次**安裝或更新** `jsc-code``jsc-doc``jsc-persona``jsc-shared`:先盤點每個 plugin 已安裝或未安裝,未安裝就安裝、已安裝就更新到最新,最後以表格回報動作、位置、結果與版本。`agy` 走 clone+本地路徑安裝;`opencode` 這類**沒有 plugin 指令**的助理先讀該工具設定找出 skills 實際掛載路徑(可能是某個專案下的 `.opencode/skills`),**已安裝就在該路徑就地更新、未安裝才放進工具的全域資料夾** | `/jsc-shared:plugins-install`;可帶 `--assistant claude\|codex\|copilot\|agy\|opencode``--plugins code,doc,persona,shared``--host <gitea 主機>``--clone-dir <目錄>``--yes` |
| `plugins-uninstall` | 一次**移除** `jsc-code``jsc-doc``jsc-persona``jsc-shared`:動手前先列出將被移除的項目與不會被碰的資料請使用者確認,移除順序固定把 `jsc-shared` 放最後(本 skill 就住在裡面)。人格倉庫與記憶目錄一律不刪 | `/jsc-shared:plugins-uninstall`;可帶 `--assistant …``--plugins code,doc,persona,shared``--keep-marketplace``--yes` | | `plugins-uninstall` | 一次**移除** `jsc-code``jsc-doc``jsc-persona``jsc-shared`:動手前先列出將被移除的項目與不會被碰的資料請使用者確認,移除順序固定把 `jsc-shared` 放最後(本 skill 就住在裡面)。人格倉庫與記憶目錄一律不刪 | `/jsc-shared:plugins-uninstall`;可帶 `--assistant …``--plugins code,doc,persona,shared``--keep-marketplace``--yes` |
> `plugins-install` 與 `plugins-uninstall` 都會處理 `jsc-shared`;移除時一定放最後一步。 > `plugins-install` 與 `plugins-uninstall` 都會處理 `jsc-shared`;移除時一定放最後一步。
+1 -1
View File
@@ -1,6 +1,6 @@
{ {
"name": "jsc-shared", "name": "jsc-shared",
"version": "0.0.4", "version": "0.0.5",
"description": "JSC 跨 AI 助理共用規範 skills plugin`skills/` 為唯一真實來源,並提供整組 plugin 的安裝/更新/移除管理(plugins-install 一次安裝或更新 jsc-codejsc-docjsc-personajsc-sharedplugins-uninstall 一次移除四個 JSC plugin)。安裝與更新一律以 Gitea 遠端 repo 的 README 與檔案為準,不依賴既有本機存取庫;所有 skills 以 SKILL.md 為共通標準。", "description": "JSC 跨 AI 助理共用規範 skills plugin`skills/` 為唯一真實來源,並提供整組 plugin 的安裝/更新/移除管理(plugins-install 一次安裝或更新 jsc-codejsc-docjsc-personajsc-sharedplugins-uninstall 一次移除四個 JSC plugin)。安裝與更新一律以 Gitea 遠端 repo 的 README 與檔案為準,不依賴既有本機存取庫;所有 skills 以 SKILL.md 為共通標準。",
"skills": "./skills/" "skills": "./skills/"
} }
+64 -13
View File
@@ -1,6 +1,6 @@
--- ---
name: plugins-install 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。 description: 一次把 JSC 的四個 pluginjsc-codejsc-docjsc-personajsc-shared)安裝或更新到一個或多個 AI 助理,可同時處理 Claude Code、Codex、GitHub Copilot CLI、Antigravity 四家原生 plugin CLI 與 OpenCode 這類沒有 plugin 指令、靠複製 skills 目錄的助理;沒指定時偵測本機裝了哪些 CLI 並讓使用者多選,每個 plugin 先判斷已安裝或未安裝,未安裝就安裝、已安裝就更新到最新。非指令助理另走「先讀該工具設定找出 skills 實際掛載路徑」的判定:已安裝就在設定指到的那個路徑(可能是某個專案目錄)就地更新,未安裝才把 skills 放進該工具的預設資料夾,最後以「助理 × plugin」的表格回報動作、位置、結果與版本。當使用者說要安裝所有 jsc plugin、一次更新全部 skill 套件、把 codedocpersonashared 都裝起來、要同時更新好幾個 CLI、換新機器要把 plugin 都補齊、OpenCode 的 skill 更新到錯的地方、要更新專案自己那份 skills、或問怎麼一次更新所有 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]" argument-hint: "[--assistant <助理清單,逗號分隔,或 all>] [--plugins code,doc,persona,shared] [--host <gitea 主機>] [--clone-dir <目錄>] [--yes]"
--- ---
@@ -12,7 +12,7 @@ argument-hint: "[--assistant <助理清單,逗號分隔,或 all>] [--plugins
| --- | --- | | --- | --- |
| A. 前置設定 | 決定要操作哪些助理(`--assistant` 可帶多個或 all/偵測本機有哪些 CLI/多個就讓使用者多選)→ 決定 gitea 主機 → 決定 plugin 清單(預設 code、doc、persona、shared | | A. 前置設定 | 決定要操作哪些助理(`--assistant` 可帶多個或 all/偵測本機有哪些 CLI/多個就讓使用者多選)→ 決定 gitea 主機 → 決定 plugin 清單(預設 code、doc、persona、shared |
| B. 現況盤點 | 對每個 plugin 查詢 marketplace 與 plugin 是否已存在,決定「安裝」或「更新」 | | B. 現況盤點 | 對每個 plugin 查詢 marketplace 與 plugin 是否已存在,決定「安裝」或「更新」 |
| C. 安裝/更新 | 依助理的原生指令逐一執行;Antigravity 與 OpenCode 走 clone/複製路徑 | | C. 安裝/更新 | 依助理的原生指令逐一執行;Antigravity 走 clone+本地路徑,OpenCode 這類**非指令助理**走「讀設定 → 就地更新/放進工具資料夾」 |
| D. 回報 | 以表格列出每個 plugin 的動作、結果與版本,並提醒重啟工作階段 | | D. 回報 | 以表格列出每個 plugin 的動作、結果與版本,並提醒重啟工作階段 |
--- ---
@@ -58,7 +58,7 @@ argument-hint: "[--assistant <助理清單,逗號分隔,或 all>] [--plugins
| repo 短名 | skill 目錄 | | repo 短名 | skill 目錄 |
| --- | --- | | --- | --- |
| `code` | `action-composite``action-docker``action-node``image``issues``nuget``review-resolve``sync` | | `code` | `action-composite``action-docker``action-node``image``issues``nuget``review-resolve``sync``target` |
| `doc` | `docker``funcs``issues-analyze``issues-analyze-to-file``issues-sync``worklog` | | `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` | | `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` | | `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` |
@@ -103,7 +103,7 @@ argument-hint: "[--assistant <助理清單,逗號分隔,或 all>] [--plugins
| Codex | `codex plugin marketplace list``codex plugin list` | 同上 | | Codex | `codex plugin marketplace list``codex plugin list` | 同上 |
| GitHub Copilot CLI | `copilot plugin marketplace list``copilot plugin list` | 同上 | | GitHub Copilot CLI | `copilot plugin marketplace list``copilot plugin list` | 同上 |
| Antigravity | `agy plugin list`,並看 `<clone-dir>/<repo>` 是否存在 | 目錄在且已安裝 → 更新;否則安裝 | | Antigravity | `agy plugin list`,並看 `<clone-dir>/<repo>` 是否存在 | 目錄在且已安裝 → 更新;否則安裝 |
| OpenCode | 看 `~/.config/opencode/skills/` 底下是否已有該 plugin 的 skill 目錄 | 有 → 更新(重新複製;注意不是覆蓋,見階段 C);沒有 → 安裝 | | OpenCode(非指令助理) | 先依「非指令助理的安裝位置判定」找出**所有**候選 skills 目錄,再看哪個底下已有該 plugin 的 skill 目錄 | 有 → **更新該位置**(重新複製;注意不是覆蓋,見階段 C);沒有 → 安裝到工具預設資料夾 |
盤點的迴圈是**助理 × plugin**:階段 A1 選定的每個助理,都要對每個 plugin 各判定一次,結果分開記。 盤點的迴圈是**助理 × plugin**:階段 A1 選定的每個助理,都要對每個 plugin 各判定一次,結果分開記。
@@ -174,9 +174,44 @@ agy plugin install <clone-dir>/<repo>
- `git pull --ff-only` 失敗(本機有未提交變更或分支分岔)→ **停在該 plugin**,回報現況讓使用者裁示,不得 `reset --hard``clean`,其餘 plugin 照常繼續。 - `git pull --ff-only` 失敗(本機有未提交變更或分支分岔)→ **停在該 plugin**,回報現況讓使用者裁示,不得 `reset --hard``clean`,其餘 plugin 照常繼續。
- **先確認 clone 在哪個分支**:`git -C <clone-dir>/<repo> branch --show-current`。若不是發佈分支(`master`),代表要裝進去的是未合併的內容——先告訴使用者,由他決定要換分支還是照裝。預設的 `~/plugins` 很可能就是開發者自己的工作區。 - **先確認 clone 在哪個分支**:`git -C <clone-dir>/<repo> branch --show-current`。若不是發佈分支(`master`),代表要裝進去的是未合併的內容——先告訴使用者,由他決定要換分支還是照裝。預設的 `~/plugins` 很可能就是開發者自己的工作區。
### OpenCode ### OpenCode(非指令助理)
> OpenCode 的 plugin 是 npm 套件,不適用 skill 包;改用目錄安裝。OpenCode 只會帶入 `skills/`,安裝前要先告知使用者。 > OpenCode 的 plugin 是 npm 套件,不適用 skill 包;改用**目錄安裝**。OpenCode 只會帶入 `skills/`,安裝前要先告知使用者。
> 這類助理**沒有 plugin CLI 可查安裝清單**,所以不能像四家原生 CLI 那樣「問 CLI 裝了沒」,也**不可預設就往全域目錄倒**——先讀設定找出它實際掛在哪,再決定要更新誰。
#### C-1. 先判定安裝位置(讀設定,不要臆測)
候選位置由近到遠如下,**只有實際存在於磁碟的才納入候選**:
| 順位 | 候選 skills 目錄 | 判定依據 |
| --- | --- | --- |
| 1 | `<專案根>/.opencode/skills/` | 從目前工作目錄往上找到第一個含 `opencode.json``opencode.jsonc``.opencode/` 的目錄,即為專案根 |
| 2 | `${XDG_CONFIG_HOME:-$HOME/.config}/opencode/skills/` | 工具全域資料夾(**未安裝時的預設安裝目標**) |
| 3 | `$HOME/.claude/skills/``$HOME/.agents/skills/` | OpenCode 也會讀的相容來源 |
```bash
# 全域設定目錄(工具資料夾)
OC_HOME="${XDG_CONFIG_HOME:-$HOME/.config}/opencode"
# 從目前工作目錄往上找專案根
proj=""; d="$PWD"
while [ "$d" != "/" ]; do
if [ -f "$d/opencode.json" ] || [ -f "$d/opencode.jsonc" ] || [ -d "$d/.opencode" ]; then proj="$d"; break; fi
d="$(dirname "$d")"
done
# 列出實際存在的候選 skills 目錄
for c in ${proj:+"$proj/.opencode/skills"} "$OC_HOME/skills" "$HOME/.claude/skills" "$HOME/.agents/skills"; do
[ -d "$c" ] && echo "$c"
done
```
判定「這個 plugin 有沒有裝在某個候選位置」,用**對照表列出的 skill 目錄名**去看:候選底下只要出現該 plugin 的任一個 skill 目錄,就算已安裝在那裡。
- 設定檔存在但**內容看不懂或解析失敗** → 不猜。記為「需人工確認」,非 `--yes` 時先問使用者要更新哪個位置。
- 若設定把 skills 指到上表以外的自訂路徑,**以設定為準**,不要改回預設目錄。
#### C-2. 已安裝 → 到該位置就地更新
```bash ```bash
# 取得或更新本機 clone(同 Antigravity,不要無條件 clone # 取得或更新本機 clone(同 Antigravity,不要無條件 clone
@@ -186,11 +221,24 @@ else
git clone <url> <clone-dir>/<repo> git clone <url> <clone-dir>/<repo>
fi fi
mkdir -p ~/.config/opencode/skills # <target> = C-1 判定出「已經有這個 plugin」的那個目錄(可能是某個專案下的 .opencode/skills
cp -r <clone-dir>/<repo>/skills/* ~/.config/opencode/skills/ cp -r <clone-dir>/<repo>/skills/* "<target>/"
``` ```
> **Windows PowerShell**`cp -r A B` → `Copy-Item A B -Recurse -Force`、`~` → `$HOME` - **就地更新,不要另外補一份到全域目錄**:設定指到專案路徑就更新專案路徑;多倒一份到 `~/.config/opencode/skills/` 會造成同名 skill 兩份、之後每次更新都要記得更兩邊
- **多個候選位置都已安裝** → 全部更新,並在階段 D **逐列列出各自的位置**,同時提醒使用者這個 plugin 被重複安裝了,建議留一份。
- **目標在某個 git 專案內**(例如 `.opencode/skills` 被該專案追蹤)→ 複製後會產生未提交變更。依 `/jsc-shared:spec-git-safety`:只回報「該專案有新增/異動檔案待處理」,**不代為 commit、不動既有變更**。
#### C-3. 未安裝 → 放進工具的資料夾
```bash
mkdir -p "${XDG_CONFIG_HOME:-$HOME/.config}/opencode/skills"
cp -r <clone-dir>/<repo>/skills/* "${XDG_CONFIG_HOME:-$HOME/.config}/opencode/skills/"
```
四個候選位置都沒有這個 plugin 時,才裝進工具的全域資料夾;**不要因為當下剛好在某個專案目錄,就自作主張裝進那個專案**。
> **Windows PowerShell**`cp -r A B` → `Copy-Item A B -Recurse -Force`、`~` → `$HOME`、`${XDG_CONFIG_HOME:-$HOME/.config}` → `$env:XDG_CONFIG_HOME` 沒設就用 `$HOME\.config`。
- **`cp -r` 不是覆蓋,是合併**:同名檔案會更新,但**上游已經刪掉的檔案會原地留著**。所以 skill 改名或移除之後,OpenCode 端會同時留著新舊兩份。要乾淨更新就先刪該 plugin 帶入的目錄再複製一次(刪法見 `/jsc-shared:plugins-uninstall` 的 OpenCode 段)。回報時不要講「已覆蓋」,講「已複製,舊檔可能殘留」。 - **`cp -r` 不是覆蓋,是合併**:同名檔案會更新,但**上游已經刪掉的檔案會原地留著**。所以 skill 改名或移除之後,OpenCode 端會同時留著新舊兩份。要乾淨更新就先刪該 plugin 帶入的目錄再複製一次(刪法見 `/jsc-shared:plugins-uninstall` 的 OpenCode 段)。回報時不要講「已覆蓋」,講「已複製,舊檔可能殘留」。
@@ -200,13 +248,16 @@ cp -r <clone-dir>/<repo>/skills/* ~/.config/opencode/skills/
以表格回報,**一個「助理 × plugin」一列**: 以表格回報,**一個「助理 × plugin」一列**:
| 助理 | plugin | 動作 | 結果 | 版本 | | 助理 | plugin | 動作 | 位置 | 結果 | 版本 |
| --- | --- | --- | --- | --- | | --- | --- | --- | --- | --- | --- |
| Claude Code | `jsc-code` | 安裝/更新/跳過 | ✅ 成功/⚠ 需處理/❌ 失敗 | 例 `0.0.2` | | Claude Code | `jsc-code` | 安裝/更新/跳過 | CLI 自管快取 | ✅ 成功/⚠ 需處理/❌ 失敗 | 例 `0.0.2` |
| Codex | `jsc-code` | 更新 | ✅ 成功 | 未知 | | Codex | `jsc-code` | 更新 | CLI 自管快取 | ✅ 成功 | 未知 |
| OpenCode | `jsc-code` | 更新 | `~/work/app/.opencode/skills` | ✅ 成功 | `0.0.2` |
只處理一個助理時可以省掉「助理」欄。**處理多個時一定要有**,否則使用者看不出哪一格出問題。 只處理一個助理時可以省掉「助理」欄。**處理多個時一定要有**,否則使用者看不出哪一格出問題。
- 「位置」欄對**非指令助理必填**(寫出實際複製到的絕對路徑),四家原生 CLI 寫「CLI 自管快取」即可。使用者要知道這次更新的是專案那份還是全域那份。
- 版本取自該 plugin 的 `plugin.json`。**只有 Antigravity 與 OpenCode 拿得到**(它們有本機 clone 可讀);ClaudeCodexCopilot 把 plugin 放在各自 CLI 自管的快取目錄,除非該 CLI 的 `plugin list` 印得出版本,否則一律寫「未知」,不要去猜。 - 版本取自該 plugin 的 `plugin.json`。**只有 Antigravity 與 OpenCode 拿得到**(它們有本機 clone 可讀);ClaudeCodexCopilot 把 plugin 放在各自 CLI 自管的快取目錄,除非該 CLI 的 `plugin list` 印得出版本,否則一律寫「未知」,不要去猜。
- 有任何一列不是 ✅ → 在表格下方逐項說明原因與建議動作。 - 有任何一列不是 ✅ → 在表格下方逐項說明原因與建議動作。
- 最後固定提醒:**安裝或更新後要重啟工作階段**才會生效;`jsc-persona` 在 Claude Code 還要用 `/hooks` 確認六個 hook 都在。 - 最後固定提醒:**安裝或更新後要重啟工作階段**才會生效;`jsc-persona` 在 Claude Code 還要用 `/hooks` 確認六個 hook 都在。
+1 -1
View File
@@ -59,7 +59,7 @@ argument-hint: "[--assistant <助理清單,逗號分隔,或 all>] [--plugins
| repo 短名 | skill 目錄 | | repo 短名 | skill 目錄 |
| --- | --- | | --- | --- |
| `code` | `action-composite``action-docker``action-node``image``issues``nuget``review-resolve``sync` | | `code` | `action-composite``action-docker``action-node``image``issues``nuget``review-resolve``sync``target` |
| `doc` | `docker``funcs``issues-analyze``issues-analyze-to-file``issues-sync``worklog` | | `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` | | `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-gitea``spec-git-safety``spec-output``spec-plugin-version``spec-project-board``spec-time-log` | | `shared` | `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` |