@teeras/afterhours
v0.16.1
Published
See whether your coding agents give you time back: agent time, time back, quiet nights, your evening. One command; nothing leaves your machine. For Codex, Claude Code, Gemini CLI, Cursor.
Maintainers
Readme
Teeras Afterhours
See whether your coding agents give you time back. One command prints your week: agent time, the part that needed you, the stretches long enough to leave the desk, your quiet nights, and when your evening starts. Timestamps and counts only; prompts, code, output, projects, and paths never leave your machine.
npx @teeras/afterhours setupThirty seconds. No account for your first week.
Your agents work. Your time is yours.
When your agents can continue without you, choose what happens next:
- Play in Rush — Play a game. Find something fun.
- Reset in Teeras — Take a moment for movement, breathing, or recovery.
Setup prints both destinations. In Claude Code, ask "what can I do while you work?"
after setup installs the Teeras skill. For occasional invitations, enable
trs notes on; trs notes off turns them off. Invitations are optional, at
most once an hour, and depend on the existing activity thresholds. Neither
link promises a remaining wait or turns on a completion alert.
What you get
teeras · afterhours
agent time 34.8h of your week · 2.0× at once
with you 17.6h
time back 3.7h · 7 stretches over 20m · 11% of your agent time
quiet nights 5/7 · no check-ins after your finish-by time
your evening starts at 6:00 pm · you chose
34.8h agent time = 17.6h with you + 3.7h back, in stretches you could use + 13.6h in gaps too short to leave
Most time back on Wednesday, 1.5h. 5 of 7 nights were quiet after your finish-by time.Every number is a count of timestamps. "time back" and run lengths are estimates, and say so.
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. Nothing is sent
without a terminal.
What leaves your Mac
| Field | Leaves the machine | | --- | --- | | run started · run ended · agent kind | yes, once you connect an account | | check-ins per hour · hourly buckets | yes, once you connect an account | | prompt text · model output | never read | | source code · diffs · repository names · working directories · file paths | never read |
trs privacy prints the same boundary from the code that enforces it.
Then
Open the week large on teeras.com/app, or see it against last night's sleep in the iPhone app. Your finish-by time is one value on the Mac, the web, and the phone.
Commands
setup is the one command: it signs this Mac in, installs the agent hooks,
syncs once, and prints your week — agent time, the part that needed you, the
part that ran without you in stretches long enough to leave, and your quiet
nights. Without an account, npx @teeras/afterhours alone prints the same
week from local history. After that first local report, on a terminal, Teeras
asks once whether to count you as one anonymous user — a single ping with the
collector version, platform, and number of agent kinds found, and no identifier
of any kind. Agents running it for someone: nothing is sent without a terminal;
relay the printed count me line and run trs count-me only if your user says
yes. Install it once and the short commands are:
trs setup
trs
trs week
trs now
trs finish-by [HH:MM]
trs notes on|off|status
trs sync
trs report
trs sources
trs privacy
trs count-me [off|status]
trs off
trs logout
trs hook-config codex
trs hook-config claude
trs --help
trs --versionAlso available: trs connect and trs login sign in and sync once without
installing hooks; they close with the same summary setup prints.
Since 0.9.0, trs now prints today so far — time back with its share of agent
time, the last hour's tempo (check-ins, how fast you came back, re-prompts
under a minute), and what is running now — and trs now --json prints the
same object the MCP tool afterhours_now returns. Tempo is computed from the
hook journal's timestamps and agent ids alone. trs setup also adds a Claude
Code skill at ~/.claude/skills/teeras/SKILL.md (only where Claude Code is
present, never over a file that is not ours), so you can ask your agent "how is
my day going?" and hear the answer in the same words. Agent notes are off by
default: trs notes on lets the Claude Code hook hand your agent one line of
context at most once an hour, after ten check-ins in an hour with runs over
five minutes — how often you checked in, how long runs have run, nothing else.
trs finish-by [HH:MM] sets the time you chose to be done — one value on the Mac, the web, and the phone.
Afterhours 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.
While your agent works
Run trs in a terminal while an agent is running and it opens a small pane:
one good thing to do right now, picked from the clock and your day, with a key
to start it (space one more, s skip, q back). On a call with no start,
d marks it done and s skips to the next one; squats now start with u. Run it with nothing
running and it shows your day instead. The pick reads timestamps and counts
only. Durations in it are estimates and say so.
Your evening, for your agents
trs line shows when your evening starts, as your agents hear it. It is off
until you turn it on.
trs line # show it
trs line gentle # your agents get one note when your evening starts
trs line firm # gentle, plus one pause: send the message again to go ahead
trs line off # your agents hear nothing about it
trs line breaks 90 # a break note after 90 minutes without one (30-240)
trs line asks 40 # a pause note after 40 asks an hour (10-200)
trs line rules on # also write the time into your agents' instruction files
trs line rules off # remove it againSupported agents: Claude Code, Codex (CLI, desktop app, IDE), Gemini CLI, Cursor, VS Code Copilot, Windsurf, and, through the local MCP server, anything that speaks MCP. Claude Code and Codex hear it on every message; Gemini CLI too; Cursor and Copilot hear it when a session starts; Windsurf gets the pause only. Chat apps with no hooks (Claude app chat, ChatGPT) are not reached by this release; your phone still marks the time.
What the hook sends: your evening time and a few counts, as one short note, at most once per state. What it never reads: your message, your code, the agent's answer, paths, or repository names; the hook looks at the event name and nothing else. The firm pause is yours, not a lock. It happens at most once a day, and if anything goes wrong it lets the message through.
rules on writes a marked, removable block into the user-level AGENTS.md,
GEMINI.md, and CLAUDE.md in your home folders (never into a project, never
through a symlink), and rules off removes exactly that block. It is off by
default.
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.
