timeline-stop-hook.ts
Stop hook that closes skill timeline entries left open when a session ends. It always exits 0 so it cannot block a session.
- Kind
- Hook
- Works with
- Claude Code
- Languages
- TypeScript / JavaScript
- Source
- garrytan/gstack @ 01593aa67c94
- Path
- hosts/claude/hooks/timeline-stop-hook.ts
- License
- MIT
- Jobs
- Automation
InstallCopy it from the source repository, or sign in and let the assistant adapt it for your project.
#!/usr/bin/env bun
/**
* Stop hook: close dangling "started" timeline entries (#2553).
*
* The preamble writes {"skill":X,"event":"started",...} at every skill start;
* the completion write lives in prose at the END of the skill workflow and is
* unenforceable — an interrupted session, a context blowout, or an agent that
* simply stops leaves started > completed forever, and the leak is
* unrepairable after the fact. This hook runs on Claude Code's Stop event and
* appends event:"completed" (outcome "unknown", source "stop-hook") for every
* "started" entry in the project's timeline that has no matching "completed".
*
* FAIL-OPEN CONTRACT (F5) — a telemetry repair must never block a session:
* - ALWAYS exits 0, whatever happens (corrupt timeline, missing file, bad
* stdin, unreadable slug). Errors go to ~/.gstack/hook-errors.log,
* best-effort.
* - Internal time budget (~2s): work is bounded up front — the timeline is
* skipped entirely over a size cap, only the last TAIL_WINDOW_BYTES are
* read and parsed (P3: this hook runs on EVERY Stop event machine-wide,
* and a full read+parse scaled to the cap at ~100-300ms/turn), and the
…