{
  "feed_url": "https://micro.webology.dev/feed.json",
  "home_page_url": "https://micro.webology.dev/",
  "icon": "https://micro.webology.dev/avatar.jpg",
  "items": [
    {
      "content_html": "\u003cp\u003eI’ve been running a new remote development setup for the last month or so, and the goal is simple: move between all of my devices without losing my place.\u003c/p\u003e\n\u003cp\u003eThe way I think about it, I have three default states:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eAt my desk on my Mac Studio\u003c/li\u003e\n\u003cli\u003eHome or out somewhere with my laptop or an iPad and a portable keyboard\u003c/li\u003e\n\u003cli\u003eOnly my phone, at practice or running errands\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eI wanted a setup that works across all three without rebuilding anything when I switch. I’d rather grab my iPhone or iPad with a portable keyboard than lug a laptop everywhere. If I’m at one of my kids’ practices and want to quickly follow up on something or implement an idea, I always have my phone with me.\u003c/p\u003e\n\u003cp\u003eThe stack is basically:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://tailscale.com\"\u003eTailscale\u003c/a\u003e - glues all of my devices onto one secure network\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/tmux/tmux\"\u003etmux\u003c/a\u003e - keeps my dev environment alive so I can leave and come back without rebuilding\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://mosh.org\"\u003eMosh\u003c/a\u003e - keeps remote connections resilient across flaky WiFi and network changes\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://cmux.com\"\u003ecmux\u003c/a\u003e - Ghostty + Workspaces for macOS, the desktop side of this\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://getmoshi.app\"\u003eMoshi\u003c/a\u003e - the best iPhone and iPad shell I have found\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe first three are the foundation. They work the same no matter which device I’m sitting at. cmux is how I connect from a desktop or laptop, and Moshi is how I connect from my phone or iPad.\u003c/p\u003e\n\u003ch2 id=\"tailscale-ties-the-machines-together\"\u003eTailscale ties the machines together\u003c/h2\u003e\n\u003cp\u003eStart with Tailscale. I\u0026rsquo;ve used Tailscale for almost a decade because it\u0026rsquo;s free, has clients for everything like my phone, iPads, Macs, Linux boxes, and even routers and TVs. It\u0026rsquo;s a low-friction way to access all of your devices from anywhere securely and privately.\u003c/p\u003e\n\u003cp\u003eTailscale gives me a private network across my devices, so I can connect to my Mac Studio at the office, my Mac Mini at home, my MacBook Air, and Linux boxes without opening SSH to the public internet.\u003c/p\u003e\n\u003cp\u003eThat’s a big part of why I’m comfortable with this setup.\u003c/p\u003e\n\u003cp\u003eThese machines are not sitting there with public SSH ports open. They’re only reachable from my tailnet. Tailscale handles the secure network piece, and I don’t have to mess with WireGuard directly.\u003c/p\u003e\n\u003cp\u003eIt just works.\u003c/p\u003e\n\u003ch2 id=\"tmux-keeps-the-work-alive\"\u003etmux keeps the work alive\u003c/h2\u003e\n\u003cp\u003etmux is the core of the setup. I’ve been running it for the last couple of months because I wanted something I could reconnect to later, similar to screen, but better suited to the way I actually work.\u003c/p\u003e\n\u003cp\u003eA lot of the time, I have something running for work, a client, or one of my own projects. I might have Django in one pane, logs in another, and Claude Code or Codex running somewhere else. With tmux, I can leave that entire development environment in place and come back to it later. Being able to do that has been worth the switch on its own.\u003c/p\u003e\n\u003cp\u003eI\u0026rsquo;m probably not using 90% of what tmux was built for. Mostly I\u0026rsquo;m using it to create sessions, connect to them, and disconnect without losing my place. I can split panes and move between them when I need to, but I find myself doing that less and less. The persistence is the part that actually matters to me.\u003c/p\u003e\n\u003cp\u003eSome alternatives to tmux are \u003ca href=\"https://zellij.dev\"\u003eZellij\u003c/a\u003e and \u003ca href=\"https://herdr.dev\"\u003eHerdr\u003c/a\u003e. I attempted to use Zellij, but struggled with the basics, so I bailed and went back to tmux. I haven\u0026rsquo;t tried Herdr, but I\u0026rsquo;ve seen people talking about it and wanted to include it.\u003c/p\u003e\n\u003ch2 id=\"mosh-makes-remote-sessions-feel-less-fragile\"\u003eMosh makes remote sessions feel less fragile\u003c/h2\u003e\n\u003cp\u003eThe bigger improvement came when I added Mosh.\u003c/p\u003e\n\u003cp\u003eBefore I left for PyCon US, I decided I didn’t want to spend the week fighting flaky hotel, airport, and conference WiFi.\u003c/p\u003e\n\u003cp\u003eI remembered that Mosh solves a lot of the disconnect problems SSH has, so I installed it on my server, my work Mac Studio, my home Mac Mini, and my MacBook Air before I left (Homebrew on macOS, your package manager of choice on Linux).\u003c/p\u003e\n\u003cp\u003eI connected to a session before getting on the plane. About an hour into the flight, I opened my laptop, and the session resumed automatically. I didn’t have to rebuild anything or start over. It worked better than I thought it would.\u003c/p\u003e\n\u003cp\u003eMosh and tmux make a great pair. Mosh keeps the connection resilient, and tmux keeps the actual working state alive.\u003c/p\u003e\n\u003ch2 id=\"on-a-desktop-or-laptop-cmux-ties-it-together\"\u003eOn a desktop or laptop, cmux ties it together\u003c/h2\u003e\n\u003cp\u003eWhen I’m at a real keyboard, cmux is how I connect. It gives me Ghostty terminals and workspaces on macOS, which makes it easy to keep several machines and sessions organized at once.\u003c/p\u003e\n\u003cp\u003eWhere cmux really earns its place is how it handles agents and shared sessions. One workflow I’ve come to rely on: I’ll start a tmux session on a remote machine, then connect to it in a second terminal window in cmux. Then I’ll have Claude or Codex connect to that same machine and attach to the same tmux session to do the actual work, like setting up a new Linux box or installing packages.\u003c/p\u003e\n\u003cp\u003eThe nice part is that when Claude hits an interactive prompt, I can just take over the tmux session directly. I’m already attached. I can paste in API keys, answer prompts, or make changes that I wouldn’t want to hand off to an agent. Claude normally tries to handle those moments itself, and it doesn’t always do it well. This way I stay in control of the sensitive parts without losing the automation for everything else.\u003c/p\u003e\n\u003ch2 id=\"on-my-phone-or-ipad-moshi-is-the-missing-piece\"\u003eOn my phone or iPad, Moshi is the missing piece\u003c/h2\u003e\n\u003cp\u003eWhen I only have my phone or iPad with me, the part I was missing was a good way to connect to my remote sessions.\u003c/p\u003e\n\u003cp\u003eI had tried Termius before, and it was decent, but I kept running into small UI issues. CLI apps are not really designed for phones and tablets, so little things like getting to the right key at the right time can become annoying fast.\u003c/p\u003e\n\u003cp\u003eThen I tried \u003ca href=\"https://getmoshi.app\"\u003eMoshi\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eMoshi is an iOS and iPad app for remote terminal connections. It also runs on Apple Silicon Macs as an iPad app, which is a nice bonus.\u003c/p\u003e\n\u003cp\u003eMoshi has really good tmux support, and probably other multiplexers I haven’t tried yet. When I connect to a server that has tmux sessions running, Moshi prompts me with a list of those sessions before I even get to a shell. I don’t have to remember the command or go hunting around. I just pick the session and I’m back where I left off. That’s the feature that made the whole setup click.\u003c/p\u003e\n\u003cp\u003eMoshi also has a good mobile UI for this kind of work. I created a couple of shortcuts, one for space and one for enter, and that gets me through most of what I need when I’m using Claude Code or Codex from my phone.\u003c/p\u003e\n\u003cp\u003eCodex still has a few spots where it wants escape, and I haven’t fully figured that out yet. That may have been a connection issue, or it may be something I need to configure better.\u003c/p\u003e\n\u003cp\u003eBut for most of what I’m doing, it works shockingly well. I can open my phone, connect to an existing tmux session, check logs, nudge an agent, review what changed, or keep something moving without opening my laptop.\u003c/p\u003e\n\u003ch3 id=\"setup-was-easier-than-expected\"\u003eSetup was easier than expected\u003c/h3\u003e\n\u003cp\u003eMoshi also handles setup nicely.\u003c/p\u003e\n\u003cp\u003eWhen you connect to a server, it can show a QR code. You scan that from your phone, and it handles creating and copying the SSH key for you.\u003c/p\u003e\n\u003cp\u003eThat makes setup about as easy as I think it can be.\u003c/p\u003e\n\u003cp\u003eOn Apple devices, Moshi can also share connection settings across devices on the same Apple account. Once I had it set up, connecting from my iPad was painless. I hit the button, picked my session, and I was in.\u003c/p\u003e\n\u003cp\u003eThere is an Android version too. I haven’t tested it because I don’t have an Android device, but it’s there if you need it.\u003c/p\u003e\n\u003cp\u003eMoshi is a paid app, unlike the rest of this stack, which is free or open source. It runs around $30 a year or around $80 for lifetime access, which felt reasonable given how much I’m using it.\u003c/p\u003e\n\u003ch3 id=\"voice-input\"\u003eVoice input\u003c/h3\u003e\n\u003cp\u003eMoshi also supports voice input, which ended up being a bigger deal than I expected.\u003c/p\u003e\n\u003cp\u003eOn my Mac, I already use voice input a lot. I use tools like MacWhisper because voice to text has become a really good input method for me.\u003c/p\u003e\n\u003cp\u003eMoshi brings that same idea to my phone and iPad.\u003c/p\u003e\n\u003cp\u003eIt can use Apple’s voice to text, and it can also run a Whisper model. That means I can connect to a remote session from my phone and use voice input to interact with the tools I already have running.\u003c/p\u003e\n\u003cp\u003eClaude Code has voice support on the Mac, but that doesn’t really help when I’m remotely connected into another machine. Moshi having voice support built in makes the whole thing much more useful.\u003c/p\u003e\n\u003ch2 id=\"where-im-using-it\"\u003eWhere I’m using it\u003c/h2\u003e\n\u003cp\u003eSo far, I’ve been using this setup on Django TV, my job board, client work, and a bunch of one-off projects.\u003c/p\u003e\n\u003cp\u003eI have a Mac Studio at the office and a Mac Mini at home, and I’m constantly moving between them from my MacBook Air. I’ve also been playing with \u003ca href=\"https://direnv.net\"\u003edirenv\u003c/a\u003e so I can jump into a project and have the right environment load on the right machine. It’s not really part of this stack, but it pairs well with it.\u003c/p\u003e\n\u003cp\u003eThe split helps me keep things organized. Client work lives on the Mac Studio at the office. Side projects and personal work live on the Mac Mini at home. I can connect to whichever one I need without mixing everything together on my laptop. It also helps my MacBook Air battery, because the heavier work is happening somewhere else.\u003c/p\u003e\n\u003cp\u003eAnd because the sessions are always running, I don’t have to worry about rebooting my MacBook Air or losing a Claude Code or Codex session mid-task. If one machine is having a problem, I can exit and switch to the other one while everything I care about stays up and running.\u003c/p\u003e\n\u003cp\u003eReview has also gotten easier. I can pull up GitHub’s web interface or the GitHub desktop app from wherever I am and review pull requests without needing my full dev environment in front of me. The work is already staged. I just need a browser.\u003c/p\u003e\n\u003cp\u003eI can still work locally when I want to. There’s nothing wrong with that. But keeping these remote sessions open all the time has been a much better experience.\u003c/p\u003e\n\u003cp\u003eThe databases are already connected. The processes are already running. The agents are already in context. I can leave things in progress and come back later without rebuilding the whole setup.\u003c/p\u003e\n\u003ch2 id=\"the-glue-code\"\u003eThe glue code\u003c/h2\u003e\n\u003cp\u003eI\u0026rsquo;ve also been writing some shell aliases and scripts to smooth over the rough edges, because I don\u0026rsquo;t want to memorize tmux\u0026rsquo;s command flags.\u003c/p\u003e\n\u003cp\u003eI have a set of \u003ccode\u003etmux-*\u003c/code\u003e aliases that handle the things I actually do: create a new session, resume an existing one, and kill one when I\u0026rsquo;m done. That covers most of what I need without having to look anything up.\u003c/p\u003e\n\u003cp\u003eOn the cmux side, I\u0026rsquo;ve been experimenting with its CLI and API. I wrote \u003ca href=\"https://github.com/jefftriplett/dotfiles/blob/main/home/bin/cmux-dump\"\u003e\u003ccode\u003ecmux-dump\u003c/code\u003e\u003c/a\u003e and \u003ca href=\"https://github.com/jefftriplett/dotfiles/blob/main/home/bin/cmux-restore\"\u003e\u003ccode\u003ecmux-restore\u003c/code\u003e\u003c/a\u003e commands to save and reload workspace layouts. The idea is to build out profiles for each project so I can get everything running the way I want it with one command. That might mean starting a tmux session on a remote machine and connecting to it over Mosh, all from a single alias.\u003c/p\u003e\n\u003cp\u003eAll of this lives in my \u003ca href=\"https://github.com/jefftriplett/dotfiles\"\u003edotfiles repo\u003c/a\u003e and will keep changing as I figure out what actually works. I\u0026rsquo;m still early in this part of the setup.\u003c/p\u003e\n\u003ch2 id=\"when-and-why-you-need-each-tool\"\u003eWhen and why you need each tool\u003c/h2\u003e\n\u003cp\u003eYou don’t have to adopt all five of these at once. Each one solves a specific problem, and you can add them as you hit that problem.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eTailscale\u003c/strong\u003e is the one to start with if your machines aren’t already on a shared network. You need it the moment you want to reach a machine that isn’t sitting in front of you without exposing SSH to the public internet. If all of your work happens on one machine, you can skip it for now.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003etmux\u003c/strong\u003e is what you need when losing your terminal state hurts. If closing a laptop lid or dropping a connection means rebuilding your dev environment, restarting servers, or losing an agent session mid-task, tmux fixes that. It’s also the piece that lets two terminals, or you and an agent, share the same session.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eMosh\u003c/strong\u003e matters when your network is unreliable. Hotel WiFi, airports, conferences, tethering, or just moving between home and office. If you only ever connect over a stable wired network, plain SSH is fine. The moment you roam, Mosh is the difference between a session that survives and one you have to reconnect constantly.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003ecmux\u003c/strong\u003e is for the desktop side, when you’re juggling several machines and sessions and want them organized into workspaces instead of a pile of terminal windows. Any terminal works here, but cmux makes the multi-machine setup easier to live in.\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eMoshi\u003c/strong\u003e is for the phone and iPad side. You need it when you want to check on or nudge work from wherever you are. Its tmux session picker, key shortcuts, and voice input are what make a phone a usable terminal instead of a frustrating one.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eThe short version: Tailscale gets you to the machine, tmux keeps the work alive on it, Mosh keeps the connection from breaking, and cmux and Moshi are the front doors from a desk and from a phone.\u003c/p\u003e\n\u003ch2 id=\"this-is-not-about-working-all-the-time\"\u003eThis is not about working all the time\u003c/h2\u003e\n\u003cp\u003eThe real reason I like this setup is not because I want to maximize every spare minute of my life.\u003c/p\u003e\n\u003cp\u003eIt’s almost the opposite.\u003c/p\u003e\n\u003cp\u003eThis setup gives me more flexibility.\u003c/p\u003e\n\u003cp\u003eIf I have 15 minutes at my son’s track meets or baseball practice, I can pull out my phone and reconnect to something already in progress. If I’m waiting on slow tests, client feedback, or a deploy, I don’t have to sit glued to my desk.\u003c/p\u003e\n\u003cp\u003eI can make dinner. I can pack lunch. I can pick up one of my kids. I can run an errand.\u003c/p\u003e\n\u003cp\u003eThen, when something is ready, I can check in, make the next change, and keep moving.\u003c/p\u003e\n\u003cp\u003eIt makes the work less jarring. I don’t have to reset everything on my laptop just to make one small change or direct an agent for two minutes.\u003c/p\u003e\n\u003cp\u003eThe best part is that I can just close my laptop or walk away from my desk and know that my Claude and Codex sessions are going to keep running. When I come back, whether it’s on my phone or back at my desk, I can resume right where I left off without worrying about a disconnected session or a timed-out agent.\u003c/p\u003e\n\u003ch2 id=\"why-this-feels-different\"\u003eWhy this feels different\u003c/h2\u003e\n\u003cp\u003eThe built-in remote options from tools like Claude Code and Codex work sometimes, but I kept running into connection weirdness when one laptop was trying to coordinate across multiple machines.\u003c/p\u003e\n\u003cp\u003eWhat I wanted was something that didn’t require rebuilding context every time I moved. This stack gives me that. The connection doesn’t break. The session doesn’t disappear. The agents don’t lose their place.\u003c/p\u003e\n\u003cp\u003eThat’s a different kind of flexibility than I had before. It’s not about squeezing more work into more hours. It’s about not paying a tax every time I pick up where I left off.\u003c/p\u003e\n\u003cp\u003eThis is what’s working well for me right now, but I’m genuinely curious what you’re using. If you have a tool that replaces one of these or collapses a few layers into one, I want to hear about it. If you try any of this and it works for you, let me know. And if I’m holding one of these tools wrong and there’s a better way, I’m all ears for that too.\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eWritten by Jeff via a mix of voice transcription and typed notes. Edited with Claude Code.\u003c/p\u003e\n",
      "date_published": "2026-06-13T11:04:52-05:00",
      "id": "http://webology.micro.blog/2026/06/13/how-i-work-from-anywhere/",
      "summary": "A Dev Setup That Survives Airports, Flights, Road Trips, Walks, Errands, and Track Practice",
      "tags": [
        "Django",
        "LLM",
        "Today I Learned"
      ],
      "title": "How I Work From Anywhere Without Losing My Place",
      "url": "https://micro.webology.dev/2026/06/13/how-i-work-from-anywhere/"
    },
    {
      "content_html": "\u003cp\u003eThis week, I joined \u003ca href=\"https://wsvincent.com\"\u003eWill Vincent\u003c/a\u003e and \u003ca href=\"https://noumenal.es\"\u003eCarlton Gibson\u003c/a\u003e on the \u003ca href=\"https://djangochat.com\"\u003eDjango Chat\u003c/a\u003e podcast for \u003ca href=\"https://djangochat.com/episodes/djangocon-europe-recap-other-news-jeff-triplett\"\u003eDjangoCon Europe Recap + Other News\u003c/a\u003e. You can also watch it on \u003ca href=\"https://djangotv.com/videos/djangochat/2026/djangocon-europe-recap-other-news-jeff-triplett/\"\u003eDjangoTV via YouTube\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eOn this episode, we discussed \u003ca href=\"https://2026.djangocon.eu\"\u003eDjangoCon Europe\u003c/a\u003e, which Carlton had attended. We caught up on what\u0026rsquo;s going on with \u003ca href=\"https://django-news.com\"\u003eDjango News\u003c/a\u003e and the \u003ca href=\"https://www.djangoproject.com\"\u003eDjango Software Foundation\u003c/a\u003e. We also spent a good chunk of time on AI workflows and tooling. And I got to have a little soapbox rant at the end, which is always fun for me.\u003c/p\u003e\n\u003ch2 id=\"projects-i-recommended\"\u003eProjects I Recommended\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/pydantic/pydantic-ai\"\u003ePydantic AI\u003c/a\u003e is the Django ORM for accessing LLM providers\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/steipete/CodexBar\"\u003eCodexBar\u003c/a\u003e - If you are on a Mac, CodexBar will let you easily track and see your token usage across 20+ providers\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://ghostty.org\"\u003eGhostty\u003c/a\u003e - After almost two decades of using iTerm2, I switched.\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://cmux.com\"\u003ecmux\u003c/a\u003e - Built on Ghostty but a nice UX to switch between Agent sessions\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://goodsnooze.gumroad.com/l/macwhisper\"\u003eMacWhisper\u003c/a\u003e - Still my favorite voice to text Mac app\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"books-i-recommended\"\u003eBooks I Recommended\u003c/h2\u003e\n\u003cp\u003eAt the end of the episode, I recommended these two books:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.simonandschuster.co.uk/books/The-Greatest-Bedtime-Story-Ever/Jessie-Sima/9781665974523\"\u003eThe Greatest Bedtime Story Ever\u003c/a\u003e by Jessie Sima\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://us.macmillan.com/books/9780374619329/enshittification/\"\u003eEnshittification: Why Everything Suddenly Got Worse and What to Do About It\u003c/a\u003e by Cory Doctorow \u003cem\u003e(I recommended this one, but maybe not for the reasons you might think)\u003c/em\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"conclusion\"\u003eConclusion\u003c/h2\u003e\n\u003cp\u003eI\u0026rsquo;m always excited and honored to be invited on the show, and I always enjoy it. I hope it was a good listen, and I especially appreciated getting to step on the soapbox one more time at the end.\u003c/p\u003e\n",
      "date_published": "2026-04-30T13:10:04-05:00",
      "id": "http://webology.micro.blog/2026/04/30/djangochat-podcast-e/",
      "summary": "This week, I joined the Django Chat podcast episode discussing DjangoCon Europe, recent developments in Django, AI workflows, and shared recommendations for projects and books.",
      "tags": [
        "Django",
        "Python",
        "LLM",
        "Today I Learned"
      ],
      "title": "Django Chat Podcast: E201",
      "url": "https://micro.webology.dev/2026/04/30/djangochat-podcast-e/"
    },
    {
      "content_html": "\u003cp\u003eThis is my annual list of DjangoCon US talks I\u0026rsquo;d like to see. I have been doing this since 2015, and it\u0026rsquo;s one of my favorite traditions.\u003c/p\u003e\n\u003cp\u003e\u003ca href=\"https://2026.djangocon.us\"\u003eDjangoCon US 2026\u003c/a\u003e is in Chicago this year, August 24-28.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eThe \u003ca href=\"https://pretalx.com/djangocon-us-2026/cfp\"\u003eCFP\u003c/a\u003e is open. The deadline is March 23, 2026 at 11 AM CDT. Submit a talk!\u003c/strong\u003e\u003c/p\u003e\n\u003ch3 id=\"past-editions\"\u003ePast editions\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"/2024/04/28/djangocon-us-talks.html\"\u003e2024 Edition\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://jefftriplett.com/2023/djangocon-us-talks-i-d-like-to-see-2023-edition/\"\u003e2023 Edition\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://jefftriplett.com/2022/djangocon-us-talks-i-d-like-to-see-2022-edition/\"\u003e2022 Edition\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://jefftriplett.com/2018/djangocon-us-talks-i-d-like-to-see-2018-edition/\"\u003e2018 Edition\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://jefftriplett.com/2017/django-talks-id-like-to-see/\"\u003e2017 Edition\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://jefftriplett.com/2016/djangocon-us-talks-id-like-to-see/\"\u003e2016 Edition\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://gist.github.com/jefftriplett/cdda63bf42c592b1a6c8\"\u003e2015 Edition\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"drews-topics\"\u003eDrew\u0026rsquo;s Topics\u003c/h2\u003e\n\u003cp\u003e\u003ca href=\"https://winstel.dev\"\u003eDrew Winstel\u003c/a\u003e published a great list of \u003ca href=\"https://winstel.dev/2026/01/05/talk-ideas-for-dcus-26/\"\u003etalk ideas for DCUS \u0026lsquo;26\u003c/a\u003e with over 20 ideas. Here are some of my favorites from his list. Any of these would make good talk ideas, so check out Drew\u0026rsquo;s full list too.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eGPTs, LLMs, and AIs, oh my!\u003c/li\u003e\n\u003cli\u003eDeployment at any size\u003c/li\u003e\n\u003cli\u003eUnexpected use cases, especially ones that make the world better\u003c/li\u003e\n\u003cli\u003eClever hacks (such as Carlton Gibson\u0026rsquo;s single-file Django project)\u003c/li\u003e\n\u003cli\u003eUsing Django in machine learning projects\u003c/li\u003e\n\u003cli\u003eNew features in Django 6.x\u003c/li\u003e\n\u003cli\u003eDevelopment and testing techniques that help you build better code\u003c/li\u003e\n\u003cli\u003eConvincing product management that you don\u0026rsquo;t need a SPA or yet another mobile app\u003c/li\u003e\n\u003cli\u003ePersonal growth: how the community helped you in some way and you\u0026rsquo;d like to pay it forward\u003c/li\u003e\n\u003cli\u003eAdapting communities to changes in life\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"my-topics\"\u003eMy Topics\u003c/h2\u003e\n\u003cp\u003eHere are some topics that I\u0026rsquo;d personally like to see this year.\u003c/p\u003e\n\u003ch3 id=\"whats-coming-in-python-and-django\"\u003eWhat\u0026rsquo;s coming in Python and Django\u003c/h3\u003e\n\u003cp\u003eWith some big shifts coming in Python 3.15 and 3.16, it would be really interesting to see more about what Django developers would benefit from knowing about what\u0026rsquo;s coming up. Something a little more core to Python would be interesting.\u003c/p\u003e\n\u003cp\u003eI\u0026rsquo;d also love to see more Django talks, whether it\u0026rsquo;s from the Steering Council or anybody working on features for the Django 7 series. What\u0026rsquo;s coming? What are the big features being tackled?\u003c/p\u003e\n\u003ch3 id=\"djangos-deployment-story\"\u003eDjango\u0026rsquo;s deployment story\u003c/h3\u003e\n\u003cp\u003eLast year I was on a panel called \u003ca href=\"https://djangotv.com/videos/djangocon-us/2025/panel-discussion-two-decades-of-django-the-past-present-and-future-with-velda-kiara/\"\u003eTwo Decades of Django: The Past, Present, and Future\u003c/a\u003e. During that panel, I challenged people to really look into Django\u0026rsquo;s deployment story and find ways to improve it. If we can remove one or two steps along the way, we can make the deployment story better.\u003c/p\u003e\n\u003cp\u003eA couple of projects came out of that conversation that I really liked, including \u003ca href=\"https://github.com/nanorepublica/django-prodserver\"\u003eDjango Prod Server\u003c/a\u003e. Anything that makes deployments better and reduces the number of steps is worth exploring. If anybody has topics around improving Django\u0026rsquo;s deployment experience, that would be a great one to discuss.\u003c/p\u003e\n\u003ch3 id=\"rust-in-our-ecosystem\"\u003eRust in our ecosystem\u003c/h3\u003e\n\u003cp\u003eI\u0026rsquo;d like to hear more about Rust in our ecosystem. Tools like uv, Ruff, and Pydantic are all built with Rust. Pydantic led to Django Ninja and other applications built around it. Are you using Rust in your Django applications? Why? Where are you building with it? How is it improving your workflow? Is it for linters? Code formatters? Are you solving performance bottlenecks with Rust? What should Django learn from Rust? Which parts of Django would be better if rewritten in Rust? That story is really fascinating to me.\u003c/p\u003e\n\u003ch3 id=\"llms-and-django\"\u003eLLMs and Django\u003c/h3\u003e\n\u003cp\u003eI\u0026rsquo;d like to see more LLM talks about the amazing things people are building. This could be with Pydantic AI, creating model agents, or things you\u0026rsquo;re building that either run Django websites or help people do amazing things with agents. What does it look like to give a functional brain to a Django app? That would be an interesting talk idea.\u003c/p\u003e\n\u003ch3 id=\"agent-skills-and-productivity\"\u003eAgent skills and productivity\u003c/h3\u003e\n\u003cp\u003eI\u0026rsquo;d also like to hear about agent skills. How are you improving your productivity? How are you taking some of the drudge work out of working with Django? What skills do you use? What problems are you solving that a skill helps you with? What should Django learn from LLMs, skills, and agents? That would be another interesting topic.\u003c/p\u003e\n\u003ch3 id=\"real-talk-about-llms-and-team-productivity\"\u003eReal talk about LLMs and team productivity\u003c/h3\u003e\n\u003cp\u003eThere are a lot of talks about the negative things about LLMs and AI, and I think that is respectable and understandable. But it has become taboo for some weird reason that people who use LLMs every day aren\u0026rsquo;t speaking out about it and aren\u0026rsquo;t talking about the productivity gains they get. Especially if you\u0026rsquo;re on a small team doing a lot of stuff.\u003c/p\u003e\n\u003cp\u003eIf you\u0026rsquo;re working with a bigger team and everybody\u0026rsquo;s using these tools, how are you managing it? How are you getting through pull review processes? How are you making your code better? What\u0026rsquo;s working? What didn\u0026rsquo;t work? What\u0026rsquo;s scaled up for you?\u003c/p\u003e\n\u003cp\u003eEverything is changing in our industry whether we like it or not. Agents are here. The companies as of today are not going anywhere and the bubble hasn\u0026rsquo;t burst. I\u0026rsquo;m really curious about team productivity. What do you like? What don\u0026rsquo;t you like?\u003c/p\u003e\n\u003ch3 id=\"defending-and-embracing-llm-traffic\"\u003eDefending and embracing LLM traffic\u003c/h3\u003e\n\u003cp\u003eOn the flip side with LLMs, so many things have changed in the last year that we have to be a little more defensive with our websites, whether that\u0026rsquo;s using CDNs like Cloudflare or Fastly. I\u0026rsquo;m really interested in what people are doing to scale their servers now with LLMs in mind.\u003c/p\u003e\n\u003cp\u003eSome people may or may not want to make their websites more LLM friendly. There are definitely advantages and disadvantages to doing that. Writing a website to be consumed by LLMs is an interesting topic, both defensively and in terms of how you take advantage of it.\u003c/p\u003e\n\u003ch2 id=\"submit-a-talk\"\u003eSubmit a talk\u003c/h2\u003e\n\u003cp\u003eYou can always go back to my \u003ca href=\"/2024/04/28/djangocon-us-talks.html\"\u003e2024 list\u003c/a\u003e and of course there\u0026rsquo;s \u003ca href=\"https://winstel.dev/2026/01/05/talk-ideas-for-dcus-26/\"\u003eDrew\u0026rsquo;s list\u003c/a\u003e too. Some of the best topics that will be submitted will be things that don\u0026rsquo;t fit either of our lists. The whole idea is just to give people a starting point for things we\u0026rsquo;d both personally like to see, but that shouldn\u0026rsquo;t limit your imagination.\u003c/p\u003e\n\u003cp\u003eOutside opinions are great. Not everything needs to be about Django. We always get a bunch of community talks and talks that don\u0026rsquo;t have to be about the tech. But I think it\u0026rsquo;s an exciting year to really dig deeper into some of the tech because so much is changing on a weekly basis.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003e\u003ca href=\"https://pretalx.com/djangocon-us-2026/cfp\"\u003eSubmit your talk for DjangoCon US 2026!\u003c/a\u003e\u003c/strong\u003e\u003c/p\u003e\n",
      "date_published": "2026-03-19T15:54:26-05:00",
      "id": "http://webology.micro.blog/2026/03/19/djangocon-us-talks-id-like/",
      "tags": [
        "Django",
        "Python"
      ],
      "title": "DjangoCon US Talks I'd Like to See 2026 Edition",
      "url": "https://micro.webology.dev/2026/03/19/djangocon-us-talks-id-like/"
    },
    {
      "content_html": "\u003cp\u003eI first got exposed to \u003ca href=\"https://github.com/westerveltco/django-simple-nav\"\u003edjango-simple-nav\u003c/a\u003e while working with \u003ca href=\"https://github.com/joshuadavidthomas\"\u003eJosh Thomas\u003c/a\u003e at \u003ca href=\"https://github.com/westerveltco\"\u003ethe Westervelt Company\u003c/a\u003e over the last two or three years. It quickly became a go-to library in my toolkit. django-simple-nav lets you define nav items and groupings in Python, then hand them off to a Django template to render. I use it for sidebars, headers, dashboards, and other spots where I need a menu.\u003c/p\u003e\n\u003cp\u003eSince then, I have also started using it on a lot of personal projects. It has been a great fit every time.\u003c/p\u003e\n\u003ch2 id=\"defining-nav-items-once-and-reusing-them-everywhere\"\u003eDefining nav items once and reusing them everywhere\u003c/h2\u003e\n\u003cp\u003eRecently I wanted to reuse parts of a menu nav without having to update a bunch of different files. I had a dashboard with a sidebar full of links, and I also wanted a command palette that could search across all those same options when you hit Command-K from any page. django-simple-nav was a natural fit because you define your items once in Python and render them with whatever template you want.\u003c/p\u003e\n\u003cp\u003eHere is an example of what that looks like in Python:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-python\" data-lang=\"python\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003efrom\u003c/span\u003e django_simple_nav.nav \u003cspan style=\"color:#f92672\"\u003eimport\u003c/span\u003e Nav\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003efrom\u003c/span\u003e django_simple_nav.nav \u003cspan style=\"color:#f92672\"\u003eimport\u003c/span\u003e NavGroup\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003efrom\u003c/span\u003e django_simple_nav.nav \u003cspan style=\"color:#f92672\"\u003eimport\u003c/span\u003e NavItem\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eNAV_ITEMS \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e [\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    NavItem(title\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;Home\u0026#34;\u003c/span\u003e, url\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;home\u0026#34;\u003c/span\u003e),\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    NavItem(title\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;Dashboard\u0026#34;\u003c/span\u003e, url\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;dashboard\u0026#34;\u003c/span\u003e),\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    NavGroup(\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        title\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;Admin \u0026amp; Tools\u0026#34;\u003c/span\u003e,\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        items\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e[\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e            NavItem(title\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;Admin\u0026#34;\u003c/span\u003e, url\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;admin:index\u0026#34;\u003c/span\u003e, permissions\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e[\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;is_staff\u0026#34;\u003c/span\u003e]),\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        ],\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    ),\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    NavItem(title\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;Login\u0026#34;\u003c/span\u003e, url\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;login\u0026#34;\u003c/span\u003e),\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    NavItem(title\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;Logout\u0026#34;\u003c/span\u003e, url\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;logout\u0026#34;\u003c/span\u003e),\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003eclass\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eDashboardNav\u003c/span\u003e(Nav):\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    template_name \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;nav/dashboard.html\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    items \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e NAV_ITEMS\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#66d9ef\"\u003eclass\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eCommandPaletteNav\u003c/span\u003e(Nav):\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    template_name \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;nav/command_palette.html\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    items \u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e NAV_ITEMS\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"flexible-urls-and-named-routes\"\u003eFlexible URLs and named routes\u003c/h2\u003e\n\u003cp\u003eA few things to notice here. When you create a nav item and you have a URL, you can either use the URL\u0026rsquo;s name or you can give it the path to it and it will figure out what it is. So if I want a nav item for the Django admin, I can use \u003ccode\u003e\u0026quot;admin:index\u0026quot;\u003c/code\u003e as the URL.\u003c/p\u003e\n\u003ch2 id=\"handling-permissions-without-template-logic\"\u003eHandling permissions without template logic\u003c/h2\u003e\n\u003cp\u003eAnother nice feature is the \u003ccode\u003epermissions\u003c/code\u003e parameter. The Admin link uses \u003ccode\u003epermissions=[\u0026quot;is_staff\u0026quot;]\u003c/code\u003e, which means it only shows up for staff users. You can use this to hide things based on whether someone is staff, a superuser, or has specific Django permissions. This makes it nice to keep all of your nav options in one place without having to write special conditional logic in your templates to show or hide items for different users.\u003c/p\u003e\n\u003ch2 id=\"rendering-a-dashboard-nav-with-django-templates\"\u003eRendering a dashboard nav with Django templates\u003c/h2\u003e\n\u003cp\u003eThe other thing to notice is the two Nav classes at the bottom: \u003ccode\u003eDashboardNav\u003c/code\u003e and \u003ccode\u003eCommandPaletteNav\u003c/code\u003e. They both use the same \u003ccode\u003eNAV_ITEMS\u003c/code\u003e list but point to different templates. This is where the reuse really shines.\u003c/p\u003e\n\u003cp\u003eHere is an example nav template at \u003ccode\u003etemplates/nav/dashboard.html\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-html\" data-lang=\"html\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u0026lt;\u003cspan style=\"color:#f92672\"\u003enav\u003c/span\u003e\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  {% for item in items %}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    {% if item.items %}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u0026lt;\u003cspan style=\"color:#f92672\"\u003espan\u003c/span\u003e\u0026gt;{{ item.title }}:\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        {% for subitem in item.items %}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e          \u0026lt;\u003cspan style=\"color:#f92672\"\u003ea\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003ehref\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;{{ subitem.url }}\u0026#34;\u003c/span\u003e\u003cspan style=\"color:#960050;background-color:#1e0010\"\u003e{%\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eif\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003esubitem\u003c/span\u003e\u003cspan style=\"color:#960050;background-color:#1e0010\"\u003e.\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003eactive\u003c/span\u003e \u003cspan style=\"color:#960050;background-color:#1e0010\"\u003e%}\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eclass\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;active\u0026#34;\u003c/span\u003e\u003cspan style=\"color:#960050;background-color:#1e0010\"\u003e{%\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eendif\u003c/span\u003e \u003cspan style=\"color:#960050;background-color:#1e0010\"\u003e%}\u003c/span\u003e\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e            {{ subitem.title }}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e          \u0026lt;/\u003cspan style=\"color:#f92672\"\u003ea\u003c/span\u003e\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        {% endfor %}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u0026lt;/\u003cspan style=\"color:#f92672\"\u003espan\u003c/span\u003e\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    {% else %}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u0026lt;\u003cspan style=\"color:#f92672\"\u003ea\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003ehref\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;{{ item.url }}\u0026#34;\u003c/span\u003e\u003cspan style=\"color:#960050;background-color:#1e0010\"\u003e{%\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eif\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eitem\u003c/span\u003e\u003cspan style=\"color:#960050;background-color:#1e0010\"\u003e.\u003c/span\u003e\u003cspan style=\"color:#a6e22e\"\u003eactive\u003c/span\u003e \u003cspan style=\"color:#960050;background-color:#1e0010\"\u003e%}\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eclass\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;active\u0026#34;\u003c/span\u003e\u003cspan style=\"color:#960050;background-color:#1e0010\"\u003e{%\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eendif\u003c/span\u003e \u003cspan style=\"color:#960050;background-color:#1e0010\"\u003e%}\u003c/span\u003e\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e        {{ item.title }}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e      \u0026lt;/\u003cspan style=\"color:#f92672\"\u003ea\u003c/span\u003e\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    {% endif %}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  {% endfor %}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u0026lt;/\u003cspan style=\"color:#f92672\"\u003enav\u003c/span\u003e\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eThen in your base template, you can render it with the template tag:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-html\" data-lang=\"html\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e{% load django_simple_nav %}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e{% django_simple_nav \u0026#34;myapp.nav.DashboardNav\u0026#34; %}\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"building-a-command-palette-from-the-same-nav-items\"\u003eBuilding a command palette from the same nav items\u003c/h2\u003e\n\u003cp\u003eBecause the \u003ccode\u003eCommandPaletteNav\u003c/code\u003e class uses the same \u003ccode\u003eNAV_ITEMS\u003c/code\u003e list but with a different template, we can render the same nav data as JSON for a command palette. Here is an example template at \u003ccode\u003etemplates/nav/command_palette.html\u003c/code\u003e:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-html\" data-lang=\"html\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e{% load django_simple_nav %}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u0026lt;\u003cspan style=\"color:#f92672\"\u003escript\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003etype\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;application/json\u0026#34;\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eid\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e=\u003c/span\u003e\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;command-palette-data\u0026#34;\u003c/span\u003e\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e[{\u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003efor\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eitem\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003ein\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eitems\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e}{\u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003eif\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eitem\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eitems\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e}{\u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003efor\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003esubitem\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003ein\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eitem\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eitems\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  {\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;title\u0026#34;\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e:\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;{{ subitem.title }}\u0026#34;\u003c/span\u003e, \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;url\u0026#34;\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e:\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;{{ subitem.url }}\u0026#34;\u003c/span\u003e, \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;group\u0026#34;\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e:\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;{{ item.title }}\u0026#34;\u003c/span\u003e}{\u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003eif\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003enot\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eforloop\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003elast\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eor\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003enot\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eforloop\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003eparentloop\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003elast\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e},{\u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eendif\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e}{\u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eendfor\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e}{\u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003eelse\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  {\u003cspan style=\"color:#e6db74\"\u003e\u0026#34;title\u0026#34;\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e:\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;{{ item.title }}\u0026#34;\u003c/span\u003e, \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;url\u0026#34;\u003c/span\u003e\u003cspan style=\"color:#f92672\"\u003e:\u003c/span\u003e \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;{{ item.url }}\u0026#34;\u003c/span\u003e}{\u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e \u003cspan style=\"color:#66d9ef\"\u003eif\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003enot\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eforloop\u003c/span\u003e.\u003cspan style=\"color:#a6e22e\"\u003elast\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e},{\u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eendif\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e}{\u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eendif\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e}{\u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e \u003cspan style=\"color:#a6e22e\"\u003eendfor\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e%\u003c/span\u003e}\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e]\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u0026lt;/\u003cspan style=\"color:#f92672\"\u003escript\u003c/span\u003e\u0026gt;\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eThis also lent itself well when I was trying to do something quickly with Claude. I don\u0026rsquo;t know how to build a command palette, but I was able to just have Claude create one. I asked it to use HTMX to keep everything pretty lightweight.\u003c/p\u003e\n\u003ch2 id=\"final-thoughts\"\u003eFinal thoughts\u003c/h2\u003e\n\u003cp\u003eAll in all, django-simple-nav is a nice library to have in your toolkit. I like using it for headers, menus, dashboard navigation links, and even footer text. If you need flexible, reusable navigation in Django, give it a look.\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eWritten by Jeff. Edited with \u003ca href=\"https://grammarly.com\"\u003eGrammarly\u003c/a\u003e and \u003ca href=\"https://claude.ai/code\"\u003eClaude Code\u003c/a\u003e.\u003c/p\u003e\n",
      "date_published": "2026-02-26T21:56:51-05:00",
      "id": "http://webology.micro.blog/2026/02/26/how-i-use-djangosimplenav-for/",
      "tags": [
        "Django",
        "Python"
      ],
      "title": "How I Use django-simple-nav for Dashboards, Command Palettes, and More",
      "url": "https://micro.webology.dev/2026/02/26/how-i-use-djangosimplenav-for/"
    },
    {
      "content_html": "\u003cp\u003eIf you use a Mac, you\u0026rsquo;ve probably noticed that the menu bar fills up with icons pretty quickly. \u003ca href=\"https://www.macbartender.com\"\u003eBartender\u003c/a\u003e and \u003ca href=\"https://github.com/jordanbaird/Ice\"\u003eIce\u003c/a\u003e (sadly, now an unfortunate name) are apps that let you manage and hide unwanted icons from your macOS menu bar so it stays clean and uncluttered.\u003c/p\u003e\n\u003cp\u003eAbout a year ago, I switched from Bartender to Ice, which just happens to be open source, because there was \u003ca href=\"/2024/06/04/bartender-mac-app.html\"\u003esome drama\u003c/a\u003e. Since then, I\u0026rsquo;ve been very happy with Ice.\u003c/p\u003e\n\u003cp\u003eA couple of months ago, I upgraded to macOS Tahoe, and my menu bar stopped working correctly. The icon colors were all this weird shade of blue, so I couldn\u0026rsquo;t customize anything. After months of trying to figure it out, I noticed that it had been a while since Ice released a new version. That\u0026rsquo;s how open source goes sometimes.\u003c/p\u003e\n\u003cp\u003eI was getting to the point of deciding whether to go back to Bartender or stick with Ice. Today, I noticed that there\u0026rsquo;s a Homebrew package for \u003ccode\u003ejordanbaird-ice@beta\u003c/code\u003e. I decided to give it a try, removed the old version, installed the beta, and to my surprise and delight, the problem was fixed.\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# remove the stable version\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ebrew remove jordanbaird-ice\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# install the beta\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ebrew install jordanbaird-ice@beta\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eI\u0026rsquo;m hoping there\u0026rsquo;s a more official release soon. The new Bartender looks good too, so if Ice doesn\u0026rsquo;t keep getting updated, I might switch back. If you\u0026rsquo;ve run into this same issue, give the beta a try and let me know how it goes. And if you know of any alternatives to Bartender and Ice, I\u0026rsquo;d love to hear about those too.\u003c/p\u003e\n",
      "date_published": "2026-02-19T09:00:00-05:00",
      "id": "http://webology.micro.blog/2026/02/19/jordan-bairds-ice-beta-fixed/",
      "summary": "Jordan Baird’s Ice is an open-source app that effectively manages macOS menu bar icons, and a recent beta version resolved a color issue after upgrading to macOS Tahoe.",
      "tags": [
        "Today I Learned"
      ],
      "title": "Jordan Baird's Ice beta fixed my macOS Tahoe menu bar issues",
      "url": "https://micro.webology.dev/2026/02/19/jordan-bairds-ice-beta-fixed/"
    },
    {
      "content_html": "\u003cp\u003eToday I learned about \u003ca href=\"https://github.com/jakehilborn/displayplacer\"\u003edisplayplacer\u003c/a\u003e - \u0026ldquo;macOS command line utility to configure multi-display resolutions and arrangements.\u0026rdquo;\u003c/p\u003e\n\u003cp\u003eIn December, I upgraded to MacOS Tahoe and picked up the TS4 dock for my work machine.\u003c/p\u003e\n\u003cp\u003eWhile my upgrade was painless, the biggest issue I\u0026rsquo;ve had is with my displays. Every time my displays go to sleep and then I come back from lunch or come back the next day to work, my orientation of my displays changes and it puts them in a random order.\u003c/p\u003e\n\u003cp\u003eMy displays should be arranged like this:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003e1\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003e2\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003e3\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003e4\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eBut after waking from sleep, they end up like this:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003e2\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003e1\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003e3\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e[\u003c/span\u003e4\u003cspan style=\"color:#f92672\"\u003e]\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eIt\u0026rsquo;s really annoying. It takes a minute to fix and it\u0026rsquo;s just frustrating.\u003c/p\u003e\n\u003cp\u003eI tried displayplacer today. I had Claude Code actually run the \u003ccode\u003edisplayplacer list\u003c/code\u003e command. It figured out which displays and which settings needed to be changed. I had it record that and then I tried it out a few times where I manually dragged my displays around, put them in the wrong order, then ran the command, and it just magically worked.\u003c/p\u003e\n\u003cp\u003eI saved the working configuration to a shell script:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e#!/usr/bin/env bash\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\u003cspan style=\"color:#75715e\"\u003e# Restore display layout: 4 monitors (2x 16\u0026#34; 1920x1080, 2x 73\u0026#34; 2048x1280)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003edisplayplacer \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;id:F4AB0D6C-8E85-4E84-B5AB-C5B388536E3D res:1920x1080 hz:60 color_depth:8 enabled:true scaling:off origin:(0,0) degree:0\u0026#34;\u003c/span\u003e \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;id:C9240C8E-A9D2-418A-89AC-28D3B5DEE5FC res:1920x1080 hz:60 color_depth:8 enabled:true scaling:off origin:(-1920,0) degree:0\u0026#34;\u003c/span\u003e \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;id:B43E3352-ACB7-4163-A25B-2DDAE0174571 res:2048x1280 hz:60 color_depth:8 enabled:true scaling:off origin:(0,-1280) degree:0\u0026#34;\u003c/span\u003e \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e  \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;id:B32F530C-62CF-4F0D-9997-80BF2B812AC8 res:2048x1280 hz:60 color_depth:8 enabled:true scaling:off origin:(-2048,-1280) degree:0\u0026#34;\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eI also tried setting it up as a Stream Deck key and for some reason I couldn\u0026rsquo;t get that to work. But it\u0026rsquo;s fine. I can run a shell script and that takes a lot less time to get it in the right order.\u003c/p\u003e\n",
      "date_published": "2026-02-18T17:54:47-05:00",
      "id": "http://webology.micro.blog/2026/02/18/my-displays-keep-rearranging-and/",
      "tags": [
        "Today I Learned"
      ],
      "title": "My displays keep rearranging and displayplacer fixed it",
      "url": "https://micro.webology.dev/2026/02/18/my-displays-keep-rearranging-and/"
    },
    {
      "content_html": "\u003cp\u003eMy friend \u003ca href=\"https://treyhunner.com\"\u003eTrey Hunner\u003c/a\u003e showed me the GLM set of models before Thanksgiving. While traveling to see family, I somehow messed up my Claude Code setup because of a wrapper I have with \u003ca href=\"https://mise.jdx.dev\"\u003emise-en-place\u003c/a\u003e. I couldn\u0026rsquo;t use it for a while, and that made me realize I really need a backup for Claude Code.\u003c/p\u003e\n\u003ch2 id=\"why-glm\"\u003eWhy GLM?\u003c/h2\u003e\n\u003cp\u003e\u003ca href=\"https://z.ai\"\u003eZ.AI\u003c/a\u003e\u0026rsquo;s GLM model is better than Gemini but not quite as good as Claude Code. It\u0026rsquo;s really fast (about twice as fast as Claude Code), seems like 90+ percent as good, and it\u0026rsquo;s really cheap. You can get an annual subscription for around $26-28 for the first year, and I\u0026rsquo;ve read online that it\u0026rsquo;s very hard to hit the limit even on the lowest tier subscription.\u003c/p\u003e\n\u003cp\u003eThis is a great option for folks who can\u0026rsquo;t quite justify the $100/mo Claude plan but occasionally hit limits on the $20/mo Claude plan. I actually subscribe to the $100/mo plan, but I ended up getting the GLM Pro Plan because I like the amount of usage it gives me. The plan I\u0026rsquo;m on has five times as much token usage as the base tier.\u003c/p\u003e\n\u003ch2 id=\"running-both-side-by-side\"\u003eRunning Both Side by Side\u003c/h2\u003e\n\u003cp\u003eThere\u0026rsquo;s a \u003ca href=\"https://github.com/JoeInnsp23/claude-glm-wrapper\"\u003ewrapper tool\u003c/a\u003e that lets you use Z.AI\u0026rsquo;s models as Claude Code\u0026rsquo;s backend, so you can run both Claude and Z.AI\u0026rsquo;s GLM in two different windows. Having a reasonable backup that I can switch between or run in parallel is nice.\u003c/p\u003e\n\u003cp\u003eI never find speed to be an issue with Claude Code, but I\u0026rsquo;m definitely a fan of having options.\u003c/p\u003e\n\u003ch2 id=\"api-access\"\u003eAPI Access\u003c/h2\u003e\n\u003cp\u003eClaude doesn\u0026rsquo;t include API key access without paying extra. GLM solves this problem by giving you a raw API for a set price per month. Their API is OpenAI compatible, so I can work on agentic scripts using Open Coder or other applications without paying extra for Anthropic tokens.\u003c/p\u003e\n\u003ch2 id=\"getting-started\"\u003eGetting Started\u003c/h2\u003e\n\u003cp\u003eTo get started, run:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ebunx claude-glm-installer\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eThis will give you bash aliases that let you run various GLM models while still letting Claude default to the Anthropic backend:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-bash\" data-lang=\"bash\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eccg              \u003cspan style=\"color:#75715e\"\u003e# Claude Code with GLM-4.6 (latest)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eccg45            \u003cspan style=\"color:#75715e\"\u003e# Claude Code with GLM-4.5\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eccf              \u003cspan style=\"color:#75715e\"\u003e# Claude Code with GLM-4.5-Air (faster)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecc               \u003cspan style=\"color:#75715e\"\u003e# Regular Claude Code\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eTrey also told me about \u003ca href=\"https://github.com/musistudio/claude-code-router\"\u003eclaude-code-router\u003c/a\u003e, which lets you change models on the fly without restarting Claude Code. This might work well if you want to switch between models mid-session.\u003c/p\u003e\n\u003cp\u003eIf you find yourself running out of Claude Code tokens a couple of times a week or even a couple of times a day, it might be worth checking out GLM as a backup or alternative.\u003c/p\u003e\n\u003cp\u003eIf you want to try out Z.AI\u0026rsquo;s GLM models, please use \u003ca href=\"https://z.ai/subscribe?ic=GLMN4NLXLV\"\u003emy invite link\u003c/a\u003e (affiliate) or feel free to use \u003ca href=\"https://z.ai/subscribe?utm_medium=edm\u0026amp;utm_content=blackfriday\u0026amp;_channel_track_key=PJg2GPj2\"\u003eTrey Hunner\u0026rsquo;s invite link\u003c/a\u003e (affiliate) instead.\u003c/p\u003e\n\u003ch2 id=\"resources\"\u003eResources\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003ca href=\"https://www.reddit.com/r/ClaudeCode/comments/1nv64g5/i_made_a_tool_to_use_zais_glm_models_with_claude/\"\u003eClaude GLM Installer tool on Reddit\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/JoeInnsp23/claude-glm-wrapper\"\u003eclaude-glm-wrapper on GitHub\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e\u003ca href=\"https://github.com/musistudio/claude-code-router\"\u003eclaude-code-router on GitHub\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003cp\u003eWritten by Jeff. Edited with \u003ca href=\"https://grammarly.com\"\u003eGrammarly\u003c/a\u003e and \u003ca href=\"https://claude.ai/code\"\u003eClaude Code\u003c/a\u003e.\u003c/p\u003e\n",
      "date_published": "2025-12-10T20:43:48-05:00",
      "id": "http://webology.micro.blog/2025/12/10/trying-out-glm-with-claude/",
      "tags": [
        "LLM",
        "Today I Learned"
      ],
      "title": "🤖 Trying Out GLM with Claude Code",
      "url": "https://micro.webology.dev/2025/12/10/trying-out-glm-with-claude/"
    },
    {
      "content_html": "\u003cp\u003eI\u0026rsquo;ve been fighting a runaway \u003ca href=\"https://openai.com\"\u003eOpenAI\u003c/a\u003e bill for the last few weeks. I was worried I was leaking one of my API keys in a non-obvious way, possibly in one of my public projects.\u003c/p\u003e\n\u003cp\u003eTwo weeks ago, I deleted all my keys and contacted OpenAI support. I created new keys for every project, making it easier to track usage and identify any leaks. I had already been doing this, but I was a bit lax on a few projects while migrating from \u003ca href=\"https://www.digitalocean.com\"\u003eDigital Ocean\u003c/a\u003e to \u003ca href=\"https://www.hetzner.com\"\u003eHetzner\u003c/a\u003e. More on that migration soon.\u003c/p\u003e\n\u003cp\u003eFast forward two weeks, and OpenAI notified me again that I hit my very low recharge threshold. With granular keys in place, it only took a minute to narrow down the culprit: my \u003ca href=\"https://djangotv.com\"\u003eDjangoTV.com\u003c/a\u003e project.\u003c/p\u003e\n\u003cp\u003eI use the \u003ca href=\"https://platform.openai.com/docs/api-reference/introduction\"\u003eOpenAI API\u003c/a\u003e to help parse presenter names and clean up titles whenever we add new videos. I had recently added \u003ca href=\"https://djangotv.com/videos/djangocon-us/2025/\"\u003eDjangoCon US\u003c/a\u003e videos and \u003ca href=\"https://djangotv.com/videos/wagtail-space/2025/\"\u003eWagtail Space\u003c/a\u003e videos during the last two weeks, both on the same day our LLM usage spiked.\u003c/p\u003e\n\u003cp\u003eI checked my \u003ca href=\"https://github.com/django-q2/django-q2\"\u003eDjango-Q2\u003c/a\u003e logs and noticed several tasks failing because they were timing out after 90 seconds. The task accepts a list of video IDs and loops through them, parsing each one using \u003ca href=\"https://ai.pydantic.dev\"\u003ePydantic AI\u003c/a\u003e and the OpenAI API. When I ran it from the command line, I never hit a timeout. But when I created a Django Admin Action to bulk process videos, I was trying to process them all in one call instead of fanning them out into individual tasks.\u003c/p\u003e\n\u003ch2 id=\"what-went-wrong\"\u003eWhat Went Wrong?\u003c/h2\u003e\n\u003cp\u003eI didn\u0026rsquo;t have just one bug - I had two, possibly three bugs that weren\u0026rsquo;t obvious at the time:\u003c/p\u003e\n\u003col\u003e\n\u003cli\u003e\u003cstrong\u003eTimeout issues\u003c/strong\u003e: Tasks were timing out after 90 seconds when processing large batches\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eBulk processing\u003c/strong\u003e: Processing all videos in one call instead of individual async tasks\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eInfinite retries\u003c/strong\u003e: I failed to set a maximum number of retry attempts. I assumed that not having a default meant there was a fixed number of retries, not infinite\u003c/li\u003e\n\u003c/ol\u003e\n\u003cp\u003eThat third bug was the killer. My job ran for over 24 hours, burning through over 32 million tokens in the process. In total, I spent over 62 million tokens in November before I found and fixed the issue. Thankfully, my out-of-pocket costs were more than reasonable.\u003c/p\u003e\n\u003ch2 id=\"what-changed\"\u003eWhat Changed?\u003c/h2\u003e\n\u003cp\u003eI could blame this on vibecoding since DjangoTV is \u0026gt;99% vibe coded, but the project was built using sensible defaults and this wasn\u0026rsquo;t obvious at the time.\u003c/p\u003e\n\u003cp\u003eHere\u0026rsquo;s what I changed:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eSet \u003ccode\u003emax_attempts\u003c/code\u003e to limit retries\u003c/li\u003e\n\u003cli\u003eKept my 90 second \u003ccode\u003etimeout\u003c/code\u003e\u003c/li\u003e\n\u003cli\u003eSpaced out \u003ccode\u003eretry\u003c/code\u003e attempts to a few minutes between tries\u003c/li\u003e\n\u003cli\u003eAdjusted my \u003ccode\u003eparse_presenters_with_ai\u003c/code\u003e and \u003ccode\u003eparse_titles_with_ai\u003c/code\u003e Django Admin Actions to queue up one \u003ccode\u003easync_task\u003c/code\u003e per Video instead of processing them all in one call\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eSometimes the most expensive bugs are the ones that combine multiple small issues into one perfect storm. Granular API keys for tracking, sensible retry limits, and proper task queuing are now non-negotiable in my projects.\u003c/p\u003e\n\u003cp\u003eComputers!\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eWritten by Jeff. Edited with \u003ca href=\"https://grammarly.com\"\u003eGrammarly\u003c/a\u003e and \u003ca href=\"https://claude.ai/code\"\u003eClaude Code\u003c/a\u003e.\u003c/p\u003e\n",
      "date_published": "2025-11-23T00:01:54-05:00",
      "id": "http://webology.micro.blog/2025/11/22/how-i-accidentally-spent-over/",
      "tags": [
        "Django",
        "LLM"
      ],
      "title": "🤖 How I Accidentally Spent Over 62 Million OpenAI Tokens",
      "url": "https://micro.webology.dev/2025/11/22/how-i-accidentally-spent-over/"
    },
    {
      "content_html": "\u003cp\u003eSo, picture this: you\u0026rsquo;re working at a walking desk, you\u0026rsquo;ve got a cool voice-to-text tool like \u003ca href=\"https://goodsnooze.gumroad.com/l/macwhisper\"\u003eMacWhisper\u003c/a\u003e running, and you want to control it all with just a couple of dedicated keys. That was the dream that led me to build what I now call my \u0026ldquo;Vibe Coding Keyboard.\u0026rdquo;\u003c/p\u003e\n\u003ch3 id=\"why-voice-control-in-the-first-place\"\u003eWhy Voice Control in the First Place?\u003c/h3\u003e\n\u003cp\u003eBefore I get into the keyboard itself, let me explain why I\u0026rsquo;ve gotten so into voice control. A considerable part of my day involves Slack and Discord conversations, and voice mode is high-speed for firing off replies. I also use it to drive Claude Code sessions and other workflows, and it\u0026rsquo;s just become second nature.\u003c/p\u003e\n\u003cp\u003eBut the real game changer is the walking desk. When you\u0026rsquo;re walking and working, typing gets awkward fast. Your arms are in weird positions, and trying to maintain your stride while reaching for your keys just looks clumsy. With voice mode, I can quickly dictate a response to an email or message, clean it up if needed, and keep moving. It\u0026rsquo;s way more natural than contorting myself to type while walking.\u003c/p\u003e\n\u003ch3 id=\"why-a-dedicated-keyboard\"\u003eWhy a Dedicated Keyboard?\u003c/h3\u003e\n\u003cp\u003eI already had an Apple Magic Keyboard that I loved. It\u0026rsquo;s sleek and all, but I kept running into a minor but annoying problem: I was running out of keys to assign to all my voice-control shortcuts. I tried using the function key as a makeshift \u0026ldquo;vibe\u0026rdquo; key, but it just wasn\u0026rsquo;t cutting it.\u003c/p\u003e\n\u003cp\u003eSo I went looking for the smallest possible external keyboard I could find. I wanted something that would just plug in like a regular HID keyboard, no extra drivers or fancy setup. I originally tried to find a two-key keyboard, but I couldn\u0026rsquo;t find any that were USB-C. So I went with the \u003ca href=\"https://www.amazon.com/dp/B0BW15CPTY\"\u003eBTXETUEL 4-Key Mechanical Keyboard\u003c/a\u003e instead, and it turned out to be perfect. Its small enough that it doesn\u0026rsquo;t take up much space, and having four keys actually gives me a bit more flexibility than I originally thought I needed.\u003c/p\u003e\n\u003cimg src=\"/uploads/2025/b388258f45.png\" alt=\"The BTXETUEL 4-Key Mechanical Keyboard vibing\"\u003e\n\u003ch3 id=\"setting-up-the-vibe-keys\"\u003eSetting Up the Vibe Keys\u003c/h3\u003e\n\u003cp\u003eHere\u0026rsquo;s how I configured it:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eKey 1:\u003c/strong\u003e My \u0026ldquo;vibe\u0026rdquo; key. This one toggles MacWhisper\u0026rsquo;s dictation mode on and off. I just tap it, and boom, I\u0026rsquo;m in voice mode.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eKey 2:\u003c/strong\u003e Enter key. Super handy for confirming commands or just hitting \u0026ldquo;enter\u0026rdquo; without reaching for my main keyboard.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eKey 3:\u003c/strong\u003e Backspace. Because voice-to-text sometimes needs a quick correction.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003e\u003cstrong\u003eKey 4:\u003c/strong\u003e Escape key. Just a nice little \u0026ldquo;get me out of here\u0026rdquo; button if I need to exit a mode or cancel something.\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eAnd because I wanted a bit of flair, each key has an LED that can change color. I made the vibe key cycle through a rainbow pattern, so it stands out and literally \u0026ldquo;vibes.\u0026rdquo;\u003c/p\u003e\n\u003ch3 id=\"the-fun-of-customization\"\u003eThe Fun of Customization\u003c/h3\u003e\n\u003cp\u003eThe best part is how customizable this little gadget is. I even 3D-printed some LEGO keycaps just for fun. It\u0026rsquo;s become a hobby project, and it has made voice coding even more enjoyable for me.\u003c/p\u003e\n\u003ch3 id=\"a-boost-to-productivity-and-fun\"\u003eA Boost to Productivity (and Fun)\u003c/h3\u003e\n\u003cp\u003eIn the end, it\u0026rsquo;s not something you absolutely need, but it\u0026rsquo;s been a surprisingly nice productivity boost. Plus, it\u0026rsquo;s just plain cool to have a dedicated vibe key that lights up in rainbow colors while you work. If you\u0026rsquo;re into voice mode coding or want a fun little side project, give something like this a try!\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eWritten by Jeff. Dictated via \u003ca href=\"https://chatgpt.com\"\u003eChatGPT 5.1\u003c/a\u003e. Edited with \u003ca href=\"https://grammarly.com\"\u003eGrammarly\u003c/a\u003e and \u003ca href=\"https://claude.ai/code\"\u003eClaude Code\u003c/a\u003e.\u003c/p\u003e\n",
      "date_published": "2025-11-19T19:37:48-05:00",
      "id": "http://webology.micro.blog/2025/11/19/the-vibe-coding-keyboard-how/",
      "summary": "Ever tried typing while walking on a treadmill desk? It’s awkward.\nSo I built myself a “Vibe Coding Keyboard” - a tiny 4-key mechanical keyboard dedicated to voice control. One key toggles MacWhisper dictation, and the others handle Enter/Backspace/Escape. The vibe key even cycles through rainbow colors because why not?\nTurns out it’s perfect for firing off quick Slack/Discord replies and driving Claude Code sessions while staying in motion. Voice mode + walking desk = surprisingly productive combo.\nIf you’re into voice coding or just want a fun side project, check out how I set it up 👇",
      "tags": [
        "LLM"
      ],
      "title": "The \"Vibe Coding Keyboard\" How I Made My Walk-and-Talk Setup Even More Awesome",
      "url": "https://micro.webology.dev/2025/11/19/the-vibe-coding-keyboard-how/"
    },
    {
      "content_html": "\u003cp\u003eI\u0026rsquo;m hosting office hours on the next two Fridays in November.\u003c/p\u003e\n\u003ch2 id=\"office-hours-schedule\"\u003eOffice Hours Schedule\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ca href=\"https://time.is/0230PM_14_November_2025_in_CT\"\u003eFriday, November 14, 2025, 2:30 pm to 4:30 pm CT\u003c/a\u003e\u003c/strong\u003e\n\u003cul\u003e\n\u003cli\u003eStarting at 2pm CT, I\u0026rsquo;ll be working on some community/open source projects if anyone wants to see Claude Code or Claude Code on the web in action\u003c/li\u003e\n\u003c/ul\u003e\n\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ca href=\"https://time.is/0230PM_21_November_2025_in_CT\"\u003eFriday, November 21, 2025, 2:30 pm to 4:30 pm CT\u003c/a\u003e\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e🦃 \u003cstrong\u003eFriday, November 28th - No office hours due to US Thanksgiving\u003c/strong\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"join-us\"\u003eJoin Us\u003c/h2\u003e\n\u003cp\u003eThese sessions are open to anyone, especially those working remotely who wants to connect with others. It\u0026rsquo;s a collaborative space for discussions, catch-ups, or just hanging out while you work.\u003c/p\u003e\n\u003cp\u003eWhile we have a bunch of Python and Django developers who regularly attend, anyone is welcome to join even if you don\u0026rsquo;t use either of these things.\u003c/p\u003e\n\u003cp\u003eWhether you\u0026rsquo;re a first-time attendee or a regular, you\u0026rsquo;re welcome to drop in anytime during the session. No need to stay for the full two hours, come and go as your schedule allows.\u003c/p\u003e\n\u003ch2 id=\"how-to-join\"\u003eHow to Join\u003c/h2\u003e\n\u003cp\u003eThe Zoom link is available in the gist from our previous sessions. Feel free to reach out if you need the details.\u003c/p\u003e\n\u003ch2 id=\"ℹ-meeting-guidelines\"\u003eℹ️ Meeting Guidelines\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e🔕 Please mute when someone else is talking 👈\u003c/li\u003e\n\u003cli\u003e👍 Be respectful to other people and mute when not talking\u003c/li\u003e\n\u003cli\u003e👍 Be mindful of the spirit of the \u003ca href=\"https://policies.python.org/python.org/code-of-conduct/\"\u003ePython Code of Conduct\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e👍 Be mindful and respectful of everyone\u0026rsquo;s time.\u003c/li\u003e\n\u003cli\u003e👍 Join because you want to work on something with a small group\u003c/li\u003e\n\u003cli\u003e⚠️ No marketing your product or service\u003c/li\u003e\n\u003cli\u003e⚠️ No meeting/recording bots. Humans are welcome. Meeting bots are not.\u003c/li\u003e\n\u003cli\u003e⚠️ Mute!\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eSee you there!\u003c/p\u003e\n",
      "date_published": "2025-11-13T18:08:22-05:00",
      "id": "http://webology.micro.blog/2025/11/13/office-hours-for-november/",
      "summary": "Office hours this Friday, November 14th from 2:30-4:30pm CT! https://time.is/0230PM_14_November_2025_in_CT\nStarting at 2pm CT, I’ll be working on some community/open source projects if anyone wants to see Claude Code or Claude Code on the web in action.\nOpen to anyone working remotely who wants to connect, collaborate, or just hang out while working. Python/Django folks regularly attend, but everyone is welcome.\nDrop in anytime during the session - no need to stay for the full two hours. DM me for the Zoom link if you need it!",
      "tags": [
        "Django",
        "Python",
        "Office Hours"
      ],
      "title": "📅 Office Hours for November",
      "url": "https://micro.webology.dev/2025/11/13/office-hours-for-november/"
    },
    {
      "content_html": "\u003cp\u003eHere are my Default Apps 2025, which builds from my \u003ca href=\"https://jefftriplett.com/2024/default-apps-2024/\"\u003eDefault Apps 2024\u003c/a\u003e and \u003ca href=\"https://jefftriplett.com/2023/default-apps-2023/\"\u003eDefault Apps 2023\u003c/a\u003e posts.\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e🤖 AI Coding Assistant: \u003ca href=\"https://claude.ai/code\"\u003eClaude Code\u003c/a\u003e + \u003ca href=\"https://github.com/features/copilot/cli\"\u003eGitHub Copilot CLI\u003c/a\u003e + \u003ca href=\"https://openai.com/codex/\"\u003eCodex\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e⚙️ Automation: \u003ca href=\"https://www.hammerspoon.org\"\u003eHammerspoon\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🎒 Backups: \u003ca href=\"https://www.backblaze.com\"\u003eBackblaze\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🔖 Bookmarks: \u003ca href=\"https://raindrop.io\"\u003eRaindrop.io\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🌐 Browser: \u003ca href=\"https://vivaldi.com\"\u003eVivaldi\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e📆 Calendar: Apple Calendar\u003c/li\u003e\n\u003cli\u003e💬 Chat: Apple Messages (family \u0026amp; friends), \u003ca href=\"https://discord.com/\"\u003eDiscord\u003c/a\u003e (friends), \u003ca href=\"https://slack.com/\"\u003eSlack\u003c/a\u003e (work and community work), \u003ca href=\"https://telegram.org\"\u003eTelegram\u003c/a\u003e  (weird bots)\u003c/li\u003e\n\u003cli\u003e📁 Cloud File Storage: iCloud Drive + \u003ca href=\"https://syncthing.net\"\u003eSyncthing\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🧑‍💻 Code Editor: \u003ca href=\"https://www.sublimetext.com/\"\u003eSublime Text\u003c/a\u003e + \u003ca href=\"https://zed.dev\"\u003eZed\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🤖 Containers: \u003ca href=\"https://orbstack.dev\"\u003eOrbStack\u003c/a\u003e + \u003ca href=\"https://www.docker.com\"\u003eDocker Compose\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e✍️ Grammar: \u003ca href=\"https://grammarly.com\"\u003eGrammarly\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🚀 Launcher: \u003ca href=\"https://www.alfredapp.com\"\u003eAlfred 5\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e📨 Mail Client: \u003ca href=\"https://mimestream.com\"\u003eMimestream\u003c/a\u003e (Gmail only and not very often)\u003c/li\u003e\n\u003cli\u003e📮 Mail Server: \u003ca href=\"https://www.fastmail.com\"\u003eFastmail\u003c/a\u003e  (I pay for it but still don\u0026rsquo;t use it enough) + Gmail\u003c/li\u003e\n\u003cli\u003e👔 Menu Bar: \u003ca href=\"https://icemenubar.app\"\u003eIce\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🎵 Music: \u003ca href=\"https://www.apple.com/apple-music/\"\u003eApple Music\u003c/a\u003e + \u003ca href=\"https://spotify.com\"\u003eSpotify\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🔐 Password Management: \u003ca href=\"https://1password.com/\"\u003e1Password\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🎤 Podcasts: Apple Podcast\u003c/li\u003e\n\u003cli\u003e📑 Read It Later: \u003ca href=\"https://raindrop.io\"\u003eRaindrop.io\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🔗 Remote Access: \u003ca href=\"https://tailscale.com\"\u003eTailscale\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🗓️ Scheduling + Booking: \u003ca href=\"https://cal.com\"\u003eCal.com\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🖼️ Screenshots: \u003ca href=\"https://xnapper.com\"\u003eXnapper\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🔍 Search: \u003ca href=\"https://kagi.com\"\u003eKagi\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🐚 Terminal: \u003ca href=\"https://iterm2.com\"\u003eiTerm2\u003c/a\u003e + \u003ca href=\"https://ghostty.org\"\u003eGhostty\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🌐 Terminal Proxy: \u003ca href=\"https://vibetunnel.sh\"\u003eVibeTunnel\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🎙️ Transcription: \u003ca href=\"https://goodsnooze.gumroad.com/l/macwhisper\"\u003eMacWhisper\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e🗃️ Version Control: \u003ca href=\"https://www.git-tower.com\"\u003eTower\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e📹 Video Calls: \u003ca href=\"https://zoom.us\"\u003eZoom\u003c/a\u003e + \u003ca href=\"https://cal.com\"\u003eCal.com\u003c/a\u003e + \u003ca href=\"https://www.trymeeter.com\"\u003eMeeter\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e✈️ VPN: \u003ca href=\"https://tailscale.com/mullvad\"\u003eMullvad\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e📝 Writing: \u003ca href=\"https://obsidian.md/\"\u003eObsidian\u003c/a\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"commentary\"\u003eCommentary\u003c/h2\u003e\n\u003cp\u003eThe biggest changes for me this year were the addition of more AI tooling like coding assistants, VibeTunnel, and the MacWhisper voice translating app. A year ago, I was writing my own AI coding tools with Python. Today, I use voice-to-text to interact with multiple coding assistants that I can access from any browser connected to my Tailscale Tailnet. It\u0026rsquo;s a mouthful to explain, but coding looks very different now than it did a year or two ago for me.\u003c/p\u003e\n\u003cp\u003eI\u0026rsquo;m not using Google Apps as much as I was a few years ago, though I still need to switch between Google Orgs for work and community organizations.\u003c/p\u003e\n\u003ch2 id=\"changes-from-2024\"\u003eChanges from 2024\u003c/h2\u003e\n\u003cp\u003e\u003cstrong\u003eNew Additions:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eAI Coding Assistant (Claude Code, GitHub Copilot CLI, Codex)\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eVibeTunnel\u003c/strong\u003e for accessing my terminal through any browser on my Tailnet\u003c/li\u003e\n\u003cli\u003eI started using \u003cstrong\u003eGhostty\u003c/strong\u003e to run my AI sessions, but I find its lack of find (⌘f) support to be terribly frustrating.\u003c/li\u003e\n\u003cli\u003eI have used MacWhisper for years, but now it\u0026rsquo;s a daily driver. I can hold down the globe (fn) key on my keyboard and talk to my computer and quickly reply to people or even write blog posts with my voice. It\u0026rsquo;s incredibly cool and powerful.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003e\u003cstrong\u003eApps Removed:\u003c/strong\u003e\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eI dropped \u003cstrong\u003ePolypane\u003c/strong\u003e (Browser category)\u003c/li\u003e\n\u003cli\u003eI managed to not use \u003cstrong\u003eOvercast\u003c/strong\u003e (Podcasts category) for most of the year, but I\u0026rsquo;m still not happy with Apple\u0026rsquo;s Podcast app. I might be switching back.\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003ePreviously inspired by: \u0026ldquo;Apps I\u0026rsquo;ve been using regularly this year.\u0026rdquo; Heavily inspired by \u003ca href=\"https://mattstein.com/thoughts/default-apps-2023/\"\u003eMatt Stein\u003c/a\u003e and cataloged by Robb Knight\u0026rsquo;s \u003ca href=\"https://defaults.rknight.me\"\u003eApp Defaults\u003c/a\u003e\u003c/p\u003e\n",
      "date_published": "2025-10-29T18:55:03-05:00",
      "id": "http://webology.micro.blog/2025/10/29/default-apps-here-are-my/",
      "summary": "My default apps for 2025 reflect a significant shift in how I code, with AI assistants like Claude Code and voice-to-text tools like MacWhisper becoming daily drivers. The biggest change is how I can now access my development environment from any browser through VibeTunnel and my Tailscale Tailnet.",
      "tags": [
        "Python",
        "Today I Learned"
      ],
      "title": "Default Apps 2025",
      "url": "https://micro.webology.dev/2025/10/29/default-apps-here-are-my/"
    },
    {
      "content_html": "\u003cp\u003eI checked out William Vincent\u0026rsquo;s \u003ca href=\"https://wsvincent.com/copilot-cli-secret-prompts/\"\u003eThe Secret Prompts in GitHub Copilot CLI\u003c/a\u003e tonight, and I wanted to share a few tips and what stood out to me.\u003c/p\u003e\n\u003ch2 id=\"github-copilot-cli-uses-claude-sonnet-45-by-default\"\u003eGitHub Copilot CLI uses Claude Sonnet 4.5 by default\u003c/h2\u003e\n\u003cblockquote\u003e\n\u003cp\u003eNo luck other than confirming it is using Claude models by default. Apparently, you can change the underlying model, for example, to ChatGPT 5, by updating the environment variable \u003ccode\u003eCOPILOT_MODEL=gpt-5\u003c/code\u003e; however, we will work with the defaults here.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eYou can Copilot CLI\u0026rsquo;s default model via the \u003ccode\u003e/model\u003c/code\u003e command and it will also let you pick between three models.\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e Select Model\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e Choose the AI model to use \u003cspan style=\"color:#66d9ef\"\u003efor\u003c/span\u003e Copilot CLI. The selected model will be persisted and used \u003cspan style=\"color:#66d9ef\"\u003efor\u003c/span\u003e future sessions.\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e ❯ 1. Claude Sonnet 4.5 \u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003edefault\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e \u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003ecurrent\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e   2. Claude Sonnet \u003cspan style=\"color:#ae81ff\"\u003e4\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e   3. GPT-5\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e   4. Cancel \u003cspan style=\"color:#f92672\"\u003e(\u003c/span\u003eEsc\u003cspan style=\"color:#f92672\"\u003e)\u003c/span\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e Use ↑/↓ to navigate, Enter to \u003cspan style=\"color:#66d9ef\"\u003eselect\u003c/span\u003e, Esc to cancel\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eI\u0026rsquo;m somewhat surprised that GitHub CLI isn\u0026rsquo;t shipping with \u003ccode\u003egpt-5-codex\u003c/code\u003e model support yet. From my testing, it appears to be OpenAI\u0026rsquo;s best coding model, but it may be shipping soon.\u003c/p\u003e\n\u003ch2 id=\"the-you-are-trick\"\u003eThe \u0026ldquo;You are\u0026rdquo; trick\u003c/h2\u003e\n\u003cblockquote\u003e\n\u003cp\u003eWell, what we \u0026ldquo;really\u0026rdquo; care about are any prompts that start with \u0026ldquo;you are\u0026rdquo; since those are instructions from Copilot CLI to the model.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eThe \u0026ldquo;you are\u0026rdquo; tip is one I shared with Will and \u003ca href=\"https://simonwillison.net\"\u003eSimon Willison\u003c/a\u003e, which I have used for a few years when trying to find a tool\u0026rsquo;s system prompt, which is always buried and obfuscated in their JavaScript files.\u003c/p\u003e\n\u003cp\u003eSimon and I were invited to Microsoft HQ last month for an AI Insider\u0026rsquo;s summit (I prefer not to use the term influencer), where we were given early access to GitHub Copilot CLI before the public release. The first thing we both did was dive into the system prompt to see what it contained. Every system prompt has \u0026ldquo;You are\u0026rdquo; buried in it somewhere, which makes it much easier to find that paging through 10k lines of JavaScript.\u003c/p\u003e\n\u003ch2 id=\"use-xml-tags-in-your-prompts\"\u003eUse Xml tags in your prompts\u003c/h2\u003e\n\u003cp\u003eWill posted the Copilot CLI\u0026rsquo;s system prompt, and one thing that stood out to me was the various XML-tagged sections, such as \u003ccode\u003e\u0026lt;tips_and_tricks\u0026gt;\u003c/code\u003e and \u003ccode\u003e\u0026lt;style\u0026gt;\u003c/code\u003e, which Anthropic has encouraged for years. They documented the technique in the \u003ca href=\"https://docs.claude.com/en/docs/build-with-claude/prompt-engineering/use-xml-tags\"\u003eUse XML tags to structure your prompts\u003c/a\u003e section of their docs.\u003c/p\u003e\n\u003ch2 id=\"natural-language-prompts-are-becoming-the-universal-programming-interface\"\u003eNatural language prompts are becoming the universal programming interface\u003c/h2\u003e\n\u003cp\u003eI have been experimenting with LLMs since the release of GPT-2. While I understand why it pains many developers to admit this, natural language prompts have become a language-agnostic way to program. Somebody could build the same app I\u0026rsquo;m building using Django with the same prompts in Laravel, Rails, or any other well-documented web framework and underlying programming language.\u003c/p\u003e\n\u003cp\u003eFor many people who are new to development, this is more obvious:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003ePrompts are code.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eLanguages like Python aren\u0026rsquo;t going away, but it\u0026rsquo;s much easier and faster to develop when pairing with an LLM assistant who is always online and can instantly answer any questions that you might have.\u003c/p\u003e\n\u003cp\u003eThe more I examine tools like GitHub Copilot CLI, the clearer it becomes: understanding how these tools prompt their models matters not just for curiosity\u0026rsquo;s sake, but because knowing how the prompt works helps you work better with the tool. Next time you\u0026rsquo;re using an AI coding assistant, use the \u0026ldquo;You are\u0026rdquo; trick to peek under the hood. You might be surprised by what you find.\u003c/p\u003e\n",
      "date_published": "2025-10-04T20:57:19-05:00",
      "id": "http://webology.micro.blog/2025/10/04/on-github-copilot-cli-and/",
      "tags": [
        "Django",
        "Python",
        "LLM"
      ],
      "title": "🤖 On GitHub Copilot CLI and prompts as code",
      "url": "https://micro.webology.dev/2025/10/04/on-github-copilot-cli-and/"
    },
    {
      "content_html": "\u003cp\u003eI do not want Discord\u0026rsquo;s Nitro.\u003cbr\u003e\nI do not want it, friend or foe.\u003c/p\u003e\n\u003cp\u003eI will not boost, I will not pay,\u003cbr\u003e\nI do not want it any day.\u003c/p\u003e\n\u003cp\u003eI do not want it on my phone,\u003cbr\u003e\nI do not want it when I\u0026rsquo;m alone.\u003c/p\u003e\n\u003cp\u003eI do not want it for more emoji,\u003cbr\u003e\nI do not want it—it feels too showy.\u003c/p\u003e\n\u003cp\u003eI will not take it on a stream,\u003cbr\u003e\nI will not buy it for a meme.\u003c/p\u003e\n\u003cp\u003eI do not want it, Sam-I-Post.\u003cbr\u003e\nDiscord Nitro? Not even close.\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eWritten by Jeff and ChatGPT. Edited with \u003ca href=\"https://grammarly.com\"\u003eGrammarly\u003c/a\u003e and \u003ca href=\"https://claude.ai/code\"\u003eClaude Code\u003c/a\u003e.\u003c/p\u003e\n",
      "date_published": "2025-09-24T18:20:24-05:00",
      "id": "http://webology.micro.blog/2025/09/24/i-do-not-want-discords/",
      "title": "⛔ I Do Not Want Discord's Nitro",
      "url": "https://micro.webology.dev/2025/09/24/i-do-not-want-discords/"
    },
    {
      "content_html": "\u003cp\u003eI will be in Chicago this Saturday through next week for \u003ca href=\"https://2025.djangocon.us\"\u003eDjangoCon US 2025\u003c/a\u003e (September 8-12). I hope to see people there in person. If you can\u0026rsquo;t make it, please consider getting an \u003ca href=\"https://ti.to/defna/djangocon-us-2025\"\u003eonline ticket\u003c/a\u003e. They are relatively inexpensive, you get three full days out of them, and they help support the conference. More importantly, it helps support future conference events so we can continue to offer virtual attendance. It\u0026rsquo;s important that our online sales do well enough to help us cover our online costs and help fund our grants, along with our annual Django Software Foundation donation.\u003c/p\u003e\n\u003cp\u003eWith an online ticket, you get to watch talks live and after the fact, probably a month before they come out on YouTube. You\u0026rsquo;ll have more interaction with people who are at the conference than you would get otherwise, plus the convenience of watching whenever you want. You can watch them live or on a time delay. You can join late, watch while we\u0026rsquo;re on breaks and at lunch, catch up, and join us in real time. Buying a ticket gives you the ability to watch whenever you want. If you are buying your own ticket, they\u0026rsquo;re $99. If your employer is buying you a ticket, it\u0026rsquo;s $199. So please buy a \u003ca href=\"https://ti.to/defna/djangocon-us-2025\"\u003evirtual ticket\u003c/a\u003e and enjoy over 50 excellent talks over three days. I\u0026rsquo;ll even be on a panel.\u003c/p\u003e\n\u003cp\u003eIf you\u0026rsquo;re in Chicago and want to meet up at the conference, let me know. I will be around the venue all week and hope to sprint on some new and old projects, including work on \u003ca href=\"https://djangopackages.org\"\u003eDjango Packages\u003c/a\u003e. If you want to talk about the Django News projects I\u0026rsquo;ve been working on, like \u003ca href=\"https://django-news.com\"\u003eDjango News\u003c/a\u003e, \u003ca href=\"https://djangotv.com\"\u003eDjango TV\u003c/a\u003e, \u003ca href=\"http://jobs.django-news.com\"\u003eDjango News Jobs\u003c/a\u003e, and \u003ca href=\"https://awesomedjango.org\"\u003eAwesome Django\u003c/a\u003e.\u003c/p\u003e\n\u003cp\u003eDjangoCon US has been a good excuse for me to launch a few projects over the years, including \u003ca href=\"http://jobs.django-news.com\"\u003eDjango News Jobs\u003c/a\u003e two years ago and \u003ca href=\"https://djangotv.com\"\u003eDjango TV\u003c/a\u003e last year. This year, I\u0026rsquo;m working on something too, and I\u0026rsquo;m probably going to release it sooner than I would typically do. I\u0026rsquo;m trying to figure out what would be a fun and useful project for the community. I\u0026rsquo;d love to talk to people about what that project is.\u003c/p\u003e\n\u003ch2 id=\"topics-id-love-to-discuss-at-djangocon-us\"\u003eTopics I\u0026rsquo;d Love to Discuss at DjangoCon US\u003c/h2\u003e\n\u003cp\u003eI really enjoy meeting new people whom I\u0026rsquo;ve met online, but I know that\u0026rsquo;s sometimes hard for people whom we have never met in person before. Conferences can be awkward and scary; we\u0026rsquo;ve all been there. Here\u0026rsquo;s a list of topics to help break the ice in case you find any of these interesting and want to talk more about them.\u003c/p\u003e\n\u003ch3 id=\"django-development\"\u003eDjango Development\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eSide projects and making them sustainable\u003c/li\u003e\n\u003cli\u003eThe deployment story for Django\u003c/li\u003e\n\u003cli\u003eBetter production defaults in Django\u003c/li\u003e\n\u003cli\u003eBetter ways to run a project and get projects up quickly\u003c/li\u003e\n\u003cli\u003eGrowing Django community projects to the next level\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"ai-and-llm-topics\"\u003eAI and LLM Topics\u003c/h3\u003e\n\u003cul\u003e\n\u003cli\u003eWhat MCP looks like for Django\u003c/li\u003e\n\u003cli\u003eAI-driven development with Claude Code\u003c/li\u003e\n\u003cli\u003eProjects built with LLMs (I\u0026rsquo;ve got several that are 99%+ AI-written)\u003c/li\u003e\n\u003cli\u003eHow AI can help with open source development\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch3 id=\"django-software-foundation--sustainability\"\u003eDjango Software Foundation \u0026amp; Sustainability\u003c/h3\u003e\n\u003cp\u003eWe just hired a Django fellow for the Django Software Foundation, and fundraising is really top of mind. As we\u0026rsquo;ve grown to have three fellows and an assistant, we need to make the fellowship program more sustainable and fundraise for an executive director who can help guide Django\u0026rsquo;s future. I\u0026rsquo;ve been on the board for less than a year, and it\u0026rsquo;s way more work than any of us expected. We have a very engaged board, but we need to make this more sustainable for the next board.\u003c/p\u003e\n\u003cp\u003eI\u0026rsquo;d love to talk about:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003eHow to make it more engaging for companies to support the DSF\u003c/li\u003e\n\u003cli\u003eMaking the fellowship program and Django community projects more sustainable\u003c/li\u003e\n\u003cli\u003eGrowing projects I\u0026rsquo;ve been working on with Will Vincent to provide more community value\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eNew Django releases are great and help drive a lot of good, but I\u0026rsquo;d also love to see our side projects grow to that next level of sustainability.\u003c/p\u003e\n\u003ch2 id=\"how-to-reach-me\"\u003eHow to Reach Me\u003c/h2\u003e\n\u003cp\u003eFeel free to reach out to me - I\u0026rsquo;m on \u003ca href=\"https://mastodon.social/@webology\"\u003eMastodon\u003c/a\u003e, which is probably the best way to get a hold of me. I\u0026rsquo;ll also be on the conference Slack. I\u0026rsquo;ll be helping to organize a bit, but I hope to have plenty of time to talk to and meet people in person. I am definitely open and available if people want to connect and meet in person.\u003c/p\u003e\n\u003cp\u003eI\u0026rsquo;m also a partner and a consultant at \u003ca href=\"https://www.revsys.com\"\u003eREVSYS\u003c/a\u003e in Lawrence, Kansas. If you\u0026rsquo;re having company problems and you would like to talk to either me, \u003ca href=\"https://frankwiles.com\"\u003eFrank Wiles\u003c/a\u003e, or one of my \u003ca href=\"https://www.revsys.com/about/\"\u003ecolleagues\u003c/a\u003e, we\u0026rsquo;d love to talk to you. You may be experiencing problems that we can help with, or your company is too busy, and you could use an extra set of hands. Or maybe you need some advice on how to get AI working with your company. We\u0026rsquo;ve done a lot of real-world projects for a while, and I\u0026rsquo;ve spent a couple of years with AI. I\u0026rsquo;m always happy to talk about that.\u003c/p\u003e\n",
      "date_published": "2025-09-03T21:03:11-05:00",
      "id": "http://webology.micro.blog/2025/09/03/my-djangocon-us-plans-and/",
      "tags": [
        "Django"
      ],
      "title": "My DjangoCon US 2025 Plans (and How to Find Me)",
      "url": "https://micro.webology.dev/2025/09/03/my-djangocon-us-plans-and/"
    },
    {
      "content_html": "\u003cp\u003eI\u0026rsquo;m hosting office hours on the next two Fridays in August.\u003c/p\u003e\n\u003ch2 id=\"office-hours-schedule\"\u003eOffice Hours Schedule\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ca href=\"https://time.is/0230PM_22_August_2025_in_CT\"\u003eFriday, August 22, 2025, 2:30 pm to 4:30 pm CT\u003c/a\u003e\u003c/strong\u003e\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003e\u003ca href=\"https://time.is/0230PM_29_August_2025_in_CT\"\u003eFriday, August 29, 2025, 2:30 pm to 4:30 pm CT\u003c/a\u003e\u003c/strong\u003e\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"join-us\"\u003eJoin Us\u003c/h2\u003e\n\u003cp\u003eThese sessions are open to anyone, especially those working remotely who wants to connect with others. It\u0026rsquo;s a collaborative space for discussions, catch-ups, or just hanging out while you work.\u003c/p\u003e\n\u003cp\u003eWhile we have a bunch of Python and Django developers who regularly attend, anyone is welcome to join even if you don\u0026rsquo;t use either of these things.\u003c/p\u003e\n\u003cp\u003eWhether you\u0026rsquo;re a first-time attendee or a regular, you\u0026rsquo;re welcome to drop in anytime during the session. No need to stay for the full two hours, come and go as your schedule allows.\u003c/p\u003e\n\u003ch2 id=\"how-to-join\"\u003eHow to Join\u003c/h2\u003e\n\u003cp\u003eThe Zoom link is available in the gist from our previous sessions. Feel free to reach out if you need the details.\u003c/p\u003e\n\u003ch2 id=\"ℹ-meeting-guidelines\"\u003eℹ️ Meeting Guidelines\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e🔕 Please mute when someone else is talking 👈\u003c/li\u003e\n\u003cli\u003e👍 Be respectful to other people and mute when not talking\u003c/li\u003e\n\u003cli\u003e👍 Be mindful of the spirit of the \u003ca href=\"https://policies.python.org/python.org/code-of-conduct/\"\u003ePython Code of Conduct\u003c/a\u003e\u003c/li\u003e\n\u003cli\u003e👍 Be mindful and respectful of everyone\u0026rsquo;s time.\u003c/li\u003e\n\u003cli\u003e👍 Join because you want to work on something with a small group\u003c/li\u003e\n\u003cli\u003e⚠️ No marketing your product or service\u003c/li\u003e\n\u003cli\u003e⚠️ No meeting/recording bots. Humans are welcome. Meeting bots are not.\u003c/li\u003e\n\u003cli\u003e⚠️ Mute!\u003c/li\u003e\n\u003c/ul\u003e\n\u003cp\u003eSee you there!\u003c/p\u003e\n",
      "date_published": "2025-08-21T18:54:44-05:00",
      "id": "http://webology.micro.blog/2025/08/21/office-hours-for-late-august/",
      "tags": [
        "Django",
        "Python",
        "Office Hours"
      ],
      "title": "🗓️ Office Hours for Late August",
      "url": "https://micro.webology.dev/2025/08/21/office-hours-for-late-august/"
    },
    {
      "content_html": "\u003cp\u003e\u003ca href=\"https://github.com/syncthing/syncthing/releases/tag/v2.0.0\"\u003eSyncthing 2.0\u003c/a\u003e was released last week, and I upgraded my Macs and my Intel NUC. I\u0026rsquo;m pleased with the performance. I never had complaints about it being slow, but the new app is much faster. I like that they\u0026rsquo;re using a SQLite database, which makes it easier to write hacks or tools to check the data.\u003c/p\u003e\n\u003cp\u003eUpgrading wasn\u0026rsquo;t terrible. I used \u003ca href=\"https://brew.sh\"\u003eHomebrew\u003c/a\u003e to upgrade it, which seemed to work initially, but I had problems with the service when I restarted it. I took the following steps: stopped Syncthing, removed it, reinstalled it, and then started the service. I\u0026rsquo;ve never managed to get a service to work correctly on macOS when I write them by hand, so I let Homebrew handle the services. It understands how to write the right templates and format, and gets it right. After running these commands, everything just worked:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ebrew services stop syncthing  \n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ebrew remove syncthing  \n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ebrew install syncthing  \n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ebrew services start syncthing\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eOne pro tip: once everything has stopped, you can run \u003ccode\u003esyncthing\u003c/code\u003e manually instead of invoking the service to see it migrate each folder to the new SQLite database format.\u003c/p\u003e\n\u003cp\u003eI had over 100 shared folders because I was treating each of my projects and client projects as their separate shares. I\u0026rsquo;ve recently changed that and have been migrating everything into my own \u0026ldquo;Projects\u0026rdquo; folder and keeping client stuff in a \u0026ldquo;Clients\u0026rdquo; folder. That way, everything separates. I have more control over what I have on my home or personal laptop versus what I have on my work computer. This makes a nice separation of work and home life.\u003c/p\u003e\n\u003cp\u003eI prefer Syncthing over other tools because it runs well even on ancient hardware. It works on every operating system—I mostly use macOS and Linux, but I\u0026rsquo;ve even run it on a Raspberry Pi. I\u0026rsquo;m currently running it across four or five systems, which makes file sharing seamless. The sync speed is excellent, I\u0026rsquo;m not locked into any services like Dropbox, and I don\u0026rsquo;t have to pay for features I don\u0026rsquo;t need. The usability and speed hit the sweet spot for me.\u003c/p\u003e\n\u003cp\u003eMy only complaint about Syncthing is the CLI experience for adding folders. Even after years of using it, I haven\u0026rsquo;t figured out if it\u0026rsquo;s possible or if I\u0026rsquo;m just doing it wrong. Maybe this changed in 2.0, but most forum discussions suggest editing the raw XML configuration directly. I only spent a few minutes looking into the 2.0 CLI, and it hasn\u0026rsquo;t clicked yet.\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003eWritten by Jeff. Edited with \u003ca href=\"https://grammarly.com\"\u003eGrammarly\u003c/a\u003e and \u003ca href=\"https://claude.ai/code\"\u003eClaude Code\u003c/a\u003e.\u003c/p\u003e\n",
      "date_published": "2025-08-13T22:45:10-05:00",
      "id": "http://webology.micro.blog/2025/08/13/syncthing-upgrade-notes/",
      "title": "Syncthing 2.0 Upgrade Notes",
      "url": "https://micro.webology.dev/2025/08/13/syncthing-upgrade-notes/"
    },
    {
      "content_html": "\u003cp\u003eToday I came across \u003ca href=\"https://x.com/levelsio/status/1953022273595506910\"\u003ePieter Levels\u0026rsquo; post\u003c/a\u003e about \u0026ldquo;VibeOps,\u0026rdquo; a workflow that involves SSHing to a cheap VPS server and installing Claude Code directly on it. I\u0026rsquo;m running this setup on a cheap Hetzner box. While this approach might sound risky at first, when combined with a secure networking solution like \u003ca href=\"https://tailscale.com\"\u003eTailscale\u003c/a\u003e and properly configured as a Tailnet, it becomes both safe and worth experimenting with.\u003c/p\u003e\n\u003cp\u003eI\u0026rsquo;ve also been exploring a complementary tool called \u003ca href=\"https://vibetunnel.sh\"\u003eVibe Tunnel\u003c/a\u003e, which integrates well with Tailscale and my existing Tailnet setup. It provides an elegant way to remotely create or connect to an existing Claude Code session from my browser. I like the idea of letting Claude handle some routine remote tasks.\u003c/p\u003e\n\u003cp\u003eSecurity is essential here. My Hetzner box uses their firewall product to block all ports except for SSL (443) and only allows me to access the box via Tailscale. If you aren\u0026rsquo;t using a firewall and a VPN product like Tailscale, you should not use a product like Vibe Tunnel to allow access to a running shell on your servers.\u003c/p\u003e\n\u003cp\u003eWhile trying to install Vibe Tunnel, I ran into a PAM error, so I did what anyone would do with Claude Code available on the server: I let Claude fix it for me. I thought Claude could figure it out, but after 5 to 10 minutes of noble efforts, I found \u003ca href=\"https://github.com/amantus-ai/vibetunnel/issues/499\"\u003eissue #499\u003c/a\u003e and \u003ca href=\"https://github.com/amantus-ai/vibetunnel/pull/521\"\u003epull request #521\u003c/a\u003e, which point to a bigger issue with a potential fix coming soon.\u003c/p\u003e\n\u003cp\u003eWhile I was on my server, I asked Claude to look at my Caddy setup for a bunch of parked domains, and it found some actionable changes and even fixed a few broken paths that weren\u0026rsquo;t obvious. This is exactly the kind of routine server maintenance where having Claude available directly on the server proves helpful.\u003c/p\u003e\n\u003cp\u003eI also had Claude check to see if the machine was out-of-date, and I watched it install a month\u0026rsquo;s worth of updates. Claude even wrote a nice summary for me to share in this post:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eAnalysis: The system is running a current Long Term Support release of Ubuntu with extended support until 2029. All installed packages are current with no pending updates available. No maintenance required at this time.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cblockquote\u003e\n\u003cp\u003eAction Taken: System audit only - no changes were made to the system.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eAll in all, I am a fan, even if I wouldn\u0026rsquo;t recommend this for any clients or just anyone.\u003c/p\u003e\n",
      "date_published": "2025-08-06T19:05:47-05:00",
      "id": "http://webology.micro.blog/2025/08/06/vibeops-using-claude-code-on/",
      "tags": [
        "LLM",
        "Today I Learned"
      ],
      "title": "🤖 VibeOps: Using Claude Code on Cheap VPS Servers",
      "url": "https://micro.webology.dev/2025/08/06/vibeops-using-claude-code-on/"
    },
    {
      "content_html": "\u003cp\u003eToday, I fired up the \u003ca href=\"https://github.com/nazdridoy/kokoro-tts\"\u003eVoices\u003c/a\u003e macOS app, which I occasionally use to convert blog posts or documentation text to audio files that I can take on the go. I usually use one of OpenAI\u0026rsquo;s Text to speech APIs, but today I noticed there was a new option called Kokoro, which is a local voice model. I was interested in the model and tried out a few voices. Two or three of them were amazing for a local model.\u003c/p\u003e\n\u003cp\u003eAfter trying out a few blog posts and listening to them, I decided to find a Python version of the model. It might be slow to run, but at least I can create a pipeline to automate the process of generating voice files from arbitrary text files I have lying around.\u003c/p\u003e\n\u003cp\u003eThat\u0026rsquo;s when I found the \u003ca href=\"https://github.com/nazdridoy/kokoro-tts\"\u003eKokoro TTS\u003c/a\u003e application. I downloaded it and noticed that it needed a few things. Things like NumPy required to be installed, and a couple of things were out of sync, but the project mostly just worked. While it wasn\u0026rsquo;t quite as fast as a native Mac app, it was still good enough for me to run text files through it very quickly.\u003c/p\u003e\n\u003cp\u003eTonight, I decided to write up my notes on how to bootstrap and run the project.\u003c/p\u003e\n\u003ch2 id=\"installation\"\u003eInstallation\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003egit clone git@github.com:nazdridoy/kokoro-tts.git\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ecd kokoro-tts\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003euv add numpy\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003euv sync \n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ewget https://github.com/nazdridoy/kokoro-tts/releases/download/v1.0.0/voices-v1.0.bin\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e\n\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003ewget https://github.com/nazdridoy/kokoro-tts/releases/download/v1.0.0/kokoro-v1.0.onnx\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"basic-usage\"\u003eBasic Usage\u003c/h2\u003e\n\u003cp\u003eOnce installed, you can use Kokoro TTS from the command line:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003eecho \u003cspan style=\"color:#e6db74\"\u003e\u0026#34;Hello, this is a test of Kokoro TTS\u0026#34;\u003c/span\u003e | ./kokoro-tts /dev/stdin example-streaming.mp3 \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    --format mp3 \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    --voice af_heart\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cp\u003eIf you already have an existing text file:\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e./kokoro-tts textfile.txt example-textfile.mp3 \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    --format mp3 \u003cspan style=\"color:#ae81ff\"\u003e\\\n\u003c/span\u003e\u003c/span\u003e\u003c/span\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e    --voice af_heart\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"conclusion\"\u003eConclusion\u003c/h2\u003e\n\u003cp\u003eKokoro TTS is a solid local text-to-speech option that runs entirely on your machine without requiring API calls or internet connectivity. While it may not be as fast as native Mac apps, the quality is impressive for a local model, and the ability to automate voice file creation from text files makes it valuable for anyone who wants to convert written content to audio format.\u003c/p\u003e\n\u003cp\u003eOne major advantage I discovered is that unlike most cloud APIs like OpenAI\u0026rsquo;s Text-to-speech that limit posts to around 3000 characters, Kokoro didn\u0026rsquo;t seem to have an upper limit on any of the content I tried it with. This makes it particularly useful for longer blog posts and documentation.\u003c/p\u003e\n\u003cp\u003eThe setup process is straightforward once you handle the missing dependencies, and the command-line interface makes it easy to integrate into existing workflows or automation scripts.\u003c/p\u003e\n\u003chr\u003e\n\u003cp\u003e\u003cem\u003eWritten by Jeff. Edited with \u003ca href=\"https://grammarly.com\"\u003eGrammarly\u003c/a\u003e and \u003ca href=\"https://claude.ai/code\"\u003eClaude Code\u003c/a\u003e.\u003c/em\u003e\u003c/p\u003e\n",
      "date_published": "2025-07-02T19:06:57-05:00",
      "id": "http://webology.micro.blog/2025/07/02/ditching-cloud-apis-how-i/",
      "tags": [
        "Python",
        "Today I Learned"
      ],
      "title": "Ditching Cloud APIs: How I Set Up Local Text-to-Speech with Kokoro TTS and Python",
      "url": "https://micro.webology.dev/2025/07/02/ditching-cloud-apis-how-i/"
    },
    {
      "content_html": "\u003cp\u003eI\u0026rsquo;ve been diving deep into AI-assisted development this summer, and I\u0026rsquo;ve collected some of the best articles I\u0026rsquo;ve found on the topic. This reading list focuses heavily on Claude Code and practical AI coding workflows, featuring insights from developers who are actively using these tools in their daily work. Whether you\u0026rsquo;re just getting started with AI coding assistants or looking to refine your approach, these articles are a good jump start.\u003c/p\u003e\n\u003ch2 id=\"claude-code\"\u003eClaude Code\u003c/h2\u003e\n\u003ch3 id=\"claude-code-is-my-computer\"\u003e\u003ca href=\"https://steipete.me/posts/2025/claude-code-is-my-computer\"\u003eClaude Code is My Computer\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003ePeter Steinberger describes using Claude Code with a dangerous permissions flag, transforming AI into a universal computer interface that can perform complex tasks, such as system migrations, content generation, and code management. By granting broad system access, he has found that Claude can automate numerous computing tasks, saving him significant time and operating at a fundamentally higher level of abstraction compared to traditional development tools.\u003c/p\u003e\n\u003ch3 id=\"how-i-use-claude-code\"\u003e\u003ca href=\"https://spiess.dev/blog/how-i-use-claude-code\"\u003eHow I Use Claude Code\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003ePhilipp Spiess shares his experiences and strategies for effectively using Claude Code, an AI coding assistant that has transformed his programming workflow. He emphasizes techniques like starting new threads frequently, creating precise prompts, breaking complex tasks into smaller steps, and maintaining a balance between AI automation and human oversight to maximize productivity.\u003c/p\u003e\n\u003ch3 id=\"basic-claude-code\"\u003e\u003ca href=\"https://harper.blog/2025/05/08/basic-claude-code/\"\u003eBasic Claude Code\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eHarper Reed discusses his workflow for using Claude Code, an AI coding assistant, which involves generating project specifications, using AI to create and implement prompts, and leveraging test-driven development (TDD) and pre-commit hooks. He emphasizes the importance of defensive coding practices like testing, linting, and creating project-specific configuration files to improve code quality and AI coding efficiency. Reed shares his team\u0026rsquo;s experience using Claude Code, noting increased test coverage and more effective development processes.\u003c/p\u003e\n\u003ch3 id=\"field-notes-from-shipping-real-code-with-claude\"\u003e\u003ca href=\"https://diwank.space/field-notes-from-shipping-real-code-with-claude\"\u003eField Notes From Shipping Real Code With Claude\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eThe article explores how to effectively use AI, specifically Claude, in software development by establishing clear boundaries, documentation, and workflows. The author emphasizes that AI is a powerful tool for generating code, but human oversight, particularly in writing tests and maintaining code quality, remains crucial. The piece provides a comprehensive guide to vibe-coding, a collaborative approach where humans direct AI to enhance productivity while maintaining rigorous engineering standards.\u003c/p\u003e\n\u003ch3 id=\"my-first-open-source-ai-generated-library\"\u003e\u003ca href=\"https://lucumr.pocoo.org/2025/6/21/my-first-ai-library/\"\u003eMy First Open Source AI Generated Library\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eArmin Ronacher created a sloppy XML parsing library entirely using AI (specifically Claude), which generated around 1,100 lines of code, 1,000 lines of tests, and handled package configuration. The project was an experimental exploration of AI\u0026rsquo;s capabilities in software development, resulting in a functional library that solved his immediate technical need of parsing imperfect XML output from language models.\u003c/p\u003e\n\u003ch2 id=\"ai-development-workflows\"\u003eAI Development Workflows\u003c/h2\u003e\n\u003ch3 id=\"my-llm-codegen-workflow-atm\"\u003e\u003ca href=\"https://harper.blog/2025/02/16/my-llm-codegen-workflow-atm/\"\u003eMy LLM codegen workflow atm\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eHarper Reed describes a comprehensive workflow for using Large Language Models (LLMs) to generate code, which involves three main steps: idea honing, planning, and execution. The workflow can be applied to both greenfield (new) and existing code projects, utilizing tools like Claude and Aider to iteratively develop software with minimal manual intervention. Reed emphasizes the importance of careful planning, testing, and maintaining context to effectively leverage AI in software development.\u003c/p\u003e\n\u003ch3 id=\"an-llm-codegen-hero\"\u003e\u003ca href=\"https://harper.blog/2025/04/17/an-llm-codegen-heros-journey/\"\u003eAn LLM Codegen Hero\u0026rsquo;s Journey\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eHarper Reed describes a progressive journey of adopting AI-assisted coding, starting from basic autocomplete to increasingly sophisticated AI coding tools like Cursor and Aider. The article outlines a step-by-step evolution of using Large Language Models (LLMs) for code generation, emphasizing that developers should embrace the technology incrementally and be open to its potential, ultimately reaching a point where AI agents can handle significant coding tasks with minimal human intervention.\u003c/p\u003e\n\u003ch3 id=\"how-i-program-with-agents\"\u003e\u003ca href=\"https://sketch.dev/blog/programming-with-agents\"\u003eHow I program with Agents\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eThe article explores how Large Language Model (LLM) agents, defined as a for loop that contains an LLM call, can significantly improve programming by providing environmental feedback and tools like bash commands, web searching, and compiler interactions. The author argues that agents transform LLMs from whiteboard-style code generation into powerful programming assistants that can navigate codebases, fix errors, and complete tasks more efficiently despite current limitations in speed and cost.\u003c/p\u003e\n\u003ch2 id=\"ai-industry-perspectives\"\u003eAI Industry Perspectives\u003c/h2\u003e\n\u003ch3 id=\"ai-changes-everything\"\u003e\u003ca href=\"https://lucumr.pocoo.org/2025/6/4/changes/\"\u003eAI Changes Everything\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eArmin Ronacher explores the profound impact of AI on work, creativity, and society, describing how AI tools like Claude are transforming his programming workflow. He argues that AI represents a revolutionary technological shift comparable to electricity or the printing press, and encourages embracing this change with curiosity and optimism rather than fear, believing AI can dramatically increase human agency when used well.\u003c/p\u003e\n\u003ch3 id=\"builderai-did-not\"\u003e\u003ca href=\"https://blog.pragmaticengineer.com/builder-ai-did-not-fake-ai/\"\u003eBuilder.ai did not \u0026ldquo;fake AI with 700 engineers\u0026rdquo;\u003c/a\u003e\u003c/h3\u003e\n\u003cp\u003eThe viral claim that Builder.ai used 700 engineers to manually pretend to be an AI system was false. In reality, the company built a code generation platform called Natasha using AI models like GPT and Claude, with a small team of about 15 engineers. The company collapsed due to alleged accounting fraud and misrepresentation of revenue to investors, not because of a fake AI scheme.\u003c/p\u003e\n\u003ch2 id=\"the-future-is-now-and-its-iterative\"\u003eThe Future Is Now (And It\u0026rsquo;s Iterative)\u003c/h2\u003e\n\u003cp\u003eWhat strikes me most about these articles is how quickly we\u0026rsquo;ve moved from \u0026ldquo;Can AI write code?\u0026rdquo; to \u0026ldquo;How do I optimize my AI coding workflow?\u0026rdquo; The common thread isn\u0026rsquo;t just about technology getting better but about developers becoming smarter about how they collaborate with AI. Whether it\u0026rsquo;s Harper\u0026rsquo;s methodical approach, Armin\u0026rsquo;s experimental libraries, or Peter\u0026rsquo;s all-in computer replacement strategy, AI coding is changing how we develop applications.\u003c/p\u003e\n\u003cp\u003eWritten by Jeff, typos fixed by Grammarly, summaries, feedback, and heading suggestions via Claude Code.\u003c/p\u003e\n",
      "date_published": "2025-06-25T20:38:11-05:00",
      "id": "http://webology.micro.blog/2025/06/25/building-with-ai-a-summer/",
      "summary": "A collection of articles highlights various approaches and insights into optimizing AI-assisted coding workflows, primarily focusing on Claude Code and its transformative impact on software development.",
      "tags": [
        "LLM"
      ],
      "title": "🤖 Building with AI: A Summer Reading Collection",
      "url": "https://micro.webology.dev/2025/06/25/building-with-ai-a-summer/"
    },
    {
      "content_html": "\u003cp\u003eI’m hosting a regular afternoon edition \u003cstrong\u003etomorrow (Friday, May 30)\u003c/strong\u003e to wrap up the month of May.\u003c/p\u003e\n\u003cp\u003eAfter that, I’ll be away on vacation, so I’m skipping the first \u003cstrong\u003etwo\u003c/strong\u003e Fridays in June and the first Friday in July.\u003c/p\u003e\n\u003cp\u003eHere’s the plan:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\u003cstrong\u003eFriday, June 6, 2025:\u003c/strong\u003e No office hours (vacation)\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eFriday, June 13, 2025:\u003c/strong\u003e No office hours (vacation)\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eFriday, June 20, 2025, 2:30 pm – 4:30 pm\u003c/strong\u003e (\u003ca href=\"https://time.is/0230PM_20_June_2025_in_CT\"\u003eTime.is link for CT\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eFriday, June 27, 2025, 2:30 pm – 4:30 pm\u003c/strong\u003e (\u003ca href=\"https://time.is/0230PM_27_June_2025_in_CT\"\u003eTime.is link for CT\u003c/a\u003e)\u003c/li\u003e\n\u003cli\u003e\u003cstrong\u003eFriday, July 4, 2025:\u003c/strong\u003e No office hours (US Holiday)\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"highlevel-details\"\u003eHigh‑level details\u003c/h2\u003e\n\u003cp\u003eℹ️ \u003cstrong\u003eAnyone\u003c/strong\u003e is welcome to join office hours. Many join because they work remotely, miss seeing faces, and enjoy the spontaneous conversations that occur when a small group gathers.\u003c/p\u003e\n\u003cp\u003eℹ️ It’s a collaborative space where we discuss ongoing projects, catch up, and finish the week on a productive note.\u003c/p\u003e\n\u003cp\u003e🙏 Everyone is welcome, whether you’re a regular or it’s your first time. If you’re curious, reach out.\u003c/p\u003e\n\u003cp\u003e✅ Need more details? Send me a message or check the gist from previous sessions, where you’ll always find the most recent Zoom link ⚠️\u003c/p\u003e\n",
      "date_published": "2025-05-29T09:18:30-05:00",
      "id": "http://webology.micro.blog/2025/05/29/office-hours-for-june/",
      "tags": [
        "Office Hours"
      ],
      "title": "🗓️ Office Hours for June",
      "url": "https://micro.webology.dev/2025/05/29/office-hours-for-june/"
    },
    {
      "content_html": "\u003cp\u003e🤔 I struggle with most research papers, but the \u003ca href=\"https://arxiv.org/abs/2502.15840\"\u003eVending-Bench: A Benchmark for Long-Term Coherence of Autonomous Agents\u003c/a\u003e was an easy read. The paper follows a fascinating study where researchers simulate various LLM models running a vending machine business over time.\u003c/p\u003e\n\u003cp\u003eWhat caught my eye wasn\u0026rsquo;t just the research methodology. It was this \u003ca href=\"https://mastodon.social/@benjojo@benjojo.co.uk/114573621760008267\"\u003epost by @benjojo\u003c/a\u003e sharing screenshots of the increasingly desperate emails the AI agent sent while trying to save its failing business. Watching an AI spiral into panic mode as quarterly profits tanked? That\u0026rsquo;s the kind of real-world AI behavior we rarely see documented.\u003c/p\u003e\n\u003cp\u003eThe email screenshots at the end are genuinely wild and worth checking out. You can watch the Agent\u0026rsquo;s \u0026ldquo;thought process\u0026rdquo; deteriorate from professional business correspondence to what can only be described as digital desperation after it keeps getting charged a $2 daily fee to operate.\u003c/p\u003e\n\u003ch2 id=\"finally-ai-that-closes-the-last-10-gap\"\u003eFinally, AI That Closes the Last 10% Gap\u003c/h2\u003e\n\u003cp\u003eWhat makes this research particularly relevant is the timing. I would love to see an updated version testing newer LLM models like Claude 3.7 + 4 and OpenAI\u0026rsquo;s o3 + o3-mini series. This latest generation represents the moment I noticed AI crossing from \u0026ldquo;sort-of good\u0026rdquo; to actually reliable.\u003c/p\u003e\n\u003cp\u003ePreviously, I was happy having AI solve 90% of my random side project problems and finishing the rest myself. But once Claude 3.7 and o3-mini hit production, something shifted. I could throw most issues at them and find complete, working solutions.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eThe sweet spot example:\u003c/strong\u003e Asking an LLM to build Stripe from scratch? It\u0026rsquo;s still too ambitious. But requesting it adds three specific Stripe subscription plans to an existing Django website, with proper error handling and webhook integration? That\u0026rsquo;s now a 10-minute task that seems to work.\u003c/p\u003e\n\u003cp\u003e\u003cstrong\u003eReal-world test:\u003c/strong\u003e My seven-year-old and I fell down a 45-minute YouTube rabbit hole about \u0026ldquo;How to Run a Vending Machine Business\u0026rdquo; over the weekend. We\u0026rsquo;re not actually planning to start one, but his uncle runs a laundromat and mentioned wanting to add vending machines on one of our last family visits. This research paper felt less academic and more like a preview of what\u0026rsquo;s possible when AI agents handle small business operations\u0026rsquo; mundane but critical parts.\u003c/p\u003e\n\u003cp\u003eI\u0026rsquo;m conflicted about the paper because many people won\u0026rsquo;t read it and skip to the failure as \u0026ldquo;further proof\u0026rdquo; to confirm their bias. That said, we are moving to a future where AI agents can manage the boring parts of our businesses so we can focus on what matters.\u003c/p\u003e\n\u003cp\u003eWritten by Jeff, typos fixed by Grammarly, feedback and heading suggestions via Claude 4\u003c/p\u003e\n",
      "date_published": "2025-05-26T09:31:44-05:00",
      "id": "http://webology.micro.blog/2025/05/26/when-ai-agents-start-panicking/",
      "summary": "A recent study showcasing AI agents running a vending machine business highlights the evolving capabilities of LLM models and their potential to manage mundane business tasks while revealing intriguing AI behavior under pressure.",
      "tags": [
        "LLM"
      ],
      "title": "🤖 When AI Agents Start Panicking: Wild Emails from a Failing Vending Business",
      "url": "https://micro.webology.dev/2025/05/26/when-ai-agents-start-panicking/"
    },
    {
      "content_html": "\u003cp\u003eToday I learned about \u003ca href=\"https://www.xpdfreader.com/pdftoppm-man.html\"\u003e\u003ccode\u003epdftoppm\u003c/code\u003e\u003c/a\u003e, a simple CLI tool that can convert each page of a PDF into separate image files.\u003c/p\u003e\n\u003cp\u003eMy use case was to chop up a few big PDF reports to make OCR and data analysis easier, but scanning them a page at a time.\u003c/p\u003e\n\u003ch2 id=\"install\"\u003eInstall\u003c/h2\u003e\n\u003cp\u003eI\u0026rsquo;m using \u003ca href=\"https://brew.sh\"\u003eHomebrew\u003c/a\u003e on macOS, but Poppler will also run on Linux and other operating systems.\u003c/p\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ brew install poppler\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003ch2 id=\"quick-usage\"\u003eQuick Usage\u003c/h2\u003e\n\u003cdiv class=\"highlight\"\u003e\u003cpre tabindex=\"0\" style=\"color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;\"\u003e\u003ccode class=\"language-shell\" data-lang=\"shell\"\u003e\u003cspan style=\"display:flex;\"\u003e\u003cspan\u003e$ pdftoppm -png -rx \u003cspan style=\"color:#ae81ff\"\u003e300\u003c/span\u003e -ry \u003cspan style=\"color:#ae81ff\"\u003e300\u003c/span\u003e input.pdf output\n\u003c/span\u003e\u003c/span\u003e\u003c/code\u003e\u003c/pre\u003e\u003c/div\u003e\u003cul\u003e\n\u003cli\u003e\u003ccode\u003e-png\u003c/code\u003e -\u0026gt; save the output files as PNG images\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003e-rx 300 -ry 300\u003c/code\u003e -\u0026gt; set the output resolution to 300 dpi\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003einput.pdf\u003c/code\u003e -\u0026gt; your source file which you want to process\u003c/li\u003e\n\u003cli\u003e\u003ccode\u003eoutput\u003c/code\u003e -\u0026gt; Your output file prefix which will produce \u003ccode\u003eoutput-1.png\u003c/code\u003e, \u003ccode\u003eoutput-2.png\u003c/code\u003e, \u0026hellip;\u003c/li\u003e\n\u003c/ul\u003e\n",
      "date_published": "2025-05-21T12:26:57-05:00",
      "id": "http://webology.micro.blog/2025/05/21/til-popplers-pdftoppm-to-convert/",
      "tags": [
        "Today I Learned"
      ],
      "title": "TIL Poppler's pdftoppm to convert PDF pages into PNG files",
      "url": "https://micro.webology.dev/2025/05/21/til-popplers-pdftoppm-to-convert/"
    },
    {
      "content_html": "\u003cp\u003eI miss Visual Basic. I could build something meaningful with it in 15 to 30 minutes in a way that I have never seen anything since then, even come close to.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003e\u0026ldquo;For example, I personally believe that Visual Basic did more for programming than Object-Oriented Languages did,\u0026rdquo; Torvalds wrote, \u0026ldquo;yet people laugh at VB and say it\u0026rsquo;s a bad language, and they\u0026rsquo;ve been talking about OO languages for decades. And no, Visual Basic wasn\u0026rsquo;t a great language, but I think the easy DB interfaces in VB were fundamentally more important than object orientation is, for example.\u0026rdquo;\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e\u003ca href=\"https://retool.com/visual-basic\"\u003eretool.com/visual-ba\u0026hellip;\u003c/a\u003e\u003c/p\u003e\n\u003cp\u003eVisual Basic 3 was the first programming language and application building framework that clicked with me. I never loved the language or the inconsistencies, but it just worked. I started with GW Basic, then Turbo Pascal in high school while prepping for college. My high school business teacher let me take an independent study where I made a simple video game in the spirit of Duck Hunt, where the Energizer bunny would explode into bloody bits when you clicked on it. She wasn\u0026rsquo;t prepared for that, and told me to spend the next half of the year just doing what I was doing.\u003c/p\u003e\n\u003cp\u003eVisual Basic 6 was the last version I used before Microsoft effectively killed it with .dot by trying to turn it into something it was not. I had already started writing more web/PHP code to avoid Delphi and .net/C# code.\u003c/p\u003e\n\u003cp\u003eTrying to build a Mac app today makes me sad. There isn\u0026rsquo;t a good visual way to create an app, which is both the strength and weakness of Visual Basic\u0026rsquo;s model. When you made a VB application, it looked like a Windows app. Anything I have ever dabbled with Xcode and other application frameworks looks like an unstyled/blank canvas, making me quickly feel fatigued.\u003c/p\u003e\n\u003cp\u003eI know several people are trying to build one of these apps using Python, but it still feels like the infamous owl drawing, where step #1 is too basic, and the final step is impossible to get to. I\u0026rsquo;m hoping that AI can help fill in the \u0026ldquo;how to draw the owl steps,\u0026rdquo; but my concern is that modern-day frameworks are an impossibly hard bar to maintain and worth it for someone like myself, who isn\u0026rsquo;t paid to work on them.\u003c/p\u003e\n\u003cp\u003eI love Python, but I miss Visual Basic.\u003c/p\u003e\n",
      "date_published": "2025-05-11T13:33:01-05:00",
      "id": "http://webology.micro.blog/2025/05/11/i-miss-visual-basic/",
      "tags": [
        "Python",
        "Today I Learned"
      ],
      "title": "🤷‍♂️ I miss Visual Basic",
      "url": "https://micro.webology.dev/2025/05/11/i-miss-visual-basic/"
    },
    {
      "content_html": "\u003cp\u003eThis Friday, I\u0026rsquo;m hosting a \u003cstrong\u003emorning edition\u003c/strong\u003e of my office hours, and here is my schedule for the rest of May:\u003c/p\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eFriday, May 9th, 2025, \u003cstrong\u003e8am to 10:30am\u003c/strong\u003e - 🌄 Early edition (\u003ca href=\"https://time.is/0800AM_09_May_2025_in_CT\"\u003eTime.is link for CT\u003c/a\u003e)\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFriday, May 16th, 2025: \u003cstrong\u003eNo office hours.\u003c/strong\u003e I\u0026rsquo;ll be at PyCon US.\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFriday, May 23rd, 2025, \u003cstrong\u003e2:30pm to 4:30pm\u003c/strong\u003e (\u003ca href=\"https://time.is/0230PM_23_May_2025_in_CT\"\u003eTime.is link for CT\u003c/a\u003e\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eFriday, May 30th, 2025, \u003cstrong\u003e2:30pm to 4:30pm\u003c/strong\u003e (\u003ca href=\"https://time.is/0230PM_30_May_2025_in_CT\"\u003eTime.is link for CT\u003c/a\u003e)\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003ch2 id=\"high-level-details\"\u003eHigh-level details\u003c/h2\u003e\n\u003cp\u003eℹ️ Anyone can join my office hours. Many join because they work remotely, miss seeing faces, and miss the random conversations when a small group hangs out.\u003c/p\u003e\n\u003cp\u003eℹ️ Our office hours are a collaborative space where we can discuss our ongoing projects, catch up, and work together to wrap up our week on a productive note.\u003c/p\u003e\n\u003cp\u003e🙏 As always, everyone is welcome to join, whether you’re a regular attendee or joining for the first time. If you are curious, reach out.\u003c/p\u003e\n\u003cp\u003e✅ If you need any additional details, feel free to send me a message or check out the gist from our previous sessions, where you’ll always find the most recent Zoom link ⚠️\u003c/p\u003e\n",
      "date_published": "2025-05-08T15:19:54-05:00",
      "id": "http://webology.micro.blog/2025/05/08/office-hours-for-may/",
      "tags": [
        "Office Hours"
      ],
      "title": "🗓️ Office Hours for May 2025",
      "url": "https://micro.webology.dev/2025/05/08/office-hours-for-may/"
    },
    {
      "content_html": "\u003cp\u003eI recently came across \u003ca href=\"https://simonwillison.net/2025/Apr/23/diane/\"\u003eSimon Willison\u0026rsquo;s post\u003c/a\u003e about Matt Webb\u0026rsquo;s Apple Watch dictation setup on \u003ca href=\"https://interconnected.org/home/2025/03/20/diane\"\u003eInterconnected\u003c/a\u003e. He records voice notes while running with the Whisper Memos app, then cleans up the transcript with Claude when he gets home.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eMatt Webb dictates notes into his Apple Watch while out running (using the new-to-me \u003ca href=\"https://whispermemos.com/\"\u003eWhisper Memos\u003c/a\u003e app), then runs the transcript through Claude to tidy it up when he gets home.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eMatt\u0026rsquo;s usage of Diane is a neat trick that allows him to embed instructions while recording his notes while running. While I used to be in good enough shape to talk while running, the idea of dictating lectures is wild.\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eMy generic prompt to Claude, used every time, is now:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eyou are Diane, my secretary. please take this raw verbal transcript and clean it up. do not add any of your own material. because you are Diane, also follow any instructions addressed to you in the transcript and perform those instructions\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003e[paste in transcript]\u003c/p\u003e\n\u003cp\u003eWhich means, when I\u0026rsquo;m talking through my lecture outline, I now finish by saying:\u003c/p\u003e\n\u003cblockquote\u003e\n\u003cp\u003eok Diane I think that\u0026rsquo;s it. it\u0026rsquo;s a talk, so please structure all of that into a high level outline so I can work on it. thanks.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eAnd I can mix in instructions like: \u003cem\u003eoh Diane I meant to include that point in the last section. Please move it.\u003c/em\u003e\u003c/p\u003e\n\u003cp\u003eIt works super well.\u003c/p\u003e\n\u003c/blockquote\u003e\n\u003cp\u003eThat inspired me to share the workflow I\u0026rsquo;ve been using for years.\u003c/p\u003e\n\u003ch2 id=\"tldr-my-workflow\"\u003etl;dr My Workflow\u003c/h2\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cp\u003eRecord thoughts with Apple Voice Memos on my iPhone using AirPods\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eDrag the audio file into MacWhisper to get a raw transcript\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eCopy the raw transcript into Obsidian as my writing buffer before and after each of the next steps\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ePaste the transcript into ChatGPT for cleanup\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003eRun the text through Grammarly to spot grammar and style issues\u003c/p\u003e\n\u003c/li\u003e\n\u003cli\u003e\n\u003cp\u003ePublish or iterate as needed\u003c/p\u003e\n\u003c/li\u003e\n\u003c/ul\u003e\n\u003chr\u003e\n\u003ch2 id=\"apple-voice-memos\"\u003eApple Voice Memos\u003c/h2\u003e\n\u003cp\u003eI use Apple Voice Memos on iOS, iPadOS, or macOS to capture ideas on the go. It syncs instantly across devices, so the recording is ready by the time I\u0026rsquo;m at my desk.\u003c/p\u003e\n\u003ch2 id=\"macwhisper\"\u003eMacWhisper\u003c/h2\u003e\n\u003cp\u003eOf all the transcription tools I\u0026rsquo;ve tried, \u003ca href=\"https://goodsnooze.gumroad.com/l/macwhisper\"\u003eMacWhisper\u003c/a\u003e is the most reliable. Once I\u0026rsquo;m at my Mac, I open Voice Memos, drag the file into MacWhisper, and it produces a transcript in seconds. MacWhisper is now available in the Mac App Store.\u003c/p\u003e\n\u003cp\u003eThere is even an iOS version called \u003ca href=\"https://apps.apple.com/nl/app/whisper-transcription/id6738070552?l=en-GB\u0026amp;mt=12\"\u003eWhisper Transcription\u003c/a\u003e, which I have been trying out for the last few weeks. It has the advantage of allowing me to record directly into the app and then copy the transcript into something else. This is fine, but I haven\u0026rsquo;t found an option to save the audio file, which is concerning if my transcript gets too long.\u003c/p\u003e\n\u003ch2 id=\"chatgpt\"\u003eChatGPT\u003c/h2\u003e\n\u003cp\u003eNext, I paste the raw transcript into ChatGPT to clean up filler words and pauses. My usual prompt looks like this:\u003c/p\u003e\n\u003cpre tabindex=\"0\"\u003e\u003ccode\u003ePlease tidy up these voice notes. Remove any ums, ahs, and awkward pauses.\r\n\r\n\u0026lt;notes\u0026gt;\r\n...\r\n\u0026lt;/notes\u0026gt;\r\n\r\n\u0026lt;instructions\u0026gt;\r\n- Use my words and keep the spirit of my text\r\n- Avoid using en dashes or em dashes\r\n- ... your custom instructions to clean up your habits...\r\n\u0026lt;/instructions\u0026gt;\n\u003c/code\u003e\u003c/pre\u003e\u003ch2 id=\"grammarly\"\u003eGrammarly\u003c/h2\u003e\n\u003cp\u003eAfter ChatGPT, I paste the text into the Grammarly app. As someone with dyslexia, Grammarly Pro helps me catch grammar mistakes and awkward phrasing so I can write in minutes, which used to take hours.\u003c/p\u003e\n\u003ch2 id=\"obsidian\"\u003eObsidian\u003c/h2\u003e\n\u003cp\u003eI copy the cleaned text into Obsidian. This step resolves formatting glitches from moving text between ChatGPT and Grammarly and allows me to make final tweaks.\u003c/p\u003e\n\u003ch2 id=\"publishing\"\u003ePublishing\u003c/h2\u003e\n\u003cp\u003eWhen I\u0026rsquo;m satisfied with the draft, I publish it. If it needs more work, I\u0026rsquo;ll run another quick round through ChatGPT and Grammarly until it\u0026rsquo;s ready.\u003c/p\u003e\n\u003ch2 id=\"improvements\"\u003eImprovements\u003c/h2\u003e\n\u003cp\u003eI have been trying out \u003ca href=\"https://apps.apple.com/nl/app/whisper-transcription/id6738070552?l=en-GB\u0026amp;mt=12\"\u003eWhisper Transcription\u003c/a\u003e to skip a few steps by letting me record on my iPhone while sending the finished transcript to Obsidian or ChatGPT directly.\u003c/p\u003e\n\u003cp\u003eI also want to add Matt\u0026rsquo;s \u0026ldquo;Diane\u0026rdquo; dictation trick with a more gender-neutral name, or maybe I\u0026rsquo;ll default to using \u0026ldquo;Simon\u0026rdquo; since I\u0026rsquo;m already using a half-dozen of Simon Willison\u0026rsquo;s AI/LLM tooling.\u003c/p\u003e\n\u003cp\u003eI\u0026rsquo;m already using AI and \u003ca href=\"https://github.com/simonw/llm\"\u003eLLM\u003c/a\u003e for many big and small tasks, so devising a more automated cleanup and preparation workflow shouldn\u0026rsquo;t be a big lift.\u003c/p\u003e\n",
      "date_published": "2025-04-30T18:41:51-05:00",
      "id": "http://webology.micro.blog/2025/04/30/voice-dictation-with-ai-and/",
      "tags": [
        "LLM",
        "Today I Learned"
      ],
      "title": "🤖 Voice Dictation with AI and my MacWhisper Workflow",
      "url": "https://micro.webology.dev/2025/04/30/voice-dictation-with-ai-and/"
    }
  ],
  "title": "Jeff Triplett's Micro.blog",
  "version": "https://jsonfeed.org/version/1"
}