Coding time, session hours, and dev time
Editor plugin trackers count coding time, meaning minutes with a source file focused in an IDE that has a plugin installed. That definition made sense in 2019. It misses the terminal, the agent run, the pull request you reviewed in a browser tab, the Figma file, and the twenty minutes you spent reading someone else's code before touching anything.
Quick Answer
DevClocked records your development work passively across editors, terminals, browsers, AI coding agents and git, then organises it into three nested things: a session (a stretch of work), the work blocks inside it (one per workspace, each carrying its own project attribution), and the agent streams inside those (one per agent run). Install the tracker for each surface you actually work in, connect GitHub, name your projects once, and the rest is reading. The two numbers that matter most are session hours (the wall-clock-capped headline) and dev time (your hands-on share of it, with agent execution subtracted).
Below: the three time concepts people confuse, what each tracker records and what it cannot see, the session hierarchy, the app itself, reports, issue links, invoicing, and a first-week checklist.
DevClocked's headline number is session hours. It counts every tracked surface, then caps the day at the wall clock, so two devices running at once cannot bill you twice for the same minute. If you had a laptop and a desktop both ticking from 09:00 to 11:00, that is two hours, not four.
Dev time is the human slice of the same figure. For each work block it takes the block's hours and subtracts the interval union of agent execution inside it, floored at zero. On the Reports trend chart these are two lines on one axis: session hours on top, dev time underneath, with the human share in the tooltip. The dev time line can never rise above the session line, by construction.
That gap between the two lines is the interesting part. A day with eight session hours and three dev time hours means five hours where an agent was executing while you were reviewing, prompting, or waiting. The Execution vs Idle card on Reports labels that same cut "You reviewing & prompting", which is the honest description of what most agent-heavy days actually are.
Something that trips people up here. Agent hours and human hours are additive, so they can total more than the day. Four agents running in parallel for an hour produce four agent hours inside one wall-clock hour. Session hours stay capped at the wall clock because they describe elapsed time. Agent runtime is not capped because it describes effort, and hiding the parallelism would hide the output.
Sessions, work blocks, and agent streams
Everything in the product hangs off this hierarchy, and once it clicks the rest of the interface stops being surprising.
A session is a stretch of continuous work at the user level. There are three kinds. Tracked sessions come from a live tracker. Inferred sessions are reconstructed from GitHub commits when no tracker was running, which is how your history looks populated on day one; they have no tick-level signal, so their timing and classification are approximate and the product marks them as such. Manual sessions are ones you enter yourself.
A work block sits inside a session, one per workspace. Blocks are the billable atoms. Each one carries its own project link, repo, branch, line counts, and its own billing status, which is why one session spanning three repositories still invoices correctly against three projects. When you open a session sheet and see the same session broken into rows, those rows are work blocks.
An agent stream sits inside a work block, one per agent run. Streams carry the tool, the model, token counts, turn counts, and a work signature counting reads, writes, executions and planning turns. Subagents nest under their parent stream and are labelled with the spawning tool's own registry type, such as Explore or general-purpose, never with anything from your prompt.
When a session starts and when it stops
Idle is four separate questions in DevClocked, and only one of them ends anything.
| Tier | Question | Threshold | Ends a session |
|---|---|---|---|
| OS input idle | Has anyone touched this machine | 5 minutes | No |
| Surface activity idle | Has this tracker stopped seeing local activity | 15 minutes | Requests an end |
| Server auto-close | Is this session over | 20 minutes | Yes, sole authority |
| Agent store staleness | Is this agent transcript still live | 30 minutes | No |
Only the server decides. Twenty minutes of genuine silence closes the session, whether the tracker asked for it or not, and whether the tracker crashed or not. The five-minute floor at the OS level exists so that reading a diff without touching the keyboard still reads as present rather than absent.
The trade-off is real. Very deliberate think-time, the kind where you stare at a whiteboard for half an hour, will read as idle and split your session. That is the cost of not asking you to press a start button.
Each block also gets classified into one of six activity types, with a confidence score from 0.30 to 0.95 attached. Building covers file creation and source edits. Debugging picks up debug sessions, breakpoints, terminal errors and test files. Refactoring keys off refactor commands and balanced add/delete churn. Planning covers docs, AI tools, design tools and issue trackers. Config catches CI paths, dependency manifests and dotfiles. Review is read-heavy passes and PR URLs. A live debug session scores near the top of that confidence range; a default guess at a file edit scores near the bottom, and the score is shown on every block so you know which ones to distrust.
What each tracker actually records
Coverage decides whether your numbers are any good, and no single tracker sees everything.
| Tracker | What it records | Runs on |
|---|---|---|
| Mac app + daemon | Window activity, terminal time, Figma design time, and AI session files for Claude Code and Codex CLI | macOS |
| VS Code extension | Editor activity, file paths, language, line counts, git context. Also runs inside Cursor | macOS, Windows, Linux |
| Chrome extension | Time on allowlisted developer domains, origin and path only | Any Chrome |
| CLI tracker | Any terminal work, whatever you run inside it, with git repo detection | macOS, Windows, Linux |
| Hook plugins | Agent turns and tokens reported directly by Claude Code, Codex CLI and Cursor | macOS, Windows, Linux |
| MCP server | Query your own data from inside an agent, ships with the CLI | Anywhere the CLI runs |
| GitHub App | Commits, pull requests, branches, line counts | Server side |
One constraint governs everything else here. The daemon that reads agent session files ships only inside the Mac app. On Windows and Linux there is no daemon, so AI capture comes from the hook plugin for Claude Code, Codex or Cursor instead. Terminal and editor time still work everywhere through the CLI and the VS Code extension.
Where AI capture stands, tool by tool
There is a difference between time tracked and AI usage captured, and conflating them is how people end up disappointed.
Claude Code is fully captured. The Mac app daemon parses ~/.claude/projects, and the hook plugin reports turns on any OS. You get agent turns, tokens, and the AI-versus-human split.
Codex CLI is fully captured, the same two ways. The daemon parses ~/.codex/sessions; the Codex hook plugin covers other platforms.
Cursor is captured through the DevClocked VS Code extension installed inside Cursor, plus the Cursor hook plugin. Editor time and agent runs both land.
Gemini CLI tracks terminal time today but its agent turns are not read yet. There is no session-file parser for it, so tokens and turns will not appear.
Antigravity tracks editor time through the DevClocked extension on OpenVSX. Its AI usage is not captured yet.
Windsurf and GitHub Copilot have no AI capture path at all, on any OS, and none planned. Time in those editors is still tracked by the VS Code extension where it applies. The onboarding flow says this out loud if you pick one of them, rather than accepting the answer and quietly recording nothing.
Settings → Integrations lists every agent, what it needs, and whether DevClocked has ever seen that tool report work on your account. That last column is the one to check when something looks missing, because it distinguishes "not installed" from "installed and silent".
What leaves your machine, and what never does
If you are going to install four trackers, you should know what they can see. The short version is metadata only, and the mechanisms are specific enough to verify.
Never collected, in any tracker: keystrokes, screenshots, clipboard contents, your code, your prompts, or terminal output. The desktop app's only input-related system call asks macOS one question, how many seconds since the last keyboard or mouse event, which is what drives idle detection. No event tap or key monitor is compiled into the binary. Commit and edit parsing reduces to integers, since git diff HEAD --numstat runs locally and only the added and removed line counts leave. Agent transcripts pass through a whitelist scrubber of 19 named fields for Claude Code and 16 for Codex CLI, all of them timestamps, model names, token counts, line counts and tool names, so a field that is not on the list cannot leave because no code path reads it. Terminal output gets pattern-matched locally into a single "did that look like an error" boolean, and even that boolean stays on your machine.
What does leave: tick timestamps, session boundaries, idle state, your device name, project and repo and branch names, file paths, line counts, language, tool and model names, token counts, and the origin plus path of pages on allowlisted developer domains.
Two of those have sharp edges. The VS Code and Cursor trackers transmit the full path of the file you are editing, and the daemon and IDE plugins send your workspace folder path in plain text, which on macOS includes your username. And a tracked URL path can identify something private to your own dashboard, since github.com/acme/secret-project/pull/12 names the repo even though nothing about its contents is read. The browser allowlist is fixed at 91 developer domains at the time of writing, subdomains included, and everything else is invisible to the extension. It has no content scripts, so it cannot read page contents, and query strings and fragments are stripped before sending.
Two features are opt-in and ship off. Figma file-level tracking reads the focused window title of the Figma desktop app through the macOS Accessibility permission, and that title read is the only thing the permission is used for. Session name sync sends the AI-generated title of a coding session, which is a model-written summary derived from your prompt. Your raw prompt text is never read under any setting.
Raw activity is kept for your plan's retention window plus a seven-day grace buffer, which at the time of writing is 7 days on Free, 365 on Pro, and unlimited on Ultra and Team. A daily job deletes raw ticks and agent turn events past that. Git history, invoicing records, and the derived daily and hourly aggregates that power long-term charts are kept deliberately, which is why your trend chart survives even after the underlying ticks are gone.
Full field-by-field disclosure lives at what DevClocked collects.
Reading the app
The left rail is the whole product, in roughly the order you will use it.
Home is today. Live session, current block, what is running right now.
Sessions is the list view, and the session sheet behind each row is the single most useful screen in the product. It shows dev time, the work blocks inside the session, the agent streams inside those, token spend, the activity classification with its confidence, and the leverage figure with its inputs. When a number elsewhere looks wrong, this is where you find out why.
Calendar is the month view, good for spotting shape and bad for detail, and the day drawer behind each cell gives you the same session set with its projects, AI usage and activity breakdown.
Projects is where attribution gets fixed. Repositories map to projects automatically when the canonical repo name or a path match resolves cleanly; when it does not, you resolve the candidate here. Getting this right early is the most useful thirty minutes you will spend on the product, because everything downstream (reports, timesheets, invoices, team rollups) keys off project attribution.
Reports is covered below. Timesheets and Invoicing are covered after that. Workspace holds team membership, shared projects and sharing controls. Agent is a chat surface for asking about your own data in natural language.
Reports
Reports is the analytical surface and it is deliberately dense. The sections, in order:
Trend draws the two-line session and dev time chart at daily, weekly or monthly grain. Time split breaks the period down by the six activity classes. Activity history is the tick-level record. Agent performance and Agent efficiency cover the model side, including tokens per turn and a cache-hit ratio that proxies context resets; a run producing few lines per turn on a low cache-hit ratio gets flagged as churny, and one with high output per turn gets flagged as efficient. Model efficiency compares models against each other. Execution vs idle is the human-versus-agent cut described earlier. Coding hours heatmap, Peak flow windows, Weekly and Monthly trends, and File types round it out.
Two sub-pages sit under Reports. Commits ties git history back to the sessions that produced it. Issues does the same for Linear or Jira tickets, which needs the integration below.
The metric most people ask about is leverage. It compares the output an agent produced against the attention you spent getting it, on a 1 to 10 scale that is the same for everyone. When agent runtime telemetry is present for the session, it is measured and reflects a real agent-to-attention ratio. Without that telemetry it is estimated from work patterns and the session view flags it est., which means directional, not exact. Leverage always decomposes into its inputs instead of standing alone as a bare multiplier, and that is a deliberate design choice, not a UI preference.
Flow and focus are separate, both scored 0 to 100. Flow rewards consistent tick intervals and a focused file spread while penalising context switching. Focus rewards write activity and time in your top files. They are engagement signals, not verdicts.
Token cost is read from the model's own top-level usage counts, never summed across intermediate iterations, because summing iterations double-counts. Each usage row is priced against a version-pinned price book. When a model is not yet in the book its usage is flagged as unpriced instead of valued at zero, so a new model release shows up as a visible gap and not as a cost of nothing.
Wiring in Linear or Jira
Connect Linear from Settings → Integrations with a standard OAuth install. The connection is read-only and writeback is disabled, so DevClocked never comments on, moves, or edits your issues. Jira works the same way.
Linking is done by matching the issue identifier against three places: tracked branch names, commit branches and commit messages, and pull request head branches. A work block on eng-142-fix-login links to ENG-142, and the issue then shows against the session containing that block.
The limitation to plan around is that file names and file paths are not scanned. If the issue key appears only in a path, no automatic link is created, and you would need to attach the issue by hand from the session's issue picker. Branch naming discipline is what makes this integration good, and there is no way around that.
Timing: issues re-sync roughly hourly, and the linker runs every 30 minutes across the previous 14 days of tracked work. So a fresh issue can take up to half an hour to appear against work you have already done. Cross-team and cross-project matches are held as suggestions until you confirm them, which stops a shared prefix from claiming the wrong ticket. Commit and pull request evidence needs GitHub connected.
Billable projects, timesheets, invoices
The billing chain has three steps and it fails at the first one more often than anywhere else.
First, make the project billable. Open the project on the Projects page, toggle Billable Project on, assign a client, and optionally set a default hourly rate. Only sessions from billable projects with a client assigned reach your timesheets at all, so an empty timesheet is nearly always an unassigned client.
Second, review. Timesheets has three tabs: To Review, Ready, and Invoiced. Hit sync to pull recent tracked sessions into work items, then approve them individually or in bulk. Each item can be edited before approval, including the billable toggle, the client, the project, the category, the hourly rate, and a custom total if you are billing something fixed-fee. Work items inherit the project's client and rate, and you can override either per item.
Third, invoice. From Invoicing, create a new invoice, pick the client, set issue and due dates and a currency from USD, EUR, GBP or AUD, then use Add from Sessions to pull in approved work items. They aggregate by category with hours and rates carried through. Custom lines cover expenses and fixed fees. The right panel previews the invoice live as you edit. Save Draft leaves it editable; Create Invoice finalises it and marks the underlying work items as invoiced. Xero sync is available if you want the invoice to land in your accounting system rather than as a PDF.
Teams, and the line the product will not cross
Sharing on a team is per-member and starts at private for everyone. There are four levels: private, totals, summary, and enhanced. Private generates nothing at all, and the rollup job deletes any existing rows for a private member before it aggregates. Lowering your level re-redacts immediately, not at the next sync, and it applies retroactively.
What a teammate or a manager can see comes from pre-redacted daily rollup tables that a server-side job builds at each member's chosen level. Those tables have no URL, file path, commit message, prompt, or session-detail columns, so a team query cannot return what was never written into them. You always see all of your own data.
There is no ranked list of people anywhere in the team surfaces. Team views benchmark projects. The only leaderboard in the product is the public one you opt into from your own profile. If you are being asked to roll this out to a team, the measurement ethics page states plainly what the metrics are for (attribution, capacity planning, spend justification) and what they must never be used for (performance reviews, stack ranking, PIP cases, presence policing), and it is written to be shown to the people being measured, not only to the person buying.
Your first week
Day one, do the setup that everything else depends on. Connect GitHub through the GitHub App and select the repos you want tracked, which backfills your history as inferred sessions immediately. Install the tracker for each surface you actually work in, not all of them for completeness. Set your timezone in Settings, because every daily figure in the product is sliced at your local midnight and a wrong timezone will smear your days by a few hours.
Day two or three, once real data has landed, open Projects and fix attribution. Resolve any unmapped repositories, merge duplicates, and set the display names you want to see on invoices. Then open Settings → Integrations and check the "has reported work" column against every tracker you installed. A tracker that is installed and silent is the most common failure, and it looks identical to not having installed it.
End of the first week, open one session sheet and read it top to bottom. Check that dev time looks plausible against your memory of the day, that the work blocks landed on the right projects, and that the agent streams show the tools you actually ran. If something is off, the sheet tells you which layer it broke at, and correcting attribution now costs minutes where correcting it after a month of data costs an afternoon.
Then, if you bill for the work, make one project billable and run a single session through to a draft invoice. The chain has enough steps that you want to find the broken one before an actual invoice is due.
Related Guides
- What is agentic engineering intelligence: the measurement category this product sits in, and the five dimensions it covers.
- Why git commits do not equal actual work: the gap that sessions and work blocks exist to close.
- How to measure AI coding productivity: which of these numbers are worth acting on, and which are context only.
- Engineering team visibility without surveillance: the rollout argument for a team that has been burned by monitoring tools.
- Time tracking for invoicing: the billing chain in more depth, for freelance and agency work.