diff --git a/.project-docs/10-decisions/ADR-2026-09-22-coding-teacher.md b/.project-docs/10-decisions/ADR-2026-09-22-coding-teacher.md index 9640ff11..a9c39ac6 100644 --- a/.project-docs/10-decisions/ADR-2026-09-22-coding-teacher.md +++ b/.project-docs/10-decisions/ADR-2026-09-22-coding-teacher.md @@ -22,6 +22,7 @@ - Code 咨询统一使用服务端下发智能体,不内置老师/朋友角色、本地教学人设或按名称分配的工具权限。名称、头像、简介、欢迎语和推荐问题来自发布定义。所有下发项共享上述只读工具边界,通用讨论组件协议不定义智能体人格。 - 结构化讨论在聊天内按项目保存,历史轮保留原卡片快照。正文、历史和带回草稿仅接收云端主线程文本;子线程事件仍推进续传游标。带回回答只追加原项目/Pi 来源的草稿,不自动发送或改写当前其他来源。已下发智能体的旧 Renderer 定时跟进停止派发;新的 Main 主动观察由独立任务实施,本次未接入建议投递,后续必须并入同一聊天,不能恢复项目话题入口。 - 所有下发智能体以头像和名称在顶栏并排展示,溢出横向滚动。点击恢复唯一聊天或空态、独立草稿和未读,不调用模型;移除新话题加号和话题下拉框。旧原始记录保留单独只读入口。最近50轮先加载,历史分页与流事件按请求身份合并;切换智能体保留窗口内阅读位置,已读位置由 Main 持久保存。 +- 2026-09-28 远程刷新与界面改动合并:顶栏手动刷新只读共享下发目录和配置,更新联系人资料,不重建聊天、不切换选中智能体、不清空历史或草稿;已接受问题保留原版本,下一轮由 Main 固定当前发布版本。停用后保留原聊天但禁止发送。发布介绍在顶栏悬停/聚焦显示,点击当前入口或 Escape 收起咨询栏,边缘调宽保留;不再显示重复面板标题栏或下发智能体新话题入口。追加问题使用三色卡片。 - 未发送文字草稿按账号/智能体保存;明确引用仍携带项目/Pi 来源,来源切换后须移除旧引用或恢复原上下文才能发送。只导入已登记项目中能证明当前账号与 config_id 归属的旧话题,以项目/话题/请求来源身份去重,原文件保留;重复正文不去重,失联目录稍后重试。无法证明归属的朋友/旧老师历史及旧草稿只读保留,不猜测身份。移除项目不删除账号级聊天;现有云端 coding-teacher 名称不构成角色分类。 - 输入预算在编译时计入完整执行请求。本地旧模型路径按约 2 UTF-8 字节估算 1 Token,工具定义、调用和读取预留纳入同一计量;估算不替代模型上限或实际 usage。云端以完整 JSON 转义后的 query 字节数裁剪来源节选,原文仍可按 ID 读取。固定配置/当前讨论超限与用户问题/引用超限分别提示,不静默修改发布预算、问题、明确引用或话题版本。 diff --git a/.project-docs/20-architecture/system-overview.md b/.project-docs/20-architecture/system-overview.md index f81c6098..ed87ca61 100644 --- a/.project-docs/20-architecture/system-overview.md +++ b/.project-docs/20-architecture/system-overview.md @@ -7,6 +7,8 @@ Code 咨询由 Works Square 运营下发的 Yuxi 智能体执行,不内置老师/朋友分类。Main 按账号/稳定智能体 ID 保存唯一持续聊天,Renderer 按同一身份保存文字草稿。顶栏直接选择智能体,恢复历史/空态与未读;没有新话题加号或话题下拉框。每次接受问题固定当前项目、Pi 公开消息及发布版本;项目、Pi 来源或版本变化时只轮转内部 Yuxi 线程,带入有预算的公开近期交流。历史聊天文本不能扩大本轮文件范围。Main 执行三个只读工具并回传结果;学生支付咨询模型费用,个人 Agents 保持创建者付费。正文只接收云端主线程文本,其他线程事件仍推进游标。Code 默认 Agent、项目下操作会话及 Pi 执行保持项目边界。 +顶栏与打开的咨询栏共享 useTeacherCompanion 提供的只读目录/配置刷新结果;刷新入口独立于旧跟进条件,保持账号/智能体聊天及草稿身份。当前联系人资料可更新,执行版本仍由 Main 在每轮接受时冻结;介绍卡和真实气泡共同参与原生作品预览避让。 + TeacherConversationStore 在 userData/agent-conversations// 保存轻量索引和独立轮文件,每页50轮;SSE只发送当前轮与元数据,Renderer 按请求身份合并分页和流。Main 持久保存已读,阅读锚点只缓存在当前窗口。已登记项目的旧话题仅在账号和config_id明确时按来源身份导入,保留原文件;不明身份记录单独只读。讨论卡按项目保存,引用与带回操作核对原项目/Pi 来源。新下发聊天停止旧Renderer定时跟进;独立主动观察任务尚未纳入,未来建议须幂等投递同一聊天。详见[已接受决定](../10-decisions/ADR-2026-09-22-coding-teacher.md)。 ## Current Architecture diff --git a/.project-docs/30-worklog/current-state.md b/.project-docs/30-worklog/current-state.md index e0b62d28..45c1b9b0 100644 --- a/.project-docs/30-worklog/current-state.md +++ b/.project-docs/30-worklog/current-state.md @@ -4,6 +4,8 @@ This file is the integrated default-branch snapshot. Feature tasks record progre ## Integrated Through +- 2026-09-28:续接已批准的集成任务,将远程 `4495345fb0a9ea1abef8e603629ce9b51d73eb05` 与本地 `56da6b99111027e93ae34432fb52fdaa1a016384` 合并。保留账号/智能体唯一聊天、跨项目草稿及每轮项目/发布版本,接入共享手动刷新、顶栏悬停介绍和简化咨询栏;旧话题时代测试与说明已适配,未合入独立主动观察功能。120 项相关单测、标准类型检查、scoped lint、Vite 构建、3 项 Electron 交互与9项布局场景通过。3份原有未跟踪文档和远程来源记录保持原样;未推送、打包、部署或调用真实收费模型。见[续接集成记录](tasks/20260928-merge-agent-single-chat-9911c6df.md#remote-merge-resume)。 + - 2026-09-28:无冲突合入单会话源 `7aa81da616449dead25557476cf4f1433edf84b5`(含方案 `e54f3d2`)。每个账号与下发智能体使用唯一持续聊天,移除新话题入口,跨项目分页历史、独立草稿与持久已读;项目/Pi/发布版本下沉到每轮冻结,变化时只轮转内部Yuxi线程。旧记录按可证明的账号/配置身份导入,原文件保留。已按用户批准更新咨询ADR、架构和领域规则,取代下方历史条目的项目/版本可见话题规则。产品/测试与已验证源一致,沿用365项相关单测、Renderer typecheck、scoped lint、Vite构建及1项Electron交互;扩展Main仍为66项基线诊断。三份外来文档原样保留;未推送、打包、部署或调用真实收费模型。主动观察仍在独立任务,建议投递必须在其后续合并时衔接唯一聊天。见[源记录](tasks/20260928-agent-single-chat-27da516b.md)和[集成记录](tasks/20260928-merge-agent-single-chat-9911c6df.md)。 - 2026-09-28:无冲突快进合入诊断记录 `3779f33`,客户端产品及测试无变化。确认现有咨询按账号/项目保存,每个问题绑定当前 Pi 来源;配套 Yuxi 修复 `e96d8cf` 将话题准入与每问题上下文分开,允许同项目切换编程会话后继续原话题,旧历史无需删除。Yuxi 2260 项 unit(1 skipped)、10 项真实 HTTP/PostgreSQL/worker 集成及独立审查通过;本仓不为诊断文档重跑客户端构建。三份外来文档原样保留;未推送、打包、安装或部署,线上需更新 Yuxi API。见[源记录](tasks/20260928-consultation-scope-83fa19c2.md)和[集成](tasks/20260928-merge-consultation-scope-ml-7b56cbe4.md)。 diff --git a/.project-docs/30-worklog/tasks/20260928-agent-refresh-a6d109b3.md b/.project-docs/30-worklog/tasks/20260928-agent-refresh-a6d109b3.md new file mode 100644 index 00000000..fa2b4887 --- /dev/null +++ b/.project-docs/30-worklog/tasks/20260928-agent-refresh-a6d109b3.md @@ -0,0 +1,71 @@ +# Task: Inspect delivered agent refresh behavior + +## Identity + +- Task ID: 20260928-agent-refresh-a6d109b3 +- Mode: Feature +- Branch: codex/20260928-agent-refresh-a6d109b3-agent-refresh +- Worktree: /Users/chillishark/Makelore 麦洛/.codex-worktrees/makelore/20260928-agent-refresh-a6d109b3 +- Base commit: b26e25c9ed26bf30f4d0bc03869c223f0fe34386 +- Owner: codex +- Status: Ready + +## Scope + +- Diagnose delayed delivered-Agent updates, then implement the user-approved manual refresh button beside the topbar Agent list. +- Share refreshed catalog/configuration with the open consultation panel without replacing its topic, draft or published version. + +## Intent And Constraints + +- User first requested diagnosis and product-language evaluation with no code changes, then explicitly requested implementation. +- Refresh is read-only and independent of proactive check-in eligibility; no model question, paid call, current-topic upgrade, automatic Agent switch or draft clearing. +- Preserve the latest approved hover introductions and simplified consultation panel by fast-forwarding this owned checkout to committed dependency 862477f. Its source task record remains byte-for-byte unchanged. Do not alter peer checkouts or the running trial. + +## Project Context Loaded + +- Same task/worktree resumed with matching start/status ownership; feature mode and recorded branch/base verified. Prior positioning, integrated state, decision index, teacher ADR, architecture, domain and evidence context remain loaded. Updated hover-intro peer task record reviewed; all eight peer scopes assessed, no conflicting product decisions. Concurrent and Planning Gates Passed. +- Current rules: Main owns cloud access; published Agent identity/configuration comes from the catalog; old topics pin their version. Initial catalog reads, panel-open reads and existing automatic check-ins remain supported. +- Adapt the design skill's compact, accessible loading/error feedback to the existing light UI; no new fonts, theme, or navigation patterns. +- Plan: add shared read-only loader and manual action, preserve drafts/selection/pinned history, verify unit/typecheck/build/layout/Electron behavior and obtain independent review. + +## Outcome + +- Added a compact Refresh control outside the scrolling Agent strip, with disabled/spinning loading state, three-second success feedback, visible failure feedback and retry. Keyboard labeling and polite status announcements are included. +- Manual refresh immediately reads configuration and catalog through the existing Main API, bypassing proactive five-minute/call-eligibility gates. Concurrent callers share the same request; failed reads retain the prior catalog; obsolete scope/unmounted responses are ignored. +- Topbar and open panel consume the same catalog. Same-ID updates change the version used by new topics without remounting the panel or changing existing topic definitions/versions. Opening or switching a panel still checks through the shared loader. +- Preserved current Agent selection, operation and consultation drafts, pinned history, unread messages, and pending sends. First delivery while an unassigned editor is open keeps that editor/draft stable until the user explicitly selects an Agent or a topic is bound. +- No Main/backend change, production installation, main merge, remote push, live model call, or running-trial restart. + +## Verification + +- Passed: 67 tests across teacher-companion and coding-teacher-ui, including seven new cases covering busy/composing refresh, duplicate clicks, shared latest versions, old-topic/history/draft/unread preservation, independent config/catalog errors and retry, first delivery, and obsolete project responses. +- Passed: 38 tests across coding-chat-panel and preview-clearance on final product code; 105 relevant unit tests in total. +- Passed: standard typecheck, changed-file ESLint, git diff whitespace check, production Renderer/Main/Preload/utility compilation using pinned pnpm 10.33.4. +- Passed: all 9 existing/extended Chrome layout scenarios, including 520px and 1000px scrolling strips with an always-reachable refresh control. Desktop and narrow screenshots visually reviewed. +- Passed: final-build Electron manual-refresh and proactive-presence scenarios. Manual refresh verifies held/loading state, new/renamed Agent, unchanged old topic/reply, operation and consultation draft preservation, failed refresh retention and retry. Captured API requests prove refresh performs no message/check-in/prompt POST or topic reload. +- Independent review found first-delivery draft remounting; fixed with an explicit unassigned selection and covered by a focused regression. Existing consultation E2E exposed delayed introduction reopening after clicking an Agent; explicit click suppression now preserves closure until genuine outside reentry or keyboard focus. Re-review found no additional actionable issue for either fix. +- Passed on final build: all 3 focused Electron cases (consultation switching/drafts/hover, manual refresh, proactive presence) plus 4 affected scrolling/hover layout cases, 7/7 in 16.9 seconds. No assertion was weakened. A prior unrelated sidebar drag assertion (193px instead of 256px) matched the source task’s documented native-input flake; the final full consultation scenario passed. The proactive fixture was corrected to create its new topic from the actual distributed default definition/version. Final screenshots are under ignored test-results/agent-refresh-verified/. +- check_project_docs passed. Task-aware drift checker reports the unchanged source task record inherited from 862477f as FOREIGN_DOC because it compares all commits to the original b26e25c base. Direct comparison to dependency 862477f is empty; Git blob and working-file hash both equal ffd72a12407ef3d963f49e42afa29549300f9883. No foreign/canonical document was edited, deleted, or adopted; record this checker limitation without weakening its rules. + +## Follow-ups + +- Current running trial was updated after the user explicitly requested it; integration into main remains separate. + +## Promotion Candidates + +- Target: canonical classroom interaction/current-state documentation. Proposal: topbar manual refresh immediately synchronizes catalog/configuration with open consultation, preserves drafts/history and old-topic version pinning, and issues only read requests. Evidence: explicit user request, source change, 105 unit tests, layout and Electron checks, independent review. Future impact: operational Agent publication can be checked immediately without waiting for proactive cadence. Semantic conflicts: none. Human confirmation: already supplied for this feature; canonical promotion remains integration-only. + +## Trial Update Resume + +- User explicitly requested updating the current client. Same task/ownership resumed and verified; updated peer record shows two newer approved UI strings at ae0f72d. Merge that committed dependency into the owned task so the live footer/placeholder changes are preserved. No semantic conflict; prior context remains valid, gates passed. +- Supersedes earlier no-running-trial-update constraint only for this isolated application. Preserve existing profile, conversation history, unsent input, and foreground focus. Inspect exact live process and state, update verified Renderer with minimal interruption, then verify and close temporary diagnostics. No production installation or real test question. + +### Trial Update Outcome + +- Merged the committed latest UI dependency ae0f72d (including 5e83676 footer cleanup) into this owned branch at 4f6bda4; no source conflict. After merge, typecheck, 67 companion/UI tests and production build passed. +- Updated the running Makelore Teacher Trial Renderer to this build while keeping PID 27713, window 1, Main/Host API and the same profile. Did not restart or focus the application; the window remained unfocused before and after. +- Snapshotted local storage and in-memory operation/provisional drafts before navigation; all operation drafts/attachments were empty. Restored project, operation conversation, selected consultation Agent/topic, open work/consultation panels and panel width. Login remains authenticated with the same stored identity/token. Visible input contents, consultation text/references/pending identity are unchanged; local-storage formatting/session activity updates were semantically checked. +- Live verification: Refresh button appears and a click returns 已更新; the updated 和老师聊聊 placeholder and footer cleanup remain. The check only invokes the existing read-only catalog/config action, without submitting a test conversation. +- Current process uses the new renderer path for future windows. Created an ignored background launcher in this owned build and updated trial launch metadata for subsequent starts; preserved the prior metadata as a local backup. Existing Main source and peer checkout were untouched. +- Native offscreen capture returned UnknownVizError while the app was unfocused; no focus was taken to obtain a screenshot. Prior build screenshots/layout checks plus live DOM/state checks cover the update. Temporary debugger/inspector access is closed after verification, and the in-process backup is discarded. +- Final documentation check passed. Drift checker retains the known inherited FOREIGN_DOC warning relative to the original base; the source task record remains identical to merged dependency ae0f72d (both Git blobs: 2c9fbcf0a136e2904ea1a8db3a2ef120420f3f49). Inspector endpoint closure was verified. diff --git a/.project-docs/30-worklog/tasks/20260928-agent-refresh-merge-76edc02a.md b/.project-docs/30-worklog/tasks/20260928-agent-refresh-merge-76edc02a.md new file mode 100644 index 00000000..bdbf86e5 --- /dev/null +++ b/.project-docs/30-worklog/tasks/20260928-agent-refresh-merge-76edc02a.md @@ -0,0 +1,44 @@ +# Task: Merge delivered Agent refresh into main and push + +## Identity + +- Task ID: 20260928-agent-refresh-merge-76edc02a +- Mode: Feature +- Branch: codex/20260928-agent-refresh-merge-76edc02a-agent-refresh-merge +- Worktree: /Users/chillishark/Makelore 麦洛/.codex-worktrees/makelore/20260928-agent-refresh-merge-76edc02a +- Base commit: eaf449975ca94511c032a20f4161d507f2f8ab75 +- Owner: codex +- Status: Ready for Integration + +## Scope + +- Merge the already validated manual Agent refresh implementation eaf4499 (including approved hover/copy dependency ae0f72d) into main and push origin/main. + +## Intent And Constraints + +- User explicitly requested main merge and remote push after the running trial update. +- Concurrent and Planning Gates passed in this owned isolated checkout. Entry, active task, positioning, integrated state, decision/teacher ADR, architecture, domain, evidence, commitments, success criteria and all 11 peer records reviewed. Main and origin/main are b26e25c; source descends directly from it. +- Existing canonical integration lock belongs to 20260923-classroom-integration-8b4f1e62. This task performs code merge/publication in feature mode; no canonical reconciliation or source-record edits. README already describes the shipped behavior. +- Separate reply-cleanup and Alice suggestions work are excluded; their source records note that eventual integration must preserve this refresh feature. No semantic decision is changed here. +- Preserve all source commits, unrelated work, live trial profile/window, and source worktrees. No force push, deployment, application restart, paid test question or cleanup without consent. +- Plan: independently check merge scope and history, verify source equivalence and existing test evidence, prepare a documented candidate, fast-forward main and push, verify remote identity. + +## Outcome + +- Prepared a fast-forward publication candidate containing eaf4499 and its approved ae0f72d dependency. Product code, tests and README are byte-for-byte identical to the validated source; only this merge record is added. +- Target: local main and origin/main. Publication uses a normal non-forced push after rechecking remote/main ancestry and main cleanliness; final local/remote commit identity is verified after push. +- Canonical project memory and source task records remain unchanged. Running trial and all other task branches are preserved. + +## Verification + +- Source implementation: 105 relevant unit tests, typecheck/scoped lint/build, 9 layout tests and final 7 focused Electron/layout scenarios passed. Post ae0f72d merge: typecheck, 67 companion/UI tests and build passed; live refresh returned 已更新 while preserving account/drafts/selection. +- Merge candidate changes only this task record relative to verified source eaf4499; implementation is unchanged. Main/origin main b26e25c is an ancestor of the complete source history. Project-document structure and task-aware drift checks passed; no inherited foreign-document warning for this merge task. +- Reuse source typecheck/unit/build/UI evidence because no implementation, dependency or test file changed during this merge. Verify git diff whitespace and source file identity before landing. + +## Follow-ups + +- Retain source refresh/hover checkouts because the running trial uses their compiled Renderer/Main assets. This temporary merge checkout is retained awaiting separate cleanup confirmation; cleanup permission is independent of merge/push permission. + +## Promotion Candidates + +- Canonical classroom interaction/current-state promotion from the two source tasks remains for the exclusively owned canonical integration. Source evidence and current README already capture manual read-only refresh, transient introductions and simplified consultation UI. No new product decision is introduced by this merge. diff --git a/.project-docs/30-worklog/tasks/20260928-merge-agent-single-chat-9911c6df.md b/.project-docs/30-worklog/tasks/20260928-merge-agent-single-chat-9911c6df.md index dcfa4669..ab6846a5 100644 --- a/.project-docs/30-worklog/tasks/20260928-merge-agent-single-chat-9911c6df.md +++ b/.project-docs/30-worklog/tasks/20260928-merge-agent-single-chat-9911c6df.md @@ -45,3 +45,20 @@ ## Promotion Candidates - Accepted and promoted the source account-agent/per-turn contract under the user's implementation and merge approval; no unresolved product-direction choice. Source task/proposal remain unchanged historical records. + +## Remote Merge Resume + +- User explicitly approved resuming this integration task, adopting the in-progress remote merge and preserving three pre-existing untracked task records. Official start/status passed for the same identity, branch, base and integration owner. Imported remote source records were registered unchanged before committing. +- Project Context Loaded: entry/index, own record, positioning, integrated state, decision index/teacher ADR, relevant architecture/domain/success criteria and evidence/reflection/commitment/stale indexes read. Peer scopes assessed; historical placeholders remain unknown. The completed observer task is still separate and requires future single-chat adaptation; its files are untouched. Concurrent and Planning Gates Passed. +- Resume scope: finish merge of remote main 4495345 into local main 56da6b9. Preserve account-agent ongoing conversations and per-turn context/version, integrate manual catalog refresh, hover introductions and simplified consultation UI. Remote topic-era assumptions must adapt to the approved single-chat contract. No subagents, push, packaging, deployment or live paid requests. +- Plan: resolve six conflicted source/test/README files, cover combined refresh/chat/draft/readonly behavior, run typecheck, related unit tests, scoped lint, Vite build and focused Electron/layout checks, then reconcile canonical memory and commit the merge. + +### Remote Merge Outcome And Verification + +- Resolved all six conflicts between local 56da6b9 and remote 4495345. Kept account-agent conversation identity, cross-project drafts/history, read receipts, per-turn project/version and readonly legacy access; integrated remote manual catalog refresh, hover introductions, simplified header, pastel follow-ups and placeholder/footer changes. Refresh shares catalog/config, does not submit questions or change selected contacts, and preserves an already-open unassigned draft on first delivery. Removed contacts retain readonly history. +- Updated the remote topic-era tests to the approved ongoing-chat contract, including stable-agent sends, changed contact names with retained historical turn versions, cross-project draft identity, stale refresh response exclusion and removal disabling. Fixed the layout fixture's missing unread-agent list and the Electron Host fixture's use of the original catalog. The delivered-agent presence E2E now explicitly verifies no legacy paid check-in after advancing the clock; legacy check-in unit tests remain. +- All 120 focused unit cases passed across teacher-companion, coding-teacher-ui, teacher-conversation-panel, teacher-conversation, coding-chat-panel and preview-clearance (89 unaffected cases plus final 31 companion cases). The temporary cross-test cached-conversation collision was removed by giving independent fixtures distinct stable Agent IDs, consistent with one chat per Agent. +- Standard pnpm typecheck, scoped ESLint and Vite Renderer/Main/Preload/utility production build passed using pinned pnpm 10.33.4. Existing Browserslist/chunk/dynamic-import warnings remain; no product dependency or Main implementation changes relative to pre-merge local HEAD. +- Electron scenarios passed: consultation switching/hover/drafts, manual refresh/failure/retry with ongoing history, and delivered-agent presence/focus/preview with no legacy check-in. All 9 browser layout scenarios passed after fixture adaptation. Manually inspected final refresh and narrow hover screenshots. Isolated deterministic Host responses only; no live model calls. +- README now describes current per-turn versions and unique chats consistently with refresh. Canonical teacher ADR, architecture and Integrated Through record the combined behavior. Remote source task records remain byte-identical to 4495345; the three pre-existing untracked documents are excluded from the merge. No push, deployment, packaging, source-worktree deletion or observer feature integration. +- Final scope verification includes both parent histories, no conflict markers/unmerged index entries, whitespace and task-aware documentation drift gates. No new cleanup candidate is created: the resumed root main checkout is unmanaged and is retained. diff --git a/.project-docs/30-worklog/tasks/20260928-teacher-hover-intro-a73f6e29.md b/.project-docs/30-worklog/tasks/20260928-teacher-hover-intro-a73f6e29.md new file mode 100644 index 00000000..2c9fbcf0 --- /dev/null +++ b/.project-docs/30-worklog/tasks/20260928-teacher-hover-intro-a73f6e29.md @@ -0,0 +1,83 @@ +# Task: Show playful teacher introductions on hover and simplify the consultation header + +## Identity + +- Task ID: 20260928-teacher-hover-intro-a73f6e29 +- Mode: Feature +- Branch: codex/20260928-teacher-hover-intro-a73f6e29-teacher-hover-intro +- Worktree: /Users/chillishark/Makelore 麦洛/.codex-worktrees/makelore-teacher-hover-intro +- Base commit: b26e25c9ed26bf30f4d0bc03869c223f0fe34386 +- Owner: codex +- Status: Ready for Integration + +## Scope + +- Move published teacher introductions into playful hover cards on the existing topbar entries. Remove introductions and the add/expand/close icon group from consultation headers. + +## Intent And Constraints + +- User explicitly requests this presentation/interaction change. Preserve published identities, teacher selection, conversation history, per-agent drafts, model/auth contracts and true proactive messages. Hover/focus must not start a conversation or acknowledge messages. Keep the existing single light visual system and native preview usable. +- Use the current entry to toggle its panel; selecting another teacher opens that teacher. Retain Escape and drag resizing. Keep explicit new topics as a text action inside expanded history, outside the header. +- Follow-up: user explicitly requests updating the existing temporary application without taking desktop focus. Reuse its isolated profile and avoid activating windows during verification. + +## Project Context Loaded + +- Task ID/mode/branch/worktree/base match Identity and the successful start/status registry. All other registered task scopes reviewed through their records; prior classroom/style/integration tasks are completed sources. Main's teacher-focus task is active but owns prompt work, with no overlapping frontend files. Isolated ownership avoids contention. +- Read entry/planning instructions, memory index, active task, positioning, current state, teacher ADR/decision index, relevant architecture/domain/evidence and reflection/commitment/stale indexes. Current main uses generic server-distributed identities with separate drafts and pinned topic versions; older fixed-role task records are historical. +- Design skill search selected soft playful cards. Adapt cream/pale blue, rounded borders and restrained offset shadows to existing Chinese typography; no new font download or product-wide theme. Hover content uses the published description; no invented biography. +- Gate: Passed. Plan: implement tooltip and preview clearance, simplify the panel while preserving navigation, verify relevant unit tests, browser layout and isolated Electron interactions, then document delivery. No live teacher requests, remote publication or app restart in this task. +- Trial-update resume: matching start/status ownership restored to planning; prior product context rechecked, all peer scopes reviewed and unchanged. Gate passed. Existing trial metadata points to an exited process and an older checkout; installed production is a distinct running application. Plan: reuse the verified 772da4f build in the isolated trial, add a local background startup wrapper, preserve the profile/port, and verify runtime and foreground ownership read-only. Earlier no-restart constraint is superseded only for the explicitly requested trial update. + +## Follow-up Plan: Reply Cards And Header Removal + +- User approved the proposed pale blue/cream/lavender follow-up cards with 16px text and requests removing the entire duplicate avatar/name header. Update the same trial afterward; the earlier no-focus constraint persists. +- Same task/worktree resumed via start/status; prior project context and peer scopes remain unchanged. Design search recommends soft playful cards; adapt only the approved colors/typography without adding fonts or unrelated layout. Gate passed. +- Change Renderer styles/header only, preserve generated suggestions, submission and per-agent drafts. Update affected existing tests, visually inspect in a headless fixture, and refresh the running trial in the background where feasible. + +## Follow-up Plan: Remove Redundant Footer Copy + +- User requests removing the two pictured footer messages: the invitation to type below and the count of omitted earlier messages. Delete only their Renderer presentation; preserve context selection metadata, replies and input behavior. +- Same-task ownership resumed and verified; previously loaded project context still applies. Refreshed the active peer agent-refresh record: it now implements catalog refresh on top of 862477f in its own checkout and explicitly leaves the running trial alone. Code-path overlap is limited to separate concerns in TeacherChatPanel; no semantic conflict. Gate passed. +- Remove the two elements, run existing focused verification and compile, then apply equivalent targeted hiding to the running trial without reloading its in-memory drafts or changing focus. + +## Follow-up Plan: Composer Placeholder + +- User requests the exact placeholder “和老师聊聊”. Same-task start/status identity matches; earlier loaded context remains applicable, peer refresh work is isolated and semantically separate. Gate passed. Change only the placeholder, compile, and update the live trial attribute without replacing input values or moving focus. + +## Outcome + +- Added a cream, rounded introduction card using the published teacher name, avatar and description. Hover or keyboard focus opens one card at a time outside the scrolling topbar; empty descriptions do not create a card. The pointer can enter the card to read long descriptions. Leaving, Escape or clicking the entry closes it; moving inside the clicked entry does not reopen it until a fresh entry. +- Removed the introduction and add/expand/close icon group initially; the approved follow-up removes the entire duplicate avatar/name header. Identity remains in the topbar and individual reply attribution. Clicking the selected topbar entry toggles its panel; switching entries selects that teacher. Escape restores focus to the selected teacher, per-agent drafts remain intact, drag resizing remains available, and the new-topic text action sits in expanded history. +- Extended native work preview clearance to include the introduction and any real unread speech bubble, using the maximum overlapping clearance. Hover does not create topics, send requests or acknowledge unread messages. README describes the final behavior. +- Independent review caught immediate entry-switch overlap and selected-entry focus restoration issues; both were fixed and covered. Final screenshot review prompted a second pointer-move opening-path regression, now fixed by keeping pointer-enter as the sole mouse opening path. +- During delivery, the peer teacher-focus task completed and a separate read-only agent-refresh task was registered. Its task record was reviewed; it changes no presentation/runtime code and has no semantic conflict. +- Initial implementation was isolated on the recorded branch without deployment. The explicitly requested background trial update is recorded below; no main merge, remote push or deliberate teacher/model request occurred. +- Trial update completed: existing `Makelore Teacher Trial.app` (bundle `cn.makelore.teacher-presence.trial`, Electron 43.4.0) now runs this checkout's verified 772da4f build as PID 27713. Reused `/var/folders/mx/ltbgwsks5_n8zllj69p_wbcw0000gn/T/makelore-trial-tdq_nuah/user-data` and port 54599. The prior recorded trial PID had already exited, so no running application was stopped. +- A machine-local `dist-electron/main/trial-background.cjs` bootstrap, excluded from Git, guards startup show/focus calls and launches through `open -g -j`. It leaves the window hidden until the user activates it; normal window behavior is restored upon user activation. Metadata backups and startup/focus evidence are kept beside the existing trial. Production code and the installed application were not modified. + +- Reply-card follow-up: generated follow-up questions now use pale blue, cream and lavender cards in order, 16px text and 1.8 line-height, dark readable text, responsive wrapping, hover/focus and disabled states. Both suggestion-generation and ordinary follow-up groups share the style. Removed unused header/icon styles and kept admin preview identification outside a header. +- Updated the current trial presentation through Electron insertCSS after verifying the exact PID/path/window. Renderer/Main were not restarted: operation drafts are held in memory, so this avoids losing them or authentication. The current page receives equivalent selectors for its existing markup; the rebuilt source removes the header and uses the new card markup on the next normal load. No fake cards or messages were added to the real profile. + +## Verification + +- Passed: 98 tests across teacher-companion, coding-teacher-ui, coding-chat-panel and preview-clearance suites on the final changes. +- Passed: 9 browser layout checks, including 520px/1000px scrolling teacher strips, direct teacher-to-teacher hover, keyboard focus/Escape, click then pointer movement, unread bubble preservation and native viewport clearance. Reviewed rendered card and desktop conversation screenshots. +- Passed: both targeted Electron scenarios (consultation drafts/teacher switching and topbar/proactive presence) against the final production build. One run failed before the teacher interaction at the existing sidebar drag assertion (193px instead of 256px); a separate retry of that scenario passed without source/test changes to the drag behavior. +- Passed: standard typecheck, changed-file ESLint, production Vite/Electron compilation, git diff whitespace check, project-docs structure and task-aware ownership drift checks. +- Independent code review passed. Electron interaction tests use isolated profiles and fixture responses; no real-model interaction or production installation was exercised. +- Background trial verification: exact process path and Host API listener confirmed; OPTIONS runtime-info returned 204. Loaded Renderer URL points to this checkout and `index-PjM22P-Y.js`; the document is complete and React root is mounted. Startup status recorded one blocked show, a loaded hidden/unfocused window, and the original isolated profile. A 12-second NSWorkspace foreground monitor recorded no trial activation and retained the previously foreground application's PID throughout. Verification performed no UI click, activation or test message. + +- Reply-card follow-up passed 91 existing unit tests, typecheck, changed-file ESLint, production build and whitespace checks. Existing Electron assertions were updated for the removed header but not launched during this follow-up. A headless visual sample using the supplied text verified the actual card CSS at 540px and 320px: 16px font, 28.8px line-height, three expected colors and no horizontal overflow. +- Live update retained PID 27713 and all current input values; the window remained unfocused and the foreground app PID stayed unchanged. Subsequent read-only DOM inspection confirmed the open consultation header had zero height. No generated follow-up cards were mounted at inspection, so their rendering was verified in the headless sample rather than claimed as a live conversation check. The temporary loopback Node inspector was closed after verification. + +- Footer-copy follow-up: removed the redundant invitation to type below and omitted-history message count from TeacherChatPanel; context metadata and other response behavior are unchanged. Existing coding-teacher-ui tests (38) passed, as did typecheck, scoped ESLint and production build. The live trial had three matching footer paragraphs; all three became invisible after the targeted presentation update. PID 27713, current input values and foreground PID were preserved; no reload, message or window activation occurred. Temporary inspector was closed afterward. + +- Placeholder follow-up: changed the source textarea placeholder to exactly “和老师聊聊”. Typecheck, scoped ESLint and production compilation passed. Updated the same live Renderer attribute and installed a scoped observer for subsequent panel remounts until its next normal load. Verified the exact placeholder, unchanged input values/focus, unchanged foreground app and same PID 27713. No restart/reload or message occurred; temporary inspector closed after the update. + +## Follow-ups + +- Integrate this branch when requested; retain this worktree because the updated trial now runs its compiled output. The user can activate the existing `Makelore Teacher Trial` Dock entry to review the interface. + +## Promotion Candidates + +- Target: `.project-docs/30-worklog/current-state.md` and the canonical classroom interaction description. Proposal: published teacher introductions live in transient topbar hover/focus cards, and the duplicated consultation header is removed; generated follow-up questions use three alternating pastel cards with 16px text; the selected entry toggles the panel and new topics remain available inside expanded history. Evidence: explicit user request, changed components, 98 unit tests, 9 browser layout checks and 2 Electron scenarios. Future impact: preserves the consultation capability while simplifying the teacher selection surface. Semantic conflicts: none with generic distributed identities, pinned topic versions or true proactive messages. Human confirmation: already supplied for this interaction; canonical promotion remains an integration-mode step. diff --git a/README.md b/README.md index 844f1780..08bcd2c8 100644 --- a/README.md +++ b/README.md @@ -160,14 +160,17 @@ Pi 正式包必须继续运行 `pnpm run verify:artifact:pi`、`pnpm run smoke:p ### 下发智能体咨询 +顶部智能体名单旁的“刷新”按钮可立即获取最新下发名单、发布资料和当前版本,独立于主动关心的检查条件。刷新中显示进度,成功提示“已更新”,失败保留原名单并可重试;顶部和已打开的咨询面板使用同一份结果。刷新不发起模型请求、不切换当前智能体、不清除草稿或历史,运行中的问题保留已绑定版本,下一次提问由 Main 固定当时的发布版本,同一聊天保持连续。 + 老师 Agent 是某一领域杰出人物的能力转化而成的智能体,供平台学生使用,在真实项目、作品和问题中提供专业理解、判断与解决问题的能力支持。定义以人的领域能力及学生价值为中心;蒸馏属于实现方法,云端下发、上下文读取和聊天是能力交付方式。完整理念见[老师 Agent 产品定位](.project-docs/00-brief/project-positioning.md#老师-agent-的产品定位)。 -- 新话题可选择运营下发的 Yuxi 智能体,默认使用指定智能体;提示词、Skills、知识库和模型配置由 Yuxi 管理,运营同步后生成新版本,已有话题固定原版本。Yuxi 智能体模型费用由当前学生的编程词元点数支付,个人 Agents 模块仍由创建者付费;不要求学生开通个人云智能体模块。停用的智能体仍可查看历史,不能借另一位智能体的可用状态继续提问。 +- 可在顶栏选择运营下发的 Yuxi 智能体,首次默认使用指定智能体;提示词、Skills、知识库和模型配置由 Yuxi 管理,运营同步后生成新版本,每轮接受问题时固定当前版本,历史轮次保留原版本。Yuxi 智能体模型费用由当前学生的编程词元点数支付,个人 Agents 模块仍由创建者付费;不要求学生开通个人云智能体模块。停用的智能体仍可查看历史,不能借另一位智能体的可用状态继续提问。 - Main 为智能体每轮请求绑定当前账号、项目和所选操作会话,提供 `list_project_files`、`read_project_file`、`read_conversation` 三个只读工具。云端通过持久中断请求整批读取,Main 返回配对结果并续接同一问题;若原运行仍在释放资源,保留同一批读取结果等待续接,等待期间仍支持取消并受原问题时限约束。本地旧版智能体也支持相同读取边界。可读当前项目源码及 `.makelore/project.json`,拒绝其他 `.makelore` 历史、Git 内部数据和越界路径;不提供写文件或命令执行。这些能力不按名称或人设区分。 - 本地读取使用连续分页:目录按层展开,默认四层、最多六层,跳过 `.gradle` 等生成目录;条目随页面按需产出,深层目录可单独查询;文件和会话默认每页 120 行、最多 400 行,返回连续原文、起始行列与精确 next 游标,列按 Unicode 字符计数、换行统一为 LF。单个云端结果最多 8 KiB,长行也能继续读取;不受文件 UI 的 256 KiB 预览限制。会话索引保留消息 ID 和摘要,按 ID 读取完整公开原文。每题最多十二批、累计成功结果 64 KiB(包含结果元数据),不足 512 字节时收尾;不上传 Pi 原始日志或思考。云端保留智能体对话及收到的片段,完整工程仍在本机。本地旧版模型仍按自身上下文和六批额度缩小结果。 - Code 课堂左侧项目栏默认宽 171px,可拖动右边缘在 128–256px 间调整,双击恢复默认并在本机记住宽度;标题栏同步对齐。项目名与会话名超长省略并可悬停查看;右侧咨询栏默认宽 508px,可拖动至 640px,紧凑窗口仍使用覆盖式咨询。 - 客户端没有内置老师/朋友角色。已下发智能体以头像和名称并排显示在标题栏,点击后打开对应智能体的讨论;数量较多时横向滚动,咨询面板不再提供智能体下拉框。名称、头像、简介、欢迎语和推荐问题均由服务端提供。首次使用默认选择运营指定项,各智能体的未发送草稿分别保存,同一账号与同一智能体只有一个持续聊天,跨项目保留消息和文字草稿;不再显示新话题按钮或话题选择。每轮接受时固定项目、操作对话与当前发布版本;旧的未分配项目草稿可展开查看,不自动转给其他智能体。打开或切换只读取配置和历史,不触发模型;咨询栏支持调整宽度和重新打开。 +- 鼠标悬停或键盘聚焦顶部智能体入口时,以奶油色圆角卡片显示该智能体的发布介绍;离开、Escape 或点击入口后收起,没有介绍则不显示空卡片。咨询栏不再显示重复的头像、名称标题条,也不显示介绍及新话题、展开、关闭三个图标;老师身份保留在顶部入口及消息署名中。智能体生成的追加问题以淡蓝、奶油黄、淡紫卡片依次承载,正文 16px、行高 1.8,保留整卡点击发送与忙碌时禁用。回复下方不再显示重复的输入引导或省略早期消息条数;输入框提示为“和老师聊聊”。再次点击当前入口或在咨询栏按 Escape 可收起,切换其他入口仍直接打开对应讨论;拖动边缘调宽保留,已下发智能体仅保留只读旧记录入口。悬浮介绍不会创建话题、调用模型或确认未读消息,作品原生预览同时避让介绍卡和真实主动气泡。 - 主动发言采用紧贴小头像的短气泡;只有存在真实主动消息或运营欢迎语时才显示这组浮层,收起消息时头像和气泡一起消失,顶部入口仍保留。长消息在气泡中最多显示三行,点击接回原智能体对话查看全文。不提供“智能体偶尔来看看”开关或本地模拟巡看控制,既有自动跟进与真实消息接收逻辑保留。作品原生预览对整组气泡和头像测量避让,避免图片被原生页面遮住。 - 新的单会话入口停止旧版前端定时跟进派发;项目主动观察由独立功能衔接,不能重新创建可见话题。未下发目录的旧版入口仍保留原跟进合同:前端每 5 分钟请求一次智能体跟进;窗口隐藏、来源归档、主对话正在执行、智能体正在回复或学生正在智能体栏写草稿时延后。Main 再检查在线启停、来源归属、项目级冷却和已完成文本指纹,未变上下文按下述十五分钟冷却处理。跟进沿用运营模型、已发布 Skills 与当前智能体话题,生成简短的具体建议或引导;以主动智能体发言持久化,不伪造学生消息。模型调用沿用智能体计费规则。 - 进入项目时,智能体头像旁先显示运营发布的欢迎语气泡,不调用模型、不声称已检查项目;每个账号/项目主动收起后不重复弹出。真实的未读主动建议优先替换欢迎语。主动发言在头像旁直接显示气泡,不抢焦点、不盖住作品;作品区按气泡与原生预览的实际交叠范围避让,已有工具栏高度计入计算,气泡位于独立智能体栏时不额外留白,窗口/分栏尺寸变化和收起气泡时实时归还空间;“和智能体聊聊”接回同一段咨询,“等会儿聊”收起并保留历史。已有未处理气泡时不堆叠新邀请;咨询已展开时也显示气泡,直到学生主动点击查看或收起,期间的其他回复不会吞掉未读邀请。五分钟检查计时在刷新和项目切换后保留;智能体咨询里的新讨论也算进展,即使操作对话没有变化也会继续跟进;上下文完全未变时放缓到十五分钟一次,不永久停止。事件连接丢失时,每十五秒只读同步未完成回复,收到结果后停止轮询,不重复调用模型。失败如实提示,不以本地文案替代模型回复。已接受请求恢复使用原身份,退出账号和来源删除仍沿用 Main 中止边界。 @@ -181,12 +184,12 @@ Pi 正式包必须继续运行 `pnpm run verify:artifact:pi`、`pnpm run smoke:p - 每轮格式由 Main 的对应意图协议决定;`discussion.ts` 为支持组件的请求注入唯一 `{reply, quickReplies, tool}` 协议。运营教学补充不另写字段协议或要求始终纯文字。工具内讨论保留类型、稳定 ID、未修改内容和采纳状态;暂停/未进入时 `tool:null`,没有实质变化时也可保留原内容。结构图、流程和对照目前没有独立的采纳/来源字段,待定、建议与预测只能在展示文字中明确,不能据此推导已确认共识。 - 当前输入是按预算截取的所选操作对话已完成分支文本、明确引用、咨询历史和适用的当前组件,并支持上述只读原文恢复;没有跨全部操作会话自动读取,也未向操作 Agent 注入咨询共识。“先这些”仍仅结束本轮整理,保留各条目状态,不确认全部候选、不自动制作。提示词不宣称这些系统能力已接通,也不声称看过未提供的画面或试玩过作品。Yuxi 话题经云端原生执行,旧版本地智能体由 Main 调用计费网关;均不创建本地 Pi 编程 worker。 - 智能体输入裁剪区分两种计量:本地模型以约每 2 个 UTF-8 字节估算 1 Token,并计入工具与读取预留;这不是精确分词或扣费依据,模型上限与实际 usage 仍由服务端拥有。云端沿用 query 字节上限,以完整 JSON 转义后的大小裁剪来源节选。智能体指令、当前问题和明确引用不会被静默裁掉;固定配置或当前整理本身超限时明确提示调整配置,避免让学生反复缩短短问题或新建话题。完整来源仍可由只读工具按需读取。 -- `tests/fixtures/teacher-guidance-examples.json` 提供宠物、种植、射击、蛋糕的人工多轮输入输出样例,由真实解析器、上下文编译器与讨论状态机校验;样例不加载到运行时,也不代表真实模型教学效果已验收。云端定义由 Yuxi 维护并由运营显式同步下发;本地代码修改不会自动改写云端配置或学生已有话题的固定发布版本。 +- `tests/fixtures/teacher-guidance-examples.json` 提供宠物、种植、射击、蛋糕的人工多轮输入输出样例,由真实解析器、上下文编译器与讨论状态机校验;样例不加载到运行时,也不代表真实模型教学效果已验收。云端定义由 Yuxi 维护并由运营显式同步下发;本地代码修改不会自动改写云端配置或学生已接受问题的固定发布版本。 - 下发智能体的图标随发布版本保存,顶栏、咨询面板、欢迎区和消息使用定义中的 `icon_url`;未设置或图片加载失败时使用内置头像。运营在 Yuxi 更换图标后需同步下发配置,联系人使用当前下发的名称和图标;每轮执行仍记录实际发布版本。相对图片地址由服务端使用 Yuxi 公网入口补全。 - 咨询聊天和文字草稿按当前云端账号、已下发智能体保存;切换项目或操作对话仍延续同一个聊天,每轮发送冻结当时的项目、来源和发布版本并检查启停。引用保留原项目/来源,切换后必须移除失配引用再发送;旧项目卡片不能操作当前项目。历史按50轮分页,流式事件只传当前轮;本机每轮独立原子落盘,索引保存消息摘要,旧轮次可通过只读工具按ID读取。可确认归属的旧话题按来源ID幂等迁入,原文件保留;“旧记录”入口只读查看升级前项目/来源话题。项目、Pi来源或版本变化时切换内部云线程并带入有预算的近期交流,同一段由Yuxi原生历史压缩管理上下文。此版聊天历史在本机保存,不提供跨设备同步。关闭面板或切换会话不取消已接受的问题,退出账号会中止。请求先落盘再调用模型,同一请求标识不重复发送,重启后未完成请求标记中断。云端断线按游标和持久状态恢复;停止或退出账号会取消原云端问题,下次提问先停止旧的未完成问题再绑定新上下文。只接收云端主线程回答,子智能体文本不混入正文。没有操作对话时也可咨询,但无操作文本上下文。 - 删除操作对话会停止正在使用该来源的回复,保留项目级咨询历史;归档来源需先恢复后才能引用。原有来源会话级智能体 API 与存储保持兼容,原路径历史不自动迁移到新项目级咨询栏。运营草稿试聊仍使用 `niancode://coding-teacher/preview?draft_revision=N` 打开独立示例上下文,不读取学生项目,要求桌面当前账号具有运营权限。 -- 旧版客户端生成的朋友话题在“以往讨论”中标记为仅查看,不再创建或继续调用,也不自动绑定某个云端智能体;可选择下发项新建话题。统一咨询保留原有项目草稿;旧版朋友未发送的文字和引用可从“查看旧版朋友草稿”只读查看,不自动提交。旧文件和原发布版本保留,不复制或改写历史。已有 `coding-teacher` 云端契约及历史目录名保留,避免无必要的数据迁移。 +- 旧版客户端生成的朋友话题在“以往讨论”中标记为仅查看,不再创建或继续调用,也不自动绑定某个云端智能体;可选择下发项进入唯一聊天。统一咨询保留原有项目草稿;旧版朋友未发送的文字和引用可从“查看旧版朋友草稿”只读查看,不自动提交。旧文件和原发布版本保留,不复制或改写历史。已有 `coding-teacher` 云端契约及历史目录名保留,避免无必要的数据迁移。 ## 运行内核与项目数据 diff --git a/src/lib/coding-teacher.ts b/src/lib/coding-teacher.ts index 961e9d21..278af0db 100644 --- a/src/lib/coding-teacher.ts +++ b/src/lib/coding-teacher.ts @@ -11,6 +11,10 @@ import type { TeacherTopicList, TeacherConversationView, } from '../../shared/coding-teacher'; +export interface TeacherCatalogState { + config: TeacherAvailability & { definition: TeacherDefinition | null }; + catalog: TeacherCatalog; +} export function teacherTopicsPath(projectId: string) { return projectId === 'preview' ? '/api/coding/teacher-preview/topics' diff --git a/src/pages/Chat/AgentBrowserPanel.tsx b/src/pages/Chat/AgentBrowserPanel.tsx index 54b997c1..bc8e0220 100644 --- a/src/pages/Chat/AgentBrowserPanel.tsx +++ b/src/pages/Chat/AgentBrowserPanel.tsx @@ -47,6 +47,7 @@ export interface AgentBrowserPanelProps { onOpenChange(open: boolean): void; embedded?: boolean; teacherBubble?: HTMLElement | null; + teacherIntroduction?: HTMLElement | null; conversationId?: string | null; onWorkConversation?(conversation: CodingConversationMetadata): void; workRevision?: number; @@ -133,6 +134,7 @@ export function AgentBrowserPanel({ onOpenChange, embedded = false, teacherBubble, + teacherIntroduction, conversationId, onWorkConversation, workRevision, @@ -149,7 +151,7 @@ export function AgentBrowserPanel({ const [events, setEvents] = useState([]); const viewportRef = useRef(null); const panelRef = useRef(null); - usePreviewClearance(panelRef, viewportRef, teacherBubble, embedded && open); + usePreviewClearance(panelRef, viewportRef, teacherBubble, embedded && open, teacherIntroduction); const addressInputRef = useRef(null); const eventCursorRef = useRef(0); const snapshotGenerationRef = useRef(0); diff --git a/src/pages/Chat/CodingChatPanel.tsx b/src/pages/Chat/CodingChatPanel.tsx index 0e1e551d..7fe9dd00 100644 --- a/src/pages/Chat/CodingChatPanel.tsx +++ b/src/pages/Chat/CodingChatPanel.tsx @@ -245,6 +245,7 @@ export function CodingChatPanel({ const running = ['queued', 'running', 'retrying', 'compacting', 'aborting'].includes(runStatus); const teacherCompanion = useTeacherCompanion({ projectId: activeProject?.id ?? null, sourceId: targetConversationId, sourceBusy: running, sourceArchived: Boolean(selectedConversation?.archivedAt), teacherOpen: consultationOpen, teacherComposing }); const [teacherBubble, setTeacherBubble] = useState(null); + const [teacherIntroduction, setTeacherIntroduction] = useState(null); const openTeacher = (agentId?: string) => { if (agentId) teacherCompanion.selectAgent(agentId); const selectedText = window.getSelection()?.toString().trim(); @@ -253,6 +254,19 @@ export function CodingChatPanel({ setConsultationOpen(true); setAgentBrowserOpen(true); }; + const closeTeacher = () => { + setConsultationOpen(false); + const entry = document.querySelector('.consultation-agent-tabs [aria-pressed="true"]') + ?? document.querySelector('.consultation-agent-tabs button'); + entry?.focus(); + }; + const toggleTeacher = (agentId?: string) => { + if (consultationOpen && (!agentId || agentId === teacherCompanion.selectedAgent?.teacher_id)) { + closeTeacher(); + return; + } + openTeacher(agentId); + }; const promptMode = running && draftKey ? modesByDraftKey[draftKey] ?? 'prompt' : 'prompt'; const entryLoadState = useCodingConversationStore((state) => ( targetConversationId @@ -761,7 +775,7 @@ export function CodingChatPanel({ onToggleBrowser={() => setAgentBrowserOpen((current) => !current)} projectName={activeProject?.name} consultationOpen={consultationOpen} - teacherEntry={activeProject ? : undefined} + teacherEntry={activeProject ? : undefined} />
@@ -771,6 +785,7 @@ export function CodingChatPanel({