@teeras/afterhours
v0.5.1
Published
Private AI-life balance and usage analytics for Codex, Claude Code, Gemini CLI, Cursor, and other coding agents.
Maintainers
Readme
Teeras Afterhours
Private AI-life balance and usage analytics for Codex, Claude Code, Gemini CLI, Cursor, and other coding agents.
For AI agents
Installing this for your user? Run npx @teeras/afterhours setup, relay the
printed code and link to your user, and let the command finish. Full
instructions: llms-install.md. Counts only — prompts,
code, output, repo names, and paths never leave the machine.
npx @teeras/afterhoursThe first run reads supported agent activity locally and prints a seven-day view of agent activity, human attention, and after-hours check-ins without an account. Install it once and the short command is simply:
trs
trs week
trs connect
trs login
trs sync
trs report
trs sources
trs privacy
trs hook-config codex
trs hook-config claudeAfterhours parses the local session histories already written by supported coding agents and immediately reduces them to counts and hourly buckets. It never retains or returns prompt text, source code, model output, repository names, working directories, or file paths. Only the documented aggregate snapshot syncs after the user connects Teeras.
Since 0.5.0, when an agent turn starts and ends, the collector also sends a small real-time event: the agent name, its model family, the hour of day, an opaque run id, and an estimate of how many minutes you've been active today. When the turn ends it sends the same id and the time. This lets the Teeras iPhone app tell you how long runs like this usually take. It never includes prompts, code, file paths, or repository names, it is sent once with a two-second timeout, and it never blocks the agent.
Support matrix:
- Codex desktop app and Codex CLI: activity, token, model, and episode
measurement from the shared
~/.codex/sessionshistory. A distinctCODEX_HOMEis collected alongside the default App home. - Claude Code CLI: activity, token, model, and episode measurement from
~/.claude/projects, plus a distinctCLAUDE_CONFIG_DIRwhen configured. Subagent transcripts are excluded from primary episode counts rather than double-counted as human delegations. Claude Code Desktop keeps separate history, so its shared opt-in lifecycle hook is the trustworthy live path. - Gemini CLI: activity, token, model, and episode measurement from current
~/.gemini/tmp/*/chatshistories; olderlogs.jsonbuilds retain honest session-level fidelity. - Claude desktop: detected separately. General Claude chat and Cowork activity are not claimed as measured because those surfaces do not expose a stable, content-free local lifecycle feed. Claude Code remains a separate first-class source.
- Cursor detection, ready for a consented adapter once its local schema is stable
trs connect also detects Windsurf, VS Code + Copilot, Zed, Amp, OpenCode,
Goose, and Aider. Automatic sources connect from their existing local history;
the rest are reported honestly as requiring a source adapter. The exported
SourceAdapter contract lets any coding agent add counts-only support without
changing the Afterhours core.
Keep measuring across web and mobile
The first report stays on the computer. Run trs connect when you want to keep
your history in Teeras. Continue with Google, approve the counts-only boundary,
and the CLI receives a revocable 30-day device token. Google OAuth tokens never
enter the npm package.
Connecting syncs the first report immediately. After that, a counts-only
snapshot syncs as a side effect of your own agent activity: a lifecycle hook
event can trigger one detached, rate-limited sync (at most one every 45
minutes), so web and mobile stay current while you work. Every deliberate trs
run also refreshes the history. Use trs sync to sync without printing the
report, or trs logout to remove this computer's token. Nothing runs as a
background daemon, the hook itself makes no network call, and there is no
automatic LLM call.
trs report opens your web report in the browser, already signed in: this
computer's device token buys a single-use link that lasts sixty seconds, and
opening it is what signs the browser in. No password, no second sign-in. On a
computer that has never connected — or if the link cannot be fetched — it opens
the plain site instead and you sign in there as usual.
The default command (and trs week) prints a calm seven-day report. Use
--json to inspect the privacy-safe snapshot consumed by the dashboard and
optional MCP adapter. The cloud keeps one replaceable snapshot per device per
day in a 790-day active-history window; the dashboard lets users export or
delete that history.
Optional Codex and Claude Code lifecycle hooks
Afterhours can measure episode boundaries and permission requests more accurately from opt-in lifecycle hooks.
# install the fragments for the agents found on this computer
npx @teeras/afterhours setupRunning setup is the consent: it merges the Teeras fragment into the agents
it finds on this computer, leaves every other hook untouched, and is safe to
run again — a second run reports what is already connected instead of
duplicating it. The hook command it writes is an absolute path inside
~/.teeras/afterhours, so it keeps working after the npx directory is gone.
Remove the Teeras entries from the settings file to stop hook measurement, or
run trs off to do that for you — it clears the Teeras entries from both
agents' settings and deletes the local runtime, leaving every other hook and
your local journal and credentials untouched. If a settings file cannot be
read, trs off leaves both that file and the runtime alone and says so: the
entry it could not remove still points at the runtime, and deleting it would
leave your agent calling a command that is gone.
To review the configuration and merge it by hand instead:
# Codex CLI and Codex desktop app
trs hook-config codex
# Claude Code
trs hook-config claudeFor Codex, review the fragment and merge it into
$CODEX_HOME/hooks.json (normally ~/.codex/hooks.json), then review and trust
the hook in Codex. The user-level Codex configuration is shared by the desktop
app and CLI. For Claude Code, merge the fragment into
$CLAUDE_CONFIG_DIR/settings.json (normally ~/.claude/settings.json).
Claude Code Desktop and CLI share hooks even though they maintain separate
session histories.
The hook command reduces each event immediately to a timestamp, an opaque device-keyed session id, and one allowlisted lifecycle kind. The id is keyed with a stable per-device secret (never a rotating login token), so episodes stay consistent across logins. Prompt text, working directories, transcript paths, tool inputs, notification messages, and outputs are discarded before the local journal is written.
trs sources reports Codex and Claude Code hook status separately — event
count and last event time — so a misconfigured or logged-out hook is visible
instead of silently recording nothing. Passive local-history measurement
continues even if hooks are unavailable in an older client version.
Hooks improve measurement only. They do not currently trigger Walk Mode or claim that an autonomous runway prediction is valid. Teeras first asks participants to confirm episode boundaries and attention estimates in order to validate the measurement contract.
