Skip to content

release: 提请审阅 ExoMind 0.5.0 main 候选 - #971

Open
ARCJ137442 wants to merge 1207 commits into
mainfrom
release/v0.5.0
Open

ARCJ137442 wants to merge 1207 commits into
mainfrom
release/v0.5.0

Conversation

@ARCJ137442

@ARCJ137442 ARCJ137442 commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

审阅目标

@Hailaylin,这个 PR 把“v0.5.x 规划文档合并前”的开发主线快照提交给 main 审阅,不自动合并、不打新 tag,也不在本 PR 内启动后续 0.5.x 功能开发。

候选身份

  • Base:main@b679f93c,版本 0.4.21
  • Head:release/v0.5.0@bf1105c7;候选内容快照为 dev@16d08627,三个版本文件均为 0.5.0
  • 已有 Preview:v0.5.0,tag/manifest commit 为 af046336
  • 候选内容比 Preview tag 多一个提交:Action Dock PoC 16d08627。因此已有 v0.5.0 下载资产不包含 Action Dock,不能把资产与本 PR 内容说成逐字节一致。
  • bf1105c7 只是用 ours strategy 记录 main@b679f93c 祖先、消除 squash 历史冲突的 merge wrapper;它没有文件改动,tree hash 与 16d08627 都是 5f428fdc06092e5636d6d051012d86dd25260826
  • 后续规划文档已通过 #970 合入 dev@9aa7c5da,但本发布候选严格停在 16d08627,不夹带未来计划文档。

给审阅者看的产品摘要

这是从 main 的 0.4.21 到 0.5.0 开发线的累计同步,不是一个小型补丁。主要用户可感知变化包括:

  • 0.5.0 精简了个人主页、实时语音、旧工作台、反馈/遥测/法律支持/赞助入口和 MOSS 语音接入,主语音入口切换到火山。
  • EventLog 首屏和向上翻页改为有界加载与 keyset 分页,修复长日志打开慢和翻页卡死。
  • Signal journal 增加保留上限并启用 WAL,降低长期运行时持续磁盘 I/O。
  • Focus 的 soft end/handoff 配置恢复正确语义;时间块、Agent 和嵌入式 Runtime 在 0.4.22–0.5.0 期间也积累了一批稳定性修复。
  • Head 额外包含 Windows Action Dock 独立窗口 PoC;它不是旧悬浮工作台的等价替代。

请星林重点审阅

  1. 0.5.0 精简边界:删除旧悬浮工作台在当时属于有意精简;后续两个月实际使用证明,桌面端因此仍锁在 0.4.22。请重点判断 main 是否接受“0.5.0 记录这次精简、0.5.1 再恢复原子 overlay”的版本史。
  2. tag/head 不一致:如果 main 必须与已有 v0.5.0 资产严格同 commit,应把候选收回 af046336;如果接受文档合并前 dev 快照,则保留 16d08627 并明确 Action Dock 是 post-tag 代码。
  3. 同步与能耗已知债务:长跨度 EventLog 恢复仍由 #868 追踪,当前固定 backfill 的能耗治理也未完成;不能把 0.5.0 描述成同步完整性已经收口。
  4. 累计差异规模:main 长期停在 0.4.21,候选内容累计 1206 个 dev commit、1999 个文件;发布分支另有一个无 tree 变化的 ancestry wrapper。需要按发布主线审阅,而不是按单功能 PR 逐文件期待。

已知使用限制

  • 桌面端依赖悬浮工作台的现有使用者应继续保留 0.4.22,直到 0.5.1 恢复该能力;手机端可继续使用 0.5.0。
  • v0.5.0 是 preview,既有 Release 已明确不建议把 0.5.0 当作 0.5 系列最终稳定号。
  • 同步的长历史、断线续传和同 ID 冲突尚未完成新一轮验收。
  • Action Dock 仍是 PoC,不应作为恢复悬浮工作台完成的证据。

验证证据

  • package.json、Tauri Cargo 与 Tauri config 在 head 上均为 0.5.0
  • bf1105c7^{tree}16d08627^{tree} 完全一致,main ancestry 对账没有改变候选文件内容。
  • bun run build:web 通过(TypeScript + Vite production build)。
  • bun run website:build 通过(26 个静态页面)。
  • main-sync 禁入路径检查通过:候选树中没有 agent-output/、根 CONTEXT.md、根 0public/dev-assets/ 或 workspace skill 产物。
  • v0.5.0 Release manifest 已回读:tag=v0.5.0version=0.5.0commit=af046336,并再次确认它与 PR head 相差 Action Dock 提交。
  • git diff --check main...release/v0.5.0 仍报告 673 个历史 whitespace finding;本 PR 分支没有新增提交去批量改写这些历史文件,避免把无关格式清理混进发布审阅。
  • Cloudflare Workers 外部检查在 main/dev 既有提交上持续失败且无 annotation;正式 release/pages 主链路不依赖它,本 PR 将其视为已知非阻断噪音。

审阅后的动作边界

  • 本 PR 只等待审阅,不自动 promote 现有 Preview,不修改 GitHub Release body,不创建第二套 tag。
  • 审阅通过后是否合并 main、是否将 v0.5.0 从 preview promote 为正式版本,仍是两个独立决策。
  • 后续开发从文档合并后的 dev 分叉 0.5.x,按 迭代计划 PR #970 逐个 fix 推进。

ARCJ137442 and others added 30 commits April 10, 2026 23:56
Codex `/rename` writes session names to `~/.codex/session_index.jsonl`
as `{"id": "...", "thread_name": "名称", ...}`, but the runtime was
reading `~/.codex/history.jsonl` which has no names. This caused all
Codex sessions to show first-message previews instead of their renamed
titles in the session recovery dialog.

Changes:
- Add `read_codex_session_index()` to parse `~/.codex/session_index.jsonl`
  and build a `session_id → thread_name` HashMap
- Integrate it in `discover_codex_sessions()` as the final fallback in
  the display_title priority chain:
  session file thread_name > history /rename parse > session_index.jsonl
- Add 2 unit tests covering the new fallback path

Closes #838 (Codex side)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add Bun TypeScript script to detect GitHub issue body/comment newline corruption.
Problem: bodies written via MCP with literal `\n` instead of real LF bytes render
as a single wall of text. Detection rule: charCount > 200 && newlineCount < 3.

Also:
- Move script into skills/issue-tracking/ as affiliated utility
- Update SKILL.md with usage docs and important caveat about lossy compression

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Translate "When To Use", "Load Order", and "Core Rules" sections
from English to Simplified Chinese for consistency.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Records code-level evidence that all 6 v4 architecture layers are
implemented in dev (L1-L4 adapters/environment/services/UI, Tauri 2.0,
exomind-runtime), and documents the open tech-debt sub-tasks (#452-458).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ARCJ137442 and others added 27 commits June 8, 2026 06:38
桌面 exomind.exe 每次启动会 spawn reviewer/classifier 两个 bun 子进程,但它们
从未被传入 EXOMIND_LLM_* 配置、本机也无 API key,每次收到信号即静默失败
(stderr 被 Stdio::null 吞掉),已无任何功能。时间块总结现由内置 Rust agent
timeblock_summary(订阅 timeblock.replication.completed)接管。

本次彻底移除全部 TS agent 相关代码:

- 删除 packages/ts-agent-cli/ 整个包
- 移除 Runtime spawn 机制:spawn_default_ts_agents / try_spawn_ts_agent /
  spawn_ts_agents_default_for_platform / TsAgentProcess / RuntimeStartOptions
  的 spawn_ts_agents/ts_agent_command/ts_agent_workdir 字段 / RuntimeHandle.ts_agents
  字段及 stop()/Drop kill 逻辑 / RuntimeStopError::KillTsAgent
- 删除内置 task_classifier_actor(input.classified 唯一生产者是 TS classifier,
  已随之失效)
- 清理默认信号路由:session.end→reviewer、timeblock.completed→reviewer、
  user.input.normalized→classifier、input.classified→task
- 前端:移除 timeblock.service.publishTimeblockCompleted 及调用、signal-topics
  中相关常量、agent-hub mock 路由/agent 兜底数据
- 删除/调整相关测试、scripts/start-agents.sh、vite watch 排除项

保留说明:
- resolve_project_root_from 保留为 pty 工作目录解析的通用基础设施,改用
  package.json+Cargo.toml 作为项目根标识(不再依赖 TS agent 入口文件)
- task::actor::spawn_task_store_actor(task.auto-created→TaskStore)与前端
  task.auto-created 处理器保留为通用任务持久化基础设施,当前无生产者故休眠,
  可被未来内置 classifier 重新喂入

验证:cargo check -p exomind-runtime --lib 通过;前端 tsc --noEmit 0 error;
vite-env-prefix.test 通过。(timeblock_runtime_sqlite_persistence /
today_planner_routes 的 BlockPhase 类型错误为 dev 分支既有问题,与本次无关)

Co-Authored-By: Claude <noreply@anthropic.com>
refactor(runtime): 清除已失效的 TS agent(reviewer/classifier)全部代码 (#957)
macOS 包暂未签名,arm64 在 14.4+ 上即便清隔离仍可能报'已损坏'(强制签名)。
新增 ad-hoc 自签(codesign --sign -,免 Apple 账号)用户侧指令 + 构建侧
signingIdentity:'-' 选项,docs/macos-install.md 方案 D;README/README-zh
首屏加 macOS 首次启动小节并链接完整文档。
GitHub Pages(exo-mind.ai)下载页新增双语 macOS 首次启动小节:未签名版
Gatekeeper 说明 + Apple Silicon ad-hoc 自签命令 + 链接 docs/macos-install.md。
三批功能精简(dev 直接开发, tsc --noEmit + cargo check 双绿):

批次A 杂项 + Me页:
- 删反馈建议/遥测/报告问题(MoreSection)、赞助/法律与支持(AboutSection + LegalSupportPage)
- 删 Me 个人页全链路: 页面/路由/侧边栏/me-page-enabled 开关/命令面板 navigate:me,
  及整套 me 数据层(service/port/adapter/mock/types)与 DI 接线(bootstrap/environment)
- 保留时间块反馈核心功能

批次B 语音精简(只留火山):
- 删实时语音子系统 voice-runtime: doubao / qwen-omni-realtime / omni-compatible
  providers、VoiceRuntimeLabPage、语音助手设置、Rust realtime 命令
- 删 Qwen-Omni 快捷输入适配与 voice-omni 配置
- 快捷语音输入 provider 归一为火山(volcano-only)
- 保留 voice-signal 共享总线、VoiceOverlay 录音浮窗、火山全链路
- MOSS 暂留(仍是 App 内主语音按钮引擎, 设置项改 devOnly, 待后续迁移火山再删)

批次C 工作台 / 测试页:
- 删 WorkbenchPage / 工作台浮窗、MOSS/火山/Sync 测试页、vite 多入口、Rust overlay 命令
- LegacyWorkbenchShim 改为 AgentsPage / AgentConversationPage 直渲染
- 保留 tiled-workbench(AgentsPage 平铺键盘导航, 名字碰撞非工作台)、VoiceOverlay

测试: 同步清理被删功能的测试债; voice-shortcut.service.test 改造为火山-only。
剩余 vitest 失败为预存基础设施依赖(runtime server/profile/Tauri host/测试自身 mock 不全),
非本次精简引入。

Co-Authored-By: Claude <noreply@anthropic.com>
- 新增 VolcanoRecognizeASRAdapter(src/lib/adapters/asr/volcano-recognize-asr.ts):
  实现 ports/asr-port IASRPort, transcribe 取 preRecordedAudio(WAV)→slice(44)得PCM
  →invoke('volcano_asr_recognize'),复用 voice-shortcut.service 已验证的火山一次性
  转写路径,含额度回退。配置统一从 getStoredVolcanoRuntimeConfig 读(存储值优先于 env)。
- VoiceInputButton 默认引擎 MOSSASRAdapter→VolcanoRecognizeASRAdapter,录音流程不变。
- 彻底删除 MOSS: moss-asr.ts / moss-api-key.ts / moss-asr-auth.test.ts,
  及 settings-registry 的 MOSS 设置项、settings-custom-items 的 MossVoiceTestSetting、
  voice-chat.service(死代码)的 MOSS 分支。
- 同步更新 voice-chat/voice-shortcut/settings-registry-coverage 测试。

验证: tsc --noEmit + cargo check 双绿; Tauri MCP 自动驱动真机实例端到端测 transcribe,
填入真实火山凭证后授权通过、转写链路返回合法结果(WAV→火山云→result),不再 401。
(401 仅出现在全新隔离测试实例未配凭证时;日常实例 localStorage 已存火山凭证。)

Co-Authored-By: Claude <noreply@anthropic.com>
refactor: 精简外心——删 Me页/实时语音/工作台/反馈遥测法律赞助 + MOSS→火山
issue #959:signal_journal 表只增不删(实测涨到 ~100万行/177MB),且 signal 库
未开 WAL,默认 DELETE+synchronous=FULL,每条信号一次最坏代价 fsync,tick 周期写
持续打盘。

- 新增 sqlite_util::configure_connection():集中 WAL/synchronous=NORMAL/
  busy_timeout 调优;WAL 切换 best-effort(只读库忽略,不让优化搞挂 open())。
- SqliteSignalStore::open 套用该配置;append 每 512 条增量裁剪到保留上限
  (JOURNAL_RETENTION_ROWS=10000,内存环仍 1000);open 时一次性裁剪历史膨胀
  并 VACUUM 回收磁盘,best-effort 不阻断启动。
- 两个回归测试:增量裁剪上界 + 重开裁剪历史膨胀。
- eventlog 暂不开 WAL(snapshot_bytes 直接 fs::read 主库,WAL 下快照不完整),
  仅加注释说明,列为后续项。

Co-authored-by: Claude <noreply@anthropic.com>
…卡死 (#962)

* perf(eventlog): ChatPage 改为有界加载+后端分页,消除首屏十几秒卡顿

根因:ChatPage 初次加载与轮询 fallback 都调 loadEventsDetailed() 不带 limit,
每次全量拉取账号全部事件(实测 profile-v2 达 3.4 万条 / metadata 13.9MB),
后端取行+解析+16MB JSON 传输+前端 parse+sort 叠加造成十几秒卡顿。
SQLite 已走索引、渲染已窗口化(PAGE_SIZE=50),瓶颈纯在「无上限全量快照」。

改动(方案 A 真·后端分页):
- 初次加载只拉最近 INITIAL_LOAD_LIMIT=200 条
- 向上滚动越过内存头部时,用最早事件 untilTimestamp 向后端拉下一页(OLDER_PAGE_SIZE=50)
  闭区间 until + prependOlderEventsAscending 按 id 去重;不足一页或无新增即判定到底
- 全量 reconcile 限 max(200, 已加载条数),保住已翻出的更早历史、不再全量拉数万条
- permalink 定位更旧事件时向后端回溯分页(上限 MAX_LOCATE_OLDER_PAGES)
- hasMore 同时反映内存剩余与后端可拉;prepend 保持滚动锚定

测试:typecheck 通过;更新 issue769 测试断言至有界契约(初始/ reconcile 带 limit);
与 origin/dev 基线对比零净回归(预存的 fake-timer 环境失败两边一致)。
注:滚动→后端拉更早页的组件级 wiring 因 jsdom 无布局无法自动化,需 app 内手测。

Co-Authored-By: Claude <noreply@anthropic.com>

* fix(eventlog): 滚动回溯改用 (timestamp,id) 复合游标,修同时间戳大簇卡死

实测 bug:向上翻页到某些事件就卡住、翻不到更早(如 2026-04-01 14:40:54
那条),根因是「拉更早页」只用 until_timestamp 单游标。本库存在批量导入
造成的同时间戳大簇(实测单时间戳最多 2041 条、55 个 >=50 条的簇),DESC+
limit 下每次都返回簇里 id 最大的同一批(已在内存),added=0 被误判到底、
关掉翻页 → 卡死在簇边界。

修复(真·keyset 分页):
- 后端新增对称的 list_events_before_cursor_filtered:
  WHERE timestamp < ? OR (timestamp = ? AND id < ?),吃满既有
  (user_key, timestamp DESC, id DESC) 索引;SqliteEventLogStore + EventLogStore
  (JsonFiles/Sqlite 两后端) 均实现
- 路由 GET /eventlog 加 until_id 参数,与 until_timestamp 配对触发 before-cursor;
  旧的纯 until_timestamp 路径保持向后兼容
- 前端 EventLogListOptions 加 untilId;rt-adapter buildListPath 透传 until_id;
  ChatPage.fetchOlderPageFromBackend 带 untilId=最旧事件.id
- 新增 Rust 单测覆盖「同时间戳簇跨页」(原代码缺的正是这个场景)

验证:Rust 单测通过;前端 typecheck 通过;运行的 desktop 实例端到端实测——
驱动真实滚动,事件 200→800、每页稳定 +50、最旧时刻穿过 14:40:54 簇到 14:40:46,
不再卡死。

Co-Authored-By: Claude <noreply@anthropic.com>

---------

Co-authored-by: Claude <noreply@anthropic.com>
* fix(focus): respect countdownEndMode in handoff path

Extract consumePendingHandoff's markEnding decision into a pure function
resolveHandoffAction() and add countdownEndMode guard.

Previously, when Android AlarmManager fires (either via autoOpenFocus
tryAutoOpen or user tapping the notification), the handoff consumption
path called markEnding() unconditionally, ignoring the user's
countdownEndMode='soft' preference. This caused timeblocks to be
forcibly stopped even when the user had configured "gentle reminder".

New behavior:
- soft mode: handoff only navigates to focus tab, keeps block running
- hard mode: handoff calls markEnding as before

Includes 8 unit tests locking the contract of resolveHandoffAction.

* fix(时间块总结Agent): 提示词消歧义,避免Agent把自身能量当作人的能量

通过能量机制,外心的Agent一次性只会消耗有限能量,能量耗尽后不会消耗更多token。
Agent的能量需要自我监控,并且这需要是「作为Agent,你的自我状态」而非被误解成人的状态
内部 docs 留痕:把 0.5.0-preview 的发布日志草稿归档到 docs/development/release-notes/。
原 inbox/ 副本留作工作底稿,本目录为仓库内单一真源。

含决策(与 Argon/星林 商讨):
- 0.5.0 是精简路线的起点版本
- 自 0.5 起每做一次精简/重构/bug 维护就发一个小版本号
- 用户真正可用的稳定版本是 0.x.[max] 而非 0.x.0
feat(appbar): Windows AppBar action-dock 独立窗口 + PoC 改进版接入

- 用 exomind-appbar-poc 验证后的 appbar/ 模块替换旧 windows_appbar.rs:
  关键改进:① DIP 而非原始像素 + GetDpiForWindow DPI 感知;
  ② SetWindowSubclass 监听 ABN_POSCHANGED 自动重排;
  ③ run_on_main_thread 主线程调度
- 新建 action-dock 独立 WebviewWindow(仿 voice-overlay 多窗口模式)
- 前端 Mock Demo 页面:上下分区(ExoMind 行动区 + OneNote 预览预留)
- 配置迁移:widthPx → widthDip,默认 360 DIP,范围 220–720
- 依赖:windows-sys → windows 0.61(加 HiDpi / Controls features)

Co-Authored-By: Claude <noreply@anthropic.com>
@
@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Aug 24, 2026

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
❌ Deployment failed
View logs
exomind bf1105c Aug 24 2026, 09:26 AM

@ARCJ137442
ARCJ137442 requested a review from Hailaylin August 24, 2026 09:25

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants