Most of my work on rookery this week was driven by an increasingly obsessive attempt to use it as the dashboard for organizing my academic life. As I’ve written in the rookery FAQ, one of the inspirations for rookery’s elementary notion of the ‘idea’ is Org-mode’s TODO system. My personal task management system has been more or less exclusively Org-mode todos for at least a couple of years. I typically view TODOs as a global list across all of my Org-mode files, meaning that I can drop a * TODO heading in any note at any time, and get it ‘filed’ in my list of all things:
I really like treatign TODOs as federated in this way, as it means that, in addition to showing up on my global list, TODOs are associated with a project and/or other relevant surrounding context, such as the notes for the meeting out of which they were seeded. (Clicking enter on any of the TODO lines in the view above takes me to the TODO’s original context if I want to reference it or iterate there, if the TODO involves writing or further note-taking.)
An idea in rookery was conceived as a (slightly generalized) TODO in the Org-mode sense. Rookery provides mechanisms to aggregate ideas that were hatched in various contexts, allowing them to be federated into global views or views over multiple hatching contexts, and always keeps the backlink to these hatching contexts. One of the packages I wrote this week was a skin over @rookery/core called @rookery/todos which recreates the Org-mode experience:
This is working nicely for the small part of my notes that I have ported over from my Org-mode system currently, 283 ideas in total. These ideas are a mix of conference deadlines, job postings, personal todos, meeting notes, and more Zettelkasten-style notes on entities such as academic institutions and individual academics. Ideas in rookery follow the core principle of associative archiving in that every idea exists in a flat search space. More pricipled ‘types’ (todos, meeting notes, entity entries) can then be specified through rookery’s tagging system, which is inspired by DEVONthink’s tag system. As everything in a rookery is just an idea with optional tags, someone searching it can combine these two core data types to efficiently filter the search space (search by tag) and match on content in ideas (fuzzy search that combs both title and content):
You might be thinking that this is all well and good for simple filters over ideas, but that a flat pool of strings is not a great data structure on which to build more complex metadata associated with ideas such as date lifecycles (created, updated, etc.). It’s of course possible to encode/serialize complex hierarchies and types as strings (created:2026-08-31, etc.); but this gets messy given that rookery wants to show the tags associated with an idea in its interface, as you can see in the pills beneath the search items in the image above.
Rookery tags are therefore actually not represented as an array of strings, but as a hash map. If an entry’s value in the hash map is none, then rookery treats that tag as viewer-facing and presents it in the interface as you would expect (see tags such as meeting, liminal, and tidbit in the screenshot above). If the value is not none, however, the tag is treated both as a regular tag and as a metadata entry on the idea. A tag in rookery can thus consist of metadata structures that make full use of Typst’s type system.
I’ve been working on a @rookery/timeline package, for example, associates a timeline-log with certain ideas, like so:
#let tags = (timeline-log: (
(
stage: "submitted",
timestamp: datetime(day: 29, month: 4, year: 2026),
note: [What went in ..],
),
(
stage: "under-review",
timestamp: datetime(day: 31, month: 8, year: 2026),
note: [Reception confirmed..],
estimated: true,
),
(stage: "accepted", timestamp: none),
(stage: "held", timestamp: none),
))This means that, in filters and search, we can then also filter according to the timeline-log of certain ideas, prioritizing ones with a deadline approaching. The metadata can then also be used to power custom UX elements exported from @rookery/timelinesuch as this stage-tracking footer shown in the standalone page of the idea:
In addition to @rookery/core, I now have prototypes for @rookery/search, @rookery/timeline, and @rookery/todos, which I am drafting in the 0.1.0 branch. I added a mechanism in Rheo 0.6.2 to read Rheo packages directly from git repos and branches configured in rheo.toml, which should allow me to iterate on the packages without having to constantly mint new releases. (I got up to rookery 0.6.0 this week before deciding that I had to do something about it so that the rheo-packages release stream wouldn’t be so noisy.)
None of this is live or released yet, as I want to at least notionally stabilize the @rookery/core API before minting an 0.1.0.