The way I take notes has been described by various people as "tortured," "bizarre," "pathological," and other judgy (though not entirely groundless) words. A kinder assessment might say that, like many things made by a single pair of hands, it bears all the marks of an individual history* and set of priorities**. I started all this by looking for a way to take notes that was:
After countless iterations, what I wound up was essentially a programming language for myself, with sufficient rules and consistency to make it a fun project when I took a compilers class. Once the rules and keywords solidified I realized it was possible to write tooling around it so that I could get autocomplete and syntax checking and maybe more while writing my notes in an IDE.
Literally everything else turned out to be more important for the next several years and so I sat on my compiler for a while until I found myself this past weekend with an unused month of personal Copilot tokens and a dream: code up a Visual Studio Code extension that would take my tortured, bizarre, etc. notes to new depths of over-engineering.. Fifty percent of my quota later, I now have a Textmate grammar for the language, extensions to the language that make it capable of expressing basically everything going on in my life in a single tree, syntax highlighting and checking in VS Code, a panel that shows open to-do items with a button that lets me sync my notes to GitHub, and maybe one or two other things I've forgotten in my excitement.
About an hour or so into development I was able to have the notes themselves drive development of the notes extension; I could add items, label them with an [AI] tag, and the agent would pick them up, work them, and then write notes back into the plan using the same language constructs.
Here's a sample of the notes just mentioned:
GOAL: Update extension and language with new features and fix bugs
TASK: [AI] New language feature: BUG
NB: BUG should have the same behaviors as BLOCK and can basically just be an alias
NB: Implemented as a BLOCK-behavior alias across parsing, editor behavior, syntax
highlighting, and markdown export while preserving the BUG surface keyword.
DONE
TASK: [AI] First bug: github sync doesn't work
NB: Error is `fatal: pathspec ':(glob)**/*.mprs' did not match any files`
NB: Fixed by collecting changed paths from `git status` and staging those paths directly
instead of passing both extension globs to `git add`.
DONE
TASK: [AI] Further refine documentation
NB: README is still way too big and way too self-impressed with the language.
NB: README is shown wholesale in extension information, so should be exclusively
about the extension rather than the language.
NB: README now focuses on extension capabilities, commands, AI workflow, sync
behavior, and development commands, while the language reference stays in
docs/language_reference.md.
DONE
Q: [AI] Can we consider consolidating context/goal files somewhat? For one-off things
it seems cumbersome to create an entry in a context file, create a folder, create a context
file in that folder, reference a goal file, create that goal, and write the goal.
A: Keep the explicit file structure for now, but reduce the friction by letting the extension
create missing referenced files directly from diagnostics.
Q: [AI] If we need all that structure, can the extension provide these with a right-click
action on an unrecognized context or goal ref?
A: Kind of handled with below
Q: [AI] At minimum, can the extension have a "create file" fix when it sees an invalid ref?
A: Yes; broken GOAL_REF and CONTEXT_REF diagnostics now offer a preferred quick
fix that scaffolds the missing goal or context file and opens it.
TASK: [AI] Add repo information to CONTEXT
NB: A context can be associated with a GitHub repo, so being able to label that explicitly
would be nice. However, adding "REPO" as a first-class language feature seems too
specific. What are our options? This might require a new syntax of some kind and I'm
here for it. Maybe something like `EXTERNAL_REF (REPO):` or `EXTERNAL_REF:` with
nested markers like `REPO`, `SHAREPOINT`, etc. perhaps with a definition file, library, or
config file to support these?
NB: Implemented as a `REF` convention rather than a new keyword: use `REF: github:owner/repository`
under `CONTEXT` for repo metadata.
NB: The extension now makes supported external refs clickable, and markdown export
renders GitHub repo refs as links.
DONE
BUG: [AI] `A` without parent `Q` does not throw a warning but should
NB: Fixed with a parser semantic warning: `A` must be a direct child of `Q`.
DONE
BUG: [AI] The bug I just added does not show up automatically on the dashboard (nor the pane),
so I'm not sure automatic refresh is working
NB: This one didn't show up automatically either
NB: But when I added an NB, this bug did. However, the `A` without parent `Q` one has still not
shown up yet.
NB: "BUG" is a new keyword, is that why?
NB: Fixed by treating `BLOCK` and `BUG` as open visible items in the tree/dashboard/AI brief.
DONE
TASK: [AI] `REF` should be available within GOALs, STEPs, and TASKs, not just CONTEXT, I think.
That way if I want to indicate that a STEP needs a particular external resource (like a website
or Github repo) then it's right there and clickable.
NB: This now works: `REF` is parsed anywhere in the hierarchy, external refs are clickable in the
editor, and markdown export preserves them as links where supported.
DONE
TASK: [AI] Consider whether CONTEXT needs its own file or needs to be above GOALs.
Q: Maybe goals can specify their context internally?
A: Keep `CONTEXT` as a separate organizing file for cross-file structure, and use local `REF`
entries inside GOAL/STEP/TASK when a work item needs its own external resource context.
A couple of interesting things: several of these notes are actually from the agent; it would often insert an NB to explain what it did before marking something as DONE, and directly answer questions in the document. I had to do very little prompting for it to do this, and once I had a validator written it was trivial for the agent to make sure the code passed after it had updated the notes. The traceability this gives me is pretty great, and though one of the primary reasons I started taking notes this way was to keep track of what I had done, it's a natural next step that it would help me keep track of what the agent did.
*VAX/VMS, using CP/M on a 9-inch screen, Nortel Option 11 PBX programming, the Mikado method, the all-caps terminal commands in Wargames, and an incomplete, idealized concept of the Franklin day planner
**My priorities are to encode meaning in structure to avoid having to write it myself and, relatedly, having internal controls against my natural prolixity