Skip to content

feat(penpal): persist recent files activity across restarts - #595

Merged
loganj merged 1 commit into
mainfrom
recent-files-persistence-acros
Apr 9, 2026
Merged

feat(penpal): persist recent files activity across restarts#595
loganj merged 1 commit into
mainfrom
recent-files-persistence-acros

Conversation

@loganj

@loganj loganj commented Apr 9, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • The activity tracker was purely in-memory — recent files were lost on every server restart. Now activity is persisted to ~/.config/penpal/activity.json.
  • Saves are debounced (5s after last change) to avoid disk thrash, with a final flush on shutdown after HTTP requests drain.
  • Persisted entries are pruned to the most recent 500 to bound file size.

🤖 Generated with Claude Code

The activity tracker was purely in-memory, so recent files were lost on
every server restart. Now activity is saved to ~/.config/penpal/activity.json
with debounced writes (5s) and a final flush on shutdown.

- Add Save/Load to activity.Tracker with atomic writes and pruning (500 max)
- Wire up load-on-start, debounced-save-on-change, save-on-shutdown in main.go
- Shutdown drains HTTP requests before saving so in-flight activity is captured
- Add 9 unit tests covering round-trip, corrupt JSON, pruning, nested paths, etc.
- Update PRODUCT.md, ERD.md, TESTING.md with E-PENPAL-ACTIVITY-PERSIST

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@loganj
loganj marked this pull request as ready for review April 9, 2026 15:59
@loganj
loganj merged commit c4614c6 into main Apr 9, 2026
5 checks passed
@loganj
loganj deleted the recent-files-persistence-acros branch April 9, 2026 15:59
loganj added a commit that referenced this pull request Apr 9, 2026
…ktree-dis

* origin/main: (45 commits)
  feat(penpal): persist recent files activity across restarts (#595)
  feat: persist open windows, tabs, and geometry across app restarts (#588)
  feat(staged): generate next prefill text when generating notes (#594)
  feat(staged): add "Run again" button to action output dialog (#593)
  feat: queue repo sessions in project MCP with async cancellation fix (#591)
  fix(staged): lowercase "building" subtitle for consistency (#592)
  fix(staged): use completedAt for commit prefill timeline ranking (#590)
  fix: add per-branch mutex to prevent worktree setup race condition (#589)
  feat: add diff commit session launcher (#585)
  fix: avoid error state for empty titled code reviews (#587)
  fix: cancel in-flight auto reviews before manual sessions (#584)
  feat(settings): add repo context search (#583)
  fix(staged): sort timeline items by completion time so queued items appear before completed ones (#568)
  fix: drain queued branch sessions from backend lifecycle (#579)
  fix: restore resume session metadata for resumed actions (#580)
  feat(staged): add purple diff comment theme (#578)
  fix(ui): hide branch actions during setup (#572)
  fix: validate parsed PR URLs before extraction (#577)
  fix: centralize staged relative time updates (#576)
  fix: avoid UI freezes when starting background sessions (#575)
  ...

# Conflicts:
#	apps/penpal/internal/watcher/watcher.go

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d4b702eb86

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".


for i := range entries {
e := &entries[i]
t.RecordAt(e.Type, e.Project, e.FilePath, e.Timestamp)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Reconcile loaded entries with newer filesystem activity

Loading persisted items with RecordAt means they occupy the project+path key before lazy scan seeding runs; since EnsureProjectScanned also seeds via RecordAt, files edited while the server was down keep the older persisted timestamp/type after restart. In practice, /api/recent can remain stale (wrong order and activity label) until each file is touched again in-session.

Useful? React with 👍 / 👎.

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.

1 participant