diff --git a/.project-docs/30-worklog/tasks/20260929-teacher-prompt-buttons-a682d30f.md b/.project-docs/30-worklog/tasks/20260929-teacher-prompt-buttons-a682d30f.md index 87a93cb0..726a8873 100644 --- a/.project-docs/30-worklog/tasks/20260929-teacher-prompt-buttons-a682d30f.md +++ b/.project-docs/30-worklog/tasks/20260929-teacher-prompt-buttons-a682d30f.md @@ -20,7 +20,7 @@ ## Outcome -- Configured teacher shortcuts sit outside and directly above the composer. Latest approved styling uses 13px normal green text, no fill/border/shadow, a small chevron and hover underline; wrapping/overflow/keyboard focus supported. +- Configured teacher shortcuts sit outside and directly above the composer. Latest approved styling uses 13px/600 green text with a subtle text shadow, no fill/border/box shadow, a small chevron and hover underline. The target-to-composer gap is 8px; wrapping/overflow/keyboard focus supported. - Adapted product/tests dependency from main 53d5b6b (bb96941); original source task record remains in its source commit, excluded from this feature boundary. Explicit empty arrays hide prompts; absent historical field retains approved fallback. Published label and prompt are unchanged. - Trial Renderer updated in place in PID 32583; Main and empty-work preview overlay remain intact. Live Alice cloud v53 supplies “继续看看咯”. @@ -37,7 +37,7 @@ ## Promotion Candidates -- Target: integrated classroom UI documentation. Proposal: configured prompts live above the composer as borderless body-size buttons with soft shadows; exact cloud labels/prompts, absent/empty compatibility and send guards retained. Evidence: user approval, 75 unit / 23 browser tests and live trial comparison. No product-policy conflict; canonical promotion belongs to integration. +- Target: integrated classroom UI documentation. Proposal: configured prompts live 8px above the composer as transparent 13px/600 clickable text with a subtle text shadow and hover underline; exact cloud labels/prompts, absent/empty compatibility and send guards retained. Evidence: user approval, 75 unit / 23 browser tests and live trial comparison. No product-policy conflict; canonical promotion belongs to integration. ## Project Context Loaded @@ -96,3 +96,14 @@ - Verification: four existing shortcut/layout scenarios passed at 319px and 508px (including click/prompt contract, eight long labels, focus, hover/pressed/reduced-motion, empty config and input/send position). Typecheck, full lint (0 errors / 8 existing warnings), source and combined trial production builds passed. Inspected browser screenshot. Task-aware docs drift and diff whitespace checks passed. - Updated only the live stylesheet to index-_6TMWSCY.css in PID 32583; no Renderer reload, Main restart, prompt or native focus call. Copied the latest Code-brand/hidden-model/group-intro composite before applying this CSS so peer work remains. Served index/assets also prepared for subsequent normal reload. Immediate swap remained unfocused. Read-only check confirmed transparent/none/13px/30px rules; route unchanged and no localStorage changes beyond normal auth state. The app loaded 14 messages after the initial empty snapshot and later became focused with its consultation open, so live message/input snapshots were not stationary and are not claimed byte-identical. No history or draft writes were performed. Inspector closed. - Evidence: /tmp/teacher-text-link-{browser,typecheck,lint,build,trial-build}.log, /tmp/teacher-text-link-results and trial teacher-text-shortcuts-a682d30f/verification.json. No main merge/push or cloud publication in this follow-up. + + +## Text Weight and Spacing Follow-up + +- Same-task ownership resumed at fd0b720; verified task/feature/branch/worktree and read peer scopes. Existing design/planning context reused unchanged. Latest trial sidebar-group overlay is unrelated and must be retained. No subagents or native activation; scope is only shortcut typography/spacing. Gate passed. +- User asks for bolder text, a text shadow, and closer placement above the composer. Plan: use 600 weight and a subtle 1px green text shadow; reduce group bottom margin from 10px to 2px while keeping focus-ring clearance (button-to-composer gap 16px to 8px). Preserve transparent background, no box shadow, labels, click behavior, 30px target and wrapping. Update existing layout assertions, run checks/build and hot-swap CSS from a copy of the latest composite trial. + +- Completed: 600 weight, 1px subtle green text shadow and 8px target-to-composer gap. Transparent background, no box shadow, cloud text/prompt, input visibility and click behavior unchanged. +- Verification: four existing browser scenarios at 319/508px passed, including exact shortcut sends, long-label overflow and focus/hover/pressed behavior. Browser screenshot inspected. Typecheck, full lint (0 errors / 8 existing warnings), source and composite production builds passed. +- Trial: copied the latest sidebar-groups composite and changed only shortcut CSS. Built stylesheet index-DLG7JTx3.css was activated in PID 32583 without Renderer reload or Main restart; installed composite assets for later normal reload. Read-only verification confirmed 13px/600 and rgba(83,105,73,0.25) text shadow. Route, storage, drafts, 14 operation messages and teacher contents are unchanged; focused=false before/after. Inspector closed. No live prompts, cloud publication or main merge/push. +- Evidence: /tmp/teacher-text-depth-{browser,typecheck,lint,build,trial-build}.log, /tmp/teacher-text-depth-results and temporary trial teacher-text-depth-a682d30f/verification.json. Task-aware docs and whitespace checks passed before commit. diff --git a/README.md b/README.md index 88e1bc49..03f0417d 100644 --- a/README.md +++ b/README.md @@ -183,7 +183,7 @@ Pi 正式包必须继续运行 `pnpm run verify:artifact:pi`、`pnpm run smoke:p - 咨询正文支持 Markdown 标题、列表、表格、代码围栏、HTTP(S) 链接/图片和数学公式,长代码与表格在栏内横向滚动,不执行 HTML。云端正文维持 string 合同,未知对象不会猜测转成回答。工具活动只从云端主线程的类型化工具事件及 Main 本地读取过程获得,按本次问题/工具调用身份合并名称和状态,跨云端暂停、续接仍只计一次;暂停读取不算失败,状态以实际读取结果或问题终态为准,单独折叠显示;参数、结果原文和内部错误不混入回复,思考内容不作为正文。客户端仅保存自己实际收到的工具状态,不能补回旧历史或断线期间已经过期的事件。 - 云端咨询在 local_context 声明 read_protocol=2;需先部署配套 Yuxi API 和 worker,再升级客户端。云端持久累计读取字节及批次,每轮告知模型剩余额度;预算耗尽后消费最后一批结果,并以 tool_choice=none 要求根据现有证据形成答案和说明缺口。Main 限制实际返回量并拒绝第十三批读取,区分读取达到上限、上下文失效及格式无效。服务端对未声明协议的已安装旧客户端保留原工具参数与六批边界。 - 智能体人设、职责、提示词和 Skills 由发布配置决定。Main 不追加固定教学基线、不生成“小麦”、不清空所选智能体的 Skills,只添加真实工具能力、上下文边界和本轮界面协议。智能体名称叫“老师”“朋友”或“代码顾问”不改变调用路径或权限。 -- 输入框为空时,在输入框外上方显示当前老师已发布的快捷提示;采用与回复正文一致的 13px 常规字重,显示为无底色、无边框、无阴影的绿色可点击文字与小箭头;悬停时文字加深并显示下划线,键盘聚焦有清晰轮廓,保留 30px 点击高度,横向排列并自动换行。按 Yuxi 中配置的顺序展示文案,点击直接发送该项实际提示词。Yuxi“编辑 → 快捷提示”支持最多 8 项,每项文案最多 40 字、提示词最多 6000 字;保存并发布后,目录更新即可生效,历史和未发送草稿保留。明确发布空列表隐藏全部按钮;缺少字段的历史版本保留“帮我整体看🧠”。多个长文案在限定高度内滚动,运行中禁止重复发送。上线需先更新 WS 登记接口,再更新 Yuxi 和客户端。 +- 输入框为空时,在输入框外上方显示当前老师已发布的快捷提示;采用 13px 半粗字重和轻微文字阴影,显示为无底色、无边框、无块状阴影的绿色可点击文字与小箭头,入口距输入框 8px;悬停时文字加深并显示下划线,键盘聚焦有清晰轮廓,保留 30px 点击高度,横向排列并自动换行。按 Yuxi 中配置的顺序展示文案,点击直接发送该项实际提示词。Yuxi“编辑 → 快捷提示”支持最多 8 项,每项文案最多 40 字、提示词最多 6000 字;保存并发布后,目录更新即可生效,历史和未发送草稿保留。明确发布空列表隐藏全部按钮;缺少字段的历史版本保留“帮我整体看🧠”。多个长文案在限定高度内滚动,运行中禁止重复发送。上线需先更新 WS 登记接口,再更新 Yuxi 和客户端。 - `reply.ts` 只声明正文与快捷回复的输出格式,语言、长度、前缀与表达风格由所选智能体的云端配置决定。客户端不再发送选择、生成、转换或维护展示组件的指令。旧话题内的组件状态、快照和解析诊断作为不透明历史数据原样保留,不校验删除、不恢复交互;旧组件修改路由已移除。 - 当前输入是按预算截取的所选操作对话已完成分支文本、明确引用、咨询正文和快捷回复,并支持上述只读原文恢复;旧组件状态、快照和未解析原文不加入模型上下文或咨询历史读取结果。没有跨全部操作会话自动读取,也未向操作 Agent 注入咨询共识。提示词不声称看过未提供的画面或试玩过作品。Yuxi 话题经云端原生执行,旧版本地智能体由 Main 调用计费网关;均不创建本地 Pi 编程 worker。 - 智能体输入裁剪区分两种计量:本地模型以约每 2 个 UTF-8 字节估算 1 Token,并计入工具与读取预留;这不是精确分词或扣费依据,模型上限与实际 usage 仍由服务端拥有。云端沿用 query 字节上限,以完整 JSON 转义后的大小裁剪来源节选。智能体指令、当前问题和明确引用不会被静默裁掉;固定配置或回复协议超限时明确提示调整配置,避免让学生反复缩短短问题或新建话题。完整来源仍可由只读工具按需读取。 diff --git a/src/pages/Chat/classroom-workspace.css b/src/pages/Chat/classroom-workspace.css index 0501e0c6..122ba46d 100644 --- a/src/pages/Chat/classroom-workspace.css +++ b/src/pages/Chat/classroom-workspace.css @@ -52,8 +52,8 @@ .consultation-retry { display: inline-flex; align-items: center; justify-content: center; align-self: flex-start; min-height: 44px; max-width: 100%; padding: 8px 16px; border: 1.5px solid #e3ce8f; border-radius: 16px 16px 16px 6px; background: #fff2c9; color: #6f5127; box-shadow: 0 3px 0 #e7d7a6, inset 0 1px 0 #fff9e8; font-size: 14px; font-weight: 600; line-height: 24px; cursor: pointer; transition: background-color 160ms ease, border-color 160ms ease, box-shadow 160ms ease, transform 160ms ease; } .consultation-retry:hover:not(:disabled) { background: #ffe9a9; border-color: #d6b76f; } .consultation-retry:active:not(:disabled) { transform: translateY(2px); box-shadow: 0 1px 0 #e7d7a6, inset 0 1px 0 #fff9e8; } -.consultation-shortcuts { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 4px 16px; max-height: min(192px, 24vh); overflow-y: auto; margin-bottom: 10px; padding: 3px 4px 6px; } -.consultation-hint { display: inline-flex; align-items: center; gap: 7px; max-width: 100%; min-height: 30px; padding: 4px 2px; border: 0; border-radius: 4px; background: transparent; box-shadow: none; color: #536949; font-size: 13px; font-weight: 400; line-height: 22px; text-align: left; white-space: normal; overflow-wrap: anywhere; text-decoration: underline; text-decoration-color: transparent; text-decoration-thickness: 1px; text-underline-offset: 4px; cursor: pointer; transition: color 150ms ease, text-decoration-color 150ms ease; } +.consultation-shortcuts { display: flex; flex-wrap: wrap; align-items: flex-start; gap: 4px 16px; max-height: min(192px, 24vh); overflow-y: auto; margin-bottom: 2px; padding: 3px 4px 6px; } +.consultation-hint { display: inline-flex; align-items: center; gap: 7px; max-width: 100%; min-height: 30px; padding: 4px 2px; border: 0; border-radius: 4px; background: transparent; box-shadow: none; color: #536949; font-size: 13px; font-weight: 600; text-shadow: 0 1px 1px #53694940; line-height: 22px; text-align: left; white-space: normal; overflow-wrap: anywhere; text-decoration: underline; text-decoration-color: transparent; text-decoration-thickness: 1px; text-underline-offset: 4px; cursor: pointer; transition: color 150ms ease, text-decoration-color 150ms ease; } .consultation-hint::after { content: ''; width: 5px; height: 5px; flex-shrink: 0; border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor; transform: rotate(-45deg); opacity: 0.7; } .consultation-hint:hover:not(:disabled) { color: #304631; text-decoration-color: currentColor; } .consultation-hint:active:not(:disabled) { color: #243727; } diff --git a/tests/e2e/teacher-reply-layout.spec.ts b/tests/e2e/teacher-reply-layout.spec.ts index 10aec5bb..1c0d70c8 100644 --- a/tests/e2e/teacher-reply-layout.spec.ts +++ b/tests/e2e/teacher-reply-layout.spec.ts @@ -60,7 +60,8 @@ for (const width of [319, 508]) { const composer = panel.locator('.consultation-composer'); await expect(composer.locator('.consultation-hint')).toHaveCount(0); await expect(shortcuts.first()).toHaveCSS('font-size', await panel.getByTestId('teacher-reply').first().evaluate(el => getComputedStyle(el).fontSize)); - await expect(shortcuts.first()).toHaveCSS('font-weight', '400'); + await expect(shortcuts.first()).toHaveCSS('font-weight', '600'); + await expect(shortcuts.first()).not.toHaveCSS('text-shadow', 'none'); await expect(shortcuts.first()).toHaveCSS('border-top-width', '0px'); await expect(shortcuts.first()).toHaveCSS('box-shadow', 'none'); await expect(shortcuts.first()).toHaveCSS('background-color', 'rgba(0, 0, 0, 0)'); @@ -153,7 +154,7 @@ for (const width of [319, 508]) { const hintBounds = (await hint.boundingBox())!; expect(hintBounds.x).toBeLessThan(initialSend.x); expect(hintBounds.height).toBe(30); - expect(hintBounds.y + hintBounds.height).toBeLessThan((await page.locator('.consultation-composer').boundingBox())!.y); + expect((await page.locator('.consultation-composer').boundingBox())!.y - hintBounds.y - hintBounds.height).toBe(8); await page.getByTestId('teacher-chat-panel').screenshot({ path: test.info().outputPath(`composer-hint-${width}.png`) }); expect(await sent()).toEqual([]); await input.fill('我想先自己说说');