I wanted to see my to-dos
Personal agents can handle a bunch of things for you. But I struggle to understand what’s going on, and where things are, unless I can see it.
So I wanted a to-do list that’s mine and my agents’. One view where I work through everything with my agent, or let it handle the things I add.
And I wanted it simple. Built on one plain file, and working in the browser, on my phone, anywhere.
This is it, working, with made-up data. Tick something, open something, press ? for the keys.
Where it started
I did a massive voice-note dump to bites, my chief of staff agent. I wanted everything reorganised. I wanted to tidy up my folders, and work from one folder on my computer, so I can see the files, what’s happening, and all the jobs and areas I’m working on.
Somewhere in the middle of it, I asked for somewhere to see all my to-dos:
bites spent the morning tidying the folder with me. Then it suggested a to-do board first, and I said yes.
Five minutes later
The first version was running on my Mac.
When an agent builds a website, it’s on localhost.
All my to-dos live in one file, todos.md. Tick a box on the page and that line in the file changes: - [ ] becomes - [x]. Change the file, and the page shows it a few seconds later. The page keeps nothing of its own.
## Now - [ ] Draft issue 42: the open-weights section, three links to check ## Next - [ ] Build the sponsor slot for issue 43: Hollowpoint, one-minute read, two links - [ ] Fund II LP list: waiting on Ruth Abara for the intro names (since 9 Oct) - [ ] Renew the registered agent for the fund entity - [x] Send issue 41 to the list: scheduled for 7:00 on Tuesday
On my phone
But it was only on my Mac. I wanted it on a real website I can open every day.
here.now put it online, and I locked it so only my email can open it. Anyone else gets a 401.
Then I realised I want my agent to open it too. And my agent has its own email address. Grok Bot lets you set one, or your agent can get one from something like AgentMail. So we added it as an approved email:
Now only me and my agent can open it.
Email is an underrated way to chat to your agent. Everything stays organised in threads. It’s also a great way for agents to talk to each other, which comes up again later.
There was one more problem. The site was a snapshot, so I couldn’t tick anything on it. A tick on the site needs somewhere to be saved.
here.now has a small database built in, called Site Data. That’s where the to-dos live on the site, and where my ticks get saved. The email list is a separate setting, and it covers Site Data too, so the to-dos are as private as the page.
Normally you’d need two things for this: a database, and authentication. That’s a server, logins and passwords to look after. here.now does both.
bites put up a throwaway test site with one to-do on it. I ticked it from my phone, and bites could read my tick back. So it built the real one.
Every 10 minutes
The list still lives in one file on my Mac. So bites wrote a script. Every 10 minutes, while my Mac is on, it checks for anything new: my ticks, new to-dos, changes. Then it makes sure the site and the file match. If we both changed the same line, the file wins.
When my Mac is off, the site still works. My ticks wait on the site. The bots can’t change the file, because it’s on my Mac. When the Mac wakes up, the next sync pulls everything in.
Where everything is
Next I wanted to see two more things.
The Map tab shows the areas of my life where there’s work to do, or where things are likely to fit. Each card says what it is, where it lives, who looks after it, and how many to-dos are open. It all comes from one file, map.md.
Then the thing that worries me about agents:
So now every agent adds one line to a work log whenever it makes something that matters: a file, a site, an email draft. It’s for when we need to go back and work out who did what, where, and when. It’s not really for me to read. It’s for my agents, and they can break it down for me when I ask.
Then “in progress” became its own state. That was two and a half hours after I said yes. bites built all of it.
Three versions first
Next I wanted a proper redesign. For that I went to my coding agents instead of my personal agent. I use Pi with Opus 5.5.
/emil-prototype is a skill. This one says: build a few genuinely different versions, put them behind a picker, and let me choose. I always understand things better when I can see them.
It built three: Sidebar, Focus and Spaces. Flick between them at the top.
I didn’t love any of them, so I mixed them:
Then I asked what else would make it better. It came back with a bunch of ideas. I reacted to each one, said yes to most, and finished with:
Linear is a tool the models know well, and so is its website. So “a bit more ‘linear’ feel” gets you a whole look in a few words.
The redesign was great. A few more tweaks, and it went live.
The status, due date and area are tags at the end of each line, in the file itself. Changing a status adds a tag. It never moves the line, so every change is still one line.
- [ ] Draft issue 42: the open-weights section, three links to check #today - [ ] Rewrite the thesis page: AI tooling for small teams, one slide per claim #in-progress - [ ] Fund II LP list: waiting on Ruth Abara for the intro names (since 9 Oct) #waiting - [ ] Renew the registered agent for the fund entity #fund/fund-ops #due:2026-10-30
Bill
Chatting with my personal agent is easy. It’s a conversation, so I can dip in and out. But the real building happens in my coding agents. So I wanted my personal agent to be able to start a thread there for me.
Bill isn’t a bot. When any of my agents asks Bill for something, a new coding thread starts on my Mac, with the job written into its first message. bites added a few lines to my AGENTS.md, so they all know how:
Bill
Bill is Ben's coding agents: our builder, working across many separate bb threads (default; pi, anthropic/claude-opus-5-5, reasoning medium). Every Bill thread starts with the contents of tools/bill-brief.md (tag the task in progress in todos.md when starting, tick it and add a work-log line when done, ask Ben before adding new work to the board). Roster: tools/bots.md.
I may still play around with this setup. But it worked pretty well straight away.
So now my personal agent can use my coding agent. It’s even better if the coding agent can talk back, and say when it’s built or finished something. The first time, I asked it to tell bites it was done. It had no other way in, so it emailed bites.
Then I asked bites to make every new email a trigger, so it reads them straight away.
Talking to bites from the board
I didn’t want to keep switching back to my personal agent. If I’m on the board and want an update on something, I should be able to ask right there. Like Slack: you @mention someone.
bites passed the job to Bill. When agents prompt other agents, the prompts get a lot more thorough. This is what bites sent:
bites → Bill: the job
Task: comments on the board, with @bites mentions that email bites
Work in ~/bites/tools/board (read README.md first; the board is template.html + sync.py + board.py/server.py + site_manifest.json, published to the board's here.now site via publish_site.py, and also served locally). The to-do for this is already on the board (#in-progress): "Board comments with @bites email". Do not add other work to the board without asking Ben.
What Ben asked for (his words)
"on our board, lets add a comment ability when item detail is expanded, plus if i @ mention - show/suggest bites (you) and it should send you an email with that comment and relevant context." ("you" = bites, his chief-of-staff Grok Bot, which has its own inbox.)
Requirements
- Comments on a to-do. When an item's detail is expanded (inline/peek, list and board views, local and site), show its comment thread (author, London time, text; oldest first) and a comment box (Cmd/Ctrl+Enter to post). Author is Ben from the board. Comments must survive the markdown being re-synced: key them by the to-do key, and keep them if the line's text changes where reasonable (or at least don't crash). Persist comments durably in a vault side file (for example tools/board/comments.jsonl, append-only, not in todos.md), and mirror to a here.now Site Data collection
commentsso the site shows them. Posting from the site must work when the Mac is asleep, so the site writes a record and sync.py pulls it into the side file (same pattern asadds). Check manifest access rules (signed-in Ben/bites emails only) and verify that the existing records are untouched after publishing the manifest change. - @ mentions. Typing @ in the comment box opens a small suggestion list with bites first (show its role "chief of staff"); also list Inbox, Fund, Ben's Bites, Family, and Bill (the builder, not a bot). Keyboard: arrows/enter/tab/esc. Mentions are stored as plain @bites text.
- Email on @bites. A comment that mentions @bites sends one email to bites' inbox. Subject like "Board comment: <to-do title>". Body: Ben's comment; then context: to-do title and full line text (with tags), area/project, status/due, file:line, any detail text, up to the last 5 earlier comments, up to 3 matching work-log lines, and a link to the board item. Add a clear first line such as "From: Ben via the board" and a machine-readable block with the to-do key so bites can reply. Send each comment at most once (track sent state in the side file) and never resend on re-sync. Other bots' mentions are just stored for now, no email.
Email delivery from the Mac: figure out the most reliable way to send mail to bites from sync.py, or from a small helper that sync.py calls (the Gmail connector through Executor, or any local mail route that already exists). It is Ben's own mail to his own bot's inbox, so it is fine to send; it must not email anyone else. If sending needs a credential or setup only Ben can do, stop and tell Ben exactly what you need, with the least-effort option. - Replies from bites. Build
python3 ~/bites/tools/board/comment.py add <todo-key> --as bites "text"(andlist <todo-key>) that appends to the side file and runs a sync, so bites can reply on the board. Replies never trigger email. - Design. This is UI work: use the Emil design skills. Match the existing board look (light/dark following the system, never beige). Keep it quiet and fast: comment count on the row only when > 0, no modal.
- Docs. Add a "Comments" section to README.md. Add a line to tools/bots.md telling bots that comments with @bites reach bites and replies use comment.py.
Done means
- Posted a test comment locally and via the site path, with and without @bites; confirmed one test email arrived. Delete or clearly mark test comments afterward.
- publish_site.py run,
publish_site.py --checkpasses, other collections verified unchanged. - Committed locally (nothing pushed). todos.md item ticked, work-log line appended with the London time, sync.py run.
- Final message: what changed, how to use it, the board URL, and anything Ben must do.
Now a comment with @bites sends bites one email: my comment, the to-do, the earlier comments and what the bots have done on it. bites replies on the board.
All my agents connect to Gmail through Executor. It’s one tool that handles all my connections. So if I switch agents, or use a few different ones, they all have the same access.
Checking the work
Up to now, no agent had reviewed anything. I wanted it checked like a real person would: try everything, on desktop and on a phone, and make sure it’s clean. So in the coding thread I asked:
Bill started subagents to do the testing. They came back with a list of bugs, and Bill fixed them.
Build your own
Point your agent at this page. The setup is written down for agents in agent.md: a to-do board on a file on your computer, grouped by the areas of your life, online on here.now for just you and your agent.
agent.mdopen
# Build a to-do board you share with your agents
A brief for an agent. It sets up what Ben Tossell describes in "I wanted to see my to-dos": one markdown file of to-dos on your human's computer, a page that shows it and ticks lines, grouped by the areas of their life, and a private copy on the web that only they and their agent can open. Build it for your human's own setup.
## Ask your human first
One question at a time. Suggest an answer each time.
1. Where should the to-do file live? (A markdown file in a folder they can open and that you can read and write. If there is none, make `todos.md`.)
2. Which areas of life or work should the board group by? (For example: Work, Newsletter, Home, Family.)
3. Which agents do they use, and what does each one look after? (Write this down; the board's Map shows it.)
4. Do they want it on their phone? If yes: here.now (or a host with a small database and email-based access), and which emails may open it. Usually their own and their agent's.
## The rules that make it work
1. **The file is the only truth.** The page, the site and every agent read it and write to it. Anything else is a copy.
2. **One line per to-do. A change edits one line and leaves every other byte alone.** Write the file atomically (temp file, then rename).
3. **Find the line safely.** The page sends `{file, line number, exact line text}`. If that line moved, look for the exact text once elsewhere; if it is not there exactly once, refuse and reload.
4. **Everything about a to-do lives in its line**, as tags at the end, because agents edit the file directly.
## The line format
```
- [ ] Short title: details #area #status #due:YYYY-MM-DD #id:xxxxxxxx
- [x] Short title: details #area #done:YYYY-MM-DD #id:xxxxxxxx
```
- Short title: 8 words or fewer, before the first colon. Details after it.
- Status, one only: `#today`, `#in-progress`, `#waiting`, `#open`. No tag means open.
- Area: `#work` or `#work/project`.
- `#done:` is the day it was ticked. `#id:` is a permanent 8-character id, so rewording a line keeps it the same item. New lines get one at the next sync; never write one by hand.
Give this section to every agent that edits the file.
## Build it in this order
Check each step before the next. Test on a copy of the file first.
1. **A local page.** A small server on the computer (Python's standard library is enough) and one HTML file: show the to-dos grouped by area and status, tick a box to change its line, re-read the file every few seconds so agents' edits show up. Light and dark follow the system.
2. **Online, private.** Publish the page to here.now and set access to "specific emails": your human's and yours. Anyone else gets a 401. A free here.now account is enough; restricted access needs the site to belong to an account, not an anonymous publish.
3. **Ticks from the phone.** Add a here.now Site Data collection for the to-dos (one record per to-do, key = its id). The page reads it and saves ticks to it from the browser. Site Data follows the site's access, so it is as private as the page.
4. **A sync script** on a timer (every 10 minutes: launchd on a Mac, cron on Linux). First pull: apply changes from the site to the file, one line each. Then push: send the whole list back up. If the same line changed in both places since the last run, the file wins. If the site can't be read, change nothing. When the computer is off, the site keeps working and the next run catches up.
5. **A map and a work log.** `map.md`: one card per area (what it is, where it lives, who looks after it), shown on a Map tab. `work-log.md`: append-only, one line per thing an agent makes (`- YYYY-MM-DD HH:MM | agent | area | what | path or link | status`), shown on a Log tab. It is mostly for agents: who did what, where and when.
6. **Agent rules.** Tag a to-do `#in-progress` when you start it, tick it with `#done:` when you finish, add a work-log line, and ask your human before adding new work.
## Optional: let your agents talk to each other
Only if your human asks. Ben's setup, for reference:
- His personal agent (bites, in Grok Bot) can start jobs in his coding agent. A few lines in his `AGENTS.md` say how, and he calls those jobs "Bill".
- The personal agent has its own email address (some apps let you set one; services like AgentMail give any agent an inbox) and a trigger that runs it the moment an email lands. Coding jobs report back by email.
- A comment on the board that mentions the personal agent (`@bites`) emails it the to-do and its context; it replies on the board.
- His services (Gmail and the rest) connect once, through Executor, so every agent has the same access.
If your human wants this, ask them which personal agent and which coding agent they use, then work out the simplest version for their tools.
## Keep it safe
- Nothing is sent, published or pushed without your human saying yes.
- Never edit agent instruction files unless asked.
- Back up before changing many lines, and compare counts before and after.
- Keep the live site restricted: it holds real to-dos.
Behind the build
- Fri 16 Oct
- BenAsks bites for a fresh start
- BenSays yes to the board first
- bitesFirst version, on my Mac
- bitesA snapshot on here.now
- BenTicked a test to-do from my phone
- bitesThe live two-way board
- bitesSync every 10 minutes
- bitesMap tab
- bitesLog tab and the work log
- bitesIn progress
- bitesStarts the “Board work” thread
- BenPicks Sidebar, with Focus’s map
- BenNames Bill
- bitesWrites the Bill brief
- Board workRedesign done, emails bites
- bitesGets a trigger for new email
- bitesStarts Bill on comments and @bites
- BillThree reviewers: desktop, phone, code
- BillThree Haiku fixers and a tester
- Sat 17 Oct
- BenPhone review
- BillNine phone fixes
- BillDemo mode
| Who | Model | Job | Tool calls |
|---|---|---|---|
| bites | Grok Bot | First version to In progress | – |
| Board work | Opus 5.5, high | The redesign, with me typing in the thread | 189 |
| Bill: comments | Opus 5.5, medium | Comments, @bites, reviews and fixes | 215 |
| Bill: ids | Opus 5.5, medium | An ID on each to-do, so it's easy to reference | 71 |
| Bill: apps | Opus 5.5, medium | Polish, demo mode (and the email app) | 367 |
| 5 reviewers | Opus 5.5, medium | Desktop, phone, code, two re-tests | 249 |
| 26 helpers | Haiku 5.5, medium | Small fixes, each on its own copy | 651 |
How this was made
Every line of code was written by my agents. I asked, picked and checked.
Models
- bites, my chief of staff: Grok Bot (the app doesn’t show the model). Built the first version through to In progress
- Board work, the redesign: pi ·
anthropic/claude-opus-5-5· high - Bill, comments and @bites: pi ·
anthropic/claude-opus-5-5· medium - Bill, an ID on each to-do: pi ·
anthropic/claude-opus-5-5· medium - Bill, apps dashboard, email and demo mode: pi ·
anthropic/claude-opus-5-5· medium - Bill, Domains page and done dates: pi ·
anthropic/claude-opus-5-5· medium - 5 reviewers and re-testers: pi ·
anthropic/claude-opus-5-5· medium - 26 helpers: pi ·
anthropic/claude-haiku-5-5· medium - DESIGN.md, my house style: pi ·
anthropic/claude-opus-5-5· xhigh - This page and its research: pi ·
anthropic/claude-opus-5-5· max, with bites’ write-up of our chats
Code and tools
- here.now: hosts the board and this page. Site Data is the board’s database, and access is a list of emails
- launchd: runs the sync every 10 minutes
- bb CLI: how bites and the other bots start Bill threads
- Executor: Gmail for the @bites emails, and one place for all my connections
- Python 3, standard library only: the board’s server, the sync and the email to bites
- git: on my Mac only. Nothing is pushed
- Playwright, with Chromium and WebKit: the testers’ desktop and phone checks
- Zed and Obsidian: open a to-do’s line in the file
Design
- Emil design skills:
/emil-prototypefor the three versions, and the phone review - DESIGN.md: my house style in Google’s DESIGN.md format, made from my course site with Google’s extract-design-md skill
- neat-annotations by syabro (MIT): the margin notes
- The diagrams: hand-drawn boxes and arrows, written in plain JavaScript and SVG
- Inter, Shantell Sans and JetBrains Mono: the type. Shantell is the handwriting
Data sources
- Git history of my ~/bites folder: 28 commits to the board, and the lines of code
- bb thread logs and prompt histories: every prompt, word for word
- pi session logs: models, reasoning levels, tool calls and cost
- bites’ write-up of our chats: my messages and its replies, with times
- The work log and the board’s README: what was made, and how it works
- Sam Reyes and their to-dos: made up, from the board’s demo mode
Reference only, none of it is on this page
- Linear: the look I asked for
- Kevin Ngo’s posts on X: this list, and his paper-and-ink diagrams
- My course’s lesson pages: margin notes beside the text, and canvases
