feat(佈署): 以 npm 裝出 tea-sdlc 指令並產生各平台轉接檔

單一入口 bin/tea-sdlc.js 認四個子指令。第一個位置參數是子指令,其餘 argv 原樣
交出去——既有的 flag 解析拒絕位置參數,所以子指令必須在那之前就被取走。

轉接檔裡沒有路徑,只有一句 tea-sdlc prompt --name <指令名>。正本在哪由 PATH 上
的 tea-sdlc 自己回推:fnm 把 Node 版號寫進全域安裝路徑,寫死路徑的話升一次
Node,七個平台的轉接檔會同時指向不存在的檔案,而且不會有任何錯誤訊息。

prompt 是全專案唯一輸出非 JSON 的路徑,理由只有一個:它的輸出要餵給模型讀。
失敗仍走 envelope——成功是內容,失敗才需要結構。

status 的 ok 不兼差表達環境好壞,健康與否放在 data.healthy:呼叫端要分得出
「status 掛了」與「status 成功查到你環境有問題」。

install 只寫進偵測得到的平台;缺 git/tea 只警告不中止,因為那兩個完全不影響
轉接檔產生,硬擋等於逼使用者為了裝 plugin 先去裝 tea。uninstall 只刪帶產生標記
的檔案,使用者自己寫的同名檔案一律留著並在輸出裡交代。裝哪些指令以 prompts/ 裡
實際存在的正本為準,不是寫死的六個名字——裝出指向不存在正本的轉接檔,使用者只會
看到 PROMPT_NOT_FOUND。

流程正本的 description 前綴在抄進轉接檔之前就檢查:有三個平台關不掉自動觸發,
全靠那句話把 description 窄到不會被誤判,不能等使用者發現誤觸才知道漏了。

議題 #26 #27 #28 #29 #17

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-09-17 06:59:37 +00:00
co-authored by Claude Opus 5
parent f736d11049
commit 17178f0c4d
16 changed files with 1746 additions and 39 deletions
+104 -11
View File
@@ -7,8 +7,9 @@
- **副作用集中**:所有對 Gitea 與 git 的呼叫下沉到 `scripts/` 的零相依 Node 腳本,統一 JSON 輸入輸出。
- **產出有固定形狀**:議題、PR、報表一律套 `templates/` 的模板。
> **目前處於骨架階段。** 目錄與 manifest 已就位,六個指令與腳本尚未實作。
> 完整需求見[議題 #1](https://gitea.jsc.idv.tw/plugins/tea-sdlc/issues/1),實作進度見其底下的工作包。
> **目前仍在實作中。** 安裝、佈署與腳本已經可用,六個流程正本尚未到齊——
> `tea-sdlc install` 只會佈署 `prompts/` 裡已經存在的指令。
> 完整需求見[議題 #1](https://gitea.jsc.idv.tw/plugins/tea-sdlc/issues/1),進度見其底下的工作包。
---
@@ -33,12 +34,13 @@ tea-sdlc/
├── scripts/ # 所有 Gitea / git 副作用的唯一出口(Node,零相依)
├── templates/ # 議題、PR、報表、總覽網頁的輸出模板
├── references/ # 規則正本:實作規範、註解格式、可行性檢查清單
├── bin/tea-sdlc.js # 單一指令入口:install / uninstall / prompt / status
├── skills/ # 各助理原生 plugin 機制讀取的 skills(目前為空)
├── .claude-plugin/ # Claude Code 的 plugin / marketplace manifest
├── .codex-plugin/ # Codex 的 plugin manifest
├── .agents/plugins/ # Codex 的 marketplace manifest
├── plugin.json # Antigravity 的 plugin manifest
├── package.json # 僅用於測試入口,無任何相依套件
├── package.json # npm 打包與測試入口,無任何相依套件
├── AGENTS.md # 給 AI 助理的模組邊界與慣例
└── README.md
```
@@ -57,12 +59,103 @@ tea-sdlc/
---
## 安裝 / 更新 / 移除(各助理)
## 安裝
> 以下為 plugin 機制的安裝方式。指令本身之後會改由 `install.js` 產生各平台轉接檔佈署,
> 屆時本節會一併更新。
一行裝好,終端機就多出一個 `tea-sdlc` 指令:
### Claude Code
```bash
npm i -g https://gitea.jsc.idv.tw/plugins/tea-sdlc.git
```
要裝特定版本就在網址後面接上 tag:`...tea-sdlc.git#v0.1.0`。不必設定任何 registry 或憑證。
接著把六個流程指令佈署到你裝了的每個 agent 平台:
```bash
tea-sdlc install
```
它會列出偵測到的平台讓你勾選(預設全勾),只寫進已經存在的平台目錄,不在沒裝的平台留下孤兒目錄。
沒有終端機可問時(CI、腳本)不會停下來等輸入,直接照預設全裝。
`--platform` 直接指定安裝對象,`--dry-run` 先看會動到哪些檔案:
```bash
tea-sdlc install --platform claude,codex
tea-sdlc install --dry-run
```
| 平台 | 偵測 | 轉接檔落點 | 形式 |
| --- | --- | --- | --- |
| `claude`(Claude Code) | `~/.claude/` | `~/.claude/commands/sdlc-*.md` | command |
| `codex`(Codex) | `~/.codex/` | `~/.codex/prompts/sdlc-*.md` | command |
| `opencode`(OpenCode) | `~/.config/opencode/` | `~/.config/opencode/command/sdlc-*.md` | command |
| `oh-my-pi` | `~/.omp/` | `~/.omp/commands/sdlc-*.md` | command |
| `antigravity`(Antigravity) | `~/.gemini/` | `~/.gemini/skills/sdlc-*/SKILL.md` | skill |
| `kiro`(Kiro) | `~/.kiro/` | `~/.kiro/skills/sdlc-*/SKILL.md` | skill |
| `copilot`(GitHub Copilot) | 專案裡的 `.github/` | `.github/skills/sdlc-*/SKILL.md` | skill |
轉接檔裡**沒有路徑**,只有一句「執行 `tea-sdlc prompt --name sdlc-plan`」。正本在哪由 PATH 上的
`tea-sdlc` 自己回推——升級 Node、換版本管理器、改 npm prefix 都不會讓七個平台的轉接檔同時失效。
還沒裝 `git` 或 [`tea`](https://gitea.com/gitea/tea) 也可以先裝:轉接檔的產生不需要它們,
安裝會把缺的東西列在輸出的 `missingBinaries` 與 `warning` 裡,但不會替你安裝,也不會因此中止。
真正需要它們的是流程指令本身,跑之前補上即可。
---
## 更新 / 移除
改流程正本、腳本、模板或規則,只要重裝套件,下一次叫用就讀到新的,**不必重新佈署**;
只有指令數量或轉接檔模板本身變了,才需要再跑一次 `tea-sdlc install`(轉接檔過時時,
叫用它會在輸出最前面提醒你)。
| 想做的事 | 指令 |
| --- | --- |
| 更新到最新版 | `npm i -g https://gitea.jsc.idv.tw/plugins/tea-sdlc.git` |
| 指令數量變了之後重新佈署 | `tea-sdlc install` |
| 查目前版本、正本位置與環境 | `tea-sdlc status` |
| 只移除轉接檔(正本不動) | `tea-sdlc uninstall` |
| 連套件一起移除 | `tea-sdlc uninstall` → `npm rm -g tea-sdlc` |
> **不要用 `npm update -g`。** 這個套件是從 git URL 裝的,`npm update -g` 認不得它的來源,
> 不會有任何更新發生,也不會報錯——重裝(上表第一行)才是更新的方式。
>
> **移除的順序不能顛倒。** 先 `npm rm -g tea-sdlc` 會把 `tea-sdlc` 指令一起帶走,
> 留在七個平台目錄裡的轉接檔就再也沒有東西能刪它們了,只能手動一個個找出來。
`tea-sdlc uninstall` 只刪自己產生的檔案:每份轉接檔裡都有產生標記,沒有標記的同名檔案一律留著,
並在輸出裡告訴你留了哪些。
---
## 給 agent 的入口
轉接檔指向的就是這一支。它把流程正本原樣印到 stdout,不包 JSON——那些內容是要給模型讀的。
```bash
tea-sdlc prompt --name sdlc-plan
```
其餘子指令與所有腳本一樣輸出單行 JSON `{ok, data, error:{code, message}}`,exit 0 或 1。
```bash
tea-sdlc status # 版本、正本位置、是否 link 模式、node/git/tea/登入、各平台轉接檔現況
```
`status` 在環境不健康時**指令本身仍算成功**(`ok` 為 `true`、`data.healthy` 為 `false`):
「查詢失敗」與「成功查到你環境有問題」的下一步完全不同,不該由同一個旗標表示。
---
## 附錄
### 其他安裝方式(plugin / marketplace 機制)
> 這些是各助理原生的 plugin / marketplace 機制。它們目前**裝不出任何指令**——`skills/` 還是空的,
> 真正會生效的是上面 `tea-sdlc install` 產生的轉接檔。保留在這裡是因為這些機制本身有用
> (自動更新、plugin 清單),等 `skills/` 有內容時會回來。
#### Claude Code
```bash
claude plugin marketplace add https://gitea.jsc.idv.tw/plugins/tea-sdlc.git
@@ -80,7 +173,7 @@ claude plugin marketplace remove tea-sdlc
工作階段內 slash 版(等價):把 `claude plugin` 換成 `/plugin`。
本機開發(免 push):`claude plugin marketplace add /root/plugins/tea-sdlc`(本地路徑)後再 install。
### Codex
#### Codex
```bash
codex plugin marketplace add https://gitea.jsc.idv.tw/plugins/tea-sdlc.git
@@ -96,7 +189,7 @@ codex plugin marketplace remove tea-sdlc
安裝 token `tea-sdlc@tea-sdlc` = plugin 名(`.codex-plugin/plugin.json` 的 `name`)@ marketplace 名(`.agents/plugins/marketplace.json` 的 `name`)。安裝後重啟 Codex。
### Antigravity(`agy`)
#### Antigravity(`agy`)
> `agy plugin install <url>` 目前只支援 github.com;Gitea 等自架 git 請先 clone 再用本地路徑安裝。
@@ -110,7 +203,7 @@ agy plugin uninstall tea-sdlc
agy plugin install ~/plugins/tea-sdlc
```
### GitHub Copilot CLI
#### GitHub Copilot CLI
```bash
copilot plugin marketplace add https://gitea.jsc.idv.tw/plugins/tea-sdlc.git
@@ -125,7 +218,7 @@ copilot plugin uninstall tea-sdlc@tea-sdlc
copilot plugin marketplace remove tea-sdlc
```
### OpenCode
#### OpenCode
OpenCode 的「plugin」是 TypeScript/npm 套件,不適用於本 repo;改用目錄安裝。
OpenCode 會讀 `~/.config/opencode/skills/`(也會讀 `~/.claude/skills/`、`~/.agents/skills/`)。