8 Feb: 57 commits across 10 projects
57 commits. 10 projects. One Saturday.
Here's the breakdown by project, with methods and techniques threaded through.
| Commits | Lines changed | |
|---|---|---|
| Bombay | 18 | +16,900 |
| Grok | 15 | +5,600 |
| dannyhope.co.uk | 12 | +3,100 |
| UX Brighton | 6 | +1,500 |
| highlightHoveredWord | 1 | +2,100 |
| mermaid-service-blueprints | 1 | +9 |
| Inbox harmonisation (4 repos) | 4 | — |
Grok — document restructuring SPA
Launched the MVP in the morning, then iterated through the evening. Grok is a single-page app for restructuring long documents — splitting, merging, and rearranging paragraphs across two panels.
Features built in a single session:
- Bidirectional hover highlighting — hover a paragraph in either panel and its counterpart highlights in the other
- Collapsible paragraphs — fold sections to focus on what you're editing
- Editable transclusions — edit shared content in-place, with a diff toggle to see what changed and a revert button
- Split at cursor — break a transclusion into two at the cursor position
- Listify and merge — transform paragraphs into list items or merge multiple paragraphs into one
The method here was tight iteration loops: refine the task in .in/, implement it, close it, move on. Six tasks were created and four were closed within the same session.
Bombay — Nuxt dashboard and embedding-based routing
The biggest commit count. Three main efforts:
Nuxt 3 dashboard — Built the next-generation dashboard as a Nuxt app. The classic single-HTML-file dashboard was approaching its limits (as I noted in last week's post), so this replaces it with a proper component architecture.
Embedding-based task routing — Added a fallback routing strategy for inbox items that don't match any deterministic filter. It generates embeddings for the task content and compares them against project descriptions to find the best match. This sits behind the existing rule-based filters and only fires when nothing else catches the item.
Inbox fixes — Fixed a Unicode encoding crash that appeared when importing reminders with smart quotes and narrow no-break spaces. The same bug existed in two separate scripts, so both got patched.
Other changes: custom menu bar icon with dark/light mode support, refined repo detection to require a .in/ directory, configuration GUI with settings panel, and auto-apply inbox filters in the project-watcher service.
dannyhope.co.uk — blog overhaul
Upgraded the blog from 11ty v2 to v3 and added infrastructure that was overdue:
- RSS feed at
/blog/feed.xml - Tag pages — each tag gets its own listing page
- Tag taxonomy — polyhierarchical tag inheritance so child tags roll up to parent categories
- Content style guide — applied sentence case, descriptive headings, and concise paragraphs across all existing posts
- Flat permalinks — simplified from
/blog/posts/slug/to/blog/slug/
Also published a new post: Service blueprints have no markup language.
UX Brighton — bug fixes and test suite
Three distinct pieces:
-
scrollTo shadowing fix — Renamed a custom
scrollTofunction tosmoothScrollToacross 11 files. The custom name was shadowing the nativewindow.scrollTo, causing subtle scroll behaviour differences in some browsers. -
List.js container bug — The jobs filter wasn't appearing because List.js requires the
.listcontainer to be a direct child of the List.js root element. Documented the gotcha in_docs/expertise.mdso it doesn't bite again. -
Playwright test suite — Added comprehensive browser tests covering navigation, page loads, 404 tracking, and interactive elements. Also consolidated all redirects into a single Netlify
_redirectsfile.
highlightHoveredWord — TypeScript port
Ported the Chrome extension from vanilla JavaScript to TypeScript + Vite. The original extension highlights every instance of the word under your cursor. The port adds type safety and a modern build pipeline — 19 files, clean start.
mermaid-service-blueprints
Small change: added a motivation section to the README explaining why service blueprints need a proper markup language. Context for the blog post published the same day.
Inbox harmonisation
Ran a cross-project rename of done/ → closed/ in .in/ directories across six repos (autoclose, video-speed-controller, flux-reliability, fitts-law-calculator, UX Brighton, and dannyhope.co.uk). This aligns all projects with the convention documented in CLAUDE.md.
Methods
A few patterns that made the day productive:
- Refine-then-build — In Grok, every feature started as a task file refined with
/refinebefore implementation. The refinement step clarifies scope and acceptance criteria, which keeps implementation focused. - Inbox harmonisation as a batch — Rather than fixing naming inconsistencies project-by-project, I scripted the
done/→closed/rename across all repos in one pass. - Embedding fallback — The Bombay routing change is a good example of layered automation: deterministic rules handle the common case, embeddings catch the rest. Neither approach alone would be sufficient.
- Bug documentation — The List.js container pattern gotcha was written up in
_docs/expertise.mdimmediately after fixing it. Future me (and Claude) will find it there.