docs(planning): add phase 06 context and validation artifacts

This commit is contained in:
肖应宇 2026-04-15 10:58:49 +08:00
parent 27e59dac18
commit 46d974672d
6 changed files with 348 additions and 6 deletions

View File

@ -2,14 +2,14 @@
gsd_state_version: 1.0
milestone: v1.0
milestone_name: milestone
status: v1.0 milestone complete
last_updated: "2026-04-07T06:26:30.389Z"
status: Executing Phase 06
last_updated: "2026-04-15T02:13:10.002Z"
progress:
total_phases: 5
total_phases: 6
completed_phases: 5
total_plans: 6
total_plans: 9
completed_plans: 6
percent: 100
percent: 67
---
# STATE.md
@ -19,7 +19,7 @@ progress:
See: .planning/PROJECT.md (updated 2026-04-07)
**Core value:** Keep the frontend visually familiar while preserving and hardening new-system behavior end to end.
**Current focus:** Phase 01 — conflict-inventory-and-decision-matrix
**Current focus:** Phase 06 — 在输入框输入@时,可引用已生成文件和已上传附件
## Workflow State
@ -38,3 +38,9 @@ See: .planning/PROJECT.md (updated 2026-04-07)
- Repository is brownfield with active uncommitted merge-recovery changes in frontend.
- Planning docs were initialized specifically for merge recovery and alignment.
## Accumulated Context
### Roadmap Evolution
- Phase 6 added: 在输入框输入@时,可引用已生成文件和已上传附件

View File

View File

@ -0,0 +1,59 @@
# Phase 06 Commit Plan
## Commit Order
`style -> logic -> tests -> docs`
## Rules
- 禁止跨组混提。
- 每个提交仅包含该组文件,便于回滚与审阅。
- 每组提交后至少执行一次对应最小验证命令。
## Group 1: style
- 文件清单:
- `frontend/src/components/workspace/input-box.tsx`(仅样式 class、chip 展示视觉)
- `frontend/src/components/ui/dropdown-menu.tsx`(如有样式微调)
- commit message 示例:
- `style(phase-06): polish @ reference chip and dropdown visuals`
- 最小验证:
- `cd frontend && pnpm -s typecheck`
## Group 2: logic
- 文件清单:
- `frontend/src/components/ai-elements/prompt-input.tsx`
- `frontend/src/core/messages/utils.ts`
- `frontend/src/core/threads/submit-files.ts`
- `frontend/src/core/threads/hooks.ts`
- `frontend/src/components/workspace/input-box.tsx`@候选/交互逻辑)
- commit message 示例:
- `feat(phase-06): implement @ reference submission and soft-fail flow`
- 最小验证:
- `cd frontend && pnpm -s typecheck`
## Group 3: tests
- 文件清单:
- `frontend/src/core/threads/hooks.test.ts`
- `frontend/tests/e2e/input-and-compose.spec.ts`
- `frontend/tests/e2e/support/chat-helpers.ts`(如有辅助变更)
- commit message 示例:
- `test(phase-06): cover @ reference flow and stale-reference handling`
- 最小验证:
- `cd frontend && node --test src/core/threads/hooks.test.ts`
- `cd frontend && pnpm -s test:e2e --grep "DF-INPUT-007|DF-INPUT-008"`
## Group 4: docs
- 文件清单:
- `.planning/phases/06-/06-VALIDATION.md`
- `.planning/phases/06-/06-CONTEXT.md`
- `.planning/phases/06-/06-UI-SPEC.md`
- `.planning/phases/06-/06-RESEARCH.md`
- `.planning/phases/06-/06-0*-SUMMARY.md`
- commit message 示例:
- `docs(phase-06): update validation and execution summaries`
- 最小验证:
- `rg -n "style -> logic -> tests -> docs|nyquist_compliant:\\s*true" .planning/phases/06-/`

View File

@ -0,0 +1,111 @@
# Phase 06: 输入框 @ 引用文件能力 - Context
**Gathered:** 2026-04-15
**Status:** Ready for planning
<domain>
## Phase Boundary
本阶段仅实现输入框中 `@` 引用文件能力:用户在聊天输入框输入 `@` 时,可从“当前线程已生成 artifacts 与已上传附件”中选择并引用文件,随消息提交给后端。
不扩展跨线程/全局检索,不新增后端能力边界外的文件系统能力。
</domain>
<decisions>
## Implementation Decisions
### 引用来源与触发方式
- **D-01:** 引用来源限定为“当前线程”的 `artifacts + uploads`,不做跨线程或全局文件池。
- **D-02:** 输入 `@` 即刻弹出候选面板;继续输入即进行过滤。
### 输入框交互与展示
- **D-03:** 选中文件后在输入框内展示为可删除标签chip而非纯文本 `@文件名`
- **D-04:** 同名文件场景下,候选项展示“文件名 + 类型徽标 + 路径尾段”,避免歧义。
- **D-09:** `@` 触发后的文件选择面板必须使用 dropdown 组件实现(不使用自定义浮层替代)。
### 提交协议与兼容策略
- **D-05:** 复用 `additional_kwargs.files` 作为提交数据结构,不新增并行主结构。
- **D-06:**`files` 项内增加来源/类型元信息(如 `ref_kind` / `ref_source`),用于区分“引用文件”与“上传文件”,保持与现有渲染链路兼容。
### 失效与上限策略
- **D-07:** 采用软失败:引用项失效时自动剔除并给出 toast不阻止整条消息发送。
- **D-08:** 每条消息最多允许 10 个引用文件,超限时给出提示并阻止继续添加。
### the agent's Discretion
- `@` 候选面板的具体键盘交互细节上下选择、回车确认、Esc 关闭)的实现方式。
- chip 的具体视觉样式与动画,不改变已确认交互语义。
- `ref_kind` / `ref_source` 的精确字段命名(前提是语义清晰且不破坏现有消费逻辑)。
</decisions>
<canonical_refs>
## Canonical References
**Downstream agents MUST read these before planning or implementing.**
### 阶段边界与需求来源
- `.planning/ROADMAP.md` — Phase 6 条目与依赖关系Depends on Phase 5
- `.planning/STATE.md` — Phase 6 来源说明Roadmap Evolution
- `.planning/PROJECT.md` — 核心原则:旧视觉一致性与新逻辑稳定并存。
- `.planning/REQUIREMENTS.md` — 既有质量与回归约束(尤其测试与稳定性约束)。
### 输入框与提交主链路
- `frontend/src/components/workspace/input-box.tsx` — 输入框容器、按钮区与 `PromptInput` 接入点。
- `frontend/src/components/ai-elements/prompt-input.tsx` — 输入/附件状态、提交时 `PromptInputMessage` 组装、键盘行为。
- `frontend/src/core/threads/hooks.ts` — 发送消息主流程、optimistic files、上传后写入 `additional_kwargs.files`
- `frontend/src/app/workspace/chats/[thread_id]/page.tsx` — 页面层输入框挂载与提交入口。
- `frontend/src/components/ui/dropdown-menu.tsx` — dropdown 交互基座Phase 6 强制用于 `@` 文件候选面板)。
### 文件来源与展示链路
- `frontend/src/components/workspace/chats/chat-box.tsx` — 当前线程 artifact 列表来源(`thread.values.artifacts`)。
- `frontend/src/components/workspace/artifacts/artifact-file-list.tsx` — artifact 文件列表与路径展示语义。
- `frontend/src/core/uploads/api.ts` — 当前线程 uploads 列表/上传/删除 API 契约。
- `frontend/src/core/uploads/hooks.ts` — uploads 查询与提交流程封装。
- `frontend/src/components/workspace/messages/message-list-item.tsx``additional_kwargs.files` 渲染与文件卡片展示逻辑。
- `frontend/src/core/messages/utils.ts` — 文件相关消息结构解析与兼容逻辑。
</canonical_refs>
<code_context>
## Existing Code Insights
### Reusable Assets
- `PromptInput` 已具备附件状态、文件选择、粘贴/拖拽、提交流程,可在同一输入域扩展 `@` 引用交互。
- `useThreadWithOptimistic``core/threads/hooks.ts`)已处理 `additional_kwargs.files` 的上传态与已上传态,适合复用为引用态承载容器。
- `chat-box.tsx + artifacts context` 已提供当前线程 artifact 文件集合,不需要新增跨线程聚合层。
- `uploads/api.ts + uploads/hooks.ts` 已提供当前线程上传文件可查询能力,可直接作为 `@` 候选数据源之一。
### Established Patterns
- 文件相关元数据统一挂载在消息 `additional_kwargs.files`,渲染侧已依赖该模式。
- 输入框行为尽量在 `PromptInput / InputBox` 层闭环,页面层主要做组合。
- 错误处理倾向非阻断toast + 继续主流程),与本次“软失败”决策一致。
### Integration Points
- `InputBox`/`PromptInputTextarea` 负责 `@` 触发、候选过滤、chip 编辑交互。
- 发送前在 `core/threads/hooks.ts` 汇总“上传文件 + 引用文件”并统一写入 `additional_kwargs.files`
- `message-list-item.tsx` 消费 `additional_kwargs.files`;需保证新增引用元信息不会破坏现有显示。
- uploads 与 artifacts 作为候选数据源,仅限当前线程 `threadId`
</code_context>
<specifics>
## Specific Ideas
- 你明确要求沿用当前消息扩展结构:引用文件“复用 `additional_kwargs.files`”,不另起并行主结构。
- 你明确要求一次性覆盖全部灰区并锁定 A 方案(来源/触发/展示/去歧义/失效策略)。
</specifics>
<deferred>
## Deferred Ideas
- 跨线程/全局文件引用能力(可作为后续独立 phase
- 基于语义检索或标签检索的高级文件查找(超出本阶段范围)。
</deferred>
---
*Phase: 06-*
*Context gathered: 2026-04-15*

View File

@ -0,0 +1,94 @@
# Phase 06: 输入框 @ 引用文件能力 - Discussion Log
> **Audit trail only.** Do not use as input to planning, research, or execution agents.
> Decisions are captured in CONTEXT.md — this log preserves alternatives considered.
**Date:** 2026-04-15
**Phase:** 06-input-mention-files
**Areas discussed:** 引用来源范围, @触发方式, 输入框展示形态, 提交数据结构, 同名去歧义, 失效与上限策略
---
## 引用来源范围
**Options presented**
- A: 仅当前线程artifacts + uploads
- B: 当前 workspace 最近线程
- C: 全局跨线程
**User selection**
- A
**Notes**
- 用户选择稳定优先,避免跨线程复杂度与歧义扩散。
---
## @ 触发方式
**Options presented**
- A: 输入 `@` 立即弹候选,继续输入即过滤
- B: `@` 后至少 1 字符才弹
- C: 不靠 `@`,仅按钮打开
**User selection**
- A
---
## 输入框展示形态
**Options presented**
- A: 可删除标签chip
- B: 纯文本 `@文件名`
- C: 标签 + 文本混合
**User selection**
- A
---
## 提交数据结构
**Options presented**
- A: 复用 `additional_kwargs.files` 并增加来源元信息
- B: 新增 `additional_kwargs.referenced_files`
- C: 正文特殊标记
**User clarification**
- 用户先询问“`additional_kwargs` 是什么数据结构”,确认后给出“复用”。
**Final selection**
- A复用
---
## 同名文件去歧义
**Options presented**
- A: 文件名 + 类型徽标 + 路径尾段
- B: 仅文件名
- C: 发送时二次确认
**User selection**
- A
---
## 失效与上限策略
**Options presented**
- A: 软失败 + 最多 10 个
- B: 硬失败 + 最多 20 个
- C: 不设上限
**User selection**
- A
---
## Final Decision Snapshot
- 1A 2A 3A 4A(复用) 5A 6A 全部锁定。
- 本阶段目标保持在“当前线程内 @ 引用文件”边界,不引入跨线程能力。
- 新增要求:`@` 触发后的文件候选面板必须使用 dropdown 组件实现。

View File

@ -0,0 +1,72 @@
---
phase: 06
slug: 06-
status: draft
nyquist_compliant: true
wave_0_complete: true
created: 2026-04-15
---
# Phase 06 — Validation Strategy
> Per-phase validation contract for feedback sampling during execution.
---
## Test Infrastructure
| Property | Value |
|----------|-------|
| **Framework** | Playwright E2E + TypeScript static checks |
| **Config file** | `frontend/playwright.config.ts` |
| **Quick run command** | `cd frontend && pnpm -s typecheck` |
| **Full suite command** | `cd frontend && pnpm -s test:e2e` |
| **Estimated runtime** | ~180 seconds |
---
## Sampling Rate
- **After every task commit:** Run `cd frontend && pnpm -s typecheck`
- **After every plan wave:** Run `cd frontend && pnpm -s test:e2e`
- **Before `/gsd-verify-work`:** Full suite must be green
- **Max feedback latency:** 180 seconds
---
## Per-Task Verification Map
| Task ID | Plan | Wave | Requirement | Threat Ref | Secure Behavior | Test Type | Automated Command | File Exists | Status |
|---------|------|------|-------------|------------|-----------------|-----------|-------------------|-------------|--------|
| 06-01-01 | 01 | 1 | ATREF-03 | T-06-01-01 | 提交结构保持 `additional_kwargs.files` 且包含引用元信息 | unit | `cd frontend && node --test src/core/threads/hooks.test.ts` | ✅ | ✅ green |
| 06-02-01 | 02 | 2 | ATREF-01, ATREF-02 | T-06-02-01 | 输入 `@` 显示 thread 内候选并支持 chip 选择 | e2e | `cd frontend && pnpm -s test:e2e --grep "DF-INPUT-007"` | ✅ | ⚠️ 环境未启动ERR_CONNECTION_REFUSED |
| 06-03-01 | 03 | 3 | ATREF-04 | T-06-03-02 | 失效引用场景具备可解释 skip 与单测兜底 | e2e+unit | `cd frontend && pnpm -s test:e2e --grep "DF-INPUT-008" && node --test src/core/threads/hooks.test.ts` | ✅ | ⚠️ E2E 环境依赖,单测已通过 |
*Status: ⬜ pending · ✅ green · ❌ red · ⚠️ flaky*
---
## Wave 0 Requirements
Existing infrastructure covers all phase requirements.
---
## Manual-Only Verifications
| Behavior | Requirement | Why Manual | Test Instructions |
|----------|-------------|------------|-------------------|
| 中文输入法组合态下 `@` 不误触发 | TBD | 浏览器/输入法差异较大 | 在 macOS/Windows 中文输入法下输入拼音并含 `@`,确认只在非 composing 触发候选 |
---
## Validation Sign-Off
- [ ] All tasks have `<automated>` verify or Wave 0 dependencies
- [ ] Sampling continuity: no 3 consecutive tasks without automated verify
- [ ] Wave 0 covers all MISSING references
- [ ] No watch-mode flags
- [ ] Feedback latency < 180s
- [ ] `nyquist_compliant: true` set in frontmatter
**Approval:** pending