• get_stale_contacts / get_org_members / link_person_org / find_relevant_persons
    漏加到 REACT_SYSTEM_PROMPT,LLM 不知道它们存在导致从不调用。
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • P1 #3 关系类型 + 强度:
    - DB v21→22:relations 加 type(TEXT) + strength(REAL DEFAULT 1.0)
    - RelationBuilder:strength = min(weight*0.5, 5.0) 初始化
    - RelationDao:updateType / updateStrength
    
    P1 #4 Organization 一等公民:
    - 新实体 Organization(id,name,kind,url,notes,createdAt)
    - 新实体 PersonOrg(id,personId,orgId,role,startDate,endDate)
    - DB v22→23:建两张表 + 索引
    - OrganizationDao / PersonOrgDao(fix: 补 @Delete import 解 MissingType KSP 报错)
    - Repository 暴露 organizations / personOrgs
    
    P1 #5 「谁能帮我」工具:
    - LifelogTools 新增 get_stale_contacts(失联联系人排序)
    - LifelogTools 新增 get_org_members(查组织成员)
    - LifelogTools 新增 link_person_org(建人↔组织关联,组织自动创建)
    - LifelogTools 新增 find_relevant_persons(goal)(关键词匹配 resume/impression + 关系强度加权)
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • - ContactRow 右侧显示最近联系时间(今天/昨天/N天前/N月前)
    - 超过 30 天显示红色「⚠ N月前」警告
    - ★ 最近联系人排序改用真实联系时间(微信消息 MAX + 被提到 MAX),
      替代原来只记打开档案时间的 lastAccess
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »

  • 从微信消息 / 被提到录音段 / 本人录音三者取最近时间戳,替代原来
    只记打开时间的 lastAccess,在 ProfileHero 显示「最近联系 X 天前」;
    超过 30 天自动附加红色警告标签「⚠ 超过 N 个月未联系」。
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • - app 名称:Lifelog → Life OS(strings.xml + AndroidManifest 硬编码修正)
    - 图标:红色关系网络 → 深紫渐变轨道设计(人物居中 + 双同心环 + 卫星节点)
    - 新增 TimelineScreen:录音/微信/朋友圈/照片四源按时间混排,日期分隔头,来源过滤 chip
    - 底部导航加「时间轴」tab(第三位:对话/人物/时间轴/录音/相册/设置)
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • - 新增 refresh_person_data 工具(第 ⑲ 个):查询某人前先解密
      EnMicroMsg.db 读最新聊天 + 从 SNS 缓存读最新朋友圈,写入 Room
    - REACT_SYSTEM_PROMPT 指令:查某人聊天/朋友圈/时间线前必须先调此工具
    - 恢复 Tavily 默认 key(linter 曾将其清除)
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 对话工具模式新增 web_search 工具,调用 Tavily Search API 搜索公开
    互联网;ModelConfig 加 tavilyKey/saveTavilyKey;SettingsScreen 加
    「全网搜索(Tavily)」配置区。Key 留空时工具返回提示而非报错。
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 背景:#C62828→#FF5252 渐变;前景:中央大节点(白圆+红色人物轮廓)
    + 四方位卫星节点(白圆+小人轮廓)+ 白色主线/次级连线,
    构成人际关系网络图。
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • Adaptive Icon:ic_launcher_background(#1A0A3C→#7C3AED 135° 渐变)
    + ic_launcher_foreground(白色麦克风胶囊体 + 3条声波纹路 + 弧形支架
    + 右上角红色录制圆点)。minSdk=30 只需 mipmap-anydpi-v26,无需 PNG。
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 扩展 update_person_profile 工具支持 resume / impression / realName
    三个直接列(原来只能改 profileJson 里的 JSON 字段);PersonDao 加
    updateResume + updateRealName 两个精确列更新查询。AI 现在可用单一
    工具写入所有联系人档案字段,无需多个工具。
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • Person.profileJson(DB v21)存 MBTI/八字/性格/社媒账号 JSON blob;
    PersonProfileScreen 简历 tab 新增性格分析卡 + 社媒账号卡(可点击外链)
    + 「✎ 编辑性格/社媒」入口;EditProfileJsonDialog 13 字段滚动编辑;
    AI 工具 update_person_profile(字段粒度写入)+ get_person 输出档案字段;
    ChatViewModel 工具循环改 ReAct 文本协议(TOOL_CALL: {json})兼容所有网关。
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • ## 多服务商 & 任务槽(ModelConfig + SettingsScreen)
    - 新增 ModelConfig:LlmProvider 注册表(本地/Hermes + 用户自定义远程)+ ModelSlot(VL/EMBED 槽绑定),SettingsScreen 可视化管理
    - ChatConfig 加 ChatTargetKind.REMOTE;targets() 动态合并本地+Hermes+用户服务商
    - VisionClient / EmbedClient / PhotoVlWorker 统一走 ModelConfig.slotEndpoint 取端点
    
    ## Tool Calling & Agentic Loop(LifelogTools + ChatViewModel)
    - LifelogTools:6 个本地工具(search_transcripts/persons/photos/timeline/summaries/followups),OpenAI function schema + 端上 Room 执行
    - ChatViewModel:agenticLoop 检测 tool_calls → 调 LifelogTools.execute() → tool role 追回 → 多轮直到无 tool call
    
    ## 语义搜图 embed 落地(Pixel 设备侧 + 补算)
    - 下载 bge-small-zh-v1.5-q8_0.gguf(25MB,512维中文)到 Pixel ~/models/
    - llama-swap config.yaml 新增 "embed" 条目(--embedding --pooling mean,ttl 600)
    - 补算向量:PhotoDao.withCaptionNoEmbedding/updateCaptionEmbedding + PhotologViewModel.backfillCaptionEmbeddings()
    - AlbumTab ProgressHeader 加「🔢 补算语义向量」按钮(有 caption 无 embedding 时显示,带进度)
    
    ## 文档
    - HANDOFF.md:P0/P1/P2 全部打 ✅,补 v0.9 已完成列表
    - CLAUDE.md:v0.8→v0.9,⭐待做项更新为已完成
    
    Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 4922 联系人里绝大多数是群友(共群非好友),真好友只 ~214。区分依据(真机验证):
    - 好友 = rcontact.type & 1 = 1 且 deleteFlag = 0(有备注的人无一 type=4,佐证 type=4=群友)
    - persons.wechatFriend 列(迁移 19→20,true=好友/false=群友/null=未知)
    - WeChatContactsImporter 加 isFriend 计算 + friendsOnly 参数;img_flag 改 LEFT JOIN
      (好友头像多不在 img_flag,INNER JOIN 会漏,改 LEFT 后头像可空、人照导)
    - WeChatEnrollWorker 落 wechatFriend
    - 通讯录:导入分「💬微信好友(只好友)」/「+群友(全部)」;过滤 chip 好友/群友/全部(默认好友);
      每行标签 微信好友/群友/微信
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 最后一块去 Mac 依赖——联系人/头像也端上读:
    - WeChatDb:共享的 EnMicroMsg.db 端上解密(su --mount-master + 算 key + SQLCipher 打开),
      WeChatChatImporter 重构成复用它(聊天逻辑不变)
    - WeChatContactsImporter:解密读 rcontact ⨝ img_flag 真人筛选(移植 Mac extract-wechat-avatars.py)
      → 产出 wx_enroll/enroll.json + OkHttp 12 线程并发下高清头像(img_flag.reserved1, wx.qlogo.cn 公开)
      → 触发现有 WeChatEnrollWorker 做 Person upsert + 端上人脸锚点
    - 通讯录选人页「💬 微信导入」改成端上 importWeChatContactsLocal(不再依赖 Mac 推 enroll)
    - 通讯录加「全选/取消全选(N)」批量纳入管理(作用于当前过滤列表,可先搜再全选)
    - 真机验证:读到 4922 联系人 + 4818 头像
    
    注:当前导入含群友(rcontact.type=4),好友(type&1=1)区分 + 导入筛选下一步做。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 微信聊天本地化——EnMicroMsg.db 是 SQLCipher 加密的,过去靠 Mac 解密推 wx_enroll,现在端上直接读:
    - key 纯端上可推导(真机验证,无需 Frida):MD5("1234567890ABCDEF" + uin)[:7]
      imei 用微信默认值(现代 Android 读不到真 IMEI 的回退,稳定);uin 从 shared_prefs last_login_uin 读
    - WeChatChatImporter:su --mount-master 拷 EnMicroMsg.db + 读 uin → 算 key → SQLCipher 打开
      (cipher_compatibility=1, cipher_page_size=1024) → 读 message 表 type=1 文本,按 talker 取目标 wxid
    - 依赖:net.zetetic:android-database-sqlcipher:4.5.4
    - 接线:单人「⬇下载图片」顺带解密该人聊天;「🔄更新」一次性解密整库读所有 wxid(避免逐人重复解密)
      聊天写 wechat_messages(按 talker 先清再灌,幂等);档案页「聊天」tab 直接显示
    - 真机验证:读到与某联系人的聊天记录
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 人物档案页:
    - 整页改一个 LazyColumn:hero(头像/简介)+搜索框 当列表项随滚动滑走,TabRow stickyHeader 吸顶
      → 内容区拿到整屏、能全屏滑(原来 hero 固定 top,内容只剩一小条)
    - 「简历」做成第一个 tab(真名/简历/AI印象),从 hero 的「关于卡」挪出 → hero 变矮
    - 照片网格改 LazyColumn 内手动 3 列行(避免 lazy 嵌套同向滚动)
    
    通讯录页:
    - 搜索框右边「🔄 更新」:批量更新所有有微信的管理人物——逐个 downloadWeChatCore(头像+朋友圈)
      + 全局重建 提及/关系/待办 + 催全相册识别。不碰录音;聊天暂不本地更新(EnMicroMsg 加密)
    - downloadWeChatImages 抽出 downloadWeChatCore 复用
    
    并带入并行的端上 CRM(话题 TopicExtractor/TopicsScreen 等):与本功能在 Daos/迁移链耦合,整树可编译。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »

  • 端上 CRM #3 关系分析的「待跟进」部分(社群发现/关系链/followups 表已随 2a6f991 入库)。
    - FollowupExtractor:取最近 80 段、切 25 条/窗(≤4 窗控耗时),喂本地 4B 抽行式待办,
      解析去 bullet/编号/「无」,词典子串关联 Person;写 followups(去重键 sourceTs+text)
    - FollowupsScreen + 人物 tab「✅ 待办」入口:列表(完成勾选/删除) + 右上「扫描」
    - PhotologViewModel scanFollowups/setFollowupDone/deleteFollowup;Repository 接 followups dao
    
    真机验证:扫描 4 窗 → 15 条真实待办(如「明天每人汇报个人规划」「给高宇提要求放开平台功能」),
    人物关联命中(高宇),可勾选/删除,无错。需 llama-swap(8080) 在跑。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 朋友圈/头像全部端上化,不经 Mac:
    - WeChatSnsImporter:su --mount-master 读明文 SnsMicroMsg.db + sns 缓存大图(snsb_*)。
      坑:app 申请的 su 默认在本 app 挂载命名空间(看不到微信数据)→ 必须 --mount-master 切全局;
      且 app-su 的 PATH 为空 → 脚本须 export PATH。按「条」归属:content 子串匹配 media id。
    - 人物档案「⬇下载图片」:头像→照片(归属脸,进「照片」tab);朋友圈**按条**存
      moments/<wxid>/<ms>_<i>.jpg + 文字进 moments 表;朋友圈图不进相册。幂等(getByPath/clearUser/
      目录清空)+清理旧版误导入的 moment_ 照片。
    - 朋友圈 tab 改成微信式「时间+正文+九宫格图」(MomentRow 按 createTime glob 回该条的图)。
    - 相册加「人物文件夹(默认)/所有图片」两 tab(observePersonPhotoCounts,复用 faces.personId)。
    
    并带入并行进行中的端上 CRM(人↔人共现 Relation/社群):AppDatabase v17 + Entities/Daos/
    CommunitiesScreen/crm.RelationAnalysis —— 与本功能在 Daos/迁移链上耦合,无法干净拆分,整树可编译。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 端上 CRM #1:把录音会话里同时出现的人连成关系图基础。
    - 新表 relations(personA<personB, weight, lastTs),Room v16→17
    - RelationBuilder:按 5min 静音切「会话」→ 会话内「在场」(声纹→已绑 Person) ∪「被提到」(mentions)
      两两配对成无向共现边,weight=共现会话数;全量重建(接在 mentions 重扫之后)
    - PersonProfileScreen 加「相关」tab(共现的人,按次数排,点击跳该人档案);tab 增至 6 个改 ScrollableTabRow
    - 加 onOpenPerson 人→人导航(复用 profilePersonId)
    
    真机验证:迁移成功不清库;rescan 后 RelationBuilder rebuild 1668 段→0 边(仅 1 人 managed,正确),
    「相关」tab 渲染空状态无崩溃。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 主体(回链 lemonPCRM 方向,端上版):
    - Mention 实体 + mentions 表(迁移 15→16):某段转写文本提到了某 Person(词典反查名字/别名命中)
    - crm/MentionExtractor + RelationBuilder:从转写抽人名→建 (segmentId,personId) 提及边
    - PhotologViewModel.rescanMentions:按 managed 人物词典全量重扫;档案页「被提到」展示
    - BlockProcessor / Daos / Repository 相应接线
    
    同链顺带(迁移 14→15,与 15→16 同属一条链,必须同提交才自洽):
    - 相册删除墓碑 DeletedGallery:app 内删的相册照片记 mediaId,全相册重扫不再导回;导入源删除时删私有副本
    - 照片详情显示文件名 + 存储地址(gallery 从 MediaStore 反查真实名/相对路径)+ 来源/状态/模型/#id,可长按复制
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 端上 CRM #5:从转写文本反查提到了哪些已知联系人,不依赖 LLM。
    - 新表 mentions(segmentId, personId, matchedText),Room v15→16
    - MentionExtractor/MentionScanner:拿 managed 人物的 名字/真名/昵称/备注/微信号(≥2字) 当词典,
      在 Transcript.text 里扫子串命中;零幻觉、可离线 backfill
    - BlockProcessor 实时挂钩:转写出文字后顺手扫提及入库(词典每块预载一次)
    - PhotologViewModel.rescanMentions:全量重扫按钮
    - PersonProfileScreen 加「被提到」tab(别人录音里提到 TA 的段,按声纹=谁说的 展示,可播放可搜)
    
    真机验证:迁移成功不清库;rescan 1613 转写×1人→0 提及(仅自己 managed,名字不出现在转写里,正确)。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 把整个手机相册自动跑成可搜索内容(v0.8)。本地 VL ~30-40s/张,
    全量是按天计的长任务 → 分层:快的全量先铺,慢的 VL 排队慢慢补。
    
    - GalleryScanner:MediaStore 游标扫全量,content:// uri 原地登记不拷文件,
      mediaId 去重增量;photos 加 source/mediaId/scanState/captionEmbedding(Room v14)
    - Tier-0 PhotoFaceWorker:扫描 + ML Kit 人脸 + 512d emb + GPS,秒级全量铺,
      battery-not-low;Tier-1 PhotoVlWorker:VL 场景描述 + caption 语义向量,
      优先级队列(有人脸>近期),充电时跑,尊重暂停标志
    - 搜图:关键词(caption+人名 LIKE) + 语义(caption 向量余弦,EmbedClient 打
      llama-swap embed 模型;未配置优雅降级)
    - VL 控制(PhotoVlState):运行中「暂停/停止」、空闲「立即理解/继续」切换,
      正在处理的格子转圈,格子角标 待索引/待理解/已描述
    - 修 ImageUtil.decodeUri:bounds 预解码 decodeStream 在 inJustDecodeBounds
      下按设计返回 null,原 `?:` 误判致每张提前 return(人脸全跑空)
    
    迁移 13→14 纯增量:老的已处理照片直接标 scanState=2 不重跑。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »

  • - QuietHours:可配时段(跨午夜支持,如 23:00→07:00),存 lifelog_prefs
    - RecorderService 重构为 reconcile():采集 = 非手动暂停 且 非静音时段;每 30s 调和,
      到点自动停/起。手动暂停彻底释放 wakelock;静音时段保留 wakelock 供定时器到点恢复。
      统一了手动暂停/恢复与定时不录两条路径(capturing 单一真相 + statusText 去重通知)。
    - RecorderState 加 isQuiet;首页状态显示「🌙 静音时段(自动)」、秒表冻结
    - 设置页「录音/电池」段加 定时不录 开关 + 起止时刻(整点);30s 内生效,无需重启服务
    
    真机验证:窗口外正常录音(reconcile→录音中,回归通过);窗口内自动转「静音时段」停采集、
    秒表冻结;关窗口后恢复。测试用窗口与服务状态已还原。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 块级管线下一个块的所有 turn 共用「块完整录音」.opus,靠 audioStartMs 偏移切片。
    人物档案「语音」列表 + 时间轴段操作面板原来 player.play(audioPath) 从头播整块,
    导致播的音频跟该行文字对不上(同块多行还都播同一段)。
    - SegmentRow 已带 audioStartMs(声纹打通那次顺带加的数据位),这里用上:
      player.play(audioPath, audioStartMs, durationMs) 切片播
    - 时间轴 turn 播放顺带简化:不再额外查一次 Segment 取偏移
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 参考 LinkedIn 档案格式重做档案页顶部:
    - 渐变 banner + 压在上面的大圆头像(无头像显示名字首字)
    - 名字 + 身份副行(微信名/真名/微信号/电话)
    - 身份 chip:来源(微信/手机) · 🎤声纹 · 📷人脸(已具备则高亮)
    - 操作行可横滚:编辑/录一段/选声纹/合并/AI印象
    - 「关于」卡:简历 + AI 印象
    下方保留 照片/语音/聊天/朋友圈 4 tab + 搜索不变。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 声纹本质是要识别成人物。桥接方案(保留声纹库,识别后处处显示人物):
    - 声纹 tab 每个说话人显示「已识别为人物 X / 未识别」,加「识别为人物」入口:
      IdentifySpeakerSheet 输名字→绑已有人物或新建人物(声纹↔人物强制 1:1)
    - 时间轴/段操作面板:声纹一旦识别为人物就显示 👤人物名(SegmentRow LEFT JOIN persons)
    - 自动聚类仍只产「说话人N」,确认后再升人物(不自动灌 CRM);重命名与识别为人物分开
    - PersonDao getByVoiceSpeaker/clearVoiceSpeaker;bindVoice 也保 1:1
    - 顺带:改派说话人 / 合并说话人 由 AlertDialog 改 ModalBottomSheet,
      原来列表塞进对话框被挤得不能搜索/滚动、没确认按钮
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 24/7 录音 .opus 只增不减(实测 ~32MB 攒几天),加保留期清理:
    - StorageManager.prune:按天目录名删除早于 N 天的 segments/yyyy-MM-dd/(不碰 DB,
      Segment 行保留→文字永留;audioPath 仍指向已删文件,播放对缺失文件优雅 no-op;
      不动在途 blocks/)。+ audioUsageBytes 统计占用。
    - StorageTtlWorker + StorageScheduler:每天一次 periodic 清理(电池不低时),LifelogApp 注册
    - 设置页「存储」段:录音占用显示 + 保留时长下拉(永久/7/14/30/60/90 天)+ 立即清理按钮
    - 默认「永久保留」(ttl=0 不删):自动删录音是破坏性的,由用户主动选保留期才生效
    
    真机验证:占用读数 31.9MB 与 du 一致;UI 渲染正常。未跑真实删除(默认关闭)。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 贪心单遍聚类会把同一人切成多簇:早期噪声段一旦另起簇,后续同人段按「最近质心」
    各自归簇,再不会并回(实测主说话人被拆成 说话人11+12+29,质心却差 0.65+)。
    
    - 新增 SpeakerClusterer.mergeOverSplit:重聚类后做 agglomerative 合并——反复把质心
      余弦 ≥ mergeThreshold 的两簇并掉,质心用两簇全部成员段重算(比存的封顶滑动均值
      更准,能暴露被掩盖的过切:实测 说话人11↔12 成员重算余弦 0.749)。
      约束:不并两个人工命名簇;一人工一自动并入人工保留名字;都自动并入成员多的。
      合并后刷新被并段的 speakerId 与相似度。
    - reclusterAll / clearAllAndRecluster 收尾调用合并;mergeThreshold 默认 0.55,设置页可调
    - 真机实测:32→29 簇,主说话人统一为单簇(580 段),残留仅 4 对 0.50–0.52 小簇待人工
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 档案页「🔗 合并重复」→ 独立选人子页(搜索+全部人物列表,含微信池) → 确认 → 并入当前人物:
    - 人脸归属改派、声纹/人脸锚点/头像/昵称-备注-微信号/手机号/真名/简历/AI 印象 缺啥补啥
    - contactRef 优先保留 wechat: 引用,合并后微信聊天/朋友圈/AI 印象不丢
    - 被合并的那条删除;当前人物存活并置 managed
    - DAO: FaceDao.reassignPerson + PersonDao @Update
    - 选人改用整页子页(MergePersonPickerScreen),不再塞进 AlertDialog(之前被布局挤没、看不到搜索/列表/按钮)
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 之前「📱手机通讯录」一点就全量导进池子,改为跟微信导入一致的列表+多选体验:
    - 新增 PhoneContactPickerScreen:READ_CONTACTS 后读系统联系人成内存列表(不入库),
      按拼音 A–Z 分组+搜索,每行显示 人名+手机号 带复选框,支持全选/取消全选
    - 勾选「导入选中」才入库,直接进「我管理的人物」(managed=true,不用再去池子勾第二遍)
    - VM: importPhoneContacts(全量) 拆成 loadPhoneContacts(读列表)+importSelectedPhoneContacts(导选中)
    - 保留按手机号/姓名跨源自动合并去重
    - 「通讯录」池页的手机入口改为跳转多选页(onOpenPhonePicker)
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • - Person 加 realName/resume,档案页可编辑(PersonProfileScreen);DB 迁移 12→13
    - 通讯录池新增手机系统通讯录来源(READ_CONTACTS / ContactsContract,contactRef phone:<id>),
      按手机号/姓名跨源自动合并去重(PersonDao getByPhone/getByExactName/setPhone/updatePhoneInfo/updateProfile)
    - PhotologScreen/PhotologViewModel 支持两源池子
    - AndroidManifest 加 READ_CONTACTS 权限;同步 CLAUDE.md
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 录音 tab:
    - 录音中显示「⏱ 已录制 mm:ss」秒表(RecorderState 记 startedAt/accum,暂停冻结、继续累加)
    - 「最近转写」换成「录音记录」列表:按 audioPath 聚合录音块,每行显示起止/时长/转写状态/字数/人数/段数,点击跳时间轴定位该块
    
    声纹:
    - 短段不认声纹:assign/reclusterAll 加最短识别时长闸门(默认 3s,设置页 1–8s 可调),止住短段量产伪说话人
    - 新增 clearAllAndRecluster + 「声纹」tab「清空重识别」按钮:删全部声纹+清归属后从零重聚类
    
    录音分段:
    - BlockBuffer 静音切段间隔由编译期常量改为构造参数,设置页「分段间隔」1–15min 可调(下次服务启动生效)
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 删掉底部「纪要」菜单,把它的声纹/纪要两个子页并入「录音」。
    录音菜单顶部子 tab 从 2 个(录音/时间轴)扩到 4 个(录音/时间轴/声纹/纪要)。
    底部导航 6→5:人物/录音/对话/相册/设置。
    跨子页联动保留:声纹点人→时间轴按 TA 筛选;纪要点时间戳→跳时间轴对应段。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »

  • 某些块的音频会让 sherpa-onnx 在 native 层 SIGSEGV(实测重处理历史时一个 12.8s
    正常音频块触发,原因在 native 不可控),把整个进程(含 UI)带崩——表现为「一打开
    录音页就闪退」,且重启后 listPending 又排到同一毒块,死循环崩。
    
    native SIGSEGV 无法 try/catch,改用文件标记防御:处理前写 .attempt;若启动时标记
    仍在(= 上次崩在这块、没走到删目录),把该块移到 blocks_quarantine/ 跳过。一块最多
    崩一次即被隔离,其余正常处理,app 不再死循环。隔离块留存可后续排查。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 档案页声纹行加「🎤 录一段」:对手机说 ~6s → CAMPPlus 192d 声纹 →
    新建 SpeakerProfile 绑到 TA(原「绑定」改名「选已有」走旧的选择已有声纹)。
    关键:24/7 RecorderService 占麦,录前 pause 释放 AudioRecord、录后 resume,
    避免双 AudioRecord 抢麦。VoiceEnroll 状态机驱动对话框(录音倒计时/提取中/完成/错误)。
    绑定后自动 setManaged + touch。真机验证:pause→capture→embed(dim=192)→resume 全链路通。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 人物 tab 只显示 managed=true 的人;4357 个微信联系人退为「池子」。
    新增「微信通讯录」选人页:全部联系人 A–Z + 搜索 + 勾选 → setManaged。
    标人脸 / 绑声纹 / 手动建人自动置 managed=true。observeManaged 驱动列表。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 录音文件改造:BlockProcessor 不再把块切成逐句小 .opus,整块 speech 存成「一个
    完整录音」.opus;每个 turn 只记在块内的起始偏移(audioStartMs)+时长,共享块文件。
    省空间(不重复存),且真正有「完整录音文件」可回放。
    
    时间轴 UI:
    - 时间段块头加 ▶:playSequence 把该段涉及的各块完整录音依次播。
    - 每条 turn 加 ▶:seek 到块内偏移、只播该 turn 时长(SegmentPlayer 支持 startMs/durMs)。
    - 旧逐句段 audioStartMs=0、audioPath=自身文件,照常整段播放,兼容。
    
    Schema:Segment +audioStartMs(MIGRATION_10_11)。注:本提交的 Entities/AppDatabase
    同时含并行开发中的 persons.managed(MIGRATION_11_12,version 12)——两者在同一 schema
    文件内经 version 号耦合,无法拆分提交,故一并带上。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 档案页从一长条下拉改成:固定资料头 + 搜索框 + 顶部 TabRow 切换。
    - 固定头部:头像 + 名字 + 微信号/备注/手机号 + 声纹绑定(绑定/改绑)+ AI 印象
    - 搜索框:在当前 tab 的记录里实时过滤(caption/转写/聊天/朋友圈文本子串)
    - TabRow:照片 / 语音 / 聊天 / 朋友圈(各带数量),切到哪个就显示哪个列表
      - 照片:3 列网格,点开看大图
      - 语音:TA 说过的录音段,点击播放
      - 聊天:微信气泡;朋友圈:动态列表
    
    实测:火星人档案页头部固定,「照片1/语音54/聊天1/朋友圈10」tab 切换正常。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • - 「人物」从相册子页提升为**独立一级 tab,放第一位**(默认打开);PhotologTab 拆成
      ContactsTab(通讯录+档案) 与 AlbumTab(照片),共用同一 PhotologViewModel(Activity 域)
    - 通讯录排序:点过/绑过声纹的联系人 lastAccess 置顶到「★ 最近联系人」区,
      其余仍按拼音 A–Z(Person.lastAccess 字段 + 迁移 v9→v10;点开档案/绑声纹时 touch)
    
    注:本提交还顺带含时间轴「按 5min 静音切时间段分组」的并行改动(同文件耦合,已编译通过)。
    
    实测:默认进人物页(共 4357),点联系人后回列表,顶部出现「最近联系人」;迁移 v10 零数据损失。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »
  • 档案页扩成多源聚合(里程碑 2/4/5;3 短信因本机无数据暂缓)。
    
    - data:WechatMessage / Moment 两表 + persons.impression 字段 + 迁移 v6→v7→v9;
      对应 DAO observeByTalker / observeByUser / updateImpression
    - WeChatEnrollWorker 增 Pass1.5/1.6:导入 messages.json(聊天) + moments.json(朋友圈)
      (clear+重灌幂等,按 wxid 关联 Person.contactRef)
    - PersonProfileScreen:加「微信聊天」气泡 + 「朋友圈」列表两段
    - M5 AI 印象:PhotologViewModel.enrichImpression 汇总 TA 朋友圈 → 本地 4B(8080)
      生成一句话画像 + 标签(爱好/性格),存 persons.impression,档案页展示 + 按钮触发
    - server/services/wechat/extract-wechat-chat-moments.py:Mac 侧提取脚本
      (EnMicroMsg message 表解密 + SnsMicroMsg 明文 SnsInfo protobuf 文本近似提取)
    
    实测:真机导入聊天 40 条 + 朋友圈 78 条,按 wxid 关联到联系人(火星人 10 条朋友圈)。
    M3 短信:研究清楚(mmssms.db 明文 + contacts2 手机号源),但本机 SMS=0、通讯录=0
    (纯微信用户),无数据暂缓,机制在有数据设备上可直接复用。
    
    Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
    yibo authored
     
    Browse Dir »