
claude-mem 分支記憶可視化在 Viewer 觀察卡片中展示 Git 分支與 Commit SHA【免費(fèi)下載鏈接】claude-memPersistent Context Across Sessions for Every Agent – Captures everything your agent does during sessions, compresses it with AI, and injects relevant context back into future sessions. Works with Claude Code, OpenClaw, Codex, Gemini, Hermes, Copilot, OpenCode More項(xiàng)目地址: https://gitcode.com/GitHub_Trending/cl/claude-mem本文基于 claude-mem 的分支記憶branch-memory特性開發(fā) playbook 中BRANCH-PARITY-02-Viewer-Branch-Display.md階段文檔展開講解如何把數(shù)據(jù)庫中已存儲的branch與commit_sha觀察元數(shù)據(jù)打通類型定義 → 分頁查詢 → React 卡片渲染三層鏈路最終在http://localhost:37777的 Viewer UI 中以分支徽章的形式呈現(xiàn)。讀完本文你將掌握 claude-mem Viewer 的數(shù)據(jù)流全貌、觀察卡片組件的渲染機(jī)制以及單文件 Viewer 的構(gòu)建與驗(yàn)證流程。1. 背景數(shù)據(jù)庫有分支信息Viewer 卻沒有claude-mem 的核心工作流是記錄 Agent 會話中的操作 → 用 AI 壓縮為觀察Observation → 在未來會話中重新注入相關(guān)上下文。分支記憶特性進(jìn)一步要求記憶與 Git 分支邊界對齊——同一條觀察應(yīng)當(dāng)能被追溯它是在哪個(gè)分支、哪個(gè)提交上產(chǎn)生的。按 playbook 的原始描述此時(shí)系統(tǒng)的狀態(tài)是數(shù)據(jù)庫已經(jīng)在每條觀察上存儲了branch與commit_sha由 migrations 24-25 引入的列但 React Viewer 中展示觀察卡片時(shí)只有類型、項(xiàng)目、標(biāo)題、副標(biāo)題、事實(shí)、敘事和元數(shù)據(jù)沒有分支信息原因很具體為 Viewer 供數(shù)的PaginationHelper查詢有意省略了這兩個(gè)列導(dǎo)致數(shù)據(jù)雖然入庫卻斷供于界面。因此這一階段的目標(biāo)非常聚焦給觀察卡片加上分支可見性讓用戶一眼看出每條觀察來自哪個(gè) git 分支從而補(bǔ)全分支記憶的視覺層。從源碼結(jié)構(gòu)看當(dāng)前倉庫快照中 PaginationHelper 的 SELECT 列表確實(shí)不含branch/commit_shaViewer 類型定義 的Observation接口也尚未包含這兩個(gè)字段——這與 playbook 描述的基線狀態(tài)一致該特性在 branch-memory 工作分支上開發(fā)playbook 中標(biāo)記了各任務(wù)的完成狀態(tài)。2. 類型層給 Observation 接口加上可選的分支字段第一處改動(dòng)發(fā)生在 Viewer 的 TypeScript 類型系統(tǒng) src/ui/viewer/types.ts。當(dāng)前Observation接口為export interface Observation { id: number; memory_session_id: string; project: string; merged_into_project?: string | null; platform_source: string; type: string; title: string | null; subtitle: string | null; narrative: string | null; text: string | null; facts: string | null; concepts: string | null; files_read: string | null; files_modified: string | null; prompt_number: number | null; created_at: string; created_at_epoch: number; }需要追加兩個(gè)可選且可為 null的字段branch?: string | null; commit_sha?: string | null;關(guān)鍵設(shè)計(jì)決策是可選性branch?: string | null而非必填。因?yàn)榇嬖诖罅吭缬诜种в洃浱匦缘臍v史觀察它們的branch值為NULL——若聲明為必填字段舊數(shù)據(jù)會被類型系統(tǒng)誤判為非法。這一約定同時(shí)體現(xiàn)在 Viewer 側(cè)接口和 Worker 側(cè)接口 src/services/worker-types.tsPaginationHelper從后者導(dǎo)入Observation類型playbook 在任務(wù)完成備注中特別指出由于查詢結(jié)果是泛型透傳paginateObservation()類型更新后其余部分自動(dòng)生效無需改動(dòng)映射邏輯。3. 查詢層PaginationHelper.getObservations() 補(bǔ)列數(shù)據(jù)供給的斷點(diǎn)在 src/services/worker/PaginationHelper.ts 的getObservations()方法。當(dāng)前實(shí)現(xiàn)對observations表執(zhí)行硬編碼列列表的 SELECT并按created_at_epoch DESC排序let query SELECT o.id, o.memory_session_id, o.project, o.merged_into_project, COALESCE(s.platform_source, claude) as platform_source, o.type, o.title, o.subtitle, o.narrative, o.text, o.facts, o.concepts, o.files_read, o.files_modified, o.prompt_number, o.created_at, o.created_at_epoch FROM observations o LEFT JOIN sdk_sessions s ON o.memory_session_id s.memory_session_id ;改動(dòng)只有一處在列列表末尾追加o.branch, o.commit_sha。由于結(jié)果集通過db.prepare(query).all(...)取出后直接斷言為Observation[]列補(bǔ)上之后新字段會自動(dòng)出現(xiàn)在返回對象里配合第 2 節(jié)的類型更新即完成整條鏈路。理解這段查詢的幾個(gè)配套細(xì)節(jié)有助于把握改動(dòng)邊界分頁的 hasMore 探測params.push(limit 1, offset)——每次多取一行若返回行數(shù)超過limit則判定hasMore: true隨后slice(0, limit)截?cái)唷_@是無COUNT(*)的輕量分頁模式新增列不影響該邏輯。項(xiàng)目過濾指定project時(shí)匹配o.project ? OR o.merged_into_project ?支持已合并項(xiàng)目的歸屬追溯未指定時(shí)排除OBSERVER_SESSIONS_PROJECT觀察者自身會話來自 src/shared/paths.ts 的常量。返回前的清洗sanitizeObservation()會用stripProjectPaths()把files_read/files_modified中的絕對路徑剝離為相對路徑保證卡片不泄露本機(jī)目錄結(jié)構(gòu)。分支字段不經(jīng)過任何清洗原樣透傳。4. 渲染層ObservationCard 中的分支徽章展示邏輯落在 src/ui/viewer/components/ObservationCard.tsx。當(dāng)前卡片的頭部結(jié)構(gòu)card-header-left容器內(nèi)依次渲染四枚徽章div classNamecard-header-left span className{card-type type-${observation.type}}{observation.type}/span span className{card-source source-${observation.platform_source || claude}} {observation.platform_source || claude} /span span classNamecard-project{observation.project}/span {observation.merged_into_project ( span classNamecard-merged-badge title{Merged into ${observation.merged_into_project}} merged → {observation.merged_into_project} /span )} /divplaybook 對該卡片的具體改造規(guī)格如下逐條對應(yīng)現(xiàn)有代碼模式位置分支徽章放在card-header-left內(nèi)、現(xiàn)有card-project徽章旁對應(yīng)上面代碼中約第 51 行附近。條件渲染僅在observation.branch為 truthy 時(shí)渲染——遷移前的觀察該字段為null徽章必須靜默缺省不能占位。這與card-merged-badge的條件渲染寫法{observation.merged_into_project ...}完全同構(gòu)可直接參照。圖標(biāo)與文本一個(gè)簡化的 git 分支分叉 SVG 圖標(biāo)fork 造型加分支名整體樣式仿照現(xiàn)有card-project的 span 寫法。Commit SHA 縮寫可選增強(qiáng)在分支名旁/下方展示commit_sha前 7 個(gè)字符commit_sha.slice(0, 7)使用等寬字體。配色區(qū)分徽章顏色需與項(xiàng)目徽章可區(qū)分——playbook 建議使用var(--color-text-muted)文字搭配柔和背景。配套的.card-branch新 CSS 類規(guī)格寫入 Viewer 樣式模板 src/ui/viewer-template.html屬性取值依據(jù)字號~11px與.card-project徽章一致背景var(--color-surface-hover)一類柔和表面色playbook 建議值圓角與現(xiàn)有徽章一致模板中徽章圓角為 3px參照 viewer-template.html 中.card-merged-badge的border-radius: 3pxSHA 部分等寬字體保證十六進(jìn)制串等寬對齊作為參照現(xiàn)有徽章體系在模板中的定義是.card-project僅設(shè)color: var(--color-text-muted).card-merged-badge則是 9px 小字號、background: var(--color-type-badge-bg)、1px 邊框、opacity: 0.85的弱化樣式。分支徽章介于兩者之間——比 merged 徽章醒目、比 type 徽章克制——符合次要元數(shù)據(jù)的視覺層級。5. 構(gòu)建與驗(yàn)證單文件 Viewer 的產(chǎn)出鏈路Viewer 不是獨(dú)立部署的 Web 應(yīng)用而是構(gòu)建為單文件 HTML內(nèi)嵌 CSS/JS源樣式模板src/ui/viewer-template.html含--color-text-muted等主題 CSS 變量多套主題下各有取值構(gòu)建產(chǎn)物plugin/ui/viewer.html——Worker 服務(wù)啟動(dòng)后由http://localhost:37777直接提供。驗(yàn)證流程playbook 的任務(wù)清單在 package.json 中確認(rèn)構(gòu)建腳本生產(chǎn)構(gòu)建入口為npm run build-and-sync其展開為npm run build npm run sync-marketplace node scripts/restart-marketplace-worker.cjs類型檢查有獨(dú)立腳本typecheck:viewer即tsc --noEmit -p src/ui/viewer/tsconfig.json可在完整構(gòu)建前單獨(dú)快速校驗(yàn) Viewer 側(cè)改動(dòng)本例中類型層與組件層改動(dòng)都在這里被覆蓋運(yùn)行npm test確認(rèn)無回歸檢查構(gòu)建產(chǎn)物plugin/ui/viewer.html中是否出現(xiàn)新的.card-branch樣式與渲染分支。6. 放到分支記憶全景中看本 playbook 是 Branch-Parity 階段的第 02 部分同目錄下還有BRANCH-PARITY-01-Chroma-Branch-Sync.md讓向量檢索層ChromaDB感知分支邊界——在StoredObservation/StoredSummary/ChromaMetadata三處接口加字段、在formatObservationDocs()中把分支元數(shù)據(jù)寫進(jìn) Chroma 文檔、在buildWhereFilter()中用{ commit_sha: { $in: commitShas } }加$or兼容無 commit_sha 的舊文檔實(shí)現(xiàn)分支感知過濾BRANCH-PARITY-03-MCP-Output-And-Verification.mdMCP 輸出層的收尾與整體驗(yàn)證。三個(gè)階段共同指向同一架構(gòu)思路分支元數(shù)據(jù)在 SQLite 中一次性落庫migrations 24-25 給observations加列Phase 01 還補(bǔ)了session_summaries的同名列此后每一層消費(fèi)方——分頁查詢、Chroma 同步、MCP 工具輸出——都只是把已有列透傳出去。Viewer 展示本文主題是這條透傳鏈路的最后一環(huán)讓分支記憶從數(shù)據(jù)可查變成用戶可見。7. 小結(jié)改動(dòng)極小、鏈路極清晰可選字段進(jìn)兩個(gè)Observation接口types.ts 與 worker-types.tsSELECT 補(bǔ)兩列PaginationHelper.ts卡片條件渲染一枚徽章ObservationCard.tsx即可讓分支元數(shù)據(jù)從數(shù)據(jù)庫直達(dá)界面向后兼容是硬性約束branch?: string | null的可選聲明與truthy 才渲染徽章的組合保證遷移前的舊觀察在類型系統(tǒng)與 UI 上都自然降級為無分支不產(chǎn)生占位或報(bào)錯(cuò)驗(yàn)證閉環(huán)完整typecheck:viewer→npm test→npm run build-and-sync產(chǎn)出 plugin/ui/viewer.html構(gòu)建產(chǎn)物可人工核驗(yàn)新徽章的渲染結(jié)果?!久赓M(fèi)下載鏈接】claude-memPersistent Context Across Sessions for Every Agent – Captures everything your agent does during sessions, compresses it with AI, and injects relevant context back into future sessions. Works with Claude Code, OpenClaw, Codex, Gemini, Hermes, Copilot, OpenCode More項(xiàng)目地址: https://gitcode.com/GitHub_Trending/cl/claude-mem創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考