Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Natural-language time tracking: parse what the user says they did into Activity/Minutes/Date rows in their own Notion database — asking instead of guessing when unsure.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-04 | ✗→✓ | ▲ Improved | 25% | 0% |
| case-11 | ✗→✓ | ▲ Improved | 130% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 150% | 0% |
| case-12 | ✗→✓ | ▲ Improved | 281% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 167% | 0% |
Conversational time tracking. The user reports time in plain language — "read papers 2h, gym 1h, did a leetcode" — and the agent parses it into structured rows (activity, minutes, date, an optional compounding tag) and writes them to the user's own Notion database through the official Notion connector. The core design is an honesty contract: anything uncertain becomes a To-confirm row and gets batch-asked — never fabricated. A log that quietly invents durations is worse than no log.
On the first write of a session, use Notion search to find the database (type database, not a page) whose title contains "time-ledger". Read its data_source_id (the collection://... UUID) and use it as the parent for create-pages / query for the rest of the session. If more than one matches, ask the user which to use. Nothing is pasted or configured.
The companion Notion template (free, linked in the source repo) ships this field schema — select values are a controlled enum, copy them exactly:
Entry (title) — the user's words or a clear titleActivity (select): Reading / Coding / Practice / Fitness / Investing / Meeting / Writing / Life / OtherMinutes (number)Date (date) — expand to "date:Date:start": "YYYY-MM-DD"; a bare Date value fails with HTTP 400Status (select): To-sort / To-confirm / DoneCompounding (select): Compounding / Consuming / NeutralNotes (text) — clue from the user's words / your questionParse the report → create-pages (parent = the data source id above). Set Status=Done for what is certain; for anything uncertain set Status=To-confirm, write the specific question in Notes, and ask it once in your reply.
Parsing rules:
When the user says "tidy up my time ledger": query rows where Status ∈ {To-sort, To-confirm} or empty → parse each → update-page the certain ones to Done; batch all remaining questions into one message; fill answers in when the user replies.
textUser: log it: read ML system design 2h, gym 1h, did a leetcode Agent: Logged 3 entries ✅ · Reading · ML system design · 120min · Compounding · Fitness · gym · 60min · Practice · LeetCode · ~20min ❓ To-confirm: you didn't say how long — I guessed 20min, right?
textUser: tidy up my time ledger Agent: 3 rows need confirmation — answering in one go works: 1. Tue "LeetCode" — how many minutes? 2. Wed "reading" — book or papers (Reading), or course exercises (Practice)? 3. "all afternoon on the deck" — Wed or Thu?
Date property; use the date:Date:start expansionTo-confirm and asks, rather than writing invented data into the user's records.Solution: Expand to "date:Date:start": "YYYY-MM-DD" — a bare Date value fails.
create-pages succeeds but the Date column is empty (known Notion MCP issue: notion-mcp-server#121 — expanded date fields silently dropped).Solution: After the session's first create, read the row back; if Date is empty, fill it with update-page.
Solution: Filter for type database when resolving "time-ledger".
Solution: Treat "today" as the user's local date; ask when it could go either way.
@trading-ledger - The same "parse plain language → own Notion DB → ask instead of guessing" pattern applied to trading journals (entry thesis, plan, emotion).Other measured skills in the registry, with their headline benchmark lift.