Handle repository-specific CLI UI and message-presentation work in d2r-hyper-launcher. Use this whenever the user wants to change visible CLI wording, headers, startup announcements, menu layout, option alignment, prompt/error/success formatting, submenu navigation presentation, grouped multiline messages, or any `cmd/d2r-hyper-launcher` display flow, even if they only mention 'UI', 'menu', 'header', '公告', '訊息顯示', '排版', or 'CLI 看起來怪怪的'.
這個 skill 專注在 d2r-hyper-launcher 的 CLI UI layer 與玩家可見訊息呈現。處理這類任務時,先把自己限制在 cmd/d2r-hyper-launcher 的 renderer / menu / input 邊界,避免把單純的顯示調整誤做成 domain 邏輯重寫。
printStartupAnnouncement() / printMenu() 的呼叫位置feedback.go 現在不是單純 prefix helper,而是 CLI UI layer;call site 應只表達語意,不直接決定 icon、divider、prompt spacing 或 option 對齊。headf(...):表示目前位於哪個環節 / sectionmenuBlock(func(){ ... }):表示玩家準備閱讀並輸入的一組內容headf(...) 會依 headerDivider 的顯示寬度置中,寬度計算要走 displayWidth(...),不能只用 rune count。newMenuOptions() 收集;option(...) 以 key / label / comment 三欄資料建模,再由 render() 依最長 prefix 與 label 做 display-width-aware 對齊;cliMenuOptions 會綁定建立它的 ui。q 離開選項,優先使用 ui.mainMenuOptions(func(*cliMenuOptions));它會統一補上 custom options 後的空行與「退出」。b / h / q 導航,優先使用 ui.subMenuOptions(func(*cliMenuOptions));它會統一補上 custom options 後的空行與「回上一層 / 回主選單 / 離開程式」。infoLines(...) / warningLines(...) / promptLines(...) / successLines(...) / errorLines(...) 是「同一組訊息的多段內容」,只會顯示一次 icon,後續段落縮排對齊到 icon 後方。b / h / q,且仍應保留在 submenu 的最後一組選項。ui.commandf(...),並由 > prefix 表示實際執行的命令列。fmt.Print* 或直接操作 scanner。ui.infof(...)、ui.commandf(...)、ui.warningf(...)、ui.promptf(...)、ui.headf(...)、ui.menuBlock(...)、ui.newMenuOptions()、ui.mainMenuOptions(...)、ui.subMenuOptions(...);不要直接拼接裸輸出。*Lines(...) helper,不要手動塞 \n 後又重複 icon。cliMenuOptions,並優先把補充資訊放進 comment 欄位;不要在 label 內硬塞一長串括號後又自己猜最長寬度。displayWidth(...) 邏輯;不要回退成 utf8.RuneCountInString(...)。ui_test.go 與 main_test.go 的預期仍反映最新 UX。README.md、docs/ 與 AGENTS.md 是否要更新。printStartupAnnouncement()infoLines(...) 或 warningLines(...)headf(...),不要把 announcement 改回零散 rawln(...)printMenu() 或對應 cli_*.go flowui.mainMenuOptions(func(options *cliMenuOptions) { ... })newMenuOptions() 收集所有選項,再 render()option(key, label, comment);主動作放 label,狀態 / 補充說明放 commentui.subMenuOptions(func(options *cliMenuOptions) { ... }),讓 UI layer 自動補上空行與固定導覽選項feedback.go 的 message helpers 與 renderMessage(...)*Lines(...)readInputf(...) 與 anyKeyContinue(),不要自行分叉新 prompt 行為若有改到 Go 程式或可見 UI 行為,至少跑:
.\scripts\go-test.ps1
New-Item -ItemType Directory -Force .\.tmp | Out-Null
go build -o .\.tmp\d2r-hyper-launcher-dev.exe ./cmd/d2r-hyper-launcher
至少確認:
ui_test.go 的 renderer 規則仍通過main_test.go 的主選單 / announcement 預期仍通過