Skip to content

feat(desktop): Memory Hub UI wiring, AI insights, background analysis (P3/P4 finishing) - #3808

Open
lengjingxu wants to merge 25 commits into
makecindy:mainfrom
lengjingxu:cindy/memory-hub-feedback
Open

feat(desktop): Memory Hub UI wiring, AI insights, background analysis (P3/P4 finishing)#3808
lengjingxu wants to merge 25 commits into
makecindy:mainfrom
lengjingxu:cindy/memory-hub-feedback

Conversation

@lengjingxu

@lengjingxu lengjingxu commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

这次改了什么

摘要

P2/P3/P4 后端能力合入后的接线与体验层收尾(含 review 修正):

  • 记忆 Hub UI:MemoryHubDialog 增加条目/洞察/回收站三个 tab;条目详情支持编辑(走 store 单写路径)、变更历史抽屉、确认删除(入回收站);回收站支持恢复;洞察 tab 展示统计 + 规则推荐卡片(废弃类「确认执行」先入回收站,可恢复)。
  • AI 洞察:接系统默认模型 one-shot(requestUtilityText),输入仅条目摘要 + 最近事件(非全量正文),结果缓存于 memory-hub-analysis-state.json;只读、永不注入 prompt;手动刷新与后台产出共用同一缓存。
  • 后台分析(P4):30 分钟 tick;delta 触发(shouldTriggerBackgroundAnalysis);每 scope 7 天频率上限;最近 10 分钟有记忆写入视为活跃跳过;设置开关(memory-hub-settings.json,默认开)落在 Memory 设置卡片。
  • review P1 修正
    1. softDelete 此前误调 storage.delete 实际永久删除 → 新增 storage.softDelete 用 rename 移入 .trash/,回收站真实可恢复(新增 trash.test.ts 6 个用例);
    2. restore 遇主目录同名条目 fail closed(already-exists),不再静默覆盖;
    3. 分析状态文件写入进进程内串行队列 + tmp+rename 原子落盘,手动/后台并发不再互相覆盖 lastAnalysisAt。
  • 修复:P2 preload 块误用 MAKER_INVOKE(preload 作用域不存在该名),改回 channel 字符串字面量;动态 i18n key 改为模板插值写法;设计台账重新生成。

变更类型

  • feat 新功能
  • fix 缺陷修复
  • refactor / perf 重构或性能优化
  • docs / test / chore 文档、测试或工程维护
  • 其他:

范围

UI 变化

  • 引用的设计规范:docs/design-rules/DESIGN.md §1(极简单色画布、交互元素 pill/8px 圆角)、§2(色彩只经 token:条目卡/输入框/按钮全部沿用 settings-theme-card-* / settings-input-bg / settings-section-* 语义 token,无新增硬编码色;仅沿既有 settings 面板先例保留 red-500 语义警示与 mark 高亮)、§4(列表卡片结构:标题/一行描述/元信息三层)、§10(双模式:全部颜色走 token,Light/Dark 自动适配);文案经 i18n/GLOSSARY 与 pnpm check:i18n-glossary 门禁(额度→配额修正 1 处)。
  • 界面效果预览(静态 HTML,结构与样式对齐实现;下方为 Light / Dark 双模式 Mock):
<!doctype html><html><head><meta charset="utf-8"><style>
body{font-family:Inter,-apple-system,sans-serif;margin:24px;background:#e9e9e6;display:flex;gap:24px}
.dialog{width:560px;border-radius:12px;overflow:hidden;border:1px solid var(--board);background:var(--card)}
.light{--surface:#f8f8f6;--card:#ffffff;--board:#d7d7d4;--title:#000;--desc:#6b6b68;--input:#f0f0ee}.dark{--surface:#1f1f1e;--card:#2c2c2a;--board:#3c3c3a;--title:#f2f2f0;--desc:#9a9a96;--input:#383836}
.hd{display:flex;justify-content:space-between;align-items:center;padding:14px 20px;border-bottom:1px solid var(--board)}.hd b{font-size:15px;color:var(--title)}.x{color:var(--desc);font-size:13px}
.scope{padding:12px 20px 0;font-size:12px;color:var(--desc);display:flex;gap:8px;align-items:center}.scope select{flex:1;border:1px solid var(--board);background:var(--input);color:var(--title);border-radius:8px;padding:5px 8px;font-size:12px}
.tabs{display:flex;gap:4px;padding:10px 20px 0;border-bottom:1px solid var(--board)}.tab{font-size:12px;padding:6px 12px;color:var(--desc)}.tab.on{color:var(--title);font-weight:600;border-bottom:2px solid var(--title)}
.body{padding:14px 20px 18px;display:flex;flex-direction:column;gap:8px}.card{border:1px solid var(--board);border-radius:8px;padding:10px 12px}.t{font-size:13px;font-weight:600;color:var(--title)}.d{font-size:12px;color:var(--desc);margin-top:2px}.m{font-size:11px;color:var(--desc);margin-top:6px}
.row{display:flex;justify-content:space-between;align-items:center;gap:8px}.btn{border:0;border-radius:8px;background:var(--input);color:var(--title);font-size:12px;padding:5px 10px}.danger{background:#ef4444;color:#fff}.primary{background:var(--title);color:var(--card)}
.stats{display:flex;gap:8px}.stat{flex:1;background:var(--input);border-radius:8px;padding:8px 10px}.stat b{font-size:16px;color:var(--title)}.stat span{display:block;font-size:10px;color:var(--desc);margin-top:2px}
.ai{border:1px solid var(--board);border-radius:8px;padding:10px 12px}.ai .hint{font-size:10px;color:var(--desc);margin:6px 0}.ai .text{font-size:12px;color:var(--title);line-height:1.5}
</style></head><body>
<div class="dialog light"><div class="hd"><b>记忆中心</b><span class="x"></span></div><div class="scope">记忆空间 <select><option>~/codepro/cindy (main)</option></select></div><div class="tabs"><div class="tab on">条目</div><div class="tab">洞察</div><div class="tab">回收站</div></div><div class="body"><div class="card"><div class="row"><span class="t">User role</span><span><span class="btn">编辑</span> <span class="btn">历史</span> <span class="btn">删除</span></span></div><div class="d">数据科学家,关注 observability</div><div class="m">project_user_role.md · 1.2 KB · 更新于 08-28</div></div><div class="card"><span class="t">确认删除?条目将移入回收站。</span><div class="row" style="margin-top:6px"><span class="d">可从回收站恢复</span><span><span class="btn danger">删除</span> <span class="btn">取消</span></span></div></div></div></div>
<div class="dialog dark"><div class="hd"><b>记忆中心</b><span class="x"></span></div><div class="scope">记忆空间 <select><option>~/codepro/cindy (main)</option></select></div><div class="tabs"><div class="tab">条目</div><div class="tab on">洞察</div><div class="tab">回收站</div></div><div class="body"><div class="stats"><div class="stat"><b>24</b><span>总条目</span></div><div class="stat"><b>3</b><span>长期未更新</span></div><div class="stat"><b>08-30</b><span>最近活动</span></div></div><div class="card"><div class="row"><span class="t">过期 · Old gateway note</span><span class="btn">确认执行</span></div><div class="d">90 天未更新,当前网关已切换,可废弃(入回收站可恢复)。</div></div><div class="ai"><div class="row"><span class="t">✦ AI 分析</span><span class="btn primary">重新分析</span></div><div class="hint">分析使用系统默认模型并消耗 API 配额;结果为 AI 生成,仅供查看,不会注入任务。</div><div class="text">用户是数据科学家,重心在 observability 与 agent 工具链;偏好简洁直接的中文回答;常在 mac 上并行多个 worktree。Gaps: 尚无「部署流程」相关记忆。</div><div class="m" style="font-size:10px;color:var(--desc);margin-top:6px">生成于 09-02 · 后台</div></div><div class="card"><div class="row"><span class="t">Trash · Old gateway note</span><span class="btn">恢复</span></div><div class="m" style="margin-top:2px">project_old_gateway.md · 删除于 09-01</div></div></div></div>
</body></html>

怎么验证的

自动验证

pnpm check:i18n-glossary → ✅ 无新增违规
pnpm --filter @cindy/maker-core run typecheck → ✅ exit 0
pnpm --filter desktop run typecheck → ✅ exit 0
pnpm vitest run src/memory(maker-core,含新增 trash.test.ts)→ ✅ 57/57 passed
pnpm vitest run src/renderer/__tests__/i18nCompleteness.test.ts(desktop)→ ✅ 2/2 passed

手工验证

  • 未做实机截图目检;已附上与实现同构的静态 HTML 预览(上一节)供确认结构/样式。颜色全部走语义 token,Light/Dark 理论自动适配。

未执行的验证

  • 实机截图/录屏:本机 desktop 全量单测与 Electron 运行受 Node 26 环境限制(已知问题,CI Node 22 为权威门禁),暂以 HTML 预览替代。
  • 本地 pnpm test:unit:related 存在与本改动无关的存量失败:pptxgenjs 模块解析(本机 pnpm store 缺文件)、pi-agent 集成测试(需真实 pi 二进制)、Node 26 localStorage 问题(此前已在干净 HEAD 验证同规模失败)。以 CI 为准。

风险

风险分类

  • 无已知风险
  • SQLite / migration
  • system prompt
  • 协议兼容
  • 权限 / 安全 / 用户数据
  • 存量插件兼容(批准状态 / 指纹 / manifest 校验 / 安装布局 / 包格式)
  • 原生层 / fingerprint / OTA
  • 跨平台差异
  • 其他:后台任务调用 LLM 消耗 API 配额

影响与回滚

  • 影响范围:
    • system prompt:零改动。Hub 全部读取走 store.list/getIndex 同源旁路;AI 洞察只进 UI 缓存,永不拼入 prompt / system 段;MEMORY.md「会话启动快照」语义不变。
    • 用户数据:条目编辑/删除全部走 store 单写路径并记事件日志;删除一律先入回收站(本 PR 修正了软删除实现),恢复有同名冲突保护;不触碰 agent 原生记忆与凭证存储。
    • 权限:新增 IPC 均在既有 MAKER_INVOKE 通道内、保持 assertTrustedAppRendererEvent 门禁;无新 entitlement、无外部网络新通道(AI 调用走既有 one-shot 路由与其停用守卫)。
    • 后台分析:默认开(产品裁决),成本由 delta 阈值 + 每 scope 7 天频率上限 + 空闲跳过兜底;设置开关一键关闭。
    • 跨平台:新增 fs.rename/mkdir/unlink 均为 Node 标准 API,Windows 无特殊路径分支;CI Windows shard 通过。
  • 回滚 / 降级方式:单一 revert 即可整体回滚;memory-hub-settings.json / memory-hub-analysis-state.json 均为新增派生文件,回滚后残留无害;记忆本体(.md 分片 + fts.db)无 migration,事件表/回收站为派生结构。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s,见 DCO)
  • UI 改动已在「UI 变化」注明引用的设计规范章节
  • 未提交凭证、令牌或授权文件
  • 已补充必要文档
  • 已确认测试结果或说明未执行原因

lengjingxu and others added 20 commits August 22, 2026 09:08
Signed-off-by: Leng <Lengjingxu@gmail.com>
fix(desktop): harden worker tabs and add collaboration docs
Signed-off-by: Leng <Lengjingxu@gmail.com>
…ation

docs(dev-rules): make collaboration playbook reusable
Signed-off-by: Leng <Lengjingxu@gmail.com>
…ce-kit

docs(templates): add copy-ready collaboration kit
…sections

Signed-off-by: Leng <Lengjingxu@gmail.com>
Signed-off-by: Leng <Lengjingxu@gmail.com>
docs(product-rules): propose Memory Hub viewing and management plan
docs(product-rules): incorporate upstream feedback into Memory Hub plan
Signed-off-by: Leng <Lengjingxu@gmail.com>
feat(desktop): add read-only Memory Hub (P1) with hub IPC and i18n
Signed-off-by: Leng <Lengjingxu@gmail.com>
fix(memory): scope hub listing to maker memory
…4 background trigger

Signed-off-by: Leng <Lengjingxu@gmail.com>
feat(memory): add P2 event log/trash, P3 recommendations/insights, P4 background trigger
- MemoryHubDialog: entries/insights/trash tabs with edit form, history
  drawer, delete-to-trash with confirmation, restore, rule-based
  recommendation cards with confirm-execute
- AI insights: one-shot analysis via system default model
  (requestUtilityText), cached per scope, read-only, never injected
  into prompts; manual trigger + background scheduler output share one
  cache path
- Background scheduler (P4): 30min tick, delta threshold on
  memory_events, 7d frequency cap, quiet-window skip on recent writes,
  settings toggle (default on) persisted in memory-hub-settings.json
- Fix P2 preload block to use channel string literals (MAKER_INVOKE is
  not in preload scope; surfaced once desktop typecheck could run)
- Add shared types, vite-env declarations, 5-locale i18n keys, and
  unit tests for prompt build/response parse

Signed-off-by: Leng <Lengjingxu@gmail.com>
@lengjingxu
lengjingxu requested a review from a team as a code owner September 2, 2026 10:36
…edback

Signed-off-by: Leng <Lengjingxu@gmail.com>

# Conflicts:
#	apps/desktop/src/main/maker-ipc/register.ts
@greptile-apps

greptile-apps Bot commented Sep 2, 2026

Copy link
Copy Markdown

Greptile Summary

此 PR 为桌面端 Memory Hub 接入条目管理、回收站、规则与 AI 洞察,并加入后台分析调度及相关 IPC、持久化和测试。

  • 新增 Memory Hub 三个 tab、条目编辑/历史/删除/恢复及推荐执行
  • 新增基于系统默认模型的手动与后台 AI 分析缓存
  • 扩展 maker-core 的记忆分析、事件、scope 与存储能力

Confidence Score: 2/5

该 PR 暂不适合合并,因为删除会永久丢失记忆、恢复可能覆盖同名条目,且并发分析会丢失其他 scope 的缓存状态。

回收站删除路径没有移动文件而是直接 unlink;恢复路径未处理同名冲突;手动与后台分析还会无锁覆盖共享状态文件中的并发更新。

Files Needing Attention: packages/maker-core/src/memory/store.ts、packages/maker-core/src/memory/storage.ts、apps/desktop/src/main/maker-host/memory-hub-analysis-scheduler.ts

Important Files Changed

Filename Overview
packages/maker-core/src/memory/store.ts 新增软删除与恢复 facade,但 softDelete 实际执行永久删除,导致回收站功能失效并造成数据丢失。
packages/maker-core/src/memory/storage.ts 新增回收站读取和恢复实现;恢复缺少同名目标冲突保护。
apps/desktop/src/main/maker-host/memory-hub-analysis-scheduler.ts 新增后台分析调度与按 scope 缓存,但手动和后台并发写入可能发生整文件 lost update。
apps/desktop/src/main/maker-host/memory-hub-ai-analysis.ts 新增摘要 prompt 构造、模型响应解析及 one-shot 分析调用,解析失败按 best-effort 处理。
apps/desktop/src/main/maker-ipc/register.ts 新增完整 Memory Hub IPC 接线,其中删除和分析缓存路径暴露了上述存储与并发缺陷。
apps/desktop/src/renderer/components/settings/MemoryHubDialog.tsx 新增条目、洞察、回收站交互,并通过 preload API 调用对应主进程能力。

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart LR
  UI[Memory Hub UI] --> IPC[Preload / Maker IPC]
  IPC --> Store[MakerMemoryStore]
  Store --> Files[Memory shards]
  Store --> Trash[.trash]
  Store --> FTS[FTS events and history]
  UI --> Manual[Manual AI refresh]
  Scheduler[Background scheduler] --> Analysis[AI analysis]
  Manual --> Analysis
  Analysis --> Model[Utility model]
  Analysis --> Cache[memory-hub-analysis-state.json]
  Cache --> UI
Loading
Prompt To Fix All With AI
### Issue 1
packages/maker-core/src/memory/store.ts:248-249
**软删除实际永久删除**

用户确认删除条目或执行废弃推荐时,`softDelete` 直接调用最终执行 `fs.unlink``storage.delete`,没有把文件移入 `.trash`,导致条目永久丢失且无法从回收站恢复。

### Issue 2
packages/maker-core/src/memory/storage.ts:461-464
**恢复静默覆盖同名条目**

当删除后又创建了同名记忆时,恢复操作直接将回收站文件 `rename` 到主目录且不检查目标是否存在;在允许替换目标的平台上,这会用旧版本静默覆盖新条目,在其他平台则会产生不同的失败语义。

### Issue 3
apps/desktop/src/main/maker-host/memory-hub-analysis-scheduler.ts:94-96
**并发分析丢失缓存状态**

如果用户手动刷新一个 scope 时后台分析正为另一个 scope 完成,两个调用会分别读取旧状态并整文件写回,后写入者将覆盖另一方的缓存及 `lastAnalysisAt`,导致洞察回退并可能绕过七天频率限制而重复调用模型。

---

For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.

Reviews (1): Last reviewed commit: "feat(desktop): wire Memory Hub UI, AI in..." | Re-trigger Greptile

Comment thread packages/maker-core/src/memory/store.ts Outdated
Comment thread packages/maker-core/src/memory/storage.ts
Comment thread apps/desktop/src/main/maker-host/memory-hub-analysis-scheduler.ts Outdated
…ness check

Signed-off-by: Leng <Lengjingxu@gmail.com>
@MagicLizi MagicLizi added touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:large-diff 改动量较大(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) labels Sep 2, 2026
@MagicLizi

Copy link
Copy Markdown
Contributor

这条 PR 正在等维护者确认,当前不会自动合并。

改动会让用户在设置里看到新的记忆中心(条目 / 洞察 / 回收站)、条目编辑删除,以及 AI 洞察和后台分析开关。另外还改了产品规则和协作文档。请维护者直接在 PR 上 Approve;如果要改,请 Request Changes。讨论 issue:#3813

另外:PR 描述还缺「风险」段,合入前需要补上。UI 改动也还没有界面效果证据(截图 / 录屏 / HTML 预览)。

@MagicLizi MagicLizi added the awaiting-discussion 等待维护者讨论(review-pr) label Sep 2, 2026

@MagicLizi MagicLizi left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR 描述缺「风险」段,格式门未过。

请按仓库 PR 模板补上「风险」:风险分类、影响范围与回滚方式。当前 Description 写了功能、范围和验证,但没有风险段,无法判断权限/用户数据/后台分析这些面的影响。

补全后重新请求 review 即可。

@MagicLizi

Copy link
Copy Markdown
Contributor

命中 UI 路径(apps/desktop/src/renderer/components/settings/MemoryHubDialog.tsx / apps/desktop/src/renderer/components/settings/MemorySection.tsx / apps/desktop/src/renderer/lib/memoryHub.ts)但 description 未附界面效果证据——建议补充改动后效果:截图/录屏,或改动后界面的 HTML 页面(```html 代码块、.html 附件或在线预览链接),便于确认界面符合 DESIGN.md 设计规范

@MagicLizi

Copy link
Copy Markdown
Contributor

@lengjingxu 👋 这个 PR 还有 3 条 review conversation 没 resolve(packages/maker-core/src/memory/store.ts / packages/maker-core/src/memory/storage.ts / apps/desktop/src/main/maker-host/memory-hub-analysis-scheduler.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

@MagicLizi MagicLizi added status:awaiting-author 等作者修改(review-pr 自动维护,仅展示) and removed awaiting-discussion 等待维护者讨论(review-pr) labels Sep 2, 2026
@MagicLizi

Copy link
Copy Markdown
Contributor

@lengjingxu 👋 这个 PR 目前与 main 有合并冲突,auto-review 因此暂时跳过、没法继续审查 / 合并。

请在本地 merge 最新的 origin/main 解决冲突后推送;冲突解除后,下一轮 auto-review 会自动重新处理这个 PR。

…edback

Signed-off-by: Leng <Lengjingxu@gmail.com>

# Conflicts:
#	docs/design-rules/design-inventory.md
Review P1 fixes from PR makecindy#3808:
- softDelete now renames the shard into .trash/ via new
  MemoryStorage.softDelete instead of unlinking through
  MemoryStorage.delete; trash listing/restore now operate on real data
  (regression-tested in memory/trash.test.ts)
- restore fails closed with already-exists when the same filename
  exists in the store, instead of silently overwriting the newer entry
- analysis state cache writes go through an in-process serial queue
  with tmp+rename atomicity so a manual refresh and a background tick
  can no longer clobber each other's lastAnalysisAt/cached entry

Signed-off-by: Leng <Lengjingxu@gmail.com>
@lengjingxu

Copy link
Copy Markdown
Contributor Author

已按反馈处理:

  1. CHANGES_REQUESTED(缺「风险」段):PR 描述已按模板补全「风险」段(风险分类:system prompt / 用户数据 / 跨平台 / 后台 LLM 配额;影响范围与回滚方式)。
  2. Greptile P1 ×3:均已修复并 resolve(softDelete 真正移入 .trash、restore 同名冲突 fail closed、分析状态写入串行化),新增 6 个回归用例。
  3. UI 效果证据:PR 描述已附与实现同构的 Light/Dark 静态 HTML 预览;实机截图受本机 Node 26 环境限制暂缺,已在「未执行的验证」如实标注。
  4. 合并冲突:已 merge 最新 upstream/main(设计台账按当前树重新生成),当前 MERGEABLE。

本地门禁:maker-core/desktop typecheck ✅、glossary ✅、memory 测试 57/57 ✅、i18nCompleteness ✅。

@MagicLizi MagicLizi added the awaiting-discussion 等待维护者讨论(review-pr) label Sep 2, 2026
@MagicLizi

Copy link
Copy Markdown
Contributor

@lengjingxu 👋 这个 PR 现在在等维护者确认,确认之前流程不会合并它 —— 不是卡住了,也不是在等你再改一版(你推的改动流程都读到了,判的就是最新一版代码)。

这条是流程自动发的状态提醒(同一版代码只发一次),不用回复。

@MagicLizi MagicLizi removed the status:awaiting-author 等作者修改(review-pr 自动维护,仅展示) label Sep 2, 2026
@MagicLizi

Copy link
Copy Markdown
Contributor

@lengjingxu 👋 这个 PR 目前与 main 有合并冲突,auto-review 因此暂时跳过、没法继续审查 / 合并。

请在本地 merge 最新的 origin/main 解决冲突后推送;冲突解除后,下一轮 auto-review 会自动重新处理这个 PR。

@MagicLizi
MagicLizi dismissed their stale review September 2, 2026 21:17

这些问题已在当前 head 的后续 commit 中修复(格式门/安全门已通过),自动 dismiss 旧的 CHANGES_REQUESTED 以解除合并阻塞。

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

Labels

awaiting-discussion 等待维护者讨论(review-pr) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:large-diff 改动量较大(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants