feat(sidebar): persisted project-level last-activity timestamp#160
Merged
Conversation
Projects now carry their own last-activity timestamp, bumped on session create and on real turns (session UpdatedAt moves), and never rolled back on delete. The sidebar sorts project groups by this timestamp (falling back to deriving from child sessions when absent) and shows a relative time in the project header — so deleting a conversation no longer changes its project's time or reorders the project list. Storage: a projects.json sidecar next to the session index (NOT an embedded key in session.json — an older binary rewriting the shared index would silently drop an embedded section on mixed-version installs; a sidecar it never touches is immune). All comparisons are on parsed RFC3339 instants, not strings: the data mixes server-local offsets with UTC, and lexicographic order breaks across offsets. - session: ProjectMeta + projects.json (atomic private writes under indexMu), monotonic-max touch on addToIndex / UpdateSessionMeta, untouched on DeleteSessionByUUID, ListProjectMeta accessor - web: GET /api/projects endpoint; task_status WS events now carry the project path + the exact server-side timestamp being persisted - web UI: projectTimes in the session slice (merge-on-load, live touch from task_status with the server's values), project header time + delete-stable ordering in the Sidebar - tests: lifecycle contract incl. mixed-offset monotonicity, legacy fallback, delete/title round-trip; GET /api/projects handler
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (12)
📝 WalkthroughWalkthroughProject activity timestamps are persisted in ChangesProject activity metadata
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant SessionEngine
participant WebSocket
participant WSBridge
participant SessionStore
participant Sidebar
SessionEngine->>WebSocket: task_status with project and updated_at
WebSocket->>WSBridge: forward task status metadata
WSBridge->>SessionStore: touchProjectTime(path, updatedAt)
SessionStore->>Sidebar: updated projectTimes
Sidebar->>Sidebar: reorder groups and render relative time
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
需求
给 conversation 的 project 加上 last update 时间;删除 conversation 时 project 的时间不变、排序不变。
实现
存储:在 session index 旁新增
projects.jsonsidecar 文件(project path → last-activity timestamp)。不嵌入session.json,是因为共享 index 可能被旧版本二进制重写而静默丢掉嵌入字段(桌面 sidecar + CLI 混版场景);sidecar 文件旧版本完全不碰,天然免疫。写入时机(均为单调 max,按解析后的 RFC3339 瞬时比较而非字符串——数据混有本地时区偏移与 UTC,字符串比较在跨时区时会出错):
addToIndex)→ 用会话 StartTime 触碰 project 时间UpdateSessionMeta中 UpdatedAt 变化,即一轮对话开始/结束)→ 同步触碰API:新增
GET /api/projects返回[{path, updated_at}]。前端:
projectTimes;启动时loadProjects拉取(与 tasks 并行),采用 per-key 单调 max 合并(避免覆盖 in-flight 的实时触碰)task_statusWS 事件现在携带 project 路径 + 服务端写入的精确时间戳,前端用服务端值实时触碰(不用浏览器时钟)验证
go test -race ./internal/session/ ./internal/web/通过;新增生命周期契约测试(含混合时区单调性、legacy 回退、删除/改名 round-trip)与GET /api/projectshandler 测试golangci-lint0 issues;make lint-web通过projects.json时间戳不变,侧栏该 project 仍显示原相对时间且排序不变(子会话只剩 10d 旧任务时,project 头仍显示 19h 并保持置顶)对抗评审
已经过一轮对抗评审(adversarial review),修复了:
setProjectTimes全量替换可能覆盖实时触碰(改为单调 max 合并)Summary by CodeRabbit
New Features
Bug Fixes