Files
mindfulness/spec_kit/Text Wrap/modules/search-engine-widget/tasks.md
2026-02-10 11:39:33 +08:00

79 lines
3.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# search-engine-widget任务清单
> 目标:在 WIDGET 场景实现确定性 Beam Search文档 9.2),支持 `widthMode=MEASURE/APPROX`,并输出最优 layout 或可解释失败原因。
## 0. 对齐与准备
- [x] 阅读并对齐口径
- [x] 阅读 `spec_kit/Text Wrap/modules/search-engine-widget/spec.md`
- [x] 阅读 `spec_kit/Text Wrap/modules/search-engine-widget/plan.md`
- [x] 阅读 `设计说明文档/文档换行算法.md` 的 9.2/9.3/11 章节
- [x] 创建客户端模块目录
- [x] 新建 `client/src/features/textWrap/searchWidget/`
## 1. 类型定义与导出
- [x] 新建 `client/src/features/textWrap/searchWidget/types.ts`
- [x] 定义 `WidthMode = 'MEASURE' | 'APPROX'`
- [x] 定义 `SearchWidgetConfig``beamK``expandM``tooLongThresholds`
- [x] 定义 `SearchWidgetInput`
- [x] `tokens/lang/breakpoints/availableWidth/maxLines/context='WIDGET'`
- [x] `measure: { widthMode; contextProfile?; fontSpec?; measureWidthImpl? }`
- [x] `scoring: { config; lexicons; debug? }`
- [x] 定义 `SearchWidgetResult`
- [x] 成功:`bestLayout { breaks; lines; wrappedText; meta }`
- [x] 失败:`{ ok:false; reason:'TOO_LONG'|'NO_CANDIDATE'; meta? }`
- [x] 新建 `client/src/features/textWrap/searchWidget/index.ts`
- [x] 统一导出 types 与入口 `searchBestLayoutWidget()`
## 2. TopK/BeamK 维护(确定性)
- [x] 新建 `client/src/features/textWrap/searchWidget/topK.ts`
- [x] 实现 comparescore desctieKey ascbreaks 字典序
- [x] 实现去重:同 breaks 只保留最优
- [x] 实现 `insertTopK`(用于全局 beamK 保留)
## 3. 约束与降级 meta
- [x] 新建 `client/src/features/textWrap/searchWidget/constraints.ts`
- [x] `isTooLong`TC>60 / EN>30
- [x] `isLineStartPunctTC(tokens, nextPos, tcPunctuations)`H6
- [x] `approxWidth(line, lang)`EN=tokenCount / TC=charCount
## 4. Beam Search 主流程
- [x] 新建 `client/src/features/textWrap/searchWidget/beam.ts`
- [x] 初始化 beams`[{pos:0, breaks:[], lines:[], score:0}]`
- [x] 循环 lineIndex=1..maxLines
- [x] 对每个 beam 枚举 nextPosbreakpoints>pos + N
- [x] 裁剪:仅取前 `expandM` 个 nextPospos 升序)
- [x] 构造行文本:`joinTokens`
- [x] 计算行宽:
- [x] widthMode=MEASURE尝试 `measureSliceWidthCached`;失败则降级 approx 并 meta.reason 标记
- [x] widthMode=APPROX直接 approx并 meta.reason=WIDTH_UNKNOWN
- [x] 硬约束过滤:
- [x] 禁止空行、maxLines、TC H6
- [x] 若 width 可用且 > availableWidth过滤仅 MEASURE 可信)
- [x] 评分:`scoreLayout` + `buildTieKey`
- [x] 全局 newBeams 维护 TopKbeamK
- [x] 结束:从 beams 中选 pos==N 最优,否则 NO_CANDIDATE
## 5. 单测Vitest
- [x] 新建 `client/src/features/textWrap/searchWidget/__tests__/searchWidget.test.ts`
- [x] 确定性:同输入重复执行结果一致
- [x] widthMode=APPROX仍可输出且 meta.reason=WIDTH_UNKNOWN
- [x] 性能约束expandM/beamK 生效(可统计测量/扩展次数)
- [x] TC H6行首标点被禁止
## 6. 收尾
- [x] 跑测试与类型检查
- [x] `npm test`
- [x] `npx tsc --noEmit`
- [x] 将本 `tasks.md` 全部勾选完成
- [x] 更新 `spec_kit/overview.md`
- [x] 标记 `search-engine-widget` 已完成编码(阶段性)
- [x] 写入变更文件清单