Skip to content

tooling: persistent session marker for accurate /end-session reporting#143

Open
petterlindstrom79 wants to merge 1 commit into
mainfrom
tooling/session-state-marker
Open

tooling: persistent session marker for accurate /end-session reporting#143
petterlindstrom79 wants to merge 1 commit into
mainfrom
tooling/session-state-marker

Conversation

@petterlindstrom79
Copy link
Copy Markdown
Member

Summary

  • Ports the tilja session-state pattern. Replaces session-close-check.ts's fixed now - 6h window with a real session-start timestamp read from .claude/state/session-state.json.
  • /end-session now archives the marker and surfaces real duration, starting commit, and ending commit in the final report — fixing the long-session-truncation / short-session-noise problem in today's report.
  • Graceful fallback: when the marker is missing (no SessionStart hook, ad-hoc invocation) the close-check uses the previous 6h behaviour. SESSION_WINDOW_HOURS=N env override still wins.

Files touched

  • scripts/session-state.mjs (new)ensure / end / read CLI. Marker at .claude/state/session-state.json, archive at .claude/state/session-archive/. Both paths already covered by the .claude/state/ gitignore entry. 12h stale-rotation matches tilja.
  • apps/api/scripts/session-close-check.ts — reads marker, falls back to window, logs [source: marker | env override | fallback] so the report is honest about which boundary it used.
  • .claude/commands/end-session.md — step 7 calls node scripts/session-state.mjs end and adds duration + commit-range lines to the report block.

Required follow-up (per-machine, not shippable)

.claude/settings.json is gitignored, so the SessionStart hook can't go in the repo. Paste this into your local .claude/settings.local.json so the marker is created at true session start (without it, the marker is created lazily when /end-session runs and duration shows "unknown"):

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "*",
        "hooks": [
          { "type": "command", "command": "node scripts/session-state.mjs ensure" }
        ]
      }
    ]
  }
}

Test plan

  • node scripts/session-state.mjs ensure → creates marker, second call returns existing (idempotent).
  • node scripts/session-state.mjs end "test" → emits JSON with duration_ms, starting_commit, ending_commit, archive path; removes the live marker.
  • npx tsc --project apps/api/tsconfig.json --noEmit → clean.
  • npx tsx apps/api/scripts/session-close-check.ts with marker present → header reads [source: marker (ISO)].
  • Manual: install the hook snippet, start a fresh CC session, run /end-session, confirm duration block populates.
  • Manual: remove the marker, run the close-check, confirm header shows [source: fallback (last 6h — no marker found)] and behaviour matches today.

Notes

  • Parallel CC instances on the same repo would share one marker. Solo-founder usage means this is rarely a problem; if it bites, scope the marker per-worktree (the script already resolves REPO_ROOT from its own location, so worktree-scoped install drops in without changes).
  • The archive trail in .claude/state/session-archive/ is local-only (gitignored) — useful for retrospectives, not a governance artifact.

🤖 Generated with Claude Code

Ports the session-state pattern from tilja. Replaces the fixed "now - 6h"
window in session-close-check with a real session-start timestamp written
to .claude/state/session-state.json at session start, captured on
/end-session as duration + starting/ending commit.

Files:
- scripts/session-state.mjs (new): ensure/end/read CLI. Marker + archive
  live under .claude/state/ (already gitignored). 12h stale-rotation.
- apps/api/scripts/session-close-check.ts: reads marker if present,
  falls back to the existing SESSION_WINDOW_HOURS (default 6h) when
  missing or unparseable. Env override still wins.
- .claude/commands/end-session.md: step 7 now archives the marker and
  surfaces real duration + starting/ending commits in the report block.

SessionStart hook is not shipped here (settings.json is gitignored).
PR description has the snippet to paste into .claude/settings.local.json.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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