Skip to content

Commit 97e0e68

Browse files
josealekhineclaude
andcommitted
feat: add start_time/end_time to session files for correlation
Add session boundary timestamps to enable correlating context entries to sessions by time overlap: - Manual saves (ctx session save): Include start_time and end_time in YYYY-MM-DD-HHMM format, using CTX_SESSION_START env var if available - Auto-saves (SessionEnd hook): Extract start_time from transcript's first entry timestamp, add end_time as current time These timestamps match the format used by ctx add, enabling agents to determine which session added a learning/decision/task by checking if its timestamp falls within the session's time bounds. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent 51f8190 commit 97e0e68

3 files changed

Lines changed: 34 additions & 3 deletions

File tree

.context/TASKS.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,8 +134,8 @@
134134
- [x] Add timestamp to formatTask() in add.go — currently tasks have no timestamp, add `#added:YYYY-MM-DD-HHMM` or similar
135135
- [x] Increase timestamp precision in formatLearning() — change from YYYY-MM-DD to YYYY-MM-DD-HHMM
136136
- [x] Increase timestamp precision in formatDecision() — change from YYYY-MM-DD to YYYY-MM-DD-HHMM
137-
- [ ] Add start_time field to session summary files — record when session began
138-
- [ ] Add last_update_time field to session summary files — update on each ctx add call during session
137+
- [x] Add start_time field to session summary files — record when session began
138+
- [-] Add last_update_time field to session summary files — skipped: end_time provides session bounds; tracking live updates requires state persistence
139139
- [ ] Document timestamp correlation approach in AGENT_PLAYBOOK.md — explain how to correlate entries to sessions by time overlap
140140

141141
### Phase 13: Rich Context Entries `#priority:medium` `#area:cli`

internal/claude/tpl/auto-save-session.sh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,24 @@ FILENAME="$SESSIONS_DIR/${TIMESTAMP}-session-${REASON}.jsonl"
3737
# Copy the transcript
3838
cp "$TRANSCRIPT_PATH" "$FILENAME"
3939

40+
# Extract session start time from transcript (first entry timestamp) if possible
41+
START_TIME=""
42+
if [ -f "$TRANSCRIPT_PATH" ]; then
43+
# Try to get timestamp from first line of transcript
44+
FIRST_TS=$(head -1 "$TRANSCRIPT_PATH" | jq -r '.timestamp // empty' 2>/dev/null)
45+
if [ -n "$FIRST_TS" ]; then
46+
# Convert to YYYY-MM-DD-HHMM format
47+
START_TIME=$(date -d "$FIRST_TS" +%Y-%m-%d-%H%M 2>/dev/null || echo "")
48+
fi
49+
fi
50+
51+
# Fall back to current time if we couldn't extract start time
52+
if [ -z "$START_TIME" ]; then
53+
START_TIME=$(date +%Y-%m-%d-%H%M)
54+
fi
55+
56+
END_TIME=$(date +%Y-%m-%d-%H%M)
57+
4058
# Also create a human-readable summary
4159
SUMMARY_FILE="$SESSIONS_DIR/${TIMESTAMP}-session-${REASON}-summary.md"
4260
cat > "$SUMMARY_FILE" << EOF
@@ -46,6 +64,8 @@ cat > "$SUMMARY_FILE" << EOF
4664
**Reason**: $REASON
4765
**Session ID**: $SESSION_ID
4866
**Transcript**: ${TIMESTAMP}-session-${REASON}.jsonl
67+
**start_time**: $START_TIME
68+
**end_time**: $END_TIME
4969
5070
This session was auto-saved by the SessionEnd hook.
5171
To analyze the full transcript, read the .jsonl file.

internal/cli/session.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -680,11 +680,22 @@ func sanitizeFilename(s string) string {
680680
func buildSessionContent(topic, sessionType string, timestamp time.Time) (string, error) {
681681
var sb strings.Builder
682682

683-
// Header
683+
// Header with timestamp fields for session correlation
684684
sb.WriteString(fmt.Sprintf("# Session: %s\n\n", topic))
685685
sb.WriteString(fmt.Sprintf("**Date**: %s\n", timestamp.Format("2006-01-02")))
686686
sb.WriteString(fmt.Sprintf("**Time**: %s\n", timestamp.Format("15:04:05")))
687687
sb.WriteString(fmt.Sprintf("**Type**: %s\n", sessionType))
688+
689+
// Session correlation timestamps (YYYY-MM-DD-HHMM format matches ctx add timestamps)
690+
// start_time: When session began (use CTX_SESSION_START env var if available, else save time)
691+
startTime := timestamp
692+
if envStart := os.Getenv("CTX_SESSION_START"); envStart != "" {
693+
if parsed, err := time.Parse("2006-01-02-1504", envStart); err == nil {
694+
startTime = parsed
695+
}
696+
}
697+
sb.WriteString(fmt.Sprintf("**start_time**: %s\n", startTime.Format("2006-01-02-1504")))
698+
sb.WriteString(fmt.Sprintf("**end_time**: %s\n", timestamp.Format("2006-01-02-1504")))
688699
sb.WriteString("\n---\n\n")
689700

690701
// Summary section (placeholder for the user to fill in)

0 commit comments

Comments
 (0)