From dccedf372efa9611c953ce15cacfc20ea39ca204 Mon Sep 17 00:00:00 2001 From: jesse-ux Date: Fri, 18 Sep 2026 18:29:56 +0800 Subject: [PATCH] =?UTF-8?q?fix(web):=20=E8=81=8A=E5=A4=A9=E5=88=97?= =?UTF-8?q?=E8=A1=A8=E6=81=A2=E5=A4=8D=E9=A1=B9=E7=9B=AE=E7=AC=A6=E5=8F=B7?= =?UTF-8?q?=EF=BC=8C=E6=94=B6=E7=B4=A7=E5=AE=9A=E4=B9=89=E5=88=97=E8=A1=A8?= =?UTF-8?q?=EF=BC=8C=E5=8E=8B=E6=80=9D=E8=80=83=E6=9D=A1=E9=97=B4=E8=B7=9D?= =?UTF-8?q?=EF=BC=88BUG-962/963/964=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 4 ++ docs/BUG_HISTORY.md | 48 +++++++++++++ .../PROGRESS-chat-markdown-list-20260918.md | 63 ++++++++++++++++++ docs/tasks/README.md | 4 +- .../chat-markdown-list-20260918-after.png | Bin 0 -> 54387 bytes docs/testing/chat-markdown-list-20260918.md | 23 +++++++ frontend/DESIGN.md | 10 ++- frontend/src/app/globals.css | 23 ++++++- frontend/src/lib/chat-definition-lists.ts | 11 ++- frontend/tests/chat-definition-lists.test.ts | 13 ++++ frontend/tests/chat-stream-layout.test.ts | 19 +++++- .../tests/rectification-agentic-entry.test.ts | 5 +- 12 files changed, 214 insertions(+), 9 deletions(-) create mode 100644 docs/tasks/PROGRESS-chat-markdown-list-20260918.md create mode 100644 docs/testing/chat-markdown-list-20260918-after.png create mode 100644 docs/testing/chat-markdown-list-20260918.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 2daa9d37..77a9ca5c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,10 @@ 合同没跑完但模型写了字时,那段回答会先按句子过一遍合规门:保证性结论整句拿掉,其余留下,并注明这次没跑完星盘计算。不会只丢一句说明、上面空空的。同一轮重试过的旧稿不会再拼进这次回答。Skill 版本不变。 +## 2026-09-18 — 聊天列表画出符号,思考条贴紧正文 + +回答里的清单重新画出圆点和序号,不再只是往右缩进的孤行。口语段落里的冒号不会再被改成列表。思考条和正文之间的空隙收成一档。Skill 版本不变。 + ## 2026-09-18 — 申报时段咨询重新能回答 只知道一段出生范围时,问事业 / 运势会在几十毫秒内失败,提示「未完成必要的方法与计算步骤」,从八月下旬起一直如此。根因是这条路线的助手装了方法校验、却没把方法写进系统提示,模型一次都没被叫到。现在方法已经装上;没有跑完计算但模型写过字时,会把那段留下并注明「没跑完星盘计算」,不再整轮空白。Skill 版本不变。 diff --git a/docs/BUG_HISTORY.md b/docs/BUG_HISTORY.md index 043bf6a4..164bf380 100644 --- a/docs/BUG_HISTORY.md +++ b/docs/BUG_HISTORY.md @@ -12664,6 +12664,54 @@ - 复发自:无 - 修复版本:`5b6abc23` +## BUG-962 | 聊天正文列表没有项目符号 + +- 状态:resolved +- 首次发现:2026-09-18 +- 最近更新:2026-09-18 +- 影响面:`.message-markdown ul.markdown-list` / `ol.markdown-list`(聊天正文,不含个人报告 Markdown) +- 用户现象:回答里的清单只是往右缩进的孤行,看不出是列表;正文段落靠左、列表块缩进,页面出现两级左边界。 +- 触发条件:助手回答含 bullet / 有序列表,或 `promoteDefinitionLists` 提升出的列表。Tailwind v4 preflight 把 `ul, ol` 的 `list-style` 清成 `none`。 +- 根因:`.markdown-list` 设了 `display: grid`、`gap`、`padding-inline-start`,没有恢复 `list-style`。 +- 修复:`ul.markdown-list` 用 `list-style-type: disc`,`ol.markdown-list` 用 `decimal`;`::marker` 取 `--color-ink-secondary`。保持 `display: grid`。不改 `personal-report-markdown-view`。 +- 验证:`frontend/tests/chat-stream-layout.test.ts` 源码断言该选择器块含 `list-style-type`(ul=disc / ol=decimal)。 +- 防复发:`.markdown-list` 规则块必须含 `list-style`;不得再只设缩进不设符号。 +- 相关记录:BUG-356、BUG-963、BUG-964 +- 复发自:无 +- 修复版本:待发布 + +## BUG-963 | 四标题口语散文被自动提升成列表 + +- 状态:resolved +- 首次发现:2026-09-18 +- 最近更新:2026-09-18 +- 影响面:`promoteDefinitionLists`(`frontend/src/lib/chat-definition-lists.ts`) +- 用户现象:申报时段回答里三段带冒号的散文被改写成三条列表项,和文末真正的行动清单同一种样式。 +- 触发条件:BUG-943 之后本命/窗口正文是四标题口语体,段落经常写成「你这半年的事业是 X:……」「推的是火星:……」。连续 ≥2 段被旧判据当成并列定义项。 +- 根因:`DEFINITION_LINE = /^(.{2,80}?)[::](.+)$/` 的 term 允许含句号,body 只要求 `length >= 4`。一段一百多字的多句散文照样算「解释」。 +- 修复:收紧,不删除。连续 ≥2 段且同时满足:term 不含句末标点 `。!?;!?;` 与换行;body 是单句(不含句末标点,或仅以一个句末标点收尾);body ≤ 40 字。仍跳过 fence 与已有列表。BUG-356 的并列短项(如「情绪与精力契合。」)继续提升。 +- 验证:`frontend/tests/chat-definition-lists.test.ts` 既有 BUG-356 fixture 仍绿;新增申报时段口语 fixture 保持三段原文,不产出 `- **term**:`。 +- 防复发:不得放宽 term 句末标点或 body 长度上限来「多提升一些」;散文冒号不是列表。 +- 相关记录:BUG-356、BUG-943、BUG-962 +- 复发自:BUG-356(并列短项提升判据过宽,口语体冒号段被误伤) +- 修复版本:待发布 + +## BUG-964 | 思考条与正文之间空 56px + +- 状态:resolved +- 首次发现:2026-09-18 +- 最近更新:2026-09-18 +- 影响面:`.consultation-thinking-report`、`.message-stage-and-answer`、会话作用域 `.message-markdown h2` +- 用户现象:思维链和正文中间间隔好大。harness 实测思考条底到正文首标题 56px。 +- 触发条件:会话里助手回答以 `h2` 开头(四标题口语体的「先回答你的问题」)。 +- 根因:56px = `.consultation-thinking-report { gap: 24px }` + 首个 `h2` 的 `margin-top: 32px`。`.message-markdown > *:first-child { margin-top: 0 }` 被更高特指度的 `.conversation:not(.is-empty):not(.is-rectification) .message-markdown h2 { margin: var(--space-8) 0 var(--space-3) }` 盖掉。另一条路径 `.message-stage-and-answer` 的 gap 只有 8px。 +- 修复:会话作用域补 `.message-markdown > *:first-child { margin-top: 0 }`(无 `!important`)。两条路径的 gap 都改读 `--consult-think-answer-gap`(`var(--space-3)` = 12px)。会话 `.markdown-list` 的 gap 从 `--space-4`(16px)降到 `--space-2`(8px)。 +- 验证:`frontend/tests/chat-stream-layout.test.ts` 锁会话 first-child 清零、两处 gap 同一 token、列表符号恢复。headless Chrome:`gapPx=12`,`h2MarginTop=0px`,`listStyle=disc`。截图 `docs/testing/chat-markdown-list-20260918-after.png`。 +- 防复发:思考条与正文间距不得再各写各的;会话作用域不得让首元素 `h2` 再带 `--space-8` 的 margin-top。 +- 相关记录:BUG-962、BUG-356 +- 复发自:无 +- 修复版本:待发布 + ## BUG-968 | 账户弹窗打开后整个弹窗点不动,退出登录做不了 diff --git a/docs/tasks/PROGRESS-chat-markdown-list-20260918.md b/docs/tasks/PROGRESS-chat-markdown-list-20260918.md new file mode 100644 index 00000000..9e622bf8 --- /dev/null +++ b/docs/tasks/PROGRESS-chat-markdown-list-20260918.md @@ -0,0 +1,63 @@ +# PROGRESS · 回答正文的列表渲染(2026-09-18) + +- 分支:`codex/chat-markdown-list-20260918`,worktree `.worktrees/chat-markdown-list-20260918` +- 基线:`origin/staging` @ `1061514f`(任务书写 `ea0280c1`,本 worktree 从当时 origin/staging 拉出) +- BUG:962 / 963 / 964 +- Skill 版本:不变 + +## 1. 做了什么 + +| BUG | 落点 | +| --- | --- | +| 962 列表无符号 | `globals.css`:`.message-markdown ul.markdown-list { list-style-type: disc }`,`ol` 用 `decimal`;`::marker` 用 `--color-ink-secondary`。保持 `display: grid`。不动个人报告 Markdown。 | +| 963 散文被提升 | `chat-definition-lists.ts`:收紧 `isDefinitionLine`,不删函数。term 不得含 `。!?;!?;` / 换行;body 必须单句且 ≤ 40 字;仍要连续 ≥2 段,仍跳过 fence 与已有列表。 | +| 964 思考条空 56px | 新增 `--consult-think-answer-gap: var(--space-3)`(12px),`.consultation-thinking-report` 与 `.message-stage-and-answer` 都读它。会话作用域补 `.message-markdown > *:first-child { margin-top: 0 }`,盖过 h2 的 `--space-8`。会话 `.markdown-list` gap 从 `--space-4`(16px)降到 `--space-2`(8px)。 | + +BUG-356 防复发仍在:既有 fixture「月亮行运三分本命太阳……:情绪与精力契合。」等短项继续提升成 `- **term**:body`。那些 body 最长约 10 字,远低于 40。 + +## 2. 间距口径(headless Chrome 实测) + +改前(任务书 harness):思考条底 → 正文首标题 **56px** = 报告 gap 24 + h2 margin-top 32,`list-style: none`。 + +改后(本机 Chrome headless,`renderChatMarkdown` + 会话作用域 CSS + Tailwind preflight 的 `ul, ol { list-style: none }`): + +``` +{"gapPx":12,"h2MarginTop":"0px","reportGap":"12px","listStyle":"disc","pCount":3,"liCount":2,"firstChild":"H2"} +``` + +| 项 | 改前 | 改后 | +| --- | --- | --- | +| `.consultation-thinking-report` gap | `--space-6`(24px) | `--consult-think-answer-gap`(12px) | +| `.message-stage-and-answer` gap | `--space-2`(8px) | 同一 token(12px) | +| 会话首元素 `h2` margin-top | `--space-8`(32px,特指度压过清零) | 0px | +| 思考条底 → 正文首标题 | 56px | **12px**(≤ 16px) | +| 会话 `.markdown-list` gap | `--space-4`(16px) | `--space-2`(8px) | +| 列表 `list-style-type` | `none` | `disc` | +| 三段口语冒号段 | 三条 `
  • ` | 三个 `

    `;只有文末行动是列表 | + +截图:`docs/testing/chat-markdown-list-20260918-after.png`。步骤仍写在 `docs/testing/chat-markdown-list-20260918.md`。 + +## 3. 被改的既有断言(原值 / 新值 / 原因) + +| 文件 · 测试 | 原值 | 新值 | 原因 | +| --- | --- | --- | --- | +| `tests/chat-stream-layout.test.ts` | `.message-stage-and-answer { gap: var(--space-2) }` | `gap: var(--consult-think-answer-gap)`,并新增 thinking-report 同 token、first-child 清零、ul/ol `list-style-type` | BUG-964 / 962 | +| `tests/rectification-agentic-entry.test.ts` | 同上 `--space-2` | 同上 `--consult-think-answer-gap` | 同一 token,校正面也走这条堆叠 | + +`chat-definition-lists.test.ts` 既有「consecutive label-colon paragraphs become a markdown list」**一字未改**且须保持绿。 + +## 4. 测试 + +| 项 | 结果 | +| --- | --- | +| `tsc --noEmit` | 0 错 | +| `npm run lint` | 0 error / 120 warning(未新增;未顺手修) | +| `tsx --test tests/chat-definition-lists.test.ts` | 3/3 | +| `tsx --test tests/chat-stream-layout.test.ts` | 6/6 | +| `tsx --test tests/chat-markdown-split.test.ts` | 5/5 | +| `tsx --test tests/markdown-code-block-contract.test.ts` | 5/5 | +| `tsx --test tests/rectification-agentic-entry.test.ts` | 43/43 | +| `npm test` 全量 | tests 3458 / pass 3380 / fail 78。多出来的红是本机 Windows 环境:`G:\G:\…` 路径加倍、symlink EPERM、无 Docker 的 database/backup。与本轮 CSS/lib 无关。任务书 Linux 基线是 3501 / 3455 / 31。 | +| `next build` | 未跑。本轮只动 CSS 与一个 lib,首屏 gzip 预期接近 0;staging 验收时再核 `/` 仍 Static。 | + +Chrome headless 改后:`gapPx=12`(≤16)、`listStyle=disc`、三段口语仍是 `

    `。 diff --git a/docs/tasks/README.md b/docs/tasks/README.md index 3a5cb4f1..5c92a715 100644 --- a/docs/tasks/README.md +++ b/docs/tasks/README.md @@ -140,8 +140,8 @@ | `TASK-consult-pass4-streaming-20260918.md` | `PROGRESS-consult-pass4-streaming-20260918.md` | 验收 review 三轮:Pass 4 一 hold 正文就整段蹦出、逐字流式消失(BUG-950 产品拍板按句放行);无出生分钟模式整段被一句拒绝顶掉、一般知识句一起丢(951 改按句丢弃);该模式下日期不留痕(952);校正流 token 级 thinking 是死链,按 P2 删除并把测试翻转成否定合同(953)。基线 `1e553976` | 待验收 | `cd4775ae` | | `TASK-window-consult-contract-20260918.md` | `PROGRESS-window-consult-contract-20260918.md` | **P0 线上**:申报时段模式**自 2026-08-21 起每轮秒败**(69ms、0 token、模型从未被调用)。服务端日志实证根因:窗口 Agent attach 了 `jyotishSkillBinding()`,但 `windowJyotishInstructions` 从来不含方法块 marker,输入处理器直接 abort(BUG-954)。abort 与「模型没调工具」同码,是它藏四周的原因(955);另含合同未绿不得丢正文(956)、计算不该由模型触发(957,须等 954 上线后另轮)、窗口指令应期冲突(958)。基线 `9cdcf96b` | 已验收通过(Claude:tsc 0 / lint 0 error / npm test 3501 条 31 红同基线 / `/` Static / gzip 无变化;实跑确认窗口 Agent 指令已含 marker);review 另出 BUG-959~961 见下一行 | `5b6abc23` | | `TASK-contract-degraded-pass4-20260918.md` | `PROGRESS-contract-degraded-pass4-20260918.md` | 验收 review:BUG-956 新增的降级交付路径绕过 Pass 4,保证句原样送达(BUG-959);`uncontractedText` 跨 attempt 不清零,同一轮正文说两遍(960);降级后还空跑一轮 compose(961)。基线 `877128ce` | 待验收 | `e07d5190` | -| `TASK-window-consult-contract-20260918.md` §5 | `PROGRESS-window-consult-precompute-20260918.md` | BUG-957:申报时段计算改为服务端预跑并走同请求缓存。产品确认 BUG-954 已在 staging 验证,本轮单独做。不得 `toolChoice: "required"`,本命不预跑 | 待验收 | `59788ac6` | -| `TASK-chat-markdown-list-20260918.md` | — | 真机排版反馈:聊天正文列表**没有项目符号**(Tailwind v4 preflight 清了 `list-style`,`.markdown-list` 没恢复,BUG-962);`promoteDefinitionLists` 把四标题口语体的散文误判成并列项,三段正文被改写成列表(BUG-963,判据太松,收紧而非删除——BUG-356 的场景要留);思考条与正文之间实测 56px=报告 grid gap 24 + 首标题 margin-top 32,后者是被特指度压掉的「首元素清零」规则(BUG-964)。基线 `ea0280c1` | 待领取 | — | +| `TASK-window-consult-contract-20260918.md` §5 | `PROGRESS-window-consult-precompute-20260918.md` | BUG-957:申报时段计算改为服务端预跑并走同请求缓存。产品确认 BUG-954 已在 staging 验证,本轮单独做。不得 `toolChoice: "required"`,本命不预跑 | 待验收 | `efd40d43` | +| `TASK-chat-markdown-list-20260918.md` | `PROGRESS-chat-markdown-list-20260918.md` | 真机排版反馈:聊天正文列表**没有项目符号**(Tailwind v4 preflight 清了 `list-style`,`.markdown-list` 没恢复,BUG-962);`promoteDefinitionLists` 把四标题口语体的散文误判成并列项,三段正文被改写成列表(BUG-963,判据太松,收紧而非删除——BUG-356 的场景要留);思考条与正文之间实测 56px=报告 grid gap 24 + 首标题 margin-top 32,后者是被特指度压掉的「首元素清零」规则(BUG-964)。基线 `ea0280c1` | 待验收 | `8b102d52` | | `TASK-secondary-page-entry-20260918.md` | — | 真机反馈:星盘 / 星历 / 报告进入时抖一下——三页都是「矮的等待文案块 → 高的正文块」一次推挤,且 `use-chart-page` 无缓存所以每次进入都抖(BUG-966)。产品已拍板方案一:统一外壳 + 缓存 + 预取消灭中间态,**不加 spinner**,红线不动。另含 BUG-967:标签页跨过部署后客户端导航静默失效(BUG-965 已复现确认,刷新即恢复),要按 `NEXT_PUBLIC_GIT_COMMIT` 与 `/api/health` 比对自愈。基线 `41902067` | 待领取 | — | | `TASK-account-dialog-inert-20260918.md` | — | 真机:账户弹窗打开后整个弹窗点不动、退出登录做不了,刷新依旧——`e4e73f56` 把 `SidebarInset` 搬进 layout 后 `inert={modalOpen}` 罩住了没有 portal 的 `AccountDialogOverlay`(BUG-968,P0,代码级确认)。另含 BUG-969:校正「换一件事问」后无下文,服务端已出下一题且快照重算完整,客户端停在开场状态,GET 路由与客户端两端静默,本单只做可观测 + 不静默 + 题干进正文。基线 `1061514f` | 待领取 | — | | `TASK-first-paint-dead-screen-fallback-20260917.md` | — | 真机:首页永远停在「正在载入账户」,兜底全在没跑起来的 bundle 里(BUG-936 investigating)。根 layout 加与 bundle 无关的内联兜底 + 去掉本仓正则后行断言 | 待领取 | — | diff --git a/docs/testing/chat-markdown-list-20260918-after.png b/docs/testing/chat-markdown-list-20260918-after.png new file mode 100644 index 0000000000000000000000000000000000000000..356300f063c987745252537673dc4db05e36fcc1 GIT binary patch literal 54387 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 a^$VXBLHNik9v|p$UWf@v3zqWh`u;D_aRoL2 literal 0 HcmV?d00001 diff --git a/docs/testing/chat-markdown-list-20260918.md b/docs/testing/chat-markdown-list-20260918.md new file mode 100644 index 00000000..a2b2c8b3 --- /dev/null +++ b/docs/testing/chat-markdown-list-20260918.md @@ -0,0 +1,23 @@ +# 真人验收 · 聊天列表符号、散文不提升、思考条间距(2026-09-18) + +本机有 Chrome,无登录态。headless 已用 `renderChatMarkdown` + 会话 CSS 量过改后数字(见下)。staging 真机走查仍欠。 + +## 产品可见 + +1. 打开一段带清单的助手回答(文末「这周可以做的一件事」那种短行动,或模型自己写的 `-` 列表):每条前面有圆点,符号颜色是次级文字色,不是纯黑。 +2. 打开一段申报时段 / 四标题口语体回答(「先回答你的问题」起头,正文里有「你这半年的事业是……:……」「推的是火星:……」):这三段仍是段落,不是三条列表。文末真正的行动清单才是列表。 +3. 同一条回答里,思考条底边到正文第一个标题之间不要空出一块「像缺了一行」的空白。目测大约一个小间距(12px 量级),不要再是将近两行的空隙。 +4. 个人报告页的 Markdown 列表样子不变。 + +## 量思考条到正文的 gap(headless Chrome,本轮未跑) + +改前 harness 数字(任务书已测):`gapPx=56`,其中报告 grid gap 24px + 首个 `h2` margin-top 32px,`listStyle=none`。 + +改后实测(本机 headless Chrome):`gapPx=12`,`h2MarginTop=0px`,`reportGap=12px`,`listStyle=disc`,三段口语仍是 `

    `。截图 `docs/testing/chat-markdown-list-20260918-after.png`。 + +步骤: + +1. 用仓库自己的渲染管线跑 `renderChatMarkdown(answer)`(`frontend/src/components/chat-markdown-view.tsx`),`answer` 以 `## 先回答你的问题` 开头。 +2. 套 `next build` 产物里的 CSS chunk,容器 class 同时带 `conversation`(不要 `is-empty` / `is-rectification`)、`consultation-thinking-report`、`message-markdown`。思考条用一个固定高度的占位块。 +3. headless Chrome 里对思考条底与首个 `h2` 顶做 `getBoundingClientRect`,记录 `gapPx`、`h2MarginTop`、`reportGap`、列表的 `listStyleType`。 +4. 截 `.message-markdown`(改前改后各一张)。数字写进本轮进度记录,不要口算。 diff --git a/frontend/DESIGN.md b/frontend/DESIGN.md index 29e77a8d..c2f9632a 100644 --- a/frontend/DESIGN.md +++ b/frontend/DESIGN.md @@ -186,7 +186,7 @@ One documented exception: the thinking text inside a timeline step (`.consultati ## 4. Spacing & Layout -The base unit is 4px. Tokens are `--space-1: 4px`, `--space-2: 8px`, `--space-3: 12px`, `--space-4: 16px`, `--space-5: 20px`, `--space-6: 24px`, `--space-8: 32px`, `--space-10: 40px`, `--space-12: 48px`, `--space-16: 64px`, and `--space-24: 96px`. +The base unit is 4px. Tokens are `--space-1: 4px`, `--space-2: 8px`, `--space-3: 12px`, `--space-4: 16px`, `--space-5: 20px`, `--space-6: 24px`, `--space-8: 32px`, `--space-10: 40px`, `--space-12: 48px`, `--space-16: 64px`, and `--space-24: 96px`. `--consult-think-answer-gap` is `var(--space-3)` (12px): it is the only gap between the thinking bar and the answer body. Both `.consultation-thinking-report` and `.message-stage-and-answer` use it; do not write a second value on either path. Radii have two visual steps. Controls use 8px (`--radius-md`; `--radius-xs` and `--radius-sm` alias that value). Cards and sheets use 12px (`--radius-lg`; `--radius-xl` aliases it). Circles stay `50%`; pills stay `999px`. @@ -755,6 +755,14 @@ Admin 的 antd `` 是独立设计系统,不在此表。 - **窄屏表格:** 三列表(技法审计)继续卡片化。四列及以上(Yoga、统一参数)在 `.conversation` 里横向滚动,右缘用 canvas 渐隐提示还可滑;`.conversation` 自身 `overflow-x: hidden`,页面不得出现横向滚动条。个人报告表格不走这套规则。 - **表单输入 16px:** 全局 `input` / `select` 用 `--type-body-md`(16px)。iOS Safari 对小于 16px 的字段聚焦时会整页放大且不缩回。`.otp-input` 仍是 20px,`.composer textarea` 仍是 16px。 +### Chat body lists + +Three product rules for assistant markdown in `.message-markdown` (BUG-962 / 963 / 964). Personal-report markdown (`personal-report-markdown-view`) is a different surface and is not restyled here. + +- **Lists have markers.** `.message-markdown ul.markdown-list` is `list-style-type: disc`; `ol.markdown-list` is `decimal`. `::marker` uses `--color-ink-secondary`, not ink. Tailwind v4 preflight zeros `ul, ol { list-style }`; this surface must restore it. Keep `display: grid` — markers render with grid. +- **Prose is not auto-promoted to lists.** `promoteDefinitionLists` still lifts consecutive short `term:body` blocks (BUG-356: parallel transit / advice items). A block promotes only when every one of these holds, and still only for ≥2 consecutive blocks: the term has no sentence-end punctuation (`。!?;!?;`) and no newlines; the body is a single sentence (no sentence-end, or exactly one at the end); the body is ≤ 40 characters; fences and existing lists are skipped. Spoken four-heading prose with a colon inside a long paragraph stays paragraphs. +- **Thinking-bar-to-body spacing is one token.** `--consult-think-answer-gap` (`var(--space-3)` = 12px) is the gap on both `.consultation-thinking-report` and `.message-stage-and-answer`. In conversation scope, `.message-markdown > *:first-child { margin-top: 0 }` so an opening `h2` does not add `--space-8` on top of that gap. Conversation `.markdown-list` item gap is `--space-2` (8px). + ## 14. 断点 宽度切点只允许出现在 `globals.css` 顶部注释的白名单里。壳层切点以 `sidebarViewportForWidth` 为准:小于 768 移动,小于 1024 平板,否则桌面。组件级栅格(会员方案卡、校正候选)用 640/641。校正独立问题块(`.rectification-message-question.is-standalone`)与助手正文共用 `--assistant-content-inset`。报告目录在 860 塌成抽屉,因为那是第三栏的内容宽度,不是设备宽度。 diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css index 2ee41cff..62ac86b5 100644 --- a/frontend/src/app/globals.css +++ b/frontend/src/app/globals.css @@ -163,6 +163,10 @@ --space-12: 48px; --space-16: 64px; --space-24: 96px; + /* Gap between the thinking bar and the answer body. Both stacked paths + (timeline report and stage-and-answer) must use this token — do not + write a second value on either (BUG-964). */ + --consult-think-answer-gap: var(--space-3); --composer-reserve: 124px; --ease-out: cubic-bezier(.22, 1, .36, 1); /* The personal report's paper surface. Declared here so the dark blocks can @@ -556,7 +560,7 @@ button:disabled { cursor: default; opacity: .45; } .agent-thinking-panel + .message-answer { margin-top: var(--space-2); } .message-stage-and-answer { display: grid; - gap: var(--space-2); + gap: var(--consult-think-answer-gap); } .message-stage-and-answer .agent-thinking-panel, .message-stage-and-answer .agent-activity-status { @@ -1196,7 +1200,7 @@ button:disabled { cursor: default; opacity: .45; } } .consultation-thinking-report { display: grid; - gap: var(--space-6); + gap: var(--consult-think-answer-gap); } .consultation-report-analysis { min-width: 0; @@ -1340,6 +1344,15 @@ button:disabled { cursor: default; opacity: .45; } margin: var(--space-3) 0 var(--space-5); padding-inline-start: 1.35em; } +.message-markdown ul.markdown-list { + list-style-type: disc; +} +.message-markdown ol.markdown-list { + list-style-type: decimal; +} +.message-markdown .markdown-list ::marker { + color: var(--color-ink-secondary); +} .message-markdown .markdown-list > li { padding-block: 0; padding-inline-start: 6px; @@ -2343,7 +2356,7 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class } .conversation:not(.is-empty):not(.is-rectification) .message-markdown .markdown-list { - gap: var(--space-4); + gap: var(--space-2); } .conversation:not(.is-empty):not(.is-rectification) .markdown-table { @@ -2355,6 +2368,10 @@ input:not([type="radio"]):not([type="checkbox"]):not([class^="ant-"]):not([class margin: var(--space-8) 0 var(--space-3); } +.conversation:not(.is-empty):not(.is-rectification) .message-markdown > *:first-child { + margin-top: 0; +} + .conversation:not(.is-empty):not(.is-rectification) .message-markdown h2 { font-size: var(--type-title-lg); } diff --git a/frontend/src/lib/chat-definition-lists.ts b/frontend/src/lib/chat-definition-lists.ts index 0d14ee33..57a5d718 100644 --- a/frontend/src/lib/chat-definition-lists.ts +++ b/frontend/src/lib/chat-definition-lists.ts @@ -1,17 +1,26 @@ const FENCE = /(```[\s\S]*?```)/; const DEFINITION_LINE = /^(.{2,80}?)[::](.+)$/u; +const SENTENCE_END = /[。!?;!?;]/u; +const BODY_MAX_CHARS = 40; function isSkippableLine(line: string): boolean { return /^(#{1,6}\s|>\s|[-*+]\s|\d+[.)]\s|\|)/.test(line) || line.startsWith("```"); } +function isSingleSentence(text: string): boolean { + return !SENTENCE_END.test(text.replace(/[。!?;!?;]$/u, "")); +} + function isDefinitionLine(block: string): boolean { const trimmed = block.trim(); if (!trimmed || trimmed.includes("\n") || isSkippableLine(trimmed)) return false; const match = DEFINITION_LINE.exec(trimmed); if (!match) return false; + const term = match[1]?.trim() ?? ""; const body = match[2]?.trim() ?? ""; - return body.length >= 4; + if (body.length < 4 || body.length > BODY_MAX_CHARS) return false; + if (SENTENCE_END.test(term)) return false; + return isSingleSentence(body); } function toListItem(block: string): string { diff --git a/frontend/tests/chat-definition-lists.test.ts b/frontend/tests/chat-definition-lists.test.ts index f9263bee..b4f2a17a 100644 --- a/frontend/tests/chat-definition-lists.test.ts +++ b/frontend/tests/chat-definition-lists.test.ts @@ -29,3 +29,16 @@ test("code fences and existing lists are left alone", () => { ].join("\n"); assert.equal(promoteDefinitionLists(source), source); }); + +test("spoken four-heading prose with a colon stays paragraphs", () => { + const prose = [ + "你这半年的事业是「外刚内不承」:表面硬气是真的硬——你确实扛得住场面,底下却承不住。别人看见的是硬气,盘上撑着的是另一层。", + "", + "推的是火星:事情由你自己起动、自己顶上去。别人帮不上忙,你也没法把责任分出去,更别指望场面自己圆。", + "", + "所以别去应火星的「硬顶」,也别去应土星弱位的「拖」。去扮演太阳的「署名」:把事做成一件能签字的作品,而不是一场硬顶。", + ].join("\n"); + const result = promoteDefinitionLists(prose); + assert.equal(result, prose); + assert.equal(result.includes("- **"), false); +}); diff --git a/frontend/tests/chat-stream-layout.test.ts b/frontend/tests/chat-stream-layout.test.ts index 348ad975..ba92814c 100644 --- a/frontend/tests/chat-stream-layout.test.ts +++ b/frontend/tests/chat-stream-layout.test.ts @@ -80,7 +80,24 @@ test("shows honest agent activity states before and during streamed text", () => assert.doesNotMatch(messageRowSource, /vargaSentence=\{showThinkingPanel \? null : vargaSentence\}/); assert.match(messageRowSource, / \*:first-child \{[\s\S]*margin-top:\s*0/, + ); + assert.match(globalStyles, /\.message-markdown ul\.markdown-list \{[\s\S]*list-style-type:\s*disc/); + assert.match(globalStyles, /\.message-markdown ol\.markdown-list \{[\s\S]*list-style-type:\s*decimal/); + assert.match(globalStyles, /\.markdown-list[^{]*\{[^}]*list-style/); + assert.match( + globalStyles, + /\.conversation:not\(\.is-empty\):not\(\.is-rectification\) \.message-markdown \.markdown-list \{[\s\S]*gap:\s*var\(--space-2\)/, + ); + assert.match(globalStyles, /\.markdown-list ::marker \{[\s\S]*color:\s*var\(--color-ink-secondary\)/); assert.match(globalStyles, /\.agent-activity-status \+ \.message-answer/); // Former lock: `