<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Claude-Code on Nick Liu - Software Engineer</title>
    <link>https://nick-liu.com/tags/claude-code/</link>
    <description>Recent content in Claude-Code on Nick Liu - Software Engineer</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <managingEditor>nickboy@users.noreply.github.com (Nick Liu)</managingEditor>
    <webMaster>nickboy@users.noreply.github.com (Nick Liu)</webMaster>
    <copyright>2026 Nick Liu</copyright>
    <lastBuildDate>Fri, 10 Jul 2026 20:05:23 -0700</lastBuildDate><atom:link href="https://nick-liu.com/tags/claude-code/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Running Several AI Coding Agents Without Losing Track</title>
      <link>https://nick-liu.com/posts/managing-many-ai-agents/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <author>nickboy@users.noreply.github.com (Nick Liu)</author>
      <guid>https://nick-liu.com/posts/managing-many-ai-agents/</guid>
      <description>&lt;div class=&#34;lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl&#34;&gt;&#xA;  &#xA;Once you&#39;re comfortable with AI coding agents, you start running several at once: one refactoring here, one writing tests there, one stuck waiting for your approval. Keeping them straight is its own little skill.&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;nav class=&#34;series-progress&#34; aria-label=&#34;Series progress&#34;&gt;&#xA;    &lt;span class=&#34;series-progress-label&#34;&gt;Taming Claude Code Sessions · Part 4 of 4&lt;/span&gt;&#xA;    &lt;ol class=&#34;series-progress-dots&#34;&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/find-claude-code-sessions/&#34; title=&#34;Stop Losing Your Claude Code Conversations&#34;&gt;1&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/first-claude-code-hook/&#34; title=&#34;Your First Claude Code Hook: Auto-Name Every Session&#34;&gt;2&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/tmux-window-titles/&#34; title=&#34;Make tmux Show What Each Window Is Doing&#34;&gt;3&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-current&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/managing-many-ai-agents/&#34; title=&#34;Running Several AI Coding Agents Without Losing Track&#34; aria-current=&#34;step&#34;&gt;4&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;/ol&gt;&#xA;  &lt;/nav&gt;&#xA;&lt;div class=&#34;tested-with&#34; role=&#34;note&#34;&gt;&#xA;  &lt;span class=&#34;tested-with-icon&#34; aria-hidden=&#34;true&#34;&gt;🧪&lt;/span&gt;&#xA;  &lt;span&gt;Tested with &lt;strong&gt;Claude Code&lt;/strong&gt; &lt;code&gt;2.1.x&lt;/code&gt; · macOS / Linux&lt;/span&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;Here are two ways to do it: a lightweight tmux plugin, and (briefly) dedicated&#xA;&amp;ldquo;AI terminal&amp;rdquo; apps.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Stop Losing Your Claude Code Conversations</title>
      <link>https://nick-liu.com/posts/find-claude-code-sessions/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <author>nickboy@users.noreply.github.com (Nick Liu)</author>
      <guid>https://nick-liu.com/posts/find-claude-code-sessions/</guid>
      <description>&lt;div class=&#34;lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl&#34;&gt;&#xA;  &#xA;You&#39;re deep in a great Claude Code conversation. You close the terminal. The next day you want to pick up where you left off… and you can&#39;t find it. Sound familiar? Let&#39;s fix that.&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;nav class=&#34;series-progress&#34; aria-label=&#34;Series progress&#34;&gt;&#xA;    &lt;span class=&#34;series-progress-label&#34;&gt;Taming Claude Code Sessions · Part 1 of 4&lt;/span&gt;&#xA;    &lt;ol class=&#34;series-progress-dots&#34;&gt;&lt;li class=&#34;series-progress-dot is-current&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/find-claude-code-sessions/&#34; title=&#34;Stop Losing Your Claude Code Conversations&#34; aria-current=&#34;step&#34;&gt;1&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/first-claude-code-hook/&#34; title=&#34;Your First Claude Code Hook: Auto-Name Every Session&#34;&gt;2&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/tmux-window-titles/&#34; title=&#34;Make tmux Show What Each Window Is Doing&#34;&gt;3&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/managing-many-ai-agents/&#34; title=&#34;Running Several AI Coding Agents Without Losing Track&#34;&gt;4&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;/ol&gt;&#xA;  &lt;/nav&gt;&#xA;&lt;div class=&#34;tested-with&#34; role=&#34;note&#34;&gt;&#xA;  &lt;span class=&#34;tested-with-icon&#34; aria-hidden=&#34;true&#34;&gt;🧪&lt;/span&gt;&#xA;  &lt;span&gt;Tested with &lt;strong&gt;Claude Code&lt;/strong&gt; &lt;code&gt;2.1.x&lt;/code&gt; · macOS / Linux&lt;/span&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&#xA;&lt;h2 class=&#34;relative group&#34;&gt;What is a &amp;ldquo;session,&amp;rdquo; and where does it go?&#xA;    &lt;div id=&#34;what-is-a-session-and-where-does-it-go&#34; class=&#34;anchor&#34;&gt;&lt;/div&gt;&#xA;    &#xA;    &lt;span&#xA;        class=&#34;absolute top-0 w-6 transition-opacity opacity-0 -start-6 not-prose group-hover:opacity-100 select-none&#34;&gt;&#xA;        &lt;a class=&#34;text-primary-300 dark:text-neutral-700 !no-underline&#34; href=&#34;#what-is-a-session-and-where-does-it-go&#34; aria-label=&#34;Anchor&#34;&gt;#&lt;/a&gt;&#xA;    &lt;/span&gt;&#xA;    &#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Every time you run &lt;code&gt;claude&lt;/code&gt;, you start a &lt;strong&gt;session&lt;/strong&gt;, one conversation, with&#xA;its full history. When you quit, that history doesn&amp;rsquo;t vanish. Claude Code saves&#xA;it to disk, organized &lt;strong&gt;per project folder&lt;/strong&gt;, here:&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Your First Claude Code Hook: Auto-Name Every Session</title>
      <link>https://nick-liu.com/posts/first-claude-code-hook/</link>
      <pubDate>Sun, 21 Jun 2026 00:00:00 +0000</pubDate>
      <author>nickboy@users.noreply.github.com (Nick Liu)</author>
      <guid>https://nick-liu.com/posts/first-claude-code-hook/</guid>
      <description>&lt;div class=&#34;lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl&#34;&gt;&#xA;  &#xA;In Part 1 we learned that named sessions are easy to find. Now let&#39;s make naming automatic with a hook. This is also a perfect first hook project, so I&#39;ll explain the whole idea from scratch.&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;nav class=&#34;series-progress&#34; aria-label=&#34;Series progress&#34;&gt;&#xA;    &lt;span class=&#34;series-progress-label&#34;&gt;Taming Claude Code Sessions · Part 2 of 4&lt;/span&gt;&#xA;    &lt;ol class=&#34;series-progress-dots&#34;&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/find-claude-code-sessions/&#34; title=&#34;Stop Losing Your Claude Code Conversations&#34;&gt;1&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-current&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/first-claude-code-hook/&#34; title=&#34;Your First Claude Code Hook: Auto-Name Every Session&#34; aria-current=&#34;step&#34;&gt;2&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/tmux-window-titles/&#34; title=&#34;Make tmux Show What Each Window Is Doing&#34;&gt;3&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/managing-many-ai-agents/&#34; title=&#34;Running Several AI Coding Agents Without Losing Track&#34;&gt;4&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;/ol&gt;&#xA;  &lt;/nav&gt;&#xA;&lt;div class=&#34;tested-with&#34; role=&#34;note&#34;&gt;&#xA;  &lt;span class=&#34;tested-with-icon&#34; aria-hidden=&#34;true&#34;&gt;🧪&lt;/span&gt;&#xA;  &lt;span&gt;Tested with &lt;strong&gt;Claude Code&lt;/strong&gt; &lt;code&gt;2.1.x&lt;/code&gt; · macOS / Linux&lt;/span&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;&lt;a href=&#34;https://nick-liu.com/posts/find-claude-code-sessions/&#34; &gt;Part 1&lt;/a&gt; left us with one chore: you still&#xA;have to remember to name your sessions. Let&amp;rsquo;s delete that chore.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Claude Code vs Cursor vs Copilot vs Windsurf: An Honest 2026 Comparison</title>
      <link>https://nick-liu.com/posts/vibe-coding-tools-compared/</link>
      <pubDate>Sun, 10 May 2026 00:00:00 +0000</pubDate>
      <author>nickboy@users.noreply.github.com (Nick Liu)</author>
      <guid>https://nick-liu.com/posts/vibe-coding-tools-compared/</guid>
      <description>&lt;div class=&#34;lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl&#34;&gt;&#xA;  &#xA;The AI coding tool landscape in 2026 has finally settled into four serious players: &lt;span class=&#34;flex cursor-pointer&#34;&gt;&#xA;  &#xA;  &#xA;  &#xA;  &#xA;    &lt;span&#xA;      class=&#34;rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400&#34;&gt;&#xA;  &#xA;    Claude Code&#xA;  &lt;/span&gt;&#xA;&lt;/span&gt;&#xA;&#xA;, &lt;span class=&#34;flex cursor-pointer&#34;&gt;&#xA;  &#xA;  &#xA;  &#xA;  &#xA;    &lt;span&#xA;      class=&#34;rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400&#34;&gt;&#xA;  &#xA;    Cursor&#xA;  &lt;/span&gt;&#xA;&lt;/span&gt;&#xA;&#xA;, &lt;span class=&#34;flex cursor-pointer&#34;&gt;&#xA;  &#xA;  &#xA;  &#xA;  &#xA;    &lt;span&#xA;      class=&#34;rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400&#34;&gt;&#xA;  &#xA;    GitHub Copilot&#xA;  &lt;/span&gt;&#xA;&lt;/span&gt;&#xA;&#xA;, and &lt;span class=&#34;flex cursor-pointer&#34;&gt;&#xA;  &#xA;  &#xA;  &#xA;  &#xA;    &lt;span&#xA;      class=&#34;rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400&#34;&gt;&#xA;  &#xA;    Windsurf&#xA;  &lt;/span&gt;&#xA;&lt;/span&gt;&#xA;&#xA;. I&#39;ve used all four on real work. This is the honest comparison.&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;Forget feature checklists. What matters is how each tool feels under real engineering work, the kind I do every day as a senior software engineer at Meta. I built &lt;a href=&#34;https://nick-liu.com/posts/vibe-coding-workflow/&#34; &gt;this site&lt;/a&gt; primarily with Claude Code, but I&amp;rsquo;ve put serious hours into the others.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Holding HTTP open for 590 seconds so a Stream Deck key can approve a tool call</title>
      <link>https://nick-liu.com/posts/permission-round-trip/</link>
      <pubDate>Sun, 10 May 2026 00:00:00 +0000</pubDate>
      <author>nickboy@users.noreply.github.com (Nick Liu)</author>
      <guid>https://nick-liu.com/posts/permission-round-trip/</guid>
      <description>&lt;div class=&#34;lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl&#34;&gt;&#xA;  &#xA;Claude Code wants to run a shell command. I want to press a physical Stream Deck key, the YES key two inches to the left of my keyboard, to approve it. The hook gets exactly one HTTP response to decide allow vs deny. The key press might land in 200 milliseconds; it might land seven minutes later, after I&#39;ve been pulled into a meeting and come back. The trick is that Claude Code&#39;s hook timeout is 600 seconds, which turns out to be just enough headroom to hold the HTTP response open the whole time and let a hardware button write the answer.&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;nav class=&#34;series-progress&#34; aria-label=&#34;Series progress&#34;&gt;&#xA;    &lt;span class=&#34;series-progress-label&#34;&gt;Building ClaudeDeck · Part 6 of 10&lt;/span&gt;&#xA;    &lt;ol class=&#34;series-progress-dots&#34;&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/claude-code-hooks-reality/&#34; title=&#34;The Claude Code hooks docs are wrong. Here&amp;#39;s what&amp;#39;s actually on the wire.&#34;&gt;1&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/streamdeck-sdk-quirks/&#34; title=&#34;Two Stream Deck SDK quirks that cost me a weekend&#34;&gt;2&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/lru-session-eviction/&#34; title=&#34;Five Stream Deck keys, N Claude sessions: LRU that keeps the order I see&#34;&gt;3&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/statusline-side-channel/&#34; title=&#34;The Claude Code statusline is a per-turn telemetry side channel&#34;&gt;4&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/plan-usage-statusline-pivot/&#34; title=&#34;I polled an undocumented endpoint for 18 hours. The data was on stdin.&#34;&gt;5&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-current&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/permission-round-trip/&#34; title=&#34;Holding HTTP open for 590 seconds so a Stream Deck key can approve a tool call&#34; aria-current=&#34;step&#34;&gt;6&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/pty-wrap-migration/&#34; title=&#34;I split my daemon in two so a Node subprocess could own the PTY&#34;&gt;7&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/tcc-cdhash-trap/&#34; title=&#34;TCC pins your Accessibility grant to a cdhash. Every rebuild breaks it.&#34;&gt;8&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/tahoe-hotkey-dead-end/&#34; title=&#34;What replaced CGEventPost in my Stream Deck daemon&#34;&gt;9&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/launchd-bootstrap-debugging/&#34; title=&#34;launchctl unload returned 0. The daemon was still running. KeepAlive raced.&#34;&gt;10&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;/ol&gt;&#xA;  &lt;/nav&gt;&#xA;&lt;div class=&#34;tested-with&#34; role=&#34;note&#34;&gt;&#xA;  &lt;span class=&#34;tested-with-icon&#34; aria-hidden=&#34;true&#34;&gt;🧪&lt;/span&gt;&#xA;  &lt;span&gt;Tested with &lt;strong&gt;Claude Code&lt;/strong&gt; &lt;code&gt;2.1.x&lt;/code&gt; · macOS&lt;/span&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;(Setup, for anyone who hasn&amp;rsquo;t seen this stack before: Claude Code is Anthropic&amp;rsquo;s terminal CLI for Claude, and one of its hook events, &lt;code&gt;PreToolUse&lt;/code&gt;, is a script Claude spawns and waits on before running a tool like &lt;code&gt;Bash&lt;/code&gt; or &lt;code&gt;Edit&lt;/code&gt;. The script&amp;rsquo;s stdout decides &amp;ldquo;allow&amp;rdquo; / &amp;ldquo;deny&amp;rdquo; / &amp;ldquo;ask&amp;rdquo;. Stream Deck is Elgato&amp;rsquo;s USB grid of programmable LCD keys. The plumbing I&amp;rsquo;m describing here lives in a daemon, a background process at &lt;code&gt;127.0.0.1:9127&lt;/code&gt;, that the hook script POSTs to and that the Stream Deck plugin connects to over WebSocket. For the hooks docs themselves and the four other gotchas in that layer, see &lt;a href=&#34;https://nick-liu.com/posts/claude-code-hooks-reality/&#34; &gt;the hooks-reality post&lt;/a&gt;.)&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>I polled an undocumented endpoint for 18 hours. The data was on stdin.</title>
      <link>https://nick-liu.com/posts/plan-usage-statusline-pivot/</link>
      <pubDate>Sun, 10 May 2026 00:00:00 +0000</pubDate>
      <author>nickboy@users.noreply.github.com (Nick Liu)</author>
      <guid>https://nick-liu.com/posts/plan-usage-statusline-pivot/</guid>
      <description>&lt;div class=&#34;lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl&#34;&gt;&#xA;  &#xA;My daemon logged 111 consecutive HTTP 429s against `https://api.anthropic.com/api/oauth/usage` over an 18-hour stretch, with zero successful responses ever in its lifetime. The poller was reading `Retry-After: 272` and ignoring it. While I was arguing with the backoff, Claude Code was pushing the same `rate_limits.five_hour` and `rate_limits.seven_day` numbers to my statusline command every turn, on stdin, for free.&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;nav class=&#34;series-progress&#34; aria-label=&#34;Series progress&#34;&gt;&#xA;    &lt;span class=&#34;series-progress-label&#34;&gt;Building ClaudeDeck · Part 5 of 10&lt;/span&gt;&#xA;    &lt;ol class=&#34;series-progress-dots&#34;&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/claude-code-hooks-reality/&#34; title=&#34;The Claude Code hooks docs are wrong. Here&amp;#39;s what&amp;#39;s actually on the wire.&#34;&gt;1&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/streamdeck-sdk-quirks/&#34; title=&#34;Two Stream Deck SDK quirks that cost me a weekend&#34;&gt;2&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/lru-session-eviction/&#34; title=&#34;Five Stream Deck keys, N Claude sessions: LRU that keeps the order I see&#34;&gt;3&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/statusline-side-channel/&#34; title=&#34;The Claude Code statusline is a per-turn telemetry side channel&#34;&gt;4&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-current&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/plan-usage-statusline-pivot/&#34; title=&#34;I polled an undocumented endpoint for 18 hours. The data was on stdin.&#34; aria-current=&#34;step&#34;&gt;5&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/permission-round-trip/&#34; title=&#34;Holding HTTP open for 590 seconds so a Stream Deck key can approve a tool call&#34;&gt;6&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/pty-wrap-migration/&#34; title=&#34;I split my daemon in two so a Node subprocess could own the PTY&#34;&gt;7&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/tcc-cdhash-trap/&#34; title=&#34;TCC pins your Accessibility grant to a cdhash. Every rebuild breaks it.&#34;&gt;8&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/tahoe-hotkey-dead-end/&#34; title=&#34;What replaced CGEventPost in my Stream Deck daemon&#34;&gt;9&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/launchd-bootstrap-debugging/&#34; title=&#34;launchctl unload returned 0. The daemon was still running. KeepAlive raced.&#34;&gt;10&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;/ol&gt;&#xA;  &lt;/nav&gt;&#xA;&lt;div class=&#34;tested-with&#34; role=&#34;note&#34;&gt;&#xA;  &lt;span class=&#34;tested-with-icon&#34; aria-hidden=&#34;true&#34;&gt;🧪&lt;/span&gt;&#xA;  &lt;span&gt;Tested with &lt;strong&gt;Claude Code&lt;/strong&gt; &lt;code&gt;2.1.x&lt;/code&gt; · macOS&lt;/span&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;(Quick framing: &lt;em&gt;Claude Code&lt;/em&gt; is Anthropic&amp;rsquo;s terminal CLI for Claude; &lt;em&gt;Claude Max&lt;/em&gt; is the higher-tier subscription plan with weekly and 5-hour usage windows. HTTP &lt;em&gt;429&lt;/em&gt; is &amp;ldquo;Too Many Requests&amp;rdquo;, the server&amp;rsquo;s polite way of saying &amp;ldquo;back off.&amp;rdquo; &lt;em&gt;Retry-After&lt;/em&gt; is the response header that tells the client how long to wait. &lt;em&gt;OAuth&lt;/em&gt; is the auth protocol Claude Code uses to talk to Anthropic on behalf of a logged-in user. And the &lt;em&gt;statusline&lt;/em&gt; (the same one I covered in &lt;a href=&#34;https://nick-liu.com/posts/statusline-side-channel/&#34; &gt;the statusline side-channel post&lt;/a&gt;) is the script Claude Code spawns every turn with a JSON blob on stdin.)&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>I split my daemon in two so a Node subprocess could own the PTY</title>
      <link>https://nick-liu.com/posts/pty-wrap-migration/</link>
      <pubDate>Sun, 10 May 2026 00:00:00 +0000</pubDate>
      <author>nickboy@users.noreply.github.com (Nick Liu)</author>
      <guid>https://nick-liu.com/posts/pty-wrap-migration/</guid>
      <description>&lt;div class=&#34;lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl&#34;&gt;&#xA;  &#xA;I built a Claude Code permission gate that holds an HTTP response open until a Stream Deck key is pressed. Then I needed to inject a keystroke into Claude Code&#39;s own TTY so a key press could write `1\r` straight into Claude&#39;s stdin. Bun can hold HTTP open all day. Bun cannot reliably wrap a child PTY through `node-pty` and capture the parent shell&#39;s PID. So I split my daemon: HTTP and WebSocket stay on Bun, and a Node CommonJS subprocess owns the PTY that runs Claude.&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;nav class=&#34;series-progress&#34; aria-label=&#34;Series progress&#34;&gt;&#xA;    &lt;span class=&#34;series-progress-label&#34;&gt;Building ClaudeDeck · Part 7 of 10&lt;/span&gt;&#xA;    &lt;ol class=&#34;series-progress-dots&#34;&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/claude-code-hooks-reality/&#34; title=&#34;The Claude Code hooks docs are wrong. Here&amp;#39;s what&amp;#39;s actually on the wire.&#34;&gt;1&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/streamdeck-sdk-quirks/&#34; title=&#34;Two Stream Deck SDK quirks that cost me a weekend&#34;&gt;2&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/lru-session-eviction/&#34; title=&#34;Five Stream Deck keys, N Claude sessions: LRU that keeps the order I see&#34;&gt;3&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/statusline-side-channel/&#34; title=&#34;The Claude Code statusline is a per-turn telemetry side channel&#34;&gt;4&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/plan-usage-statusline-pivot/&#34; title=&#34;I polled an undocumented endpoint for 18 hours. The data was on stdin.&#34;&gt;5&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/permission-round-trip/&#34; title=&#34;Holding HTTP open for 590 seconds so a Stream Deck key can approve a tool call&#34;&gt;6&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-current&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/pty-wrap-migration/&#34; title=&#34;I split my daemon in two so a Node subprocess could own the PTY&#34; aria-current=&#34;step&#34;&gt;7&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/tcc-cdhash-trap/&#34; title=&#34;TCC pins your Accessibility grant to a cdhash. Every rebuild breaks it.&#34;&gt;8&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/tahoe-hotkey-dead-end/&#34; title=&#34;What replaced CGEventPost in my Stream Deck daemon&#34;&gt;9&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/launchd-bootstrap-debugging/&#34; title=&#34;launchctl unload returned 0. The daemon was still running. KeepAlive raced.&#34;&gt;10&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;/ol&gt;&#xA;  &lt;/nav&gt;&#xA;&lt;div class=&#34;tested-with&#34; role=&#34;note&#34;&gt;&#xA;  &lt;span class=&#34;tested-with-icon&#34; aria-hidden=&#34;true&#34;&gt;🧪&lt;/span&gt;&#xA;  &lt;span&gt;Tested with &lt;strong&gt;Claude Code&lt;/strong&gt; &lt;code&gt;2.1.x&lt;/code&gt; · macOS&lt;/span&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;(Quick grounding before the story: a &lt;em&gt;PTY&lt;/em&gt; (pseudo-terminal) is the kernel object every interactive shell talks to. It&amp;rsquo;s a pair of file descriptors, master and slave; the program reads/writes the slave end as if it were a real terminal, and anything you write to the master end looks to that program like a human typing. The &lt;em&gt;TTY&lt;/em&gt; is the slave end seen from the child&amp;rsquo;s side. &lt;code&gt;node-pty&lt;/code&gt; is Microsoft&amp;rsquo;s library that gives a JavaScript parent process a writable handle to the master. &lt;em&gt;Bun&lt;/em&gt; is a JavaScript runtime, Node&amp;rsquo;s faster sibling, and &lt;em&gt;Node CommonJS&lt;/em&gt; is plain old &lt;code&gt;require()&lt;/code&gt;-based Node, no transpile step. The story below is about which runtime owns the PTY.)&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>My Vibe Coding Workflow: How I Built This Site with Claude Code</title>
      <link>https://nick-liu.com/posts/vibe-coding-workflow/</link>
      <pubDate>Sun, 10 May 2026 00:00:00 +0000</pubDate>
      <author>nickboy@users.noreply.github.com (Nick Liu)</author>
      <guid>https://nick-liu.com/posts/vibe-coding-workflow/</guid>
      <description>&lt;div class=&#34;lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl&#34;&gt;&#xA;  &#xA;I rebuilt my portfolio site in a weekend using vibe coding with &lt;span class=&#34;flex cursor-pointer&#34;&gt;&#xA;  &#xA;  &#xA;  &#xA;  &#xA;    &lt;span&#xA;      class=&#34;rounded-md border border-primary-400 px-1 py-[1px] text-xs font-normal text-primary-700 dark:border-primary-600 dark:text-primary-400&#34;&gt;&#xA;  &#xA;    Claude Code&#xA;  &lt;/span&gt;&#xA;&lt;/span&gt;&#xA;&#xA;. This is the real workflow, no hype, with honest tradeoffs.&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;Andrej Karpathy coined &amp;ldquo;vibe coding&amp;rdquo; in early 2025. The pitch: describe what you want in natural language, let the AI write the code, spend your time directing instead of typing. Collins Dictionary named it Word of the Year. Most takes on it are either breathless hype or dismissive eye-rolls. Here&amp;rsquo;s what it looks like when a senior engineer uses it for a real project.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>The Claude Code hooks docs are wrong. Here&#39;s what&#39;s actually on the wire.</title>
      <link>https://nick-liu.com/posts/claude-code-hooks-reality/</link>
      <pubDate>Sun, 10 May 2026 00:00:00 +0000</pubDate>
      <author>nickboy@users.noreply.github.com (Nick Liu)</author>
      <guid>https://nick-liu.com/posts/claude-code-hooks-reality/</guid>
      <description>&lt;div class=&#34;lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl&#34;&gt;&#xA;  &#xA;I wrote a daemon to listen to Claude Code hooks. My first version read `$CLAUDE_HOOK_PAYLOAD` and logged empty bodies for two days straight. The payload was sitting on stdin the whole time.&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;nav class=&#34;series-progress&#34; aria-label=&#34;Series progress&#34;&gt;&#xA;    &lt;span class=&#34;series-progress-label&#34;&gt;Building ClaudeDeck · Part 1 of 10&lt;/span&gt;&#xA;    &lt;ol class=&#34;series-progress-dots&#34;&gt;&lt;li class=&#34;series-progress-dot is-current&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/claude-code-hooks-reality/&#34; title=&#34;The Claude Code hooks docs are wrong. Here&amp;#39;s what&amp;#39;s actually on the wire.&#34; aria-current=&#34;step&#34;&gt;1&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/streamdeck-sdk-quirks/&#34; title=&#34;Two Stream Deck SDK quirks that cost me a weekend&#34;&gt;2&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/lru-session-eviction/&#34; title=&#34;Five Stream Deck keys, N Claude sessions: LRU that keeps the order I see&#34;&gt;3&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/statusline-side-channel/&#34; title=&#34;The Claude Code statusline is a per-turn telemetry side channel&#34;&gt;4&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/plan-usage-statusline-pivot/&#34; title=&#34;I polled an undocumented endpoint for 18 hours. The data was on stdin.&#34;&gt;5&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/permission-round-trip/&#34; title=&#34;Holding HTTP open for 590 seconds so a Stream Deck key can approve a tool call&#34;&gt;6&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/pty-wrap-migration/&#34; title=&#34;I split my daemon in two so a Node subprocess could own the PTY&#34;&gt;7&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/tcc-cdhash-trap/&#34; title=&#34;TCC pins your Accessibility grant to a cdhash. Every rebuild breaks it.&#34;&gt;8&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/tahoe-hotkey-dead-end/&#34; title=&#34;What replaced CGEventPost in my Stream Deck daemon&#34;&gt;9&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/launchd-bootstrap-debugging/&#34; title=&#34;launchctl unload returned 0. The daemon was still running. KeepAlive raced.&#34;&gt;10&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;/ol&gt;&#xA;  &lt;/nav&gt;&#xA;&lt;div class=&#34;tested-with&#34; role=&#34;note&#34;&gt;&#xA;  &lt;span class=&#34;tested-with-icon&#34; aria-hidden=&#34;true&#34;&gt;🧪&lt;/span&gt;&#xA;  &lt;span&gt;Tested with &lt;strong&gt;Claude Code&lt;/strong&gt; &lt;code&gt;2.1.x&lt;/code&gt; · macOS&lt;/span&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;This post is the five gotchas I hit while wiring up &lt;a href=&#34;https://github.com/nickboy/claudedeck&#34;  target=&#34;_blank&#34; rel=&#34;noreferrer&#34;&gt;ClaudeDeck&lt;/a&gt;, a Stream Deck plugin (a small program that runs inside Elgato&amp;rsquo;s Stream Deck app on the USB grid of programmable LCD keys) that talks to Claude Code over its hooks system. Claude Code is Anthropic&amp;rsquo;s terminal CLI for Claude (&lt;code&gt;claude&lt;/code&gt; in your shell), and its hooks are user-defined scripts it spawns at certain points in a session (before a tool call, on session start, on prompt submit). My daemon is a long-running background process the plugin and the hooks both talk to over a local socket. None of the gotchas are exotic. All of them cost me hours. Each one is a place where the docs were either silent, ambiguous, or contradicted by tribal knowledge I picked up from other people&amp;rsquo;s projects.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>The Claude Code statusline is a per-turn telemetry side channel</title>
      <link>https://nick-liu.com/posts/statusline-side-channel/</link>
      <pubDate>Sun, 10 May 2026 00:00:00 +0000</pubDate>
      <author>nickboy@users.noreply.github.com (Nick Liu)</author>
      <guid>https://nick-liu.com/posts/statusline-side-channel/</guid>
      <description>&lt;div class=&#34;lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl&#34;&gt;&#xA;  &#xA;Claude Code calls a custom statusline command every turn with a JSON payload on stdin. The payload includes the current context-window fill percentage, model, cost, and cwd. Nothing in the contract says you can only read it, and you can fork it to anything you want while the command stays a statusline.&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;nav class=&#34;series-progress&#34; aria-label=&#34;Series progress&#34;&gt;&#xA;    &lt;span class=&#34;series-progress-label&#34;&gt;Building ClaudeDeck · Part 4 of 10&lt;/span&gt;&#xA;    &lt;ol class=&#34;series-progress-dots&#34;&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/claude-code-hooks-reality/&#34; title=&#34;The Claude Code hooks docs are wrong. Here&amp;#39;s what&amp;#39;s actually on the wire.&#34;&gt;1&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/streamdeck-sdk-quirks/&#34; title=&#34;Two Stream Deck SDK quirks that cost me a weekend&#34;&gt;2&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-done&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/lru-session-eviction/&#34; title=&#34;Five Stream Deck keys, N Claude sessions: LRU that keeps the order I see&#34;&gt;3&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot is-current&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/statusline-side-channel/&#34; title=&#34;The Claude Code statusline is a per-turn telemetry side channel&#34; aria-current=&#34;step&#34;&gt;4&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/plan-usage-statusline-pivot/&#34; title=&#34;I polled an undocumented endpoint for 18 hours. The data was on stdin.&#34;&gt;5&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/permission-round-trip/&#34; title=&#34;Holding HTTP open for 590 seconds so a Stream Deck key can approve a tool call&#34;&gt;6&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/pty-wrap-migration/&#34; title=&#34;I split my daemon in two so a Node subprocess could own the PTY&#34;&gt;7&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/tcc-cdhash-trap/&#34; title=&#34;TCC pins your Accessibility grant to a cdhash. Every rebuild breaks it.&#34;&gt;8&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/tahoe-hotkey-dead-end/&#34; title=&#34;What replaced CGEventPost in my Stream Deck daemon&#34;&gt;9&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;li class=&#34;series-progress-dot&#34;&gt;&#xA;          &lt;a href=&#34;https://nick-liu.com/posts/launchd-bootstrap-debugging/&#34; title=&#34;launchctl unload returned 0. The daemon was still running. KeepAlive raced.&#34;&gt;10&lt;/a&gt;&#xA;        &lt;/li&gt;&lt;/ol&gt;&#xA;  &lt;/nav&gt;&#xA;&lt;div class=&#34;tested-with&#34; role=&#34;note&#34;&gt;&#xA;  &lt;span class=&#34;tested-with-icon&#34; aria-hidden=&#34;true&#34;&gt;🧪&lt;/span&gt;&#xA;  &lt;span&gt;Tested with &lt;strong&gt;Claude Code&lt;/strong&gt; &lt;code&gt;2.1.x&lt;/code&gt; · macOS&lt;/span&gt;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;(Quick framing for anyone new to Claude Code: it&amp;rsquo;s Anthropic&amp;rsquo;s terminal CLI for Claude, and the &lt;em&gt;statusline&lt;/em&gt; is the configurable line of text it prints under your prompt every turn, like a shell prompt for the agent. You point at any script in &lt;code&gt;settings.local.json&lt;/code&gt;, Claude pipes a JSON object to it on stdin, and whatever the script writes to stdout becomes the visible line.)&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Vibe Coding Won&#39;t Replace Senior Engineers. It Amplifies Them.</title>
      <link>https://nick-liu.com/posts/vibe-coding-senior-engineer/</link>
      <pubDate>Sun, 10 May 2026 00:00:00 +0000</pubDate>
      <author>nickboy@users.noreply.github.com (Nick Liu)</author>
      <guid>https://nick-liu.com/posts/vibe-coding-senior-engineer/</guid>
      <description>&lt;div class=&#34;lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl&#34;&gt;&#xA;  &#xA;The hype says anyone can code now. The reality: vibe coding changes *what* senior engineers do, not *whether* we&#39;re needed. And the gap between experienced and inexperienced developers is getting wider, not narrower.&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;Collins Dictionary named &amp;ldquo;vibe coding&amp;rdquo; their Word of the Year for 2025. Search interest spiked over 6,000%. The narrative is seductive: describe what you want, AI writes the code, programming becomes as easy as having a conversation.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>Building a Knowledge Base That AI Can Actually Use</title>
      <link>https://nick-liu.com/posts/obsidian-claude-code-knowledge-base/</link>
      <pubDate>Sat, 21 Mar 2026 00:00:00 +0000</pubDate>
      <author>nickboy@users.noreply.github.com (Nick Liu)</author>
      <guid>https://nick-liu.com/posts/obsidian-claude-code-knowledge-base/</guid>
      <description>&lt;div class=&#34;lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl&#34;&gt;&#xA;  &#xA;Obsidian + Claude Code is everywhere right now. But pointing an AI at a folder of markdown files and hoping for the best doesn&#39;t work. What matters is how you structure the knowledge base. Get that right, and Claude becomes genuinely useful. Get it wrong, and you get confident garbage.&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;There&amp;rsquo;s been a wave of posts about this combo lately: &lt;a href=&#34;https://x.com/jameesy/status/2026628809424781787&#34;  target=&#34;_blank&#34; rel=&#34;noreferrer&#34;&gt;James Bedford&amp;rsquo;s full walkthrough&lt;/a&gt;, &lt;a href=&#34;https://x.com/gregisenberg/status/2026036464287412412&#34;  target=&#34;_blank&#34; rel=&#34;noreferrer&#34;&gt;Greg Isenberg&amp;rsquo;s &amp;ldquo;personal OS&amp;rdquo; approach&lt;/a&gt;, &lt;a href=&#34;https://x.com/kepano/status/2008578873903206895&#34;  target=&#34;_blank&#34; rel=&#34;noreferrer&#34;&gt;kepano (Obsidian&amp;rsquo;s CEO) sharing Claude Skills&lt;/a&gt;. They&amp;rsquo;re all worth reading.&lt;/p&gt;</description>
      
    </item>
    
    <item>
      <title>What I Learned from How Claude Code&#39;s Creator Uses Claude Code</title>
      <link>https://nick-liu.com/posts/boris-claude-code-tips/</link>
      <pubDate>Sat, 21 Mar 2026 00:00:00 +0000</pubDate>
      <author>nickboy@users.noreply.github.com (Nick Liu)</author>
      <guid>https://nick-liu.com/posts/boris-claude-code-tips/</guid>
      <description>&lt;div class=&#34;lead text-neutral-500 dark:text-neutral-400 !mb-9 text-xl&#34;&gt;&#xA;  &#xA;Boris Cherny created Claude Code. When he shared how he actually uses it day-to-day, the setup was surprisingly simple. I went through every tip, tried most of them, and have opinions about all of them.&#xA;&#xA;&lt;/div&gt;&#xA;&#xA;&lt;p&gt;The original thread is on &lt;a href=&#34;https://x.com/bcherny/status/2007179832300581177&#34;  target=&#34;_blank&#34; rel=&#34;noreferrer&#34;&gt;Boris&amp;rsquo;s X account&lt;/a&gt;. A good companion site is &lt;a href=&#34;https://howborisusesclaudecode.com&#34;  target=&#34;_blank&#34; rel=&#34;noreferrer&#34;&gt;howborisusesclaudecode.com&lt;/a&gt; which compiles everything in one place.&lt;/p&gt;</description>
      
    </item>
    
  </channel>
</rss>
