# 「我的一天」日历：分阶段实现与接口边界

更新：2026-09-20 18:39。**已接入文档化的按日来源：个人记录、私聊/群聊收发与 @/回复关系、通话、Arko、Bot、DSH 已同步输入、录音覆盖与地点。分页和接口历史覆盖边界仍然存在；当前 Arko 新接口实测返回服务器繁忙。**

## 本轮最终回归与实际边界

### 页面说明与状态展示（2026-10-20）

- 沿用现有布局、组件、筛选、详情与生成入口。月历常驻说明精简为数字/圆点图例，日期悬停与键盘提示说明实际活动类别；只含录音/对话的日期不再被描述为“暂无记录”。
- 无已知录音且覆盖完整时不画空时间条；读取失败、覆盖不完整仍明确展示。活动加载提示合并，已有内容持续可读；地点说明仅在地点筛选或位置页出现，移除重复页脚。
- “检查更新”改称“刷新”，仍是读取状态，不生成、不扣费。生成中保留实际进度，并按日总结/时间轴标签说明完成后展示的内容。资料缺失继续标示，不将部分数据冒充完整结果；旧结果没有提示词快照时不再显示技术性缺省提示。
- 本轮仅调整 UI 展示及中文提示，不新增 Host 查询/命令、SDK/Tools 能力、配置或存储结构；SDK/Tools 无新增消费场景。

### 渐进加载与详情一致性（2026-10-20）

- 同一读取批次内，文档化来源可以分批返回。`snapshotId` 标识读取批次，列表游标标识分页位置；二者均不承担详情内容版本的职责。
- `DayActivityEntry.detailRevision` 由适配器按分组成员及其详情版本生成，仅包含记录标识和计数，不复制正文。成员增加、去重后补齐富文本都会更新版本；其他来源返回不会改变未受影响分组的版本。批次内详情固定的适配器可以省略该字段。
- 已展开的分组发生变化时，详情层取消旧读取，从第一页重建用户已打开的分页范围，再替换详情。读取失败、撤权或游标异常时不保留旧正文；迟到响应不能覆盖新版本。不为详情刷新重新请求全部活动来源。
- 沿用现有展开、关闭、加载更多和来源跳转交互。本次只调整客户端读取一致性，没有新增 Host/API、Tools/SDK 业务能力、持久化结构或配置项。
- 回归覆盖真实适配器的慢来源合并、同条消息富文本补齐、无关来源不触发详情重读，以及详情分页重建、取消、失败、撤权和游标循环。

### 紧凑活动片段（2026-09-20，用户确认后实施）

- 标题优先显示联系人备注名或真实群名，并复用现有账号范围内的头像读取；无头像的来源使用类型图标。
- 同一来源片段从已加载正文中选择最多两条原文摘录，优先有内容的交流而不是最后一句“好的／继续”，并标明我、对方或已知群成员。选文不请求 AI、不改写正文、不推测消息回复关系；仅有简短回复时仍保留该回复。
- 选文不改变片段身份、时间排序、原始条数和展开内容；同来源 15 分钟相邻规则保持不变，原始明细模式仍逐条展示。
- 去掉重复来源文案，缩小片段间距，明确展示展开入口。录音显示实际覆盖时长，不再显示“0 条原始记录”；同一分钟内不重复显示相同起止时间。
- DSH 尚无可靠任务名关联的输入仍标明 DSH 输入，不把记录所属主题名冒充任务名。Arko 等来源的接口错误和未覆盖范围仍独立显示。
- 原有自主确认的 AI 小结入口保留；本轮选文、头像与详情检查不调用它，也不改变会话已读状态。
- 验证：10 个直接相关测试文件 118 项、6 个来源/通话/地点/群互动回归文件 151 项通过；类型检查、构建及差异检查通过。固定 3098 已更新，安装产物与本地构建一致。
- 18:54–18:56 使用独立 Chromium 连接已登录 3098 实测：今天与 9 月 18 日显示真实名称、原文摘录和通话；头像补读后实际图片可见；群片段展开保留 5 条消息，原始明细/活动片段、录音筛选可切换；1440/800/420 宽度无横向溢出、无页面脚本异常。测试监听了发送/已读/创建/AI 生成入口，没有触发这些写入。内嵌浏览器控制连接超时，未声称已替用户刷新其现有标签页；深色主题未单独验收。

- 使用与浏览器相同的适配器跑测试，移除了此前 `NODE_ENV=test` 时切回旧适配器的分支；避免测试通过而实际浏览器走另一套逻辑。
- Chat 正文读取实际 `record.payload.text_content`，Host 批量复用会话目录的备注名与账号绑定的来源引用；不把原始 `chat_session_uid` 作为可直接导航的引用。同一会话的相邻片段展开包含所有已加载成员消息，不只显示第一条的 240 字预览。
- 个人记录复用既有权限、隐私锁、富媒体及临时地点引用投影。只有地点摘要而没有坐标时不会崩溃；展开地点按响应真实 access/recordUid 校验。相同本人记录只在公开记录身份和会话身份均一致时与 Chat 去重，并保留图文与位置，不按文本/昵称/时间猜测。
- 通话按所选日期范围读取既有聚合接口，并复用备注名、已有摘要、签名引用及按需通话详情；范围进入缓存键。录音覆盖分页累积，某段展开时才按 `recording_id` 查询转写；没有读取全日人声不能宣称没有人声。当前新入口不自动拉取旧 `recordings.day` 的录音 AI 回顾，下面旧阶段的该项说明不代表本轮已完成同等接入。
- 独立游标循环会明确失败，未选择的来源不发请求，后端 `coverage=partial` 不被误报为完整；月历刷新与日期切换也重置对应请求。
- 2026-09-20 18:38–18:39，已登录 3098 真实浏览器确认：9 月 20 日显示联系人备注名、群名、消息正文及 DSH 输入；9 月 18 日显示 7 次通话，展开周鹏的通话可查看已有摘要和转写。
- 21 个相关测试文件共 256 项通过，最后地点去重补丁另复跑 30 项通过；类型检查、构建和安装产物哈希一致性通过。这不是全库、所有日期或两端真实收发验收。
- Arko `/api/v1/arko/activities/query` 在只读联调时返回 502 / `arkme-code-1002`（服务器繁忙）；前端保留其它来源并显示重试。请后端排查新接口部署、migration 21、MySQL 时区表及日志，不能从此响应断言具体是哪项失败。
- 没有发送消息、生成 AI 小结、发起通话/录音或主动写会话已读；原有 TRTC 音量工作线程加载警告仍存在，未纳入本轮修复。

以下较早阶段的说明用于保留演进背景；与本节不一致时以本节及文档化接口回接为准。

## 文档接口回接升级（2026-09-20）

本轮已把同事返回的「我的一天」接口契约接入桌面端时间线。前端不把多个来源拼成一个假接口，而是通过 Host 的 `calendar.activity` 只读入口分别读取并在浏览器内合成：每个来源保留自己的游标、失败状态和是否还有下一页。

| 来源 | 桶/明细读取 | 桌面端呈现 |
| --- | --- | --- |
| 个人记录 | `/api/v1/calendar/buckets/query`、`/api/v1/calendar/records/query` | 快记、DSH 输入、备注名优先、位置摘要与按需位置详情 |
| 私聊/群聊 | `/api/v1/chats/activities/buckets/query`、`/api/v1/chats/activities/query` | 发送、收到、@我、回复我的互动；私聊/群聊按来源身份展示 |
| 通话 | `/api/v1/call/history-buckets/query`、`/api/v1/call/history-aggregate` | 时间、对象、语音/视频、结果与已有摘要 |
| 录音 | `/api/v1/audio/get-calender-summary`、`/api/v1/audio/coverage/query`、`/api/v1/audio/transcripts/query` | 物理录音覆盖与有人声/转写分层，录音不是只有转写才算存在 |
| Arko / Bot | 各自的 `activities/buckets`、`activities` | 对话活动来源标识、分页与失败提示 |

月历会合并没有个人快记、但有聊天/通话/录音/Arko/Bot 活动的日期；日期格用来源圆点区分，数字仍只代表个人记录数，不把不同口径相加。时间线支持「活动片段 / 原始明细」、按日历时区计算日界线，单一来源失败时保留其它来源并明确显示部分状态。

该入口只允许文档列出的来源、模式和请求体，不能传任意 URL；浏览器不执行写操作、不触发已读、不自动启动录音或通话。记录的位置摘要只显示后端明确返回的标签和采集时间，不伪造坐标；有临时位置引用时仍通过既有 `calendar.record-location` 做权限复核。

## 轻量回顾与展示优化（2026-09-20）

- 顶部概览只统计当前筛选下已加载且可查看的活动，不是全天总量。原始明细模式使用「条对话记录」，活动模式使用「段对话」，不混淆计量口径。
- 重复的能力范围说明收进「查看范围」，部分来源标识常显；实际读取失败仍在外部显示，并有手动重试入口。时间轴按所选时区标注凌晨、上午、下午、晚上，不改变原来由近到远的排序或 15 分钟同源分组边界。
- 复用 `recordings.day` 已返回的摘要和录音时间线，仅选已完成且可查看的最新版本。显示对应日期、录音来源和生成时间；作为独立折叠回顾，不能绑定到任意一个短录音时段。这里不触发新生成。通话卡片明确标注已有摘要。
- AI 小结增加插件内部 Host 操作 `calendar.day-recap`，使用已有 `/api/v1/managed-ai/chat/completions` 通道，不新增业务后端接口，也不调用 `arko.ask` / `qa/new-msg-v2`，不建立会话或执行 Agent 工具。
- 用户先点「生成 AI 小结」查看云端处理及可能消耗额度的提示，可展开核对实际摘录，再点「确认生成」。输入最多 24 段当前筛选下可查看的活动预览、序列化合计不超过 6000 字符；不是完整原文。只允许时间、来源类型、备注优先标题、预览和范围说明，排除来源密文引用、位置字段和音视频附件；文本中的 URL 和明确坐标对也省略。用户原文仍可能包含地点或其他个人信息，因此提供实际摘录审阅。
- 复用默认托管 Flash 路由，动态核对模型能力，优先关闭思考或低思考，上限 1000 输出 token / 60 秒。没有工具、自动重试或模型兜底；不支持轻量档、余额不足、取消和失败均向用户说明。取消已提交请求可能仍消耗部分额度。
- 小结最多 5 条，每条校验来源编号确实存在；点击来源仅展开当前活动详情，不跳入会话、不写已读回执。来源存在性校验不等于 AI 内容事实核验，界面明确提示可能有误、核对原文，不声称恢复了未读到的数据。
- 缓存只在当前挂载页面内存中保存一次结果，以账号、日期、时区、筛选和素材身份/内容绑定；内容不变时折叠展开不重新计费。切换日期/账号取消在途请求，旧结果不显示；素材变化提示手动更新。关闭日历后不落盘保存，重新生成会再次调用模型。
- Host 校验当前账号、请求来源、用户确认字段、输入/输出界限及并发；取消信号贯穿到模型请求。现有日历权限/撤权通知限制仍然存在，此功能不宣称引入跨端实时权限事件。

原有后端缺口不因 AI 小结而消失：完整接收消息/群互动、完整 Bot/DSH 历史、按日期通话读取、全天地点和增量更新仍以文末接口边界为准。

### 本轮验证边界

- 2026-09-20：日历、摘录约束、AI 服务、Host、托管模型适配器等 16 个测试文件共 381 项通过；类型检查、完整构建和差异空白检查通过。
- 固定 `127.0.0.1:3098` 的独立已登录预览已更新，客户端构建哈希与仓库一致。实际浏览器验证了 9 月 20 日、17 日和 15 日的切换、已加载概览、时间段分组、通话已有摘要标注、录音覆盖，以及范围说明折叠、AI 摘录审阅与取消确认。
- AI 生成、来源定位回调、取消、账号/日期变化、重复生成保护、无效引用与模型失败通过自动化模拟验证。本轮未将真实私人摘录提交给云端 AI，也未声称已完成真实模型端到端验收；用户需在审阅摘录后主动确认首次生成。
- 此次抽查日期没有返回可展示的已完成录音回顾；回顾版本选择和折叠展示由合成数据测试覆盖，不以测试结果替代真实回顾样本验收。实际窗口为亮色主题，未把这轮浏览器验证扩大为全部尺寸和主题验收。
- 仅更新并重启独立 Web 预览；已安装 Arkme 客户端及其运行端口未改动。没有发送消息、写已读、发起通话、录音、提交、推送或发布。

## 本轮补齐：真实能力与边界

顶部分类为「全部 / 个人记录 / 对话 / 通话 / 录音」，另保留「地点」筛选。「对话」合并私聊、群聊、Arko、Bot、DSH 五类来源，统一按时间排列并保留逐页加载；卡片仍显示具体来源，详情与权限边界不变。这只是前端组合筛选，不新增业务接口，也不代表尚未接入的历史已完整可读。

| 来源 | 当前实现 | 仍然缺什么 |
| --- | --- | --- |
| 私聊 / 群聊 | 使用日历授权来源身份和备注名，显示与谁、在哪个群的互动；同一来源相邻 15 分钟内记录可合成片段 | 目前以我发送的记录为线索，不冒充完整双方往来；完整接收消息、被 @、背景群动态需要按日跨会话索引 |
| 通话 | 复用 `calls.history.list`、`calls.history.detail`；显示语音/视频、备注名、结果、真实通话时长、已有摘要；详情复用通话模块的转写/视频 | 历史接口当前只消费 limit/cursor，未消费按日期过滤；较早日期可能需继续翻页，不把未加载当作当天没有通话 |
| Arko | `arko.history` 每次 20 条；根据 sessionId 分组，区分我与 Arko 的回复 | 全历史按日索引；当前仍是 offset 分页，显示未加载完整的提示 |
| Bot | 先读 `bots.list`，每次最多读取 2 个 Chat-owned Bot 的近期窗口；插件增加 `bots.private-chat.history.read`，Host 重新校验 owner，只读 Chat timeline | Subject-owned 旧 Bot 的接口会走 open/ensure，不用于日历；近期窗口之外的日期分页尚未接入 |
| DSH | 明确的 creationSource=3 / dsh_agent_input 分类为 DSH，保留已同步输入与原始来源 | 完整工作会话、Agent 回复及工具事件的统一按日读取；共用登录不等于共享本地 DSH 工作历史 |
| 地点 | 当前可见活动最多自动补读 8 个，最多并行 2 个；另可手动展开读取，提供已确认地点筛选 | 全日完整位置索引；地点只代表某条记录的设备采集点，不是整段活动的地点或停留时长 |

- 此轮仅插件内部增加只读门面，复用既有云端接口；不修改手机端或业务后端。
- 通话引用会重新签发，不能比较密文引用是否相等。历史、聊天通话卡片和详情携带稳定的公开哈希标识；只在标识一致时去重。原始明细模式保留独立原记录。
- Arko 仅按明确 `entryRecordUid` 关联原输入，不能按 `createdRecordUids` 合并 Agent 产生的其他记录。Bot 只按明确 recordUid 关联。时间或昵称相同不能作为去重依据。
- 全部、私聊、群聊、通话、Arko、Bot、DSH、个人记录、录音均可筛选；活动片段和原始明细可切换。分段是已加载记录的显示聚合，不推断持续工作时长或 AI 语义事件。
- 每次主动分页最多读取一页日历、一页通话、一页 Arko 和两个 Bot；没有自动扫描全部历史。每次合并重排已加载窗口，旧日期/账号/刷新批次响应被丢弃。
- 默认预览与详情不发送已读回执，不发消息、不自动生成摘要、不启动通话/录音、不创建 Bot/DSH 会话；主动进入原会话后按原有行为处理。
- 2026-09-20 本轮验证：11 个相关测试文件共 157 项通过；完整构建包含类型检查通过。已登录 3098 验证了 9 月 18 日通话/私聊/群聊/DSH 输入及地点，9 月 17 日 Arko 历史，通话详情展开包含已有摘要、视频入口和转写。未发起通话、播放录音、发送消息或写已读回执；未对旧 Bot 完整历史、完整 DSH 工作过程或全天轨迹作已完成声明。

以下「第一阶段」段落保留此前交付记录；当前范围以上表为准。

## 核心需求

按日期回答：什么时候，与谁发生了什么互动，自己记录了什么，通话和录音发生了什么。

最终默认看活动片段，需要时展开原始明细，不把海量消息、转写逐条堆满。收到消息不等于参与讨论，预览不触发会话已读。录音覆盖与已识别人声分层，没有转写不代表没有录音。

## 不必等待全部新接口：先实现什么

| 能力 | 已有读取操作与业务接口 | 第一阶段使用方式 |
| --- | --- | --- |
| 自己的记录月历 | `calendar.buckets` → `/api/v1/calendar/buckets/query` | 数字仍是个人记录数，不冒充全部活动数 |
| 自己当天的记录 | `calendar.records` → `/api/v1/calendar/records/query` | 发给自己、私聊/群聊中我发送的记录及 DSH 输入；不是完整双方聊天 |
| 录音月历 | `recordings.calendar` → `/api/v1/audio/get-calender-summary` | 圆点表示录音索引有内容，具体本人归属以当日结果为准 |
| 录音覆盖与转写 | 现有 `recordings.day` | 已同步云端、明确归属于本人的物理音频区间及其转写 |

本次没有新增假设存在的 HTTP 路由，没有修改手机端、业务后端或已安装 Arkme 客户端。线上联调仍需可用的已登录预览环境。

### 第一阶段交互

- 第一栏日历打开「我的一天」：左侧轻量月历，右侧自己的记录与录音，按时间由近到远排列。
- 筛选全部、个人记录、录音；暂不显示未接入的私聊、群聊、通话筛选，说明文字明确当前范围。
- 个人记录逐条显示，保留原有图文、附件、长文详情。录音仅合并同一来源、同一状态且物理上连续或重叠的区间，不跨空档、不推断语义事件。
- 音频覆盖底层与已识别人声上层分开画；失败不伪装成空白完整日历，转写失败不隐藏已知音频覆盖。
- 点击预览不发送消息、已读回执或录音启动操作；主动点击来源入口才导航。进入原会话后沿用原有会话读取行为。
- 保留「原版日历」回退入口，不改变私聊/群聊内部的日历。
- 使用现有主题颜色，宽屏并列详情，窄屏上下排列。

## 性能、权限与一致性的真实限制

### 位置第一阶段（2026-09-20，已确认方案）

- 活动行显示已加载的设备采集地点标签，没有位置不占一行。点击标签或详情里的「查看地点」才发起详情读取；成功后补上该活动标签。
- 新增的是插件内部 Host/SDK 操作 `calendar.record-location`，复用已有业务接口 `/api/v1/records/detail` 与 `/api/v1/records/location/context/get`，没有新增云端接口。
- 地点读取只接受由本人全局日历授权记录签发的随机临时引用；按账号、服务地址隔离，15 分钟失效、最多 1000 个，不持久化。读取详情时重新检查记录身份、本人归属、内容访问状态及隐私锁，切换日期/账号会取消并丢弃旧结果。
- 仅 `location.source_kind=1` 的明确设备采集事实参与；不把分享地点、正文中的地点、转发内容、别人的位置当作本人行踪。不把位置自动扩展到录音时段，不推断停留时长或路线。
- 独立历史读取模型保留真实 `captured_at`，缺失时显示「采集时间未知」，不沿用旧快照解析中 `Date.now()` 的兜底。原有发送用的定位结构与采集行为不变。
- 来源设备及精度只显示真实返回值；设备名称未知不能推断为手机。当前保存接口未持久化浏览器精度，历史精度缺失是允许状态。
- 地点列表摘要只使用日历当前返回的元数据，不对每条记录执行两个额外请求。现有日历服务若没有返回位置字段，则先通过明确点击详情读取后补标签；不声称已获取所有记录地点。
- 读取失败显示错误和重试，不伪装成「没有位置」。未知/受保护记录不显示位置；当前日历授权投影仍受下文说明的实时撤权通知限制。
- 未包含全天位置点轨道、地图、地点聚合、连续定位或新定位授权。完整每日位置概览仍需确认现有位置查询能否按日期/本人设备采集来源过滤，或在日历记录接口附带轻量位置摘要；不扫描全部历史来补齐。

### 其他来源边界

1. 不扫描所有会话或全部历史。个人记录每次读 20 条，每页最多呈现 40 个条目；录音只读选中日期。旧录音时段等个人记录时间游标推进后再出现，不为排序一次下载全天所有个人记录。
2. `recordings.day` 目前返回当天转写等数据。本阶段复用它，**不声称录音网络数据已经按详情懒加载**。详情每次呈现最多 50 条转写。超长录音日可后续加轻量覆盖读取与转写分页，但不是首阶段的前提。
3. 仅 `recordingBelongsToViewer === true` 纳入转写；上传者、`isSelf` 说话人身份及昵称均不是录音归属证明。物理覆盖沿用现有 `coverage` 的本人归属判定，见 `recording-calendar-coverage.md`。
4. 录音接口使用设备本地日期，个人记录也用同一时区查询，不混用任意时区。按本地次日计算边界，夏令时日期不硬编码 24 小时。
5. 现有适配器的 `snapshotId` 是 `local-read-*` 客户端读取批次，只阻止不同查询或刷新批次混用，**不是服务端跨来源原子快照**。手动刷新和现有日历失效通知重新读取当天。
6. 详情沿用当前读取批次的授权投影，不声称已实现跨端即时撤权/删除推送。受保护记录不返回标题、预览或详情。账号/日期切换取消在途读取，旧响应不能更新新页面，来源访问仍经原有流程鉴权。
7. 一方来源失败不阻断另一方；读取最多等 30 秒，不对写操作重试。游标循环或过期要求刷新，不猜测后续数据。
8. 本机未上传录音、其他端正在录音状态、完整通话及所有收到的聊天不在本阶段已实现范围。它们保留在对应原有模块，后续单独接入。

## 后续缺什么，不要混成「所有功能都需要新接口」

| 后续目标 | 已有基础 | 需后端确认/补齐 |
| --- | --- | --- |
| 完整当日聊天互动 | 单会话日期统计、时间线定位、既有群聊 @ 互动读取 | 跨会话当日索引或批量查询；明确双方往来、本人参与、被 @ / 被回复、背景消息口径，避免枚举所有聊天 |
| 通话按日汇总 | 通话历史聚合和详情；当前插件历史只传 limit/cursor | 完整通话日期范围查询或日期索引。已发现 WebRTC history-buckets 路由仅覆盖其特定历史来源，不能当作全部通话 |
| 全来源月历 | 个人记录月历、录音索引可以先共存 | 各类存在性、计数及完整性；不能将不同含义的数字直接相加 |
| 活动分段与跨来源去重 | 原始记录来源引用、原文 | 稳定活动 ID、分段边界、关联 ID、参与对象、分页与版本；不因时间相似就合并通话卡片和录音 |
| 跨端即时更新与权限失效 | 各领域鉴权、刷新、局部通知 | 统一增量版本/失效事件及删除、撤回、权限变化语义 |

AI 摘要可异步补充，不是上线前提。先用来源、时间、真实记录数，不伪造摘要或猜测说话人身份。

这些结论基于本地消费代码，不等于证明线上所有服务缺少相关能力。后端同事先确认已有接口、服务归属和部署状态，再决定扩展还是新增。

## 代码与验证

- `ArkmePersonalDayCalendar.tsx`：第一栏入口、双来源月历、来源跳转、原版回退、丰富快记详情。
- `existing-day-activity-reader.ts`：现有接口只读适配、有限分页合并、物理音频区间及归属过滤。
- `ArkmeDayTimeline.tsx`、`use-day-activities.ts`、`calendar-activity-model.ts`：时间线、详情、查询隔离、能力筛选；前端视图模型不是新后端协议。
- 领域适配、入口、位置按需读取及原日历/录音/导航/Host/SDK 回归：16 个测试文件，357 项通过；类型检查和完整构建通过。位置用例覆盖缺失采集时间、非设备位置排除、隐私与归属校验、过期引用、取消读取及旧响应隔离。
- 离线浏览器验收使用真实组件和合成数据，网络全部拦截，不连接真实账号或业务服务：1440 像素亮/暗主题、800 像素暗色、420 像素亮色，均无横向溢出或页面脚本错误。这不等同于已登录联调。
- 当前分支 `codex/ts0919-02-日历活动时间线` 基于创建时的 `origin/master` `55d8525`（v0.1.68）；未提交、推送或发布。
- 2026-09-20 已恢复固定 3098 的独立 Web 预览，并按用户要求共用桌面端当前的系统凭据存储；没有复制业务令牌、退出账号、修改或重启已安装的 Arkme 客户端。共用凭据时请勿在测试中执行退出登录。
- 实际宿主发现的样式加载缺口已修复：DSH 客户端工厂不会自动加载打包器额外输出的 `style.css`。日历 CSS 改为随现有 `installArkmeRedesignStyles` 内联安装，两处组件不再依赖 CSS 副作用导入；离线预览也使用同一安装入口，避免 Vite 自动加载 CSS 掩盖实际插件缺口。原布局、明暗配色与业务逻辑未变。
- 本次修复新增 3 项样式回归（规则安装、实际固定定位/网格样式、重复安装与清理），修复前失败、修复后通过；相关 7 个测试文件共 87 项通过，类型检查、完整构建及差异检查通过。安装到独立预览的 `client.js` 与本地构建哈希一致，日历/地点样式已包含于客户端包中，不再产生孤立的 `style.css`。
- 已登录 3098 浏览器实测：第一栏日历正确覆盖主界面；今天/昨天日期切换、真实记录、活动详情、录音筛选及当天 5 段物理音频覆盖可正常展示。此次实际窗口为亮色约 817 像素宽；未将此冒烟验证扩大为所有主题、窗口尺寸、位置样本或全部业务功能的验收，前述离线验证仍是独立证据。
