<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>hi, it&#39;s mike</title>
    <link>https://mike.puddingtime.org/tags/lmno/</link>
    <description>Recent content on hi, it&#39;s mike</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <managingEditor>mike@puddingtime.org (mike)</managingEditor>
    <webMaster>mike@puddingtime.org (mike)</webMaster>
    <copyright>© 2026, mike</copyright>
    <lastBuildDate>Mon, 14 Jul 2025 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://mike.puddingtime.org/tags/lmno/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>What is practice</title>
      <link>https://mike.puddingtime.org/posts/2025-07-14-what-is-practice/</link>
      <pubDate>Mon, 14 Jul 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-07-14-what-is-practice/</guid>
      <description>&lt;p&gt;Al and I went to a dome show at OMSI called &amp;ldquo;Trust the Universe: The Philosophy of Alan Watts.&amp;rdquo; Up front, because reviews are thin on the ground, I would recommend against it: It&amp;rsquo;s only 45 minutes long, feels pretty disjointed, and the psychedelic visuals are sometimes a little campy. When the lotus position guy sort of gets sucked up into the mandala having dissolved his own ego I was annoyed.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Al and I went to a dome show at OMSI called &ldquo;Trust the Universe: The Philosophy of Alan Watts.&rdquo; Up front, because reviews are thin on the ground, I would recommend against it: It&rsquo;s only 45 minutes long, feels pretty disjointed, and the psychedelic visuals are sometimes a little campy. When the lotus position guy sort of gets sucked up into the mandala having dissolved his own ego I was annoyed.</p>
<p>I find Alan Watts engaging. He was a gifted explainer who could make heady, paradoxical ideas flicker into solidity and coherence. There are a few moments in the show where his ideas do come together and you get a sense of what he was about, particularly about teaching and spiritual practice.</p>
<p>It ended up giving Al and I something to think about afterward. She&rsquo;s a member of a local Zen center. I&rsquo;ve never really felt very compelled to take up a formal practice. Certainly nothing like Soto Zen. I have some contradictory feelings about it that the show resurfaced, because Watts saw some spiritual practice and relationships with teachers as a sort of revolving door one could never get out of if they don&rsquo;t push us toward our &ldquo;oh, it&rsquo;s in here&rdquo; moment.</p>
<p>I guess I&rsquo;ve always felt like big changes and shifts are &ldquo;it&rsquo;s in here&rdquo; moments. There are lots of techniques and approaches to get us to those shifts, and a skilled coach, mentor, teacher, or counselor can help us to or through those shifts, but my moments of radical clarity have always come just bumping into life. It&rsquo;s interview season right now, for instance, and I have been reminded of the &ldquo;pouncer&rdquo; and &ldquo;stalker&rdquo; learning styles. I think in life matters I&rsquo;ve turned out to be a &ldquo;pouncer.&rdquo;</p>
<p>But I also think there&rsquo;s value in spiritual community &ndash; even having a teacher &ndash; because to be raised in a liberal society in the 21st century is, regardless of your ideological tilt, to be coached toward profound egoism and a kind of selective sollipsism. Finding someone to trust and someone willing to work through our egoism and self-protection can be helpful. I know I&rsquo;ve benefitted from it when I&rsquo;ve been stuck on something, even if the benefit I got wasn&rsquo;t a resolution, so much as an ability to sit with the discomfort of a lack of resolution.</p>
<p>I titled this post &ldquo;What is practice?&rdquo; because I&rsquo;m not always sure. If I ask that question of a Soto Zen practitioner I&rsquo;ll get a kind of answer. If I ask three Soto Zen practitioners, I will likely get three different answers. If I widen my survey to different sects, still more answers. If I ask the person trying to sell me a mindfulness app, there will be another answer, and since there seem to be dozens of those people, probably dozens more answers.</p>
<p>I think for now my working definition is &ldquo;whatever grants you the most ability to sit with your thoughts and feelings in a place of remove from them, but engagement with them.&rdquo; For some people, that will involve very austere forms &ndash; Al says at her Zen center you can opt in to a firm rod on the shoulder if your form slips &ndash; and for others not anything like that at all. I&rsquo;m most in a &ldquo;practice mindset&rdquo; when I&rsquo;m running, doing some kinds of writing, and playing some kinds of games.</p>
<p>Those aren&rsquo;t buttons I can push &ndash; click I am running so I am correctly engaged with my thoughts and feelings &ndash; because I find myself sometimes a mile down the trail having been eaten by a narrative instead of understanding where a narrative came from &ndash; but they&rsquo;re the most reliable cues to get to the right relationship.</p>
<p>So, I don&rsquo;t know, I said I wouldn&rsquo;t recommend that dome show. I suppose if you have a few Alan Watts books sitting around, or care to undertake some internet research and are careful to avoid what appears to be a recent trend of people making Alan Watts deep fakes that spout mysticism, you could sort of rig something up for yourself with headphones and a good screensaver. But it did remind me of a few questions about practice and mysticism I hadn&rsquo;t thought about for a while. It did smell a little like weed in the dome theater, though.</p>
]]></content:encoded>
    </item>
    <item>
      <title>About this project</title>
      <link>https://mike.puddingtime.org/posts/2025-07-13-about-this-project/</link>
      <pubDate>Sun, 13 Jul 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-07-13-about-this-project/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m adding a section to my Claude Code-driven project READMEs (below).&lt;/p&gt;
&lt;p&gt;I came across someone&amp;rsquo;s attempt to create an &amp;ldquo;AI Free&amp;rdquo; badge people could adopt for their projects, and decided that while I appreciate the sentiment, it is not actually helpful to anyone besides people whose position stops at &amp;ldquo;I don&amp;rsquo;t want to use code produced by an LLM.&amp;rdquo; That&amp;rsquo;s a fine position I take no philosophical issue with, but it doesn&amp;rsquo;t help people who come across my projects, which are plainly excluded from using that badge, to understand what it means to use them or interact with the code base if their position is not reflexively anti-AI.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I&rsquo;m adding a section to my Claude Code-driven project READMEs (below).</p>
<p>I came across someone&rsquo;s attempt to create an &ldquo;AI Free&rdquo; badge people could adopt for their projects, and decided that while I appreciate the sentiment, it is not actually helpful to anyone besides people whose position stops at &ldquo;I don&rsquo;t want to use code produced by an LLM.&rdquo; That&rsquo;s a fine position I take no philosophical issue with, but it doesn&rsquo;t help people who come across my projects, which are plainly excluded from using that badge, to understand what it means to use them or interact with the code base if their position is not reflexively anti-AI.</p>
<p>I <em>could</em> take a sort of naive position of, &ldquo;look, a repo on GitHub is just a repo on GitHub. There are no promises in this world.&rdquo; And I&rsquo;ve chosen the MIT license for everything, because it has such a &ldquo;do whatever you want with this&rdquo; vibe. But I got a PR on one of the projects, read it and the problem the user was trying to solve, and realized &ldquo;oh, right, it&rsquo;s a GitHub repo and even though Claude is signing all the commits, there&rsquo;s an expectation here that the act of having this code in a public repo on GitHub sets with at least some people.&rdquo; Making it worse, the PR tripped my &ldquo;I don&rsquo;t think this PR sounds safe, exactly,&rdquo; instincts, which meant I had now incurred <em>work</em> by being unclear about what it is I am up to here.</p>
<p>The other thought that crossed my mind came from a conversation with a VP of UX years ago, when I told him we were struggling to make the CSS for our very oldest Puppet documentation work with recent design changes.</p>
<p>He asked me, &ldquo;do you maintain those docs anymore?&rdquo;</p>
<p>&ldquo;No. And we say so.&rdquo;</p>
<p>&ldquo;Are the releases they cover supported anymore?&rdquo;</p>
<p>&ldquo;No. We mention that, too.&rdquo;</p>
<p>&ldquo;Can you still read the docs, even if the CSS is broken?&rdquo;</p>
<p>&ldquo;Well, it&rsquo;s ugly and a bit distracting, but the content is there.&rdquo;</p>
<p>&ldquo;Good. Then it sets the right expectation. Let it serve as signal. You&rsquo;ll probably get less complaints about it because you&rsquo;ve made your position clear with the non-support message, and backed it up with obvious neglect.&rdquo;</p>
<p>So instead I&rsquo;m going to disable PRs to just foreclose on potential for misunderstanding, and also do my own version of a &ldquo;Made with AI&rdquo; Dubious Housekeeping Seal.</p>
<p>I&rsquo;m going to also make a commitment to make my language about these experiments less twee:</p>
<p>I did not &ldquo;work with the robots,&rdquo; &ldquo;ask the robots,&rdquo; &ldquo;torture a bot,&rdquo; etc. I used an LLM, used AI, used Claude, etc.</p>
<p>Whether it shows or not, I am in some fairly serious <em>internal</em> discussion about what these tools mean, how we should use them, how/if there can be ethical use of them, etc. The spectrum of takes on AI covers a range of people I know, care about, and respect. It feels disingenuous and a little dishonest for <em>me</em> to use diminishing or <em>faux</em> naive language to describe what I&rsquo;m doing here, as if to me it is a matter of idle amusement or something I don&rsquo;t understand I should take seriously or be thinking about.</p>
<p>So, this is the new README edition. And once I resolve the issue the PR I got against one of the projects is resolved, I&rsquo;ll turn off PRs: More signal.</p>
<h2 id="important-consideration-before-using-this-code-or-interacting-with-this-codebase">Important consideration before using this code or interacting with this codebase</h2>
<p>This application is an experiment in using Claude Code as the primary driver the development of a small, focused app that concerns itself with the owner&rsquo;s particular point of view on the task it is accomplishing.</p>
<p>As such, this is not meant to be what people think of as &ldquo;an open source project,&rdquo; because I don&rsquo;t have a commitment to building a community around it and don&rsquo;t have the bandwidth to maintain it beyond &ldquo;fix bugs I find in the process of pushing it in a direction that works for me.&rdquo;</p>
<p>It&rsquo;s important to understand this for a few reasons:</p>
<ol>
<li>
<p>If you use this code, you&rsquo;ll be using something largely written by an LLM with all the things we know this entails in 2025: Potential inefficiency, security risks, and the risk of data loss.</p>
</li>
<li>
<p>If you use this code, you&rsquo;ll be using something that works for me the way I would like it to work. If it doesn&rsquo;t do what you want it to do, or if it fails in some way particular to your preferred environment, tools, or use cases, your best option is to take advantage of its very liberal license and fork it.</p>
</li>
<li>
<p>I&rsquo;ll make a best effort to only tag the codebase when it is in a working state with no bugs that functional testing has revealed. Tags just mean &ldquo;seemed to be in working order.&rdquo;</p>
</li>
</ol>
<p>While I appreciate and applaud assorted efforts to certify code and projects AI-free, I think it&rsquo;s also helpful to post commentary like this up front: Yes, this was largely written by an LLM so treat it accordingly. Don&rsquo;t think of it like code you can engage with, think of it like someone&rsquo;s take on how to do a task or solve a problem.</p>
]]></content:encoded>
    </item>
    <item>
      <title>OmniFocus through a new lens</title>
      <link>https://mike.puddingtime.org/posts/2025-07-11-omnifocus-through-a-new-lens/</link>
      <pubDate>Fri, 11 Jul 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-07-11-omnifocus-through-a-new-lens/</guid>
      <description>&lt;p&gt;I got a notification that the OmniFocus subscription I forgot all about was about to expire, so naturally I had to go see what I made of that. It was sort of interesting reapproaching OF through the lens of having spent a bunch of time trying different task management tools before deciding to make my own that did everything I wanted.&lt;/p&gt;
&lt;p&gt;My past reaction to OmniFocus has traditionally been &amp;ldquo;no, get it away from me.&amp;rdquo; Some of that reaction is to the tool itself and some of it is cultural: I remember OmniFocus when it was a bunch of AppleScript meant to make OmniOutliner do unnatural things, and I remember the culture it came out of. And some of that reaction is from thinking it is just too much, but that &amp;ldquo;productivity wang overkill&amp;rdquo; is pretty much its most loyal niche.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I got a notification that the OmniFocus subscription I forgot all about was about to expire, so naturally I had to go see what I made of that. It was sort of interesting reapproaching OF through the lens of having spent a bunch of time trying different task management tools before deciding to make my own that did everything I wanted.</p>
<p>My past reaction to OmniFocus has traditionally been &ldquo;no, get it away from me.&rdquo; Some of that reaction is to the tool itself and some of it is cultural: I remember OmniFocus when it was a bunch of AppleScript meant to make OmniOutliner do unnatural things, and I remember the culture it came out of. And some of that reaction is from thinking it is just too much, but that &ldquo;productivity wang overkill&rdquo; is pretty much its most loyal niche.</p>
<p>So I didn&rsquo;t like its chances. But I had Claude write a quick importer for me that turned all my denote-task tasks into OmniFocus tasks, and I was able to quickly get some production data to work with.</p>
<p>My sole objective was to see how amenable &ndash; despite all its gears, buttons, and blinking lights &ndash; OmniFocus would be to just giving me my river of tasks and then providing ways to filter the river down.</p>
<p>To be honest, pretty well. The tool to use to get to the base view is Perspectives, and you can make a simple one that just shows all your open tasks and lists due dates, tags, and parent projects. I added a group-by-date to give me &ldquo;today, the next week, the next month, beyond&rdquo; grouping.</p>
<p>For project view, there&rsquo;s a Projects perspective that&rsquo;s fine. I just dragged them all into order.</p>
<p>To clean up the view a little I just collapsed the inspector sidebar on the right and the &hellip; sidebar sidebar? &hellip; on the left. That got me pretty much the view I have in denote-tasks, which I&rsquo;ve taken to thinking of as &ldquo;the big dumb list view.&rdquo;</p>
<p>I still think OmniFocus is probably overkill for me, but I have a new appreciation for its flexibility.</p>
<p>I also did this exercise with Things, which I&rsquo;ve always felt more warmly toward.</p>
<p>It is not really able to do the Big Dumb List view because it wants to show you today, upcoming, and anytime in discrete areas. I prefer seeing today + upcoming in the same place because sometimes I don&rsquo;t want to do a today thing right now and like just looking down the list for a one- or two-pointer I can pick off.</p>
]]></content:encoded>
    </item>
    <item>
      <title>denote-tasks</title>
      <link>https://mike.puddingtime.org/posts/2025-07-10-denote-tasks/</link>
      <pubDate>Thu, 10 Jul 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-07-10-denote-tasks/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://live.staticflickr.com/65535/54647278914_80ca1a82ff_b.jpg&#34; alt=&#34;Denote Tasks&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/pdxmph/denote-tasks&#34;&gt;denote-tasks&lt;/a&gt; is pretty much &amp;ldquo;what I hoped to get with TaskWarrior but didn&amp;rsquo;t.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Rather than using sqlite it uses Markdown files named using Denote conventions, with some extra metadata in the YAML frontmatter for priority, due date, and project associations.&lt;/p&gt;
&lt;p&gt;I chose to use the Denote naming convention because it gives me a reliable index for making associations between normal tasks and projects and can be the foundation for subtasks at some point. That also means you can use it in the context of a normal Denote notes corpus and take advantage of Denote stuff like dblocks if you like.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://live.staticflickr.com/65535/54647278914_80ca1a82ff_b.jpg" alt="Denote Tasks"></p>
<p><a href="https://github.com/pdxmph/denote-tasks">denote-tasks</a> is pretty much &ldquo;what I hoped to get with TaskWarrior but didn&rsquo;t.&rdquo;</p>
<p>Rather than using sqlite it uses Markdown files named using Denote conventions, with some extra metadata in the YAML frontmatter for priority, due date, and project associations.</p>
<p>I chose to use the Denote naming convention because it gives me a reliable index for making associations between normal tasks and projects and can be the foundation for subtasks at some point. That also means you can use it in the context of a normal Denote notes corpus and take advantage of Denote stuff like dblocks if you like.</p>
<p>I chose plain text instead of a database because you can just pop open a task or project and make notes in it, or link to other notes, or whatever. There&rsquo;s a <code>(l)og</code> hotkey to drop a quick timestamped note into any project or task. I use it when I close a task out or have new context to add.</p>
<p>I do need to go in and straighten out some of the hotkeys, because it started life as an extension to another notes management TUI, but that got a little cumbersome and complex.</p>
<p>Either way, it&rsquo;s very keyboard-centric: Hotkeys let you change priorities, dates, and tags from the task list. No need to open a metadata window or sidebar, which drives me crazy with a lot of todo apps. You can navigate the task list with j/k/gg/G.</p>
<p>There&rsquo;s a plain old CLI, too, for scriptability and because I like having an alias that just pops out today&rsquo;s todos without opening an app, but it needs a bit more work &ndash; the syntax is a bit mangled from going a couple of wrong directions.</p>
<p>I liked TaskWarrior&rsquo;s conception of &ldquo;contexts&rdquo; but borrowed Things3&rsquo;s &ldquo;areas&rdquo; to name it. You can filter by area at launch, so <code>denote-tasks -t --area=work</code> will open up the task list to your work tasks and projects.</p>
<p>And I liked TaskWarrior&rsquo;s core UI: A big list. Partly because it feels grounding. A lot of task management tools hide tasks away behind whatever their organizational containers are (projects, etc.) and while I get that this is meant to be a calming design decision, it doesn&rsquo;t work for my particular brain. I take a little of the potential sense of overwhelm out with a simple horizontal rule that underlines the block of tasks due today, and have filters for priority, estimate, tag, etc. so I can quickly narrow things down if I need.</p>
<p>It also has the core task states I tend to think in: open, done, delegated, paused, dropped. There are little visual indicators for those states, and the list is filterable by those, too.</p>
<p>Oh, there&rsquo;s also fuzzy search and tag search. Great for 1:1s if you take the time to tag tasks with people.</p>
<p>So, I think mooooost people who are super into Denote would probably tend to just use org-mode for tasks. Moooost people who are into Denote would just tend to use Denote in the context of Emacs. I just really like Denote naming conventions conceptually, and like some of the portability baked into them and I don&rsquo;t want to go live in Emacs right now. I&rsquo;m still really digging Helix because since first setting up LSPs for it and doing basic configuration, I haven&rsquo;t felt the urge to fiddle with it. Launches super fast, doesn&rsquo;t need a daemon, does everything I want.</p>
<p>And denote-tasks does everything I want. I really wanted to like TaskWarrior, and like a lot of its ideas. But other parts of it were a little hard to swallow and there&rsquo;s a ton of complexity there. This gets me the parts I liked, inflected to suit my particular mental model a bit better.</p>
<p>Oh &hellip; also I did this one with Claude Code as opposed to Claude Desktop. It is a lot more eager to take credit when it makes commits, and I think that&rsquo;s a good thing. It&rsquo;s fine and probably good if people know they&rsquo;re getting code churned out by a bot.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Trying to figure out how to live with LLMs at work</title>
      <link>https://mike.puddingtime.org/posts/2025-07-03-trying-to-figure-out-how-to-live-with-llms-at-work/</link>
      <pubDate>Thu, 03 Jul 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-07-03-trying-to-figure-out-how-to-live-with-llms-at-work/</guid>
      <description>&lt;p&gt;Today I was writing an interview summary in Greenhouse, the recruiting tool, when I noticed one of those little &amp;ldquo;pixie dust&amp;rdquo; icons I have come to understand means &amp;ldquo;AI here!&amp;rdquo; It made me curious, so I carefully saved my work elsewhere then clicked the button.&lt;/p&gt;
&lt;p&gt;Because I sit on my company&amp;rsquo;s AI governance committee, I have spent a lot of time over the past 18 months or so wondering what that button does in its many manifestations in all the apps where it appears. Sometimes it suggests some stuff you might want the LLM to do for you, like help plan a project, and other times it just does some sort of rewrite based on &amp;hellip; ideas? &amp;hellip; about &amp;ldquo;helping&amp;rdquo; you with your writing.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Today I was writing an interview summary in Greenhouse, the recruiting tool, when I noticed one of those little &ldquo;pixie dust&rdquo; icons I have come to understand means &ldquo;AI here!&rdquo; It made me curious, so I carefully saved my work elsewhere then clicked the button.</p>
<p>Because I sit on my company&rsquo;s AI governance committee, I have spent a lot of time over the past 18 months or so wondering what that button does in its many manifestations in all the apps where it appears. Sometimes it suggests some stuff you might want the LLM to do for you, like help plan a project, and other times it just does some sort of rewrite based on &hellip; ideas? &hellip; about &ldquo;helping&rdquo; you with your writing.</p>
<p>I know some ESL folks who like the pixie dust button when it stands for &ldquo;writing aid,&rdquo; because they want help with their writing. Because they&rsquo;re on their second or third language, while they may not be experts about English they have a proven skill in language acquisition, so they&rsquo;re not naive about what the button means. Not nearly as naive, at least, as people who speak one language and don&rsquo;t give a fuck about that one, let alone any others. So they scrutinize the output. One of them consults unfamiliar words in the dictionary before accepting them, but appreciates the help with basic structure.</p>
<p>I also know people who want help with their effectiveness. Like the ESL people I know, they&rsquo;re coming into that interaction less from the perspective of &ldquo;I barfed some shit into a form and the robot made it good.&rdquo; They&rsquo;re coming at it with a use case like, &ldquo;my boss is think-skinned, defensive, reactive, and mildly paranoid so how can I tell them something they don&rsquo;t want to hear without triggering an episode?&rdquo;</p>
<p>Having typed in what they <em>want</em> to say, then prompting for how they want to be received, when a more diplomatic revision comes out of the little pixie dust slot, they read it carefully, think about using it, then maybe massage it a little, or just use it as a suggestion. In other words, they apply their judgment, but benefit from the slight frame shift to imagine better alternatives.</p>
<p>One person I&rsquo;ve talked to who uses AI in that mode has had a lot of success with the approach. It takes a little extra time because she never just copy/pastes the output, but it has gotten her good results: She truly struggled to express herself in a way that her thin-skinned, defensive, reactive, mildly paranoid boss could hear, and now she&rsquo;s getting better outcomes in those interactions.</p>
<p>&ldquo;I feel like I&rsquo;m cheating,&rdquo; she said. &ldquo;Like I&rsquo;m not doing my job.&rdquo;</p>
<p>I said, &ldquo;you&rsquo;re a senior director for one of the largest Medicaid consumers in the state, and your <em>job</em> is to communicate effectively enough that your 100 employees can get shit done without you triggering a diplomatic incident or your boss losing her shit because you decided fuck it, she doesn&rsquo;t <em>need</em> to like what she&rsquo;s reading.&rdquo;</p>
<p>So I don&rsquo;t really judge the pixie dust button or the edits it sometimes suggests to be an unalloyed social ill.</p>
<p>It was in that spirit I clicked the Greenhouse button.</p>
<p>I was <em>hoping</em> it&rsquo;d be something novel or different. Like, maybe it would offer some insight particular to this kind of writing, or would analyze my commentary for unconscious bias, or even warn me that I was about to commit a hiring practices violation to a corporate system of record. Instead it just mostly repeated my writing but replaced a few turns of phrase I chose very intentionally with more cliched ones that altered my meaning.</p>
<p>I don&rsquo;t know how many hires I&rsquo;ve done, nor how many hundreds of interviews I&rsquo;ve conducted. Lots. Lots and lots. When I&rsquo;m the hiring manager, I&rsquo;m a close reader of interview notes. I pay attention. When I&rsquo;m on someone else&rsquo;s panel, I write carefully and want to be clear.</p>
<p>Today was the first day that I acutely felt the impact of AI fucking with two things I care about: Hiring and communicating. It took my words and Business Englished them into something other. It altered meaning, and to no good end. Nothing was more clear. There were no syntactical, grammar or punctuation issues to call out. It just, I dunno, <strong>blorped</strong> them. There&rsquo;s no word for it. It didn&rsquo;t, like, insert sexist slurs or generate a picture of a Black Nazi. It just sorta gnawed the input like a slobbery, toothless dog and left a saliva-covered pile of verbiage normalized to some inscrutable standard. It was sort of like how when you have shake reduction on a camera, you&rsquo;re supposed to turn it <em>off</em> when you put the camera on a tripod because it counter-intuitively risks blur: Feed the LLM good enough English, just not statistically congruent English, and it&rsquo;ll just sort of cock its head then spit on your sandwich because it&rsquo;s supposed to do <em>something</em> when you click the pixie dust button.</p>
<p>So my mind went immediately to some recent examples I&rsquo;ve caught go by in other parts of my job where someone was plainly hucking their shit into a form and pressing the pixie dust button. The tells were the tells we&rsquo;re all learning to spot &ndash; the sorta flowery lilt, needless explication, and obtuse summarizing; the gratuitous length that reminds me of early efforts to use CG in superhero movies, where it&rsquo;s just obvious that it&rsquo;s CG because human bodies just can&rsquo;t articulate like that, and would rip their own arms off or snap their own necks moving with that kind of speed. Like, nobody in their right mind, asked for a quick outline of a modified five step process you could fit on half a sheet of paper, would spend the time it took to extend that to five pages.</p>
<p>But as much as it was a waste of my time, it was easily addressed because it was obvious and gratuitous. The perp owned it, reminded me of their insecurities about writing, and agreed that they&rsquo;d lost sight of the problem they were trying to solve because for a few seconds it felt really good to not struggle quite as much to make words come out. I don&rsquo;t think it was meant to be a knife-twist that they said they fed it some of my writing as a guide.</p>
<p>And for a lot of business writing tasks, I worry less. If my helpdesk manager wants to send a quick nastygram to three engineers who won&rsquo;t send back their old laptops because they&rsquo;re too lazy to get their shit off of them and put them in the return box, I don&rsquo;t care. &ldquo;My director is going to tell your director, then he said I can lock that fucking thing and delete all your shit&rdquo; is going to be clear no matter what the pixie dust button does.</p>
<p>But I benefitted from Puppet&rsquo;s outstanding emphasis on interviewing and hiring a long time ago, and every detail of those things has mattered to me ever since. I&rsquo;ll cut corners, let myself have bad days, fudge, procrastinate, take unwarranted mental health days, accidentally nap through the first 30 minutes of a QBR, and generally be a slob about a lot of other things, but interviews matter. Period. They&rsquo;re an absolute. When I have one coming up, I pull my shit together and go do it. When I sense someone else isn&rsquo;t invested, or they&rsquo;re phoning in their feedback, or they didn&rsquo;t pay attention during the kickoff, I judge.</p>
<p>Greenhouse provides a button to fuck with something that matters. A kind of writing that matters. It was just a stupid fucking five-pointer to some dev, plopped in the backlog by some product owner who might not even see the sense in it but knew they needed a third bullet for the AI features list, mandated by some director of product who got it loud and clear from someone above them that the market demands moar pixie dust buttons.</p>
<p>Anyhow, it was sort of clarifying. I&rsquo;ve been a little paralyzed when I get the weird AI documents, because sometimes they&rsquo;re non-objectionable. Maybe too long, or too wordy, or with odd little nuances that aren&rsquo;t <em>wrong</em> but are <em>off</em>, but I ask myself &ldquo;for everyday dumb bloodless business writing meant to detail a process, explain a system, or document some steps, is this okay?&rdquo;</p>
<p>Usually yeah. It&rsquo;s fine.</p>
<p>But this got me off the fence a little. I know some people like to announce total bans on AI assistance. I think that&rsquo;s risking losing sight of some things, and I actually can&rsquo;t because we&rsquo;re under a mandate at work to use exactly the kinds of integrated assistance these things offer via all the Google Gemini integrations. (I did overhear a team mentioning that something they were given to work with by their leader would need careful review &ldquo;because it came straight out of AI and probably has mistakes,&rdquo; and that made me cringe.)</p>
<p>So I just told my folks that I&rsquo;ve needed a reason to follow the thirty percent rule a little more, anyhow &ndash; ask for review when you think you&rsquo;re thirty percent done &ndash; and that I want the 30 percent they put in front of me to be just them, not a bot. I just want to know they thought about the core of the thing they&rsquo;re doing, and that they&rsquo;ve chosen a direction we can discuss further if needed, before pressing the pixie dust button. If that runs afoul of the &ldquo;use this shit&rdquo; mandate, because we&rsquo;re also supposed to be offloading our thinking, I&rsquo;ll see ya on the soup line.</p>
<p>If I could burn that button out of Greenhouse though, I totally would.</p>
<p><strong>Coda, bright spot:</strong> I listened to a C-level exec from a major software company say that the biggest challenge they have with AI features is that uptake is really poor. People don&rsquo;t like a lot of it, or technology leaders are resistant. That sort of tracks with the tools I&rsquo;ve got in my portfolio at work. AI was pitched as an expansion or upsell a lot last year. This past several months, three pretty big ones I manage just said &ldquo;fuck it, you win,&rdquo; turned the features on for me, and rolled them into the main SKU without charge. That&rsquo;s some money and time down a hole.</p>
]]></content:encoded>
    </item>
    <item>
      <title>I think I&#39;m finally over the savage wound that was GNOME 2.</title>
      <link>https://mike.puddingtime.org/posts/2025-07-02-i-think-im-finally-over-the-savage-wound-that-was-gnome-2/</link>
      <pubDate>Wed, 02 Jul 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-07-02-i-think-im-finally-over-the-savage-wound-that-was-gnome-2/</guid>
      <description>&lt;p&gt;I finally remembered after a lot of &amp;ldquo;it must be in here somewhere&amp;rdquo; through each tiny little submenu of GNOME Tweaks that the &amp;ldquo;swap fn and ctrl&amp;rdquo; option is actually in Framework&amp;rsquo;s BIOS settings, not somewhere near &amp;ldquo;swap meta and super&amp;rdquo; in GNOME Tweaks.&lt;/p&gt;
&lt;p&gt;I got so used to GNOME&amp;rsquo;s overview being under my thumb with only x percent of thumb curl instead of the pre-tweak y percent that the Framework 12 felt actively hostile. Now it matches my other Linux stuff and the slight change in the number of milimeters my thumb curls to invoke the overview/launcher feels like much less effort.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I finally remembered after a lot of &ldquo;it must be in here somewhere&rdquo; through each tiny little submenu of GNOME Tweaks that the &ldquo;swap fn and ctrl&rdquo; option is actually in Framework&rsquo;s BIOS settings, not somewhere near &ldquo;swap meta and super&rdquo; in GNOME Tweaks.</p>
<p>I got so used to GNOME&rsquo;s overview being under my thumb with only x percent of thumb curl instead of the pre-tweak y percent that the Framework 12 felt actively hostile. Now it matches my other Linux stuff and the slight change in the number of milimeters my thumb curls to invoke the overview/launcher feels like much less effort.</p>
<p>Now I&rsquo;m eyeing the Mac Studio. It&rsquo;s a first-gen M1 Max model and it is still going strong, but when I&rsquo;m being realistic, my <em>main</em> tether to macOS is Lightroom, and my main tethers to Lightroom are a. it has 24 years of digital photos in it that and b. a few raw profiles I&rsquo;d need to figure out how to replicate with another tool.</p>
<p>I like the occasional abrupt swerve into more Linux usage because it&rsquo;s got that whole &ldquo;slightly parallax world&rdquo; thing going on. My mindset in front of a Linux machine is much less interested in hucking stuff on it than I&rsquo;m willing to do with a Mac, and I&rsquo;m less willing to keep stuff on it just in case. It&rsquo;s a much more down to business or, at least, down to the task at hand mindset.</p>
<p>I remember being <em>furious</em> over the turn GNOME 2 took in the naughts, after Sun did a usability study and the team started unbolting shit and tossing it out the back of the plane. Years of configuration equity and tweaks went out the window overnight, and the project leadership just did. not. care. if you were mad about it.</p>
<p>Over 20 years later, though, when I sit down to a fresh GNOME instance where I haven&rsquo;t yet had an opportunity to add &ldquo;missing&rdquo; features with assorted tweaks, I appreciate the mindset. It&rsquo;s a very calm interface.</p>
<p>It&rsquo;s not entirely the fault of Apple or macOS designers that macOS feels more and more busy to me these days. It&rsquo;s that most macOS apps seem to feel entitled to taskbar real estate, so you spend a lot of time finding the &ldquo;show in task bar&rdquo; option as you realize your taskbar situation is out of control.</p>
<p>It&rsquo;s clockwork predictable that after I set up a new Linux machine or start using one after time away I will go through my Macs and do everything I can to remove anything that detracts from a sense of a blank slate when I start a session.</p>
<p>If you asked me if, in the abstract, which desktop ecosystem would produce the more consistent, calm behavior on my part, I&rsquo;d probably reason that the edge macOS has in uniformity would lead to more ordered behavior.</p>
<p>In practice, my Linux machines seem to be the more restrained ones, and a little time on one of them causes me to pare back the widget creep that happens on my Macs.</p>
<p>I wonder if some of that is that my formative years on Linux well preceded the iPhone era and the way it kind of &ldquo;appified&rdquo; the macOS mindset. Like, when I look at what&rsquo;s in /Applications on a long-lived Mac, I <em>wish</em> my biggest problem was that I can never bring myself to drag Pages into the trash &ldquo;just in case.&rdquo; My biggest problem is that I&rsquo;ve got a ton of unneeded single-purpose things it was easy enough to add and inoffensive enough to leave, letting the clutter pile up. I just don&rsquo;t act like that on a Linux system.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Just me, my list, and a day with no meetings</title>
      <link>https://mike.puddingtime.org/posts/2025-06-27-just-me-my-list-and-a-day-with-no-meetings/</link>
      <pubDate>Fri, 27 Jun 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-06-27-just-me-my-list-and-a-day-with-no-meetings/</guid>
      <description>&lt;p&gt;Today was the first day in a little while that I had a true &amp;ldquo;heads down&amp;rdquo; day to truly dig in on the backlog I&amp;rsquo;ve been storing in Taskwarrior: No scheduled meetings, a painful awareness I&amp;rsquo;m behind on a few things, and a vague unease over the fact that unstructured time is my biggest enemy.&lt;/p&gt;
&lt;p&gt;It was off to a good start, though, when I just made sure I was in the right context in TW and got ready to dig in: &lt;code&gt;task context:work&lt;/code&gt; filtered out the non-work stuff, and all my &amp;ldquo;today&amp;rdquo; stuff was red, with tasks from my current focus project in yellow. Very easy to be clear on what I&amp;rsquo;d committed to or what the best things to pull forward would be if I exhausted the day&amp;rsquo;s list, and it helped me spot things that I knew I&amp;rsquo;d need to rethink as I worked through the focus project and future tasks were affected by current work.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Today was the first day in a little while that I had a true &ldquo;heads down&rdquo; day to truly dig in on the backlog I&rsquo;ve been storing in Taskwarrior: No scheduled meetings, a painful awareness I&rsquo;m behind on a few things, and a vague unease over the fact that unstructured time is my biggest enemy.</p>
<p>It was off to a good start, though, when I just made sure I was in the right context in TW and got ready to dig in: <code>task context:work</code> filtered out the non-work stuff, and all my &ldquo;today&rdquo; stuff was red, with tasks from my current focus project in yellow. Very easy to be clear on what I&rsquo;d committed to or what the best things to pull forward would be if I exhausted the day&rsquo;s list, and it helped me spot things that I knew I&rsquo;d need to rethink as I worked through the focus project and future tasks were affected by current work.</p>
<p>It&rsquo;s one thing to sort of develop a model in your head and get it set up. It&rsquo;s another thing to nibble around the edges with a little use here and there while you&rsquo;re figuring out the model. It&rsquo;s a completely other thing to have a long stretch of time in front of you where it&rsquo;s just you and the system and an opportunity to do all the things with it.</p>
<p>So glad I took an axe to the default color scheme and made a much more simplified one. I felt pretty relaxed having only maybe four status colors to deal with for &ldquo;today,&rdquo; &ldquo;next few days,&rdquo; &ldquo;projects,&rdquo; and &ldquo;all the rest.&rdquo;</p>
<p>I&rsquo;m glad I&rsquo;ve taken the time to set up simple shell aliases to make some tagging implicit. It was easy to capture stuff as it came in via Slack, etc. and when I took a pause mid-day to triage some of the incoming it was easy to start from the bottom and retag/add to projects/etc. I&rsquo;m okay with a very linear list of tasks with high resolution at the top and very little at the bottom.</p>
<p>I wasn&rsquo;t sure how I&rsquo;d deal with the wall of tasks I get when I have a minimal filter in place and run the basic list. But after a day of checking in with it, I realized I really like it: Yep, there&rsquo;s a lot to do, but I do really poorly with tools that tidy things up, hide next steps, etc. I know GTD theory says &ldquo;don&rsquo;t try to keep it all in your head,&rdquo; but I appreciate the reinforcement and feel less likely to have something languish because it&rsquo;s out of sight, and I like the opportunity to make a random connection.</p>
<p>On that last point, for instance, one of the folks on my team shared some concerns about their career growth. I made the concern a task, because I owe a conversation about that, and I made it a p1 so it gets a brighter color treatment, and as I worked through a couple of strategic projects today, whenever I checked back in with my list, there was that bright orange, unscheduled p1 sitting down there reminding me that as I think about the big picture I&rsquo;ve got to also pull some things into its wake. There are some things you can&rsquo;t compartmentalize.</p>
<p>I think TW has some features that would allow me to get to a bit more of a &ldquo;only see as much as you need to take the next step&rdquo; state without losing sight of stuff, but one piece of meta awareness I&rsquo;m bringing to this iteration is that leaving features on the table is healthy. The mental complexity people describe when they talk about their &ldquo;productivity methodologies&rdquo; always leaves me feeling skeptical that the system they&rsquo;re describing is sustainable or helpful. One reason I&rsquo;ve always appreciated Things in the Things/OmniFocus debate is that Things does a better job of sort of tucking away all the options unless you choose to use them. Maybe OmniFocus has improved in this regard, but it always felt more willing to expose all the knobs and dials.</p>
<p>So, great experience. I don&rsquo;t have a ton of them next week owing to the compressed holiday timeline, but I do have a few stretches of time, and I&rsquo;m already feeling a little less of the nervousness I feel when I see I&rsquo;ve got some hours to fill.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Well, I remember kind of what I was thinking</title>
      <link>https://mike.puddingtime.org/posts/2025-06-27-well-i-remember-kind-of-what-i-was-thinking/</link>
      <pubDate>Fri, 27 Jun 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-06-27-well-i-remember-kind-of-what-i-was-thinking/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://live.staticflickr.com/65535/54618930208_1787c2eeae_b.jpg&#34; alt=&#34;tinyPod&#34;&gt;&lt;/p&gt;
&lt;p&gt;I forgot I even ordered a &lt;a href=&#34;https://thetinypod.com&#34;&gt;tinyPod&lt;/a&gt; until it showed up at my door Wednesday. I ordered it a very long time ago. (Checked the mail after posting this: &lt;em&gt;10 months ago&lt;/em&gt;!)&lt;/p&gt;
&lt;p&gt;It, uh, it turns your Apple Watch into an Apple Watch encased in plastic with a scroll wheel.&lt;/p&gt;
&lt;p&gt;I think the logic of this purchase was:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I don&amp;rsquo;t really like my Apple Watch as a watch anymore. I am wearing my field watch these days.&lt;/li&gt;
&lt;li&gt;It seems like a neat idea to have a little iPod-like thing with cellular connectivity.&lt;/li&gt;
&lt;li&gt;I like the idea of having access to things like calendar, weather, directions, etc. without having my phone along.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;One could say, &amp;ldquo;if you&amp;rsquo;re getting all that utility out of the watch anyhow, one easy way to carry it would be on your wrist.&amp;rdquo;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://live.staticflickr.com/65535/54618930208_1787c2eeae_b.jpg" alt="tinyPod"></p>
<p>I forgot I even ordered a <a href="https://thetinypod.com">tinyPod</a> until it showed up at my door Wednesday. I ordered it a very long time ago. (Checked the mail after posting this: <em>10 months ago</em>!)</p>
<p>It, uh, it turns your Apple Watch into an Apple Watch encased in plastic with a scroll wheel.</p>
<p>I think the logic of this purchase was:</p>
<ul>
<li>I don&rsquo;t really like my Apple Watch as a watch anymore. I am wearing my field watch these days.</li>
<li>It seems like a neat idea to have a little iPod-like thing with cellular connectivity.</li>
<li>I like the idea of having access to things like calendar, weather, directions, etc. without having my phone along.</li>
</ul>
<p>One could say, &ldquo;if you&rsquo;re getting all that utility out of the watch anyhow, one easy way to carry it would be on your wrist.&rdquo;</p>
<p>Fair point!</p>
<p>In this case, I had just sort of moved on from wearing any kind of wearable and was back to my trusty titanium field watch, and I couldn&rsquo;t bring myself to sell the Apple Watch because I doubted I&rsquo;d get much for it. The &lt;$100 I paid for the tinyPod meant I could have a little connected device that wasn&rsquo;t a phone, and do something with the watch that I kept not selling.</p>
<p>I think the natural niche for these is probably &ldquo;get a deal on a used Apple Watch, convert it to one of these things to have a smart iPod nano.&rdquo;</p>
<p>Oh, details, I guess:</p>
<p>A few of the buttons are a little stiff/vague, but the main one works well enough. The scroll wheel is fine; though you sort of want the middle bump to be a clicker and it isn&rsquo;t. The natural way to operate the screen is with your thumb and that works fine. There&rsquo;s a cutout in the back so you can use your watch charger with it. It feels very nice and solid in the hand. They did a nice job with most of the design: It fits right in with an AirPods case.</p>
<p>I&rsquo;d really like it if someone just made something like this that was a purpose-built connected smart device in a tiny, non-phone form-factor. There is some serious wasted space in this thing that could go to battery. In low power mode with all the health detection features turned off, it sips power. I think a solid week from a charge could be a reasonable expectation.</p>
<p>And the why is just &ldquo;I don&rsquo;t like carrying a slab around in my pocket, and I don&rsquo;t like all the things that slab does, but I do want access to a limited amount of data now and then.&rdquo;</p>
<p>A few years back I got into a habit I liked of just leaving my phone and not having it around the house, and leaving it behind sometimes when I went out for coffee or whatever. My job affords me some roaming and flexibility, and it&rsquo;s nice to be able to go, &ldquo;oh, when&rsquo;s that thing I&rsquo;ve got to be back at my desk for?&rdquo; without having a phone to do that.</p>
<p>I guess it&rsquo;s partly an esthetic thing, partly a bent kind of over-optimization, and partly contrarianism. I guess I like some of the things that smartphones allow, but sort of hate that smartphones continue to get bigger and do more.</p>
<p>Anyhow, I guess I <em>have</em> a tiny connected device that can do all that stuff now, and I <em>don&rsquo;t</em> need to haul my phone around or have it to fuck around with when I&rsquo;ve generally been happier when, sitting and waiting for my order, or for the movie to start, or whatever, I&rsquo;m not doing anything but sitting quietly and thinking about whatever.</p>
<p>Okay. I guess I&rsquo;m okay with this thing. Thank you past me. You were momentarily inscrutable and mysterious, but you made a good call.</p>
]]></content:encoded>
    </item>
    <item>
      <title>More on managing Taskwarrior (and integrating with mutt and notes-tui)</title>
      <link>https://mike.puddingtime.org/posts/2025-06-26-more-on-managing-taskwarrior-and-integrating-with-mutt-and-notes-tui/</link>
      <pubDate>Thu, 26 Jun 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-06-26-more-on-managing-taskwarrior-and-integrating-with-mutt-and-notes-tui/</guid>
      <description>&lt;p&gt;After a few days of fiddling, I almost feel like Taskwarrior is dialed in.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve got a pair of aliases that take away some of the wordiness of task entry: &lt;code&gt;twa&lt;/code&gt; and &lt;code&gt;twp&lt;/code&gt; for things that get either the work or personal tag. If I want to add metadata I can, but if I need to just dash something in, it&amp;rsquo;s fast.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve set up a &lt;code&gt;work&lt;/code&gt; context, a &lt;code&gt;personal&lt;/code&gt; context (which is just &lt;code&gt;not tagged work&lt;/code&gt;), and a &lt;code&gt;contacts&lt;/code&gt; context. So it&amp;rsquo;s easy to cut away the noise from different areas of concern.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>After a few days of fiddling, I almost feel like Taskwarrior is dialed in.</p>
<p>I&rsquo;ve got a pair of aliases that take away some of the wordiness of task entry: <code>twa</code> and <code>twp</code> for things that get either the work or personal tag. If I want to add metadata I can, but if I need to just dash something in, it&rsquo;s fast.</p>
<p>I&rsquo;ve set up a <code>work</code> context, a <code>personal</code> context (which is just <code>not tagged work</code>), and a <code>contacts</code> context. So it&rsquo;s easy to cut away the noise from different areas of concern.</p>
<p>I customized <code>priority</code> to <code>p1</code>, <code>p2</code>, and <code>p3</code> and I customized <code>estimate</code> to ye olde Fibonacci sequence.</p>
<p>I tried using the start/stop functionality and it created an overwhelming amount of visual noise, so I promptly quit doing that, and had such a bad reaction that I ended up radically simplifying the color scheme:</p>
<ul>
<li>red: overdue</li>
<li>paleish orange: due next 48 hours</li>
<li>yellow: active tasks, which by convention I am limiting to my most important project</li>
<li>normal text: the rest</li>
<li>cyan: a &ldquo;project container&rdquo;</li>
</ul>
<p>On that last, Taskwarrior doesn&rsquo;t really have subtasks. It does have dependencies and it does have projects. I&rsquo;m not sure where I&rsquo;m at on the lack of subtasks. Right now I&rsquo;m feeling my way through. One way I&rsquo;ve adapted is to make a task that I tag with <code>project</code> that states the outcome of the project. Something like &ldquo;Turn off Otter Integration.&rdquo; Then I set the date I want that to happen and tag it <code>project</code> as well as add it to, e.g. <code>project:otter</code> along with all the related tasks.</p>
<p>When I run the big task list report, the project deadlines/delivery dates all show up in cyan, so I can get a sense of relative timing of everything I have going on, or will have going on, and how much stuff is between me and getting that thing done.</p>
<p>I&rsquo;m trying to be sort of roadmappy/backloggy about all this. I am trying to avoid prematurely assigning due dates until I feel pretty confident I can honor them, or until I&rsquo;m getting close enough to &ldquo;due&rdquo; on a project that I better make a plan.</p>
<p>Since I due-sort everything on my lists, it means there&rsquo;s sort of a pool of undated tasks down at the bottom of the report just bumping around. That&rsquo;s fine. They&rsquo;re the backlog. The meaningful action is the stuff to the top of the list with light color-coding for the stuff I&rsquo;ve decided needs to happen right now. If I want to start more detailed scheduling on a given project, I can just run the list for it, e.g. <code>task project:otter</code>, and then assign due dates on as much as I need to keep going. If I want to go prospecting, I can run <code>task undue</code> to find things without dates.</p>
<p>I once knew an engineering director the project managers dreaded because he wanted to plan out and schedule the next six sprints in detail, then re-ripple the plan at every sprint close. Basically pantomime horse Agile, I guess, shoving Jira tickets around a board. It was tedious make-work in the service of a fundamental hypocrisy of the place we were working, which was that we&rsquo;d &ldquo;gone Agile&rdquo; but weren&rsquo;t at all Agile.</p>
<p>I am not making software. I&rsquo;m just running an IT org in the middle of a pre-IPO tech company. That company has four or five processes for everything and has the usual struggles around alignment and prioritization that 600 people are going to have. A lot of deadlines are negotiable. The hardest deadlines tend to be based on contract cycles or compliance motions. So there&rsquo;s no sense in me deciding I&rsquo;m going to be utter death about turning off the Otter integration on time: It isn&rsquo;t costing money, it&rsquo;s just making Legal nervous and it&rsquo;s annoying me. So planning it all out is pointless, unrealistic, and fussy.</p>
<p>On the other hand, there&rsquo;s that one app I&rsquo;ve been gunning for two years running, I keep missing the window to run a sunsetting motion, and this is the year for it. That requires some detailed dates.</p>
<p>I&rsquo;m leaving some Taskwarrior stuff on the table:</p>
<p>It has a calculated &ldquo;urgency&rdquo; score that I have disabled on all the task lists and taken out of the color scheme. It&rsquo;s information overload and I don&rsquo;t need it.</p>
<p>You can make things active and inactive. That also makes more visual noise than adds clarity, though I am experimenting with making all the tasks in the highest priority project active and giving them a different color treatment so I can keep them in easy view.</p>
<p>There are dependencies. Yet more detail that I don&rsquo;t need to manage. If I get into something so deep that I need to do dependency mapping, the staff program manager will probably be insisting she be allowed to get involved, and all that shit is going in Jira.</p>
<p>So I think what I&rsquo;m left with is a task list that has some nice ways of storing task metadata (tags, projects, due dates, priority, estimation) without needing to manage fussy plaintext syntax: Taskwarrior uses sqlite, so while you need to type it in correctly, you don&rsquo;t have to worry about an errant semicolon blowing up your carefully manicured plaintext todo list.</p>
<p>You can leave a lot of features on the table if you like, and everything is amenable to customization.</p>
<h2 id="tying-into-notes-tui">Tying into notes-tui</h2>
<p>Today I spent some time working on integrating this with notes-tui, which is now mostly compatible with Denote, meaning every file has an identifier.</p>
<ul>
<li>I added a feature to notes-tui to open a note by identifier</li>
<li>I added a custom data type to Taskwarrior to store a note identifier</li>
<li>I added a command to notes-tui to create a Taskwarrior task storing the note identifier</li>
<li>I have a wrapper script that lets me type <code>tasknote 52</code> (or whatever task number) and open the associated note.</li>
</ul>
<h2 id="tying-into-mutt">Tying into mutt</h2>
<p>Likewise, I have a mutt macro that creates a task with the subject and sender and stores the msgid in a custom field in the task, and a wrapper script that finds the associated message for a task in mutt and opens it.</p>
]]></content:encoded>
    </item>
    <item>
      <title>On Monokai Pro</title>
      <link>https://mike.puddingtime.org/posts/2025-06-26-on-monokai-pro/</link>
      <pubDate>Thu, 26 Jun 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-06-26-on-monokai-pro/</guid>
      <description>&lt;p&gt;I really like the Monokai Pro theme. I&amp;rsquo;m using it in Helix as I write this post. Specifically, I really like the &amp;ldquo;Ristretto&amp;rdquo; sub theme, which hits a really nice note with its browns, oranges, and cyans. (Green figures heavily in it, too, and it&amp;rsquo;s one of those things where it can be used well or used too much, so I won&amp;rsquo;t use kitty&amp;rsquo;s version of Ristretto because I&amp;rsquo;d need to go in and figure out how to swap out the green in my shell color scheme and haven&amp;rsquo;t yet.)&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I really like the Monokai Pro theme. I&rsquo;m using it in Helix as I write this post. Specifically, I really like the &ldquo;Ristretto&rdquo; sub theme, which hits a really nice note with its browns, oranges, and cyans. (Green figures heavily in it, too, and it&rsquo;s one of those things where it can be used well or used too much, so I won&rsquo;t use kitty&rsquo;s version of Ristretto because I&rsquo;d need to go in and figure out how to swap out the green in my shell color scheme and haven&rsquo;t yet.)</p>
<p>So today I made Monokai Pro Ristretto themes for mutt and Taskwarrior, and in the process discovered that there&rsquo;s a business entity that licenses an icon pack and themes for a few editors. It grants an endless demo license or you can pay a few Euro to license it for your editor, so there&rsquo;s not exactly a heinous money grab involved. If Monokai has been involved in cease and desists against terminal theme authors, feel free to inform me.</p>
<p>But I&rsquo;ve been seeing Monokai, Monokai Pro, and the assorted variants around forever, everywhere, and never realized anyone was selling licenses. I&rsquo;d be gobsmacked if any of the people shipping Monokai Pro themes (as opposed to plain old Monokai) licensed them for distribution. I get the impression the designer is happy to get a few euro for his efforts and more pleased to have made a thing that is literally everywhere.</p>
<p>Anyhow, I guess there&rsquo;s sort of an applied ethics thing here, which is &ldquo;now I know,&rdquo; so I&rsquo;ll keep what I came up with to myself and slide a few bucks to the designer, because Monokai and/or Monokai Pro has been a goto for me on every terminal app and editor I&rsquo;ve used that supports it for a while, and the creator has signaled that he&rsquo;d like some money for his work.</p>
<p>You can read about <a href="https://monokai.pro/history">Monokai Pro&rsquo;s history</a> from back in TextMate days to today if you&rsquo;re curious. I think if my theme had screen time on an episode of <em>Silicon Valley</em> I&rsquo;d be jazzed, too.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Seeking the right kind of friction</title>
      <link>https://mike.puddingtime.org/posts/2025-06-24-seeking-the-right-kind-of-friction/</link>
      <pubDate>Tue, 24 Jun 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-06-24-seeking-the-right-kind-of-friction/</guid>
      <description>&lt;p&gt;I picked TaskWarrior as an entry point into CLI todo tools. There are a lot of them, and the struggle between Danny-O&amp;rsquo;Brien-style &amp;ldquo;just write it in a text file&amp;rdquo; minimalism and &amp;hellip; the other extreme &amp;hellip; is real.&lt;/p&gt;
&lt;p&gt;I picked TW because it has been around forever. I will not presume to judge its design decisions. I can tell a few strategically placed aliases would do a lot to remove the sense of crushing overhead. I also picked it because it is super scriptable, so it was easy to build a tasks backend into my contacts TUI with it.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I picked TaskWarrior as an entry point into CLI todo tools. There are a lot of them, and the struggle between Danny-O&rsquo;Brien-style &ldquo;just write it in a text file&rdquo; minimalism and &hellip; the other extreme &hellip; is real.</p>
<p>I picked TW because it has been around forever. I will not presume to judge its design decisions. I can tell a few strategically placed aliases would do a lot to remove the sense of crushing overhead. I also picked it because it is super scriptable, so it was easy to build a tasks backend into my contacts TUI with it.</p>
<p>I decided, alongside implementing TaskWarrior support, that I&rsquo;d probably better implement Things support. Of all the task management tools I&rsquo;ve ever used, Things has been the most sticky, because it&rsquo;s always lurking around whatever device from the last time I used it, and it is so easy to ramp back up. Whenever I pick Things back up again I collapse the sidebar and live in the Inbox list until it gets to the point I&rsquo;m setting up projects again. So I added Things support in case TaskWarrior turned into a misadventure, as these things can.</p>
<p>The best way to describe my relationship to any task management tool is probably &ldquo;anticipated decay&rdquo; I never get into one thinking &ldquo;this is it forever.&rdquo; I know it&rsquo;s going to follow a cycle:</p>
<ul>
<li>Tentative first steps, barely justifying its existence over a legal pad or Apple Reminders with just one todo list</li>
<li>Creeping complexity: Projects, areas, tagging, subtasks</li>
<li>Data entry simplification. If there&rsquo;s a hotkey, widget, Raycast thinger or whatever, I&rsquo;m all about it. This is always the beginning of the end. It really should not be easy to make work for yourself.</li>
<li>Fully operational battle station. A sense of pleased familiarity when I review what&rsquo;s in it each day.</li>
<li>Minor vibrations and oscillations as priorities shift; increasing in intensity until I dread reviewing what&rsquo;s in it each day.</li>
<li>Collapse. I go into crisis for a few weeks and write a few hasty export scripts to at least remember what plates were spinning. Then I walk away.</li>
</ul>
<p>Inevitably, somewhere between the &ldquo;things are getting real with this thing&rdquo; and the &ldquo;I need to make the process of making work for myself buttery smooth,&rdquo; the mobile or multi-platform questions rear their heads.</p>
<p>I imagine life without being able to consult my many deliverables from my phone and some unpleasant part of my personality sends a jolt to the pain and nausea centers, hitting the intersection of old work trauma and pigheaded nerd completionism.</p>
<p>The old work trauma is simple to explain:</p>
<p>My first well-paying job was for an online content play whose leadership utterly failed to anticipate the devastation of the dotcom bust in the early aughts.</p>
<p>When they hired me I was a recently discharged paratrooper splitting my days between running a database for a school and doing secretarial work. The pay was miserable, but my half of the rent came out to $250 a month so I spent my time screwing around with that database and getting called &ldquo;four-eyes&rdquo; by the kids who got sent to the office. I wrote a long comment about <code>man</code> pages on Slashdot that caught the attention of a Linux.com editor who turned it into an article, and that caught the notice of a website editor who offered me 3x the pay to come write a story a week, moderate comments, and keep a newswire site running.</p>
<p>So when the good times began to run out the next year, and the layoffs started, my little workgroup went from 15 people to just me in about six months because, I later figured out, &ldquo;3x part-time database, part-time secretary pay&rdquo; was still pretty cheap in the online content world at the time.</p>
<p>But I was terrified of losing that job. Terrified at the prospect of being laid off. I spent one nine-month stretch working every single day of the week. I got good at a very primitive sort of early 2000s mobile computing because if I wanted to leave the house on a Sunday afternoon, I needed to at least moderate comments from a device, somehow.</p>
<p>Eventually some things went really, really wrong with that place and I quit caring whether I kept the job or not, and I finally just left and went back to school, but I never really lost the habit of thought that some mobile access is very, very important.</p>
<p>When I pause for a moment and have a thought, I realize that is mostly ridiculous.</p>
<p>At work, I live on director time. I&rsquo;m struggling mightily to imagine a scenario where I would need to know the details of some particular task on the spot, or where it would not be okay for me to say, &ldquo;you know what, I know that&rsquo;s in my tracker. When I get home I&rsquo;ll Slack it to you.&rdquo;</p>
<p>In my personal life, again, no. Groceries, I guess, but those go in Apple Reminders because we&rsquo;re an Apple family, as do most little one-offs.</p>
<p>Someone, somewhere mightily disagrees with all this. That is fine. I&rsquo;ve been reading about peoples&rsquo; assorted &ldquo;systems&rdquo; and &ldquo;methodologies&rdquo; for, like, decades. Everyone needs what they need.</p>
<p>And what I need is &ldquo;less,&rdquo; because my unchecked impulse is to optimize for things that I don&rsquo;t need to optimize for just because I can, and because the <em>correct</em> direction for anything having to do with work and a mobile device is toward little more than &ldquo;whatever I need to answer a management on-call page or do backup 2FA for Okta.&rdquo;</p>
<p>So as I was fussing around figuring out the useful aliases to set up for TaskWarrior I had a brief &ldquo;but how do I check tasks on my iPhone?&rdquo; thought that yielded gratifyingly quickly to &ldquo;I know there are ways, but just don&rsquo;t allow for that use case this time.&rdquo;</p>
<p>So I&rsquo;m not.</p>
<p>There&rsquo;s a tiny bit of friction in the system as a result, and I think that is fine.</p>
<p>I do some extra data entry: During the day I have a daily note with Markdown checkboxes for todos I acquire during meetings and 1:1s. I have a calendared reminder called &ldquo;clear the decks&rdquo; around five on weekdays that is my cue to sweep the tasks from my daily note into my task system, when I can think about describing them better. My notes tool has an &ldquo;unchecked box&rdquo; search I can use to make sure I haven&rsquo;t missed a stray item.</p>
<p>This afternoon&rsquo;s deck sweeping netted a few things that I shouldn&rsquo;t have written down in the first place, and a chance to catch a pattern from reviewing the day that I missed in three separate moments during the day.</p>
<p>As with any CLI tool, a certain amount of practice is in order, so I&rsquo;ve invested some time doing a lot of manual task entry just to get the basic syntax burned in. Yes, I briefly considered scripting an import, but decided to do it the hard way for the practice, so no AI-fueled moral hazard for me!</p>
<p>(While I was puttering around, I was briefly reminded of when I was a really big fan of the old <a href="https://dianne.skoll.ca/projects/remind/">Remind</a> app, too.)</p>
<p>Anyhow, it&rsquo;s been sort of interesting rewiring my brain around CLI/TUI tools the past few weeks. My sense of what it means for something to be discoverable, scannable, or legible has shifted a little as I&rsquo;ve built interfaces that suit my particular sensibility about how to be keyboard-oriented. Things that initially felt a little opaque or closed-in have begun to feel more expansive.</p>
<p>I&rsquo;ve tried to be mindful about how much time things <em>really</em> take, not just how long we&rsquo;re sort of <em>conditioned</em> to think things take, or conditioned to believe are more easy or discoverable.</p>
<p>It led to a curious iteration where I got sort of tired of dealing with Emacs as an uneasy citizen of macOS, to deciding maybe if I pared back Obsidian&rsquo;s UI a ton I&rsquo;d be happier there, to wandering into my own notes app backed by Helix, where I&rsquo;ve been able to define what is most legible and discoverable to <em>me</em>.</p>
<p>It is pretty nice to just fullscreen Helix in a kitty session, or split my notes into one <a href="https://zellij.dev">Zellij</a> pane and my tasks into another. There are some tradeoffs living that life, but it feels less cluttered.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Helix and Marksman LSP server</title>
      <link>https://mike.puddingtime.org/posts/2025-06-23-helix-and-marksman-lsp-server/</link>
      <pubDate>Mon, 23 Jun 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-06-23-helix-and-marksman-lsp-server/</guid>
      <description>&lt;p&gt;The &lt;a href=&#34;https://github.com/artempyanykh/marksman&#34;&gt;Marksman&lt;/a&gt; LSP server experience with Helix is so smooth. Given a directory of Markdown files, dropping in a blank &lt;code&gt;.marksman.toml&lt;/code&gt; or running &lt;code&gt;git init .&lt;/code&gt; puts the directory on Marksman&amp;rsquo;s radar as a thing to work with. Provided Marksman is in your path, there&amp;rsquo;s no need for additional config.&lt;/p&gt;
&lt;p&gt;Drop into insert mode, start typing wikilink brackets (&lt;code&gt;[[&lt;/code&gt;) and it invokes autocomplete on every file in the directory.&lt;/p&gt;
&lt;p&gt;Placing the cursor over a wikilink, you can use &lt;code&gt;gd&lt;/code&gt; (&lt;code&gt;go to definition&lt;/code&gt;) to open that file in a new buffer.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>The <a href="https://github.com/artempyanykh/marksman">Marksman</a> LSP server experience with Helix is so smooth. Given a directory of Markdown files, dropping in a blank <code>.marksman.toml</code> or running <code>git init .</code> puts the directory on Marksman&rsquo;s radar as a thing to work with. Provided Marksman is in your path, there&rsquo;s no need for additional config.</p>
<p>Drop into insert mode, start typing wikilink brackets (<code>[[</code>) and it invokes autocomplete on every file in the directory.</p>
<p>Placing the cursor over a wikilink, you can use <code>gd</code> (<code>go to definition</code>) to open that file in a new buffer.</p>
<p>In other Helix progress notes, I briefly had a bunch of vim keybindings set up to quit stumbling over the evil muscle memory I picked up from Doom Emacs. Over the weekend, sitting in a hotel room waiting for a concert to start, I decided I wasn&rsquo;t so proficient at vim that I should cling to it, so I got rid of them.</p>
<p>That is definitely making for a few mistakes here and there, but Helix isn&rsquo;t <em>that</em> hard to pick up.</p>
<p>Other Helix stuff I picked up:</p>
<p>You can hack in Markdown auto-increment for unordered lists and tasks by saying they&rsquo;re comments in your <code>languages.toml</code> file:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[[</span><span class="nx">language</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl"><span class="nx">name</span> <span class="p">=</span> <span class="s2">&#34;markdown&#34;</span>
</span></span><span class="line"><span class="cl"><span class="nx">comment-tokens</span> <span class="p">=</span> <span class="p">[</span><span class="s2">&#34;-&#34;</span><span class="p">,</span> <span class="s2">&#34;+&#34;</span><span class="p">,</span> <span class="s2">&#34;*&#34;</span><span class="p">,</span> <span class="s2">&#34;1.&#34;</span><span class="p">,</span> <span class="s2">&#34;&gt;&#34;</span><span class="p">,</span> <span class="s2">&#34;- [ ]&#34;</span><span class="p">]</span></span></span></code></pre></div>
<p>&hellip; and this lets me check off Markdown tasks with <code>spc x</code>:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-toml" data-lang="toml"><span class="line"><span class="cl"><span class="p">[</span><span class="nx">keys</span><span class="p">.</span><span class="nx">normal</span><span class="p">.</span><span class="s2">&#34;space&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="nx">x</span> <span class="p">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;extend_to_line_start&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;flip_selections&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;extend_to_line_end&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;extend_line&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;&#34;&#34;:pipe awk &#39;{
</span></span></span><span class="line"><span class="cl"><span class="s2">    if ($0 ~ /^- \\[ \\]/) {
</span></span></span><span class="line"><span class="cl"><span class="s2">      sub(/^- \\[ \\]/, &#34;</span><span class="nx">-</span> <span class="p">[</span><span class="nx">x</span><span class="p">]</span><span class="s2">&#34;); print;
</span></span></span><span class="line"><span class="cl"><span class="s2">    } else if ($0 ~ /^- \\[x\\]/) {
</span></span></span><span class="line"><span class="cl"><span class="s2">      sub(/^- \\[x\\]/, &#34;</span><span class="nx">-</span> <span class="p">[</span> <span class="p">]</span><span class="s2">&#34;); print;
</span></span></span><span class="line"><span class="cl"><span class="s2">    } else if ($0 ~ /^- /) {
</span></span></span><span class="line"><span class="cl"><span class="s2">      sub(/^- /, &#34;</span><span class="nx">-</span> <span class="p">[</span> <span class="p">]</span> <span class="s2">&#34;); print;
</span></span></span><span class="line"><span class="cl"><span class="s2">    } else {
</span></span></span><span class="line"><span class="cl"><span class="s2">      print &#34;</span><span class="nx">-</span> <span class="p">[</span> <span class="p">]</span> <span class="s2">&#34; $0;
</span></span></span><span class="line"><span class="cl"><span class="s2">    }
</span></span></span><span class="line"><span class="cl"><span class="s2">  }&#39;&#34;&#34;&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;goto_first_nonwhitespace&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;collapse_selection&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;move_line_down&#34;</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span></span></span></code></pre></div>
<p>When I kick off the day with a daily note I like to check whatever I&rsquo;m using for tasks to figure out the most pressing stuff, and it goes into a checklist where it&rsquo;s not an official todo, just a priority I&rsquo;ll keep seeing as I go in and out of the daily note to log stuff during the day.</p>
<p>It is a little disorienting to have a full-featured editor that launches so quickly without worrying about daemonizing it. I mean, micro is pretty full-featured and has some nice plugins, but at some point evil-mode won me over to modal editing and micro doesn&rsquo;t do that. It&rsquo;s got a remarkably flexible keymapping system, but not so flexible that you can go modal with it.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Integrating notes and contacts</title>
      <link>https://mike.puddingtime.org/posts/2025-06-20-integrating-notes-and-contacts/</link>
      <pubDate>Fri, 20 Jun 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-06-20-integrating-notes-and-contacts/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been plugging away at another TUI app, &lt;a href=&#34;https://github.com/pdxmph/notes-tui&#34;&gt;this time for notes&lt;/a&gt;. It&amp;rsquo;s very much in line with the thing I was trying to do with bash and fzf, but instead in Go. Right now:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fast search for notes in either a configured directory or one named on the command line&lt;/li&gt;
&lt;li&gt;Tag search, either in-line (&lt;code&gt;#tag&lt;/code&gt;) or in YAML frontmatter&lt;/li&gt;
&lt;li&gt;Open to-do search&lt;/li&gt;
&lt;li&gt;Hotkey to make a daily note of a given format&lt;/li&gt;
&lt;li&gt;Alternate note template. If you see the point in YAML frontmatter, it&amp;rsquo;ll do that. If you prefer &amp;ldquo;l1 heading from the title&amp;rdquo; it&amp;rsquo;ll do that.&lt;/li&gt;
&lt;li&gt;It does a very basic sort of Markdown rendering on its own for note preview, or you can configure it to shell out to bat, glow, etc. I am using glow because it has an option to edit a file under preview.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It works really well with Helix or other LSP-aware editors, because you can add the &lt;a href=&#34;https://github.com/artempyanykh/marksman&#34;&gt;Marksman&lt;/a&gt; LSP server and have your own connected notes system with wiki-linking without having to adopt another app, like Obsidian, if you don&amp;rsquo;t want that whole ride.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I&rsquo;ve been plugging away at another TUI app, <a href="https://github.com/pdxmph/notes-tui">this time for notes</a>. It&rsquo;s very much in line with the thing I was trying to do with bash and fzf, but instead in Go. Right now:</p>
<ul>
<li>Fast search for notes in either a configured directory or one named on the command line</li>
<li>Tag search, either in-line (<code>#tag</code>) or in YAML frontmatter</li>
<li>Open to-do search</li>
<li>Hotkey to make a daily note of a given format</li>
<li>Alternate note template. If you see the point in YAML frontmatter, it&rsquo;ll do that. If you prefer &ldquo;l1 heading from the title&rdquo; it&rsquo;ll do that.</li>
<li>It does a very basic sort of Markdown rendering on its own for note preview, or you can configure it to shell out to bat, glow, etc. I am using glow because it has an option to edit a file under preview.</li>
</ul>
<p>It works really well with Helix or other LSP-aware editors, because you can add the <a href="https://github.com/artempyanykh/marksman">Marksman</a> LSP server and have your own connected notes system with wiki-linking without having to adopt another app, like Obsidian, if you don&rsquo;t want that whole ride.</p>
<p>This morning I realized there is an opportunity to integrate it with <a href="https://github.com/pdxmph/contacts-tui">contacts-tui</a> via tag searching, so I added a command line switch to search for a tag and launch with that tag search: <code>notes-tui --tag=@label</code>. On the <code>contacts-tui</code> side, I added a command to launch that search by tapping <code>O</code> on a selected contact.</p>
<p>Launching that tag search from contacts-tui, I end up in the notes app with all the related notes for that contact in view. I can cursor around, read the notes, etc. and when I <code>ESC</code> out of the notes app, I&rsquo;m back at the contact record in the contacts app. Tap <code>t</code> and I get a list of open tasks for that contact in TaskWarrior, Things, or dstask.</p>
<p>Or do none of that, because both tools work fine on their own.</p>
<p>It kinda gives me the idea to move contacts out of its sqlite backend and just move to plaintext serializing for contact info, with ripgrep to manage contact search.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Helix</title>
      <link>https://mike.puddingtime.org/posts/2025-06-19-helix/</link>
      <pubDate>Thu, 19 Jun 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-06-19-helix/</guid>
      <description>&lt;p&gt;I had insomnia a few nights ago, so I started fiddling with different things, including the CLI tasks tool dstask, which is sort of TaskWarrior without the misanthropy. (I kid.)&lt;/p&gt;
&lt;p&gt;So a kind of nice thing about dstask is that with &lt;code&gt;dstask #{note number} note&lt;/code&gt; you pop open $EDITOR in a Markdown note attached to the task. dstask is aware of any Markdown checklists inside the task note and blocks completion of the task if there are open ones.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I had insomnia a few nights ago, so I started fiddling with different things, including the CLI tasks tool dstask, which is sort of TaskWarrior without the misanthropy. (I kid.)</p>
<p>So a kind of nice thing about dstask is that with <code>dstask #{note number} note</code> you pop open $EDITOR in a Markdown note attached to the task. dstask is aware of any Markdown checklists inside the task note and blocks completion of the task if there are open ones.</p>
<p>That&rsquo;s maybe bad for me because I am a compulsive subtask-maker with a bad habit of opening a task, loading the subtasks into my buffer, and just doing them all without looking back. So if I stick with it dstask may shape my habits that way.</p>
<p>For some annoying reason, dstask also barfs if <code>$EDITOR</code> has an argument, e.g. <code>emacsclient -nw</code>, and I found myself once again writing some kind of wrapper for emacsclient. That is not Emacs&rsquo; fault, but it raised the perennial question &ldquo;when does $EDITOR come into play and do you need a whole-ass Emacs config for those times?&rdquo;</p>
<p>So I think &ldquo;your go-to for this used to be jed, which acts like Emacs where it matters.&rdquo; But I&rsquo;ve been using evil in Emacs for years now: If I want to keep my muscle memory between quick CLI edits and my whole-ass Emacs config, what I really need is something from the <code>vi</code> family.</p>
<p>It being 3 in the morning, I embark on a tour of modern vi&rsquo;s, looking for some sweet spot of &ldquo;nimble&rdquo; and &ldquo;feature-packed.&rdquo; I burn through a few neovim tutorials and starter kits (nooooooope) before stumbling into a feud between neovim people and Helix people on reddit.</p>
<p>So around 4 I&rsquo;m running <code>brew install helix</code> and going through <code>:tutorial</code>.</p>
<p>It&rsquo;s pretty nice! It launches quickly. No plugin system so the futzmonkey sort of has to stay in its cage, but it&rsquo;s very batteries-included. I found a <a href="https://helix-editor-tutorials.com/tutorials/writing-documentation-and-prose-in-markdown-using-helix/">tutorial for setting it up for Markdown</a> that wasn&rsquo;t overwhelming and helped me get a sense of how its config works.</p>
<p>It is <em>not</em> &ldquo;just a batteries included vim.&rdquo; It has its own keybinding grammar (subject/verb, not verb/subject), so after bonking my head on those changes a few times I <a href="https://github.com/LGUG2Z/helix-vim/blob/master/config.toml">cheated</a> and lifted a few vimisms.</p>
<p>I guess I also went through a quick consideration of micro, but the CUA-style default keybindings confused me the way nano often confuses me.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Integrating task trackers with contacts-tui</title>
      <link>https://mike.puddingtime.org/posts/2025-06-18-integrating-task-trackers-with-contacts-tui/</link>
      <pubDate>Wed, 18 Jun 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-06-18-integrating-task-trackers-with-contacts-tui/</guid>
      <description>&lt;p&gt;One of the best parts of my org-contacts setup was that when I moved a contact into a given state (followup, call, write, etc.) it&amp;rsquo;d become a task in my org agenda, along with all my other todos.&lt;/p&gt;
&lt;p&gt;I added integrations with TaskWarrior, dstask, and Things to contacts-tui this evening:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Put a contact in a given state, the tasks backend creates a todo in your configured tracker with that contact&amp;rsquo;s label as a tag.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>One of the best parts of my org-contacts setup was that when I moved a contact into a given state (followup, call, write, etc.) it&rsquo;d become a task in my org agenda, along with all my other todos.</p>
<p>I added integrations with TaskWarrior, dstask, and Things to contacts-tui this evening:</p>
<ul>
<li>
<p>Put a contact in a given state, the tasks backend creates a todo in your configured tracker with that contact&rsquo;s label as a tag.</p>
</li>
<li>
<p>The task view on each contact includes tasks with their contact tag. You can close them out from within contacts-tui with a note.</p>
</li>
</ul>
<p>This bridges the gap between contacts-tui and my todos, which is pretty important to me: If I want to be good at keeping up connections, I need the reinforcement that this is a thing as meaningful to me as any other thing I&rsquo;m willing to commit to a tracker.</p>
<p>The connection isn&rsquo;t truly bidirectional: If I close a task in contacts-tui, it&rsquo;s closed in the tracker. If I close a task in the tracker, it&rsquo;s still open in contacts-tui, but there&rsquo;s some incentive to just close it out there: When you do, you can include a quick note about the call, email exchange, followups, etc. to keep the system up to date. (The note you enter in contacts-tui gets added to the Things note when it closes, so you keep the information both places, fwiw.)</p>
<p>The task backends are pretty modular and follow a simple pattern with just three calls (make, find, close), so just about any CLI task tool or scriptable tool could have a backend.</p>
<p>I started with TaskWarrior last night out of curiosity. I&rsquo;ve never really warmed up to it but it&rsquo;s sorta the big CLI task tool. I like <a href="https://github.com/naggie/dstask">dstask</a> a little better and learned how to use it through a bout of insomnia last night. But cold light of day thinking told me that when I go on these CLI kicks for productivity tools they don&rsquo;t usually last, so I added Things support as the realist option.</p>
<p><a href="https://github.com/pdxmph/contacts-tui/releases/tag/v0.5.0">v0.5.0</a> has all the new stuff.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Contacts management in a TUI</title>
      <link>https://mike.puddingtime.org/posts/2025-06-17-contacts-management-in-a-tui/</link>
      <pubDate>Tue, 17 Jun 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-06-17-contacts-management-in-a-tui/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://live.staticflickr.com/65535/54595512292_cf719d7c1e_b.jpg&#34; alt=&#34;Contacts TUI screenshot&#34;&gt;&lt;/p&gt;
&lt;p&gt;I haven&amp;rsquo;t really liked social networking as a development. Sometimes I&amp;rsquo;d even say I mourn its existence. I used to have people with whom I shared a great email correspondence who abandoned that in favor of the Eternal Holiday Newsletter mode of Facebook, or the &amp;ldquo;oh, I tweeted about it last week if you want to look it up&amp;rdquo; of the assorted microblogging services.&lt;/p&gt;
&lt;p&gt;The kind of conversation we can have at a BBQ you invited your high school friends to is different from the one we can have over coffee. The kinds of things I&amp;rsquo;d say to you on my front porch might even be different from what I&amp;rsquo;d say at the cafe.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://live.staticflickr.com/65535/54595512292_cf719d7c1e_b.jpg" alt="Contacts TUI screenshot"></p>
<p>I haven&rsquo;t really liked social networking as a development. Sometimes I&rsquo;d even say I mourn its existence. I used to have people with whom I shared a great email correspondence who abandoned that in favor of the Eternal Holiday Newsletter mode of Facebook, or the &ldquo;oh, I tweeted about it last week if you want to look it up&rdquo; of the assorted microblogging services.</p>
<p>The kind of conversation we can have at a BBQ you invited your high school friends to is different from the one we can have over coffee. The kinds of things I&rsquo;d say to you on my front porch might even be different from what I&rsquo;d say at the cafe.</p>
<p>So the net effect has been to have a higher volume of very lossy connections at the cost of some very meaningful and higher-fidelity connections.</p>
<p>As I get older, that has gone from something I don&rsquo;t like to something I feel very concerned about. Alison is constantly on me to stretch before and after our morning runs because she&rsquo;s right: I do not have the body that once came off a six-week layoff from a parachuting injury to run in the Ft. Bragg 10-Miler the first day I was allowed to run again. Likewise, as much as I have a few habits of thought I try to cultivate to keep from turning completely inward sometimes, there are some parts of the world that don&rsquo;t become <em>more</em> comfortable to deal with as we age. Some days, my reaction to whatever is going on out there is to wish people would just shut the fuck up about it. I think that&rsquo;s a fair, reasonable, understandable reaction, but I also think that&rsquo;s not a great place to go live.</p>
<p>As much as I&rsquo;m introverted, politely contrarian, and completely over some of the fucking takes I&rsquo;m reading, I have to stretch. As much as there are some people I&rsquo;d love to hear more and different from, at some point you just have to acknowledge that for whatever reason, those vibrant email threads petered out and are not coming back, so you have to replenish the supply of human connection.</p>
<p>During my unplanned sabbatical a couple of years ago, I realized I was going to need to settle in for a few months of being at loose ends while I figured out what was next and started to drum up opportunities. I knew I needed to network, and I also knew I needed to just interact with people. Left to my own devices, and without a plan, I knew I&rsquo;d just go full introvert and I didn&rsquo;t want to go full introvert.</p>
<p>So I set about leveraging org-contacts to build what I called the <a href="https://gist.github.com/pdxmph/c24471962cdf18e4b781718944073a12">plaintext CRM</a>: A bunch of functions that made it easier to keep in touch with people. The core ideas were:</p>
<ul>
<li>Different kinds of relationships need different kinds of attention</li>
<li>It&rsquo;s easy to lose track of a thread, so it helps to have some workflow management when you reach out to someone</li>
<li>It&rsquo;d be nice to have a log of contacts so you could remember where you left off</li>
<li>It&rsquo;d be nice to integrate this with org-mode so ticklers to ping people or follow up, or just mark a contact &ldquo;timed out&rdquo; would show up in my agenda each day.</li>
</ul>
<p>I used it for plain old social stuff during my layoff, and also to track recruiter pings. It helped me feel (and behave) a lot less transactionally about reaching out to people, because while I did have a small pitchfork at my back to get out and network, it reminded me to follow up on social stuff as well.</p>
<p>It was a good system for where I was at, because I was living in Emacs, it was sort of a fun and stunty layoff project to implement something like that in Emacs, and I was able to stick to it because it was right there in my todo system.</p>
<p>Usage fell off once I was back at work and got busy again, which has bothered me on and off for a while now.</p>
<p>Several weeks ago, I fed the elisp to Claude as a proof of concept for an MCP. The repo for that is private because I did put it into production for a period and the security studies on MCP are a little dire. They&rsquo;re just modulations on common security issues other protocols can present, but I&rsquo;m not gonna lay bare my vibe-coded contact management infra.</p>
<p>The MCP itself worked as well as a chat-based interface can, and did what a lot of AI stuff does these days: Points to something that is both pretty cool and simply not there yet.</p>
<p>The pretty cool part was making Claude aware of my contacts database and the state of contact with everyone in it. During day-planning, I had it set up to check in on the state of contacts and drop a few pings, followups, or calls into my calendar for the day. That was a small proof of concept for MCPs as a kind of executive assistant.</p>
<p>The parts that were not there yet:</p>
<ul>
<li>It&rsquo;s a slow interface. An MCP is just API calls, which are fast enough over a local network and hitting a sqlite db, but there&rsquo;s some overhead to get an LLM to invoke the tool, interpret the results, and do something with them.</li>
<li>It&rsquo;s a lossy interface. I spent a few iterations tuning instructions to get Claude to do the right thing with certain language, but there was still an element of the <a href="https://puddingtime.org/the-one-armed-bandit">one-armed bandit effect</a>: Make a comment the wrong way, and Claude would add to a contact&rsquo;s note instead of recording an interaction, for instance.</li>
<li>It&rsquo;s an opaque interface. Some of the better MCPs include some kind of CLI component so you can directly manage their state. I was stuck with telling Claude to change this or that thing once I realized it had done something I didn&rsquo;t like &ndash; a whole lost several minutes to &ldquo;show me what you did; change what you did; no not that way &ndash; this way.&rdquo;</li>
<li>It&rsquo;s a bad idea to let an LLM near this kind of information.</li>
</ul>
<p>On that last point:</p>
<p>You see people advertising their MCPs as &ldquo;running locally and completely in your control.&rdquo; Well, okay, but what the LLM is doing with that data is not completely in your control. What the LLM&rsquo;s owner is doing with that data is not completely in your control. And for a homebrew sort of hobby implementation of a new protocol in a fast-moving technology, you&rsquo;re assuming extra risk.</p>
<p>Second, I&rsquo;m just curious, not completely obtuse. I want to learn about these things &ndash; work actually <em>requires</em> me to learn about these things &ndash; but there are people with heartfelt, sincere, thought-through objections to the AI industry whom I know would not like that even innocuous data about them is being fed into an LLM maw. I&rsquo;m sorry I picked a project that involved that. I stopped at &ldquo;actual need and well-understood problem&rdquo; and didn&rsquo;t think past that.</p>
<p>So I took the MCP down, which left me a little frustrated: I really did not want to go back to managing contacts in Emacs, and I really do not like any of the alternatives I&rsquo;ve found for contact management: Finding the sweet spot of actually managing contact information and also managing the workflow of interacting with contacts has been a little hard.</p>
<p>So I teed up one last session with Claude to use the existing MCP workflows, data structures, and actions and turned them into a Go TUI that just repurposed my existing sqlite-hosted data into a database on my local disk. It does pretty much what my original elisp implementation does, but it&rsquo;s written in Go so it&rsquo;s a compact binary (and Claude is sort of a Go prodigy compared to experiments in Typsecript, Ruby, and bash).</p>
<p>I&rsquo;m pretty happy with what I got:</p>
<ul>
<li>It&rsquo;s fast.</li>
<li>It does all the contact lifecycle stuff I used to do in Emacs.</li>
<li>It adds the ability to define a custom cadence and style for some individuals, because there are folks you don&rsquo;t need to reach out to much but if you see they had a nice life event or career development, it&rsquo;s good to drop in a reminder to ping them with congratulations (or condolences).</li>
<li>It has hot keys for most interactions, so there&rsquo;s not a lot of cursoring around the interface.</li>
<li>It has some nice state-setting and filtering hot keys: Quick to find overdue contacts, filter down to family, friends, or professional network.</li>
<li>It has archiving, so for that one recruiter from a few years ago at the place you walked away from, you can get them out of the contact management cadence but keep the context for later, just in case.</li>
<li>It&rsquo;s completely local and un-networked. Not only is everyone&rsquo;s data not going into the LLM maw, it&rsquo;s not getting sucked in by anyone else trying to build their graph on your friends&rsquo; data.</li>
</ul>
<p>This version is publicly available and pretty easy to build and install on a Mac, at least:</p>
<p><a href="https://github.com/pdxmph/contacts-tui">pdxmph/contacts-tui</a></p>
<p>There are a few features mentioned in the docs for creating a fixtures db you can kick the tires with, or just onboard with a blank db and start using it. There is no contact import tooling. Given the simplicity of the sqlite backend, it&rsquo;d be pretty easy to lash up a CSV importer, and iirc it is not terribly hard to write some AppleScript to do that from the Contacts app or from a format like VCF.</p>
<p>I&rsquo;m not sure it solves anything for anyone else the way they&rsquo;d like, but it hits an intersection that&rsquo;s useful to me by creating structure to be better at something I often neglect and wish I did better.</p>
]]></content:encoded>
    </item>
    <item>
      <title>The One-Armed Bandit</title>
      <link>https://mike.puddingtime.org/posts/2025-06-14-the-one-armed-bandit/</link>
      <pubDate>Sat, 14 Jun 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-06-14-the-one-armed-bandit/</guid>
      <description>&lt;p&gt;Well, I&amp;rsquo;ve spent a few weeks now playing around with Claude on two projects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;An MCP for Remember the Milk&lt;/li&gt;
&lt;li&gt;An MCP for contacts management&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I haven&amp;rsquo;t read a lot of commentary on how to code with AI, and I&amp;rsquo;ll say a little more on the kind of AI-related commentary I &lt;em&gt;have&lt;/em&gt; read in a bit. Instead, I just let myself stumble into the challenges and try to figure out my way around them. The biggest ones were:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Well, I&rsquo;ve spent a few weeks now playing around with Claude on two projects:</p>
<ul>
<li>An MCP for Remember the Milk</li>
<li>An MCP for contacts management</li>
</ul>
<p>I haven&rsquo;t read a lot of commentary on how to code with AI, and I&rsquo;ll say a little more on the kind of AI-related commentary I <em>have</em> read in a bit. Instead, I just let myself stumble into the challenges and try to figure out my way around them. The biggest ones were:</p>
<ul>
<li>Session length. Once either project got into complexity, the amount of progress I could make in a session slowed down. Claude would end conversations for going on too long in the middle of a debugging session, and all the context would get dumped.</li>
<li>Context preservation. If you have to chain together a series of sessions to get one feature done, then you need some way for Claude to remember what it was up to.</li>
<li>&ldquo;Behavioral.&rdquo; Sometimes Claude does dumb or misguided things. Describing them would be as fun for you as making you listen to me talk about a dream I had, so I won&rsquo;t.</li>
</ul>
<p>So as I&rsquo;d pick up on a problem, I&rsquo;d look for a way to address it, and largely landed on:</p>
<ul>
<li>User preferences that stress collaborative testing, step-by-step examination of a problem, and limited ability to move on until the user has said it&rsquo;s okay to move on.</li>
<li>Specific project instructions that explain what the sources of truth are, where the local code lives, how to go about selecting what to work on, and further reinforcement that we don&rsquo;t write scripts to test scripts that test the code, etc.</li>
<li>Reliance on continuity tools of some kind.
<ul>
<li>Markdown notes of what it has gotten done so far, what it needs to know to return to work on a problem, etc.</li>
<li>Continutity notes in GitHub issues, so it can pull the original issue, then record and catch up on its own progress with comments on the issue.</li>
</ul>
</li>
<li>Remembering to explicitly dig out API docs and include them in the prompt with little nudges: &ldquo;I see a parameter asking for a location id &hellip;&rdquo;</li>
<li>Continuity prompts: &ldquo;You were doing this, you recorded progress here, as always you can read about this entire project here.&rdquo;</li>
</ul>
<p>Luke sent me <a href="https://ferd.ca/the-gap-through-which-we-praise-the-machine.html">an article that very thoughtfully dissected this process</a>:</p>
<blockquote>
<p>&ldquo;&hellip; the people I’ve seen most excited and effective about agentic work were deeply involved in constantly correcting and recognizing bugs or loops or dead ends the agent was getting into, steering them away from it, while also adding a bunch of technical safeguards and markers to projects to try and make the agents more effective. When willingly withholding these efforts, their agents’ token costs would double as they kept growing their context windows through repeating the same dead-end patterns; oddities and references to non-existing code would accumulate, and the agents would increasingly do unhinged stuff like removing tests they wrote but could no longer pass.</p>
</blockquote>
<blockquote>
<p>&ldquo;I’ve seen people take the blame for that erratic behavior on themselves (&lsquo;oh I should have prompted in <em>that</em> way instead, my bad&rsquo;), while others would just call out the agent for being stupid or useless.&rdquo;</p>
</blockquote>
<p>&hellip; then turned it around:</p>
<blockquote>
<p>&ldquo;It may sound demeaning, like I’m implying people lack awareness of their own processes, but it absolutely isn’t. The process of adaptation is often not obvious, even to the people doing it. There are lots of strategies and patterns and behaviors people pick up or develop tacitly as a part of trying to meet goals. Cognitive work that gets deeply ingrained sometimes just feels effortless, natural, and obvious. Unless you’re constantly interacting with newcomers, you forget what you take for granted—you just know what you know and get results.&rdquo;</p>
</blockquote>
<blockquote>
<p>&ldquo;By extension, my supposition is that those who won’t internalize the idiosyncrasies and the motions of doing the scaffolding work are disappointed far more quickly: they may provide more assistance to the agent than the agent provides to them, and this is seen as the AI failing to improve their usual workflow and to deliver on the wonders advertised by its makers.&rdquo;</p>
</blockquote>
<p>Phil Agre <a href="https://pages.gseis.ucla.edu/faculty/agre/how-to-help.html">wrote about this</a> years ago: &ldquo;Most user interfaces are terrible. When people make mistakes it&rsquo;s usually the fault of the interface. You&rsquo;ve forgotten how many ways you&rsquo;ve learned to adapt to bad interfaces.&rdquo;</p>
<p>Both the contacts MCP and the Remember the Milk MCP were easy assignments: The contacts MCP just keeps a sqlite database and operates under some rules about when to nudge the user to check in on a contact and what to do when the user reports a contact. The RTM MCP takes advantage of a comprehensive, mostly straightforward API, mapping each tool to an endpoint with a pretty obvious purpose.</p>
<p>I won&rsquo;t go into a ton of detail about the bad derails that still happened. The content of those derails is less the point than the simple fact that over a couple of weeks of evolving a pretty elaborate set of rituals to avoid memory issues, session length issues, and behavioral issues, there was still always a nagging sense of &ldquo;when will this go wrong and how?&rdquo;</p>
<p>For instance, the underlying Claude service itself is flakey. After a while I&rsquo;d developed a pretty good sense of when a conversation was going long, but every now and then I&rsquo;d get two or three messages into one &ndash; right at the point where the furniture had been rearranged in some function &ndash; and get a session length error. There went the context <em>and</em> all the sources of truth were out of sync with the code base.</p>
<p>Or it&rsquo;d report writing the continuity note but truncate it. Or, or, or.</p>
<p>A boss of mine once said about an early scripting effort of mine, &ldquo;it&rsquo;s not that the bear dances well, but that it dances at all.&rdquo;</p>
<p>That&rsquo;s sort of where I&rsquo;m at. In the end, I agree with this:</p>
<blockquote>
<p>&ldquo;&hellip; what is imagined is powerful agents who replace engineers (at least junior ones), make everyone more productive, and that will be a total game changer. LLMs are artifacts. The scaffolding we put in place to control them are how we try to transform the artifacts into tools; the learning we do to get better at prompting and interacting with the LLMs is part of how they transform us. If what we have to do to be productive with LLMs is to add a lot of scaffolding and invest effort to gain important but poorly defined skills, we should be able to assume that what we’re sold and what we get are rather different things.&rdquo;</p>
</blockquote>
<blockquote>
<p>&ldquo;That gap implies that better designed artifacts could have better affordances, and be more appropriate to the task at hand. They would be easier to turn into productive tools. A narrow gap means fewer adaptations are required, and a wider gap implies more of them are needed.</p>
</blockquote>
<blockquote>
<p>&ldquo;Flipping it around, we have to ask whether the amount of scaffolding and skill required by coding agents is acceptable. If we think it is, then our agent workflows are on the right track. If we’re a bit baffled by all that’s needed to make it work well, we may rightfully suspect that we’re not being sold the right stuff, or at least stuff with the right design.&rdquo;</p>
</blockquote>
<p>&hellip; because as I painstakingly evolved my &ldquo;get working code out of this thing&rdquo; workflow, there were two things on my mind:</p>
<ul>
<li>Learning how to write all this for myself would keep me from having the tool I&rsquo;ve imagined any time soon.</li>
<li>If I&rsquo;m sitting here in my living room working through this process with these readily identified limitations, other people who are starting from a place of more sophistication and more ability to do the meta-work of hiding all this tool-building I&rsquo;m doing will probably be getting on that. In fact, they are. I added an MCP called &ldquo;vibe check&rdquo; that arrested a few spinouts before they happened by making the LLM ask what its original prompt was before it does anything. The number of memory persistence MCPs is growing.</li>
</ul>
<p>On that latter bullet, I guess this puts me on the vaguely optimistic side about all this: My Brompton is a <em>great</em> implementation of a bike. Penny Farthing bikes are &ndash; given all we know <em>today</em> &ndash; a <em>terrible</em> implementation of a bike. If I tried to do an eight-mile ride downtown on a Penny Farthing bike, I&rsquo;d say &ldquo;bikes don&rsquo;t work for commuting shortish distances.&rdquo; With the Brompton, on the other hand, the gearing is excellent and does a lot to offset those 16&rdquo; wheels. It&rsquo;s <em>fine</em> for six or eight miles. Given the kind of Schwinn I had in grade school, with a banana seat, a big lever for a shifter, and high handle bars for that cool chopper look, I&rsquo;d probably say &ldquo;bikes aren&rsquo;t great for commuting medium distances, but are fine for a spin around the neighborhood, and I can see how a few design changes could make them better.&rdquo;</p>
<p>The metaphor breaks down quickly the second you shift out of &ldquo;does it work&rdquo; questions and move into asking &ldquo;what is the return given the consumption of resources?&rdquo; whether that&rsquo;s electricity, water, developer hours lost to correcting spinouts, support tickets, or the human toll of inevitable misapplications at all levels of society.</p>
<h2 id="the-one-armed-bandit">The one-armed bandit</h2>
<p>So, I&rsquo;m glad to be sitting here writing instead of sitting on top of Claude, waiting for it to invent a non-existent API call, forget that a given parameter is an id and not a string, crash and burn with a partially edited private function I hadn&rsquo;t realized was in there, or take it upon itself to push a broken image into production.</p>
<p>My two MCPs work pretty well, harmonizing with each other the way I hoped they would, giving me a conversational interface into personal planning that does a good job of &ldquo;remembering&rdquo; stuff and getting it back in front of me when I need it to. Claude itself has written READMEs that vastly oversell what it is accomplishing, because it has never met a project it has worked on with anything other than intimations of brilliance and completeness.</p>
<p>I had a good experience working on these things in a few ways. I got working tools, learned a bit more about what the tech is good for and not, and just as I was deep in the process, MCPs flared up as a security topic at work. It was very, very useful to be able to listen patiently, knowing something about how these things work, and have a useful opinion or two about how to characterize the risk they pose.</p>
<p>During this period, there was no avoiding The AI Discourse, and that was less fun. The discursive environment is up to the same shit it is with everything, and my deep annoyance with rhetorical moves that involve psychologizing people with whom we disagree has found no relief.</p>
<p>But for as much as the experience was edifying and interesting, the image that kept coming to mind was a slot machine, or a video poker game.</p>
<p>I once ended work early during a week in Las Vegas, gave myself an allowance to try gambling, and had a pretty terrible experience with it all. Years later I read that humans are succeptible to gambling addiction because we&rsquo;re very inclined to seek patterns, and very inclined to misinterpret things as patterns, and easily unhinged by rewards we believe we can unlock if we just figure out the pattern.</p>
<p>If you&rsquo;ve never gambled but have sat up all night trying to beat that one boss, getting worse and worse at it as you get more and more tired and frustrated, that&rsquo;s sort of how a bad session with Claude felt, because yes, these things &ldquo;work,&rdquo; but for particular definitions of &ldquo;work&rdquo; that have to include the derails, setbacks, workarounds, constant vigilance, and ever-present awareness that Anthropic, OpenAI, Google, or whichever could twist some tuning screw down in the clockwork and alter the thing&rsquo;s operating model in a way that throws it all out of sync, creating more digressions to unwind.</p>
<p>In the end, that level of engagement with the toolmaking tool to get the tools I was trying to make was sort of exhausting. I kept thinking of Bill Murray in <em>Groundhog Day</em>, waking up every morning to Sonny and Cher, wondering how far I&rsquo;d make it.</p>
<p>Funny enough, Claude itself sort of pointed that out to me, because a few weeks ago I added something to my user preferences called &ldquo;Focus Guardian,&rdquo; which is a set of directives to catch me spiraling on stuff that is not what I want to spend my time on. Diving into yet another session to add just one more feature, with all the uncertainty of whether it&rsquo;d be a quick walk in the park or a long slog, the focus guardian protocol kicked in and asked &ldquo;are you doing this because it furthers one of the things that brings you joy or because you&rsquo;re curious about some new tool or over-optimizing? Is there a writing project you could tackle instead?&rdquo;</p>
<p>I guess AI &ldquo;works.&rdquo;</p>
]]></content:encoded>
    </item>
    <item>
      <title>Remember the Milk MCP</title>
      <link>https://mike.puddingtime.org/posts/2025-06-07-remember-the-milk-mcp/</link>
      <pubDate>Sat, 07 Jun 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-06-07-remember-the-milk-mcp/</guid>
      <description>&lt;p&gt;I have a lot of todos and a lot of meetings. I hate playing task/calendar Tetris. Sometimes my task list gets way out in front of my calendar. I got pretty curious about &amp;ldquo;what is an MCP and how do they work?&amp;rdquo; So this morning, when I woke up early anyhow, I set about to work with Claude to make a Remember the Milk MCP using some stuff I learned from making imgup.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I have a lot of todos and a lot of meetings. I hate playing task/calendar Tetris. Sometimes my task list gets way out in front of my calendar. I got pretty curious about &ldquo;what is an MCP and how do they work?&rdquo; So this morning, when I woke up early anyhow, I set about to work with Claude to make a Remember the Milk MCP using some stuff I learned from making imgup.</p>
<p>I set a goal of getting enough functionality in the MCP right away to start using the MCP to help manage development by keeping the project backlog in it.</p>
<p>And my long-term (for as long-term as &ldquo;get this done before lunch&rdquo; can be) goal was &ldquo;get this into a place where I can use Claude&rsquo;s connection to my calendar and RTM to do a planning session.&rdquo;</p>
<p>A couple of things went well, a couple of things did not:</p>
<p>I did a test implementation of an MCP for Things last night. It went really quickly because the Things scripting API is pretty simple overall, until it didn&rsquo;t go quickly because there are blind spots in either the Apple Events (Applescript/JXA) or URL scheme APIs. But a lot of time was eaten up by the fact that Applescript APIs are a bit more opaque to Claude than a published API. RTM on the other hand, has a pretty thoroughly documented one that Claude was able to grok in one shot most of the time.</p>
<p>I set aside the Things implementation because RTM is, overall, a more feature-complete tool, and its mental model is a bit more like mine. I think when I got to the part of the Things doc about prioritization that read sort of like a climb-down from an orthodox position, I felt a little impatient.</p>
<p>So, getting the foundations layed in for RTM worked well.</p>
<p>At one point, my very methodical approach to keeping project context intact worked against me, because I let Claude pick what to work on next and it rabbitholed on something it had done, but hadn&rsquo;t marked as done in the project todos, because I have pretty rigid Project Instructions to keep things focused on preserving context. It managed to exhaust its chat length spinning out, left some half-complete work in place, and it took a lot of screwing around to sort out the damage.</p>
<p>At one point mid-morning the Claude API started getting irritable and dumped a few chats mid-session. I downshifted from Opus to Sonnet and that helped it move faster, but at the expense of having to get very controlling about its test cycle and occasionally needing to go look up API calls and explain them to it.</p>
<p>But by lunch time it was pretty far along. Far enough along that I set up Project Instructions for a personal organization project that:</p>
<ul>
<li>Allows Claude to work with my Google calendar and RTM to examine priorities and figure out good start times given my time estimates</li>
<li>Catch when people, tasks, and meetings intersect, flagging those for a daily note</li>
<li>Create Markdown project notes out of projects I have it create in RTM so I&rsquo;ve got a place to hold more context</li>
<li>Reprioritize, defer, flag, and remove assorted tasks</li>
</ul>
<p>I&rsquo;ve tried a few variants of this kind of workflow over the past month with different tools and approaches, and this is the most fluid I&rsquo;ve managed to get it, combining calendar access, a todo app, and an LLM with structured guardrails on what goes where and what does what.</p>
<p>In the background, I&rsquo;ve woken my <a href="https://gist.github.com/pdxmph/c24471962cdf18e4b781718944073a12">plaintext people relationship manager idea</a> back up, because once I realized MCPs are not the most complex things on the planet, and that I&rsquo;ve got a working way to talk to an LLM about things I need to do, it&rsquo;d be pretty simple to move the contact management workflow into sqlite for state, and delegate the contact workflow to whatever task backend I want to use. The last time I came at this idea I felt pretty sharply at odds with other peoples&rsquo; ideas of what a good contact manager on the Mac is for what I want to keep track of.</p>
<p>Anyhow, <a href="https://github.com/pdxmph/rtm-mcp">here&rsquo;s the MCP</a>. Just a hunk of Ruby with a script-driven OAuth onboarding workflow. I mean to just live with it for a while and see how it goes.</p>
]]></content:encoded>
    </item>
    <item>
      <title>imgup v0.12.0 (flipping the script)</title>
      <link>https://mike.puddingtime.org/posts/2025-06-05-imgup-v0120-flipping-the-script/</link>
      <pubDate>Thu, 05 Jun 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-06-05-imgup-v0120-flipping-the-script/</guid>
      <description>&lt;p&gt;One of my bigger annoyances with Lightroom CC is how magestically indifferent it is to anything a normal human being using a Mac in 2025 might want to with it in the way of sharing your pictures. It is a literal void on the desktop: AppleScript? lol. Even the standard macOS share sheet? Nope. You can export out to disk, and you can share things to Adobe&amp;rsquo;s own services. If you want more extensibility or flexibility well, go use Lightroom Classic.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>One of my bigger annoyances with Lightroom CC is how magestically indifferent it is to anything a normal human being using a Mac in 2025 might want to with it in the way of sharing your pictures. It is a literal void on the desktop: AppleScript? lol. Even the standard macOS share sheet? Nope. You can export out to disk, and you can share things to Adobe&rsquo;s own services. If you want more extensibility or flexibility well, go use Lightroom Classic.</p>
<p>LR CC does offer one out, though: It has this idea of &ldquo;Connections,&rdquo; of which there are very few. One of them happens to be SmugMug. So as I ponder whether I want to stick with Lightroom as my DAM &ndash; and I am leaning against, but feel very fluid with it as an editing tool &ndash; I realized I can save a tiny bit of the wasted motion Lightroom&rsquo;s blinkered refusal to participate in a normal &ldquo;share this image to these desktop endpoints and services&rdquo; by using imgup to not just <em>push</em> up to backend storage services, but <em>pull</em> from them as well.</p>
<p>So I&rsquo;ve added <code>pull</code> to its list of things it can do as a cheap and cheerful way to squirt a few images from Lightroom up to a SmugMug album, then make a post from the CLI.</p>
<p><code>imgup pull</code> takes a few arguments: the number of images to pull, any post text you care to add, which storage backend, which album on that backend, and which destination social media services (Mastodon or Bluesky right now).</p>
<p>So:</p>
<p><code>imgup pull 5 --service smugmug --album &quot;uploads&quot; --mastodon --post &quot;Pictures from the show&quot;</code></p>
<p>&hellip; will trigger a pull from the last five images. If you&rsquo;re using a plain old terminal, you get a list of image filenames and the description metadata if you took the time to add it at some point. Pick the index numbers of the ones you want to post and imgup will make a post to Mastodon pulling in the tags from each image.</p>
<p>If you&rsquo;re using kitty and set <code>kitty_thumbnails&quot;: true</code> you get thumbnails to help you make the right choice.</p>
<p><a href="https://www.flickr.com/photos/98806759@N00/54570607303"><img src="https://live.staticflickr.com/65535/54570607303_302bc6e8c7_b.jpg" alt="imgupv2 using Kitty for thumbnail preview"></a></p>
<p>If you leave out the <code>--post</code> switch, you get the same list and can make your selection, and imgup generates JSON and opens it in <code>$EDITOR</code>. There you can add the post text, tweak alt tags, etc. before closing the file, which pipes it back in for sharing to Mastodon or Bluesky.</p>
<p><code>pull</code> has one other thing it can do, which is filter by tags with the <code>--tags</code> switch.</p>
<p><a href="https://github.com/pdxmph/imgupv2/">v0.12.0 is up on GitHub</a>.</p>
<p>If you use Homebrew, the easy way to get it is:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$ brew tap pdxmph/tap
</span></span><span class="line"><span class="cl">$ brew install --cask pdxmph/tap/imgupv2</span></span></code></pre></div>
]]></content:encoded>
    </item>
    <item>
      <title>imgupv2 0.9.0 - Bluesky, multi-image, caching</title>
      <link>https://mike.puddingtime.org/posts/2025-06-03-imgupv2-090-bluesky-multi-image-caching/</link>
      <pubDate>Tue, 03 Jun 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-06-03-imgupv2-090-bluesky-multi-image-caching/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://live.staticflickr.com/65535/54566811333_767aa432cf_b.jpg&#34; alt=&#34;Screenshot of imgupv2 ready to upload multiple images with indicators for completed alt text&#34;&gt;&lt;/p&gt;
&lt;p&gt;I pushed out &lt;a href=&#34;https://github.com/pdxmph/imgupv2&#34;&gt;imgupv2 0.9.1&lt;/a&gt;. It&amp;rsquo;s what I&amp;rsquo;d call feature complete:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;multi-image posting to Flickr, Smugmug, Bluesky, and Mastodon&lt;/li&gt;
&lt;li&gt;world&amp;rsquo;s crabbiest, most indifferent caching strategy&lt;/li&gt;
&lt;li&gt;GUI for posting straight from Apple Photos or Finder selection&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I kinda like where it ended up with multi-images from the command line. They were super clunky using standard command line switches and positional arguments, and I think that&amp;rsquo;s a weird use case for the command line, but it&amp;rsquo;s a normal use case for automation, so the tool biases in favor of machines talking at each other in those instances:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://live.staticflickr.com/65535/54566811333_767aa432cf_b.jpg" alt="Screenshot of imgupv2 ready to upload multiple images with indicators for completed alt text"></p>
<p>I pushed out <a href="https://github.com/pdxmph/imgupv2">imgupv2 0.9.1</a>. It&rsquo;s what I&rsquo;d call feature complete:</p>
<ul>
<li>multi-image posting to Flickr, Smugmug, Bluesky, and Mastodon</li>
<li>world&rsquo;s crabbiest, most indifferent caching strategy</li>
<li>GUI for posting straight from Apple Photos or Finder selection</li>
</ul>
<p>I kinda like where it ended up with multi-images from the command line. They were super clunky using standard command line switches and positional arguments, and I think that&rsquo;s a weird use case for the command line, but it&rsquo;s a normal use case for automation, so the tool biases in favor of machines talking at each other in those instances:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-gdscript3" data-lang="gdscript3"><span class="line"><span class="cl"><span class="c1"># Create JSON and pipe it</span>
</span></span><span class="line"><span class="cl"><span class="n">echo</span> <span class="s1">&#39;{</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;images&#34;</span><span class="p">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;path&#34;</span><span class="p">:</span> <span class="s2">&#34;/path/to/image1.jpg&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;title&#34;</span><span class="p">:</span> <span class="s2">&#34;Sunset&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;description&#34;</span><span class="p">:</span> <span class="s2">&#34;Beautiful sunset&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;tags&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;sunset&#34;</span><span class="p">,</span> <span class="s2">&#34;photography&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;alt&#34;</span><span class="p">:</span> <span class="s2">&#34;Orange sunset over mountains&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;path&#34;</span><span class="p">:</span> <span class="s2">&#34;/path/to/image2.jpg&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;title&#34;</span><span class="p">:</span> <span class="s2">&#34;Moon&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;description&#34;</span><span class="p">:</span> <span class="s2">&#34;Full moon&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;tags&#34;</span><span class="p">:</span> <span class="p">[</span><span class="s2">&#34;moon&#34;</span><span class="p">,</span> <span class="s2">&#34;night&#34;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;alt&#34;</span><span class="p">:</span> <span class="s2">&#34;Full moon in clear sky&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;social&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;mastodon&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;enabled&#34;</span><span class="p">:</span> <span class="bp">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;text&#34;</span><span class="p">:</span> <span class="s2">&#34;Some photos&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;visibility&#34;</span><span class="p">:</span> <span class="s2">&#34;public&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">},</span>
</span></span><span class="line"><span class="cl">    <span class="s2">&#34;bluesky&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;enabled&#34;</span><span class="p">:</span> <span class="bp">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="s2">&#34;text&#34;</span><span class="p">:</span> <span class="s2">&#34;Hello, thirst-trap bots.&#34;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span><span class="s1">&#39; | imgup upload --json</span></span></span></code></pre></div>
<p>The GUI poster is sort of nice: Little thumbnails so you can catch it if you meant to upload from Finder but have Photos selected (and v/v), and while it won&rsquo;t <em>force</em> you to add alt text, you get an affirming little green check if you add it to each of your multi-post images so that you don&rsquo;t have to go back and check.</p>
<p>The caching thing &hellip; it&rsquo;s okay. Basically, you upload something and its URL and some metadata get written into a sqlite db, so if you ever try to upload the same image again, you just get your snippet back without a duplicate. If you delete the image from SmugMug or Flickr, you&rsquo;ll just get a broken image link in your clipboard, so if you&rsquo;re a <em>volatile</em> Flickr or SmugMug user, just:</p>
<p><code>imgup config set default.duplicate_check false</code></p>
<p>And it&rsquo;s installable with Homebrew:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">brew tap pdxmph/tap
</span></span><span class="line"><span class="cl">brew install --cask pdxmph/tap/imgupv2</span></span></code></pre></div>
<p>&hellip; assign the <code>imgupv2-gui.app</code> a keyboard shortcut from Shortcuts or FastScripts or whatever you care to do and invoke it on a Photos or Finder photo selection.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Well, I&#39;m less likely to subtoot, anyhow.</title>
      <link>https://mike.puddingtime.org/posts/2025-06-02-well-im-less-likely-to-subtoot-anyhow/</link>
      <pubDate>Mon, 02 Jun 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-06-02-well-im-less-likely-to-subtoot-anyhow/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m currently on my second life in Mastodon. I deleted my omg.lol account after a long period of having 30-day self-destructing toots anyhow, then sort of pulled myself together and &lt;a href=&#34;https://social.lol/@mph&#34;&gt;reinstated it&lt;/a&gt;. I turned off the self-destructing part, too.&lt;/p&gt;
&lt;p&gt;But part of the reason for getting rid of almost all my social accounts was frustration over seeing things go by and rinsing/repeating the whole &amp;ldquo;someone is wrong on the internet&amp;rdquo; cycle, except I&amp;rsquo;m way too retiring to do anything other than delete the post or turn it into a homeopathically vague subtoot. &amp;ldquo;If a tree falls on Jupiter and nobody is around to hear it&amp;rdquo; levels of vague.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I&rsquo;m currently on my second life in Mastodon. I deleted my omg.lol account after a long period of having 30-day self-destructing toots anyhow, then sort of pulled myself together and <a href="https://social.lol/@mph">reinstated it</a>. I turned off the self-destructing part, too.</p>
<p>But part of the reason for getting rid of almost all my social accounts was frustration over seeing things go by and rinsing/repeating the whole &ldquo;someone is wrong on the internet&rdquo; cycle, except I&rsquo;m way too retiring to do anything other than delete the post or turn it into a homeopathically vague subtoot. &ldquo;If a tree falls on Jupiter and nobody is around to hear it&rdquo; levels of vague.</p>
<p>But having picked up and stuck to <a href="https://puddingtime.org/experiments-in-atomic-writing">an atomic writing practice</a> over the past few weeks, I have taken to just letting myself feel my first reaction and commit it to a note that I might drop a few tags into if I have recently written notes about similar things, and I then I keep going with whatever I was up to. The impulse to &ldquo;say&rdquo; something is honored, I waste no time crafting it down to a mild subtoot, and it&rsquo;s actually better for later thinking, because it&rsquo;s way easier to process a very brief, unfiltered observation than it is to process an overcooked one. The atomic note is just a hunk of raw ore for later.</p>
<p>One piece of advice I gave myself this time around was to not think about how all the notes would hang together, but to just write, tag a little, and periodically link back to the top of a topical tree or nearby note, not in a rigid <a href="https://zettelkasten.de/folgezettel/">folgezettel</a> kind of way, but in a &ldquo;this is part of a cluster&rdquo; kind of way. I will not have a very awe inspiring graph view. That&rsquo;s fine. This is more of a mental health exercise than a &ldquo;walk in the footsteps of Luhmann&rdquo; exercise.</p>
]]></content:encoded>
    </item>
    <item>
      <title>There&#39;s an addressable market of 1</title>
      <link>https://mike.puddingtime.org/posts/2025-06-01-theres-an-addressable-market-of-1/</link>
      <pubDate>Sun, 01 Jun 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-06-01-theres-an-addressable-market-of-1/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://live.staticflickr.com/65535/54560878713_25a7191dce_b.jpg&#34; alt=&#34;Screenshot of the imgupv2 GUI prepared to upload the selected file from Photos&#34;&gt;&lt;/p&gt;
&lt;p&gt;Years ago when I was first learning to write scripts, I&amp;rsquo;d come up with stuff that made my life much better and would have helped other people on my team, and I&amp;rsquo;d run into the kinds of distribution problems you&amp;rsquo;d expect: I was a Linux/Mac guy, everyone around me was a Windows person, etc. I am guessing the 20th anniversary of the first time I said &amp;ldquo;well, it runs on &lt;em&gt;my&lt;/em&gt; laptop&amp;rdquo; is right around the corner. Even people who &lt;em&gt;could&lt;/em&gt; download the OSAX I was using for an AppleScript weren&amp;rsquo;t necessarily interested in doing it.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://live.staticflickr.com/65535/54560878713_25a7191dce_b.jpg" alt="Screenshot of the imgupv2 GUI prepared to upload the selected file from Photos"></p>
<p>Years ago when I was first learning to write scripts, I&rsquo;d come up with stuff that made my life much better and would have helped other people on my team, and I&rsquo;d run into the kinds of distribution problems you&rsquo;d expect: I was a Linux/Mac guy, everyone around me was a Windows person, etc. I am guessing the 20th anniversary of the first time I said &ldquo;well, it runs on <em>my</em> laptop&rdquo; is right around the corner. Even people who <em>could</em> download the OSAX I was using for an AppleScript weren&rsquo;t necessarily interested in doing it.</p>
<p>I learned Sinatra and HAML because I wanted to make work I was doing accessible to other people, and the best way to solve the distribution problem was to just build a web GUI and plumb all those Ruby scripts in as controllers.</p>
<p>When I wrote the first imgup, I did it in Sinatra and got it going on Heroku well enough that I could document how someone else could grab the source and run it for themselves. When I decided to pivot it into a command line app, the distribution problem came back, but I&rsquo;ve learned enough over the years that if there were any issues with someone else using the code, I can&rsquo;t really blame it on distribution woes, just my own disinterest in a test matrix bigger than &ldquo;the OS running on the machine I am testing on.&rdquo;</p>
<p>So after deciding to quit futzing with imgup &ndash; that it was as done as it can be &ndash; I started writing a blog post about the experience of doing the migration from Sinatra/Web to a command line tool using Claude.</p>
<p>The development loop I landed on over a few weeks of intermittent fussing had come down to leveraging the <a href="https://basicmachines.co">Basic Memory MCP</a> to preserve more project context between sessions, and to chain project context with a special project architecture note in Basic Memory and what I came to call &ldquo;continuity prompts.&rdquo;</p>
<p>Basic Memory is just an archive of Markdown/YAML files kept on your disk with light markup to create persistence: You can annotate Basic Memory notes with &ldquo;Observations&rdquo; and &ldquo;Relationships&rdquo; that it uses to build a graph out of notes.</p>
<p>Observations look like:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="k">-</span> [architecture] Direct API metadata is cleaner than file embedding
</span></span><span class="line"><span class="cl"><span class="k">-</span> [performance] Removing exiftool dependency significantly improved upload speed
</span></span><span class="line"><span class="cl"><span class="k">-</span> [simplicity] Upload-then-set pattern is more maintainable than metadata embedding
</span></span><span class="line"><span class="cl">- [consistency] Aligning Flickr with SmugMug&#39;s approach simplified the codebase</span></span></code></pre></div>
<p>&hellip; and they work, to the extent that when I would turn on Extended Thinking and watch Claude talking to itself, it would mention them as things it &ldquo;knew&rdquo; or was trying to take into account when working on a chunk of code.</p>
<p>My <code>Project Context</code> note provides all the things Claude needed to know to start each session without going through rediscovery each time we worked on a new feature or bugfix. I devised a continuity prompt that reminded Claude to check out the project context:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl">I&#39;m working on imgupv2, my fast image uploader for photographers. Please read the project context first:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">memory://imgupv2-project-context-working-preferences
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">Key reminders:
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">-</span> The GUI is Wails (Go + Web), NOT Swift
</span></span><span class="line"><span class="cl"><span class="k">-</span> External dependencies need full paths (GUI apps don&#39;t inherit shell PATH)
</span></span><span class="line"><span class="cl"><span class="k">-</span> Always ask before making changes
</span></span><span class="line"><span class="cl">- Work incrementally and wait for confirmation</span></span></code></pre></div>
<p>The Project Context note includes things like:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="gu">### 1. CLI Binary (`imgup`)
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">-</span> **Location**: <span class="sb">`/Users/mph/code/imgupv2/cmd/imgup/`</span>
</span></span><span class="line"><span class="cl"><span class="k">-</span> **Binary locations**:
</span></span><span class="line"><span class="cl">  <span class="k">-</span> Development: <span class="sb">`/Users/mph/code/imgupv2/imgup`</span>
</span></span><span class="line"><span class="cl">  <span class="k">-</span> Installed: <span class="sb">`~/go/bin/imgup`</span> or <span class="sb">`/usr/local/bin/imgup`</span> or <span class="sb">`/opt/homebrew/bin/imgup`</span>
</span></span><span class="line"><span class="cl"><span class="k">-</span> **Purpose**: Core upload functionality, authentication, configuration
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="gu">### 2. GUI Application (`imgupv2-gui.app`)
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">-</span> **Location**: <span class="sb">`/Users/mph/code/imgupv2/gui/`</span>
</span></span><span class="line"><span class="cl"><span class="k">-</span> **Technology**: Wails (Go + Web frontend, NOT Swift)
</span></span><span class="line"><span class="cl">  <span class="k">-</span> [architecture] GUI uses Wails (Go + Web frontend), NOT Swift <span class="ni">#imgupv2</span> <span class="ni">#wails</span> (correcting common misconception)
</span></span><span class="line"><span class="cl"><span class="k">-</span> **Frontend**: <span class="sb">`/Users/mph/code/imgupv2/gui/frontend/`</span> (HTML/JS/CSS)
</span></span><span class="line"><span class="cl"><span class="k">-</span> **Features**:
</span></span><span class="line"><span class="cl">  <span class="k">-</span> Detects selected images from Finder/Photos.app
</span></span><span class="line"><span class="cl">  <span class="k">-</span> Metadata review before upload
</span></span><span class="line"><span class="cl">  <span class="k">-</span> Mastodon integration with dynamic form
</span></span><span class="line"><span class="cl">  - Seamless white window design</span></span></code></pre></div>
<p>and &hellip;</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="gu">## Project Structure
</span></span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">/Users/mph/code/imgupv2/ ├── cmd/imgup/ # CLI entry point ├── pkg/ │ ├── services/ # Service implementations │ │ ├── flickr/ # Flickr client │ │ └── mastodon/ # Mastodon client │ ├── config/ # Configuration management │ └── metadata/ # EXIF/metadata extraction ├── gui/ # Wails GUI application │ └── frontend/ # Web frontend (NOT Swift!) │ └── dist/ # Must copy files here for build ├── homebrew/ # Homebrew cask definition ├── build-macos-release.sh # Release packaging script ├── release.sh # GitHub release automation └── build-and-release.sh # Complete release automation</span></span></code></pre></div>
<p>That is, btw, a Go project. Because in the midst of writing up my notes about what I learned working with Claude, I realized ways in which I&rsquo;d made a very useful workflow that would have saved me a ton of time doing what should have been a simple migration of some controller logic out to a command line script, and that if could use Claude <em>poorly</em> to get a mostly okay reimplementation in a language I know, maybe if I used it <em>well</em> I could get a good reimplementation &ndash; and a more portable, accessible one &ndash; with a language I don&rsquo;t know so well.</p>
<p>So I started with a clean slate, started a new Claude &ldquo;Project,&rdquo; and set out to make <a href="https://github.com/pdxmph/imgupv2">imgupv2</a> in Go using everything I learned to work with Claude and the Basic Memory MCP.</p>
<p>I would have been happy to just have a distributable binary I could share, but the approach I took to the whole thing let everything move super fast. To the point imgup can be installed with Homebrew, and ships with a little (optional) popup GUI so you can just select an image in the Finder or Photos, invoke a Shortcut with a hotkey. Its backward compatible with the old Ruby version, so it can be wired into anything you&rsquo;d care to script, like Raycast Script Actions or Hazel folder actions.</p>
<p>I also added some new features because the core feature set went in fast. Oauth registration with Flickr, SmugMug, and Mastodon works without pasting URLs, etc. because imgup config fires up a little callback server duing onboarding. And after <a href="https://baty.net/posts/2025/05/letting-flickr-host-my-blog-s-images/">Jack Baty mentioned wanting to customize another little flickr script</a> I had come up with, I added snippet templating:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl">  <span class="s2">&#34;templates&#34;</span><span class="err">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;html&#34;</span><span class="p">:</span> <span class="s2">&#34;\u003cimg src=\&#34;%image_url%\&#34; alt=\&#34;%alt|description|title|filename%\&#34;\u003e&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;json&#34;</span><span class="p">:</span> <span class="s2">&#34;{\&#34;photo_id\&#34;:\&#34;%photo_id%\&#34;,\&#34;url\&#34;:\&#34;%url%\&#34;,\&#34;image_url\&#34;:\&#34;%image_url%\&#34;}&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;markdown&#34;</span><span class="p">:</span> <span class="s2">&#34;![%alt|description|title|filename%](%image_url%)&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;org&#34;</span><span class="p">:</span> <span class="s2">&#34;[[%image_url%][%alt|description|title|filename%]]&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;url&#34;</span><span class="p">:</span> <span class="s2">&#34;%url%&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span></span></span></code></pre></div>
<p>&hellip; so instead of living with my particular idea of how an HTML snippet should look, you can roll your own and override the default.</p>
<p>I also added accessibilty prompts and support (you get a reminder if you don&rsquo;t specify an <code>--alt</code> flag, but the snippet will degrade from <code>alt</code> to the image <code>description</code> to the image <code>title</code> when making a post.)</p>
<p>&hellip; and I successfully used Claude itself as a sort of consultant. I was miserable about the way I&rsquo;d added flickr support because it was dog slow due to my own limitations, but I was able to use Claude to reimplement flickr uploads in a way that makes them super fast and removes external dependencies on exiftool: I told it the pain point, which involved extracting images, writing them out to disk, and embedding the metadata from Photos <em>then</em> uploading them; and it suggested a pair of API calls: One to upload the image, and one to write the metadata over the API.</p>
<p>And the last &ldquo;feature&rdquo; is an automated build and distribution pipeline, complete with Apple notarization. One build script compiles the macOS and Linux binaries, signs the macOS binaries, builds the GUI, tags a release, and updates the Homebrew cask:</p>
<p><code>brew install --cask pdxmph/tap/imgupv2</code></p>
<p>&hellip; but also just &hellip;</p>
<p><code>go install github.com/pdxmph/imgupv2/cmd/imgup@latest</code> if you don&rsquo;t care about the GUI or want to build something in Raycast, Apple Shortcuts, Alfred, etc.</p>
<h2 id="but-why-tho">But why tho</h2>
<p>Just curiosity, I guess. AI is a big deal at work right now, and my job puts me in the middle of a lot of it: Working through security issues, thinking about how to onboard and configure the flood of new AI features rolling out from all our vendors, and lately helping out with a training program. Our product is going to be using AI a lot more in the coming year.</p>
<p>There are a lot of folks around me at work who have a lot of takes, good and bad, realistic and unrealistic. One person scoffed, &ldquo;I tried to get AI to write a program for my kids and it couldn&rsquo;t! Smoke and mirrors!&rdquo; Plot that take on a <code>skepticism -&gt; credulity</code> bell curve, and I can probably think of equal and opposite occupants on the other end that I&rsquo;ve heard.</p>
<p>Up until this past month, I&rsquo;d mostly used LLMs as a coding <em>augment</em>. When I was writing the first, Sinatra-based imgup, I struggled with the syntax for building and tearing down OAuth sessions in Ruby, so ChatGPT helped me out there. I did a few proofs of concept for things like &ldquo;write some Ruby that uses the TriMet API to tell me when the next three trains are due at my Max station&rdquo; just to understand how it worked and what it could do. And if I&rsquo;d come across an error, I&rsquo;d use it to paste in the error, provide a little context, and get something as serviceable as a direct visit to Stack Overflow.</p>
<p>I&rsquo;d never tried to use one to do a whole project with multiple discrete pieces.</p>
<p>Could I have, as that one person apparently tried, just said &ldquo;make a thing called imgup. It needs to post pictures to flickr or smugmug from the command line, operate on the selected file in the Finder or Photos, and optionally post to Mastodon,&rdquo; well, no, that would not have worked.</p>
<p>It didn&rsquo;t even &ldquo;work,&rdquo; in my early first attempt to allow for its shortcomings, to make a thorough project prompt and keep sessions concise: It was incredibly inefficient, forgetful, and self-defeating, constantly introducing regressions as it forgot how one piece connected to the other, even when it had a copy of the repo attached to its project memory.</p>
<p>What finally made it &ldquo;work,&rdquo; if our definition of &ldquo;work&rdquo; is &ldquo;make code that does what I want with about as many obvious bugs or issues as if I&rsquo;d devoted months to this project starting from scratch,&rdquo; was leveraging Basic Memory to give it some persistent project knowledge, careful marshaling of its limited session lengths, fastidious continuity prompting, and the occasional &ldquo;go describe this problem to another instance outside the project to see if an evil twin can poke holes in the solutions offered by the other AI &lsquo;developer.&rsquo;&rdquo;</p>
<p>So my curiosity is satisfied, for the most part.</p>
<p>Less public than this project, though, is all the writing I&rsquo;m doing for myself right now not about how to make it work, but what to make of it &ndash; &ldquo;AI&rdquo; &ndash; generally. Because as surely as there&rsquo;s a wide and varied distribution of takes on whether AI can do this or do that, if it&rsquo;s &ldquo;real&rdquo; or &ldquo;just smoke and mirrors,&rdquo; the social issues are at our doorstep. This almost felt like me saying to myself, &ldquo;well, you know what it <em>can</em> do; so now you can figure out what it <em>means</em>.&rdquo;</p>
]]></content:encoded>
    </item>
    <item>
      <title>imgup v0.13.0 (Fedi-Ready)</title>
      <link>https://mike.puddingtime.org/posts/2025-05-28-imgup-v0130-fedi-ready/</link>
      <pubDate>Wed, 28 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-28-imgup-v0130-fedi-ready/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54550622732_10eb18d114_b.jpg&#34; alt=&#34;Asphalt factory machine shack&#34;&gt;&lt;/p&gt;
&lt;p&gt;Over the weekend I roughed in support for posting to gotosocial or Mastodon &lt;a href=&#34;https://github.com/pdxmph/imgup-cli&#34;&gt;imgup&lt;/a&gt;, but made a decision about UI that my old jazz band director would have called &amp;ldquo;a choice that was not as good as the other ones,&amp;rdquo; and it took trying to wire the new functionality into a Raycast script to catch how it was a problem.&lt;/p&gt;
&lt;p&gt;So this morning was &amp;ldquo;untangle that mess&amp;rdquo; and I think it&amp;rsquo;s in a way better place:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://farm66.staticflickr.com/65535/54550622732_10eb18d114_b.jpg" alt="Asphalt factory machine shack"></p>
<p>Over the weekend I roughed in support for posting to gotosocial or Mastodon <a href="https://github.com/pdxmph/imgup-cli">imgup</a>, but made a decision about UI that my old jazz band director would have called &ldquo;a choice that was not as good as the other ones,&rdquo; and it took trying to wire the new functionality into a Raycast script to catch how it was a problem.</p>
<p>So this morning was &ldquo;untangle that mess&rdquo; and I think it&rsquo;s in a way better place:</p>
<ul>
<li>Post to flickr or SmugMug and get back a Markdown, org-mode, or HTML snippet, same as before.</li>
<li>Post to Mastodon or gotosocial with post text and visibility settings</li>
<li>Optional tags, title, and caption (which we use as alt text for image tags and social posts)</li>
</ul>
<p>I have a couple of Linux laptops, so the core tool is written for the command line to make it easily scriptable, but remain amenable to working in demi-GUI workflows, such as a Raycast shell script action or something like Shortcuts or Automator. <a href="https://github.com/pdxmph/raycast-actions/blob/main/photos-to-imgup.sh">Here&rsquo;s a sample Raycast action to upload the selected image in Photos</a>. You can even hook it up to a <a href="https://github.com/pdxmph/imgup-cli/blob/main/extras/hazel_smugmug.sh">Hazel folder action</a> that knows to pull the title and caption from metadata.</p>
<p>To add an image to this post, for instance, I:</p>
<ul>
<li>Found a photo in Apple Photos</li>
<li>Triggered a Raycast script and added title, caption/alt, and tags</li>
<li>Got back a Markdown snippet on my clipboard: <code>![Asphalt factory machine shack](https://farm66.staticflickr.com/65535/54550622732_10eb18d114_b.jpg)</code></li>
<li>Pasted it into this post</li>
</ul>
<p>The original impetus for all this was &ldquo;blogging providers don&rsquo;t care about image quality and it shows,&rdquo; and that was why imgup started as a little <a href="https://github.com/pdxmph/imgup">Sinatra-backed web tool</a>. The impulse that eventually took over was &ldquo;reduce as much friction to uploading and sharing images as possible.&rdquo;</p>
<p>For my own use, I&rsquo;m trying to build surrounding tools that reward good behavior: The Hazel upload action, for instance, will grab existing metadata: That&rsquo;s a great reason to include title and caption in my editing workflow in Lightroom. In the short term it makes posting simple and frictionless. In the future, I&rsquo;ll be more grateful for the title and caption than the 30 seconds I saved by not posting &ldquo;the long way.&rdquo;</p>
<p>One semantic thing I need to back out of or address: Photo tools are all over the place on the metadata they expose and allow you to edit. At some point LR CC added an alt text field, but imgup&rsquo;s &ldquo;caption&rdquo; flag acts as the alt text for the image tags it produces or the social media posts it makes. I need to look at the SmugMug and Flickr APIs and think about the logic there.</p>
<p>And I want to add Bluesky to the list of supported services.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Exposure therapy</title>
      <link>https://mike.puddingtime.org/posts/2025-05-26-exposure-therapy/</link>
      <pubDate>Mon, 26 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-26-exposure-therapy/</guid>
      <description>&lt;p&gt;I should probably apologize to a few people on the Fediverse for double-follows or weird Mastodon noise, but I&amp;rsquo;m not entirely clear on what kind of noise a small experiment might have generated. If you know me and noticed a weird follow, it&amp;rsquo;s because a quick automated trawl of my timeline flagged you as low-noise, high-signal for photography-related stuff and dropped you into my Photographers list.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;reason&lt;/em&gt; for the trawl was to get back to a practice I used to follow a long time ago where I&amp;rsquo;d wake up in the morning and load up Flickr&amp;rsquo;s &amp;ldquo;Explore&amp;rdquo; feed in Flipboard and make myself flip through it for a while. It was a little hard to do some mornings, but I stuck with it, adopting a mindset of:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I should probably apologize to a few people on the Fediverse for double-follows or weird Mastodon noise, but I&rsquo;m not entirely clear on what kind of noise a small experiment might have generated. If you know me and noticed a weird follow, it&rsquo;s because a quick automated trawl of my timeline flagged you as low-noise, high-signal for photography-related stuff and dropped you into my Photographers list.</p>
<p>The <em>reason</em> for the trawl was to get back to a practice I used to follow a long time ago where I&rsquo;d wake up in the morning and load up Flickr&rsquo;s &ldquo;Explore&rdquo; feed in Flipboard and make myself flip through it for a while. It was a little hard to do some mornings, but I stuck with it, adopting a mindset of:</p>
<ul>
<li>You don&rsquo;t have to like all of it.</li>
<li>There are better and worse choices, so figure out why you think which is which.</li>
<li>You&rsquo;re not as good as a lot of these people, but you do your thing for your own reasons, not Flickr&rsquo;s (or anyone else).</li>
<li>Figure out why things work or don&rsquo;t work for you. Don&rsquo;t do the things that don&rsquo;t work, learn how to do the things that do work.</li>
</ul>
<p>I think this is just basic self-development for people, I just had to learn it for myself because &hellip; well because.</p>
<p>So the trawl was to find accounts with a high percentage of media-only posts along with the absence of a list of stopwords in their posts, and the reason was to put them in a Mastodon list so I can wake up my Exposure Therapy approach, just using Mastodon instead of Flickr Explore. I just looked in on Explore, and it is about the same as it was. I think it could serve the same purpose, but I think the photography I see on Mastodon is a little more to my general taste, but not so much I&rsquo;m closing myself off from learning opportunities.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Focus Guardian</title>
      <link>https://mike.puddingtime.org/posts/2025-05-26-focus-guardian/</link>
      <pubDate>Mon, 26 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-26-focus-guardian/</guid>
      <description>&lt;p&gt;Claude has enabled a sort of exuberant play recently, as I&amp;rsquo;ve figured out what it is good for and how it can help me do stuff that I&amp;rsquo;ve thought would be interesting or fun to play with, but not practical to implement on my own. That&amp;rsquo;s been fun, but also it has felt a little weird because it has led me fully into the territory of doing things because I can, not because they&amp;rsquo;re really useful.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Claude has enabled a sort of exuberant play recently, as I&rsquo;ve figured out what it is good for and how it can help me do stuff that I&rsquo;ve thought would be interesting or fun to play with, but not practical to implement on my own. That&rsquo;s been fun, but also it has felt a little weird because it has led me fully into the territory of doing things because I can, not because they&rsquo;re really useful.</p>
<p>Several years ago I read Cal Newport&rsquo;s <em>Digital Minimalism</em>, going into the book thinking it would be one thing and learning it was something else I was much happier to think about, which was &ldquo;why am I doing any of the things I do?&rdquo; I spent a lot of time inventorying, thinking, and writing about that question, figuring out what my purpose was.</p>
<p>Some of that was painful to do. A few weeks ago Al asked me for some advice on a problem she was dealing with at work, and my opinions on the matter were so reflexive and so anchored on what is turning into a big portion of my life thinking about management problems that I felt a little dizzy and had to just stop and reflect on where that all even came from.</p>
<p>&ldquo;I wish,&rdquo; I said, &ldquo;that I knew less about solving management problems than I seem to know. I could have been doing something else with all that bandwidth.&rdquo;</p>
<p>So &ldquo;what is my purpose? Why do I do these things?&rdquo; were hard to ask because I had to spend a lot of time thinking about what the answers might have once been, and consider what I thought of being pulled away from that.</p>
<p>But from the exercise came some clear answers about <em>what</em> I do: I write, I take pictures, I read. Almost everything I screw around with, fiddle with, experiment with, or futz with has something to do with one of those things and some idea I have about how it will make one of those things better somehow. My <em>reasons</em> for doing those things are going to remain my own. I could share the ones that don&rsquo;t feel super personal to me, but they&rsquo;re the kinds of reasons you probably have yourself if you do any of those things much.</p>
<p>I&rsquo;ve made a sort of mantra out of that list.</p>
<p>My rabbit holes are adjacent to my interests most of the time, but their utility is never completely guaranteed: Sometimes parts of my personality come to the fore that make my rabbit holes and digressions feel wasteful. They don&rsquo;t pan out, or they do and they aren&rsquo;t as useful as I hoped, or they triggered a bunch of fussing around with something that was fine as is. When I&rsquo;m done, I feel a little dulled and uneasy, and I think &ldquo;I could&rsquo;ve been writing, or reading, or taking pictures.&rdquo;</p>
<p>When I&rsquo;m feeling very reflective I feel pretty self-conscious about those time-sucks. They feel like failures. I try not to be too hard on myself, because I&rsquo;ve also come to realize there is probably something going on it&rsquo;d be good to try to tease out. Like, I can tell you <em>exactly</em> why I haven&rsquo;t been reading or writing much lately, and it has been helpful to know that and remember it.</p>
<p>So back to Claude: It has powered a sort of &ldquo;oh, that&rsquo;d be cool&rdquo; digression factory that is always in sight of what I care about, but is always not doing the things I care about. It got really bad with one small project that spun out until I&rsquo;d burned a whole evening on it. The time was just gone. And I wish I&rsquo;d noticed for some reason besides &ldquo;this didn&rsquo;t pan out, why did I spend this time on it?&rdquo;</p>
<p>So today I made the &ldquo;focus guardian&rdquo; prompt and stuck it in Claude&rsquo;s user instructions. I think people tend to use that for facts about themselves, or the tone they prefer in responses, or whatever. I decided to use it to get a little help with my digressions. It&rsquo;s a little lengthy, and I&rsquo;m saying enough about the inside of my own head to even discuss this in public, so I&rsquo;ll just outline what it does in the 350 words it takes:</p>
<ul>
<li>Looks for red flag expressions and requests</li>
<li>Intervenes with a mix of questions and principles</li>
<li>Suggests some alternatives</li>
</ul>
<p>It caught me this afternoon, asked an intervening question, and provided some suggestions. I folded my laptop shut for a few minutes and wondered what I had been about to do, and decided I might as well enforce this new protocol I&rsquo;m trying to implement in my own skull by writing about it.</p>
]]></content:encoded>
    </item>
    <item>
      <title>imgup v0.10.0 - sharing is caring (fedi support)</title>
      <link>https://mike.puddingtime.org/posts/2025-05-25-imgup-v0100-sharing-is-caring-fedi-support/</link>
      <pubDate>Sun, 25 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-25-imgup-v0100-sharing-is-caring-fedi-support/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54545850354_7d63ed0380_b.jpg&#34; alt=&#34;A test post from imgup to gotosocial&#34;&gt;&lt;/p&gt;
&lt;p&gt;I started the day working through the setup for a &lt;a href=&#34;https://gotosocial.org&#34;&gt;gotosocial&lt;/a&gt; server. It took a little fussing with the Synology, but it&amp;rsquo;s &lt;a href=&#34;https://social.puddingtime.org&#34;&gt;up and running&lt;/a&gt;. There&amp;rsquo;s a little more to it than &amp;ldquo;because I could,&amp;rdquo; but not much. I think I&amp;rsquo;ll find a few things to follow from there that are not humans with feelings and see how well it runs before moving there.&lt;/p&gt;
&lt;p&gt;But that made me start thinking about imgup and how it&amp;rsquo;d be kind of cool to be able to use it to post to Fediverse services. So &lt;a href=&#34;https://github.com/pdxmph/imgup-cli/&#34;&gt;imgup 0.10.0&lt;/a&gt; does that by adding a way to enroll it with gotosocial as an app then adding it as an option when posting to Flickr or Smugmug.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://farm66.staticflickr.com/65535/54545850354_7d63ed0380_b.jpg" alt="A test post from imgup to gotosocial"></p>
<p>I started the day working through the setup for a <a href="https://gotosocial.org">gotosocial</a> server. It took a little fussing with the Synology, but it&rsquo;s <a href="https://social.puddingtime.org">up and running</a>. There&rsquo;s a little more to it than &ldquo;because I could,&rdquo; but not much. I think I&rsquo;ll find a few things to follow from there that are not humans with feelings and see how well it runs before moving there.</p>
<p>But that made me start thinking about imgup and how it&rsquo;d be kind of cool to be able to use it to post to Fediverse services. So <a href="https://github.com/pdxmph/imgup-cli/">imgup 0.10.0</a> does that by adding a way to enroll it with gotosocial as an app then adding it as an option when posting to Flickr or Smugmug.</p>
<p>Nothing has changed about the way it has traditionally worked:</p>
<p><code>imgup -c &quot;Some caption/the alt text&quot; --tags some,tags -b flickr imgfile000.jpg</code></p>
<p>&hellip; but if you register it with gotosocial, you can add the <code>--post</code> and <code>--fedi</code> switches to compose the post text and make a post.</p>
<p><code>imgup -c &quot;Some caption&quot; --tags some,tags -b flickr imgfile000.jpg --fedi --post &quot;the text of your post&quot;</code></p>
<p>You can run the OAuth setup for that up with <code>imgup setup fedi</code>.</p>
<p>v0.11.0, which I have not full tested offers a simplifed flow to sign imgup to use your Mastodon instance, and adds the <code>--mastodon</code> switch, which behaves the same way.</p>
<p>So, it&rsquo;s becoming a little bit of a Swiss Army Knife:</p>
<ul>
<li>Use it to upload photos to Flickr or SmugMug and get back a snippet you can paste into your blog</li>
<li>Use it to post photos to those services and also make a Fediverse post out of them</li>
<li>Use it to just post to the Fediverse</li>
</ul>
<p>When you use Flickr or SmugMug alongside creating a post, you get to take advantage of their image resizing, which is nicer than a lot of blog hosting services: The images being shared are optimized without being turned into mush.</p>
<p>I&rsquo;ve got a few ideas about extending it to support Bluesky and Pixelfed. Bluesky would behave a lot more like the Mastodon or gotosocial functionality. Pixelfed has a few other features around albums and stories worth considering. Adding those sort of turns it into an image cross-posting tool for services open enough to work with one.</p>
]]></content:encoded>
    </item>
    <item>
      <title>lmno-blog-capture bump (adds and polishes &#39;drafts&#39;)</title>
      <link>https://mike.puddingtime.org/posts/2025-05-24-lmno-blog-capture-bump-adds-and-polishes-drafts/</link>
      <pubDate>Sat, 24 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-24-lmno-blog-capture-bump-adds-and-polishes-drafts/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://live.staticflickr.com/65535/54513598558_7def3a08a0_b.jpg&#34; alt=&#34;bike commuter on a foggy morning&#34;&gt;&lt;/p&gt;
&lt;p&gt;I rolled the lmno &amp;lsquo;drafts&amp;rsquo; stuff into &lt;a href=&#34;https://github.com/pdxmph/lmno-blog-capture&#34;&gt;lmno-blog-capture&lt;/a&gt;, which is sort of like org-capture for a &lt;a href=&#34;https://lmno.lol&#34;&gt;monolithic lmno.lol blog file&lt;/a&gt;: Invoke it, get a little transient window with a pre-populated heading, do your thing, &lt;code&gt;C-c C-c&lt;/code&gt; to save/exit.&lt;/p&gt;
&lt;p&gt;With the drafts feature added, you can configure a drafts file (e.g. &lt;code&gt;drafts-lmno.md&lt;/code&gt;), position the cursor inside a draft you&amp;rsquo;re working on in your main blog file, and teleport it to your drafts file. If you&amp;rsquo;re done with a draft, you can send it back over to the top of your lmno.lol file.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://live.staticflickr.com/65535/54513598558_7def3a08a0_b.jpg" alt="bike commuter on a foggy morning"></p>
<p>I rolled the lmno &lsquo;drafts&rsquo; stuff into <a href="https://github.com/pdxmph/lmno-blog-capture">lmno-blog-capture</a>, which is sort of like org-capture for a <a href="https://lmno.lol">monolithic lmno.lol blog file</a>: Invoke it, get a little transient window with a pre-populated heading, do your thing, <code>C-c C-c</code> to save/exit.</p>
<p>With the drafts feature added, you can configure a drafts file (e.g. <code>drafts-lmno.md</code>), position the cursor inside a draft you&rsquo;re working on in your main blog file, and teleport it to your drafts file. If you&rsquo;re done with a draft, you can send it back over to the top of your lmno.lol file.</p>
<p>I added a bit of polish/a potential shoe-gun to the draft thing since I last wrote about it: When you shuttle something out of the drafts file, it overwrites the date stamp with the current date.</p>
<p>That&rsquo;s me thinking more like a writer-who-publishes than a diarist-who-logs, and also keeps me from having to contemplate sorting the headings in the monolith.</p>
]]></content:encoded>
    </item>
    <item>
      <title>The FujiFilm half made me think about the XF10</title>
      <link>https://mike.puddingtime.org/posts/2025-05-23-the-fujifilm-half-made-me-think-about-the-xf10/</link>
      <pubDate>Fri, 23 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-23-the-fujifilm-half-made-me-think-about-the-xf10/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54540514424_4bfef2f15b_b.jpg&#34; alt=&#34;Portland waterfront on a misty morning&#34;&gt;&lt;/p&gt;
&lt;p&gt;The new #fujifilm #half looks sort of fun. I checked its dimensions against the XF10, and they&amp;rsquo;re quite similar.&lt;/p&gt;
&lt;p&gt;I re-read some release reviews of the XF10, then looked it up in Lightroom. I didn&amp;rsquo;t take too many pictures with it: I&amp;rsquo;ve never really done well with cameras that don&amp;rsquo;t have a viewfinder, and I got mine during the summer, when working with an LCD on bright beaches, etc. was a challenge.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://farm66.staticflickr.com/65535/54540514424_4bfef2f15b_b.jpg" alt="Portland waterfront on a misty morning"></p>
<p>The new #fujifilm #half looks sort of fun. I checked its dimensions against the XF10, and they&rsquo;re quite similar.</p>
<p>I re-read some release reviews of the XF10, then looked it up in Lightroom. I didn&rsquo;t take too many pictures with it: I&rsquo;ve never really done well with cameras that don&rsquo;t have a viewfinder, and I got mine during the summer, when working with an LCD on bright beaches, etc. was a challenge.</p>
<p>But still: APS-C sensor in a genuinely pocketable camera, similar to a GRIII, and it had a snap focus setup I didn&rsquo;t appreciate at the time but got better at when I did get a GRIII, which has a similar feature.</p>
<p>I think, at the time, I was perturbed that it didn&rsquo;t have Acros, and I was still all in on the notion that X-Trans sensors were dipped in unicorn juices before getting seated in the camera. Still, I never got rid of it, so I dug it out yesterday and charged the battery. I think the trick with it might be to re-learn the snap focus feature and dial in a decent film simulation preset.</p>
<p>I also don&rsquo;t see a half in my future <em>too</em> soon. I own one of the digital Instax hybrids. It&rsquo;s far too bulky to just carry around, and the &hellip; hybridity? &hellip; of the thing feels grubby: They don&rsquo;t let you use the camera to its fullest without forcing a film purchase on you. The half isn&rsquo;t that bad about it, but <a href="https://petapixel.com/2025/05/21/fujifilm-x-half-review-as-close-to-film-as-digital-can-get/">the most thorough review I&rsquo;ve found</a> suggests they&rsquo;ve committed to the bit a little too hard for the money. What I&rsquo;d <em>like</em> would be an XF10 successor with an optional OVF or EVF and a little more wherewithal. Or maybe not. I eventually sold the GRIII because it wasn&rsquo;t so pocketable that it made a ton more sense than an X100.</p>
<p>Anyhow &hellip; the XF10 is sitting there. Seems like fun to mess around with it.</p>
<p>Oh, the comments in the Petapixel review are tragicomic. The worst part of photography sites is truly all the photographers.</p>
]]></content:encoded>
    </item>
    <item>
      <title>The Priorities app</title>
      <link>https://mike.puddingtime.org/posts/2025-05-23-the-priorities-app/</link>
      <pubDate>Fri, 23 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-23-the-priorities-app/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54541134086_eb2d7a9765_b.jpg&#34; alt=&#34;Priorities PWA&#34;&gt;&lt;/p&gt;
&lt;p&gt;A long while back I had a small falling out with a boss. I was a green manager and we were trying to figure out what I needed for headcount. I had no idea how to have that conversation: I just knew &amp;ldquo;more people == more work done.&amp;rdquo; After a few back-and-forths, he finally realized I wasn&amp;rsquo;t getting it, and he said, &amp;ldquo;Look, I need to know each thing the team is doing, how important you think it is, and what it takes to keep the lights on. Tell me that and we can figure out if there&amp;rsquo;s something we could be doing differently, or slow down on, or reprioritize.&amp;rdquo;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://farm66.staticflickr.com/65535/54541134086_eb2d7a9765_b.jpg" alt="Priorities PWA"></p>
<p>A long while back I had a small falling out with a boss. I was a green manager and we were trying to figure out what I needed for headcount. I had no idea how to have that conversation: I just knew &ldquo;more people == more work done.&rdquo; After a few back-and-forths, he finally realized I wasn&rsquo;t getting it, and he said, &ldquo;Look, I need to know each thing the team is doing, how important you think it is, and what it takes to keep the lights on. Tell me that and we can figure out if there&rsquo;s something we could be doing differently, or slow down on, or reprioritize.&rdquo;</p>
<p>Oh.</p>
<p>At the time I was full steam ahead on <a href="https://github.com/pdxmph/docs_decomposer/">a Rails app that helped manage technical docs</a>. We&rsquo;d grown the page count 3x in just over a year, and we were starting to miss things like product screenshots that didn&rsquo;t change. We also had problems with internal customers telling us they weren&rsquo;t sure how to tell us about issues. So the Docs Decomposer offered up a rendered view of all our Markdown docs. You could leave a Google Docs-style comment on a selection, and you could also use a bookmarklet with it that let you select a problematic passage and file a Jira ticket with it. It <em>also</em> tracked screenshots and reported on which ones hadn&rsquo;t changed between versions so we could look in and make sure the product hadn&rsquo;t changed too much.</p>
<p>Since it was already up and running on internal infra, I just went home and started modeling how my boss had told me how to think about prioritization, and I made a tool that sat in an unlinked page in the Decomposer. You could enter a list of the stuff your team did, then tell it the priority of the item, how well you thought you were doing it, and how much effort it took. If you said something was a P1, but you weren&rsquo;t doing it well, you got a little &ldquo;this is on fire&rdquo; treatment on the priorities report.</p>
<p>So at our next 1:1 I put my browser on the screen in the conference room and walked my boss through what we were up to. We had a great conversation. He thought some stuff we were doing was better left to developers to work on, and he had some stuff he wanted me to emphasize more, and he agreed two more writers for the coming year would be a great idea.</p>
<p><img src="https://farm66.staticflickr.com/65535/54541500910_821e442836_b.jpg" alt="Priorities Rails"></p>
<p>I ended up turning it into an app of its own, adding accounts and separate projects. I developed a practice around it with my teams:</p>
<ol>
<li>Dump what you&rsquo;re doing into the tool.</li>
<li>Set Priority, Support, and Effort.</li>
<li>Look for disconnects.</li>
<li>Renegotiate priorities.</li>
</ol>
<p>I kept it pretty simple. Each priority has a page that shows similarly prioritized or supported items to give you an idea of what you&rsquo;re ranking similarly, and there&rsquo;s a notes field to capture whatever.</p>
<p>It works well with some teams, not so well with others. I&rsquo;ve learned over the years that you have to help the team keep from spiraling into minutiae, and you need to keep an eye on guilt reactions. But when it works, it&rsquo;s very clarifying and you can cut a lot of junk out of the backlog.</p>
<p>It&rsquo;s such a simple idea that it didn&rsquo;t really need a Rails app. One manager I hired just made his own version in a spreadsheet. Another did Jira reporting with labels. The value isn&rsquo;t so much the app as it is the thinking process, and having a supportive, thoughtful conversation with your team about what they&rsquo;re up to, what you can take off their plate, and where their time could be better spent.</p>
<p>Tonight it took about 30 minutes with Claude to get it turned into <a href="https://pdxmph.github.io/priorities-web">a PWA</a> that does about the same thing. It uses local storage and you can save it to your phone&rsquo;s homescreen. I don&rsquo;t think the app interface is good for a tool like this. It&rsquo;s meant to be a &ldquo;put it on the screen and let everyone talk about it,&rdquo; but I wanted to see how simple it would be to talk through the design and turn Claude loose on it. It took about 30 minutes of back-and-forth. Enough to get it working and convince me it&rsquo;s not a great idea for phones, but could be a simple webapp that doesn&rsquo;t need any infra.</p>
<p>People have asked me if I could dig out their logins to it years after we&rsquo;d worked together, so it works for some kinds of brains. And I&rsquo;ve thought a lot more about how prioritization works (or doesn&rsquo;t) since I built it. I like the idea of treating it less like AN APP YOU USE and almost more like an educational tool for people who are new to thinking about prioritization and don&rsquo;t really have their own model yet.</p>
<p>For instance, just looking at the little report, it could do more to suggest overall backlog health, and it could offer ways to think about disconnects. One thing I never got around to coding in last time but was able to add in two minutes tonight was what to do when something is low priority and getting a lot of effort. It used to be those items got a green checkmark &hellip; now they get called out.</p>
<p>Anyhow, fun.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Plain text is calming</title>
      <link>https://mike.puddingtime.org/posts/2025-05-21-plain-text-is-calming/</link>
      <pubDate>Wed, 21 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-21-plain-text-is-calming/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54537151905_067d9236ec_b.jpg&#34; alt=&#34;Monochrome: Two fishermen walk on a jetty under tall clouds.&#34;&gt;&lt;/p&gt;
&lt;p&gt;I managed to get too many plates spinning again, and made it worse for myself by trying very hard to use Asana, because it&amp;rsquo;s what we use for a few things at work and it&amp;rsquo;s easier to send todos back and forth in 1:1 and team boards. My own personal project board isn&amp;rsquo;t great and I vacillate between a column view and list view, but the fact is Asana just makes my brain freeze. I do not like it. It doesn&amp;rsquo;t matter how I arrange the view.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://farm66.staticflickr.com/65535/54537151905_067d9236ec_b.jpg" alt="Monochrome: Two fishermen walk on a jetty under tall clouds."></p>
<p>I managed to get too many plates spinning again, and made it worse for myself by trying very hard to use Asana, because it&rsquo;s what we use for a few things at work and it&rsquo;s easier to send todos back and forth in 1:1 and team boards. My own personal project board isn&rsquo;t great and I vacillate between a column view and list view, but the fact is Asana just makes my brain freeze. I do not like it. It doesn&rsquo;t matter how I arrange the view.</p>
<p>I think it is extra infuriating to me because I recently tried to add a project status field and noticed that easily ten of my coworkers had each created their own custom &ldquo;red/yellow/green&rdquo; status fields and added them to the collective library. They&rsquo;re <em>all</em> just red/yellow/green. Not other metadata, no nothing. You can&rsquo;t have not seen the other nine in the library in the process of deciding to make your own, but here we are. People are animals.</p>
<p>But too many plates, and I was feeling miserable and behind, so I opened up a fresh org-mode buffer and started outlining it all instead of trying to make it into little tasks or cards or whatever.</p>
<p>I keep coming back to something I love about org-mode: You can dip in and out of planning and writing about what you&rsquo;re planning so easily: One second you&rsquo;re defining a TODO, the next line down you&rsquo;re writing about it. No dipping into a notes box, etc. If a paragraph into the whole thing you think of a few extraneous tasks, make them checkboxes, keep writing, and add a cookie to the parent when you think of it so you can see completion. Decide a thing needs to get parked &hellip; org-refile it to the <code>* Parked</code> heading and keep moving. Setting priority is just <code>S-up</code> or <code>S-down</code>.</p>
<p>The only thing I regret is having to re-learn this over and over. There is a little extra overhead to keep an org project file and also do the necessary ticketing in Asana to keep things going with the team, but I can&rsquo;t <em>think</em> in Asana, I can just <em>track</em> there. Different things.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Hoarder</title>
      <link>https://mike.puddingtime.org/posts/2025-05-20-hoarder/</link>
      <pubDate>Tue, 20 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-20-hoarder/</guid>
      <description>&lt;p&gt;I started to write about Basic Memory this afternoon, and that gave me an idea that turned into an evening of coaching Claude into helping me do some stuff:&lt;/p&gt;
&lt;p&gt;I took my corpus of old micro.blog posts and migrated them into my notes. They&amp;rsquo;re all YAML-n-Markdown, so they could just be imported.&lt;/p&gt;
&lt;p&gt;I did the same with my mono-topic Hugo posts. Same idea.&lt;/p&gt;
&lt;p&gt;I made a script for the many, many daily posts I wrote over a few years, grateful that I stuck to a convention of organizing them with l2 headings: Each heading became a title of a new, atomized post. I did that because my daily posts could cover a lot, so now it&amp;rsquo;s all more searchable.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I started to write about Basic Memory this afternoon, and that gave me an idea that turned into an evening of coaching Claude into helping me do some stuff:</p>
<p>I took my corpus of old micro.blog posts and migrated them into my notes. They&rsquo;re all YAML-n-Markdown, so they could just be imported.</p>
<p>I did the same with my mono-topic Hugo posts. Same idea.</p>
<p>I made a script for the many, many daily posts I wrote over a few years, grateful that I stuck to a convention of organizing them with l2 headings: Each heading became a title of a new, atomized post. I did that because my daily posts could cover a lot, so now it&rsquo;s all more searchable.</p>
<p>And I <em>finally</em> sat down with my DayOne journals, all exported as JSON, and turned them into Basic-Memory-ready Markdown (which is to say &ldquo;Markdown&rdquo;). That included not just my journals from as long as I&rsquo;ve been using DayOne, but also the entire collection of 2,000 posts from my original blog &ndash; the one that started as MovableType, then became WordPress.</p>
<p>Oh, I also imported my Scribbles blog.</p>
<p>I&rsquo;ll put the source material up somewhere safe, but for the first time I have about 25 years worth of journals, diary entries, blog posts, and other personal writing sitting in a repo in a mostly standard format, organized by source.</p>
<p>It all also caused me to look at a 15-year-old project I worked on when management came around and told my team we&rsquo;d have to spend three weeks classifying 17 years worth of articles from 40 sites in a spreadsheet. I mustered my rudimentary Ruby and wrote <a href="https://github.com/pdxmph/autotaxonomizer">autotaxonomizer</a> in an afternoon, got a friendly dba to give me an article dump, sold my boss with a proof of concept, and reduced a three-week slog for 12 editors to each of them spending maybe 30 minutes filling out a spreadsheet with the keywords for their site categories.</p>
<p>Maybe the best part was after I talked the rest of the team through what I was going to do and noticed a text from my best work friend, Amy. I thought it was gonna be &ldquo;awesome!&rdquo; but it was &ldquo;This sucks. I was looking forward to three weeks of just filling out a spreadsheet.&rdquo;</p>
]]></content:encoded>
    </item>
    <item>
      <title>The eglot/lsp/apheleia rabbithole</title>
      <link>https://mike.puddingtime.org/posts/2025-05-20-the-eglotlspapheleia-rabbithole/</link>
      <pubDate>Tue, 20 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-20-the-eglotlspapheleia-rabbithole/</guid>
      <description>&lt;p&gt;&amp;hellip; I went down it last night and this morning.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m back on Doom after patiently dismantling a bunch of cruft I&amp;rsquo;d added to it. I set a goal of getting my package count under 200 (including all the batteries Doom includes). Because its default stance is that you want &lt;a href=&#34;https://github.com/emacs-lsp&#34;&gt;emacs-lsp&lt;/a&gt; and not &lt;a href=&#34;https://github.com/joaotavora/eglot&#34;&gt;eglot&lt;/a&gt; I went along with that initially, and it drove me a little bonkers. I think these things assume a much more organized person than I am, and LSP began to nag pretty much constantly until I made the mistake of telling it to blocklist &lt;code&gt;~/&lt;/code&gt;, at which point it pretty much stopped working, because there&amp;rsquo;s an implicit &lt;code&gt;-r&lt;/code&gt; in there.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>&hellip; I went down it last night and this morning.</p>
<p>I&rsquo;m back on Doom after patiently dismantling a bunch of cruft I&rsquo;d added to it. I set a goal of getting my package count under 200 (including all the batteries Doom includes). Because its default stance is that you want <a href="https://github.com/emacs-lsp">emacs-lsp</a> and not <a href="https://github.com/joaotavora/eglot">eglot</a> I went along with that initially, and it drove me a little bonkers. I think these things assume a much more organized person than I am, and LSP began to nag pretty much constantly until I made the mistake of telling it to blocklist <code>~/</code>, at which point it pretty much stopped working, because there&rsquo;s an implicit <code>-r</code> in there.</p>
<p>So I toggled eglot in <code>init.el</code>, and the nagging stopped. It seems to need less explicit guidance.</p>
<p>Something I like about eglot as it works in Doom vs. emacs-lsp is that if it doesn&rsquo;t have a needed server for a given mode, it just tells you that in the minibuffer. It doesn&rsquo;t steal focus, demand action, or try to download anything for you. emacs-lsp (at least as Doom handles it) does all of that stuff and it&rsquo;s disruptive. I think it&rsquo;s an attempt to help you keep flow by just handling the matter, but about 1 time in 10 in the past it causes a hang and that sucks way worse than &ldquo;first time editing this code, pause, install, resume.&rdquo;</p>
<p>That brought me to &ldquo;now that it is not driving me to distraction, why do we even want LSPs?&rdquo;</p>
<p>With Markdown it&rsquo;s to have <a href="https://github.com/artempyanykh/marksman">Marksman</a>, which does this very cool thing where if you lead with <code>[[</code> it offers autocompletions of all the Markdown files in your project and creates a wiki link to the file you can then hop over to with <code>C-c C-o</code> or just by tapping <code>return</code> if you <code>toggle wiki links</code> in markdown-mode.</p>
<p>With everything else, it&rsquo;s just sort of educational to have something smarter about the code than me providing running commentary.</p>
<p>Next up, I had turned on Doom&rsquo;s support for code formatting/prettification, and that was causing everything to barf errors on save, most because I hadn&rsquo;t installed an expected formatter. Doom uses <a href="https://github.com/radian-software/apheleia">apheleia</a>, which is pretty well behaved but was not working with Ruby. That got annoying because you have to grab the formatter (<a href="https://prettier.io">prettier</a>), then deal with some errors that&rsquo;d seem to have nothing to do at all with the fact that it wants a <code>.prettierrc</code> either in project root or <code>~/</code>.</p>
<p>I knew I got it working because I ran it on this:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="ch">#!/bin/env ruby</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">fruits</span> <span class="o">=</span> <span class="o">[</span><span class="s2">&#34;apple&#34;</span><span class="p">,</span><span class="s2">&#34;banana&#34;</span><span class="p">,</span><span class="s2">&#34;orange&#34;</span><span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">fruits</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">  <span class="nb">puts</span> <span class="n">f</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">apples</span> <span class="o">=</span> <span class="o">[</span><span class="s2">&#34;golden delicious&#34;</span><span class="p">,</span> <span class="s2">&#34;honeycrisp&#34;</span><span class="p">,</span> <span class="s2">&#34;fuji&#34;</span><span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">apples</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">a</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">  <span class="nb">puts</span> <span class="n">a</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span></span></span></code></pre></div>
<p>&hellip; and got back:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-ruby" data-lang="ruby"><span class="line"><span class="cl"><span class="ch">#!/bin/env ruby</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">fruits</span> <span class="o">=</span> <span class="sx">%w[apple banana orange]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">fruits</span><span class="o">.</span><span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="nb">puts</span> <span class="n">f</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">apples</span> <span class="o">=</span> <span class="o">[</span><span class="s2">&#34;golden delicious&#34;</span><span class="p">,</span> <span class="s2">&#34;honeycrisp&#34;</span><span class="p">,</span> <span class="s2">&#34;fuji&#34;</span><span class="o">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">apples</span><span class="o">.</span><span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">a</span><span class="o">|</span> <span class="nb">puts</span> <span class="n">a</span> <span class="p">}</span></span></span></code></pre></div>
<p>I sat with my feelings about that for a few seconds and decided it was educational. It&rsquo;s never really been about being particularly <em>good</em> or <em>sound</em> or <em>correct</em>, just about getting the thing to run.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Simple &#39;drafts&#39; for lmno.lol</title>
      <link>https://mike.puddingtime.org/posts/2025-05-19-simple-drafts-for-lmnolol/</link>
      <pubDate>Mon, 19 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-19-simple-drafts-for-lmnolol/</guid>
      <description>&lt;p&gt;lmno.lol does have a feature for hiding posts, but the last time I did blogging out of a monolithic file I struggled to remember to toggle that, so when I started working on a post that got longer and longer I ended up moving the work into a scratch buffer. That was annoying to me, so there&amp;rsquo;s this:&lt;/p&gt;






&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defvar&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mph/blog-drafts-file&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;expand-file-name&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;drafts_lmno.md&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;~/journal/blog/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defvar&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mph/blog-published-file&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;expand-file-name&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;lmno.md&amp;#34;&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;~/journal/blog/&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;defun&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mph/move-heading-between-draft-and-published&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Move current Markdown L1 heading to the other blog file (drafts_lmno.md or lmno.md).
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;If in drafts_lmno.md, moves to lmno.md. If in lmno.md, moves to drafts_lmno.md.
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;s&#34;&gt;Always inserts at the beginning of the file.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;interactive&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;  &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;let*&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;current-file&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;buffer-file-name&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;         &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;target-file&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;cond&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                       &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;string=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;file-truename&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;current-file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;file-truename&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mph/blog-drafts-file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mph/blog-published-file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                       &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;string=&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;file-truename&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;current-file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;file-truename&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mph/blog-published-file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;mph/blog-drafts-file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;                       &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;no&#34;&gt;t&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;user-error&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;This file is not drafts_lmno.md or lmno.md&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;c1&#34;&gt;;; Save and cut the heading&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;save-excursion&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;c1&#34;&gt;;; Find the beginning of the current L1 heading&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;beginning-of-line&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;looking-at&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;^# &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;bobp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;forward-line&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;-1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;unless&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;looking-at&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;^# &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;user-error&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Not on a Markdown L1 heading&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;start&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;;; Find the end of the current heading (next L1 heading or end of buffer)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;forward-line&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;while&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nb&#34;&gt;and&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;looking-at&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;^# &amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nf&#34;&gt;not&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;eobp&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;forward-line&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;1&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;c1&#34;&gt;;; Cut the heading and its content&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;k&#34;&gt;let&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;((&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;heading-text&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;buffer-substring-no-properties&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;start&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;delete-region&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;start&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;point&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;c1&#34;&gt;;; Paste into target file at beginning&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;          &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;with-current-buffer&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;find-file-noselect&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;target-file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;goto-char&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;point-min&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;insert&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;heading-text&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;            &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;save-buffer&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;message&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Moved heading to %s&amp;#34;&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;file-name-nondirectory&lt;/span&gt; &lt;span class=&#34;nv&#34;&gt;target-file&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;))))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;c1&#34;&gt;;; Doom leader key setup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;map!&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;:leader&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;ss&#34;&gt;:desc&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Blog commands&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s&#34;&gt;&amp;#34;l&amp;#34;&lt;/span&gt; &lt;span class=&#34;o&#34;&gt;&amp;#39;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;(&lt;/span&gt;&lt;span class=&#34;ss&#34;&gt;:ignore&lt;/span&gt; &lt;span class=&#34;no&#34;&gt;t&lt;/span&gt; &lt;span class=&#34;ss&#34;&gt;:which-key&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;blog&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;ss&#34;&gt;:desc&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;Move heading to other blog file&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s&#34;&gt;&amp;#34;l r&amp;#34;&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;mph/move-heading-between-draft-and-published&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;ss&#34;&gt;:desc&lt;/span&gt; &lt;span class=&#34;s&#34;&gt;&amp;#34;New lmno blog entry (md)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;      &lt;span class=&#34;s&#34;&gt;&amp;#34;l b&amp;#34;&lt;/span&gt; &lt;span class=&#34;nf&#34;&gt;#&amp;#39;&lt;/span&gt;&lt;span class=&#34;nv&#34;&gt;lmno-capture-post&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Just, &lt;code&gt;SPC l r&lt;/code&gt; on a given l1 heading to shuttle it to either the drafts file or the main blog file.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>lmno.lol does have a feature for hiding posts, but the last time I did blogging out of a monolithic file I struggled to remember to toggle that, so when I started working on a post that got longer and longer I ended up moving the work into a scratch buffer. That was annoying to me, so there&rsquo;s this:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-lisp" data-lang="lisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nb">defvar</span> <span class="nv">mph/blog-drafts-file</span> <span class="p">(</span><span class="nv">expand-file-name</span> <span class="s">&#34;drafts_lmno.md&#34;</span> <span class="s">&#34;~/journal/blog/&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nb">defvar</span> <span class="nv">mph/blog-published-file</span> <span class="p">(</span><span class="nv">expand-file-name</span> <span class="s">&#34;lmno.md&#34;</span> <span class="s">&#34;~/journal/blog/&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nb">defun</span> <span class="nv">mph/move-heading-between-draft-and-published</span> <span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="s">&#34;Move current Markdown L1 heading to the other blog file (drafts_lmno.md or lmno.md).
</span></span></span><span class="line"><span class="cl"><span class="s">If in drafts_lmno.md, moves to lmno.md. If in lmno.md, moves to drafts_lmno.md.
</span></span></span><span class="line"><span class="cl"><span class="s">Always inserts at the beginning of the file.&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="nv">interactive</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">(</span><span class="k">let*</span> <span class="p">((</span><span class="nv">current-file</span> <span class="p">(</span><span class="nv">buffer-file-name</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">         <span class="p">(</span><span class="nv">target-file</span> <span class="p">(</span><span class="nb">cond</span>
</span></span><span class="line"><span class="cl">                       <span class="p">((</span><span class="nf">string=</span> <span class="p">(</span><span class="nv">file-truename</span> <span class="nv">current-file</span><span class="p">)</span> <span class="p">(</span><span class="nv">file-truename</span> <span class="nv">mph/blog-drafts-file</span><span class="p">))</span> <span class="nv">mph/blog-published-file</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                       <span class="p">((</span><span class="nf">string=</span> <span class="p">(</span><span class="nv">file-truename</span> <span class="nv">current-file</span><span class="p">)</span> <span class="p">(</span><span class="nv">file-truename</span> <span class="nv">mph/blog-published-file</span><span class="p">))</span> <span class="nv">mph/blog-drafts-file</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                       <span class="p">(</span><span class="no">t</span> <span class="p">(</span><span class="nv">user-error</span> <span class="s">&#34;This file is not drafts_lmno.md or lmno.md&#34;</span><span class="p">)))))</span>
</span></span><span class="line"><span class="cl">    <span class="c1">;; Save and cut the heading</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nv">save-excursion</span>
</span></span><span class="line"><span class="cl">      <span class="c1">;; Find the beginning of the current L1 heading</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="nv">beginning-of-line</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="nv">while</span> <span class="p">(</span><span class="nb">and</span> <span class="p">(</span><span class="nf">not</span> <span class="p">(</span><span class="nv">looking-at</span> <span class="s">&#34;^# &#34;</span><span class="p">))</span> <span class="p">(</span><span class="nf">not</span> <span class="p">(</span><span class="nv">bobp</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nv">forward-line</span> <span class="mi">-1</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="nb">unless</span> <span class="p">(</span><span class="nv">looking-at</span> <span class="s">&#34;^# &#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nv">user-error</span> <span class="s">&#34;Not on a Markdown L1 heading&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="k">let</span> <span class="p">((</span><span class="nv">start</span> <span class="p">(</span><span class="nv">point</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">        <span class="c1">;; Find the end of the current heading (next L1 heading or end of buffer)</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nv">forward-line</span> <span class="mi">1</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="nv">while</span> <span class="p">(</span><span class="nb">and</span> <span class="p">(</span><span class="nf">not</span> <span class="p">(</span><span class="nv">looking-at</span> <span class="s">&#34;^# &#34;</span><span class="p">))</span> <span class="p">(</span><span class="nf">not</span> <span class="p">(</span><span class="nv">eobp</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl">          <span class="p">(</span><span class="nv">forward-line</span> <span class="mi">1</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="c1">;; Cut the heading and its content</span>
</span></span><span class="line"><span class="cl">        <span class="p">(</span><span class="k">let</span> <span class="p">((</span><span class="nv">heading-text</span> <span class="p">(</span><span class="nv">buffer-substring-no-properties</span> <span class="nv">start</span> <span class="p">(</span><span class="nv">point</span><span class="p">))))</span>
</span></span><span class="line"><span class="cl">          <span class="p">(</span><span class="nv">delete-region</span> <span class="nv">start</span> <span class="p">(</span><span class="nv">point</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">          <span class="c1">;; Paste into target file at beginning</span>
</span></span><span class="line"><span class="cl">          <span class="p">(</span><span class="nv">with-current-buffer</span> <span class="p">(</span><span class="nv">find-file-noselect</span> <span class="nv">target-file</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="nv">goto-char</span> <span class="p">(</span><span class="nv">point-min</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="nv">insert</span> <span class="nv">heading-text</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">(</span><span class="nv">save-buffer</span><span class="p">)))))</span>
</span></span><span class="line"><span class="cl">    <span class="p">(</span><span class="nv">message</span> <span class="s">&#34;Moved heading to %s&#34;</span> <span class="p">(</span><span class="nv">file-name-nondirectory</span> <span class="nv">target-file</span><span class="p">))))</span>
</span></span><span class="line"><span class="cl"><span class="c1">;; Doom leader key setup</span>
</span></span><span class="line"><span class="cl"><span class="p">(</span><span class="nv">map!</span> <span class="ss">:leader</span>
</span></span><span class="line"><span class="cl">      <span class="ss">:desc</span> <span class="s">&#34;Blog commands&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="s">&#34;l&#34;</span> <span class="o">&#39;</span><span class="p">(</span><span class="ss">:ignore</span> <span class="no">t</span> <span class="ss">:which-key</span> <span class="s">&#34;blog&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="ss">:desc</span> <span class="s">&#34;Move heading to other blog file&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="s">&#34;l r&#34;</span> <span class="nf">#&#39;</span><span class="nv">mph/move-heading-between-draft-and-published</span>
</span></span><span class="line"><span class="cl">      <span class="ss">:desc</span> <span class="s">&#34;New lmno blog entry (md)&#34;</span>
</span></span><span class="line"><span class="cl">      <span class="s">&#34;l b&#34;</span> <span class="nf">#&#39;</span><span class="nv">lmno-capture-post</span><span class="p">)</span></span></span></code></pre></div>
<p>Just, <code>SPC l r</code> on a given l1 heading to shuttle it to either the drafts file or the main blog file.</p>
]]></content:encoded>
    </item>
    <item>
      <title>So many brooms, so many buckets (Updated)</title>
      <link>https://mike.puddingtime.org/posts/2025-05-17-so-many-brooms-so-many-buckets-updated/</link>
      <pubDate>Sat, 17 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-17-so-many-brooms-so-many-buckets-updated/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54525470407_762922cb42_b.jpg&#34; alt=&#34;A yellow CAT with a big claw approaches a big blue box.&#34;&gt;&lt;/p&gt;
&lt;p&gt;I started the day playing around with &lt;a href=&#34;https://modelcontextprotocol.io/introduction&#34;&gt;MCP&amp;rsquo;s&lt;/a&gt; for Claude Desktop. I found &lt;a href=&#34;https://github.com/keegancsmith/emacs-mcp-server&#34;&gt;one for Emacs&lt;/a&gt; and one called &lt;a href=&#34;https://github.com/basicmachines-co/basic-memory&#34;&gt;Basic Memory&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;emacs-mcp-server sends evals to your running Emacs instance via &lt;code&gt;emacsclient.&lt;/code&gt; It&amp;rsquo;s sort of fascinating to watch in progress. Not the fastest thing on the planet, but it was a jolt the first time I turned my attention to something else and came back to realize it had created a new function and added it to my configuration.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://farm66.staticflickr.com/65535/54525470407_762922cb42_b.jpg" alt="A yellow CAT with a big claw approaches a big blue box."></p>
<p>I started the day playing around with <a href="https://modelcontextprotocol.io/introduction">MCP&rsquo;s</a> for Claude Desktop. I found <a href="https://github.com/keegancsmith/emacs-mcp-server">one for Emacs</a> and one called <a href="https://github.com/basicmachines-co/basic-memory">Basic Memory</a>.</p>
<p>emacs-mcp-server sends evals to your running Emacs instance via <code>emacsclient.</code> It&rsquo;s sort of fascinating to watch in progress. Not the fastest thing on the planet, but it was a jolt the first time I turned my attention to something else and came back to realize it had created a new function and added it to my configuration.</p>
<p>It was an even <em>bigger</em> jolt when I went after the problem of Emacs not being properly associated with a number of file types on my Mac:</p>
<p>It wrote a script to use <a href="https://github.com/moretension/duti">duti</a> to make all the associations, and when I reported that they weren&rsquo;t &ldquo;sticking&rdquo; it decided to write a systemd agent to periodically re-run its duti script. I didn&rsquo;t realize that had happened until macOS sent me a notification that something new was running on my behalf.</p>
<p>I &hellip; am not sure what to make of this, entirely.</p>
<p>Well &hellip; a little I am.</p>
<p>For about an hour, this seemed very cool. I haven&rsquo;t used Claude much, but with it able to pilot Emacs we got through a small reimplementation of org-capture for Markdown files that built on a few recent projects and allows for simple templating. Neat. Pretty complex. Functioned correctly.</p>
<p>Unlike previous sessions with an LLM doing this kind of thing, though, it was a little dulling and weird to have Claude and Emacs quietly collaborating to write all this. It got me to a fundamental understanding of how I am feeling about LLM-driven development:</p>
<p>I have one eye cocked over my shoulder because most people I know personally do not like to admit they perceive any utility with these things, often seem uncomfortable mentioning it if they do use them, and seem to feel a small, almost ritualized compulsion to shit on them even if they do perceive utility. There are any number of reasons someone might be there with these things. They activate a whole catalog of anxieties and irritations.</p>
<p><em>But</em> I am able to make things with these tools I couldn&rsquo;t make without 10x the time and effort, and the things I make let me get to what I want to do and spend less time doing the toil of supporting activities more quickly.</p>
<p>I guess I think that they are labor saving devices with the same caveats riding lawnmowers are. Like, I&rsquo;m glad to be free of the scythe, but also once I have a new John Deer riding mower I understand I can&rsquo;t sort of tie the steering wheel to a 15 degree angle, put a brick on the accelerator, and get back to my nap.</p>
<p>And I understand they&rsquo;re not people replacing. Even with the modest projects I work on I can see that.</p>
<p>But one thing I&rsquo;ve come to enjoy is the part that involves playing to their weaknesses:</p>
<p>I can&rsquo;t sit back and say &ldquo;make this thing for me that does <em>some broad directive</em>.&rdquo;</p>
<p>I have to ask for something simple, then slowly layer things on, redirecting from blind alleys or unwanted optimizations. It&rsquo;s a creative, iterative process and I enjoy it. It&rsquo;s a way to engage with a problem I&rsquo;d like to solve that involves patiently working through the steps of the problem, having second thoughts, realizing that I want things that are at odds with each other, sometimes realizing there&rsquo;s a much more elegant way to do something. The things I end up with are maybe not the best in terms of their coding craft, but they&rsquo;re tailored to my mental model.</p>
<p>So Claude and Emacs working in concert removed a small amount of friction I actually welcome in the process of looking at code, moving it over, reading it before evaluating it in a buffer, etc. I didn&rsquo;t care for that. It was alienating.</p>
<p>The <em>other</em> MCP server I mentioned, <a href="https://github.com/basicmachines-co/basic-memory">Basic Memory</a>, sits in Claude Desktop and remembers what you tell it by writing Markdown notes in a directory. They&rsquo;re basic &ldquo;Markdown-n-YAML&rdquo; files with light structure. You can have the usual sort of &ldquo;talk to a robot&rdquo; conversation for a while, then prompt it to make a note, and it does. Then those notes become part of its persistent context. There are db-backed services to do this at scale, but it suits me very much to have something like this. It&rsquo;s super transparent and introspectable.</p>
<p>In addition to notes, you can record &ldquo;Observations&rdquo; in your Markdown files. Observations are simple lines of Markdown, as these examples from the project repo:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-markdown" data-lang="markdown"><span class="line"><span class="cl"><span class="k">-</span> [method] Pour over extracts more floral notes than French press
</span></span><span class="line"><span class="cl"><span class="k">-</span> [tip] Grind size should be medium-fine for pour over <span class="ni">#brewing</span>
</span></span><span class="line"><span class="cl"><span class="k">-</span> [preference] Ethiopian beans have bright, fruity flavors (especially from Yirgacheffe)
</span></span><span class="line"><span class="cl"><span class="k">-</span> [fact] Lighter roasts generally contain more caffeine than dark roasts
</span></span><span class="line"><span class="cl"><span class="k">-</span> [experiment] Tried 1:15 coffee-to-water ratio with good results
</span></span><span class="line"><span class="cl"><span class="k">-</span> [resource] James Hoffman&#39;s V60 technique on YouTube is excellent
</span></span><span class="line"><span class="cl"><span class="k">-</span> [question] Does water temperature affect extraction of different compounds differently?
</span></span><span class="line"><span class="cl">- [note] My favorite local shop uses a 30-second bloom time</span></span></code></pre></div>
<p>These become grist for the MCP, alongside your notes, creating a sort of synthesizing glue, and it persists from session to session.</p>
<p>It is still far too early to say much about this. I&rsquo;ve got a few ideas about how to use it in some work and personal contexts, but haven&rsquo;t paused long enough to think of a workflow to facilitate those ideas.</p>
<p><em>( <strong>Note:</strong> Updated this post to narrow down a little more finely the kinds of social responses to LLMs and their use I have noticed.)</em></p>
]]></content:encoded>
    </item>
    <item>
      <title>A cautionary Syncthing tale</title>
      <link>https://mike.puddingtime.org/posts/2025-05-15-a-cautionary-syncthing-tale/</link>
      <pubDate>Thu, 15 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-15-a-cautionary-syncthing-tale/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54521695712_d63f238ec5_b.jpg&#34; alt=&#34;Sticker: &amp;ldquo;Fresh meat for the grinder&amp;rdquo;&#34;&gt;&lt;/p&gt;
&lt;p&gt;Over on the other blog I &lt;a href=&#34;https://mike.puddingtime.org/synctrain-for-syncthing-on-ios/&#34;&gt;recently enthused about SyncTrain&lt;/a&gt;, an iOS SyncThing client. I still maintain it is very good, but wow did I end up foot-gunning with it:&lt;/p&gt;
&lt;p&gt;I set Journelly up to use a SyncTrain share on my iPhone, promising myself I&amp;rsquo;d make sure to do the occasional manual sync, never leave my Journelly file open when not editing it on one of the real computers, etc. I still managed to end up with a sync error, and SyncThing dutifully created a sync error file. The Journelly app picked up that file and started using it as the default file to write to – I&amp;rsquo;m assuming iOS filesystem arcana is involved – which I wouldn&amp;rsquo;t have noticed if I hadn&amp;rsquo;t manually peeked in the directory instead of just using an org-capture template to make Journelly entries on my Mac.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://farm66.staticflickr.com/65535/54521695712_d63f238ec5_b.jpg" alt="Sticker: &ldquo;Fresh meat for the grinder&rdquo;"></p>
<p>Over on the other blog I <a href="https://mike.puddingtime.org/synctrain-for-syncthing-on-ios/">recently enthused about SyncTrain</a>, an iOS SyncThing client. I still maintain it is very good, but wow did I end up foot-gunning with it:</p>
<p>I set Journelly up to use a SyncTrain share on my iPhone, promising myself I&rsquo;d make sure to do the occasional manual sync, never leave my Journelly file open when not editing it on one of the real computers, etc. I still managed to end up with a sync error, and SyncThing dutifully created a sync error file. The Journelly app picked up that file and started using it as the default file to write to – I&rsquo;m assuming iOS filesystem arcana is involved – which I wouldn&rsquo;t have noticed if I hadn&rsquo;t manually peeked in the directory instead of just using an org-capture template to make Journelly entries on my Mac.</p>
<p>This was only going on for two days and three short entries, but it was pesky: I had a Journelly.org file that went up to Sunday, then a Journelly.sync-error.org file that had grabbed those three short entries, and also spawned a Journelly media folder with the same name. The fix, in the end, was to move my Journelly.org file and media folder into an empty iCloud folder, delete the Journelly app, then reinstall it and immediately tell it to use the new iCloud location. Then I was able to go in and tack on the three entries from the conflicted version. So no data lost, but in hindsight it was a bad move to try to use SyncThing on iOS for app data: There is no reliable background syncing on iOS, just semi-manual workarounds, so it&rsquo;s inevitable that there&rsquo;ll be a conflict.</p>
<p>The recommended non-in-app storage method for Journelly is iCloud, and I&rsquo;d endorse that if being able to edit your Journelly file on the desktop is mandatory.</p>
<p>It&rsquo;s not a ding on Journelly. It can only work with the files it tells you to. It&rsquo;s not a ding on SyncThing, which I use for several other applications. It&rsquo;s not a ding on SyncTrain, which does the best it can with the limitations iOS imposes. And it&rsquo;s not a ding on iOS, which we all understand quite well at this point: It doesn&rsquo;t really tolerate long-lived background services and nobody has ever pretended otherwise. It&rsquo;s on me for thinking it was a good idea in the first place.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Offsite&#39;s over</title>
      <link>https://mike.puddingtime.org/posts/2025-05-15-offsites-over/</link>
      <pubDate>Thu, 15 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-15-offsites-over/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54522731514_e87aff2e15_b.jpg&#34; alt=&#34;A table by a corner window with metal stools around it.&#34;&gt;&lt;/p&gt;
&lt;p&gt;Rainy afternoon here on the last day of the work offsite. We all went down to Pine St. Market and had ramen at the end of the day, and I said goodbye to some of the folks who came in from out of town. A few I&amp;rsquo;ll see once more for dinner tomorrow.&lt;/p&gt;
&lt;p&gt;This kind of work function is always a little draining by the time it&amp;rsquo;s over. Spending days in a small room, even with pretty good people, just takes some battery, and this one was a little melancholy because one of my teammates is moving on.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://farm66.staticflickr.com/65535/54522731514_e87aff2e15_b.jpg" alt="A table by a corner window with metal stools around it."></p>
<p>Rainy afternoon here on the last day of the work offsite. We all went down to Pine St. Market and had ramen at the end of the day, and I said goodbye to some of the folks who came in from out of town. A few I&rsquo;ll see once more for dinner tomorrow.</p>
<p>This kind of work function is always a little draining by the time it&rsquo;s over. Spending days in a small room, even with pretty good people, just takes some battery, and this one was a little melancholy because one of my teammates is moving on.</p>
]]></content:encoded>
    </item>
    <item>
      <title>trying to get org-capture to work is nature&#39;s way of telling us to slow down</title>
      <link>https://mike.puddingtime.org/posts/2025-05-13-trying-to-get-org-capture-to-work-is-natures-way-of-telling-us-to-slow-down/</link>
      <pubDate>Tue, 13 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-13-trying-to-get-org-capture-to-work-is-natures-way-of-telling-us-to-slow-down/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54518426203_6e7fccbac4_b.jpg&#34; alt=&#34;An attendant stands alone in front of a house of mirrors.&#34;&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been so happy with my emacs-plus install that there was an when-not-if element to the whole thing. It came today when I tried to get org-capture to work and it … just wouldn&amp;rsquo;t. So I tried an alternate build and lost over an hour I could have spent writing to uninstalling, reinstalling, troubleshooting, rewriting a launchd agent, etc.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://farm66.staticflickr.com/65535/54518426203_6e7fccbac4_b.jpg" alt="An attendant stands alone in front of a house of mirrors."></p>
<p>I&rsquo;ve been so happy with my emacs-plus install that there was an when-not-if element to the whole thing. It came today when I tried to get org-capture to work and it … just wouldn&rsquo;t. So I tried an alternate build and lost over an hour I could have spent writing to uninstalling, reinstalling, troubleshooting, rewriting a launchd agent, etc.</p>
<p>I&rsquo;m sensitive about my writing time, because my first team is in town this week and I&rsquo;ll be spending most of my days and a chunk of my evenings downtown doing <em>strategy stuff</em> with some great people, but I won&rsquo;t have any writing time. So that time I could have had today is lost.</p>
<p>… and I guess I&rsquo;m annoyed because it was such a stupid little rabbit hole: I thought something sounded sorta cool, figured it&rsquo;d just take a second and then <em>poof</em>. And such a violent <em>poof</em> that stuff I&rsquo;d had working <em>just fine</em> an hour earlier suddenly <em>wasn&rsquo;t working</em> thanks to some mystery of I don&rsquo;t even know what.</p>
<p>So, back on track again. In the end I just had to clean up some of my config&rsquo;s hygiene, and that was probably for the best anyhow.</p>
<p>But still down over an hour of writing time.</p>
<p>Spending this much time writing about it probably seems like a bad reaction to a small thing, but part of what I have liked a lot about my increased journaling and personal writing output has been the opportunity it affords me to learn and internalize. So this is sort of a public exercise in re-learning something: I&rsquo;m happier when I&rsquo;m making a thing, not when I&rsquo;m fucking around with the tools to make things.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Digging in on the photo project</title>
      <link>https://mike.puddingtime.org/posts/2025-05-12-digging-in-on-the-photo-project/</link>
      <pubDate>Mon, 12 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-12-digging-in-on-the-photo-project/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54515858100_18cc789705_b.jpg&#34; alt=&#34;A man walks by a brick building, partially painted light blue partially natural brick.&#34;&gt;&lt;/p&gt;
&lt;p&gt;I abhor feeling attachment to &lt;em&gt;things&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Years ago I was out in the garage going through some old boxes at the same time I was thinking about some people I knew who seemed very connected to what they had been, and uncertain of how to go about being who they had become. So when I reached into the box and pulled out some old object I thought, &amp;ldquo;I don&amp;rsquo;t want this thing anymore,&amp;rdquo; then I thought &amp;ldquo;oh, but it&amp;rsquo;s a reminder of …&amp;rdquo; and then I thought, &amp;ldquo;I&amp;rsquo;m in no danger of forgetting that time.&amp;rdquo;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://farm66.staticflickr.com/65535/54515858100_18cc789705_b.jpg" alt="A man walks by a brick building, partially painted light blue partially natural brick."></p>
<p>I abhor feeling attachment to <em>things</em>.</p>
<p>Years ago I was out in the garage going through some old boxes at the same time I was thinking about some people I knew who seemed very connected to what they had been, and uncertain of how to go about being who they had become. So when I reached into the box and pulled out some old object I thought, &ldquo;I don&rsquo;t want this thing anymore,&rdquo; then I thought &ldquo;oh, but it&rsquo;s a reminder of …&rdquo; and then I thought, &ldquo;I&rsquo;m in no danger of forgetting that time.&rdquo;</p>
<p>Since then, I&rsquo;ve tried to just … put things aside when it occurs to me.</p>
<p>My collection of digital photographs is not something I feel able to simply set aside. I got a reminder of that this afternoon, when I noticed Arq complaining about a failed Lightroom backup that, on initial investigation, appeared to be a tanked drive. The drive had not tanked, but there was a moment of uncertainty about whether data was lost, and how much that might be, what it would take to recover it, etc.</p>
<p>I&rsquo;ve got my Lightroom stuff split into two vaults. One runs from ca. 2000 to 2014, and the other covers 2015 to now. The vault with older stuff just sits there. It&rsquo;s poorly curated, with duplicates and culls all mixed in. I am sure most of what I care about at all is in the equally desultory shoebox that is my iCloud Photos collection. It&rsquo;s all backed up both to NAS and my B2 account (though, you know, B2 seems <a href="https://arstechnica.com/gadgets/2025/04/backblaze-responds-to-claims-of-sham-accounting-customer-backups-at-risk/">less ikely to outlive me</a> than I&rsquo;d hoped) but it&rsquo;s not usable to anyone in my family, really. It&rsquo;s just a mess that happens to be backed up. The newer vault is in a little better shape, but it&rsquo;s still not great.</p>
<p>Anyhow, the brief not-incident reminded me of the project I&rsquo;ve meant to for a couple of years:</p>
<ul>
<li>Go through year by year and figure out the 50 or 100 images from each year that get five stars. I&rsquo;ve done that for a few years, but when I went way back it got hard.</li>
<li>Opportunistically delete the culls and duplicates when I spot them.</li>
<li>Make an artifact out of the five-star images. Right now I&rsquo;m thinking photo books.</li>
<li>Organize those &ldquo;best of the year&rdquo; images somewhere they&rsquo;re easy for family to find. flickr has an actual non-profit foundation now, and it&rsquo;s not expensive to maintain a Pro account.</li>
<li>Establish 3-2-1 backups terminating in Glacier, and quit thinking about it all as a potential thing. Rather, realize the potential as best I can imagine living with, and then set it aside.</li>
</ul>
<p>There are a few other moving parts I identified as I was outlining how to set the project up and actually do it, but it&rsquo;s definitely time.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Experiments in atomic writing</title>
      <link>https://mike.puddingtime.org/posts/2025-05-12-experiments-in-atomic-writing/</link>
      <pubDate>Mon, 12 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-12-experiments-in-atomic-writing/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54516189438_ec2728009f_b.jpg&#34; alt=&#34;Three men sit around a Starbucks.&#34;&gt;&lt;/p&gt;
&lt;p&gt;I am not sure how this will go and it could be this is futzing under another guise, but this evening I &lt;em&gt;did&lt;/em&gt; improve on my futz pattern a little by choosing to devote a journal entry to some thinking I&amp;rsquo;ve been doing about The News, how to consume it, how much to consume, etc. etc. IOW, instead of diddling around with a tool or a toy, I started writing about something that matters to me.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://farm66.staticflickr.com/65535/54516189438_ec2728009f_b.jpg" alt="Three men sit around a Starbucks."></p>
<p>I am not sure how this will go and it could be this is futzing under another guise, but this evening I <em>did</em> improve on my futz pattern a little by choosing to devote a journal entry to some thinking I&rsquo;ve been doing about The News, how to consume it, how much to consume, etc. etc. IOW, instead of diddling around with a tool or a toy, I started writing about something that matters to me.</p>
<p>Ordinarily, writing like that either gets punted into a blog post pretty quickly or gets a few sentences then peters off. Worse, it sometimes becomes a blog draft that I kill because it&rsquo;s not a viable blog post for whatever reason, but now it&rsquo;s too other-oriented to be a good journal entry any longer.</p>
<p>Tonight I started drifting in that direction – the blog post that would not come to a good end– and I didn&rsquo;t like that. But there&rsquo;s more to think about because when I look at my behavior toward news media in the past several months something has definitely changed very profoundly, and while we can all guess <em>why</em> I&rsquo;m not sure how to feel about that yet.</p>
<p>Last time around, post-2016, I picked up a lot of baggage about media consumption, what I made of <em>other</em> peoples&rsquo; apparent patterns, what I thought that was doing to them, where I thought it was coming from, and what I thought of all the rationales people deploy to justify their choices.</p>
<p>This time around, I can feel some of those thoughts rolling around inside, but I feel a little more detached from them, it feels a little less personal, things that seemed very urgent seem less so, and some stuff just can&rsquo;t be allowed to matter. It turns out <a href="https://xkcd.com/386/">someone is <em>still</em> wrong on the internet</a>.</p>
<p>But I don&rsquo;t want to write an essay about all of it. I&rsquo;ve never liked outlines much. So I decided to experiment with atomic notes on this topic, just committing little nuggets and chaining them off of each other, but when I could tell I was headed out of the narrow confines of one atom – say, &ldquo;what&rsquo;s good about the news?&rdquo; – and into another atom – &ldquo;how much news is enough to get the good parts?&rdquo; – I made a new atom and picked up there.</p>
<p>It helped me in one way that didn&rsquo;t occur to me going in, which is that it&rsquo;s much easier to resist having a narrative of some kind, or an urge toward a conclusion. When I asked &ldquo;what&rsquo;s good about the news?&rdquo; and wrote about that, and then thought, &ldquo;probably a good idea to make a sibling to ask what&rsquo;s bad about it,&rdquo; that got its own node and I didn&rsquo;t have both sets of things sitting there right next to each other jostling for head of the line, or demanding I steer toward the conclusion.</p>
<p>Because I don&rsquo;t <em>have</em> a conclusion. All I know is that something has definitely changed in my thinking and behavior around a core part of most college-educated peoples&rsquo; ideas about how they&rsquo;re supposed to behave in the world, and I&rsquo;d like to think it through without having a conclusion in mind. So we&rsquo;ll keep at this for now.</p>
<p>Oh, right, what&rsquo;s the toy: <a href="https://protesilaos.com/emacs/denote">Denote</a> and <a href="https://protesilaos.com/emacs/denote-sequence">denote-sequence</a>. Of all the note frameworks, etc. that I&rsquo;ve played around with, my org-based Denote notes are still the most legible, useful, and navigable. Still getting the hang of how to wrangle a sequence, but not so much that I&rsquo;ve had to stop writing and screw around with it to the point of a derail.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Eugene</title>
      <link>https://mike.puddingtime.org/posts/2025-05-11-eugene/</link>
      <pubDate>Sun, 11 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-11-eugene/</guid>
      <description>&lt;p&gt;We took a trip to Eugene to visit Ben. Walking around this morning we came across the &lt;a href=&#34;https://smjhouse.org&#34;&gt;Shelton McMurphey Johnson House&lt;/a&gt;, and then picked up the trail up Skinner&amp;rsquo;s Butte.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54513438300_9ff7ef8f66_b.jpg&#34; alt=&#34;Concrete steps leading up to an old Victorian mansion&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54513267499_f2417da57f_b.jpg&#34; alt=&#34;An air conditioner, old electricity meters, and barred windows on a green building&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54513346273_fc50bfb2b1_b.jpg&#34; alt=&#34;A rock climber scales a face&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54513438965_7fa5b541d0_b.jpg&#34; alt=&#34;A covered parking area in green and yellow light at night&#34;&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>We took a trip to Eugene to visit Ben. Walking around this morning we came across the <a href="https://smjhouse.org">Shelton McMurphey Johnson House</a>, and then picked up the trail up Skinner&rsquo;s Butte.</p>
<p><img src="https://farm66.staticflickr.com/65535/54513438300_9ff7ef8f66_b.jpg" alt="Concrete steps leading up to an old Victorian mansion"></p>
<p><img src="https://farm66.staticflickr.com/65535/54513267499_f2417da57f_b.jpg" alt="An air conditioner, old electricity meters, and barred windows on a green building"></p>
<p><img src="https://farm66.staticflickr.com/65535/54513346273_fc50bfb2b1_b.jpg" alt="A rock climber scales a face"></p>
<p><img src="https://farm66.staticflickr.com/65535/54513438965_7fa5b541d0_b.jpg" alt="A covered parking area in green and yellow light at night"></p>
]]></content:encoded>
    </item>
    <item>
      <title>flickr&#39;s alright</title>
      <link>https://mike.puddingtime.org/posts/2025-05-11-flickrs-alright/</link>
      <pubDate>Sun, 11 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-11-flickrs-alright/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been using SmugMug for a while, and really like how well it has worked for &lt;a href=&#34;https://pix.puddingtime.org&#34;&gt;my pix subdomain&lt;/a&gt;, but it has always come with a little feeling of &amp;ldquo;what am I even doing on SmugMug to begin with?&amp;rdquo; It&amp;rsquo;s meant for people who want to sell their photography, and everything about its customer comms reminds you of that.&lt;/p&gt;
&lt;p&gt;In the process of getting imgup to broaden its horizons and work with flickr, I remembered that I actually &lt;em&gt;like&lt;/em&gt; flickr (which is owned and operated by SmugMug now). It&amp;rsquo;s just more oriented around &amp;ldquo;you want to put photos up online,&amp;rdquo; without any emphasis on being a &amp;ldquo;pro,&amp;rdquo; and without Glass&amp;rsquo;s … whatever it is about Glass&amp;rsquo;s vibe.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I&rsquo;ve been using SmugMug for a while, and really like how well it has worked for <a href="https://pix.puddingtime.org">my pix subdomain</a>, but it has always come with a little feeling of &ldquo;what am I even doing on SmugMug to begin with?&rdquo; It&rsquo;s meant for people who want to sell their photography, and everything about its customer comms reminds you of that.</p>
<p>In the process of getting imgup to broaden its horizons and work with flickr, I remembered that I actually <em>like</em> flickr (which is owned and operated by SmugMug now). It&rsquo;s just more oriented around &ldquo;you want to put photos up online,&rdquo; without any emphasis on being a &ldquo;pro,&rdquo; and without Glass&rsquo;s … whatever it is about Glass&rsquo;s vibe.</p>
<p>In the end, it&rsquo;s not about flickr being a permanent &ldquo;home.&rdquo; I wouldn&rsquo;t trust any commercial entity to be home for my photos. But it&rsquo;s a fine place to put photos to share.</p>
]]></content:encoded>
    </item>
    <item>
      <title>The futzes</title>
      <link>https://mike.puddingtime.org/posts/2025-05-11-the-futzes/</link>
      <pubDate>Sun, 11 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-11-the-futzes/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54513392574_38506308f6_b.jpg&#34; alt=&#34;Seattle Waterfront&#34;&gt;&lt;/p&gt;
&lt;p&gt;Yeesh. So, re: imgup. It is pretty much &amp;ldquo;done&amp;rdquo; to me as a tool. Meaning, it does exactly what I want it to do, plus a few things I didn&amp;rsquo;t start out with. There&amp;rsquo;s maybe one more tweak (&amp;ldquo;just give me the URL&amp;rdquo;) I can go add in five minutes when I get around to it. But today I was thinking &amp;ldquo;oh, it&amp;rsquo;d be cool if it had a history,&amp;rdquo; and &amp;ldquo;oh, it&amp;rsquo;d be cool if it could show thumbnails in kitty.&amp;rdquo;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://farm66.staticflickr.com/65535/54513392574_38506308f6_b.jpg" alt="Seattle Waterfront"></p>
<p>Yeesh. So, re: imgup. It is pretty much &ldquo;done&rdquo; to me as a tool. Meaning, it does exactly what I want it to do, plus a few things I didn&rsquo;t start out with. There&rsquo;s maybe one more tweak (&ldquo;just give me the URL&rdquo;) I can go add in five minutes when I get around to it. But today I was thinking &ldquo;oh, it&rsquo;d be cool if it had a history,&rdquo; and &ldquo;oh, it&rsquo;d be cool if it could show thumbnails in kitty.&rdquo;</p>
<p>No real utility to those things, exactly. Well, the history idea <em>kind of</em> has utility. The kitty thumbnails thing is sheer &ldquo;what if I could …&rdquo; pointlessness I&rsquo;d never take advantage of. I was just riding in the car up I5 from Eugene, sort of daydreaming, and I imagined what the feature would look like and got a little curious.</p>
<p>But making it do that would just be noodling I could do to noodle. It&rsquo;s <em>not</em> doing the things I made that tool to help me do, which are write and share photos.</p>
<p>I&rsquo;m glad I realized I didn&rsquo;t need to do anything more with it. I guess I just wish I didn&rsquo;t have the impulse to begin with. I&rsquo;m sitting around the house, maybe a little bored, not wanting to do anything in particular … I&rsquo;d rather my first impulse be &ldquo;pick up a book,&rdquo; or &ldquo;work with some photos,&rdquo; or &ldquo;listen carefully to some album.&rdquo;</p>
<p>I think some of this is recent back problems. I let myself stop running for a few weeks and tightened up, so now it&rsquo;s a back-and-forth process to get the stiffness worked out, and it feels <em>great</em> to spend a lot of time in a chair with a heating pad, being acutely aware that I don&rsquo;t want to do much. But &ldquo;not doing much&rdquo; has seeped into things I could be doing, not just things it&rsquo;s probably not a good idea to do a ton of.</p>
]]></content:encoded>
    </item>
    <item>
      <title>writeroom-mode</title>
      <link>https://mike.puddingtime.org/posts/2025-05-11-writeroom-mode/</link>
      <pubDate>Sun, 11 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-11-writeroom-mode/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54513402166_3694b82d0c_b.jpg&#34; alt=&#34;rusty tools hanging on a barn wall&#34;&gt;&lt;/p&gt;
&lt;p&gt;For whatever reason I have an allergic reaction to the phrase &amp;ldquo;distraction-free,&amp;rdquo; but as I&amp;rsquo;ve waffled back and forth between org-mode and Markdown as the starting point for prose I&amp;rsquo;ve also thought about how my model writing app on macOS is probably &lt;a href=&#34;https://ia.net/writer&#34;&gt;iA Writer&lt;/a&gt;, because it&amp;rsquo;s just so easy on the eyes. I kinda buy the limited choice it offers, too. That might be why it edges out Ulysses.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://farm66.staticflickr.com/65535/54513402166_3694b82d0c_b.jpg" alt="rusty tools hanging on a barn wall"></p>
<p>For whatever reason I have an allergic reaction to the phrase &ldquo;distraction-free,&rdquo; but as I&rsquo;ve waffled back and forth between org-mode and Markdown as the starting point for prose I&rsquo;ve also thought about how my model writing app on macOS is probably <a href="https://ia.net/writer">iA Writer</a>, because it&rsquo;s just so easy on the eyes. I kinda buy the limited choice it offers, too. That might be why it edges out Ulysses.</p>
<p>So I&rsquo;ve given <a href="https://github.com/joostkremers/writeroom-mode">writeroom-mode</a> for Emacs a spin and it does a nice job of presenting a simple, clean writing screen. No modeline, pulls the margins in, and you can enlarge the font (and pick a variable pitch one).</p>
<p>On a macBook with Emacs running in full screen mode it is, indeed, pretty distraction free. Using the monokai-pro theme, it&rsquo;s plenty contrasty, but not glaring.</p>
<p>It&rsquo;s sort of nice <a href="https://puddingtime.org/emacs-plus">having a good Emacs build again</a>. When I have an overloaded config with too much going on, things feel sort of rickety and weird and there&rsquo;s an underlying sense of non-calm under the surface that makes it hard to use as a creative tool.</p>
<p>When it&rsquo;s set up for simplicity and stability – when there&rsquo;s less junk going on – it&rsquo;s able to just sort of look nice and feel comfortable.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Missing Mixel</title>
      <link>https://mike.puddingtime.org/posts/2025-05-10-missing-mixel/</link>
      <pubDate>Sat, 10 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-10-missing-mixel/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://live.staticflickr.com/7146/6774603235_d9ee88a716_b.jpg&#34; alt=&#34;A collage of clipart and Soviet-era imagery&#34;&gt;&lt;/p&gt;
&lt;p&gt;Does anyone else remember Mixel? It was a collaborative collage app that arrived early in the iPad era, was amazing for a little while, then pivoted into online postcards or something, then slipped under the waves.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://live.staticflickr.com/7174/6810827461_e4c9ba06a0_b.jpg&#34; alt=&#34;Line art astronauts come through a swirling portal in a wheat field&#34;&gt;&lt;/p&gt;
&lt;p&gt;You started with a blank canvas and a collection of images that sort of acted like stickers you could plop on the canvas and manipulate into a collage. The collection was socially driven, so for periods something would find its way into collective consciousness, spawning a bunch of riffs on a theme.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://live.staticflickr.com/7146/6774603235_d9ee88a716_b.jpg" alt="A collage of clipart and Soviet-era imagery"></p>
<p>Does anyone else remember Mixel? It was a collaborative collage app that arrived early in the iPad era, was amazing for a little while, then pivoted into online postcards or something, then slipped under the waves.</p>
<p><img src="https://live.staticflickr.com/7174/6810827461_e4c9ba06a0_b.jpg" alt="Line art astronauts come through a swirling portal in a wheat field"></p>
<p>You started with a blank canvas and a collection of images that sort of acted like stickers you could plop on the canvas and manipulate into a collage. The collection was socially driven, so for periods something would find its way into collective consciousness, spawning a bunch of riffs on a theme.</p>
<p><img src="https://live.staticflickr.com/7188/6855269919_9ee3c8f452_b.jpg" alt="Photo montage of a giant Leonardo DiCaprio against a burning cityscape"></p>
<p>You could import someone else&rsquo;s Mixel and get access to all the little clips and elements they created.</p>
<p><img src="https://live.staticflickr.com/7162/6777265173_38d418f3e3_b.jpg" alt="Photo collage of a vintage station wagon and camper against an infernal backdrop"></p>
<p>There were some genuinely gifted people on Mixel, making little collages out of tiny, intricate parts. There were a lot of goofballs. For periods someone would drift through your field of view, and maybe you&rsquo;d start playfully volleying ideas back and forth, then one or the other would drift off.</p>
<p>Possibly one of the best creative-apps-with-social-component ever.</p>
<p><a href="https://www.flickr.com/photos/michaelhall/albums/72157628944175181/with/6794392705">All the ones I managed to preserve before the service tanked.</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>I don&#39;t miss lockdown &amp;#x2026;</title>
      <link>https://mike.puddingtime.org/posts/2025-05-09-i-dont-miss-lockdown-x2026/</link>
      <pubDate>Fri, 09 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-09-i-dont-miss-lockdown-x2026/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://photos.smugmug.com/photos/i-SSQFFqX/0/NPD7vdwXBLPJgbgpBT98zkw3CVVLrKgrsjKngT7df/XL/i-SSQFFqX-XL.jpg&#34; alt=&#34;A woman eats alone in a plastic-enclosed outdoor eating area&#34;&gt; … but I do miss that it exerted tremendous pressure to figure out whatever it took to do things I cared about, and that sustained me.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://photos.smugmug.com/photos/i-mBV2z7q/0/Kv53qhgKf4WqrQPrvdrDcbG86HRjPZkfVQwMJJF8Z/XL/i-mBV2z7q-XL.jpg&#34; alt=&#34;Food Cart&#34;&gt;&lt;/p&gt;
&lt;p&gt;So for a long while there, almost every night, it was just &amp;ldquo;grab a camera and go somewhere.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://photos.smugmug.com/photos/i-WJb98qh/0/KkxRPKKL9FxD5rfZBN7JwjchQgsq3kXWShFW4p9Xg/XL/i-WJb98qh-XL.jpg&#34; alt=&#34;A masked man in a red hat reads a menu on the wall&#34;&gt;&lt;/p&gt;
&lt;p&gt;I guess I&amp;rsquo;m thinking about it because when we were walking on Foster Road last night I noticed that three places that had kept their outdoor areas all the way through now have taken them down in the space of a week.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://photos.smugmug.com/photos/i-SSQFFqX/0/NPD7vdwXBLPJgbgpBT98zkw3CVVLrKgrsjKngT7df/XL/i-SSQFFqX-XL.jpg" alt="A woman eats alone in a plastic-enclosed outdoor eating area"> … but I do miss that it exerted tremendous pressure to figure out whatever it took to do things I cared about, and that sustained me.</p>
<p><img src="https://photos.smugmug.com/photos/i-mBV2z7q/0/Kv53qhgKf4WqrQPrvdrDcbG86HRjPZkfVQwMJJF8Z/XL/i-mBV2z7q-XL.jpg" alt="Food Cart"></p>
<p>So for a long while there, almost every night, it was just &ldquo;grab a camera and go somewhere.&rdquo;</p>
<p><img src="https://photos.smugmug.com/photos/i-WJb98qh/0/KkxRPKKL9FxD5rfZBN7JwjchQgsq3kXWShFW4p9Xg/XL/i-WJb98qh-XL.jpg" alt="A masked man in a red hat reads a menu on the wall"></p>
<p>I guess I&rsquo;m thinking about it because when we were walking on Foster Road last night I noticed that three places that had kept their outdoor areas all the way through now have taken them down in the space of a week.</p>
<p><img src="https://photos.smugmug.com/photos/i-NMkJTqS/0/MdWrGfPSxSsf3Vdw8tpp9srq2qF2PJrbncChsPhMk/XL/i-NMkJTqS-XL.jpg" alt="A gas station attendant at run down station"></p>
]]></content:encoded>
    </item>
    <item>
      <title>imgup 0.6 (flickr!)</title>
      <link>https://mike.puddingtime.org/posts/2025-05-09-imgup-06-flickr/</link>
      <pubDate>Fri, 09 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-09-imgup-06-flickr/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://farm66.staticflickr.com/65535/54509153410_4d4d6e94e3_b.jpg&#34; alt=&#34;Yellow brick walls in an SF Chinatown alley at night&#34;&gt;&lt;/p&gt;
&lt;p&gt;flickr&amp;rsquo;s API is way more comprehensible than SmugMug&amp;rsquo;s, so adding flickr support went down much more quickly. Just get an API key/secret (links in the README) and step through onboard to auth your copy of imgup.&lt;/p&gt;
&lt;p&gt;Otherwise, it&amp;rsquo;s the exact same interface and UI. You just have to add a &lt;code&gt;--backend&lt;/code&gt; argument to use flickr when you run it:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;imgup -b flickr -t &amp;quot;The Title&amp;quot; -c &amp;quot;The Caption&amp;quot; -f md img_123.jpg&lt;/code&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://farm66.staticflickr.com/65535/54509153410_4d4d6e94e3_b.jpg" alt="Yellow brick walls in an SF Chinatown alley at night"></p>
<p>flickr&rsquo;s API is way more comprehensible than SmugMug&rsquo;s, so adding flickr support went down much more quickly. Just get an API key/secret (links in the README) and step through onboard to auth your copy of imgup.</p>
<p>Otherwise, it&rsquo;s the exact same interface and UI. You just have to add a <code>--backend</code> argument to use flickr when you run it:</p>
<p><code>imgup -b flickr -t &quot;The Title&quot; -c &quot;The Caption&quot; -f md img_123.jpg</code></p>
<p>You can skip any of them except the image itself, but you probably want to set <code>--caption</code> to get a description/alt text back.</p>
<p><a href="https://github.com/pdxmph/imgup-cli">pdxmph/imgup-cli</a> (Gem on the release page)</p>
<p>I also added a pair of extras:</p>
<ul>
<li>A Hazel folder action script: If you set the &ldquo;caption&rdquo; field in LightRoom or Apple Photos, then export an image into the watched folder, you&rsquo;ll get a snippet back to your clipboard with the caption as description/alt text.</li>
<li>A Raycast script action: (Needs to be fixed to use the new backend selector, so hardcode that if you want to just get it running with flickr by adding the argument in the script)</li>
</ul>
]]></content:encoded>
    </item>
    <item>
      <title>imgup-cli 0.1.0</title>
      <link>https://mike.puddingtime.org/posts/2025-05-09-imgup-cli-010/</link>
      <pubDate>Fri, 09 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-09-imgup-cli-010/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://photos.smugmug.com/photos/i-rxrZLQf/0/KRxchj8kFzcmvbhrL9LwhnSKH8xg2PMq4JgzfmJvZ/XL/i-rxrZLQf-XL.jpg&#34; alt=&#34;High on Fire&#34;&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been using imgup as a cli tool for a few days and it has worked pretty well. A few things bothered me about it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The OAuth situation was janky and not very portable. You had to have a .env file with very little help in the way of configuring it.&lt;/li&gt;
&lt;li&gt;Onboarding via oauth was non-existent.&lt;/li&gt;
&lt;li&gt;Configuring a target album involved fiddling around in the API or knowing exactly where to hover your mouse on the website.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So I spent some time just cleaving the CLI out of the core project and working on cleaning some of that up.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://photos.smugmug.com/photos/i-rxrZLQf/0/KRxchj8kFzcmvbhrL9LwhnSKH8xg2PMq4JgzfmJvZ/XL/i-rxrZLQf-XL.jpg" alt="High on Fire"></p>
<p>I&rsquo;ve been using imgup as a cli tool for a few days and it has worked pretty well. A few things bothered me about it:</p>
<ul>
<li>The OAuth situation was janky and not very portable. You had to have a .env file with very little help in the way of configuring it.</li>
<li>Onboarding via oauth was non-existent.</li>
<li>Configuring a target album involved fiddling around in the API or knowing exactly where to hover your mouse on the website.</li>
</ul>
<p>So I spent some time just cleaving the CLI out of the core project and working on cleaning some of that up.</p>
<p>There&rsquo;s <a href="https://github.com/pdxmph/imgup-cli">a new repo</a>, and a better onboarding deal:</p>
<ul>
<li>Install the gem (available from the <a href="https://github.com/pdxmph/imgup-cli/releases">release page</a>)</li>
<li>Run <code>imgup setup</code></li>
<li>Go through a not-great but viable oauth setup</li>
<li>Reply to a prompt to pick a target album</li>
<li>Get your config file written for you in a normal place</li>
<li>Start using</li>
</ul>
<p>No more .env files or any of that. It behaves way more like a normal app you can just go install.</p>
<p>I wanted to get it into that shape because I like how it is working now: It&rsquo;s a little bit of plumbing you can fit into all sorts of possible workflows to make it easier to do a small thing that can involve fiddling and typos when all you really want to do is put an image in a blog post. At the same time, while SmugMug is cool and all, I&rsquo;d like to fold in support for flickr, imgur, and maybe a few others that are more common, and also leave the web UI behind.</p>
<p>So as I have time and feel like messing around, I&rsquo;ll probably go after flickr next, since I have an account and plenty of albums to play around with.</p>
<p>(I was hoping to include <a href="https://some.pics">omg.lol&rsquo;s some.pics</a>, but there&rsquo;s no API to talk to.)</p>
]]></content:encoded>
    </item>
    <item>
      <title>Bar Carlo</title>
      <link>https://mike.puddingtime.org/posts/2025-05-08-bar-carlo/</link>
      <pubDate>Thu, 08 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-08-bar-carlo/</guid>
      <description>&lt;p&gt;We decided to walk down to Foster Rd. for dinner at Bruno&amp;rsquo;s tonight, and walked past Bar Carlo. I still haven&amp;rsquo;t adjusted to the new red paint job, but it&amp;rsquo;s pretty striking.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://photos.smugmug.com/photos/i-fCcB6kT/0/MLNM2mmfRCQZ9FxXZTgCN3N7b8kz46g8FqWC2wnPg/XL/i-fCcB6kT-XL.jpg&#34; alt=&#34;Bright red Bar Carlo in the low evening sun.&#34;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://photos.smugmug.com/photos/i-mrCZ4ww/0/Mmt8TSGDpcTTC6nbVf9hczFRcQckMNkbMFkXrjnMb/XL/i-mrCZ4ww-XL.jpg&#34; alt=&#34;Bar Carlo back when it was blue.&#34;&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>We decided to walk down to Foster Rd. for dinner at Bruno&rsquo;s tonight, and walked past Bar Carlo. I still haven&rsquo;t adjusted to the new red paint job, but it&rsquo;s pretty striking.</p>
<p><img src="https://photos.smugmug.com/photos/i-fCcB6kT/0/MLNM2mmfRCQZ9FxXZTgCN3N7b8kz46g8FqWC2wnPg/XL/i-fCcB6kT-XL.jpg" alt="Bright red Bar Carlo in the low evening sun."></p>
<p><img src="https://photos.smugmug.com/photos/i-mrCZ4ww/0/Mmt8TSGDpcTTC6nbVf9hczFRcQckMNkbMFkXrjnMb/XL/i-mrCZ4ww-XL.jpg" alt="Bar Carlo back when it was blue."></p>
]]></content:encoded>
    </item>
    <item>
      <title>Black mist filters</title>
      <link>https://mike.puddingtime.org/posts/2025-05-08-black-mist-filters/</link>
      <pubDate>Thu, 08 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-08-black-mist-filters/</guid>
      <description>&lt;p&gt;Late in the season last year I started getting into black mist filters on my cameras. They&amp;rsquo;re just glass with little black flecks that end up creating a really nice halation effect with night-time lighting; and they soften digital images a tiny bit, in a way that pairs well with the right preset if you like a kinda vintage look.&lt;/p&gt;
&lt;p&gt;I forgot I had one along on my trip to the Mutoid Man show and that was a mild bummer: The light was so low that the X100VI&amp;rsquo;s perfectly serviceable 3200 ISO had more of an uphill battle. On the other end of the spectrum, during bright daylight, they turn the highlights into a glowing mess.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Late in the season last year I started getting into black mist filters on my cameras. They&rsquo;re just glass with little black flecks that end up creating a really nice halation effect with night-time lighting; and they soften digital images a tiny bit, in a way that pairs well with the right preset if you like a kinda vintage look.</p>
<p>I forgot I had one along on my trip to the Mutoid Man show and that was a mild bummer: The light was so low that the X100VI&rsquo;s perfectly serviceable 3200 ISO had more of an uphill battle. On the other end of the spectrum, during bright daylight, they turn the highlights into a glowing mess.</p>
<p>I&rsquo;m on the fence because I like the effect, but don&rsquo;t like remembering/forgetting that the filter is on there at all.</p>
<p><img src="https://photos.smugmug.com/photos/i-43Nvd82/0/NTT8RDTv8SWxkFFXnj3mLTJ3q4fHwwqX7rhVkr2dJ/XL/i-43Nvd82-XL.jpg" alt="Steven Brodsky plays a solo"></p>
<p><img src="https://photos.smugmug.com/photos/i-LsppZ9B/0/NJmCzBvGs3H925CWPrWMMgzgv6jMwmfk8TtqtKxT2/XL/i-LsppZ9B-XL.jpg" alt="John Doe plays a solo"></p>
<p><img src="https://photos.smugmug.com/photos/i-W3DMnT2/0/Mzs5m2tW4jGrNjcJgc8KbTg5Kn7g9Xmp8MTCgPFnH/XL/i-W3DMnT2-XL.jpg" alt="red neon at Kelly&rsquo;s"></p>
<p><img src="https://photos.smugmug.com/photos/i-c2FTfF9/0/L7XDvHhbF68HPdzvFP6VsssLmjGm7vmBLnRCvPRLR/XL/i-c2FTfF9-XL.jpg" alt="Neon lit stairwell at Pike Place"></p>
<p><img src="https://photos.smugmug.com/photos/i-g3Km9Wb/0/K3gVxn6RPGw559vQNDDWt9QbhxvXmpM9H9MhjMFLx/XL/i-g3Km9Wb-XL.jpg" alt="Fish market at Pike Place"></p>
]]></content:encoded>
    </item>
    <item>
      <title>lmno-export</title>
      <link>https://mike.puddingtime.org/posts/2025-05-08-lmno-export/</link>
      <pubDate>Thu, 08 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-08-lmno-export/</guid>
      <description>&lt;p&gt;I packageized &lt;a href=&#34;https://github.com/pdxmph/lmno-export&#34;&gt;lmno-export&lt;/a&gt;, which just lets you work on your lmno blog in org-mode then export it to clean Markdown. Mainly I wanted &amp;ldquo;real&amp;rdquo; org-capture instead of my &lt;a href=&#34;https://github.com/pdxmph/lmno-blog-capture&#34;&gt;hacky alternative&lt;/a&gt;, and I like being able to reuse my org-mode notes as-is instead of extracting and converting them.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Write your blog in a monolithic org-mode file (set in Customize).&lt;/li&gt;
&lt;li&gt;Export it with &lt;code&gt;lmno-org-export-blog&lt;/code&gt; .&lt;/li&gt;
&lt;li&gt;It opens the target file (set in Customize).&lt;/li&gt;
&lt;li&gt;If you&amp;rsquo;re a Mac person, drag the proxy icon into the lmno.lol uploader.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&amp;rsquo;s the org-capture template, which reuses the source file variable:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I packageized <a href="https://github.com/pdxmph/lmno-export">lmno-export</a>, which just lets you work on your lmno blog in org-mode then export it to clean Markdown. Mainly I wanted &ldquo;real&rdquo; org-capture instead of my <a href="https://github.com/pdxmph/lmno-blog-capture">hacky alternative</a>, and I like being able to reuse my org-mode notes as-is instead of extracting and converting them.</p>
<ul>
<li>Write your blog in a monolithic org-mode file (set in Customize).</li>
<li>Export it with <code>lmno-org-export-blog</code> .</li>
<li>It opens the target file (set in Customize).</li>
<li>If you&rsquo;re a Mac person, drag the proxy icon into the lmno.lol uploader.</li>
</ul>
<p>Here&rsquo;s the org-capture template, which reuses the source file variable:</p>
<pre><code>(add-to-list 'org-capture-templates
  '(&quot;l&quot;
    &quot;LMNO blog post&quot;
    entry
    (file lmno-org-input-file)
    &quot;* [%&lt;%Y-%m-%d&gt;] %?\n\n&quot;
    :prepend t))
</code></pre>
<p>Under the hood, it has to do some footwork: org-export wants to wrap anything that looks like an org-mode date stamp with spans, and there is no configurable option for that. Likewise, it applies anchor id&rsquo;s to every heading.</p>
<p>I am not sure what was going on with image attributes in all that, either, but they weren&rsquo;t surviving the export with alt tags in place, so I found this custom link format in a Stack Overflow answer that somehow sidestepped the issue:</p>
<pre><code>(org-add-link-type
 &quot;img&quot; nil
 (lambda (path desc backend)
   (when (org-export-derived-backend-p backend 'md)
     (format &quot;![%s](%s)&quot; desc path))))
</code></pre>
]]></content:encoded>
    </item>
    <item>
      <title>Make a Markdown or org snippet from the flickr image in your browser (Raycast)</title>
      <link>https://mike.puddingtime.org/posts/2025-05-08-make-a-markdown-or-org-snippet-from-the-flickr-image-in-your-browser-raycast/</link>
      <pubDate>Thu, 08 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-08-make-a-markdown-or-org-snippet-from-the-flickr-image-in-your-browser-raycast/</guid>
      <description>&lt;p&gt;I don&amp;rsquo;t think I&amp;rsquo;ll use this a ton day-to-day because I haven&amp;rsquo;t put anything in flickr for a while, and generally use SmugMug these days for embedding stuff in a blog, but I&amp;rsquo;ve been learning how Raycast script actions work and this was an exercise in how to pass arguments in an action instead of going out to osascript dialogs.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Visit a flickr image in Safari or Chrome&lt;/li&gt;
&lt;li&gt;Invoke the action from Raycast and:
&lt;ul&gt;
&lt;li&gt;select a snippet format&lt;/li&gt;
&lt;li&gt;type in some alt text&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Get a snippet in Markdown, org, or HTML with your alt text, suitable for pasting into a blog post&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Why you want to do this:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I don&rsquo;t think I&rsquo;ll use this a ton day-to-day because I haven&rsquo;t put anything in flickr for a while, and generally use SmugMug these days for embedding stuff in a blog, but I&rsquo;ve been learning how Raycast script actions work and this was an exercise in how to pass arguments in an action instead of going out to osascript dialogs.</p>
<ol>
<li>Visit a flickr image in Safari or Chrome</li>
<li>Invoke the action from Raycast and:
<ul>
<li>select a snippet format</li>
<li>type in some alt text</li>
</ul>
</li>
<li>Get a snippet in Markdown, org, or HTML with your alt text, suitable for pasting into a blog post</li>
</ol>
<p>Why you want to do this:</p>
<ol>
<li>If you&rsquo;re all in on Flickr, then your blog becomes more easily portable if you ever move it, because the image tags have a stable URL</li>
<li>Flickr cares more about the quality of the embeds than a lot of blogging providers.</li>
<li>You&rsquo;re using lmno or some other service that doesn&rsquo;t manage image uploads at all, and you <em>have</em> to have a third party host.</li>
</ol>
<p>Pick your poison: If you&rsquo;re a forward-thinking SSG kinda person who has made it easy to ensure image tag hygiene in the event of a domain or platform change, this might not be appealing. If you&rsquo;ve been doing this for 25 or 30 years and occasionally stray into the less portable corners of the web, but are willing to hitch your wagon to flickr, this is an option that compares favorably to &ldquo;all your images were ingested, compressed into a mealy, blurry mess, and given an indecipherable path to some S3 bucket.&rdquo; If you&rsquo;re constantly playing around and moving posts back and forth between providers and frameworks, this could also be a helpful strategy.</p>
<pre><code>#!/usr/bin/env bash
# Required parameters:
# @raycast.schemaVersion 1
# @raycast.title  Flickr snippet from active tab
# @raycast.mode silent
# @raycast.icon 🌄
# @raycast.description  Grab the URL of your frontmost browser tab (Flickr only) and copy a Markdown/Org/HTML &lt;img&gt; snippet
# @raycast.argument1 { &quot;type&quot;: &quot;dropdown&quot;, &quot;placeholder&quot;: &quot;Format&quot;, &quot;optional&quot;: false, &quot;data&quot;: [ { &quot;title&quot;: &quot;Markdown&quot;, &quot;value&quot;: &quot;md&quot; }, { &quot;title&quot;: &quot;Org‑mode&quot;, &quot;value&quot;: &quot;org&quot; }, { &quot;title&quot;: &quot;HTML&quot;, &quot;value&quot;: &quot;html&quot; } ] }
# @raycast.argument2 { &quot;type&quot;: &quot;text&quot;, &quot;placeholder&quot;: &quot;Alt text (optional)&quot;, &quot;optional&quot;: true }

set -euo pipefail

FORMAT=$1
ALT_TEXT=${2:-&quot;&quot;}

# 1) Get frontmost browser’s URL
APP=$(osascript -e 'tell application &quot;System Events&quot; to name of first application process whose frontmost is true')
case &quot;$APP&quot; in
Safari)
    URL=$(osascript -e 'tell application &quot;Safari&quot; to return URL of front document') # :contentReference[oaicite:0]{index=0}
    ;;
&quot;Google Chrome&quot; | &quot;Brave Browser&quot; | &quot;Microsoft Edge&quot;)
    URL=$(osascript -e 'tell application &quot;Google Chrome&quot; to return URL of active tab of first window') # :contentReference[oaicite:1]{index=1}
    ;;
*)
    echo &quot;⚠️ Unsupported app: $APP&quot;
    exit 1
    ;;
esac

# 2) Validate it’s a Flickr photo page
if [[ ! $URL =~ https?://(www\.)?flickr\.com/photos/ ]]; then
    echo &quot;⚠️ Not a Flickr photo URL: $URL&quot;
    exit 1
fi

# 3) oEmbed → JSON
ENC=$(python3 -c 'import urllib.parse,sys; print(urllib.parse.quote(sys.argv[1], safe=&quot;&quot;))' &quot;$URL&quot;)
OEMBED=$(curl -s &quot;https://www.flickr.com/services/oembed?format=json&amp;url=$ENC&quot;)

# 4) Extract direct image URL
IMG_URL=$(echo &quot;$OEMBED&quot; | /usr/bin/jq -r .url)
if [[ -z $IMG_URL || $IMG_URL == &quot;null&quot; ]]; then
    echo &quot;⚠️ Failed to extract image URL.&quot;
    exit 1
fi

# 5) Build snippet
case $FORMAT in
md)
    [[ -n $ALT_TEXT ]] &amp;&amp; SNIP=&quot;![${ALT_TEXT//\&quot;/\\\&quot;}]($IMG_URL)&quot; || SNIP=&quot;![]($IMG_URL)&quot;
    ;;
org)
    [[ -n $ALT_TEXT ]] &amp;&amp; SNIP=&quot;[[${IMG_URL}][${ALT_TEXT//\]/\\]}]]&quot; || SNIP=&quot;[[${IMG_URL}]]&quot;
    ;;
html)
    [[ -n $ALT_TEXT ]] &amp;&amp; SNIP=&quot;&lt;img src=\&quot;$IMG_URL\&quot; alt=\&quot;${ALT_TEXT//\&quot;/\\\&quot;}\&quot;&gt;&quot; || SNIP=&quot;&lt;img src=\&quot;$IMG_URL\&quot;&gt;&quot;
    ;;
esac

# 6) Copy &amp; notify
printf '%s' &quot;$SNIP&quot; | pbcopy
terminal-notifier -title &quot;Flickr snippet&quot; -message &quot;Copied $FORMAT snippet&quot; -sound default
</code></pre>
<p><img src="https://live.staticflickr.com/65535/52583647627_296a68de1c_b.jpg" alt="A skateboarder cruises by The Newberry in downtown Portland"></p>
]]></content:encoded>
    </item>
    <item>
      <title>Maybe it was the shell scripts we made along the way</title>
      <link>https://mike.puddingtime.org/posts/2025-05-08-maybe-it-was-the-shell-scripts-we-made-along-the-way/</link>
      <pubDate>Thu, 08 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-08-maybe-it-was-the-shell-scripts-we-made-along-the-way/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://photos.smugmug.com/photos/i-dwXr6Bv/0/LrhHRTQPDvFHpCwDNj38f2cXbKQJLCDFgs9LLpQTF/XL/i-dwXr6Bv-XL.jpg&#34; alt=&#34;Tourists in a Seattle alley&#34;&gt;&lt;/p&gt;
&lt;p&gt;The fundamental mania at work here is basically &amp;ldquo;wring all the motion out of a thing you can.&amp;rdquo; I wrote imgup because I hated what Microblog was doing to my photos, but also hated the whole shuffle of &amp;ldquo;upload an image to SmugMug, hand-write the markup to embed it in a post.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;So it was an incremental improvement to build a web UI that stripped all the extraneous motion out of that workflow using the only thing I knew very well, which is Ruby/Sinatra.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://photos.smugmug.com/photos/i-dwXr6Bv/0/LrhHRTQPDvFHpCwDNj38f2cXbKQJLCDFgs9LLpQTF/XL/i-dwXr6Bv-XL.jpg" alt="Tourists in a Seattle alley"></p>
<p>The fundamental mania at work here is basically &ldquo;wring all the motion out of a thing you can.&rdquo; I wrote imgup because I hated what Microblog was doing to my photos, but also hated the whole shuffle of &ldquo;upload an image to SmugMug, hand-write the markup to embed it in a post.&rdquo;</p>
<p>So it was an incremental improvement to build a web UI that stripped all the extraneous motion out of that workflow using the only thing I knew very well, which is Ruby/Sinatra.</p>
<p>My recent journey into better note management reminded me it&rsquo;s not terrible to work in a shell scripting environment, so that&rsquo;s why I dusted off imgup, which was nothing but a web front-end until this week, and bolted on a CLI interface. I started that thinking &ldquo;well, you usually just export photos from Lightroom or Photos onto ~/Desktop before uploading them with imgup, so just save a trip to the browser.&rdquo;</p>
<p>Then <em>that</em> became &ldquo;why even open a shell when you have Raycast there and understand how to work on selections in Photos or Finder with AppleScript?&rdquo;</p>
<p>And then I remembered that an early pass at imgup extracted the exif caption to provide the alt text (since then Adobe has exposted a literal alt text field in Lightroom) because I was thinking &ldquo;why not just embed that in the photo itself once, when you&rsquo;re already processing it?&rdquo; I don&rsquo;t know why I abandoned that, but this evening my thinking took me toward &ldquo;why even work on a file in the Finder from Raycast when you could just export the image straight from Lightroom to Smugmug via this shell tool you&rsquo;ve built?&rdquo;</p>
<p>So I wired imgup&rsquo;s CLI to a Hazel folder action:</p>
<ul>
<li>Edit the photo in Lightroom</li>
<li>Make sure to edit the caption field (this is the only thing Photos and Lightroom expose in common)</li>
<li>Export to a Hazel-watched folder</li>
<li>Set up a folder action that grabs the photo, extracts the caption, and feeds that as an argument to imgup</li>
<li>Copy the resulting SmugMug link/markup/etc. to the clipboard</li>
<li>Hazel dumps the copy in the trash</li>
</ul>
<p>Barring Adobe doing something freakishly helpful, like adding a scripting library, I can&rsquo;t think of any way to wring any more motion out of this thing: Type in a caption, press cmd-e to do the last export action, and the photo goes from Lightroom up to SmugMug and back to a snippet in my clipboard.</p>
<p>There&rsquo;s one small tragedy in this, which is that Apple Photos both tells you that you are setting the &ldquo;Caption&rdquo; for a photo, then seems to fail to actually store that anywhere in the EXIF data. <code>exiftool</code> can&rsquo;t find it, anyhow. OTOH, now that I have the Hazel/imgup folder going, I can process images-to-snippets from any photo tool, and Photos was at least amenable to making a QuickAction to dump the selected photo into the upload folder. I just end up having to add the caption after the snippet is made, and my SmugMug photo hygiene suffers.</p>
<p>(Update: Apple Photos actually does seem to set the field, but my code was exporting the original photo, and Apple seems to treat any metadata you add in Photos as a non-destructive change, so you have to disable the &ldquo;original&rdquo; flag in the AppleScript export.)</p>
]]></content:encoded>
    </item>
    <item>
      <title>imgup CLI improvement</title>
      <link>https://mike.puddingtime.org/posts/2025-05-07-imgup-cli-improvement/</link>
      <pubDate>Wed, 07 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-07-imgup-cli-improvement/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://photos.smugmug.com/photos/i-bcCGxXj/0/NHVh4RT7f5wwdCPHt5kPcCXL9s5qvwcRtSLP9559d/XL/i-bcCGxXj-XL.jpg&#34; alt=&#34;CLI imgup outputting multiple formats&#34;&gt;&lt;/p&gt;
&lt;p&gt;I added a &lt;code&gt;format&lt;/code&gt; option to the &lt;a href=&#34;https://github.com/pdxmph/imgup&#34;&gt;imgup&lt;/a&gt; CLI, so it&amp;rsquo;ll provide a snippet in either org, Markdown, or HTML markup now, matching what it can do from the web interface. Also realized I don&amp;rsquo;t have a &amp;ldquo;picture of the week&amp;rdquo; feature anymore, so I replaced that part of the menu with a direct link to the Smugmug target album in the Smugmug management UI. Great for quickly getting to a bunch of test photos and removing them.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://photos.smugmug.com/photos/i-bcCGxXj/0/NHVh4RT7f5wwdCPHt5kPcCXL9s5qvwcRtSLP9559d/XL/i-bcCGxXj-XL.jpg" alt="CLI imgup outputting multiple formats"></p>
<p>I added a <code>format</code> option to the <a href="https://github.com/pdxmph/imgup">imgup</a> CLI, so it&rsquo;ll provide a snippet in either org, Markdown, or HTML markup now, matching what it can do from the web interface. Also realized I don&rsquo;t have a &ldquo;picture of the week&rdquo; feature anymore, so I replaced that part of the menu with a direct link to the Smugmug target album in the Smugmug management UI. Great for quickly getting to a bunch of test photos and removing them.</p>
<p>Next on the todo list:</p>
<ul>
<li>Wire it into Raycast for quick &ldquo;upload this image and return a snippet&rdquo; action.</li>
<li>Figure out if there&rsquo;s a way to make a Photos sharing action out of it, too.</li>
</ul>
<p>To restate the problem imgup started out solving:</p>
<p>You never know what your blog hosting provider is going to do to your photos when you upload them. Gnarly compression, weird image renames, path rewrites, maybe they don&rsquo;t even support image uploads and you&rsquo;re left to your own devices for hosting. Move your blog, and the images are probably going to break if you were depending on any provider magic at all.</p>
<p>So … skip all that. If you have an image hosting service you already like, and if they specialize in treating your photographs well, use &rsquo;em!</p>
<p>imgup just takes a photo, uploads it to a hidden (but not private) album, and returns a snippet of Markdown, org, or HTML you can paste into your blog post, complete with alt text if you provide it.</p>
<p>The command line tool is a recent addition because the &ldquo;open web UI, select, upload, copy, paste&rdquo; workflow is fine given how many steps it saves otherwise, but a CLI option is even more efficient (and automatable).</p>
<p>The thing imgup can&rsquo;t solve is using it to do something besides share screenshots of things that make blogging easier. Lately we&rsquo;ve been verging into &ldquo;blogging about things that make blogging easier&rdquo; territory, and that feels icky.</p>
]]></content:encoded>
    </item>
    <item>
      <title>In which I solve a food bank communications problem</title>
      <link>https://mike.puddingtime.org/posts/2025-05-07-in-which-i-solve-a-food-bank-communications-problem/</link>
      <pubDate>Wed, 07 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-07-in-which-i-solve-a-food-bank-communications-problem/</guid>
      <description>&lt;p&gt;I volunteered at the neighborhood food bank/pantry again today. &lt;a href=&#34;https://puddingtime.org/everyone-gets-a-number-choose-one-were-great-on-funyuns-but-the-rice-ran-out&#34;&gt;Like last week&lt;/a&gt; I was put on what I guess is the &amp;ldquo;starch and carbs&amp;rdquo; station:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One from a selection of a bag of flour, a bag of baking mix, or a bag of generic corn flakes cereal&lt;/li&gt;
&lt;li&gt;One or the other of a packet of spaghetti noodles or rice&lt;/li&gt;
&lt;li&gt;a can of pureed pumpkin&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I had more to keep track of this week, and there was something in the air. The first people to draw numbers for their place in the line got high ones: in the 90s and 100s. They didn&amp;rsquo;t want high numbers because the better items are long gone by the last 25 or so people, but the food bank folks don&amp;rsquo;t allow do-overs. Then a general mood hit and everybody started crowding for their number, a few people darted past the line control people and tried to get a second number, and it got a little rowdy.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I volunteered at the neighborhood food bank/pantry again today. <a href="https://puddingtime.org/everyone-gets-a-number-choose-one-were-great-on-funyuns-but-the-rice-ran-out">Like last week</a> I was put on what I guess is the &ldquo;starch and carbs&rdquo; station:</p>
<ul>
<li>One from a selection of a bag of flour, a bag of baking mix, or a bag of generic corn flakes cereal</li>
<li>One or the other of a packet of spaghetti noodles or rice</li>
<li>a can of pureed pumpkin</li>
</ul>
<p>I had more to keep track of this week, and there was something in the air. The first people to draw numbers for their place in the line got high ones: in the 90s and 100s. They didn&rsquo;t want high numbers because the better items are long gone by the last 25 or so people, but the food bank folks don&rsquo;t allow do-overs. Then a general mood hit and everybody started crowding for their number, a few people darted past the line control people and tried to get a second number, and it got a little rowdy.</p>
<p>Once things settled down and people started coming down the line I found it pretty hard to communicate &ldquo;one from this group of three, one from this set of two.&rdquo; Most of the patrons are elderly Asian folks, so there&rsquo;s a language barrier that both sides of the table try to mitigate with broad gestures and repetition.</p>
<p>I realized about five minutes in that the line is just sort of set up wrong for those conditions:</p>
<p>When you have a pair of crates side-by-side with bags of rice in one and bags of noodles in the other and no way to communicate what &ldquo;one&rdquo; means in that context when &ldquo;one or the other&rdquo; doesn&rsquo;t mean anything to the other person, there&rsquo;s a lot of gesturing and a few attempts to just take one of each, and then some unhappiness when you ask for them to put one back (with a lot of gesturing and repeating and some of the other volunteers weighing in because nothing breaks down language barriers like <em>everyone</em> yelling in unison).</p>
<p>So I rearranged my station:</p>
<ul>
<li>The flour, cereal, and baking mix all went in one column.</li>
<li>The rice and noodles went in another column.</li>
<li>The pumpkin puree just sat there. I said to the coordinator at the start of the shift, &ldquo;guessin&rsquo; that&rsquo;s not gonna fly off the shelves&rdquo; and got a wry smile.</li>
</ul>
<p>Set up thus, I could just make eye contact, hold my hand out over a column, say &ldquo;one,&rdquo; and it seemed much more clear that I meant &ldquo;one from this column.&rdquo; And that was <em>great</em>, partly because it just helped things move along and partly because having removed the overhead of gesticulating, repeating, and the hurt feelings of people having to put things back, people were more inclined to say thank you, or make jokes about <em>wanting</em> more than one, and I had more time to help them load their bags or remember to hand things over with both hands when they preferred that I hand things to them.</p>
<p>It did mean I had to keep more stuff readily at hand and I had to more frequently re-up my columns, but I think a concentrated 60 or 70 minutes of moving a little quickly for the sake of making it less sucky was a good tradeoff.</p>
<p>This week we ran out of rice early. Plenty of Funyuns, same as last week. The coordinator tells me the money has been drying up, so they can&rsquo;t buy the staples, but donations of junk food tend to be plentiful.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Uploading to imgup from Photos</title>
      <link>https://mike.puddingtime.org/posts/2025-05-07-uploading-to-imgup-from-photos/</link>
      <pubDate>Wed, 07 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-07-uploading-to-imgup-from-photos/</guid>
      <description>&lt;p&gt;Woof. It involved some AppleScripting, shell scripting, and some ugliness due to RayCast not wanting to inherit my login shell environment (circumventing rbenv to run imgup), but I finally got it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Pick an image in photos&lt;/li&gt;
&lt;li&gt;Fire off the action in RayCast&lt;/li&gt;
&lt;li&gt;Select a snippet format of `org` or `markdown`&lt;/li&gt;
&lt;li&gt;Provide an alt tag&lt;/li&gt;
&lt;li&gt;Get a copy/pasteable snippet back from imgup I can drop into the blog&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I have a matching one for a selected file in the Finder.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Woof. It involved some AppleScripting, shell scripting, and some ugliness due to RayCast not wanting to inherit my login shell environment (circumventing rbenv to run imgup), but I finally got it:</p>
<ul>
<li>Pick an image in photos</li>
<li>Fire off the action in RayCast</li>
<li>Select a snippet format of `org` or `markdown`</li>
<li>Provide an alt tag</li>
<li>Get a copy/pasteable snippet back from imgup I can drop into the blog</li>
</ul>
<p>I have a matching one for a selected file in the Finder.</p>
<p>Now I just need to go take pictures.</p>
]]></content:encoded>
    </item>
    <item>
      <title>imgup and org-mode (and lmno.org)</title>
      <link>https://mike.puddingtime.org/posts/2025-05-06-imgup-and-org-mode-and-lmnoorg/</link>
      <pubDate>Tue, 06 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-06-imgup-and-org-mode-and-lmnoorg/</guid>
      <description>&lt;p&gt;This morning I woke up wondering &amp;ldquo;what if I could do my lmno blogging from org-mode instead of Markdown?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Partly &amp;ldquo;why not&amp;rdquo; and partly &amp;ldquo;you get real org-capture and it becomes easier to shuttle text around.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;That led to this:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;(defun lmno/org-export-blog ()
  &amp;quot;Export ~/notes/blog.org → ~/notes/lmno.md.&amp;quot;
  (interactive)
  (let* ((input-file  (expand-file-name &amp;quot;~/notes/lmno.org&amp;quot;))
         (output-file (expand-file-name &amp;quot;~/notes/lmno.md&amp;quot;)))
    (with-temp-buffer
      (insert-file-contents input-file)
      (org-mode)
      ;; turn off all the bells that inject TOC, numbers, dates, etc.
      (let ((org-export-with-toc            nil)
            (org-export-with-section-numbers nil)
            (org-export-with-author         nil)
            (org-export-with-creator        nil)
            (org-export-with-date           nil)
            (org-export-with-priorities     nil)
            (org-export-with-timestamps     nil)
            (org-export-with-smart-quotes   nil)
            (org-export-with-broken-links   &#39;mark))
      (org-export-to-buffer &#39;md &amp;quot;*lmno-export*&amp;quot; nil nil nil nil))
      (with-current-buffer &amp;quot;*lmno-export*&amp;quot;
        ;; strip the anchors org&#39;s export insists on inserting
        (goto-char (point-min))
        (while (re-search-forward &amp;quot;&amp;lt;a id=\&amp;quot;[^\&amp;quot;]+\&amp;quot;&amp;gt;&amp;lt;/a&amp;gt;&amp;quot; nil t)
          (replace-match &amp;quot;&amp;quot;))
        ;; strip the overhelpful datestamp spans
        (goto-char (point-min))
        (while (re-search-forward &amp;quot;&amp;lt;/?span[^&amp;gt;]*&amp;gt;&amp;quot; nil t)
          (replace-match &amp;quot;&amp;quot;)))
      ;; write out the clean Markdown
      (with-current-buffer &amp;quot;*lmno-export*&amp;quot;
        (write-region (point-min) (point-max) output-file)))
    (message &amp;quot;Clean export complete → %s&amp;quot; output-file)))
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It has to do two things I wish it didn&amp;rsquo;t:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>This morning I woke up wondering &ldquo;what if I could do my lmno blogging from org-mode instead of Markdown?&rdquo;</p>
<p>Partly &ldquo;why not&rdquo; and partly &ldquo;you get real org-capture and it becomes easier to shuttle text around.&rdquo;</p>
<p>That led to this:</p>
<pre><code>(defun lmno/org-export-blog ()
  &quot;Export ~/notes/blog.org → ~/notes/lmno.md.&quot;
  (interactive)
  (let* ((input-file  (expand-file-name &quot;~/notes/lmno.org&quot;))
         (output-file (expand-file-name &quot;~/notes/lmno.md&quot;)))
    (with-temp-buffer
      (insert-file-contents input-file)
      (org-mode)
      ;; turn off all the bells that inject TOC, numbers, dates, etc.
      (let ((org-export-with-toc            nil)
            (org-export-with-section-numbers nil)
            (org-export-with-author         nil)
            (org-export-with-creator        nil)
            (org-export-with-date           nil)
            (org-export-with-priorities     nil)
            (org-export-with-timestamps     nil)
            (org-export-with-smart-quotes   nil)
            (org-export-with-broken-links   'mark))
      (org-export-to-buffer 'md &quot;*lmno-export*&quot; nil nil nil nil))
      (with-current-buffer &quot;*lmno-export*&quot;
        ;; strip the anchors org's export insists on inserting
        (goto-char (point-min))
        (while (re-search-forward &quot;&lt;a id=\&quot;[^\&quot;]+\&quot;&gt;&lt;/a&gt;&quot; nil t)
          (replace-match &quot;&quot;))
        ;; strip the overhelpful datestamp spans
        (goto-char (point-min))
        (while (re-search-forward &quot;&lt;/?span[^&gt;]*&gt;&quot; nil t)
          (replace-match &quot;&quot;)))
      ;; write out the clean Markdown
      (with-current-buffer &quot;*lmno-export*&quot;
        (write-region (point-min) (point-max) output-file)))
    (message &quot;Clean export complete → %s&quot; output-file)))
</code></pre>
<p>It has to do two things I wish it didn&rsquo;t:</p>
<ul>
<li>Find and replace a bunch of anchor links org&rsquo;s HTML export drops onto headings</li>
<li>Find and replace a bunch of spans org&rsquo;s HTML export wraps around what it considers datestamps</li>
</ul>
<p>But then it just plops the whole monolith into the Markdown file I can drag into lmno&rsquo;s uploader.</p>
<p>… then I noticed &ldquo;the images have no alt tags,&rdquo; so I found someone wrote this custom org link type:</p>
<pre><code>(org-add-link-type
 &quot;img&quot; nil
 (lambda (path desc backend)
   (when (org-export-derived-backend-p backend 'md)
     (format &quot;![%s](%s)&quot; desc path))))
</code></pre>
<p>It just registers a custom org-mode <code>img</code> link, and exports to Markdown with an alt tag, so this in org-mode:</p>
<pre><code>[[img:https://photos.smugmug.com/photos/i-rnGMdNb/0/K3vtM5mZMTn4s9zVwkhdGBXdcBgNPzD74g957cG6J/XL/i-rnGMdNb-XL.jpg][Some alt text]]
</code></pre>
<p>becomes this when exported to Markdown:</p>
<pre><code>![Some alt text](https://photos.smugmug.com/photos/i-rnGMdNb/0/K3vtM5mZMTn4s9zVwkhdGBXdcBgNPzD74g957cG6J/XL/i-rnGMdNb-XL.jpg)
</code></pre>
<p>… so then I thought, what if imgup could provide not just Markdown and HTML snippets, but also org-mode img link snippets?</p>
<p><img src="https://photos.smugmug.com/photos/i-VBbRpJz/0/M6nqkvphptZnK7kD7k6t2sTmCpQjkj6vsKzXqr9Bk/XL/i-VBbRpJz-XL.jpg" alt="An imgup window showing snippets for Markdown, org, and HTML"></p>
<p>(It&rsquo;ll do that from the command line version, too.)</p>
<p>Fifteen years later, <a href="https://mike.puddingtime.org/org-mode-in-your-pocket-is-a-gnu-shaped-devil/">still true.</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>git-auto-sync (and LaunchControl, and the Jurassic Park kid)</title>
      <link>https://mike.puddingtime.org/posts/2025-05-05-git-auto-sync-and-launchcontrol-and-the-jurassic-park-kid/</link>
      <pubDate>Mon, 05 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-05-git-auto-sync-and-launchcontrol-and-the-jurassic-park-kid/</guid>
      <description>&lt;p&gt;I don&amp;rsquo;t think it&amp;rsquo;s as magical as whatever nb is up to, but for wandering from machine to machine and not getting &lt;em&gt;too&lt;/em&gt; out of control with it, &lt;a href=&#34;https://github.com/GitJournal/git-auto-sync/&#34;&gt;git-auto-sync&lt;/a&gt; seems to do an okay job of periodically syncing up with a remote behind your back. When you target a directory with it, it creates a launchd agent, so the syncing daemon persists over reboots, etc.&lt;/p&gt;
&lt;p&gt;I got it from Homebrew, and discovered one issue with it, which is that the agent it sets up wants to log to &lt;code&gt;/usr/local/var/log&lt;/code&gt;, which is locked down in at least recent versions of macOS (and ignores &lt;code&gt;/opt/homebrew/var/log&lt;/code&gt;, which is already correctly permissioned, so now I&amp;rsquo;m wondering if I have the wherewithal to submit a patch somewhere). So you can either make that directory and set the right permissions, or twiddle the launch agent.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I don&rsquo;t think it&rsquo;s as magical as whatever nb is up to, but for wandering from machine to machine and not getting <em>too</em> out of control with it, <a href="https://github.com/GitJournal/git-auto-sync/">git-auto-sync</a> seems to do an okay job of periodically syncing up with a remote behind your back. When you target a directory with it, it creates a launchd agent, so the syncing daemon persists over reboots, etc.</p>
<p>I got it from Homebrew, and discovered one issue with it, which is that the agent it sets up wants to log to <code>/usr/local/var/log</code>, which is locked down in at least recent versions of macOS (and ignores <code>/opt/homebrew/var/log</code>, which is already correctly permissioned, so now I&rsquo;m wondering if I have the wherewithal to submit a patch somewhere). So you can either make that directory and set the right permissions, or twiddle the launch agent.</p>
<p>So if one wanted to use something like cielagonote with Gollum and didn&rsquo;t care for nb as an intermediary, this might be a way to go.</p>
<p>In addition to the daemon, you can also manually fire off a sync, so I can see making a little script for Alfred or RayCast that does a sync before stepping away from a machine.</p>
<p>In the process of debugging the log issue I discovered <a href="https://www.soma-zone.com/LaunchControl/">LaunchControl</a>, which does a lot to make launchd a little more legible with a mildly busy but helpful GUI.</p>
<p><img src="https://photos.smugmug.com/photos/i-SDBqrHr/0/LQqDSJvvPtKgW2TszkgDGpxc3ZhhbqTshSnzs3dw9/XL/i-SDBqrHr-XL.png" alt="img"></p>
<p>Through this I learned that <code>launchd</code> is pretty irritable with jobs it considers &ldquo;inefficient&rdquo; for reasons I am not completely clear on, so I saw watching the Homebrew <code>emacs-plus</code> service failing/starting/failing/starting over and over. From the point of view of someone who is just launching <code>emacsclient -c --no-wait</code> from RayCast, there is nothing untoward going on: It launches in an eyeblink. I did a little reading about what the throttling/inefficiency issue might be, but we&rsquo;re rapidly getting into the ineffable wisdom/hatred of experts that informs the macOS ecosystem and I think I&rsquo;m gonna just close that window and pretend it&rsquo;s fine.</p>
<p><strong>Us:</strong> &ldquo;It&rsquo;s a UNIX system! I know this!&rdquo;</p>
<p><strong>Apple:</strong> &ldquo;Whatever, kid.&rdquo;</p>
]]></content:encoded>
    </item>
    <item>
      <title>git-auto-sync, Raycast, and terminal-notifier</title>
      <link>https://mike.puddingtime.org/posts/2025-05-05-git-auto-sync-raycast-and-terminal-notifier/</link>
      <pubDate>Mon, 05 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-05-git-auto-sync-raycast-and-terminal-notifier/</guid>
      <description>&lt;p&gt;Raycast has a nice setup for making shell scripts into actions. I have one wrapper for emacsclient that just invokes a GUI Emacs window from a running Emacs server and then foregrounds the window:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/bin/bash

# Required parameters:
# @raycast.schemaVersion 1
# @raycast.title Emacsd
# @raycast.mode silent

# Optional parameters:
# @raycast.icon 🤖
# @raycast.packageName Emacs

# Documentation:
# @raycast.description Launch Emacs
# @raycast.author pdxmph
# @raycast.authorURL https://raycast.com/pdxmph

/opt/homebrew/bin/emacsclient -c --no-wait
osascript -e &#39;tell application &amp;quot;Emacs&amp;quot; to activate&#39;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;… and I made another one that lets me trigger &lt;code&gt;git-auto-sync&lt;/code&gt; operations when I&amp;rsquo;m going to step away for a while and want to make sure everything in my notes repo has been pushed:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Raycast has a nice setup for making shell scripts into actions. I have one wrapper for emacsclient that just invokes a GUI Emacs window from a running Emacs server and then foregrounds the window:</p>
<pre><code>#!/bin/bash

# Required parameters:
# @raycast.schemaVersion 1
# @raycast.title Emacsd
# @raycast.mode silent

# Optional parameters:
# @raycast.icon 🤖
# @raycast.packageName Emacs

# Documentation:
# @raycast.description Launch Emacs
# @raycast.author pdxmph
# @raycast.authorURL https://raycast.com/pdxmph

/opt/homebrew/bin/emacsclient -c --no-wait
osascript -e 'tell application &quot;Emacs&quot; to activate'
</code></pre>
<p>… and I made another one that lets me trigger <code>git-auto-sync</code> operations when I&rsquo;m going to step away for a while and want to make sure everything in my notes repo has been pushed:</p>
<pre><code>#!/bin/bash

# Required parameters:
# @raycast.schemaVersion 1
# @raycast.title Sync Notes
# @raycast.mode silent

# Optional parameters:
# @raycast.icon 🤖

# Documentation:
# @raycast.description Run git-auto-sync on notes directory
# @raycast.author pdxmph
# @raycast.authorURL https://raycast.com/pdxmph

set -euo pipefail
IFS=$'\n\t'

# ——— set up a user‐level log directory ———
LOGDIR=&quot;$HOME/Library/Logs/git-auto-sync&quot;
mkdir -p &quot;$LOGDIR&quot;
LOGFILE=&quot;$LOGDIR/sync.log&quot;

on_error() {
    local exit_code=$?
    local lineno=$1
    local msg=&quot;ERROR on line $lineno (exit $exit_code)&quot;
    echo &quot;$(date '+%Y-%m-%d %H:%M:%S') ▶ $msg&quot; &gt;&gt;&quot;$LOGFILE&quot;
    logger -t git-auto-sync &quot;$msg&quot;
    terminal-notifier \
        -title &quot;🔥🤖🔥 git-auto-sync FAILED&quot; \
        -message &quot;See Console.app or $LOGFILE&quot; \
        -sound default
    exit $exit_code
}
trap 'on_error $LINENO' ERR

{
    echo &quot;=== Sync started at $(date '+%Y-%m-%d %H:%M:%S') ===&quot;
    logger -t git-auto-sync &quot;Sync started&quot;
    cd &quot;$HOME/notes&quot;
    /opt/homebrew/bin/git-auto-sync s
    echo &quot;=== Sync succeeded at $(date '+%Y-%m-%d %H:%M:%S') ===&quot;
    logger -t git-auto-sync &quot;Sync succeeded&quot;
} &gt;&gt;&quot;$LOGFILE&quot; 2&gt;&amp;1

terminal-notifier \
    -title &quot;🤖 git-auto-sync&quot; \
    -message &quot;Sync complete&quot; \
    -sound default
</code></pre>
<p>It uses <a href="https://github.com/julienXX/terminal-notifier">terminal-notifier</a> to let me know things either worked:</p>
<p><img src="https://photos.smugmug.com/photos/i-wHnHvPF/0/NZVTSQQhCxStZKWpDpWB4s3GRVL89gZS7d3HFhNFm/XL/i-wHnHvPF-XL.png" alt="img"></p>
<p>… or didn&rsquo;t:</p>
<p><img src="https://photos.smugmug.com/photos/i-2JxZZj4/0/KfZpN6T9mRNwRJLBnH2TLzh3FhBP8g7gfQsSTqzsW/XL/i-2JxZZj4-XL.png" alt="img"></p>
<p>I pinned both actions to the top of my Raycast window:</p>
<p><img src="https://photos.smugmug.com/photos/i-Gqg3j8T/0/KgLppR9hgCt2TdKZJ2PWh58Mpdm52q29R3KMDq4gf/XL/i-Gqg3j8T-XL.jpg" alt="img"></p>
<p>Left to its own devices, git-auto-sync does its thing every few minutes. This is just a way to know it&rsquo;s safe to close the laptop if I&rsquo;ve been working in my notes.</p>
<p>I really like Raycast. The number of supported apps in the store is pretty impressive, and there&rsquo;s a nice SDK/API for making GUI tools. My work Asana is much easier to deal with when I can make a card without having to actually be in the Asana web app, and without having to deal with a plaintext syntax to express which project/board, who owns it, the deadline, etc.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Taking the X100VI to shows</title>
      <link>https://mike.puddingtime.org/posts/2025-05-04-taking-the-x100vi-to-shows/</link>
      <pubDate>Sun, 04 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-04-taking-the-x100vi-to-shows/</guid>
      <description>&lt;p&gt;I guess every music venue has rules for cameras and photography, and the nice thing about the X100VI is that it manages to avoid the &amp;ldquo;no interchangeable lens cameras&amp;rdquo; and &amp;ldquo;no lenses over 4 inches long&amp;rdquo; rules while also avoiding scrutiny as a &amp;ldquo;professional camera&amp;rdquo; because it&amp;rsquo;s small and vintage-looking. And it&amp;rsquo;s great for carrying along because it&amp;rsquo;s easy to cinch the strap up and have it close without a lot of bulk or weight.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I guess every music venue has rules for cameras and photography, and the nice thing about the X100VI is that it manages to avoid the &ldquo;no interchangeable lens cameras&rdquo; and &ldquo;no lenses over 4 inches long&rdquo; rules while also avoiding scrutiny as a &ldquo;professional camera&rdquo; because it&rsquo;s small and vintage-looking. And it&rsquo;s great for carrying along because it&rsquo;s easy to cinch the strap up and have it close without a lot of bulk or weight.</p>
<p>I took it to see X a few weeks ago and it was fine from the front row. There was a guy standing a bit forward of me who <em>also</em> had an X100VI, and he was doing a lot of double-exposure stuff that involved waving the camera around for a slow exposure, then taking a faster one. I&rsquo;m sure the effect is neat, but one <em>drawback</em> of the X100VI is that the rear panel doesn&rsquo;t fold in, so if you&rsquo;re a &ldquo;preview via the rear panel&rdquo; person, everyone&rsquo;s getting a face full of that unless you turn off the rear display, which I will do once I remember all the possible combinations.</p>
<p>Anyhow, I got a lot of shots I was pretty happy with for being behind a rail, and the 40MP sensor lets you crop a ton.</p>
<p><img src="https://photos.smugmug.com/photos/i-MdQMSBZ/0/MPKB6zqpPvRdZw4ZsGffTdj399ffDdt6kNcST25qw/XL/i-MdQMSBZ-XL.jpg" alt="img"></p>
<p>I also took it to see Mutoid Man at the Twilight Cafe, and that was a much bigger win for the small size. It was a pretty crowded, excited room and I was pressed against the low stage, so I kept the camera close with an eye out for the mosh finding me. I guess, as that picture shows, I also liked that the small size let me do some discrete documentary shooting waiting for the show to start.</p>
<p><img src="https://photos.smugmug.com/photos/i-DhK9Bnm/0/KNpkCMzZZmP4BvwrnXPTwwH2kvBFJGQcHJRG9zpgs/XL/i-DhK9Bnm-XL.jpg" alt="Stephen Brodsky and Ben Koller before Mutoid Man performed"></p>
<p>The stage at the Twilight Cafe was much less well lit than the Crystal Ballroom, and I keep auto ISO set to go as high as it needs while holding the shutter speed to 200. That meant an ISO of 3200 for most shots, which is noisy but fine for the subject matter.</p>
<p>I experimented a little with face detection AF and got mixed results. I was much closer to Steven Brodsky than I was Jeff Matz, and sometimes – maybe due to the lighting and motion – the AF would target Jeff, which wasn&rsquo;t great with a wide open aperture. I think I may map one of the buttons to toggling that on and off if I see it getting flaky. I don&rsquo;t tend to trust AF much beyond &ldquo;set to a small point, set that point manually, don&rsquo;t do subject detection.&rdquo;</p>
<p>Then there was Silver Lake, who performed in a small bar/guitar shop. It was super crowded and I hadn&rsquo;t meant to take many pictures, but Al asked me to for her friend. The light was mixed and it was super crowded so I had to shoot over peoples&rsquo; heads. I was glad for plenty of megapixels to crop because I was so far away, and I was glad for the small size because it was a pretty intimate setting and there was already a videographer at work. Face detection was much more reliable in that setting, too. Every now and then it sort of hunted between the lead singer and the bass player because they were right next to each other.</p>
<p><img src="https://photos.smugmug.com/photos/i-tpDkcPf/0/LHmC9vV44z9d9vF9CkpnPQmZBpKtN5wvkmCGFJVv8/XL/i-tpDkcPf-XL.jpg" alt="img"></p>
<p>For both Mutoid Man and Silver Lake I could have brought along either my Olympus with its f1.4/20mm or my Fujifilm X-T5 with its f1.4/33mm and might have liked having a little more light-gathering, but the X100VI works fine for what I&rsquo;m doing and doesn&rsquo;t look threatening to security. I just want to work on quieting down that rear screen.</p>
]]></content:encoded>
    </item>
    <item>
      <title>emacs-plus</title>
      <link>https://mike.puddingtime.org/posts/2025-05-03-emacs-plus/</link>
      <pubDate>Sat, 03 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-03-emacs-plus/</guid>
      <description>&lt;p&gt;I switched my Homebrew Emacs package to &lt;a href=&#34;https://github.com/d12frosted/homebrew-emacs-plus&#34;&gt;emacs-plus@30&lt;/a&gt; this past week. I am sure there are nuances that are escaping me, but I was mostly after something with a tested launchd service I could manage from &lt;code&gt;brew services&lt;/code&gt;, and I thought the built-in support for system appearance changes seemed pretty cool, since it let me retire 20 lines of elisp that wasn&amp;rsquo;t nearly as effective as this build is at detecting when Dark Mode is on or off.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I switched my Homebrew Emacs package to <a href="https://github.com/d12frosted/homebrew-emacs-plus">emacs-plus@30</a> this past week. I am sure there are nuances that are escaping me, but I was mostly after something with a tested launchd service I could manage from <code>brew services</code>, and I thought the built-in support for system appearance changes seemed pretty cool, since it let me retire 20 lines of elisp that wasn&rsquo;t nearly as effective as this build is at detecting when Dark Mode is on or off.</p>
<p>With emacs-plus, I think I&rsquo;ve found the thing that most conforms to what I&rsquo;m willing to be patient with. Enough so that I was able to make a simple <a href="https://www.raycast.com">Raycast</a> launcher that wraps <code>emacsclient -c --no-wait</code> (and could easily make something similar for Alfred or just an Automator app) then hide the Emacs.app from possible completions, and I can get a fresh Emacs frame as close to instantaneously as I care to imagine, without a lot of hassle. I tossed in a quick <code>osascript</code> at the bottom of the Raycast launcher script to make sure my new frame gets focus right away.</p>
<p>Unlike running <code>(server-start)</code> inside my init file, the combination of emacs-plus and a service is immune to accidentally bonking my entire Emacs instance: The daemon still toils away in the background even with errant cmd-q&rsquo;s. I know there are recipes for homegrown launchd services and that none of this is new. I guess the nice part is knowing that this is all packaged up and tested.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Ignoring the plumbing; Journelly and hashtags for mindful journaling</title>
      <link>https://mike.puddingtime.org/posts/2025-05-03-ignoring-the-plumbing-journelly-and-hashtags-for-mindful-journaling/</link>
      <pubDate>Sat, 03 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-03-ignoring-the-plumbing-journelly-and-hashtags-for-mindful-journaling/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s fun watching the threads around what people have been doing with &lt;a href=&#34;https://apps.apple.com/us/app/journelly/id6470714669&#34;&gt;Journelly&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;A lot of people are very into the fact that it uses org-mode underneath. I am, too, because unlike Markdown, org-mode is super amenable to a variety of plaintext workflows that you could probably pull off with Markdown but without all the supporting infrastructure to make it easier.&lt;/p&gt;
&lt;p&gt;Take, for instance, the small problem of recreating reverse-chronological posting to a file:&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>It&rsquo;s fun watching the threads around what people have been doing with <a href="https://apps.apple.com/us/app/journelly/id6470714669">Journelly</a>.</p>
<p>A lot of people are very into the fact that it uses org-mode underneath. I am, too, because unlike Markdown, org-mode is super amenable to a variety of plaintext workflows that you could probably pull off with Markdown but without all the supporting infrastructure to make it easier.</p>
<p>Take, for instance, the small problem of recreating reverse-chronological posting to a file:</p>
<h2 id="part-1-content-authoring-vs-information-management">Part 1. Content authoring vs. information management</h2>
<p>When I wanted to do that with org-capture and Journelly, it just took this:</p>
<pre><code>(after! org
(add-to-list 'org-capture-templates
'(&quot;j&quot; &quot;Journelly&quot; entry (file &quot;~/journal/Journelly.org&quot;) &quot;* %U @ Home\n%?&quot; :prepend t)))
</code></pre>
<p>… because org-mode provides a ton of infrastructure, including the ability to assume that if I tell an org-capture template to <code>prepend</code> to a given file, it will know to skip all the metadata at the top of the file and just plop the new level-1 entry on top of the top-most heading. Done. (Though I didn&rsquo;t realize prepend was that clever, so I&rsquo;ll just not show the eight or ten lines of lisp I thought I needed to do that with before <a href="https://xenodium.com">Álvaro</a> kindly straightened me out.)</p>
<p>I guess the thing about org-mode is that it&rsquo;s not just a kind of markup, but is also an information management framework and its internal tooling has grown up to reflect that.</p>
<p>But when we take the use case of reverse-chronological posting to a Markdown journal, it can get dicey. The infrastructure really isn&rsquo;t there, because at its core Markdown is just there to ease authoring, not management. I once ran a team of technical writers who struggled with The Markdown Revolution, because technical writers are also technical information managers who want to think in terms of efficient content reuse and refactored and recombined information. They ended up migrating to <a href="https://dita-lang.org">DITA</a> (sit with that home page for a while), which was hugely alienating to the developer teams they worked with, but which allowed them to do stuff like localize their docs or effectively refactor documentation for a bunch of different kinds of presentation. I still grind my teeth on their behalf when I run into Markdown reductionists.</p>
<p>Anyhow, the reverse-chronological posting thing in Markdown:</p>
<p>There are three ways assorted Markdown systems I&rsquo;ve come across handle how to set the title of a file.</p>
<p>YAML (or TOML) frontmatter:</p>
<pre><code>---
title: &quot;This pretty good file&quot;
---
</code></pre>
<p>&ldquo;The first H1 is implicitly the title&rdquo;:</p>
<pre><code># This Pretty Good File
</code></pre>
<p>… and even one &ldquo;piece it together from the slugified file name&rdquo; case I spotted somewhere:</p>
<pre><code>this-pretty-good-file.md
</code></pre>
<p>… which makes my gums itch.</p>
<p>All of those require some footwork to get a new Markdown H2 wedged into a file, and because Markdown is fragmented all to hell in part to solve information management problems it wasn&rsquo;t designed to consider in the first place, there is no general-purpose solution. The best you can do is pick how you&rsquo;re going to do it and build your tools accordingly.</p>
<p>In a situation where you&rsquo;re making a logging tool, I imagine most people would just punt and append to a log file and live with chronologically-ordered entries. I happen to like reverse-chronological logs, so I made <a href="https://github.com/pdxmph/md-capture/blob/main/md-capture.el">md-capture.el</a> to recreate the org-capture experience in Markdown, and it is 105 lines of Emacs lisp that is to org-capture as a donkey in a dead lion&rsquo;s pelt is to Aslan. If anything, md-capture convinced me that I should just use org-mode for any writing I care about and that needs to be part of a larger body of writing or interact with other parts of that body.</p>
<h2 id="part-2-you-dont-have-to-care-about-any-of-that-with-journelly">Part 2. You don&rsquo;t have to care about any of that with Journelly</h2>
<p>org-mode&rsquo;s &ldquo;problem,&rdquo; to the extent it has one, is that it&rsquo;s a creature of Emacs and lisp, so it inherits their marginalized status. It was sort of fun when Puppet started using Clojure, because overnight I started seeing Spacemacs start popping up on developer screens: lisp was back! As someone who&rsquo;d been thinking of Emacs as home since 1992, I felt vindicated!</p>
<p>Talking to a Puppet product manager in the ensuing years, how much of a win that shift was for anyone is an open question: Even Puppet&rsquo;s traditional Ruby foundation was a <em>touch</em> exotic for the average sysadmin who might also be willing to submit a PR, but was way more legible than Clojure. I don&rsquo;t know if Puppet was cooling off anyhow, or if Clojure just made it impenetrable to would-be contributors, but the claim was made that community contributions to the core seemed to drop off with Clojure.</p>
<p>Well, anyhow, you don&rsquo;t <em>need</em> to understand org-mode to get benefit from Journelly. This is the third tool Álvaro has made that bridges the world of org-mode with iOS, and does so in a way that lets &ldquo;app people&rdquo; just have an app they can use, while &ldquo;org-mode people&rdquo; can take advantage of the wider org-mode ecosystem if they so choose.</p>
<p>There are other org-mode &ldquo;bridge&rdquo; apps out there, but my observation has been that even with a touch-driven GUI they seem to prefer to expose the functionality in a way that is still visually anchored on org-mode as a way to markup text for information management. Journelly, along with <a href="https://xenodium.com/plain-org-for-ios">Plain Org</a> and <a href="https://xenodium.com/flat-habits-for-ios">Flat Habits</a>, does a great good job of &ldquo;just working&rdquo; without needing to know about all the infrastructure available to you if you care to use it, and without making you deal with UI elements that want to remind you of their plaintext counterparts. Technically its use of hashtags probably counts as an extension of org-mode, since they&rsquo;re not, as near as I understand, in the org-mode spec. In day-to-day use with standard Emacs tools, I&rsquo;m not sure how much it matters.</p>
<p>So with Journelly we get an app that a non-Emacs person who just wants to have a flexible, elegant journaling tool can pick up and use: It has hashtags, you can add pictures to your entries, there&rsquo;s search, etc. etc. and you don&rsquo;t need to know about the plumbing that holds it all together. You still <em>benefit</em>, because if Álvaro announced tomorrow he was done with it and pulling it from the market, your stuff could be exported into a format that might not be <em>popular</em> but that is easily processed into something that <em>is</em> by Pandoc.</p>
<h2 id="part-3-forgetting-the-plumbing-helped-me-use-journelly-better">Part 3. Forgetting the plumbing helped me use Journelly better</h2>
<p>So I mentioned that I&rsquo;m not sure about the place of <code>#hashtags</code> in the org-mode specification.</p>
<p>&ldquo;Tagging&rdquo; in org-mode happens at the heading level:</p>
<pre><code>** This is a sub-heading about particular fruits :grapefruit:citrus:
</code></pre>
<p>When you search for tags in assorted parts of the org-mode ecosystem, you are searching for <code>:tag:</code>, and <code>:tag:</code> occurs at the end of a heading.</p>
<p>The social-media-era <code>#hashtag</code> doesn&rsquo;t exist in org-mode, so you don&rsquo;t get any of the org-mode infrastructure benefits of using them in an org-mode file. They&rsquo;re still perfectly <em>searchable</em> as a matter of being a string that starts with <code>#</code>, but org-mode has no place for them semantically. <a href="https://www.reddit.com/r/orgmode/comments/70p9lk/hashtags_in_orgmode/">People have behaved unpleasantly to each other about this.</a></p>
<p>When I first picked up Journelly, I remember <em>seeing</em> the little <code>#</code> button, and not even knowing how to process it, because I knew Journelly was using org-mode underneath. So I ignored it. I was sort of excited that there was this very friendly journaling tool that I could use as a plain old mobile app, and that underneath it had this familiar, feature-rich format if I wanted to do something with my data in Emacs. In my mental model of how to use a tool that uses org-mode underneath, I was doing the same thing some other org-mode app designers have done, which is try to exist inside org-mode&rsquo;s markup model.</p>
<p>I don&rsquo;t even know why I decided to see what the <code>#</code> button would do. I think I had just downloaded the latest Testflight beta and maybe tags were mentioned. Maybe I was bored. So I tapped it and added some text and saved the entry. Oh … huh … that text had become a tappable link that listed my one entry with that <code>#tag</code>. So I went back to some past entries and stuck some tags in and proved to myself that <code>#tags</code> do something in Journelly that is technically a divergence from org-mode proper, but which are useful and intuitive in the app context.</p>
<p>It was the &ldquo;technically a divergence from org-mode proper&rdquo; part that stuck with me, because in the moment I had to make a decision, I guess:</p>
<p>Ignore <code>#tags</code> because they wouldn&rsquo;t work quite like <code>:tags:</code> in Emacs, or accept them in the context of Journelly because they&rsquo;re useful.</p>
<p>An exchange I&rsquo;d had with Álvaro gave me another useful nudge. I was trying to solve the problem of how to edit my Journelly file from the desktop without blowing it up in a sync error, and sort of problem-solved my way into thinking it&rsquo;d be interesting if Journelly could handle multiple files and maybe interleave them since the entries are all predictably time/date-stamped. He said he liked having a monolithic file because he could find everything with <a href="https://github.com/abo-abo/swiper">swiper</a> searches. I&rsquo;d never used it myself, but I had my Doom config going and it&rsquo;s already wired up with SPC-s-s (or SPC-s-S to search for the thing at point), so I learned it&rsquo;s a fuzzy search tool.</p>
<p>Well, there&rsquo;s your &ldquo;how a <code>#hashtag</code> would work in org-mode&rdquo; solution: It&rsquo;s just text. Use a native tool in the context of a monolithic journal. And there are plenty of other fuzzy search tools for multi-file search.</p>
<p>So I got unstuck on using hashtags in Journelly and decided Álvaro wasn&rsquo;t trying to embrace/extend/extinguish org-mode to build his app empire.</p>
<h2 id="part-4-mindful-journaling-with-hashtags">Part 4. mindful journaling with hashtags</h2>
<p>Which is what brings me to something I&rsquo;ve never used a journal for before: Checking back in on how I think or feel about something, which I stumbled into.</p>
<p>Once I decided to start using hashtags in my Journelly entries, I wasn&rsquo;t sure how to use them. Semantically, in a social media context, they are a discovery tool. I&rsquo;ve read it recommended that if you&rsquo;re using Mastodon you should <em>really</em> lean into them, because say what you will about the toxicity of algorithmic discovery, without it you need to figure out some other way to discover stuff.</p>
<p>I won&rsquo;t use Microblog because it has taken the position that hashtags aren&rsquo;t okay, and the one time I mentioned the discovery use case I got a snide &ldquo;why is it so important to be discovered?&rdquo; from the founder that was just … like … because <em>I want my writing to be discovered by people who may share my interests or even express appreciation for my writing or photography or other endeavors</em>. Why the fuck do you have a first and last name, asshole? For a period I wedged hashtags into my Microblog blog with <a href="https://paste.lol/mph/tags.html">a Hugo shortcode that linked to a Mastodon search for a given tag</a> and a custom social posting feed that made sure the tags were injected into the description, but decided if a service has set aside a very basic and commonly understood tool for discovery because the founder thinks hashtags ruined Twitter, why bother?</p>
<p>So I was just putting tags on all sorts of things to see what would stick: People, moods, places, kinds of events, themes, etc. etc.</p>
<p>The most useful pattern to emerge was completely coincidental:</p>
<p>I was struggling to manage interactions with someone at work, to the point I was dreading every call or meeting. I had deeply internalized the idea that this person was impossible. If asked &ldquo;what do you think of this person,&rdquo; I&rsquo;d have described someone who could not be worked with, would not respond to basic interpersonal communications strategies, and for whom I&rsquo;d resigned myself to merely co-existing.</p>
<p>Over a few weeks, as I&rsquo;d come out of meetings or interactions, I&rsquo;d do my best to remember the positive parts of the interaction: Things where maybe they were their usual intransigent self, but had surprised me by showing up better, or responding well. But when talking about them over dinner, after work, my &ldquo;they&rsquo;re impossible&rdquo; narrative would crowd out any in-the-minute observations.</p>
<p>Then one day, having just finished a post-meeting entry, I tapped on their name hashtag and got all my past entries where I&rsquo;d mentioned them, and had a ton of evidence in front of me that for weeks I&rsquo;d been seeing good things, positive signs, indications that they were not, in fact, impossible or hopeless. That <em>most</em> of the time they were showing up okay. The &ldquo;omg nothing good came of that&rdquo; entries were pretty sparse.</p>
<p>I guess if I were faced with a solid cube with no apparent openings that didn&rsquo;t respond to anything I did to find out what was inside it, or a solid cube with a small number pad that required a eight-digit pin to open, I&rsquo;d probably complain that seven digits is a documented boundary of our ability to memorize a string of digits, but would prefer that to not being able to open the cube at all. I would probably save the eight digits in 1Password or write them on a sticky or make a snippet of them.</p>
<p>Which is sort of what using hashtags for a difficult human being helped me do in Journelly.</p>
]]></content:encoded>
    </item>
    <item>
      <title>lmno-blog-capture v0.2 (&#39;won&#39;t somebody think of the windows&#39; edition)</title>
      <link>https://mike.puddingtime.org/posts/2025-05-03-lmno-blog-capture-v02-wont-somebody-think-of-the-windows-edition/</link>
      <pubDate>Sat, 03 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-03-lmno-blog-capture-v02-wont-somebody-think-of-the-windows-edition/</guid>
      <description>&lt;p&gt;My initial idea for &lt;a href=&#34;https://github.com/pdxmph/lmno-blog-capture&#34;&gt;lmno-blog-capture&lt;/a&gt; was &amp;ldquo;for dashing off super small posts in a transient window.&amp;rdquo; I wanted something org-capture-like so I could be writing about something, have a thought, and keep whatever I was working on in sight.&lt;/p&gt;
&lt;p&gt;So it never occurred to me to test what would happen if I had ended up going long and deciding to give myself more screen real estate with &lt;code&gt;C-x 1&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Then I did that and Emacs started squawking about having only one window to close, so even though it was saving my lmno.md file, it was complaining and not closing the posting minibuffer. I thought I fixed it once, but turns out I was fixing the wrong file in the wrong place for another project. Then it complained at me again today so I fixed it for real this time.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>My initial idea for <a href="https://github.com/pdxmph/lmno-blog-capture">lmno-blog-capture</a> was &ldquo;for dashing off super small posts in a transient window.&rdquo; I wanted something org-capture-like so I could be writing about something, have a thought, and keep whatever I was working on in sight.</p>
<p>So it never occurred to me to test what would happen if I had ended up going long and deciding to give myself more screen real estate with <code>C-x 1</code>.</p>
<p>Then I did that and Emacs started squawking about having only one window to close, so even though it was saving my lmno.md file, it was complaining and not closing the posting minibuffer. I thought I fixed it once, but turns out I was fixing the wrong file in the wrong place for another project. Then it complained at me again today so I fixed it for real this time.</p>
<h2 id="the-sublime-distraction">The Sublime distraction</h2>
<p>While I was In the midst of thrashing around with Emacs configs I wanted to keep working on another project, so I dusted off Sublime Text to just keep moving while I worked through my feelings about Emacs (again). I&rsquo;ve always had an uneasy relationship with it. I love that it&rsquo;s fast and smooth and runs on everything in the house, Linux and Mac alike. I love that it&rsquo;s got a good package ecosystem. I&rsquo;m not a Python person, though, so if I had an itch to scratch in the form of making my own plugin for it, I&rsquo;d be back at the bottom of the hill. I liked Textmate back when because I could write my own plugins in Ruby, and I like BBEdit for similar reasons: Text filters can be any scripting language.</p>
<p>But I&rsquo;m not actually <em>good</em> at Emacs lisp. Not on the level of something like making lmno-blog-capture on my own. Instead I fire up whichever LLM I want to play with and go through a sort of iterative process of describing what I&rsquo;d like to see happen, then testing it out, then layering on another idea, etc. etc.</p>
<p>That&rsquo;s time that could be spent getting gud at Emacs lisp, I guess, but when I think about making that investment … it just doesn&rsquo;t strike me.</p>
<p>I asked ChatGPT to translate lmno-blog-capture to a Sublime Text plugin for me, just to see the code side-by-side, and it was pretty legible. It also took zero iterations to have a working version. Getting an LLM to kick out working lisp on the first go is often hilarious, which makes sense.</p>
<p>Anyhow, nothing to do with it for now. I&rsquo;ve got this emacs-plus setup in a good place, and there&rsquo;s usually something that does what I want already in the ecosystem.</p>
<p><strong>Update:</strong> I did go ahead and <a href="https://github.com/pdxmph/subl-lmno-blog-capture">make a package out of the Sublime version</a> because why not. There&rsquo;s a package file you can download and install in the releases. It&rsquo;s funny because it is just not my conception of Sublime Text that you&rsquo;d live in it in this manner, but it seems completely right and proper that the exact same functionality would exist in Emacs.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Music night: Mutoid Man and Silver Lake</title>
      <link>https://mike.puddingtime.org/posts/2025-05-03-music-night-mutoid-man-and-silver-lake/</link>
      <pubDate>Sat, 03 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-03-music-night-mutoid-man-and-silver-lake/</guid>
      <description>&lt;p&gt;Last night ended up being kinda &amp;ldquo;music night&amp;rdquo;:&lt;/p&gt;
&lt;p&gt;Alison&amp;rsquo;s friend Patricia Rojas played a set with her band, Silver Lake, at a guitar shop/bar in Buckman. Really nice Americana.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://photos.smugmug.com/photos/i-CwCZvzM/0/Mg5T7kpr39CRNnDv5fpWrbRXGgwSLm9Hvd7M92hBN/XL/i-CwCZvzM-XL.jpg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;p&gt;Then we headed to the Twilight Cafe for Mutoid Man. I was super-excited for that one because I love just that band, and because all three members are in other bands I really love: High on Fire, Converge, and Cave In. They were really, really good and it was a great audience.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Last night ended up being kinda &ldquo;music night&rdquo;:</p>
<p>Alison&rsquo;s friend Patricia Rojas played a set with her band, Silver Lake, at a guitar shop/bar in Buckman. Really nice Americana.</p>
<p><img src="https://photos.smugmug.com/photos/i-CwCZvzM/0/Mg5T7kpr39CRNnDv5fpWrbRXGgwSLm9Hvd7M92hBN/XL/i-CwCZvzM-XL.jpg" alt="img"></p>
<p>Then we headed to the Twilight Cafe for Mutoid Man. I was super-excited for that one because I love just that band, and because all three members are in other bands I really love: High on Fire, Converge, and Cave In. They were really, really good and it was a great audience.</p>
<p><img src="https://photos.smugmug.com/photos/i-74VNnM7/0/L2KrVvkvwDptBMFnbwR2HcRrVsmr5RLNthVvjSj4W/XL/i-74VNnM7-XL.jpg" alt="img"></p>
]]></content:encoded>
    </item>
    <item>
      <title>cielagonote v0.11 (Home of the Whopper)</title>
      <link>https://mike.puddingtime.org/posts/2025-05-02-cielagonote-v011-home-of-the-whopper/</link>
      <pubDate>Fri, 02 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-02-cielagonote-v011-home-of-the-whopper/</guid>
      <description>&lt;p&gt;I sat for a day with the nb daily plugin support question, a little torn:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I do not like the daily file-naming convention (&lt;code&gt;yyyymmdd.ext&lt;/code&gt;), especially since other files have datestamps in the names.&lt;/li&gt;
&lt;li&gt;I much prefer the &lt;code&gt;daily-yyyy-mm-dd.ext&lt;/code&gt; for scanability and fuzzy-finding, and I like the way cielagonote titles the daily file, which matters in some parts of the Markdown ecosystem.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So my initial approach was to tell nb people to just not expect the daily functionality to work in cielagonote, or that they&amp;rsquo;d just get a &lt;code&gt;daily-yyyy-mm-dd&lt;/code&gt; file dropped in their nb instance that wouldn&amp;rsquo;t work with the &lt;code&gt;daily&lt;/code&gt; plugin. I didn&amp;rsquo;t like that much.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I sat for a day with the nb daily plugin support question, a little torn:</p>
<ul>
<li>I do not like the daily file-naming convention (<code>yyyymmdd.ext</code>), especially since other files have datestamps in the names.</li>
<li>I much prefer the <code>daily-yyyy-mm-dd.ext</code> for scanability and fuzzy-finding, and I like the way cielagonote titles the daily file, which matters in some parts of the Markdown ecosystem.</li>
</ul>
<p>So my initial approach was to tell nb people to just not expect the daily functionality to work in cielagonote, or that they&rsquo;d just get a <code>daily-yyyy-mm-dd</code> file dropped in their nb instance that wouldn&rsquo;t work with the <code>daily</code> plugin. I didn&rsquo;t like that much.</p>
<p>I had a fork of the nb daily plugin anyhow so that I could have my preferred file-naming convention for daily notes using stock <code>nb</code> and I&rsquo;ve added some configuration logic that lets people go a few ways:</p>
<ul>
<li>Use completely stock nb and its daily plugin in or out of cn. On first daily entry of the day, you get dropped into a command line where you can type in your first log.</li>
<li>Use stock nb with the forked plugin and get the same behavior, but with a more readable file naming scheme.</li>
<li>Don&rsquo;t use nb and get the more readable file-naming scheme.</li>
</ul>
<p>This is all managed with a new <code>daily_format:</code> setting that can be set to either <code>nb</code> or <code>cn</code> to drive how files are named.</p>
<p>Personally, I&rsquo;m going to use the forked plugin so I can keep using nb for management and git syncing but have more legible filenames for daily notes.</p>
<p>You can install it from the command line with the URL and use it either in the context of cielagonote or just use it alone to pretty up your daily note filenames:</p>
<p><code>nb plugin install https://github.com/pdxmph/cielagonote/blob/main/extras/cn-daily.nb-plugin</code></p>
]]></content:encoded>
    </item>
    <item>
      <title>cielagonote v0.3</title>
      <link>https://mike.puddingtime.org/posts/2025-05-01-cielagonote-v03/</link>
      <pubDate>Thu, 01 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-01-cielagonote-v03/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/pdxmph/cielagonote/releases/tag/v0.3&#34;&gt;This version&lt;/a&gt; just gets rid of a terminal reset after exiting the editor. It slowed things down, felt laggy, and seemed to be down to a thing that comes and goes depending on the combination of terminal, editor, and sunspots. Maybe I&amp;rsquo;ll add it to the configuration options.&lt;/p&gt;
&lt;p&gt;It also adds a warning in the README that &lt;code&gt;nb&lt;/code&gt; support is incomplete. I do want to make a config switch for that.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://github.com/pdxmph/cielagonote/releases/tag/v0.3">This version</a> just gets rid of a terminal reset after exiting the editor. It slowed things down, felt laggy, and seemed to be down to a thing that comes and goes depending on the combination of terminal, editor, and sunspots. Maybe I&rsquo;ll add it to the configuration options.</p>
<p>It also adds a warning in the README that <code>nb</code> support is incomplete. I do want to make a config switch for that.</p>
]]></content:encoded>
    </item>
    <item>
      <title>cielagonote v0.5 (No Really)</title>
      <link>https://mike.puddingtime.org/posts/2025-05-01-cielagonote-v05-no-really/</link>
      <pubDate>Thu, 01 May 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-05-01-cielagonote-v05-no-really/</guid>
      <description>&lt;p&gt;Well, my lunch date canceled, so … with this version, &lt;code&gt;nb&lt;/code&gt; support is switchable:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;notes_dir: ~/notes
default_extension: md # or org
exclude_dirs:
  - denote
  - .git
hide_hidden: true # hides .files when enabled
editor: micro # will be overridden with `nb edit` if nb_support == true
nb_support: false # if true, overrides your editor: setting and enables nb file management
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So you can either just use cielagonote as a standalone note manager with no supporting ecosystem, or you can flip &lt;code&gt;nb_support:&lt;/code&gt; to &lt;code&gt;true&lt;/code&gt; and it&amp;rsquo;ll use nb&amp;rsquo;s native commands to create, rename, and delete notes, ensuring that &lt;code&gt;nb&lt;/code&gt;&amp;rsquo;s underlying git repo stays clean and in sync with remotes.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Well, my lunch date canceled, so … with this version, <code>nb</code> support is switchable:</p>
<pre><code>notes_dir: ~/notes
default_extension: md # or org
exclude_dirs:
  - denote
  - .git
hide_hidden: true # hides .files when enabled
editor: micro # will be overridden with `nb edit` if nb_support == true
nb_support: false # if true, overrides your editor: setting and enables nb file management
</code></pre>
<p>So you can either just use cielagonote as a standalone note manager with no supporting ecosystem, or you can flip <code>nb_support:</code> to <code>true</code> and it&rsquo;ll use nb&rsquo;s native commands to create, rename, and delete notes, ensuring that <code>nb</code>&rsquo;s underlying git repo stays clean and in sync with remotes.</p>
<p>One bit of config logic: if you enable nb support, the editor cn invokes will be based on your nb setting, not what you configured in <code>.cnconfig.yml</code>. That&rsquo;s just to be compliant with <code>nb</code>&rsquo;s expected behavior to keep the underlying repo clean.</p>
<p>… and there&rsquo;s one tradeoff: nb&rsquo;s <code>daily</code> plugin expects you to just provide it with an input argument and logs the entry for you in the daily note. I wasn&rsquo;t aware of the daily plugin when I started using nb and settled into my own <code>daily-yyyy-mm-dd.ext</code> convention. I think there&rsquo;s a way to address the whole thing that leaves both approaches intact if you choose to turn on <code>nb_support</code>, but for now the README just says &ldquo;don&rsquo;t use the <code>^t</code> keystroke if you&rsquo;re using <code>nb</code> because it doesn&rsquo;t honor the nb daily file naming convention.&rdquo;</p>
<p>I think I&rsquo;ll stop messing with it for a while now. It does what I want either as a standalone tool for anyone, or as a way to use <code>nb</code> with a slightly different twist on its native behavior. There is an fzf plugin for nb that gives you a fast way to access notes, cielagonote just adds a few conveniences so you can stay in its interface and manage notes a little more visually and a little less &ldquo;dig up a number, enter a number&rdquo; to do operations.</p>
<p><strong>Update:</strong> Oops. Introduced a regression. 0.7 is the way to go:</p>
<p><a href="https://github.com/pdxmph/cielagonote/releases/tag/v0.7">Link</a></p>
]]></content:encoded>
    </item>
    <item>
      <title>Everyone gets a number. Choose one. We&#39;re great on Funyuns, but the rice ran out.</title>
      <link>https://mike.puddingtime.org/posts/2025-04-30-everyone-gets-a-number-choose-one-were-great-on-funyuns-but-the-rice-ran-out/</link>
      <pubDate>Wed, 30 Apr 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-04-30-everyone-gets-a-number-choose-one-were-great-on-funyuns-but-the-rice-ran-out/</guid>
      <description>&lt;p&gt;I did my first volunteer shift at a neighborhood food pantry today. It was over at the elementary school across the park, where Ben went. The person running things seemed a little harried, but did take the time to show me how to stand behind several bins and ensure proper distribution:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;One or the other of a packet of spaghetti noodles or a pound of white rice&lt;/li&gt;
&lt;li&gt;One can of tomato paste, sauce, or diced tomatoes&lt;/li&gt;
&lt;li&gt;One jar of peanut butter&lt;/li&gt;
&lt;li&gt;One or the other from a box full of ramen, canned fruit, and other stuff &lt;em&gt;or&lt;/em&gt; baby food, apple sauce, white vinegar, soy sauce and cooking oils&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The station to my right had Funyuns and Nerds candies, and they were allowed to give away three of either. The station to my left had assorted meats: Hamburger, chicken thighs, and a few racks of ribs. Further down the way there was a vegetable person who had purple onions and some other vegetables.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I did my first volunteer shift at a neighborhood food pantry today. It was over at the elementary school across the park, where Ben went. The person running things seemed a little harried, but did take the time to show me how to stand behind several bins and ensure proper distribution:</p>
<ul>
<li>One or the other of a packet of spaghetti noodles or a pound of white rice</li>
<li>One can of tomato paste, sauce, or diced tomatoes</li>
<li>One jar of peanut butter</li>
<li>One or the other from a box full of ramen, canned fruit, and other stuff <em>or</em> baby food, apple sauce, white vinegar, soy sauce and cooking oils</li>
</ul>
<p>The station to my right had Funyuns and Nerds candies, and they were allowed to give away three of either. The station to my left had assorted meats: Hamburger, chicken thighs, and a few racks of ribs. Further down the way there was a vegetable person who had purple onions and some other vegetables.</p>
<p>The shift started with number distribution: A bit over 100 people lined up, and each got a token out of a plastic bin. The first person got number 1 and that made everybody laugh. The coordinator asked me to please keep an eye out for people slipping past the guy controlling the line to get a second number. Once the numbers were distributed, everyone came back into the area in front of the tent we were set up under and starting filing past.</p>
<p>I spent about an hour pointing to the spaghetti and rice bins and saying &ldquo;this or that, only one&rdquo; a lot. Some folks tried to grab both, and at first I&rsquo;d say &ldquo;oh, no … just one or the other&rdquo; but the people on either side of me faced with similar situations just firmly took the second item out of their hands, so I started doing that.</p>
<p>There was a small ripple down the line when someone lifted a pound of white rice out of the bin and discovered a different kind of rice with a more colorful label and maybe more of it. That caused a few people to double back and swap their rice out. When I ran out of peanut butter to distribute one of the other volunteers dumped a box of small Nutella knock-off jars into the bin, which didn&rsquo;t move super fast. Eventually, I was out of rice, but the Funyun station was in fine shape. I spotted a ton of extra boxes of that behind the line. Thanks, Funyun patron.</p>
<p>After distribution was mostly over a few people who couldn&rsquo;t get numbers came through, then I helped break down the tents and haul what was left back to the supply room, then grabbed some gloves and disinfected all the meat storage tubs. The coordinator was curious about what I was doing there. Given the application process and time sheet, I guess some volunteers are fulfilling a community service obligation. I just explained that I&rsquo;d searched for volunteer opportunities, wanted to support <a href="https://www.oregonfoodbank.org">the Oregon Food Bank</a>, and saw this location, which is just a five minute walk away. So I think I&rsquo;ll be going back every Wednesday: I&rsquo;m giving up my lunch and the company is giving me up from 1-2 in the afternoon.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Post-haircut drink at Bruno&#39;s</title>
      <link>https://mike.puddingtime.org/posts/2025-04-30-post-haircut-drink-at-brunos/</link>
      <pubDate>Wed, 30 Apr 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-04-30-post-haircut-drink-at-brunos/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://photos.smugmug.com/photos/i-hRKCZhv/0/KF2zvZbjm3JJvBxFjwzJ8wLM4nGF4XCMQV4SHGcHF/XL/i-hRKCZhv-XL.jpg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://photos.smugmug.com/photos/i-hRKCZhv/0/KF2zvZbjm3JJvBxFjwzJ8wLM4nGF4XCMQV4SHGcHF/XL/i-hRKCZhv-XL.jpg" alt="img"></p>
]]></content:encoded>
    </item>
    <item>
      <title>cielagonote 0.2.1 (changed daily notes and an nb plugin)</title>
      <link>https://mike.puddingtime.org/posts/2025-04-29-cielagonote-021-changed-daily-notes-and-an-nb-plugin/</link>
      <pubDate>Tue, 29 Apr 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-04-29-cielagonote-021-changed-daily-notes-and-an-nb-plugin/</guid>
      <description>&lt;p&gt;I did some quick fixups to daily notes in cielagonote this morning.&lt;/p&gt;
&lt;p&gt;You can start or add to a daily note in cielagonote with &lt;code&gt;C-t&lt;/code&gt;. That opens a file named &lt;code&gt;daily-yyyy-mm-dd.ext&lt;/code&gt; (where .ext is either &lt;code&gt;.org&lt;/code&gt; or &lt;code&gt;.md&lt;/code&gt; depending on what you set in &lt;code&gt;.cnconfig.yml&lt;/code&gt;).&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s the naming convention I&amp;rsquo;ve been using forever for daily notes, and is at odds with nb&amp;rsquo;s own daily plugin, so I forked that and added it to the cielagonote repo as an extra.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I did some quick fixups to daily notes in cielagonote this morning.</p>
<p>You can start or add to a daily note in cielagonote with <code>C-t</code>. That opens a file named <code>daily-yyyy-mm-dd.ext</code> (where .ext is either <code>.org</code> or <code>.md</code> depending on what you set in <code>.cnconfig.yml</code>).</p>
<p>That&rsquo;s the naming convention I&rsquo;ve been using forever for daily notes, and is at odds with nb&rsquo;s own daily plugin, so I forked that and added it to the cielagonote repo as an extra.</p>
<p><code>$ nb plugin install https://github.com/pdxmph/cielagonote/blob/main/extras/cn-daily.nb-plugin</code></p>
<p><code>$ nb help daily</code> for usage, but <code>nb daily 'log text'</code> will get you going.</p>
<p>I think next up should probably be the config switch for &ldquo;fully in the nb world&rdquo; vs. &ldquo;just doing your own thing.&rdquo; That would just mean adding a line to the config file to set that switch and changing the behavior for:</p>
<ul>
<li>deleting notes</li>
<li>renaming notes</li>
<li>daily notes (to conform to the stock nb plugin)</li>
</ul>
<p>… to use the stock nb commands for those things under the hood, which will trigger nb syncs and reduce the chances of collisions if you&rsquo;re the type to walk away from an open buffer.</p>
<p>As a matter of tools therapy, I&rsquo;m enjoying this little project. It all starts from the assumption that you shouldn&rsquo;t care too much what you called the things you stuffed in the shoebox, you should just be able to find them, and you should be able to make new ones that might as well be consistently named but don&rsquo;t have to be. That has created a sense of lightness in daily usage, even as I enjoy thinking about how to keep it all that simple but layer on ways to interact with it efficiently.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Headspace</title>
      <link>https://mike.puddingtime.org/posts/2025-04-28-headspace/</link>
      <pubDate>Mon, 28 Apr 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-04-28-headspace/</guid>
      <description>&lt;p&gt;I spent today in my pretty stripped down Emacs config. In the end, setting aside dependencies that got pulled in, I&amp;rsquo;ve installed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;LSP&lt;/li&gt;
&lt;li&gt;Vertico&lt;/li&gt;
&lt;li&gt;osx-clipboard&lt;/li&gt;
&lt;li&gt;exec-path-from-shell&lt;/li&gt;
&lt;li&gt;recentf&lt;/li&gt;
&lt;li&gt;company&lt;/li&gt;
&lt;li&gt;orderless&lt;/li&gt;
&lt;li&gt;which-key&lt;/li&gt;
&lt;li&gt;marginalia&lt;/li&gt;
&lt;li&gt;evil&lt;/li&gt;
&lt;li&gt;prescient&lt;/li&gt;
&lt;li&gt;undo-fu&lt;/li&gt;
&lt;li&gt;lmno-blog-capture&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;There are 269 lines in my tangled config file to make it all work, and it seems to take somewhere around 0.7 seconds to launch from the shell (more like 1.3 seconds as a GUI). I had 387 lines in my Doom config, which is honestly a decent reflection on Doom: You can go totally &amp;ldquo;kid in a candy store&amp;rdquo; with that thing and it&amp;rsquo;s doing a lot to help you suffer less for that impulse.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I spent today in my pretty stripped down Emacs config. In the end, setting aside dependencies that got pulled in, I&rsquo;ve installed:</p>
<ul>
<li>LSP</li>
<li>Vertico</li>
<li>osx-clipboard</li>
<li>exec-path-from-shell</li>
<li>recentf</li>
<li>company</li>
<li>orderless</li>
<li>which-key</li>
<li>marginalia</li>
<li>evil</li>
<li>prescient</li>
<li>undo-fu</li>
<li>lmno-blog-capture</li>
</ul>
<p>There are 269 lines in my tangled config file to make it all work, and it seems to take somewhere around 0.7 seconds to launch from the shell (more like 1.3 seconds as a GUI). I had 387 lines in my Doom config, which is honestly a decent reflection on Doom: You can go totally &ldquo;kid in a candy store&rdquo; with that thing and it&rsquo;s doing a lot to help you suffer less for that impulse.</p>
<p>I am probably not done adding stuff. Most of what&rsquo;s in that list is stuff I got used to in Doom (in significantly less engineered form than you get there). I was mildly surprised to realize how much I&rsquo;ve gotten used to <a href="https://github.com/emacs-evil/evil">evil</a>, but after an hour of blundering around and leaving stray ^, $, x, and p in my documents, I broke down and installed it.</p>
<p>The net result of the whole thing today was one of feeling uncluttered. Like, there are things I never really learned how to do with Doom because there was so much to do, and because I couldn&rsquo;t understand <em>why</em> it was doing some of what it was doing out of the box. The value of taking a step back and just putting back the things I noticed and liked includes knowing why things are doing what they&rsquo;re doing, and feeling significantly less like my editor is a mysterious box of perils and wonders. And less like an attentional honeypot.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Making an nb bookmark from iOS</title>
      <link>https://mike.puddingtime.org/posts/2025-04-28-making-an-nb-bookmark-from-ios/</link>
      <pubDate>Mon, 28 Apr 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-04-28-making-an-nb-bookmark-from-ios/</guid>
      <description>&lt;p&gt;Couldn&amp;rsquo;t resist figuring this out. You can run scripts over ssh with Shortcuts and iOS:&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://photos.smugmug.com/photos/i-RhLtbpt/0/NT4NdwNxRK5HFVQB6ZWTfq9CQkJKqqDw3FR25BbJv/XL/i-RhLtbpt-XL.png&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;p&gt;The script on the receiving end:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/opt/homebrew/bin/bash
url=${1)
/opt/homebrew/bin/nb ${1}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;a href=&#34;https://tailscale.com/&#34;&gt;Tailscale&lt;/a&gt; makes this kind of thing easier. (And yes, use an ssh key.)&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Couldn&rsquo;t resist figuring this out. You can run scripts over ssh with Shortcuts and iOS:</p>
<p><img src="https://photos.smugmug.com/photos/i-RhLtbpt/0/NT4NdwNxRK5HFVQB6ZWTfq9CQkJKqqDw3FR25BbJv/XL/i-RhLtbpt-XL.png" alt="img"></p>
<p>The script on the receiving end:</p>
<pre><code>#!/opt/homebrew/bin/bash
url=${1)
/opt/homebrew/bin/nb ${1}
</code></pre>
<p><a href="https://tailscale.com/">Tailscale</a> makes this kind of thing easier. (And yes, use an ssh key.)</p>
]]></content:encoded>
    </item>
    <item>
      <title>Bolting a CLI interface onto imgup for SmugMug uploading and blogging</title>
      <link>https://mike.puddingtime.org/posts/2025-04-27-bolting-a-cli-interface-onto-imgup-for-smugmug-uploading-and-blogging/</link>
      <pubDate>Sun, 27 Apr 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-04-27-bolting-a-cli-interface-onto-imgup-for-smugmug-uploading-and-blogging/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/pdxmph/imgup&#34;&gt;imgup&lt;/a&gt; is a project I worked on a few years ago to solve the problem of where to put photos for my blogs after experiencing a few weird things with different services: The image files being renamed into something illegible, or suffering from crappy compression. Since I have been using SmugMug for years and keep everything there, I decided to create a non-browseable album I could upload images to, then share from there.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://github.com/pdxmph/imgup">imgup</a> is a project I worked on a few years ago to solve the problem of where to put photos for my blogs after experiencing a few weird things with different services: The image files being renamed into something illegible, or suffering from crappy compression. Since I have been using SmugMug for years and keep everything there, I decided to create a non-browseable album I could upload images to, then share from there.</p>
<p>The problem with that idea was how cumbersome/tedious it was to upload things to SmugMug, grab the URL for the image, etc., so I made imgup to solve that: You just give it an image, a caption, and a title, and get back a link to the SmugMug-hosted image along with all the markup for copy/paste into a post, either as Markdown or HTML. There&rsquo;s a history page with recent uploads, too.</p>
<p>I recently migrated it off of its Heroku hosting and into Docker on my Synology, and I&rsquo;ve been especially glad for it since starting to blog on lmno, which offers no image hosting of its own, but I&rsquo;ve also wanted to be able to run it as a CLI app, so this evening I got around to making that interface for it.</p>
<p>It just takes a <code>--title</code> and <code>--caption</code> along with a filename and returns a Markdown snippet:</p>
<pre><code>$ imgup -t &quot;Breakfast at Grits 'n Gravy&quot; -c &quot;Saturday morning breakfast&quot; /Users/mph/Desktop/IMG_0627.jpg

![Breakfast at Grits 'n Gravy](https://pix.puddingtime.org/Uploads/n-47GBfb/i-CDnXqDV)
</code></pre>
<p>… which gives me this:</p>
<p><img src="https://photos.smugmug.com/photos/i-CDnXqDV/0/NZKr7D3jLjk8Q22ttSqjVsWm5M4w8BTRkL43sp5VM/XL/i-CDnXqDV-XL.jpg" alt="img"></p>
<p>The home screen of the web interface:</p>
<p><img src="https://photos.smugmug.com/photos/i-rrm879C/0/LVDzJXXM7SCPXg8BFBDGsP3ZVFRm6GW4skmvk9cqS/XL/i-rrm879C-XL.png" alt="img"></p>
<p>… and recent uploads, with snippets ready for copy/paste as either HTML or Markdown image tags:</p>
<p><img src="https://photos.smugmug.com/photos/i-4BgdznH/0/KvtLrGtBkrSDhS94n7HVbdGbKPkLpBrMbzLpCchP6/XL/i-4BgdznH-XL.png" alt="img"></p>
]]></content:encoded>
    </item>
    <item>
      <title>All along the watchtower</title>
      <link>https://mike.puddingtime.org/posts/2025-04-26-all-along-the-watchtower/</link>
      <pubDate>Sat, 26 Apr 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-04-26-all-along-the-watchtower/</guid>
      <description>&lt;p&gt;I used to have a chief engineer on my team whom I loved dearly, because when I&amp;rsquo;d be in the throes of my worst managerial contortions, he&amp;rsquo;d quietly ask, &amp;ldquo;Mike, what problem are you trying to solve?&amp;rdquo; He was very good at winding things back and resetting.&lt;/p&gt;
&lt;p&gt;At the beginning of our relationship I would feel attacked, because it&amp;rsquo;s so easy to get so far out to sea that you lose sight of that initial thing that started the process of piling up fixes and solutions and almost feel like you didn&amp;rsquo;t even know what problem you were trying to solve, you just sort of got caught up in all that change-agent energy and felt like doing something.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>I used to have a chief engineer on my team whom I loved dearly, because when I&rsquo;d be in the throes of my worst managerial contortions, he&rsquo;d quietly ask, &ldquo;Mike, what problem are you trying to solve?&rdquo; He was very good at winding things back and resetting.</p>
<p>At the beginning of our relationship I would feel attacked, because it&rsquo;s so easy to get so far out to sea that you lose sight of that initial thing that started the process of piling up fixes and solutions and almost feel like you didn&rsquo;t even know what problem you were trying to solve, you just sort of got caught up in all that change-agent energy and felt like doing something.</p>
<p>So, re: fiddling around with micro to make it behave more like Emacs, the real problem I was trying to solve was how to get in and out of an editor quickly without dealing with a lot of infrastructure and assumptions.</p>
<p>So I moved my Doom Emacs config out of the way and made a very small one.</p>
<p>I know, I know. We&rsquo;re in Battlestar Galactica territory. This has happened before, it will happen again: Then the layering on begins and soon we have a teetering edifice of bespoke config that becomes harder and harder to manage so we cry out for help to one of the <em>frameworks</em> to save us from ourselves.</p>
<p>I think the interesting thing about the past several days of iterating on cielagonotes is that once I had it into a useful state and was not only iterating on it but using it to jot things down, I felt sort of relieved. And once I <a href="https://puddingtime.org/lol">found that fzf plugin</a>, I felt even more relieved, because just typing <code>nbf</code> into a shell prompt and getting to what I wanted to get to felt like a reconnection with the problem I was trying to solve. I like some of the stuff I&rsquo;ve added into cn, but that plugin solves the vast majority of the problem.</p>
<p>And it&rsquo;s not that I don&rsquo;t want an Emacs-class editor in the mix somewhere. As I was writing down some stuff I&rsquo;d learned yesterday I found myself missing stuff you wouldn&rsquo;t think twice about in an Emacs-class editor, but that isn&rsquo;t really stuff you need massive infrastructure to achieve. Like inserting another file into the current buffer.</p>
<p>So, here we go again.</p>
]]></content:encoded>
    </item>
    <item>
      <title>cielagonote is what I woke up yesterday morning wanting to find</title>
      <link>https://mike.puddingtime.org/posts/2025-04-25-cielagonote-is-what-i-woke-up-yesterday-morning-wanting-to-find/</link>
      <pubDate>Fri, 25 Apr 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-04-25-cielagonote-is-what-i-woke-up-yesterday-morning-wanting-to-find/</guid>
      <description>&lt;p&gt;My &lt;a href=&#34;https://puddingtime.org/lmno-blog-captureel-and-the-whole-lightweight-text-thing&#34;&gt;kick&lt;/a&gt; has reached some kind of logical conclusion in the form of &lt;a href=&#34;https://github.com/pdxmph/cielagonote&#34;&gt;cielagonote&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://puddingtime.org/nuhtizhunal-veblocitrix&#34;&gt;This morning&lt;/a&gt; I started off with a zsh wrapper around fzf and nb for finding and editing notes. nb is fine and all, but I really like the sort of speedy narrowing you get from something like &lt;a href=&#34;https://github.com/jrblevin/deft&#34;&gt;deft&lt;/a&gt; or other members of the Notational Velocity family tree.&lt;/p&gt;
&lt;p&gt;So I was looking for something to wrap around nb to keep taking advantage of its git syncing and a few other features, but also warily eyeing too much dependence on it. If the Giant nb-Eating Space Goat were to pull into orbit tomorrow, I would want to simply watch it magestically devour nb, then have a quick way to write a note about my impressions of the experience without accidentally naming that note the same as another about a similar experience.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>My <a href="https://puddingtime.org/lmno-blog-captureel-and-the-whole-lightweight-text-thing">kick</a> has reached some kind of logical conclusion in the form of <a href="https://github.com/pdxmph/cielagonote">cielagonote</a>.</p>
<p><a href="https://puddingtime.org/nuhtizhunal-veblocitrix">This morning</a> I started off with a zsh wrapper around fzf and nb for finding and editing notes. nb is fine and all, but I really like the sort of speedy narrowing you get from something like <a href="https://github.com/jrblevin/deft">deft</a> or other members of the Notational Velocity family tree.</p>
<p>So I was looking for something to wrap around nb to keep taking advantage of its git syncing and a few other features, but also warily eyeing too much dependence on it. If the Giant nb-Eating Space Goat were to pull into orbit tomorrow, I would want to simply watch it magestically devour nb, then have a quick way to write a note about my impressions of the experience without accidentally naming that note the same as another about a similar experience.</p>
<p>So you just get the basic &ldquo;fuzzy-searchin&rsquo; notes&rdquo; thing:</p>
<ul>
<li>Start typing</li>
<li>full-text search narrows your options</li>
<li>Hit return to pick one and start editing or ^n to make a uniquified duplicate title for whatever reason I was worried about that.</li>
</ul>
<p>It doesn&rsquo;t do deleting or other management (yet).</p>
<p>There&rsquo;s a config file:</p>
<pre><code>notes_dir: ~/notes
default_extension: org
exclude_dirs:
  - denote_archive
  - .git
hide_hidden: true
editor: nb edit
</code></pre>
<p>If you set your editor to <code>nb edit</code> you can be assured your stuff is getting synced. Pick something else and it&rsquo;ll just manage a directory of notes.</p>
<p><code>hide_hidden:</code> just means &ldquo;no dotfiles.&rdquo; <code>exclude_dirs</code> means what it says.</p>
<p>One thing I probably ought to do is ask what file extensions you&rsquo;d <em>like</em> to see. Since this is for me, it just has .org and .md hard-coded.</p>
<p><img src="https://photos.smugmug.com/photos/i-PFWJgW5/0/LGkpRcqsNGCF48pbjvS6NxmbxGPqvQ8DtGr89qzzm/XL/i-PFWJgW5-XL.png" alt="img"></p>
<p>Down here way under the fold, probably also good and proper to note that this was mostly me fumbling around and getting help from ChatGPT. I knew the pieces I wanted to glue together, and I knew how I wanted it to behave, but it took a lot of prompting and nagging. And it&rsquo;s not a new idea. I just couldn&rsquo;t find anything that did exactly what I woke up imagining in a terminal.</p>
]]></content:encoded>
    </item>
    <item>
      <title>cielagonote v0.2.0 - WMD Edition</title>
      <link>https://mike.puddingtime.org/posts/2025-04-25-cielagonote-v020-wmd-edition/</link>
      <pubDate>Fri, 25 Apr 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-04-25-cielagonote-v020-wmd-edition/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/pdxmph/cielagonote/releases/tag/v0.2.0&#34;&gt;cielagonote 0.2.0&lt;/a&gt; adds some basic file management and a convenience feature for daily notes.&lt;/p&gt;
&lt;p&gt;&lt;img src=&#34;https://photos.smugmug.com/photos/i-VmRPJDC/0/MTkthHNsmB3FZKp4s8WhM62nKCxjDgLHgLq6sGxRd/XL/i-VmRPJDC-XL.png&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;p&gt;There are two things that I would love to polish up but probably never will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Since I am a heavy emacsclient user, I run into some interactions between it and &lt;a href=&#34;https://sw.kovidgoyal.net/kitty/&#34;&gt;kitty&lt;/a&gt; that leave the terminal in a disordered state. I&amp;rsquo;ve solved that with a reset after exiting an edit operation. It adds a small bit of latency to an otherwise zippy interaction.&lt;/li&gt;
&lt;li&gt;The rename and delete operations drop you back into the command line for a second. It&amp;rsquo;d be a lot spiffier if that were handled more nicely.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;On the other hand, this is 233 lines of Ruby and an off-the-shelf cast of supporting characters. It was pretty delightful to use it in anger a few times with my topic logs this morning, and it did what I wanted by feeling way less in the way and less &amp;ldquo;now I am entering into some other place and descending down into a corner of it and doing a thing and coming back up out of it.&amp;rdquo;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://github.com/pdxmph/cielagonote/releases/tag/v0.2.0">cielagonote 0.2.0</a> adds some basic file management and a convenience feature for daily notes.</p>
<p><img src="https://photos.smugmug.com/photos/i-VmRPJDC/0/MTkthHNsmB3FZKp4s8WhM62nKCxjDgLHgLq6sGxRd/XL/i-VmRPJDC-XL.png" alt="img"></p>
<p>There are two things that I would love to polish up but probably never will:</p>
<ol>
<li>Since I am a heavy emacsclient user, I run into some interactions between it and <a href="https://sw.kovidgoyal.net/kitty/">kitty</a> that leave the terminal in a disordered state. I&rsquo;ve solved that with a reset after exiting an edit operation. It adds a small bit of latency to an otherwise zippy interaction.</li>
<li>The rename and delete operations drop you back into the command line for a second. It&rsquo;d be a lot spiffier if that were handled more nicely.</li>
</ol>
<p>On the other hand, this is 233 lines of Ruby and an off-the-shelf cast of supporting characters. It was pretty delightful to use it in anger a few times with my topic logs this morning, and it did what I wanted by feeling way less in the way and less &ldquo;now I am entering into some other place and descending down into a corner of it and doing a thing and coming back up out of it.&rdquo;</p>
<p>This has also been piquing my interest in <a href="https://micro-editor.github.io/">micro</a>. There are some good features there, and it is super fast from a standing start, but it feels less like a rabbit hole.</p>
<p>Oh, right: cn 0.2.0 is also set up as a gem now. That was sort of fun to figure out, too.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Emacs keybindings for micro</title>
      <link>https://mike.puddingtime.org/posts/2025-04-25-emacs-keybindings-for-micro/</link>
      <pubDate>Fri, 25 Apr 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-04-25-emacs-keybindings-for-micro/</guid>
      <description>&lt;p&gt;The biggest problem I&amp;rsquo;ve had with &lt;a href=&#34;https://micro-editor.github.io/&#34;&gt;micro&lt;/a&gt; has been getting used to its very CUA-like sensibility. Sticking these in &lt;code&gt;~/.config/micro/bindings.json&lt;/code&gt; looks like it is relieving the worst of it, leaving me with a just-fine zippy little editor that doesn&amp;rsquo;t need Emacs infrastructure to operate.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;{
    &amp;quot;\u001b\u003c&amp;quot;: &amp;quot;CursorStart&amp;quot;,
    &amp;quot;\u001b\u003e&amp;quot;: &amp;quot;CursorEnd&amp;quot;,
    &amp;quot;\u003cCtrl-x\u003e\u003c0\u003e&amp;quot;: &amp;quot;Unsplit&amp;quot;,
    &amp;quot;\u003cCtrl-x\u003e\u003c2\u003e&amp;quot;: &amp;quot;HSplit&amp;quot;,
    &amp;quot;\u003cCtrl-x\u003e\u003c3\u003e&amp;quot;: &amp;quot;VSplit&amp;quot;,
    &amp;quot;\u003cCtrl-x\u003e\u003cCtrl-c\u003e&amp;quot;: &amp;quot;Quit&amp;quot;,
    &amp;quot;\u003cCtrl-x\u003e\u003cCtrl-f\u003e&amp;quot;: &amp;quot;OpenFile&amp;quot;,
    &amp;quot;\u003cCtrl-x\u003e\u003cCtrl-s\u003e&amp;quot;: &amp;quot;Save&amp;quot;,
    &amp;quot;\u003cCtrl-x\u003e\u003ch\u003e&amp;quot;: &amp;quot;SelectAll&amp;quot;,
    &amp;quot;\u003cCtrl-x\u003e\u003co\u003e&amp;quot;: &amp;quot;command:fzf&amp;quot;,
    &amp;quot;Alt-/&amp;quot;: &amp;quot;lua:comment.comment&amp;quot;,
    &amp;quot;Alt-a&amp;quot;: &amp;quot;lua:snippets.Accept&amp;quot;,
    &amp;quot;Alt-b&amp;quot;: &amp;quot;WordLeft&amp;quot;,
    &amp;quot;Alt-d&amp;quot;: &amp;quot;lua:snippets.Cancel&amp;quot;,
    &amp;quot;Alt-f&amp;quot;: &amp;quot;WordRight&amp;quot;,
    &amp;quot;Alt-s&amp;quot;: &amp;quot;lua:snippets.Insert&amp;quot;,
    &amp;quot;Alt-v&amp;quot;: &amp;quot;CursorPageUp&amp;quot;,
    &amp;quot;Alt-w&amp;quot;: &amp;quot;Copy&amp;quot;,
    &amp;quot;Alt-x&amp;quot;: &amp;quot;CommandMode&amp;quot;,
    &amp;quot;Ctrl-a&amp;quot;: &amp;quot;StartOfLine&amp;quot;,
    &amp;quot;Ctrl-e&amp;quot;: &amp;quot;EndOfLine&amp;quot;,
    &amp;quot;Ctrl-g&amp;quot;: &amp;quot;Escape&amp;quot;,
    &amp;quot;Ctrl-k&amp;quot;: &amp;quot;CutLine&amp;quot;,
    &amp;quot;Ctrl-r&amp;quot;: &amp;quot;FindPrevious&amp;quot;,
    &amp;quot;Ctrl-s&amp;quot;: &amp;quot;Find&amp;quot;,
    &amp;quot;Ctrl-v&amp;quot;: &amp;quot;CursorPageDown&amp;quot;,
    &amp;quot;Ctrl-y&amp;quot;: &amp;quot;Paste&amp;quot;,
    &amp;quot;Ctrl-z&amp;quot;: &amp;quot;Undo&amp;quot;,
    &amp;quot;CtrlP&amp;quot;: &amp;quot;command:palettero&amp;quot;,
    &amp;quot;CtrlSpace&amp;quot;: &amp;quot;command:palettero&amp;quot;,
    &amp;quot;CtrlUnderscore&amp;quot;: &amp;quot;Undo&amp;quot;,
    &amp;quot;F1&amp;quot;: &amp;quot;command:cheat&amp;quot;,
    &amp;quot;F12&amp;quot;: &amp;quot;command:makeup&amp;quot;,
    &amp;quot;F4&amp;quot;: &amp;quot;command:jumptag&amp;quot;,
    &amp;quot;F5&amp;quot;: &amp;quot;command:runit&amp;quot;,
    &amp;quot;F9&amp;quot;: &amp;quot;command:makeupbg&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I used to use &lt;a href=&#34;https://www.jedsoft.org/jed/&#34;&gt;jed&lt;/a&gt; for this, until something went wrong with it for a while. It seems to be operating correctly again to judge from my latest pull down from Homebrew, but I just went to this trouble with micro …&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>The biggest problem I&rsquo;ve had with <a href="https://micro-editor.github.io/">micro</a> has been getting used to its very CUA-like sensibility. Sticking these in <code>~/.config/micro/bindings.json</code> looks like it is relieving the worst of it, leaving me with a just-fine zippy little editor that doesn&rsquo;t need Emacs infrastructure to operate.</p>
<pre><code>{
    &quot;\u001b\u003c&quot;: &quot;CursorStart&quot;,
    &quot;\u001b\u003e&quot;: &quot;CursorEnd&quot;,
    &quot;\u003cCtrl-x\u003e\u003c0\u003e&quot;: &quot;Unsplit&quot;,
    &quot;\u003cCtrl-x\u003e\u003c2\u003e&quot;: &quot;HSplit&quot;,
    &quot;\u003cCtrl-x\u003e\u003c3\u003e&quot;: &quot;VSplit&quot;,
    &quot;\u003cCtrl-x\u003e\u003cCtrl-c\u003e&quot;: &quot;Quit&quot;,
    &quot;\u003cCtrl-x\u003e\u003cCtrl-f\u003e&quot;: &quot;OpenFile&quot;,
    &quot;\u003cCtrl-x\u003e\u003cCtrl-s\u003e&quot;: &quot;Save&quot;,
    &quot;\u003cCtrl-x\u003e\u003ch\u003e&quot;: &quot;SelectAll&quot;,
    &quot;\u003cCtrl-x\u003e\u003co\u003e&quot;: &quot;command:fzf&quot;,
    &quot;Alt-/&quot;: &quot;lua:comment.comment&quot;,
    &quot;Alt-a&quot;: &quot;lua:snippets.Accept&quot;,
    &quot;Alt-b&quot;: &quot;WordLeft&quot;,
    &quot;Alt-d&quot;: &quot;lua:snippets.Cancel&quot;,
    &quot;Alt-f&quot;: &quot;WordRight&quot;,
    &quot;Alt-s&quot;: &quot;lua:snippets.Insert&quot;,
    &quot;Alt-v&quot;: &quot;CursorPageUp&quot;,
    &quot;Alt-w&quot;: &quot;Copy&quot;,
    &quot;Alt-x&quot;: &quot;CommandMode&quot;,
    &quot;Ctrl-a&quot;: &quot;StartOfLine&quot;,
    &quot;Ctrl-e&quot;: &quot;EndOfLine&quot;,
    &quot;Ctrl-g&quot;: &quot;Escape&quot;,
    &quot;Ctrl-k&quot;: &quot;CutLine&quot;,
    &quot;Ctrl-r&quot;: &quot;FindPrevious&quot;,
    &quot;Ctrl-s&quot;: &quot;Find&quot;,
    &quot;Ctrl-v&quot;: &quot;CursorPageDown&quot;,
    &quot;Ctrl-y&quot;: &quot;Paste&quot;,
    &quot;Ctrl-z&quot;: &quot;Undo&quot;,
    &quot;CtrlP&quot;: &quot;command:palettero&quot;,
    &quot;CtrlSpace&quot;: &quot;command:palettero&quot;,
    &quot;CtrlUnderscore&quot;: &quot;Undo&quot;,
    &quot;F1&quot;: &quot;command:cheat&quot;,
    &quot;F12&quot;: &quot;command:makeup&quot;,
    &quot;F4&quot;: &quot;command:jumptag&quot;,
    &quot;F5&quot;: &quot;command:runit&quot;,
    &quot;F9&quot;: &quot;command:makeupbg&quot;
}
</code></pre>
<p>I used to use <a href="https://www.jedsoft.org/jed/">jed</a> for this, until something went wrong with it for a while. It seems to be operating correctly again to judge from my latest pull down from Homebrew, but I just went to this trouble with micro …</p>
<p>Anyhow, I realized a few things got left out there, so <a href="https://gist.github.com/pdxmph/521c06829aef0157db02a9c42952f86a">here&rsquo;s a gist with a more complete set</a> including Emacs-style <code>C-_</code> undo and <code>Alt-&lt;</code> <code>Alt-&gt;</code> top/bottom of the buffer.</p>
]]></content:encoded>
    </item>
    <item>
      <title>lol</title>
      <link>https://mike.puddingtime.org/posts/2025-04-25-lol/</link>
      <pubDate>Fri, 25 Apr 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-04-25-lol/</guid>
      <description>&lt;p&gt;Just &lt;code&gt;nb install fzf.nb-plugin&lt;/code&gt; and &lt;code&gt;nb fzf&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;alias nbf&lt;/code&gt;&amp;ldquo;nb fzf&amp;rdquo;= if you&amp;rsquo;re feeling frisky.&lt;/p&gt;
&lt;p&gt;Done.&lt;/p&gt;
&lt;p&gt;I mean, not really, because &lt;a href=&#34;https://github.com/pdxmph/cielagonote&#34;&gt;cielagonote&lt;/a&gt; does the whole &amp;ldquo;make it if it doesn&amp;rsquo;t exist&amp;rdquo; thing, and it&amp;rsquo;s doing full-text search. But if the thing you don&amp;rsquo;t like about nb is &amp;ldquo;list, get a number, enter a number&amp;rdquo; to operate on your file, this does the job.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;#!/usr/bin/env bash
###############################################################################
# fzf.nb-plugin
#
# FZF Plugin for nb
#
###############################################################################

# Add the new subcommand name with `_subcommands add &amp;lt;name&amp;gt;`.
_subcommands add &amp;quot;fzf&amp;quot;

# Define help and usage text with `_subcommands describe &amp;lt;subcommand&amp;gt; &amp;lt;usage&amp;gt;`.
_subcommands describe &amp;quot;fzf&amp;quot; &amp;lt;&amp;lt;HEREDOC
Usage:
  nb fzf
  Description:
    Search through current notebook using fzf and then edit sepected item.
HEREDOC

_fzf() {
  local note=$(_ls -t note --filename -a --no-footer --no-header --no-indicator --tree | fzf --ansi --header &amp;quot;$(_notebook current --name)&amp;quot; --preview &amp;quot;echo {} | sed &#39;&amp;quot;&#39;s/\x1b\[[0-9;]*m//g&#39;&amp;quot;&#39; | awk -F&#39;[][]&#39; &#39;&amp;quot;&#39;{print $2}&#39;&amp;quot;&#39; | xargs -n 1 nb show -p | ${NB_MARKDOWN_TOOL:-bat} -&amp;quot; | awk -F&#39;[][]&#39; &#39;{print $2}&#39;)

  if ! [[ -z &amp;quot;$note&amp;quot; ]]; then
    command nb edit &amp;quot;$note&amp;quot;
  fi
}
&lt;/code&gt;&lt;/pre&gt;</description>
      <content:encoded><![CDATA[<p>Just <code>nb install fzf.nb-plugin</code> and <code>nb fzf</code>.</p>
<p><code>alias nbf</code>&ldquo;nb fzf&rdquo;= if you&rsquo;re feeling frisky.</p>
<p>Done.</p>
<p>I mean, not really, because <a href="https://github.com/pdxmph/cielagonote">cielagonote</a> does the whole &ldquo;make it if it doesn&rsquo;t exist&rdquo; thing, and it&rsquo;s doing full-text search. But if the thing you don&rsquo;t like about nb is &ldquo;list, get a number, enter a number&rdquo; to operate on your file, this does the job.</p>
<pre><code>#!/usr/bin/env bash
###############################################################################
# fzf.nb-plugin
#
# FZF Plugin for nb
#
###############################################################################

# Add the new subcommand name with `_subcommands add &lt;name&gt;`.
_subcommands add &quot;fzf&quot;

# Define help and usage text with `_subcommands describe &lt;subcommand&gt; &lt;usage&gt;`.
_subcommands describe &quot;fzf&quot; &lt;&lt;HEREDOC
Usage:
  nb fzf
  Description:
    Search through current notebook using fzf and then edit sepected item.
HEREDOC

_fzf() {
  local note=$(_ls -t note --filename -a --no-footer --no-header --no-indicator --tree | fzf --ansi --header &quot;$(_notebook current --name)&quot; --preview &quot;echo {} | sed '&quot;'s/\x1b\[[0-9;]*m//g'&quot;' | awk -F'[][]' '&quot;'{print $2}'&quot;' | xargs -n 1 nb show -p | ${NB_MARKDOWN_TOOL:-bat} -&quot; | awk -F'[][]' '{print $2}')

  if ! [[ -z &quot;$note&quot; ]]; then
    command nb edit &quot;$note&quot;
  fi
}
</code></pre>
]]></content:encoded>
    </item>
    <item>
      <title>nuhtizhunal veblocitrix</title>
      <link>https://mike.puddingtime.org/posts/2025-04-25-nuhtizhunal-veblocitrix/</link>
      <pubDate>Fri, 25 Apr 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-04-25-nuhtizhunal-veblocitrix/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/junegunn/fzf&#34;&gt;fzf&lt;/a&gt; is a command line fuzzy finding TUI thing that gives you really fast progressive narrowing on a directory full of stuff then invokes whatever on the target. This morning&amp;rsquo;s science experiment is wrapping it in a zsh function for my nb that pops up a fuzzy finder with incremental search, or offers to start a new note in nb. If you take the &lt;code&gt;New Note&lt;/code&gt; option, you get a prompt for the title and can start typing. The whole thing is wrapped around &lt;code&gt;nb&lt;/code&gt; so I get the benefits of its autosync infrastructure, just with a search interface that is way faster for finding things.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><a href="https://github.com/junegunn/fzf">fzf</a> is a command line fuzzy finding TUI thing that gives you really fast progressive narrowing on a directory full of stuff then invokes whatever on the target. This morning&rsquo;s science experiment is wrapping it in a zsh function for my nb that pops up a fuzzy finder with incremental search, or offers to start a new note in nb. If you take the <code>New Note</code> option, you get a prompt for the title and can start typing. The whole thing is wrapped around <code>nb</code> so I get the benefits of its autosync infrastructure, just with a search interface that is way faster for finding things.</p>
<p>Getting this to work with emacsclient wasn&rsquo;t great, and in fact it does not work with emacsclient right now. I&rsquo;ve been playing around with <a href="https://micro-editor.github.io/">micro</a> and that was great for getting this far with the experiment. Not sure I&rsquo;ll keep it but one of the things I was trying to figure out when I stumbled across nb (again) was &ldquo;has anyone done a TUI Notational Velocity&rdquo;? I haven&rsquo;t found anything like that, exactly, but it is pretty cool to me that with fzf, fd, and micro, you can get most of the way there with a zsh function.</p>
<p>Anyhow, I need to catch up on some stuff today.</p>
<pre><code># ~/.zsh/functions/znotes.zsh

zn() {
  local notes_dir=~/notes
  cd &quot;$notes_dir&quot; || return 1

  local files
  files=$(fd --type f --extension org --extension md --exclude denote . &quot;$notes_dir&quot;) || return 1

  local file
  file=$( (echo &quot;[New Note]&quot;; echo &quot;$files&quot;) \
          | fzf --prompt=&quot;Edit or create note: &quot; \
                --preview='[[ {} == &quot;[New Note]&quot; ]] || bat --style=numbers --color=always --line-range=:100 {}') || return 1

  if [[ &quot;$file&quot; == &quot;[New Note]&quot; ]]; then
    echo -n &quot;New note title: &quot;
    read -r title
    [[ -z &quot;$title&quot; ]] &amp;&amp; echo &quot;Aborted: no title given.&quot; &amp;&amp; return 1

    nb new --title &quot;$title&quot;
    echo &quot;Note created. You can run \`nb list\` to see it.&quot;
  else
    nb edit &quot;$file&quot;
  fi
}
</code></pre>
]]></content:encoded>
    </item>
    <item>
      <title>log2file.el for quick logging into md or org (pencils down, back to work)</title>
      <link>https://mike.puddingtime.org/posts/2025-04-23-log2fileel-for-quick-logging-into-md-or-org-pencils-down-back-to-work/</link>
      <pubDate>Wed, 23 Apr 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-04-23-log2fileel-for-quick-logging-into-md-or-org-pencils-down-back-to-work/</guid>
      <description>&lt;p&gt;In the process of diddling around with a bunch of different kinds of logs and formats, I realized I had two things that did the same thing, more or less, for org files and Markdown files. The &lt;a href=&#34;https://github.com/pdxmph/org-topic-log&#34;&gt;org version&lt;/a&gt; bothered me because I went down the wrong track and ended up using &lt;code&gt;org-agenda-files&lt;/code&gt; with a given filetag to populate the list of potential targets and get out of some stuff I couldn&amp;rsquo;t get right. The &lt;a href=&#34;https://github.com/pdxmph/md-capture&#34;&gt;Markdown version&lt;/a&gt; was better, but didn&amp;rsquo;t have a non-fiddle-with-your-config-file way to get new files added.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>In the process of diddling around with a bunch of different kinds of logs and formats, I realized I had two things that did the same thing, more or less, for org files and Markdown files. The <a href="https://github.com/pdxmph/org-topic-log">org version</a> bothered me because I went down the wrong track and ended up using <code>org-agenda-files</code> with a given filetag to populate the list of potential targets and get out of some stuff I couldn&rsquo;t get right. The <a href="https://github.com/pdxmph/md-capture">Markdown version</a> was better, but didn&rsquo;t have a non-fiddle-with-your-config-file way to get new files added.</p>
<p>So <a href="https://github.com/pdxmph/log2file.el">log2file</a> takes both of them and adds a few functions + Custom settings to add and remove files from your list of targets: No fiddling with your org agendas, no editing your config file if you decide to add a file as a target, and it speaks both Markdown and org, picking a log heading format based on the file extension, and enforcing the presence of either a first-line l1 heading or org <code>#+TITLE:</code> line based on the filename if it doesn&rsquo;t find one.</p>
<p>I don&rsquo;t think I&rsquo;ll do much more with it. The point of embarkation on all this, as I sort of <a href="https://lmno.lol/puddingtime/lmno-blog-captureel-and-the-whole-lightweight-text-thing">failed to come back around and make clear yesterday</a>, was that I have a simple set of requirements:</p>
<ul>
<li>Keep it in plain text</li>
<li>Favor a logging/journaling approach</li>
<li>Avoid anything that feels fragile or complex</li>
</ul>
<p>On that last point, almost everything these days feels fragile, where &ldquo;fragile&rdquo; is a function of:</p>
<ul>
<li>Depending on rigid formatting conventions (filename, metadata, inline syntax of any complexity)</li>
<li>Depending on a specific app to interact with the data</li>
</ul>
<p>… and from those requirements I didn&rsquo;t feel like much of anything these days works for me. My grandmother once got very, very angry with my father for splurging on a $10 Christmas tree when we went home for the holidays, because she was a dirt-farming Depression survivor and frugality had been etched into her bones. I&rsquo;ve just had seemingly simple shit break on me in a way that is stupidly and frustratingly disruptive when you suddenly realize the underlying complexity of the tools supporting the workflow is going to make it hard to just pick up with a text editor and no supporting automation.</p>
<p>So where I <em>started</em> with this was just a collection of <code>yasnippet</code> and <a href="https://espanso.org/">Espanso</a> snippets that aped the Journelly log format:</p>
<ul>
<li>Open a log file</li>
<li>Trigger the snippet</li>
<li>Enter the text</li>
<li>Save/exit</li>
</ul>
<p>But I was really inspired by <code>org-capture</code>, which wrings out a ton of the friction in routing text to a sensible endpoint. The problems with org-capture were:</p>
<ol>
<li>org-mode dependent</li>
<li>Complex, in that it was beyond my skill to populate a custom list of targets, and I hated the idea of manually keeping a target list in a capture template.</li>
<li>org always beguiles me into more and more complexity and &ldquo;just one more thing&rdquo;</li>
</ol>
<p>So this is a way to get some speed back into the interaction … no finding/opening/snippeting … but in a way that doesn&rsquo;t leave me dependent on a bunch of fragile stuff.</p>
]]></content:encoded>
    </item>
    <item>
      <title>lmno-blog-capture.el and the whole lightweight text thing</title>
      <link>https://mike.puddingtime.org/posts/2025-04-22-lmno-blog-captureel-and-the-whole-lightweight-text-thing/</link>
      <pubDate>Tue, 22 Apr 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-04-22-lmno-blog-captureel-and-the-whole-lightweight-text-thing/</guid>
      <description>&lt;p&gt;Yesterday I made a little thing to quickly capture &lt;a href=&#34;https://lmno.lol&#34;&gt;lmno.lol&lt;/a&gt; blog posts from a little window in Emacs. I&amp;rsquo;m kind of having fun package-izing these things, so today I bundled it up into &lt;a href=&#34;https://github.com/pdxmph/lmno-blog-capture&#34;&gt;pdxmph/lmno-blog-capture&lt;/a&gt;, with a customization group (with one option).&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been on a small tear with these things lately, and whenever I go on a small tear I think &amp;ldquo;this is happening for a reason,&amp;rdquo; and the reason is usually &amp;ldquo;because there&amp;rsquo;s something you don&amp;rsquo;t want to go do,&amp;rdquo; and that is true here. But I &lt;em&gt;like&lt;/em&gt; times like this, because they exercise part of me that doesn&amp;rsquo;t get exercised much: I spend a lot of my day thinking &amp;ldquo;will this scale,&amp;rdquo; and &amp;ldquo;but do we really need to do this,&amp;rdquo; and &amp;ldquo;what is security engineering going to do when they find out this happened,&amp;rdquo; and &amp;ldquo;did I make Compliance angry.&amp;rdquo;&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>Yesterday I made a little thing to quickly capture <a href="https://lmno.lol">lmno.lol</a> blog posts from a little window in Emacs. I&rsquo;m kind of having fun package-izing these things, so today I bundled it up into <a href="https://github.com/pdxmph/lmno-blog-capture">pdxmph/lmno-blog-capture</a>, with a customization group (with one option).</p>
<p>I&rsquo;ve been on a small tear with these things lately, and whenever I go on a small tear I think &ldquo;this is happening for a reason,&rdquo; and the reason is usually &ldquo;because there&rsquo;s something you don&rsquo;t want to go do,&rdquo; and that is true here. But I <em>like</em> times like this, because they exercise part of me that doesn&rsquo;t get exercised much: I spend a lot of my day thinking &ldquo;will this scale,&rdquo; and &ldquo;but do we really need to do this,&rdquo; and &ldquo;what is security engineering going to do when they find out this happened,&rdquo; and &ldquo;did I make Compliance angry.&rdquo;</p>
<p>And I&rsquo;m feeling sort of engaged with the problem of &ldquo;what&rsquo;s just enough structure for the few notes I keep without freaking out and tipping over into Some Whole Paradigm,&rdquo; because every time I tip over into Some Whole Paradigm I&rsquo;m, like, &ldquo;well now what?&rdquo; All my brain power went to Learning the Whole Paradigm and I don&rsquo;t have any left to do stuff I should be doing.</p>
<h2 id="citing-inspirations">Citing inspirations</h2>
<p>A few people and things have been inspiring for me on this week&rsquo;s jaunt into plaintext living:</p>
<ul>
<li>I really dug an old take from Jack Baty on <a href="https://archive.baty.net/2019/using-the-emacs-deft-package-for-topic-journals/">using Deft to manage little topical journals</a>. Just, &ldquo;make some files about topics, write logs in them.&rdquo;</li>
<li>I am really into lmno.lol maker Álvaro Ramírez&rsquo;s <a href="https://apps.apple.com/us/app/journelly/id6470714669">Journelly</a>. As an app it&rsquo;s great, and as a concept it&rsquo;s cool: Underneath the friendly iOS skin, it&rsquo;s just dropping entries into an org file that you can also work with from a desktop machine if you like.</li>
<li>lmno.lol itself is a variation on that theme: Just put a datestamped entry in a Markdown file that your entire blog lives in.</li>
</ul>
<p>These things are all very simple to do. Jack&rsquo;s approach just wants text files. They could even be <em>just text files</em> with no markup.</p>
<p>Journelly has to have <em>some</em> markup, and it is a whole app that relies on a ton of assumptions about how to move files around over a network, etc. but if your phone broke and all you had was, like, <em>nano</em>, you could keep on journaling.</p>
<p>lmno.lol? Your <em>whole blog</em> is in a single Markdown file. You have to know the date and the &ldquo;#&rdquo; key, and you&rsquo;re in business.</p>
<h2 id="how-it-all-went-to-hell">How it all went to hell</h2>
<p>Let&rsquo;s travel back in time to, like, 2004 or so:</p>
<p>Danny O&rsquo;Brien gives a talk describing &ldquo;life hacks,&rdquo; the spirit of which is probably best captured by <a href="https://craphound.com/lifehacks2.txt">Cory Doctorow&rsquo;s contemporaneous notes</a>. Everyone went bananas over the idea that you&rsquo;re really better off not complexifying the shit out of everything, then set about complexifying the shit out of <em>everything</em>.</p>
<p>I mean, we&rsquo;re dealing with a population that does the whole knowledge work thing, and a distinguishing characteristic of knowledge workers is that they spend a lot of time learning and living in systems. We have the whole idea of a <a href="https://www.dissentmagazine.org/online_articles/on-the-origins-of-the-professional-managerial-class-an-interview-with-barbara-ehrenreich/">professional managerial class</a>:</p>
<blockquote>
<p>&ldquo;… salaried mental workers who do not own the means of production and whose major function in the social division of labor may be described broadly as the reproduction of capitalist culture and capitalist class relations.&rdquo;</p>
</blockquote>
<p>It was once suggested to me that where &ldquo;professional&rdquo; once meant &ldquo;a job where someone could get sued for malpractice&rdquo; (doctors, lawyers, architects), it has come to mean &ldquo;someone who is reliably aligned with the values of the capitalists they work for and behaves in a manner that is comfortably predictable to capitalists.&rdquo;</p>
<p>Point is, tech industry people live within kind of complex systems: They have to manage complex models to do their actual productive work, and they have to navigate complex functional relationships to deliver things. I still get a little swimmy in the head when I think about one place I worked deciding to embrace Scaled Agile, and I get outright nauseated when I remember a dear friend excitedly talking about &ldquo;taking the whole business Agile. All of &rsquo;em! <em>Especially</em> the marketing team!&rdquo;</p>
<p>So they can&rsquo;t really be expected to keep things simple. Part of their value is in their ability to behave predictably when confronted with complexity, so they have to like it at least a <em>little</em>.</p>
<h2 id="so-im-stealing">So I&rsquo;m stealing</h2>
<p>I&rsquo;m not sure where I&rsquo;m going to end up, but I do know at this point:</p>
<ul>
<li>Plain text files are good.</li>
<li>I&rsquo;ve had success in the past with variations on <a href="https://nesslabs.com/interstitial-journaling">interstitial journaling</a>, which is what Jack&rsquo;s idea is most like.</li>
<li>I really took to the &ldquo;stick something in a file and keep moving&rdquo; opportunity Journelly afforded me.</li>
<li>I don&rsquo;t want to live in a single text file for everything, but I do want to live in a few text files for most of the things.</li>
<li>I don&rsquo;t mind investing some time in a little automation to make it faster to do this kind of stuff with text.</li>
</ul>
<h2 id="org-or-markdown">org or Markdown</h2>
<p>What I&rsquo;m really not sure about at this point is the question of doing it in org-mode files or Markdown.</p>
<p>org pros:</p>
<ul>
<li>It&rsquo;s a little easier to add a light layer of metadata to content.</li>
<li>That metadata layer is optional.</li>
<li>At its simplest, org is as simple as Markdown</li>
</ul>
<p>org cons:</p>
<ul>
<li>There&rsquo;s so much there in the way of opportunities to complexify the living shit out of it</li>
<li>Despite a few things like <a href="https://xenodium.com/plain-org-for-ios">Plain Org</a>, there are not a lot of ways to work with it without Emacs.</li>
</ul>
<p>Markdown pros:</p>
<ul>
<li>It&rsquo;s everywhere.</li>
<li>Weirdly, even though there are ways to make it more complex, they almost always suck because there are <em>so many variants</em> that nobody ventures much past the basic spec + a few niceties like checkbox lists when building tools for it, and those extensions are often <em>hideous</em> to look at. They really damage the readability. (org does this, too, but it has things like properties drawers to hide some of that)</li>
<li>Yes, the previous bullet is a &ldquo;plus,&rdquo; because Markdown is sort of antagonistic to much complexity and I think that&rsquo;s good: I&rsquo;m a knowledge-workin&rsquo; PMC dillhole, too.</li>
</ul>
<p>Markdown cons:</p>
<ul>
<li>Wedging metadata into it is sort of a challenge outside maybe adopting an inline hashtag convention or bolting YAML/TOML frontmatter on (which not all tools will deal with well.)</li>
<li>Eventually you&rsquo;ll end up thinking &ldquo;fuck it, might as well do this in Obsidian,&rdquo; and then all hell breaks loose: Welcome to &ldquo;org mode without Emacs, just in an Electron app, but with Markdown.&rdquo;</li>
</ul>
<p>Not sure what I&rsquo;m gonna do, but in a little frenzy of ChatGPT co-piloting, I did come up with a few ways to make life in a few plaintext silos easier:</p>
<ul>
<li><a href="https://github.com/pdxmph/org-topic-log">org-topic-log</a> just pops open an org-capture-like window that lets you select from any agenda files that have <code>#+FILETAGS: topic</code> in the frontmatter. You can pick any word you like for the filetag. Super simple to invoke it, drop in a log entry, and keep going.</li>
<li><a href="https://github.com/pdxmph/md-capture">md-capture</a> does the same thing, except Markdown doesn&rsquo;t have all the infrastructure org-mode does, so you can either tell it &ldquo;just use anything in this directory&rdquo; (messier and messier over time) or specify a file list (a hassle to manage if you make new topics a lot).</li>
</ul>
<p>I&rsquo;m just wavering on whether to do it with Markdown knowing, I will regret any attempts to make those notes more complex, or org because it might be nice to have a few of its conventions (knowing its portability will nosedive the more of them I embrace).</p>
<p>Also: This post written with <a href="https://github.com/pdxmph/lmno-blog-capture">lmno-blog-capture</a>. If you have an lmno.lol blog you can just put it in your load path. If you want to keep up with it, you can add it to Doom&rsquo;s <code>packages.el</code>:</p>
<pre><code>package! lmno-blog-capture :recipe (:host github :repo &quot;pdxmph/lmno-blog-capture&quot;))
</code></pre>
]]></content:encoded>
    </item>
    <item>
      <title>Okay. We made a snippet. ✂️</title>
      <link>https://mike.puddingtime.org/posts/2025-04-21-okay-we-made-a-snippet/</link>
      <pubDate>Mon, 21 Apr 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-04-21-okay-we-made-a-snippet/</guid>
      <description>&lt;p&gt;This may be my consolation prize for &lt;a href=&#34;https://ox-hugo.scripter.co/&#34;&gt;ox-hugo&lt;/a&gt; going south on me.&lt;/p&gt;
&lt;h1 id=&#34;blog-text-art-banner&#34;&gt;blog-text-art-banner&lt;/h1&gt;
&lt;pre&gt;&lt;code&gt; _____  _____  _  _____  ______  _   _ ______ ______  _____  _   _  _____  _____  _____ ___  ___ _____  _
|_   _||_   _|( )/  ___| | ___ \| | | ||  _  \|  _  \|_   _|| \ | ||  __ \|_   _||_   _||  \/  ||  ___|| |
  | |    | |  |/ \ `--.  | |_/ /| | | || | | || | | |  | |  |  \| || |  \/  | |    | |  | .  . || |__  | |
  | |    | |      `--. \ |  __/ | | | || | | || | | |  | |  | . ` || | __   | |    | |  | |\/| ||  __| | |
 _| |_   | |     /\__/ / | |    | |_| || |/ / | |/ /  _| |_ | |\  || |_\ \  | |   _| |_ | |  | || |___ |_|
 \___/   \_/     \____/  \_|     \___/ |___/  |___/   \___/ \_| \_/ \____/  \_/   \___/ \_|  |_/\____/ (_) 🔥🤘🏻🔥
&lt;/code&gt;&lt;/pre&gt;
&lt;h1 id=&#34;blog-about&#34;&gt;blog-about&lt;/h1&gt;
&lt;p&gt;Hello 👋 I&amp;rsquo;m Mike. Regularly blogging at &lt;a href=&#34;https://mike.puddingtime.org&#34;&gt;mike.puddingtime.org&lt;/a&gt;, tooting &lt;a href=&#34;https://social.lol/@mph&#34;&gt;@mph@social.lol&lt;/a&gt; and wandering around in Portland, OR.&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p>This may be my consolation prize for <a href="https://ox-hugo.scripter.co/">ox-hugo</a> going south on me.</p>
<h1 id="blog-text-art-banner">blog-text-art-banner</h1>
<pre><code> _____  _____  _  _____  ______  _   _ ______ ______  _____  _   _  _____  _____  _____ ___  ___ _____  _
|_   _||_   _|( )/  ___| | ___ \| | | ||  _  \|  _  \|_   _|| \ | ||  __ \|_   _||_   _||  \/  ||  ___|| |
  | |    | |  |/ \ `--.  | |_/ /| | | || | | || | | |  | |  |  \| || |  \/  | |    | |  | .  . || |__  | |
  | |    | |      `--. \ |  __/ | | | || | | || | | |  | |  | . ` || | __   | |    | |  | |\/| ||  __| | |
 _| |_   | |     /\__/ / | |    | |_| || |/ / | |/ /  _| |_ | |\  || |_\ \  | |   _| |_ | |  | || |___ |_|
 \___/   \_/     \____/  \_|     \___/ |___/  |___/   \___/ \_| \_/ \____/  \_/   \___/ \_|  |_/\____/ (_) 🔥🤘🏻🔥
</code></pre>
<h1 id="blog-about">blog-about</h1>
<p>Hello 👋 I&rsquo;m Mike. Regularly blogging at <a href="https://mike.puddingtime.org">mike.puddingtime.org</a>, tooting <a href="https://social.lol/@mph">@mph@social.lol</a> and wandering around in Portland, OR.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Saw X in Portland</title>
      <link>https://mike.puddingtime.org/posts/2025-04-21-saw-x-in-portland/</link>
      <pubDate>Mon, 21 Apr 2025 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2025-04-21-saw-x-in-portland/</guid>
      <description>&lt;p&gt;&lt;img src=&#34;https://photos.smugmug.com/photos/i-dqVSw2P/0/M3J4knxn8vpw37R7HNNwW5s4X42TtKvkVXMHvp4xT/XL/i-dqVSw2P-XL.jpg&#34; alt=&#34;img&#34;&gt;&lt;/p&gt;
&lt;p&gt;This was an opportunity to try out my Smugmug/upload/image snippet app &lt;a href=&#34;https://github.com/pdxmph/imgup&#34;&gt;imgup&lt;/a&gt; (which it turns out is an amazingly common name for things that make images go up to somewhere else.)&lt;/p&gt;</description>
      <content:encoded><![CDATA[<p><img src="https://photos.smugmug.com/photos/i-dqVSw2P/0/M3J4knxn8vpw37R7HNNwW5s4X42TtKvkVXMHvp4xT/XL/i-dqVSw2P-XL.jpg" alt="img"></p>
<p>This was an opportunity to try out my Smugmug/upload/image snippet app <a href="https://github.com/pdxmph/imgup">imgup</a> (which it turns out is an amazingly common name for things that make images go up to somewhere else.)</p>
]]></content:encoded>
    </item>
  </channel>
</rss>
