<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Bun on Nick Liu - Software Engineer</title>
    <link>/tags/bun/</link>
    <description>Recent content in Bun 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>Sun, 10 May 2026 22:48:37 -0700</lastBuildDate><atom:link href="/tags/bun/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>I split my daemon in two so a Node subprocess could own the PTY</title>
      <link>/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>/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;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>
    
  </channel>
</rss>
