/sdd-stack
輸入:$ARGUMENTS。你將進行一場關於技術棧的訪談,並在使用者確認總結之後,才寫入檔案。
0. 提問之前:先查明事實
環境的事實是你的工作,切勿詢問使用者。請查看(或委派給子代理):
- 現有的 manifest 與程式碼(
package.json、pyproject.toml、go.mod、Dockerfile、.github/workflows/、頂層資料夾); .agents/specs/stack.md與architecture.md(若已填寫且未提供--revisar,則顯示摘要,只問不足之處);.specify/memory/constitution.md(已決定的限制,例如 LGPD、單一資料庫);sddkit suggest --json(偵測到的技術棧)。
已在程式碼中決定的事項視為已定決策,不做為提問。
1. 方法
- 若技能
grilling已安裝在.agents/skills/→ 遵循其方法(依決策樹邊界進行回合,每題附建議答案,直到邊界消失)。 - 若未安裝 → 同一格式:每回合中,所有前提條件已滿足的提問,依編號排列,每個提問如下:
❓ **Q1 — <標題>**: <問題,含 2–4 個選項與各選項的權衡,一行內說明>
➡️ <你的建議與理由,1–2 行>
每個問題的設計要使「是」代表接受建議。優先選擇無聊且成熟、團隊已熟悉的技術,而非最新技術;全專案使用同一語言,除非有強烈理由;使用滿足範圍所需的最少元件(每多一個服務就是多一份營運成本)。若答案與先前答案或憲法衝突,請指出並詢問哪一個為準。
2. 技術棧決策樹
依此依賴順序進行;跳過不適用的分支(例如無 UI → 無前端問題)。
- 產品: 是什麼(Web 應用程式、API、行動應用程式、桌面應用程式、CLI、函式庫、Worker)、誰使用、預期規模(使用者、資料、尖峰)、限制(LGPD、離線、成本、時程)。
- 團隊: 團隊熟練的語言;誰來維護。
- 形式: 模組化單體、含套件的單一儲存庫、或多個分離服務;哪些需要非同步處理。
- 語言與執行環境(主版本號):例如 TypeScript/Node 22、Python 3.12。
- 前端(若有 UI):框架(React/Next、Vue/Nuxt、Svelte、Astro…)、渲染方式(SPA、SSR、靜態)、元件庫與樣式(MUI、shadcn+Tailwind…)、伺服器狀態(TanStack Query…)、國際化、無障礙。
- 行動/桌面(若有):原生、React Native/Expo、Flutter、Tauri、Electron。
- 後端/API: 框架(Express、Fastify、NestJS、Hono、FastAPI、Django…)、風格(REST、GraphQL、tRPC)、合約與驗證(Zod、Pydantic、OpenAPI)。
7b. 後端範式(僅在有後端時;絕不用於前端,前端依循框架慣例):
- 風格:OOP 搭配 SOLID(帶不變量的實體、依賴介面的服務)、函數式(純函數、不可變資料、邊界的副作用)或務實式(簡單模組、只有 2 個以上實作才抽象 — 即
ponytail的預設)。 - 架構:簡單分層(controller → service → repository)、clean/六角形(領域無框架依賴、Ports 與 Adapters)或 DDD(界限上下文、聚合)。建議領域能承受的最簡單方式:僅在業務邏輯豐富時使用 clean/DDD。
- 哪些資料夾屬於後端(例如
server/**、services/**、modules/**)。這就是將範式限制在後端的方法。
- 風格:OOP 搭配 SOLID(帶不變量的實體、依賴介面的服務)、函數式(純函數、不可變資料、邊界的副作用)或務實式(簡單模組、只有 2 個以上實作才抽象 — 即
- 資料: 資料庫(PostgreSQL、MySQL、MongoDB、SQLite)、ORM/存取(Prisma、Drizzle、SQLAlchemy…)、遷移、快取。
- 非同步: 佇列/工作(BullMQ、Celery、pg-boss…)、事件、即時通訊(WebSocket/SSE)。
- 身分驗證與授權: 提供者或自訂、Session/JWT、角色/權限。
- 外部整合: 金流(PIX…)、電子郵件、AI(Anthropic SDK…)、MCP。
- 託管與營運: 在哪裡運行(Vercel、搭配 Docker 的 VPS、託管雲端)、環境、機密、可觀測性(日誌、錯誤、指標)。
- 品質: 測試(單元、整合、Playwright e2e)、Lint/格式化、型別檢查、CI(GitHub Actions)、提交(Conventional Commits/commitlint)。
3. 確認
當邊界為空時,以表格顯示總結(層級 · 選擇 · 版本 · 原因 · 排除的替代方案),並提問:「就這樣決定了嗎?」。在得到「是」之前,不要寫入任何內容。
4. 寫入
.agents/specs/stack.md:將內容(包括標記[PREENCHER)取代為:## 依元件— 每個層級含技術、主版本號與主要套件的套件名稱(例如react、@prisma/client、bullmq、fastapi):sddkit使用這些名稱來建議角色與技能;## 基礎架構— 資料庫、佇列、快取、託管、CI、可觀測性;## 決策— 每個相關選擇附上原因與排除的替代方案(含今天日期)。
.agents/specs/architecture.md:填寫## 總覽區段(元件與其溝通方式;若超過 2 個元件,加入 mermaid 圖表)並移除[PREENCHER。若已有程式碼,也填寫## 程式碼地圖(每個區域一行:進入點、關鍵資料夾、測試)。其餘區段留待有程式碼時再處理。- 後端範式(若在 7b 決定且不是「務實式」):
.agents/specs/coding-standards.md:新增## 後端 — 範式區段,包含風格、架構、後端資料夾、3–5 條具體規則(每條附一個簡短範例),以及執行規則的工具(如下)。明確說明前端不遵循此區段。- sddkit 記憶,讓代理在整個工作階段中知道範圍:
sddkit memory add "範式 <風格>/<架構> 僅限後端(<資料夾>);前端遵循框架慣例" -t paradigma sddkit memory add "在後端,coding-standards.md 的 '後端 — 範式' 區段優於 ponytail 關於介面與層級的規則" -t paradigma sddkit memory add "<最具體的規則>" -t paradigma-backend --paths "<後端資料夾>" - 技能(目錄中為選用,僅由後端角色
api、data、event-module、queue-worker載入):OOP/SOLID →sddkit add solid;clean/六角形 →sddkit add clean-architecture;DDD →sddkit add domain-driven-design。函數式:沒有好的通用技能;由coding-standards.md的規則與 lint 來達成。 - 強制性檢查(lint 僅作用於後端資料夾;若尚無程式碼,則成為
/sdd-feature的第一個設定任務):- 分層/clean/六角形/DDD:
dependency-cruiser或eslint-plugin-boundaries(TypeScript)、import-linter(Python)— 領域不應匯入基礎架構或框架; - TypeScript 函數式:在 ESLint 區塊中使用
eslint-plugin-functional,搭配files: ["<後端資料夾>"](禁止類別、禁止突變、禁止let); - OOP:沒有要求 OOP 的 linter;使用上述分層規則與程式碼審查。
- 分層/clean/六角形/DDD:
- 憲法: 若出現不可妥協的限制(例如「PostgreSQL 是唯一的真相來源」),請提出文字並建議
/speckit-constitution— 不要直接編輯憲法。 - 告知使用者在終端機執行:
sddkit init # 讀取已宣告的技術棧,並提供對應的角色與技能(不會刪除任何既有內容) sddkit doctor
最終報告(≤ 8 行)
技術棧決定 · 每層級一行 · 後端範式與其強制方式 · 已寫入的檔案 · 建議加入憲法的限制 · 下一步(sddkit init,接著 /sdd-feature)