<?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/chatgpt/</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>Fri, 12 May 2023 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://mike.puddingtime.org/tags/chatgpt/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Daily Notes for 2023-05-12</title>
      <link>https://mike.puddingtime.org/posts/2023-05-12-daily-notes/</link>
      <pubDate>Fri, 12 May 2023 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-05-12-daily-notes/</guid>
      <description>Automation vs. Augmentation, ChatGPT and ideology, day one of the Things/org experiment.</description>
      <content:encoded><![CDATA[<h2 id="automation-vs-dot-augementation">Automation vs. Augementation</h2>
<p><a href="http://www.zephoria.org/thoughts/archives/2023/04/21/deskilling-on-the-job.html">This is a thoughtful piece by danah boyd</a> that gets to some things I&rsquo;ve been thinking about re: AI.</p>
<blockquote>
<p>Whether you are in Camp Augmentation or Camp Automation, it’s really important to look holistically about how skills and jobs fit into society. Even if you dream of automating away all of the jobs, consider what happens on the other side. How do you ensure a future with highly skilled people? This is a lesson that too many war-torn countries have learned the hard way. I’m not worried about the coming dawn of the Terminator, but I am worried that we will use AI to wage war on our own labor forces in pursuit of efficiency. As with all wars, it’s the unintended consequences that will matter most. Who is thinking about the ripple effects of those choices?</p>
</blockquote>
<p>There is a lot of commentary <a href="https://www.reddit.com/r/MetaFilterMeta/comments/13chd82/how_many_people_are_feeling_or_fearing_the_impact/">in this r/metafiltermeta thread about AI</a>, which was framed from a place of anxiety:</p>
<blockquote>
<p>I&rsquo;m reading about AI&rsquo;s impact on coding, graphic design, video, motion graphics, architecture and law. I hear proponents say that they think AI will change jobs, and that smart workers will learn how to use it as an assistant, but when I review Silicon Valley&rsquo;s contributions to labor in the U.S., mostly I see entire fields gutted, and folks moved over to poorly paying gig economy work.</p>
</blockquote>
<p>The more thoughtful responses pointed, I think correctly, to the eventual Gartner Hype Cycle state of equilibrium you get to once you get unrealistic expectations out of the way, trudge through the salty marshes of &ldquo;told you it was all bullshit,&rdquo; and get to &ldquo;how is this thing going to be used day-to-day?&rdquo;</p>
<p>The people at the Peak of Inflated Expectations do what they always do: Try to solve their problems in a manner ill suited to the tool in front of them, or in a manner that is not reflective of the limitations of the model. The chorus waiting for them down at the bottom of the Trough of Disillusionment has no single motivation: Some of it is wise realism, forward thinking, and experience; some of it is whistling past the graveyard or just missing that &ldquo;productivity gains,&rdquo; like many things in technology and business, are not a series of home runs and grand slams, but rather singles and the occasional double. Reframed more bleakly, grinding down labor&rsquo;s ability to resist induced precarity is a game of inches.</p>
<p>Which is the long way around to saying that if the people who are pointing to offshoring and content-farming mania of the naughts and tens are correct in saying they&rsquo;re the closest analogies we have, and if danah boyd is right that &ldquo;we tend to optimize towards more intense work schedules whenever we introduce new technologies while downgrading the status of the highly skilled person,&rdquo; then it&rsquo;s going to mean fewer people working in AI-effected systems that are biased toward always looking for one more headcount they can get away with removing. It&rsquo;ll look different from the &ldquo;prompt engineering&rdquo; everyone imagines today. It&rsquo;ll be software companies figuring out how to integrate existing &ldquo;dumb&rdquo; systems with generative AI systems acting as synthesizers, with a few humans acting as QA on top of that process, working from a weakened position.</p>
<h2 id="chatgpt-is-an-ideology-machine">&ldquo;ChatGPT Is an Ideology Machine&rdquo;</h2>
<p><a href="https://jacobin.com/2023/04/chatgpt-ai-language-models-ideology-media-production/">Jacobin last month</a>:</p>
<blockquote>
<p>A wide variety of Marxists have also seen ideology as a form of kitsch. First articulated by the Marxist art critic Clement Greenberg in 1937, the notion of kitsch is “pre-digested form.” Among all the things we might say or think, some pathways are better traveled than others. The form of those paths is given; we don’t need to forge them in the first place. The constant release of sequels now has this quality of kitsch — we know exactly where we are when we start watching a Marvel movie. For Greenberg, the avant-garde was the formal adventurer, creating new meaning by making new paths. Hegemony and kitsch are combined in the output of GPT systems’ semantic packages, which might miss aspects of “the world” but faithfully capture ideology.</p>
</blockquote>
<h2 id="my-things-link-to-org-stuff">My Things link to org stuff</h2>
<p>Today I started using the org-protocol stuff <a href="/posts/2023-05-11-daily-notes/#connecting-things-todos-to-org-headings">I talked about yesterday</a> with a set of regular todos I added to Things. For my daily writing and journaling todos, I captured links to the headings from the org documents and pasted them into the notes field of the Things todo before marking them done. Clicking on those links brings up a new Emacs frame that jumps straight to the heading in the correct file.</p>
<p>That pretty much recreates the workflow I had with Bear and Things for other kinds of task/notes combinations, and it shows me how to use org-protocol and org-capture to do similar kinds of workflows where Emacs participates in the rest of my tools ecosystem.</p>
<p>So, promising trial experience. I&rsquo;m a little becalmed on heavy-duty task/work tracking right now, so I&rsquo;m satisfied to just note that the idea works and that I&rsquo;ll keep using it to find out where the edge cases are: Something always comes up.</p>
<p>The idea that keeps popping up in my head is that a lot of my past &ldquo;emacsimalism&rdquo; &ndash; a recurring phase I&rsquo;ve experienced over several decades &ndash; was due to the fact that Emacs was pretty much a technology island. The Mac builds weren&rsquo;t always very good, and the ways in which it could speak to the system around it were sort of flaky. But things like org-protocol and a little bit of utility glue with osascript do a lot to make it easier to find your way into and out of Emacs. You don&rsquo;t <em>have</em> to make it your everything because it can work well <em>alongside</em> other things that might suit your individual style better. The idea I&rsquo;m sort of nibbling around right now is that I don&rsquo;t like org-mode for <em>organization of work and tasks</em> so much as I like it for <em>organization of text and ideas</em>. It&rsquo;s less &ldquo;a smarter Things, OmniFocus, or Reminders,&rdquo; and more &ldquo;what I wish Ulysses had been.&rdquo;</p>
<p>Maybe that&rsquo;s why assorted org syntax implementations in more modern text editors (e.g. BBEdit, Sublime, Atom, VSCode) are always disappointing: They&rsquo;re usually just syntax highlighting and no smarts. Might as well just be doing Markdown at that point, because the <em>smarts</em> of org-mode pretty much live in Emacs and lisp. Without that, you&rsquo;re just quibbling over whether a backslash or an asterisk is better <code>emph</code> notation.</p>
<p>Anyhow, we&rsquo;ll leave it at that until there&rsquo;s something new to say. I think I&rsquo;ve visited this topic plenty.</p>
<h2 id="twitter">Twitter</h2>
<p>I disabled my Twitter account late last month, so I think I have a bit under two weeks for it to fully deactivate. I think I will thread the needle between making an <em>announcement</em> and merely noting that I have embarked on the process of closing my account by making it the last heading of today&rsquo;s post, unmentioned in the summary.</p>
<p>There&rsquo;s a needle to thread because my strong preference would be for people to give up on Twitter. So if you&rsquo;re someone with whom I might have some influence, I&rsquo;m happy for you to read this and do the primate thing &ndash; &ldquo;Hm, Mike is a thoughtful, ethical person whose ideas I tend to take under advisement, and he sees Twitter as, on balance, negative and harmful, so I will take that idea under advisement, as well.&rdquo;</p>
<p>That&rsquo;s all.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Daily Notes for 2023-04-12</title>
      <link>https://mike.puddingtime.org/posts/2023-04-12-daily-notes/</link>
      <pubDate>Wed, 12 Apr 2023 16:01:09 -0700</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-04-12-daily-notes/</guid>
      <description>More ChatGPT and org, using the org agenda, Yellowjackets again, Doom keybindings</description>
      <content:encoded><![CDATA[<h2 id="chatgpt-and-org-configuration">ChatGPT and org configuration</h2>
<p>I tried out <a href="https://github.com/alphapapa/org-super-agenda">org-superagenda</a> a while back. It improves on the vanilla org agenda by creating customizable sections, which help it scan a little better. I bounced off of it because while I wanted the quality of life improvements it offered, I was struggling a little with the syntax, and was caught up in that brainspace you can get into where you just want the thing to work and it&rsquo;s throwing off your sense of time and perception of the required investment to make it work.</p>
<p>This morning I was looking at my agenda and hating it because it was in a &ldquo;mostly correct except where it is glaringly incorrect&rdquo; state, so I figured it&rsquo;d be a good practical task to throw at ChatGPT:</p>
<p><code>Describe an orgmode super agenda configuration that shows habits, important items, overdue items, and items due in the near future</code></p>
<p>I got a copy-pastable example that met the requirements.</p>
<p><code>Could you add items due today to that list</code></p>
<p>Yep. That worked.</p>
<p><code>could you move the today list to second place and add a list at the bottom of unscheduled todo items</code></p>
<p>That response worked well, too. It does a decent job of explaining what each piece of the solution does.</p>
<h2 id="using-the-org-agenda">Using the org agenda</h2>
<p>Figuring out the org agenda has been key to how I use the tool.</p>
<p>With a good agenda setup I can feel pretty on top of things. When it&rsquo;s broken I know there are things out there in my file collection that I&rsquo;m not going to see. As I&rsquo;ve leaned into org capture, that&rsquo;s become even more true, because capture buffers keep you out of the file you&rsquo;re adding something to: You don&rsquo;t see the other things in there because you don&rsquo;t go past them to get to where you&rsquo;re adding new content.</p>
<p>Besides surfacing stuff, the agenda is also the nerve center. You can do basic scheduling and status changes from it, and maybe even more importantly for a sense of organizational calm, you can refile from it. So rather than visiting each file to find stuff and move it around, you can see it all from the agenda overview and refile it from there.</p>
<p>With a restored agenda, I made the connection between my literate Emacs config and all the other stuff flying around in my org mode ecosystem: Links I gathered about configuration tweaks or things I&rsquo;d like to try can more easily go into a literate config file, so I made an &ldquo;Ideas&rdquo; heading at the bottom of the file and started refiling my the Emacs-related things in my agenda&rsquo;s inbox into my <code>config.org</code> file.</p>
<p>People love hooking into org, too, so even things that started life without org mode in mind can pick up org affinities. The pinboard mode I adopted, for instance, doesn&rsquo;t natively use org&rsquo;s link storing function when copying a link, but someone wrote a function to do that.  Now I can retrieve a link and add it to a post without taking my hands off the keyboard or switching contexts.</p>
<h3 id="which-reminds-me-dot-dot-dot">Which reminds  me &hellip;</h3>
<p>I discovered <a href="https://www.gnu.org/software/emacs/manual/html_node/emacs/Window-Convenience.html">winner-mode</a> today.</p>
<p>It&rsquo;s annoying when an Emacs mode splits the window into frames, then leaves two frames behind when I quit it. <code>winner-mode</code> &ldquo;records the changes in the window configuration (i.e., how the frames are partitioned into windows), so that you can undo them.&rdquo; It&rsquo;s useful to me because I want to use <code>pinboard-mode</code> as a link retrieval tool for blogging. Once I&rsquo;ve grabbed the link, I just want to tap <code>q</code> and get back to my blog buffer, not find myself with a split window. <code>winner-mode</code> closes the pinboard buffer, then removes the frame, and I&rsquo;m back where I left off, able to add my link and keep typing.</p>
<h2 id="custom-doom-keybindings">Custom Doom keybindings</h2>
<p>I&rsquo;ve been digging Doom&rsquo;s modal interface, and waiting around for a reason to extend it. Yesterday&rsquo;s addition of <code>pinboard.el</code> finally gave me an excuse, since Doom was killing its keybindings out of the box.</p>
<p>The <code>p</code> prefix in Doom&rsquo;s menu system is already occupied by <code>projectile</code>, so I used <code>P</code>:</p>






<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-emacs-lisp" data-lang="emacs-lisp"><span class="line"><span class="cl"><span class="p">(</span><span class="nv">map!</span> <span class="nb">:leader</span>
</span></span><span class="line"><span class="cl">      <span class="p">(</span><span class="nb">:prefix-map</span> <span class="p">(</span><span class="s">&#34;P&#34;</span> <span class="o">.</span> <span class="s">&#34;Pinboard&#34;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="nb">:desc</span> <span class="s">&#34;open Pinboard&#34;</span> <span class="s">&#34;p&#34;</span> <span class="nf">#&#39;</span><span class="nv">pinboard</span>
</span></span><span class="line"><span class="cl">        <span class="nb">:desc</span> <span class="s">&#34;open current link&#34;</span> <span class="s">&#34;o&#34;</span> <span class="nf">#&#39;</span><span class="nv">pinboard-open</span>
</span></span><span class="line"><span class="cl">        <span class="nb">:desc</span> <span class="s">&#34;copy org link&#34;</span> <span class="s">&#34;l&#34;</span> <span class="nf">#&#39;</span><span class="nv">org-store-link</span>
</span></span><span class="line"><span class="cl">        <span class="nb">:desc</span> <span class="s">&#34;edit link&#34;</span> <span class="s">&#34;e&#34;</span> <span class="nf">#&#39;</span><span class="nv">pinboard-edit</span>
</span></span><span class="line"><span class="cl">        <span class="nb">:desc</span> <span class="s">&#34;copy URL&#34;</span> <span class="s">&#34;c&#34;</span> <span class="nf">#&#39;</span><span class="nv">pinboard-kill-url</span>
</span></span><span class="line"><span class="cl">        <span class="p">)))</span></span></span></code></pre></div>
<p>So <code>spc Pp</code> will open the pinboard buffer (or switch to it), <code>spc Po</code> will open a given link, <code>spc Pl</code> will store an org link (for retrieval via <code>spc mll</code>), etc. etc.</p>
<p>One thing I&rsquo;m struggling with here is a vagary of Doom as an environment. The logical place for all of that is in the <code>bindings.el</code> file, but the bindings don&rsquo;t &ldquo;take&rdquo; when I put them there.  They do when I put them in <code>config.el</code>. The docs weren&rsquo;t super helpful in debugging that, and the things that look syntactically intuitive didn&rsquo;t seem to solve the problem.</p>
<p>It&rsquo;s no big deal, and I&rsquo;d rather just have all of that stuff travel together with the mode it addresses, anyhow, but it&rsquo;s a thing I Do Not Understand About the Environment except at a very vague &ldquo;well, there&rsquo;s a lot of lazy loading going on to keep things fast&rdquo; level, and it&rsquo;s going to bother me.</p>
<p>I should just add an <code>INSOMNIA</code> state to my TODO lists and save it for the next &ldquo;welp, it&rsquo;s 3 a.m. and I might as well screw around with this problem&rdquo; session.</p>
<h2 id="yellowjackets-again">Yellowjackets again</h2>
<p>Well, we finished the first season last night.</p>
<ul>
<li><strong>Standalone season</strong> score: 8</li>
<li><strong>Prospects for the future</strong> score: 5</li>
</ul>
<p>Basically, my &ldquo;endless puzzlebox&rdquo; antennae are quivering.</p>
<p>The season all on its own was gripping and kept our interest. I felt invested in the characters and whatever they were dealing with. I love the way it walks right up to the <em><a href="https://www.imdb.com/title/tt6998518/">Mandy</a></em> line a few times. It has a dark sense of humor but it&rsquo;s not mean.</p>
<p>The 2 missing points for the standalone season score are because it had some minor pacing/bog-down stuff in the middle, and because some stuff going on just felt like gratuitous puzzlebox misdirection. It felt at times like it was written too self-consciously aware of recap culture and a certain kind of mock-obsessive over-read/over-think that comes along with that.</p>
<p>The &ldquo;prospects for the future&rdquo; score is a function of how I felt as the credits rolled on the season ender, and it honestly wasn&rsquo;t great. The episode didn&rsquo;t feel energetic, it suggested an appetite for &ldquo;surprise reversal&rdquo; that will exceed my patience over the long haul, and it reminded a bit too much of the first couple of seasons of HBO&rsquo;s <em><a href="https://www.imdb.com/title/tt8068860/">Servant</a></em>, which I abandoned with no remorse at the end of the second season.</p>
<p>I feel a little bad about my reaction, because maybe I&rsquo;m suggesting that television productions should simply abandon the only tools they have to get more seasons. In some ways, they <em>have</em> to pander to recap culture. They <em>have</em> to pander to fannish over-analysis. They <em>have</em> to end each season with a hook and a sense of incompleteness. They <em>have</em> to live within a fickle system run by people addicted to the analytics streaming affords, who will happily kill a property and move on to the next with no sense of investment.</p>
<p>But, you know, don&rsquo;t point out a problem without pointing out a solution:</p>
<p><em>For All Mankind</em> (Al prefers to think of it as <em>Space is Trying to Murder You Again This Week</em>) does a nice job with this conundrum: Each season has an arc and a sense of conclusion. There&rsquo;s payoff. Then it does an end-credits thing where it flash-forwards to the next season&rsquo;s era and offers you a look. It doesn&rsquo;t appeal to your thwarted expectations of closure, it appeals to your curiosity.</p>
<p>And to make note of a counterpoint, <em>Succession</em> isn&rsquo;t above leaving things on a hanging note of tension, but I&rsquo;ve stuck with it. It&rsquo;s not terrible to leave things unresolved, or end a season with a directional cue in the form of an unfinished arc. Maybe the thing I&rsquo;m reacting to with the puzzlebox stuff is the garish palette those shows paint with, swinging for the meme fences.</p>
<p>Anyhow, we have a few episodes of <em>Yellowjackets</em> season 2 cued up. The prospect of watching them, having skimmed a few episode descriptions in Plex, is not sparking a &ldquo;full-body yes.&rdquo; There&rsquo;s just so much other stuff out there that I&rsquo;m okay with the thought of letting it have its run then deciding whether it&rsquo;s worth it to watch through the whole thing.</p>
]]></content:encoded>
    </item>
    <item>
      <title>Writing elisp, Puppet code, and Ruby with ChatGPT.</title>
      <link>https://mike.puddingtime.org/posts/2023-04-10-elisp-puppet-ruby-chatgpt/</link>
      <pubDate>Mon, 10 Apr 2023 09:36:26 -0700</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-04-10-elisp-puppet-ruby-chatgpt/</guid>
      <description>I finally took the time to play with ChatGPT to configure Emacs and write some Ruby.</description>
      <content:encoded><![CDATA[<p>I finally got curious enough, and had rendered a particular Google account unimportant enough, to give ChatGPT a try. I&rsquo;ll leave out the obvious goofs &ndash; asking it to deliver the Gettysburg Address in the style of Jeff Lebowski &ndash; and write up a few slightly more complex requests. Trying to get Eliza to say swears in eighth grade got boring fast, so nothing I asked it to do was borne out of a spirit of malice toward it. Just curiosity.</p>
<p>Overall, it was a land of contrasts. It did some things really well, or got to &ldquo;really well&rdquo; with a few followup requests. But on the other end of the spectrum it simply invented non-existent functionality then documented how to configure it.</p>
<p>I don&rsquo;t have any particularly original takeaways. Put me in the broad camp of &ldquo;human venality is going to be the real problem here,&rdquo; in ways it already is where other kinds of automation are concerned. We live in a society where people not only, like, read a newspaper in their Tesla, but literally crawl into the back seat and take naps.</p>
<p>The trivial tasks I fed it were limited, so the errors it made were obvious.  I wasn&rsquo;t trying to prove or disprove its &hellip; quality?  If you&rsquo;ve ever gotten into an argument with a word processor&rsquo;s grammar checker you&rsquo;ll sort of understand what you&rsquo;re up against in this case, too, with the improvement over that scenario being that instead of staring at the alleged bad grammar and ultimately learning you&rsquo;re either a &ldquo;leave the blue squiggles&rdquo; person or a &ldquo;can&rsquo;t tolerate any blue squiggles&rdquo; person, you can tell it you didn&rsquo;t care for the answer and it often takes the hint and fixes the problem.</p>
<p>But you have to know that you don&rsquo;t like the answer. So when it wrote a Puppet module for me and did so with insecure code, I noticed that and told it to do better and it did. Nothing got into production. When it gave me unreadable output for a train schedule, its first correction was at least obviously and intuitively wrong. Nothing got into production.</p>
<p>When I think about more complex code I&rsquo;ve written the human dimension of the problem stands out more. I once modeled website revenue for a Rails app, which involved a lot of sorting out when data was sampled vs. when it wasn&rsquo;t, recursive reasoning around costs, etc. and remember the many ways I could lose my train of thought and introduce stuff that looked right even to my experienced eye as a domain expert who knew the problem space as a practitioner <em>and</em> who was describing that expertise in code. No misunderstood requirements, no senior dev fighting with the product owner because reality is stupid, no UX designer arguing that beauty is truth. Just me, passionately invested in the problem, and still introducing errors I couldn&rsquo;t spot on review &hellip; that I could only spot with tedious testing.</p>
<p>Anyhow. Nothing new.</p>
<p>Some of the things I tried:</p>
<h3 id="create-an-org-capture-template-for-daily-health-logging">Create an org capture template for daily health logging</h3>
<p>It did the request perfectly, but slightly idiosyncratically for a log format (it stuck the date in the :DRAWER: instead of as an inactive date label in the head). Subsequent conversational-style prompts (&ldquo;okay, but could you include weight and hours slept?&rdquo;) caused it to add prompts for those to the template, then &ldquo;could you make that information that appends to an org table instead&rdquo; generated a capture template appropriate to appending to a table.</p>
<p>A similar request to create an org-capture template for Hugo blogging was mostly correct, but had a few glitches and the verbose instructions left out a key variable. It was debuggable in a few minutes.</p>
<p>I&rsquo;d score it pretty highly, and using it for that task is just straightforward &ldquo;get to the point of the tool, not the labor involved in the tool&rdquo; utility. Mostly I appreciated that it matched all the parens correctly.</p>
<h3 id="tell-me-how-to-configure-offlineimap-for-use-with-mutt-on-a-mac">Tell me how to configure OfflineIMAP for use with mutt on a Mac</h3>
<p>Did I say yesterday I don&rsquo;t believe in that? I did. But it was on my mind.</p>
<p>It did this pretty well, delivering instructions tailored to the specific &ldquo;mutt + offlineimap&rdquo; use case that were as good as any tutorial, missing only the things that are idiosyncratic to Fastmail, which I forgot to mention to it. I should have thought to tell it I was getting the errors I got to see how it handled that. Instead I just searched for them on DuckDuckGo and got unstuck.</p>
<p>Interestingly, and this happened one other time, I lost the original request to a glitch in the web app. When I restated it only slightly differently &hellip; not in a way that you&rsquo;d think would materially affect the output &hellip; it came up with something slightly different that didn&rsquo;t leave out a key detail the original output did.</p>
<p>I&rsquo;d score it highly again, minus maybe its willingness to make message deletion live by default without warning. Other examples and tutorials I found mention that.</p>
<p>I followed up by asking it to show me how to capture that configuration with Puppet and hiera, and it produced a serviceable OfflineIMAP module. It would have had me storing my credentials in the plain in the Hiera YAML. I responded that I preferred not to do that so it provided me with an example that used eyaml.</p>
<h3 id="tell-me-how-to-use-mutt-with-a-bayesian-filter">Tell me how to use mutt with a Bayesian filter</h3>
<p>It went completely off the rails, inventing filtering functionality for mutt and offering configuration examples that looked &ndash; mutt-like? &ndash; but inventing a configuration variable that doesn&rsquo;t exist, near as I can tell, to invoke a configuration file mutt wouldn&rsquo;t look for to support the non-existent functionality.</p>
<p>Maybe the interesting thing that came out of the interaction was the way it cooked up a mutt-like filtering setup could work in a way that seemed idiomatically correct for mutt. It just did the technical equivalent of adding a sixth finger to the left hand by assuming a generic bayesian filter of <em>some kind</em> and taking the plumbing to connect it for granted.</p>
<h3 id="how-would-i-go-about-adding-a-second-rss-feed-with-a-different-template-for-a-hugo-site">How would I go about adding a second RSS feed with a different template for a hugo site?</h3>
<p>Another miss, with very reasonable-looking instructions that simply didn&rsquo;t work as proposed. I am not sure how close it actually got. That&rsquo;s a problem I spent some time trying to solve yesterday and it seemed close but missed some connections between content and template.</p>
<p>It gave its configuration examples in TOML, and responded correctly to a conversational &ldquo;could I have those examples in YAML&rdquo; prompt.</p>
<h3 id="tell-me-how-to-write-a-sinatra-app-to-download-an-rss-feed-filter-it-for-keywords-and-save-another-version-of-the-feed">Tell me how to write a Sinatra app to download an rss feed, filter it for keywords and save another version of the feed</h3>
<p>Prompted by a Mastodon conversation yesterday about RSS readers that could be used to filter sponsored content posts.</p>
<p>Up front, it&rsquo;s sort of a weird request on my part: I was just lazily typing in part of an idea, including Sinatra as a dependency but not explaining why (my idea would involve creating a sort of RSS proxy with dynamic filtering during each client request). I just wanted to see what it would do without putting a lot of thought into it, or sticking around to narrow things down. So I got a ruby script wrapped in a Sinatra route, honoring the request whether it made a ton of sense or not.</p>
<p>I&rsquo;ve had it do a couple of Ruby scripts, and it remembered to include `require` lines for gems. It didn&rsquo;t do that in this case. I added them and it ran. I had to tweak a few things to get it to run without error, and the filtering didn&rsquo;t work.</p>
<p>I might goof around with this one a bit more to see where it&rsquo;s going wrong.</p>
<p>This lined up with things I&rsquo;ve read from others over the past few months: It produced a scaffold of mostly working code. If I decide to mess around with it more, I&rsquo;ll have been saved digging around for examples of the basic syntax for the assorted parts of the workflow that I know from experience are correct.</p>
<h3 id="what-s-a-good-strategy-for-switching-between-regular-and-ortholinear-keyboards">&ldquo;What&rsquo;s a good strategy for switching between regular and ortholinear keyboards?&rdquo;</h3>
<p>Useless. It provided very reasonable instructions for how to learn how to use an ortholinear keyboard, but didn&rsquo;t address the actual request.</p>
<h3 id="tell-me-how-to-write-a-ruby-script-to-download-train-times-for-a-given-stop-in-portland-oregon">&ldquo;Tell me how to write a ruby script to download train times for a given stop in Portland oregon&rdquo;</h3>
<p>It produced working code that showed me the next arrival times for the next train at my neighborhood stop. It provided the correct link to sign up with TriMet to get an API key.</p>
<p>&ldquo;A-&rdquo; because it didn&rsquo;t translate epoch time to human time in the output. When I asked it to do that, it tried to comply and used the obvious syntax to convert the integer it got back from the API, but got confused by the millisecond format.</p>
<p>I tried the code and replied with:</p>
<p>&ldquo;That time format is still incorrect. I think the timestamps include miliseconds.&rdquo;</p>
<p>It replied with:</p>
<p>&ldquo;You&rsquo;re correct, I apologize for the oversight. It appears that the TriMet API returns timestamps with milliseconds.&rdquo;</p>
<p>Then it produced working code that did a simple operation on the timestamp and passed it along to <code>Time</code> and <code>strftime</code> with correctly formatted output.</p>
]]></content:encoded>
    </item>
    <item>
      <title>mutt to org-contacts</title>
      <link>https://mike.puddingtime.org/posts/2023-04-15-mutt-to-org-contacts/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><author>mike@puddingtime.org (mike)</author>
      <guid>https://mike.puddingtime.org/posts/2023-04-15-mutt-to-org-contacts/</guid>
      <description>A little script to copy address information from mutt messages into an org-contacts file.</description>
      <content:encoded><![CDATA[<p>Part of making the whole <a href="https://mike.puddingtime.org/posts/20230413-making-a-plaintext-personal-crm-with-org-contacts/">plaintext CRM</a>  thing work involves capture: Getting contact information into the database. I made a capture template for <a href="https://beorgapp.com/">beorg</a> to make it easier to capture a contact on mobile, but I have a bunch of recent email contacts I&rsquo;ve wanted to add, too, and no easy way to get them out of mutt.</p>
<p>For all of its talents, mutt doesn&rsquo;t choose to expose any message variables to its macro functionality. If you want to extract a sender&rsquo;s name or email address or whatever, the message has to be piped. I put something like that together to <a href="https://mike.puddingtime.org/posts/2023-04-09-macros-to-score-mail-in-mutt/">add senders to a mutt score file</a>, and there are a few other things out there in the mutt ecosystem, like lbdb, that capture email addresses. lbdb could have been great for this, but its whole point is capture to a database of its own.</p>
<p>I&rsquo;ve been poking around with getting ChatGPT to write little utilities for me, so I put this problem to it, asking for a Ruby script that could pipe a message through formail to extract the needed name and email address.</p>
<p>It took a second prompt &ndash; initially it just wrote the code to process the input without specifying the input &ndash; but it produced something workable to get the two pieces of data out, and I added an org-contacts template as a <code>HERE</code> doc the script writes into a <code>mutt_contacts.org</code> file. I could have sent it straight to <code>contacts.org</code> but prefer to automate into buffer files to keep the chance of conflicts, sync or otherwise, to a minimum.</p>
<p>The accompanying mutt macro looks like this:</p>
<p><code>macro index,pager .oc &quot;|~/.mutt/org_contact.rb\n&quot;</code></p>
<p>I tap <code>.oc</code> when positioned on a message and it pipes into the script.</p>
<p>I&rsquo;d like to extend the macro to include a quick note, but for now it just adds the <code>NOTES</code> todo state and schedules the entry a day out to remind me to put something in there soon: The new entries turn up in my org-mode agenda for processing and re-filing into my <code>contacts.org</code> file.</p>
<p>And it worked well enough: Once I set it up I was able to run through and add nine or ten new contacts in a few seconds, then visit them in org-mode and refile them all.</p>
<p>And yeah &hellip;still holding the line against adding an MUA to Emacs proper. I just don&rsquo;t want to do the whole OfflineIMAP thing or similar, and I am still keeping things relatively simple. Adding <code>org-caldav</code> today was a small step in the wrong direction, but I like having calendar entries in my org agenda, it syncs relatively quickly once it does the initial download, and it has no system dependencies.</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">#!/usr/bin/env ruby</span>
</span></span><span class="line"><span class="cl"><span class="nb">require</span> <span class="s1">&#39;open3&#39;</span>
</span></span><span class="line"><span class="cl"><span class="nb">require</span> <span class="s1">&#39;date&#39;</span>
</span></span><span class="line"><span class="cl"><span class="n">contacts_file</span> <span class="o">=</span> <span class="s2">&#34;~/org/mutt_contacts.org&#34;</span>
</span></span><span class="line"><span class="cl"><span class="n">message_contents</span> <span class="o">=</span> <span class="vg">$stdin</span><span class="o">.</span><span class="n">read</span>
</span></span><span class="line"><span class="cl"><span class="c1"># Define the command to extract headers with formail</span>
</span></span><span class="line"><span class="cl"><span class="n">command</span> <span class="o">=</span> <span class="s1">&#39;formail -X From: -X Sender: -X Reply-To: -x To: -x Cc: -x Bcc:&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Execute the command and capture the output</span>
</span></span><span class="line"><span class="cl"><span class="n">output</span><span class="p">,</span> <span class="n">status</span> <span class="o">=</span> <span class="no">Open3</span><span class="o">.</span><span class="n">capture2</span><span class="p">(</span><span class="n">command</span><span class="p">,</span> <span class="ss">stdin_data</span><span class="p">:</span> <span class="n">message_contents</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="n">status</span><span class="o">.</span><span class="n">success?</span>
</span></span><span class="line"><span class="cl">  <span class="n">email</span> <span class="o">=</span> <span class="kp">nil</span>
</span></span><span class="line"><span class="cl">  <span class="nb">name</span> <span class="o">=</span> <span class="kp">nil</span>
</span></span><span class="line"><span class="cl"><span class="k">end</span>
</span></span><span class="line"><span class="cl">  <span class="c1"># Parse the output and extract the email and name from the From, Sender, and Reply-To headers</span>
</span></span><span class="line"><span class="cl">  <span class="n">output</span><span class="o">.</span><span class="n">lines</span><span class="o">.</span><span class="n">each</span> <span class="k">do</span> <span class="o">|</span><span class="n">line</span><span class="o">|</span>
</span></span><span class="line"><span class="cl">    <span class="k">case</span> <span class="n">line</span>
</span></span><span class="line"><span class="cl">    <span class="k">when</span> <span class="sr">/^From:\s*(.*)$/i</span><span class="p">,</span> <span class="sr">/^Sender:\s*(.*)$/i</span><span class="p">,</span> <span class="sr">/^Reply-To:\s*(.*)$/i</span>
</span></span><span class="line"><span class="cl">      <span class="n">from</span> <span class="o">=</span> <span class="vg">$1</span><span class="o">.</span><span class="n">strip</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">      <span class="c1"># Extract the email and name from the From, Sender, or Reply-To header</span>
</span></span><span class="line"><span class="cl">      <span class="k">if</span> <span class="n">from</span> <span class="o">=~</span> <span class="sr">/(.+?)\s*&lt;(.+?)&gt;/</span>
</span></span><span class="line"><span class="cl">        <span class="n">email</span> <span class="o">=</span> <span class="vg">$2</span>
</span></span><span class="line"><span class="cl">        <span class="nb">name</span> <span class="o">=</span> <span class="vg">$1</span><span class="o">.</span><span class="n">strip</span>
</span></span><span class="line"><span class="cl">      <span class="k">else</span>
</span></span><span class="line"><span class="cl">        <span class="n">email</span> <span class="o">=</span> <span class="n">from</span>
</span></span><span class="line"><span class="cl">        <span class="nb">name</span> <span class="o">=</span> <span class="s2">&#34;No Name Found&#34;</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="c1"># Found the email and name, so break the loop</span>
</span></span><span class="line"><span class="cl">      <span class="k">break</span>
</span></span><span class="line"><span class="cl">    <span class="k">end</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">org_template</span> <span class="o">=</span> <span class="o">&lt;&lt;~</span><span class="no">TEMPLATE</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="o">**</span> <span class="no">NOTES</span> <span class="c1">#{name} :mutt:</span>
</span></span><span class="line"><span class="cl">  <span class="ss">SCHEDULED</span><span class="p">:</span> <span class="c1">#{(Date.today + 1).strftime(&#34;%Y-%m-%d&#34;)}</span>
</span></span><span class="line"><span class="cl">  <span class="ss">:PROPERTIES</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">  <span class="ss">:EMAIL</span><span class="p">:</span> <span class="c1">#{email}</span>
</span></span><span class="line"><span class="cl">  <span class="ss">:PHONE</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">  <span class="ss">:BIRTHDAY</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">  <span class="ss">:CONTACTED</span><span class="p">:</span> <span class="c1">#{Date.today.strftime(&#34;%Y-%m-%d&#34;)}</span>
</span></span><span class="line"><span class="cl">  <span class="ss">:END</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="no">TEMPLATE</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="no">File</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="n">contacts_file</span><span class="p">,</span> <span class="s2">&#34;a&#34;</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="n">f</span><span class="o">.</span><span class="n">write</span> <span class="n">org_template</span><span class="p">}</span></span></span></code></pre></div>
]]></content:encoded>
    </item>
  </channel>
</rss>
