7.4 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | requirements | must_haves | |||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 03-dialog-feedback | 01 | execute | 1 |
|
true |
|
|
Purpose:仓库 9 处 toast(...) 调用当前全部是 dead code(仅 components/ui/sonner.tsx 定义了 Toaster 包装但从未挂载),不挂载 Phase 3 的成功 / 失败反馈完全静默;这是 Phase 3 业务功能跑通的硬前置。
Output:修改后的 app/layout.tsx,新增 1 行 import + 1 个 JSX 元素挂载点。
<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/03-dialog-feedback/03-CONTEXT.md @.planning/phases/03-dialog-feedback/03-RESEARCH.md @CLAUDE.md @app/layout.tsx @components/ui/sonner.tsxFrom components/ui/sonner.tsx:
type ToasterProps = React.ComponentProps<typeof Sonner>
const Toaster: ({ ...props }: ToasterProps) => JSX.Element
export { Toaster }
调用形态:<Toaster />(无 props 即可,theme 内部已读 next-themes context;本仓库未挂 ThemeProvider,会回退到默认 "system",无错误)
```tsx
import type { Metadata } from 'next'
import './globals.css'
export const metadata: Metadata = {
title: 'v0 App',
description: 'Created with v0',
generator: 'v0.dev',
}
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html lang="en">
<body>{children}</body>
</html>
)
}
```
</read_first> 精确改动 2 处:
改动 1:在 import './globals.css' 之后追加 1 行 import:
import { Toaster } from '@/components/ui/sonner'
改动 2:把 <body>{children}</body> 改为 <body>{children}<Toaster /></body>(即在 {children} 之后、</body> 之前插入 <Toaster />)。
最终全文(应该是这样):
import type { Metadata } from 'next'
import './globals.css'
import { Toaster } from '@/components/ui/sonner'
export const metadata: Metadata = {
title: 'v0 App',
description: 'Created with v0',
generator: 'v0.dev',
}
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html lang="en">
<body>
{children}
<Toaster />
</body>
</html>
)
}
严格约束:
-
不挂 Radix Toast
<Toaster />(来自@/components/ui/toaster)—— 那是另一套实现,与 Sonner 不通信;本 phase 锁定 Sonner(CONTEXT D-Toast 决策) -
不新增 ThemeProvider / next-themes 包装 ——
components/ui/sonner.tsx:9有useTheme()fallback 到"system",无 ThemeProvider 也能跑(本仓库目前确实没挂 ThemeProvider) -
不改
metadata/html lang/globals.cssimport 顺序 -
不给 RootLayout 加
"use client"——<Toaster />自身就是 client component(components/ui/sonner.tsx:1顶部已"use client"),React Server Component 可以直接渲染 client child,无需 RootLayout 自己 client 化 -
这是本 phase 唯一改动
app/layout.tsx的 task,不在此挂任何其他 provider # Windows PowerShell(项目不含 .eslintrc*,lint 跳过沿用 Phase 1+2 判定) cd C:\Users\admin\Desktop\Lila-Server\qy-lty-admin
- `app/layout.tsx` 包含 `import { Toaster } from "@/components/ui/sonner"` 一行 - `` 内 `{children}` 之后渲染 `` - `npx tsc --noEmit` 输出过滤 `app/layout.tsx` 后 **0 条新错误**(67 条存量错误与本 task 无关) - 4 个 manifest+lockfile 在 git diff 中 0 行 diff(不引入新依赖)# A 段:tsc 整体 + 反向断言(必须 0 条指向 app/layout.tsx) npx tsc --noEmit 2>&1 | Select-String -Pattern 'app/layout\.tsx|app\\layout\.tsx' # 期望:无任何输出(0 条新错误指向本文件) # B 段:grep 验证 import + Toaster 元素都已落地(PowerShell Select-String) Select-String -Path 'app/layout.tsx' -Pattern 'from "@/components/ui/sonner"' # 期望:1 行命中 import 行 Select-String -Path 'app/layout.tsx' -Pattern '<Toaster\s*/>' # 期望:1 行命中 <Toaster /> 标签 # C 段:lockfile 未动(不引入新依赖)—— Sonner 已在 deps(^1.7.1) git diff --stat HEAD -- package.json yarn.lock package-lock.json pnpm-lock.yaml # 期望:0 行(无 diff)
- 类型检查:
npx tsc --noEmitexit 非 0(67 条存量错误,与本 phase 无关),但Select-String过滤app/layout.tsx命中 0 行 - 挂载位置正确:grep
<Toaster />命中且位于<body>内、{children}之后(不是<head>内、不在 children 之前) - 不动 lockfile:
git diff --stat HEAD -- package.json *.lock输出 0 行 - lint 跳过:项目无
.eslintrc*/eslint-config-next,沿用 Phase 1+2 判定(不阻塞)
关键失败模式(如果出现,回头修):
- 如果挂在
<html>之外或<head>内 → 渲染失败 → 修 - 如果误用
import { Toaster } from "@/components/ui/toaster"(Radix Toast)→ 与 Sonner toast() 不通信 → 修 - 如果给 layout.tsx 加了
"use client"→ 改回 RSC(无必要)
<success_criteria>
app/layout.tsximport 块包含from "@/components/ui/sonner"app/layout.tsx<body>内含<Toaster />元素npx tsc --noEmit过滤后 0 条新错误指向app/layout.tsx- 4 个 lockfile 在 git diff 中 0 行 diff
- Plan 03-02 的 toast 调用上线后能在屏幕显示(本 plan 单独无法跑通端到端,由 03-02 联动验证) </success_criteria>