grill-with-docs 的提問改用 AskUserQuestion:選擇題,可選建議答案或自行輸入

Claude Code mods(hooks plugins)。
grill-choices:/grill-with-docs 的提問改成 AskUserQuestion 選擇題,可自行輸入。ship:/ship [補充說明],驗證 → 獨立 sonnet code-review → 確認 commit 訊息 → commit → push。action-chips:每次回覆後在輸入框上方排出小框框——回覆中的檔案與網址點了開啟(可執行檔只在 Finder 顯示)、指令點了複製;標籤由 haiku 寫成「這是什麼」(如 web demo、部署指令),依回覆順序由左至右、過長換行。system1:hook,派 sub-agent(Agent 工具)前用 System One 模型(目前後端為 TypeSafe Jev)自動決定 model。需環境變數 TYPESAFE_API_KEY(沒有就不動);名稱含 grill 或 plan 的 skill(如 /grilling、/grill-with-docs)收尾時,會問是否把結論拆成原子規格條目,由 system1:planner(opus)寫入 context/specs/<id>.json,經程式與 Jev 檢查、使用者確認後生效。可用 /plugin disable system1@cch 關閉、/plugin enable system1@cch 開啟。隱私:每次派 sub-agent,description 與 prompt 前 6000 字會送到 api.typesafe.ai。/plugin marketplace add cch-agent/claude-mods
/plugin install grill-choices@cch
/plugin install ship@cch
/plugin install action-chips@cch
/plugin install system1@cch
/reload-plugins
marketplace 名稱為
cch(見.claude-plugin/marketplace.json),安裝與解除安裝都用@cch。從舊名my-mods遷移:先/plugin uninstall <mod>@my-mods、/plugin marketplace remove my-mods,再依上方步驟重裝。
hooks/register.tsx 33 lines1import type { Register } from 'claude-code'
2
3const isGrillWithDocs = (skill: string) => skill === 'grill-with-docs' || skill.endsWith(':grill-with-docs')
4const isGrilling = (skill: string) => skill === 'grilling' || skill.endsWith(':grilling')
5
6const OVERRIDE = `
7
8## 提問格式覆寫(grill-choices mod,優先於 grilling 的文字格式)
9
10提問時**不要**用純文字的 ❓/➡️ 格式,改用 \`AskUserQuestion\` 工具,讓使用者以選擇題作答:
11- 每一輪 frontier 的問題,一次呼叫 \`AskUserQuestion\` 送出(一次最多 4 題;超過就分批連續呼叫,同一輪內不要等使用者做決策以外的事)。
12- 每題 2–4 個選項,互斥且具體;把你**建議的答案放第一個**,label 結尾加「(Recommended)」,description 說明理由與取捨。
13- 不要自己加「其他」選項:工具會自動提供讓使用者自行輸入的 Other。
14- \`header\` 用短標籤(≤12 字);問題本身若無法歸納成選項(純開放式),仍用 AskUserQuestion,給 2 個你最有把握的選項即可。
15- 該由你查證的事實仍然自己查,不要拿來問使用者。
16- 使用者回答後照原本的 design tree 流程重算 frontier、進入下一輪。`
17
18export const register: Register = on => {
19 let pending = false
20
21 on('skill.prompt', ($, e, next) => {
22 if (isGrillWithDocs(e.skill)) {
23 pending = true
24 return next({ ...e, text: e.text + OVERRIDE })
25 }
26 if (pending && isGrilling(e.skill)) {
27 pending = false
28 return next({ ...e, text: e.text + OVERRIDE })
29 }
30 return next(e)
31 })
32}
33