wip: ollama session summarization - #26
Draft
razvandimescu wants to merge 6 commits into
Draft
Conversation
Background goroutine watches for sessions becoming inactive and runs ollama to generate a 2-4 sentence summary of the transcript. Summaries persist to ~/.peekm/summaries.json and surface on the timeline. - summarize.go: summaryStore, monitor goroutine, ollama exec wrapper - timeline.go: AISummary field on timelineSession + populateAISummaries - timeline-partial.html: render summary below the session header - theme-overrides.css: .timeline-ai-summary styling - main.go: spawn the monitor on startup if ollama is in PATH - Makefile: embed git short SHA + build date via -ldflags Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Long-running Claude Code sessions can span days. Two related fixes make the timeline + summaries reflect what actually happened recently rather than blurring all of a session's history into one summary. Date range badge: - New DateRange method on timelineSession that renders "Mar 31 → Apr 7" for sessions whose activity spans more than one calendar day - Defined as a method (not field) so any code path that builds a timelineSession gets the correct value without remembering to populate - Uses plain calendar day instead of effectiveDate (the 5am work-day shift used for journal grouping) so a session ending at 3am shows its real calendar date - formatSessionDuration now emits "8d" / "8d 4h" instead of unreadable "192h" for multi-day sessions Time-windowed summarization: - Drop the offset-based incremental approach. Each summarization now reads the full transcript and filters to a 24h window, so summaries describe "what happened recently in this session" instead of slowly drifting across days of accumulated context - Stop chaining previousSummary into the prompt — the windowed input is the full input, no need for historical context that drifts - mtime gate (os.Stat ModTime vs existing GeneratedAt) skips the whole pipeline when the transcript hasn't been touched since last summary, before any file read or parse - Extract generateSummary helper used by both summarizeSession (monitor) and runSummarize (CLI), eliminating ~50 lines of mirrored pipeline logic. Sentinel errors (errNoRecentActivity, errSummaryUpToDate, errInsufficientInput) let each caller format its own user-facing output (log.Printf vs stderr) - Remove dead TranscriptLines field from sessionSummary (was used as the offset for incremental reads) Test fix: TestDayLabel was brittle to runs between midnight and the 5am day boundary. Re-anchor inputs to effectiveDate(time.Now()) so the test stays deterministic at any hour. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The govulncheck step started failing on PR #26 with five Go stdlib CVEs (GO-2026-4865, 4866, 4870, plus two more) all fixed in go1.26.2. PR #25 passed earlier on the same workflow because its CI run happened before the vuln database was updated with these entries. The workflow already pinned `go-version: stable`, but actions/setup-go hits the toolchain cache by version key — once "stable" was resolved to go1.26.1 and cached, subsequent runs kept hitting the cache without re-resolving "stable" against the upstream Go release manifest. Add `check-latest: true` so setup-go always queries the manifest fresh and pulls the actual current stable (which is now go1.26.2 with the CVE fixes). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Switch summarization prompts from prose to typed-bullet extraction (decision/gotcha/preference/entity/inflight/note). Daily prompt now deduplicates across sessions instead of re-summarizing. Model: qwen3.5:27b-q8_0 → qwen3.6:35b-a3b-q4_K_M Add scripts/ollama-prompt.py for quick model testing.
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.
Summary
Background goroutine watches for Claude Code sessions becoming inactive (no heartbeats for 5 minutes) and runs a local Ollama model to generate a 2-4 sentence summary of the transcript. Summaries persist to
~/.peekm/summaries.jsonand surface on the timeline view.summaryStorewith persistence, monitor goroutine watchingglobalHeartbeatsfor active→inactive transitions, ollama exec wrapper, transcript formatter, prompt builder, result parserAISummaryfield ontimelineSession+populateAISummariespass.timeline-ai-summarystylingollamais inPATH-ldflagsWhy draft
Known issues to address before merge:
tick(): ifrunning.CompareAndSwapfails (a previous summarization batch is still running),newlyInactivesessions are dropped fromprevActiveand never retriedqwen3.5:27b-q8_0) — needs flag/env override/no_thinkprompt prefix is Qwen-specific — couples to model choice or breaks if model changestime.Tick, leaks on exit)/simplifyreview not yet runTest plan
make allpassesollamainstalled andqwen3.5:27b-q8_0pulled: start a Claude Code session, let it idle 5+ minutes, verify summary appears in~/.peekm/summaries.json/timelineunder the sessionollamainPATH: verify peekm starts cleanly with no monitor goroutinesummaries.json)🤖 Generated with Claude Code