<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:googleplay="http://www.google.com/schemas/play-podcasts/1.0"><channel><title><![CDATA[Digital Onigiri]]></title><description><![CDATA[On Building YEN: A Terminal App]]></description><link>https://blog.yen.chat</link><image><url>https://substackcdn.com/image/fetch/$s_!Twh4!,w_256,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25857f99-094a-420f-82d0-666a8c7c9f05_1024x1024.png</url><title>Digital Onigiri</title><link>https://blog.yen.chat</link></image><generator>Substack</generator><lastBuildDate>Sun, 23 Aug 2026 22:16:12 GMT</lastBuildDate><atom:link href="https://blog.yen.chat/feed" rel="self" type="application/rss+xml"/><copyright><![CDATA[YEN]]></copyright><language><![CDATA[en]]></language><webMaster><![CDATA[yenchat@substack.com]]></webMaster><itunes:owner><itunes:email><![CDATA[yenchat@substack.com]]></itunes:email><itunes:name><![CDATA[8Lee]]></itunes:name></itunes:owner><itunes:author><![CDATA[8Lee]]></itunes:author><googleplay:owner><![CDATA[yenchat@substack.com]]></googleplay:owner><googleplay:email><![CDATA[yenchat@substack.com]]></googleplay:email><googleplay:author><![CDATA[8Lee]]></googleplay:author><itunes:block><![CDATA[Yes]]></itunes:block><item><title><![CDATA[The Cat that Counts Agent Tokens]]></title><description><![CDATA[A usage meter for Claude Code & Codex and more.]]></description><link>https://blog.yen.chat/p/jp</link><guid isPermaLink="false">https://blog.yen.chat/p/jp</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Tue, 07 Jul 2026 13:26:20 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!s4Ty!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50133b93-ed2e-4a75-9134-8e49fd1c225f_808x960.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>Tiny detour from terminal land today as I just shipped the first real release of a sister product: <a href="https://jpthecat.com">JPtheCat</a>, a macOS menu-bar app that watches what your coding agents are spending and turns it into something a human can actually glance at.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>Yeah, that&#8217;s it. Super small utility but something that I cannot possibly live without. You can see me using it while I&#8217;m writing this post!</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KtDm!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb64376a-52bb-4a37-b13e-cf3dea6cb79a_2068x1568.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KtDm!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb64376a-52bb-4a37-b13e-cf3dea6cb79a_2068x1568.png 424w, https://substackcdn.com/image/fetch/$s_!KtDm!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb64376a-52bb-4a37-b13e-cf3dea6cb79a_2068x1568.png 848w, https://substackcdn.com/image/fetch/$s_!KtDm!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb64376a-52bb-4a37-b13e-cf3dea6cb79a_2068x1568.png 1272w, https://substackcdn.com/image/fetch/$s_!KtDm!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb64376a-52bb-4a37-b13e-cf3dea6cb79a_2068x1568.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KtDm!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb64376a-52bb-4a37-b13e-cf3dea6cb79a_2068x1568.png" width="1200" height="909.8901098901099" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/eb64376a-52bb-4a37-b13e-cf3dea6cb79a_2068x1568.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:1104,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:607328,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/205765967?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb64376a-52bb-4a37-b13e-cf3dea6cb79a_2068x1568.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!KtDm!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb64376a-52bb-4a37-b13e-cf3dea6cb79a_2068x1568.png 424w, https://substackcdn.com/image/fetch/$s_!KtDm!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb64376a-52bb-4a37-b13e-cf3dea6cb79a_2068x1568.png 848w, https://substackcdn.com/image/fetch/$s_!KtDm!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb64376a-52bb-4a37-b13e-cf3dea6cb79a_2068x1568.png 1272w, https://substackcdn.com/image/fetch/$s_!KtDm!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Feb64376a-52bb-4a37-b13e-cf3dea6cb79a_2068x1568.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>It simple counts your agent tokens so you can keep track of spend. Why? Because token intelligence is literally dollars and cents and if you can master your spend then you end up saving money. </p><p>And that&#8217;s what I&#8217;m trying to do.</p><p>The slightly longer version of this is that JPtheCat shows Claude Code spend and Codex rate-limit usage on your Mac, locally, without trying to become a giant dashboard, a cloud billing suite, or another dark panel full of mystery numbers. It is warm, small, opinionated, and yes, it meows.</p><p>And it&#8217;s the literal sound of my cat, JP. She&#8217;s so cute (and spicy).</p><h3>Why I Built This</h3><p>Agentic coding has a funny visibility problem.</p><p>The work feels magical right up until the bill arrives, or the rate-limit window closes, or a session that felt harmless quietly turns into a surprisingly expensive little adventure. Token counts are useful if you are a machine. </p><p>They are less useful if you are a person trying to decide whether to keep going, pause, switch models, or stop asking your agent to rewrite the same function for the seventh time.</p><p>Ask me how I know that&#8230;</p><p>I wanted something that behaved like an instrument, not a report. A small native meter. A menu-bar readout. Something that makes the cost of the current day feel visible without making the whole computer feel like an accounting department.</p><p>That is my cat. Or, rather, the digital incarnation of her now.</p><h3>What JP Does Today</h3><p><a href="https://jpthecat.com">JP the Cat</a> currently tracks Claude Code and Codex.</p><p>For Claude Code, it reads the local session data your tool already writes, deduplicates the streamed usage records, handles cache-write pricing correctly, and turns the result into real dollars. </p><p>That last part matters. Some usage tools show token counts or rough estimates. JP leads with the number you actually care about: <strong>What this is costing you</strong> to tokenmaxx to your heart&#8217;s content.</p><p>For Codex, JP reads local rollout usage and shows the official rate-limit percentages exposed by the tool: The 5-hour window and the weekly window. If a number is official, JP says so. If a future provider needs an estimate, it should be labeled as an estimate. </p><p>No provider pretending. No fake confidence.</p><p>There is also a 62-provider catalog behind the app, but only Claude Code and Codex are live today. I&#8217;m going to work on those after I get the first round of feedback.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!s4Ty!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50133b93-ed2e-4a75-9134-8e49fd1c225f_808x960.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!s4Ty!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50133b93-ed2e-4a75-9134-8e49fd1c225f_808x960.png 424w, https://substackcdn.com/image/fetch/$s_!s4Ty!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50133b93-ed2e-4a75-9134-8e49fd1c225f_808x960.png 848w, https://substackcdn.com/image/fetch/$s_!s4Ty!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50133b93-ed2e-4a75-9134-8e49fd1c225f_808x960.png 1272w, https://substackcdn.com/image/fetch/$s_!s4Ty!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50133b93-ed2e-4a75-9134-8e49fd1c225f_808x960.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!s4Ty!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50133b93-ed2e-4a75-9134-8e49fd1c225f_808x960.png" width="808" height="960" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/50133b93-ed2e-4a75-9134-8e49fd1c225f_808x960.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:960,&quot;width&quot;:808,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:316264,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/205765967?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50133b93-ed2e-4a75-9134-8e49fd1c225f_808x960.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!s4Ty!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50133b93-ed2e-4a75-9134-8e49fd1c225f_808x960.png 424w, https://substackcdn.com/image/fetch/$s_!s4Ty!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50133b93-ed2e-4a75-9134-8e49fd1c225f_808x960.png 848w, https://substackcdn.com/image/fetch/$s_!s4Ty!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50133b93-ed2e-4a75-9134-8e49fd1c225f_808x960.png 1272w, https://substackcdn.com/image/fetch/$s_!s4Ty!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F50133b93-ed2e-4a75-9134-8e49fd1c225f_808x960.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>The Cat Part Is Not Incidental</h3><p>JP is not just a logo slapped on top of a spreadsheet.</p><p>The app is intentionally light. The website is warm. The menu-bar pill is readable. The dashboard has named light and dark themes. <strong>There is a packaged meow</strong>. LOL. I had way too fun trying to get a sound capture of her talking. </p><p>She is our tiny mascot with very strong opinions about your token burn. Silly, but, not entirely unserious. I mean, money burn is serious stuff.</p><p>One thing I keep learning from YEN is that developer tools do not have to feel like punishment. A tool can be local-first, privacy-conscious, technically careful, and still have a little personality. </p><p>You see, a terminal can have sounds. A usage meter can have a cat. An installer can be pleasant. These things are not separate from quality. They are part of whether people enjoy using the thing every day.</p><p>JP is built from that same instinct. Naturally, cause it&#8217;s the same engineer.</p><p>v1.0 released yesterday and ships as a notarized macOS app for macOS 14 and newer, with Sparkle updates, a working download endpoint, a 7-day trial, live Stripe checkout, license activation and validation, refund revocation, and a one-time Mac license. The current price is <strong>$12.99 for one Mac</strong>.</p><p>It&#8217;s a premium product and one that will only get better with time. No subscriptions. Yay. So much better. You can download the DMG directly from the <a href="https://jpthecat.com">site</a>, or install it through the public Homebrew tap:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:null}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">sh
brew tap 8bittts/jpthecat
brew trust 8bittts/jpthecat
brew install --cask jpthecat</code></pre></div><p>There are still plenty of things I want to add: Budget alerts, durable history, export, per-project attribution, more providers, and a deeper paid story after the first release. But the current shape is useful now. It answers the first question cleanly:</p><blockquote><p>What are my coding agents costing me today?</p></blockquote><p>Finally, why post this here? Well, because I can.</p><p>But on a more serious note, YEN is about making the terminal feel like a real workbench. JPtheCat is about making the agent layer around that workbench more legible. They are definitely separate products (although integration did come to mind) but fundamentally they come from the same philosophy: Local-first where possible, native where it matters, honest about what is shipped, and allergic to pretending the cloud has to be involved in everything.</p><p>Small tools. Clear instruments. Less mystery. More control.</p><p>Also, occasionally, a cat.</p><p>I&#8217;d love for you to give it a try. If you send some feedback I&#8217;ll send you a coupon. 100% lifetime key for the first few folks. LMK.</p><p>&#8212; 8</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!g6_A!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42905a44-e611-4de6-bc49-3ce9b18d5aa4_1170x1522.webp" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!g6_A!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42905a44-e611-4de6-bc49-3ce9b18d5aa4_1170x1522.webp 424w, https://substackcdn.com/image/fetch/$s_!g6_A!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42905a44-e611-4de6-bc49-3ce9b18d5aa4_1170x1522.webp 848w, https://substackcdn.com/image/fetch/$s_!g6_A!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42905a44-e611-4de6-bc49-3ce9b18d5aa4_1170x1522.webp 1272w, https://substackcdn.com/image/fetch/$s_!g6_A!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42905a44-e611-4de6-bc49-3ce9b18d5aa4_1170x1522.webp 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!g6_A!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42905a44-e611-4de6-bc49-3ce9b18d5aa4_1170x1522.webp" width="1170" height="1522" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/42905a44-e611-4de6-bc49-3ce9b18d5aa4_1170x1522.webp&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1522,&quot;width&quot;:1170,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:133494,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/webp&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/205765967?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42905a44-e611-4de6-bc49-3ce9b18d5aa4_1170x1522.webp&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!g6_A!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42905a44-e611-4de6-bc49-3ce9b18d5aa4_1170x1522.webp 424w, https://substackcdn.com/image/fetch/$s_!g6_A!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42905a44-e611-4de6-bc49-3ce9b18d5aa4_1170x1522.webp 848w, https://substackcdn.com/image/fetch/$s_!g6_A!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42905a44-e611-4de6-bc49-3ce9b18d5aa4_1170x1522.webp 1272w, https://substackcdn.com/image/fetch/$s_!g6_A!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42905a44-e611-4de6-bc49-3ce9b18d5aa4_1170x1522.webp 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a><figcaption class="image-caption">Hi, I&#8217;m JP.</figcaption></figure></div>]]></content:encoded></item><item><title><![CDATA[Your Terminal Has a Native Git Drawer Now]]></title><description><![CDATA[It's fast, smart, and it just works.]]></description><link>https://blog.yen.chat/p/git-drawer</link><guid isPermaLink="false">https://blog.yen.chat/p/git-drawer</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Fri, 26 Jun 2026 22:52:57 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!hvql!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62ad338a-9656-4871-abf2-60f99c71eff9_2084x1812.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>I use Git all day, but most Git UI still makes me switch modes. And that annoys me a bit because I don&#8217;t like things that are slow or that require me to lose context and focus on my present work.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>You see, sometimes I want the full thing fast: Staging hunks, rewriting history, checking branches, reviewing commits, handling stash state. For that, YEN already bundles <strong>lazygit</strong>. And yes, it&#8217;s mature, fast, and good enough that rebuilding it from scratch would be a waste.</p><p>But there is another Git moment that happens constantly: I just want to know what changed in the split I am already looking at.</p><p>That is what the new native Git drawer is for.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!hvql!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62ad338a-9656-4871-abf2-60f99c71eff9_2084x1812.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!hvql!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62ad338a-9656-4871-abf2-60f99c71eff9_2084x1812.png 424w, https://substackcdn.com/image/fetch/$s_!hvql!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62ad338a-9656-4871-abf2-60f99c71eff9_2084x1812.png 848w, https://substackcdn.com/image/fetch/$s_!hvql!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62ad338a-9656-4871-abf2-60f99c71eff9_2084x1812.png 1272w, https://substackcdn.com/image/fetch/$s_!hvql!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62ad338a-9656-4871-abf2-60f99c71eff9_2084x1812.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!hvql!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62ad338a-9656-4871-abf2-60f99c71eff9_2084x1812.png" width="1456" height="1266" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/62ad338a-9656-4871-abf2-60f99c71eff9_2084x1812.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1266,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:451671,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/203160926?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62ad338a-9656-4871-abf2-60f99c71eff9_2084x1812.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!hvql!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62ad338a-9656-4871-abf2-60f99c71eff9_2084x1812.png 424w, https://substackcdn.com/image/fetch/$s_!hvql!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62ad338a-9656-4871-abf2-60f99c71eff9_2084x1812.png 848w, https://substackcdn.com/image/fetch/$s_!hvql!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62ad338a-9656-4871-abf2-60f99c71eff9_2084x1812.png 1272w, https://substackcdn.com/image/fetch/$s_!hvql!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62ad338a-9656-4871-abf2-60f99c71eff9_2084x1812.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>It really is that simple. And useful. And unobtrusive.</p><p>It ships in <strong>YEN v1.095</strong> as a read-only macOS drawer on <strong>Cmd + Shift + G</strong>. It opens from the bottom of the active terminal window, looks at the focused split, resolves the local Git working tree, and shows the raw local changes without launching a new shell.</p><h3>Why I Built It</h3><p>YEN is becoming a <a href="https://blog.yen.chat/p/ide">terminal-first IDE</a>, but I do not want every feature to become a second-rate clone of a mature developer tool.</p><p>The rule I keep coming back to is simple: vendor what is already excellent, build native surfaces where the terminal/window context makes the workflow better.</p><p>Git is a perfect example.</p><p><strong>lazygit</strong> is the right answer when I want to operate on a repository. It is the full TUI. It can stage, commit, stash, branch, rebase, and move around a repo with intent.</p><p>The Git drawer is not trying to replace that.</p><p>The drawer is the glance path. It answers:</p><ul><li><p>What branch is this split on?</p></li><li><p>Is this worktree clean?</p></li><li><p>What files changed?</p></li><li><p>Which changes are staged, unstaged, untracked, or conflicted?</p></li><li><p>What does the raw diff look like?</p></li><li><p>Can I copy the path, copy the diff, open the file, or jump into <strong>lazygit</strong> if this needs a real Git operation?</p></li></ul><p>That is a different job than a Git TUI, so it deserves a different shape.</p><h3>How It Works</h3><p>Simple. When you press <strong>Cmd + Shift + G</strong>, YEN opens an attached bottom drawer inside the current terminal window.</p><p>It does not create a Quick Terminal. It does not paste a command. It does not spawn an interactive shell. It uses the focused terminal split&#8217;s trusted working directory, resolves the repository root, and asks Git for structured read-only data.</p><p>The first version shows:</p><ul><li><p>Branch name.</p></li><li><p>Upstream tracking ref.</p></li><li><p>Ahead and behind counts.</p></li><li><p>Clean or dirty summary.</p></li><li><p>Total changed-file count.</p></li><li><p>Repo-wide additions and deletions.</p></li><li><p>Read-only stash count.</p></li><li><p>Grouped file changes for staged, unstaged, untracked, and conflicted files.</p></li><li><p>Per-file status badges such as M, A, D, R, U, and ??.</p></li><li><p>Per-file additions and deletions, with honest placeholders for binary and submodule rows.</p></li><li><p>Raw unified diff for the selected file.</p></li></ul><p>You know, the basics.</p><p>The default renderer is intentionally plain. I did not route this through <strong>delta</strong> for v1 because I wanted the drawer to prove the raw Git path first. Pretty diff rendering can come later. The baseline should be correct before it is decorative.</p><h3>Read-Only On Purpose</h3><p>The drawer does not stage files. It does not unstage files. It does not commit. It does not apply stash state. It does not revert files.</p><p>And all of that is deliberate.</p><p>The feature is meant to be safe to open while cycling through terminal splits. If I am jumping between server, client, tests, docs, and a scratch repo, I want <strong>Cmd + Shift + G</strong> to be a fast inspection surface, not a place where an accidental keypress mutates history.</p><p>When I need to do Git work, the drawer has a handoff button to open the current repo in bundled <strong>lazygit</strong>. That keeps the roles clean: native drawer for context, TUI for operations.</p><h3>Failure States Matter</h3><p>One of the easiest ways for a developer tool to feel sloppy is to confuse &#8220;nothing changed&#8221; with &#8220;I could not read anything.&#8221;</p><p>So the drawer now has explicit notices for the failure modes I care about:</p><ul><li><p>No Git repository here.</p></li><li><p>Bare repositories are not supported.</p></li><li><p>Git is not available at <strong>/usr/bin/git</strong>.</p></li><li><p>Git is taking too long.</p></li><li><p>Unable to read this worktree.</p></li><li><p>Read-only drawer blocked a mutating command.</p></li><li><p>Unable to open Git drawer.</p></li></ul><p>The no-repository case tells you to open a split inside a Git checkout or run <strong>git init</strong>. Bare repositories point you toward a working-tree checkout. Missing Git points at <strong>/usr/bin/git</strong>. Timeout and command-failure states suggest refresh, <strong>lazygit</strong>, permissions, hooks, or Git config depending on what happened.</p><p>A clean repository is different. A clean repo still gets the full header and says the working tree is clean. That distinction matters because &#8220;clean&#8221; is a successful state, not an empty fallback.</p><h3>Why This Belongs in the Terminal (and YEN)</h3><p>Most terminals know almost nothing about the work happening inside them.</p><p>YEN already has more context: Splits, tabs, trusted working directories, window ownership, local IDE commands, file browser state, PR review surfaces, merge-conflict surfaces, bundled tools, and macOS-native panels.</p><p>That makes a native Git drawer useful in a way a generic app-level Git sidebar is not.</p><p>The feature is small, but the context is the point. And it&#8217;s clearly very intentional. The terminal already knows which split I am working in. The Git UI should use that knowledge.</p><p>Now, I could follow-on with hunk navigation, copy, diff rendering, but, I&#8217;ll leave those until I actually find myself wanting them badly.</p><p>This narrow implementation gets me precisely where I want to go. I hope you find it useful too! I want the read-only foundation to be boringly reliable first: Open the drawer, see the local truth, copy or open what you need, and keep moving.</p><p>That is the kind of terminal-first IDE feature I want YEN to have more of. Not a giant replacement for every tool you already trust. A small native surface that removes one more context switch.</p><p>Simple. Elegant. Useful.</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[Shipping Things That Make Me Happy]]></title><description><![CDATA[Or normalizing the Settings UI / UX to be prettier.]]></description><link>https://blog.yen.chat/p/happy</link><guid isPermaLink="false">https://blog.yen.chat/p/happy</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Sun, 14 Jun 2026 00:12:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!xEl4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0683330-71e4-4309-a9b0-f4844a88a54b_2120x1584.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>This work ships in <strong>YEN v1.087</strong>.</p><p>I spent time on something that can sound small from the outside: Normalizing the design in the Settings Panel.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>That means labels, sliders, descriptions, shortcut rows, color controls, and the little bits of spacing that most people only notice when they are wrong. It is not the kind of thing that shows up well in a feature checklist. It is also exactly the kind of thing that changes whether an app feels cared for.</p><p>But I really think this stuff matters, especially because I use this small device every single day for really serious work.</p><p>You see, the Settings (as we all know) is where a user goes when the default product does not quite match how they work. If that surface feels uneven, the message is subtle but real: customization exists, but it is not loved. I want YEN to send the opposite message. </p><p>If I give you knobs, those knobs should feel deliberate. Intentional.</p><p>Cared for, even.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!xEl4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0683330-71e4-4309-a9b0-f4844a88a54b_2120x1584.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!xEl4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0683330-71e4-4309-a9b0-f4844a88a54b_2120x1584.png 424w, https://substackcdn.com/image/fetch/$s_!xEl4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0683330-71e4-4309-a9b0-f4844a88a54b_2120x1584.png 848w, https://substackcdn.com/image/fetch/$s_!xEl4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0683330-71e4-4309-a9b0-f4844a88a54b_2120x1584.png 1272w, https://substackcdn.com/image/fetch/$s_!xEl4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0683330-71e4-4309-a9b0-f4844a88a54b_2120x1584.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!xEl4!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0683330-71e4-4309-a9b0-f4844a88a54b_2120x1584.png" width="1200" height="896.7032967032967" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e0683330-71e4-4309-a9b0-f4844a88a54b_2120x1584.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:1088,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:246914,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/201930140?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0683330-71e4-4309-a9b0-f4844a88a54b_2120x1584.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!xEl4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0683330-71e4-4309-a9b0-f4844a88a54b_2120x1584.png 424w, https://substackcdn.com/image/fetch/$s_!xEl4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0683330-71e4-4309-a9b0-f4844a88a54b_2120x1584.png 848w, https://substackcdn.com/image/fetch/$s_!xEl4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0683330-71e4-4309-a9b0-f4844a88a54b_2120x1584.png 1272w, https://substackcdn.com/image/fetch/$s_!xEl4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe0683330-71e4-4309-a9b0-f4844a88a54b_2120x1584.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>The Small Things, Always</h3><p>The Settings panel had grown quickly because YEN has a lot more native configuration now.</p><p>There are terminal basics like font, cursor, opacity, padding, and background images. There are notification controls. There are workspace controls for the tab sidebar, scratchpad, and browser behavior. There is the theme gallery. There is a full keyboard shortcut editor with conflict detection. There are chromatic window borders with focused and unfocused palettes.</p><p>Individually, these features worked. Together, the page was starting to show seams.</p><p>Some labels wrapped into two lines while nearby labels stayed on one line. Some sections had helpful little descriptions under the heading, while others jumped straight into controls. </p><p>Some sliders had values on the far right, but did not give you a direct way to type a value. Padding sliders had visual marks that made the control look busier than it needed to be. Border width and border radius could both read as <strong>1 px</strong>, but their slider positions did not feel like they shared the same baseline.</p><p>None of that is catastrophic. But all of it adds up. And it hurts my face when I see things that aren&#8217;t where they should be.</p><p>Or as pretty.</p><p>A settings panel should not make you wonder whether two controls are built from two different design systems. It should feel like one surface.</p><h3>What I Changed</h3><p>I normalized the row-label column across the Settings tabs.</p><p>That is a simple sentence, but it matters. Labels now get the same amount of room in General, Sounds, Workspace, Themes, and Keyboard. A control like <strong>Window Border</strong> should not be forced into a cramped two-line label while nearby controls have space. The visual rhythm should stay stable as you move through the app.</p><p>I also made section descriptions canonical.</p><p>YEN already had a few nice section headers with short explanations, like the Browser section in Workspace. I expanded that pattern across the panel. General now explains what Font, Cursor, Behavior, and Appearance are for. Sounds explains focused notification behavior and Translate-on-Dictate. Themes explains catalog scope and gallery previewing. Keyboard categories explain what kind of shortcuts live in each group.</p><p>These descriptions are intentionally short. They are not tutorials. They are orientation. The goal is to make the panel easier to scan without turning every section into documentation.</p><p>I brought manual numeric entry back to slider-backed controls.</p><p>Sliders are good for feel. Text fields are good for precision. Settings needs both.</p><p>Padding X and Y now keep the slider, but also let you type the pixel value directly beside the control. Window Border width and radius now work the same way. The value is no longer just a readout; it is editable.</p><p>That sounds minor until you are trying to set two values to exactly the same number. A slider is great when you are exploring. It is annoying when you already know the value you want.</p><p>I also fixed the baseline mismatch between Window Border width and radius.</p><p>Both can show <strong>1 px</strong>, so both should treat <strong>1 px</strong> as the same kind of minimum. Before this pass, the radius slider could sit at a different baseline than width even when both read as <strong>1 px</strong>. That is the kind of mismatch that makes a panel feel slightly off even if you cannot immediately name why.</p><p>I checked the focused and unfocused outline color behavior too.</p><p>The Window Border controls let you pick a focused palette and an unfocused palette, or let the border match the active terminal theme. That surface only earns its keep if the colors actually resolve, persist, preview, and change independently. I tightened the review around those code paths and kept the existing contrast and theme-resolution behavior intact.</p><p>Oh, and at least for my own work on the design, I also added test coverage for saving multiple custom keyboard shortcut combinations. I don&#8217;t want to go backwards, ever.</p><p>The Keyboard tab is not just a visual list. It writes real keybind overrides. A shortcut remap has to unbind the old default trigger and bind the new one so both do not stay active in parallel. This pass added coverage for multiple remaps saving together, including combinations that use Option, Shift, Control, and Command.</p><p>That is the difference between a settings UI that looks editable and one that can be trusted.</p><h3>Why This Is Worth Doing</h3><p>I like building big features. Browser previews, speech-to-text, command palettes, file browsing, chromatic borders, and terminal-first IDE tools are fun because they are obvious. But software quality is often decided by the less obvious work.</p><p>Does the value field clear correctly when you start typing a new number? Does a label wrap because the row was designed too narrowly? Does a section tell you what it is for without talking too much? Does a slider show the same value in two places but behave differently under your hand? Does a shortcut editor really save the combination you recorded?</p><p>Those are not superficial details to the person using the app every day. They are friction.</p><p>And because YEN is a terminal-first IDE, the bar is higher. Developers live in tools for hours. They notice inconsistency. They notice when a native panel feels like a quick wrapper around a config file instead of a real product surface.</p><p>My approach is to keep the terminal powerful while making the native UI feel intentional wherever native UI is the better tool.</p><p>Settings is one of those places.</p><h3>What I Want Settings To Communicate</h3><p>The Settings panel should say: This app is configurable, but not careless.</p><p>It should say that visual customization is not an afterthought. It should say that accessibility and focus states matter. It should say that keyboard shortcuts are first-class, not a hidden text-file trick. It should say that if something has a slider, you can still type the value like an adult.</p><p>Most of all, it should say that I am willing to improve the boring parts.</p><p>There is a lot of quiet, methodical work in YEN. Some of it is deep architecture. Some of it is release safety. Some of it is making sure a label does not wrap awkwardly next to a toggle.</p><p>I think all of it counts.</p><p>The terminal is the center of the product, but the surrounding surfaces are part of the experience too. If those surfaces feel uneven, the product feels uneven. So I keep going back through them, tightening the details, and making the app feel more like itself.</p><p>That is what this Settings pass was about.</p><p>Not a redesign for the sake of a screenshot.</p><p>A normalization pass so the whole panel feels more coherent, more precise, and more respectful of the person using it.</p><p>Obsessing about the product to even the smallest pixel is how you know you really care and is a good sniff test of quality.</p><p>That&#8217;s the bar. I&#8217;m going to keep reaching for it.</p><p>And this makes me really, <em>really</em> happy.</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[Terminals and Tunes]]></title><description><![CDATA[Music for coding, focus, and the quiet hours between builds.]]></description><link>https://blog.yen.chat/p/tunes</link><guid isPermaLink="false">https://blog.yen.chat/p/tunes</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Sat, 06 Jun 2026 20:03:32 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!8Xm6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292d01e1-7a52-4e67-8271-27ce14b111cf_2916x1790.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>YEN has always had two halves in the name. The terminal half is the part you can see &#8212; the app, the IDE, the splits, the tabs, the file browser. The musical half has been quieter and never mentioned.</p><p>Well, until now.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>I just shipped <a href="https://yen.chat/tunes">Terminals and Tunes</a> &#8212; an AI-assisted music label that produces background music for the kind of person who reads my blog. Late-night coders, deep-focus readers, anxiety-relief sleepers, meditation-curious focus types, cottagecore journal-keepers. '</p><p>Five personas. Same channel. Same person behind it. Different worlds.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8Xm6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292d01e1-7a52-4e67-8271-27ce14b111cf_2916x1790.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8Xm6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292d01e1-7a52-4e67-8271-27ce14b111cf_2916x1790.png 424w, https://substackcdn.com/image/fetch/$s_!8Xm6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292d01e1-7a52-4e67-8271-27ce14b111cf_2916x1790.png 848w, https://substackcdn.com/image/fetch/$s_!8Xm6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292d01e1-7a52-4e67-8271-27ce14b111cf_2916x1790.png 1272w, https://substackcdn.com/image/fetch/$s_!8Xm6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292d01e1-7a52-4e67-8271-27ce14b111cf_2916x1790.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8Xm6!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292d01e1-7a52-4e67-8271-27ce14b111cf_2916x1790.png" width="1200" height="736.8131868131868" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/292d01e1-7a52-4e67-8271-27ce14b111cf_2916x1790.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:894,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:1312537,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/197918854?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292d01e1-7a52-4e67-8271-27ce14b111cf_2916x1790.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8Xm6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292d01e1-7a52-4e67-8271-27ce14b111cf_2916x1790.png 424w, https://substackcdn.com/image/fetch/$s_!8Xm6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292d01e1-7a52-4e67-8271-27ce14b111cf_2916x1790.png 848w, https://substackcdn.com/image/fetch/$s_!8Xm6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292d01e1-7a52-4e67-8271-27ce14b111cf_2916x1790.png 1272w, https://substackcdn.com/image/fetch/$s_!8Xm6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F292d01e1-7a52-4e67-8271-27ce14b111cf_2916x1790.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This post is about why I built it, what&#8217;s live right now, and how the pipeline actually works.</p><h3>Why Music?</h3><p>The terminal-first IDE thesis I&#8217;ve been writing about for two years is &#8220;the developer surface should be the terminal.&#8221; Background music is the same kind of surface. It&#8217;s the thing playing in the corner while you work &#8212; quiet, dependable, doesn&#8217;t need attention, doesn&#8217;t sell you something every thirty seconds. </p><p>The Lofi Girl channel earns reportedly six figures a month doing exactly this, with one persona and a finite catalog. The category is real. The audience is real. The competitive moat is taste plus volume plus distribution discipline &#8212; all things I can build with CLI tools.</p><p>So I built one to see if it would really work. </p><p>It kind of does.</p><h3>The 5 Personas</h3><p>I picked five niches I think pair well with the YEN: Terminals and Tunes brand and don&#8217;t overlap with the giants:</p><ol><li><p><strong>YEN Terminal Tunes</strong> &#8212; synthwave for late-night coding. Restrained, melodic, low-distraction. Background music for the terminal.</p></li><li><p><strong>Idle Coast</strong> &#8212; bossa nova / lounge / chillhop. For cafes, slow afternoons, and golden-hour workspaces.</p></li><li><p><strong>Noise Floor</strong> &#8212; brown noise plus soft ambient pads. For sleep and deep relaxation.</p></li><li><p><strong>Gamma Daemon</strong> &#8212; binaural focus / 40Hz gamma. For study sessions, deep focus, and meditation.</p></li><li><p><strong>Hearth 16</strong> &#8212; cottagecore acoustic folk plus nature ambience. For reading, journaling, and quiet evenings.</p></li></ol><p>Each persona has its own anime-themed visual identity, its own audio fingerprint, its own niche audience. They all roll up under one YouTube channel <a href="https://www.youtube.com/@yenFTW">(@yenFTW</a>) and one Spotify For Artists account, so I claim once and pitch all five.</p><h3>The Pipeline</h3><p>Every step is CLI or scripted. My role is taste and quality control. The actual work is:</p><ol><li><p><strong>Generate</strong> &#8212; Suno Premier through aimusicapi.ai. I send a prompt; the API returns audio. About $0.10 per track.</p></li><li><p><strong>QC</strong> &#8212; A TUI I built. I press <strong>k</strong> to keep, <strong>r</strong> to reject, <strong>p</strong> to preview. Hard taste gate. Most tracks get rejected.</p></li><li><p><strong>Mix</strong> &#8212; ffmpeg crossfade for long-form mixes. Loudness-normalize to -14 LUFS for Spotify.</p></li><li><p><strong>Cover</strong> &#8212; Higgsfield&#8217;s <strong>kling3_0</strong> at 4K renders one ten-second seamless loop per persona. Every release cover is a frame extracted from that loop, so the album art always matches the YouTube video&#8217;s character, world, and lighting.</p></li><li><p><strong>Video</strong> &#8212; ffmpeg layers the seamless loop under the audio at 4K. Audio is 320 kbps AAC, video is H.264 high-profile at CRF 16.</p></li><li><p><strong>Metadata</strong> &#8212; <strong>claude -p</strong> writes the YouTube title, description with chapter markers, and 15-25 SEO-tuned tags.</p></li><li><p><strong>Hard upload gate</strong> &#8212; Operator approval required before anything publishes. I review every file. Nothing gets posted on auto-pilot.</p></li><li><p><strong>Upload</strong> &#8212; YouTube Data API for the video (with <strong>containsSyntheticMedia: true</strong> because the AI disclosure is mandatory and honest), Supabase Storage for the durable archive, DistroKid for streaming distribution.</p></li></ol><p>The whole thing runs from a slash command: <strong>/yen-tunes</strong> generates per-persona in parallel, then converges at QC, then fans back out for per-mix cover and video. End-to-end it&#8217;s about ninety minutes of operator time and $1-2 in API credits for a single pass across all five personas.</p><p>Not too bad.</p><p>It&#8217;s just an experiment and I&#8217;m still messing with the settings and outputs as well as the distribution to other platforms. It&#8217;s not perfect but it&#8217;s amazing what you can do with a little knowledge (and an <a href="https://blog.yen.chat/p/skills">agentic harness</a>).</p><p>I can&#8217;t imagine a world where music isn&#8217;t part of my programming &#8220;logic&#8221; and so I&#8217;ve had a blast experimenting and seeing how it all fits together.</p><p>I hope you enjoy.</p><p>&#8212; 8</p><div><hr></div><p>If you want to listen, the personas and playlists are here:</p><div id="youtube2-MNBMYVlMDO4" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;MNBMYVlMDO4&quot;,&quot;startTime&quot;:&quot;2225s&quot;,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/MNBMYVlMDO4?start=2225s&amp;rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><div id="youtube2-y3zup6GHkLQ" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;y3zup6GHkLQ&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/y3zup6GHkLQ?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><div id="youtube2-kf_pCxLaJn0" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;kf_pCxLaJn0&quot;,&quot;startTime&quot;:&quot;35s&quot;,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/kf_pCxLaJn0?start=35s&amp;rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><div id="youtube2-25nKMP-Xpk4" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;25nKMP-Xpk4&quot;,&quot;startTime&quot;:&quot;42s&quot;,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/25nKMP-Xpk4?start=42s&amp;rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div><div id="youtube2-ZnwBRXzBFeE" class="youtube-wrap" data-attrs="{&quot;videoId&quot;:&quot;ZnwBRXzBFeE&quot;,&quot;startTime&quot;:null,&quot;endTime&quot;:null}" data-component-name="Youtube2ToDOM"><div class="youtube-inner"><iframe src="https://www.youtube-nocookie.com/embed/ZnwBRXzBFeE?rel=0&amp;autoplay=0&amp;showinfo=0&amp;enablejsapi=0" frameborder="0" loading="lazy" gesture="media" allow="autoplay; fullscreen" allowautoplay="true" allowfullscreen="true" width="728" height="409"></iframe></div></div>]]></content:encoded></item><item><title><![CDATA[A Quiet Terminal is a Better Terminal]]></title><description><![CDATA[Retiring custom notification sounds and downloadable sound packs.]]></description><link>https://blog.yen.chat/p/quiet</link><guid isPermaLink="false">https://blog.yen.chat/p/quiet</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Fri, 15 May 2026 20:51:10 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!DcnJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62172b31-04bf-4888-acac-359455e771de_1408x810.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks,</p><p>A small but impactful change &#8212; the type that I like.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>I&#8217;ve effectively removed the custom <a href="https://blog.yen.chat/p/making-your-terminal-sound-like-fun">notification sounds</a> and the really fun sound packs that I had originally designed.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;02c16a93-41b0-43cf-bf80-28dfe55ef45f&quot;,&quot;caption&quot;:&quot;Hey folks!&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Making Your Terminal Sound Like Fun&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:54423,&quot;name&quot;:&quot;8Lee&quot;,&quot;bio&quot;:&quot;Designer. Engineer. Master of the selfpwn.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6992612f-3d11-4a2c-83c1-0518674db408_1024x1024.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2026-02-20T17:11:27.369Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!IqZM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2ef57f57-8cbe-4465-bad8-359362601321_2394x2058.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://blog.yen.chat/p/making-your-terminal-sound-like-fun&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:188633562,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:0,&quot;comment_count&quot;:0,&quot;publication_id&quot;:7373375,&quot;publication_name&quot;:&quot;Digital Onigiri&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!Twh4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25857f99-094a-420f-82d0-666a8c7c9f05_1024x1024.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>Yeah, I know. That probably sounds like a small change. Pun intended. But, that stuff was never headline feature. It is not a big new surface. It is not the kind of thing that gets a splashy screenshot.</p><p>But it is one of those product decisions I care about a lot because it says something about what YEN is trying to become.</p><p>I want YEN to feel powerful without feeling busy. I want the terminal to pick up the things that help me move faster, and I want it to drop the things that mostly create maintenance weight, settings weight, release weight, and cognitive weight.</p><p>Custom audio notifications started as a fun idea. I liked the personality of it. A terminal can be serious and still have taste. It can have little moments of delight. That is why I shipped the original sound work in **Making Your Terminal Sound Like Fun**.</p><p>Over time, though, the honest version became clearer. The system was bigger than the value it created.</p><p>There were custom imports. There were official downloadable sound packs. There were bundled sound identifiers. There was a manifest. There were checksums. There were signatures. There was release-pipeline logic to package, upload, validate, and prune the audio artifacts. There was Settings UI for downloading and removing packs. There was public documentation that had to explain all of it.</p><p>And for what?</p><p>Most people need notification sounds to do one job: tell them that something happened. Well, macOS already has system sounds for that. They are familiar, local, accessible, and boring in exactly the right way. If YEN can let me choose <strong>None</strong>, choose a system sound, control the volume, decide whether banners appear, and decide what happens while the app is focused, then the product need is covered.</p><p>Everything beyond that has to earn its cost.</p><p>The sound packs stopped earning it. So, a few versions ago, I killed it. Now, notification sounds are just system-only. The current model is simple:</p><ul><li><p><strong>None</strong> means silence.</p></li><li><p><strong>System sounds</strong> come from macOS.</p></li><li><p><strong>General</strong> and <strong>Build</strong> notification streams keep their own routing.</p></li><li><p>Each stream still has delivery mode, volume, and focused-window behavior.</p></li><li><p>Old custom or bundled sound selections load safely and fall back to silence.</p></li></ul><p>The old audio files are not deleted from anyone&#8217;s Mac. YEN just stops scanning them, surfacing them, or depending on them. That part matters.</p><p>I do not want cleanup work to punish existing users. If someone has an old settings export or old app-support files, the next version should load cleanly. The app should not crash. The Settings panel should not show broken rows. The release pipeline should not look for artifacts that no longer exist.</p><p>Retirement should be boring. Or, at least in the case of good software.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!DcnJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62172b31-04bf-4888-acac-359455e771de_1408x810.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!DcnJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62172b31-04bf-4888-acac-359455e771de_1408x810.png 424w, https://substackcdn.com/image/fetch/$s_!DcnJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62172b31-04bf-4888-acac-359455e771de_1408x810.png 848w, https://substackcdn.com/image/fetch/$s_!DcnJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62172b31-04bf-4888-acac-359455e771de_1408x810.png 1272w, https://substackcdn.com/image/fetch/$s_!DcnJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62172b31-04bf-4888-acac-359455e771de_1408x810.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!DcnJ!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62172b31-04bf-4888-acac-359455e771de_1408x810.png" width="1200" height="690.3409090909091" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/62172b31-04bf-4888-acac-359455e771de_1408x810.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:810,&quot;width&quot;:1408,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:127663,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/197917182?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62172b31-04bf-4888-acac-359455e771de_1408x810.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!DcnJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62172b31-04bf-4888-acac-359455e771de_1408x810.png 424w, https://substackcdn.com/image/fetch/$s_!DcnJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62172b31-04bf-4888-acac-359455e771de_1408x810.png 848w, https://substackcdn.com/image/fetch/$s_!DcnJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62172b31-04bf-4888-acac-359455e771de_1408x810.png 1272w, https://substackcdn.com/image/fetch/$s_!DcnJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62172b31-04bf-4888-acac-359455e771de_1408x810.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Ok, So, Why? The Real Reason&#8230;</h3><p>The real reason is not disk space. The real reason is product clarity.</p><p>Every feature creates a shadow. The visible part is the button, picker, or setting. The shadow is everything behind it: validation, tests, docs, release automation, support burden, stale copy, edge cases, and the quiet fear that a rarely used path will break during a release.</p><p>It&#8217;s about <a href="https://blog.yen.chat/p/focus-feature">focus</a>.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;9410e4d0-8ce6-4b71-9951-6bdd57a944c3&quot;,&quot;caption&quot;:&quot;Hey folks!&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Focus is a Feature&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:54423,&quot;name&quot;:&quot;8Lee&quot;,&quot;bio&quot;:&quot;Designer. Engineer. Master of the selfpwn.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6992612f-3d11-4a2c-83c1-0518674db408_1024x1024.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2026-04-20T01:03:11.683Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!i59s!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40a2553b-a0a4-4121-9ea7-65a15cbea220_3640x2298.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://blog.yen.chat/p/focus-feature&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:194260416,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:0,&quot;publication_id&quot;:7373375,&quot;publication_name&quot;:&quot;Digital Onigiri&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!Twh4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25857f99-094a-420f-82d0-666a8c7c9f05_1024x1024.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>When a feature is central, that shadow is worth it. When a feature is peripheral, the shadow gets expensive.</p><p>YEN has already gone through this kind of pruning before. Chat, mail, and calendar were removed from the active product, but I kept the historical engineering packets so they can be understood or restored later without leaving compatibility code in the shipped app.</p><p>That is the pattern I want for a great Terminal:</p><ul><li><p>Remove the runtime surface when it no longer belongs</p></li><li><p>Preserve enough history to understand the decision</p></li><li><p>Keep old user data safe</p></li><li><p>Keep the release pipeline honest</p></li><li><p>Keep public documentation aligned with what actually ships</p></li></ul><p>That is different from pretending the feature never existed. It did exist. It taught me things. Some of the notification routing work still matters. The focused-window behavior still matters. Per-service delivery still matters. The Settings shape still matters.</p><p>The custom sound library just does not need to be part of the product anymore. Shipping as a solo developer means saying no even after saying yes once. It&#8217;s hard because I want to build everything.</p><p>But that just doesn&#8217;t make sense. Sometimes the best feature work is <strong>subtraction</strong>.</p><p>And in this case, we all just get a better product.</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[Receipts, Ports, and AppleScript]]></title><description><![CDATA[Three functional bets on a Terminal-First IDE]]></description><link>https://blog.yen.chat/p/receipts-ports-and-applescript</link><guid isPermaLink="false">https://blog.yen.chat/p/receipts-ports-and-applescript</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Fri, 01 May 2026 03:59:24 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!SOAX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcf97d8-22c9-40ac-9164-b4e977b4c3ba_1182x630.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>I&#8217;ve shipped three things into YEN over the last stretch that look unrelated on the surface &#8212; an agent evidence trail, a real port inspector, and full macOS scriptability. They are not unrelated. They are the same argument made three times.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>The argument is this: A terminal-first IDE is not a text editor with a terminal panel attached. It is the inverse. Start from the terminal and add the IDE capabilities that make the terminal safer, more contextual, and more trustworthy. Each of these three pieces is what that thesis actually looks like in code.</p><p>Here is what shipped, and why each one matters.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SOAX!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcf97d8-22c9-40ac-9164-b4e977b4c3ba_1182x630.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SOAX!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcf97d8-22c9-40ac-9164-b4e977b4c3ba_1182x630.png 424w, https://substackcdn.com/image/fetch/$s_!SOAX!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcf97d8-22c9-40ac-9164-b4e977b4c3ba_1182x630.png 848w, https://substackcdn.com/image/fetch/$s_!SOAX!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcf97d8-22c9-40ac-9164-b4e977b4c3ba_1182x630.png 1272w, https://substackcdn.com/image/fetch/$s_!SOAX!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcf97d8-22c9-40ac-9164-b4e977b4c3ba_1182x630.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SOAX!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcf97d8-22c9-40ac-9164-b4e977b4c3ba_1182x630.png" width="1200" height="639.5939086294417" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fbcf97d8-22c9-40ac-9164-b4e977b4c3ba_1182x630.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:630,&quot;width&quot;:1182,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:105950,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/196076811?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcf97d8-22c9-40ac-9164-b4e977b4c3ba_1182x630.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!SOAX!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcf97d8-22c9-40ac-9164-b4e977b4c3ba_1182x630.png 424w, https://substackcdn.com/image/fetch/$s_!SOAX!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcf97d8-22c9-40ac-9164-b4e977b4c3ba_1182x630.png 848w, https://substackcdn.com/image/fetch/$s_!SOAX!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcf97d8-22c9-40ac-9164-b4e977b4c3ba_1182x630.png 1272w, https://substackcdn.com/image/fetch/$s_!SOAX!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffbcf97d8-22c9-40ac-9164-b4e977b4c3ba_1182x630.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3><strong>If an agent touches your repo then your terminal should have receipts.</strong></h3><p>The current AI coding market has a trust problem that gets ignored because the demos look productive. A tool opens an agent session, edits files, runs a few commands, and then leaves behind something that feels more like vibes than evidence. You are expected to merge based on the fact that an agent looked busy.</p><p>That is not good enough.</p><p>YEN now ships <strong>yen agents list</strong>, <strong>yen agents open</strong>, <strong>yen agents timeline</strong>, <strong>yen agents note</strong>, <strong>yen agents export</strong>, and <strong>yen agents templates</strong> as a bounded local-first surface around first-party adapter profiles like <strong>claude</strong> and <strong>codex</strong>.</p><p><strong>yen agents open</strong> launches a session without pretending the adapter is more reliable than it is. If the binary is missing, the flow stays fail-open and drops to a normal shell. But when launch metadata is available, YEN records it: binary path, probe command, probe result, version, launch mode, fallback state, workspace identity, slot, branch, and dirty-state context. &#8220;The agent ran&#8221; is not one fact. There is a huge difference between &#8220;Claude launched normally in the expected workspace&#8221; and &#8220;the adapter was missing so the session really fell back to a shell.&#8221;</p><p><strong>yen agents timeline</strong> is the readable history surface for that state. Workspace-scoped, source-tagged, filterable. Session events show as <strong>agent:&lt;slot&gt;</strong>. Human notes are <strong>human</strong>. Supervisor-style notes are **supervisor**. Internal events are <strong>system</strong>. Output renders as text or JSON, with stable schema metadata so downstream consumers don&#8217;t reverse-engineer a second unofficial contract.</p><p>The important part is not the filter set. The important part is that the timeline doesn&#8217;t stop at &#8220;agent opened&#8221; and &#8220;agent closed.&#8221; It also carries the latest linked IDE evidence that already exists elsewhere in YEN &#8212; local <strong>verify</strong> and <strong>test</strong> results, <strong>quality</strong> and <strong>workflow</strong> reports, <strong>merge-readiness</strong> snapshots, PR-review evidence, current-branch CI state, and the local build-watch snapshot &#8212; through one shared evidence model.</p><p>Status is explicit. The timeline and export surfaces share an <strong>evidenceStatus</strong> vocabulary: <strong>missing-report</strong> when the artifact does not exist, <strong>stale-report</strong> when it exists but is too old to trust, <strong>unverified</strong> when no meaningful proof exists yet, and <strong>exported-with-gaps</strong> when I can still produce a bundle but the bundle itself tells you what is missing instead of pretending completeness.</p><p><strong>yen agents note</strong> is the missing human layer. Notes support lightweight templates for review approval, review rejection, handoff for review, and handoff for merge. They can validate that a note is actually bound to the right session or slot, so a human approval becomes a recorded part of the handoff instead of a sentence someone remembers writing in Slack ten minutes earlier.</p><p><strong>yen agents export</strong> turns the local session history into a handoff bundle in Markdown or JSON: timeline, approvals, handoffs, workspace-keyed repo context, risk summary, adapter metadata, explicit evidence gaps, linked IDE evidence references. It does not invent a second review namespace &#8212; it reuses the same truth YEN already uses for verification, workflow, merge-readiness, and PR review.</p><p>The whole surface stays local-first. Artifacts are local. Timeline is local. Notes are local. Export is local. Archive is opt-in. Retention is short by default at <strong>7 days</strong>. Redaction happens before saved artifacts are written. And if the capture path breaks, YEN fails open and preserves the terminal session rather than pretending the evidence story is stronger than it is.</p><p>That is what I mean by receipts.</p><div><hr></div><h3><strong>Your terminal should know what&#8217;s running on every port.</strong></h3><p>You are running Next.js on port 3000. Django on 8000. Postgres in Docker on 5432. Then something mysterious claims port 5000 and you have no idea what it is.</p><p>The usual answer is some combination of <strong>lsof</strong>, <strong>ps</strong>, and <strong>docker ps</strong> run separately, parsed manually, and forgotten immediately. Maybe you install a third-party tool that needs Node 18+ just to show you a table.</p><p>YEN already had <strong>yen ide ports</strong> as a basic <strong>lsof</strong> dump. Now it is a full port inspection surface:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;349091e2-9ef3-4f29-9ee9-75e9f73b04fd&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">bash
yen ide ports              # Dev ports with framework detection
yen ide ports --all        # Everything, including system services
yen ide ports 3000         # Deep dive on one port + optional kill
yen ide ports ps           # All dev processes with CPU / memory
yen ide ports clean        # Find and kill orphaned / zombie processes
yen ide ports watch        # Live monitor, 2-second polling</code></pre></div><p>Every subcommand supports <strong>--json</strong> for scripting and <strong>--yes</strong> to skip confirmation prompts. The default view is dev-focused &#8212; system services like <strong>ControlCenter</strong> and <strong>rapportd</strong> get filtered out unless you pass <strong>--all</strong>.</p><p>Framework detection runs in three tiers. First, process name and command-line pattern matching &#8212; <strong>python3 manage.py runserver</strong> is Django, <strong>bun run next dev</strong> is Next.js running on Bun. Twenty-plus frameworks covered: Next.js, Vite, Django, Flask, Uvicorn, Gunicorn, Rails, Spring, Supabase, Turso, Caddy, Traefik, Zig, Rust, Go, PHP, Deno, Bun, Node, Java, Ruby. Second, working-directory inspection &#8212; resolve each process&#8217;s <strong>cwd</strong> via <strong>lsof</strong>, walk up to find the project root by looking for <strong>package.json</strong>, <strong>go.mod</strong>, <strong>Cargo.toml</strong>, or <strong>pyproject.toml</strong>, then check for framework config files. Third, Docker container mapping &#8212; cross-reference <strong>docker ps</strong> to pull container names so Postgres, Redis, and nginx get named correctly instead of showing up as a mysterious <strong>docker-proxy</strong> process.</p><p>The result actually tells you what is going on:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;9bb3c34f-3ca3-4217-9b50-b6ab6e17ed90&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">COMMAND     PID      PORT     FRAMEWORK   UPTIME   CONTAINER   BIND
node        41023    3000     Next.js     2h 14m   &#8212;           *:3000
python3     41156    8000     Django      1h 03m   &#8212;           127.0.0.1:8000
docker-pr   41289    5432     PostgreSQL  4h 31m   myapp-db    *:5432
bun         41302    3100     Vite        22m 08s  &#8212;           *:3100</code></pre></div><p><strong>yen ide ports 3000</strong> shows everything about the process on that port &#8212; PID, user, CPU, memory, working directory, project root, git branch &#8212; then asks if you want to kill it. <strong>SIGTERM</strong> first, not <strong>SIGKILL</strong>, with a 2-second wait. Every kill gets logged to YEN&#8217;s IDE timeline because a terminal-first IDE should keep receipts on destructive actions.</p><p><strong>yen ide ports clean</strong> finds two kinds of problems: orphaned dev servers whose parent died and got reparented to PID 1, intersected with a dev-process allowlist so we don&#8217;t flag system daemons like <strong>httpd</strong> or <strong>cupsd</strong> as false positives; and zombie processes still holding a port. Both get listed with reasons, and you can batch-kill them with one confirmation prompt.</p><p><strong>yen ide ports watch</strong> polls every 2 seconds and reports opened and closed ports with timestamps, with <strong>trap</strong> cleanup on <strong>Ctrl + C</strong>, <strong>SIGTERM</strong>, or <strong>SIGHUP</strong> so the temp file doesn&#8217;t leak.</p><p>About 1,300 lines of bash and Python, 8 regression tests, no new dependencies &#8212; just <strong>lsof</strong>, <strong>ps</strong>, and <strong>docker</strong> stitched together into one terminal-native view.</p><div><hr></div><h3>Your terminal should be scriptable.</h3><p>Most terminals are black boxes. You launch them. Maybe you pass a command. That&#8217;s it.</p><p>The problem is that developers have workflows &#8212; not commands. &#8220;Open this project&#8221; means: navigate to the repo, split the window, start the test runner on the right, start the dev server on the left. Doing that manually every time is fine once. It&#8217;s friction at scale.</p><p>The standard answer in the macOS world is AppleScript. Terminals have historically been bad at it because they are fundamentally interactive processes &#8212; you can open a window, but can you address a specific surface? Can you tell a pane what to run?</p><p>YEN has a solution for this now. It ships a branded <strong>.sdef</strong>. Open Script Editor, find YEN.app in the Library, and browse the dictionary. The current surface is deliberate and minimal:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;5f0df62a-eee0-4096-bde6-b78eecd7792c&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">- new window &#8212; opens a terminal window
- new tab &#8212; opens a tab in the frontmost window
- split &#8212; splits the active surface
- surface configuration &#8212; lets you configure an individual surface
- Terminal objects have `pid` and `tty` properties</code></pre></div><p>YEN-native features &#8212; layout presets, scratchpad, tab sidebar, the PR review workspace &#8212; are not exposed through AppleScript `perform action`. The `Cmd + Option + 1-0` layout presets are intentionally not cloned into a second layout source of truth. Compose three-column layouts with `new tab` + `split` calls rather than replicating preset logic externally.</p><p>The App Intents surface shares the same canonical action-string catalog as AppleScript, so Shortcuts.app, Focus Filters, and Siri Shortcuts compose with the same YEN actions.</p><div><hr></div><h3>Why these three belong together.</h3><p>Each of these surfaces is a different cut at the same idea.</p><p>Agent receipts say: If a session changed the repo, the terminal should be able to answer &#8220;what exactly happened?&#8221; without asking you to trust a second system. The receipts stay close to the repo, the terminal, and the review flow you are already in.</p><p>Port inspection says: if a process is running, the terminal should be able to tell you what it is, where it lives, and let you kill it safely. With logging. Because a terminal-first IDE should keep receipts on destructive actions, even small ones.</p><p>Scriptability says: if your workflow has shape &#8212; open the project, split the panes, start the test runner &#8212; the terminal should let you encode that shape. Not as a brittle command sequence, but as something macOS Automation can address by surface, by `pid`, by `tty`.</p><p>In each case, the question is the same. Should this thing live in a separate hosted dashboard, a third-party CLI, or a JavaScript wrapper? Or should it live in the terminal you are already in?</p><p>I keep landing on the second answer. The terminal is where commands actually run, where repo state is visible, where output becomes real, where agents either prove their work or don&#8217;t. If that is true, then trust, observability, and scriptability belong there too &#8212; not bolted on, not in a browser tab, not behind a hosted account.</p><p>That is the bet. Not bigger spectacle. Better receipts.</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[Your Terminal Has a Browser Preview Now]]></title><description><![CDATA[It feels bigger than it is but it is kind of cool.]]></description><link>https://blog.yen.chat/p/browser</link><guid isPermaLink="false">https://blog.yen.chat/p/browser</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Sun, 26 Apr 2026 19:43:44 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!3Xyi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F078132cd-1919-4243-95d7-30e3234aa1a4_1164x672.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>I added a browser preview to YEN. That sentence can sound bigger than it is, so I want to be precise about it. YEN is not becoming a browser. It is not shipping Chromium. It is not turning into Electron. Eww.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>It is not trying to replace Safari, Arc, Chrome, Firefox, or whatever else you already use for the open web. What I shipped is much narrower and much more useful for the kind of product YEN is trying to be:</p><blockquote><p>A native WebKit preview surface, launched from the command palette or <strong>yen web</strong>, for docs, HTTPS pages, and local development servers.</p></blockquote><p>It is a standard window by default, with an explicit split when you ask for one. Yay.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!vQfG!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ce385-1d40-4b39-a013-b6b44a275993_2400x1624.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!vQfG!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ce385-1d40-4b39-a013-b6b44a275993_2400x1624.png 424w, https://substackcdn.com/image/fetch/$s_!vQfG!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ce385-1d40-4b39-a013-b6b44a275993_2400x1624.png 848w, https://substackcdn.com/image/fetch/$s_!vQfG!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ce385-1d40-4b39-a013-b6b44a275993_2400x1624.png 1272w, https://substackcdn.com/image/fetch/$s_!vQfG!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ce385-1d40-4b39-a013-b6b44a275993_2400x1624.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!vQfG!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ce385-1d40-4b39-a013-b6b44a275993_2400x1624.png" width="1200" height="811.8131868131868" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/065ce385-1d40-4b39-a013-b6b44a275993_2400x1624.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:985,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:435867,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/195181730?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ce385-1d40-4b39-a013-b6b44a275993_2400x1624.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!vQfG!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ce385-1d40-4b39-a013-b6b44a275993_2400x1624.png 424w, https://substackcdn.com/image/fetch/$s_!vQfG!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ce385-1d40-4b39-a013-b6b44a275993_2400x1624.png 848w, https://substackcdn.com/image/fetch/$s_!vQfG!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ce385-1d40-4b39-a013-b6b44a275993_2400x1624.png 1272w, https://substackcdn.com/image/fetch/$s_!vQfG!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F065ce385-1d40-4b39-a013-b6b44a275993_2400x1624.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Why Does a Terminal Need This?</h3><p>I keep coming back to the same idea with YEN: The <a href="https://blog.yen.chat/p/v1">terminal-first IDE</a> is not a text editor with a terminal panel attached. It is the reverse. Start from the terminal, then add the pieces that make terminal work more direct, more trustworthy, and less scattered.</p><p>A browser preview fits that idea, but only if it stays disciplined. Developers constantly bounce between the terminal and the browser:</p><ul><li><p>Documentation.</p></li><li><p>Localhost servers.</p></li><li><p>Preview pages.</p></li><li><p>Generated docs.</p></li><li><p>Release notes.</p></li><li><p>Internal references.</p></li></ul><p>That context switch is not always bad. The full browser is the right place for most browsing. But there is a class of terminal-adjacent web content where leaving the terminal flow feels heavier than the task deserves.</p><p>I do not want to open a whole browser tab just to check a local docs page. I do not want an embedded browser engine bundled into the terminal just because a preview window is useful. I do not want terminal links silently captured before the behavior has earned trust. </p><p>So the starting point is deliberately small: Open <strong>Cmd + Shift + P</strong>, type <strong>Browser</strong>, press <strong>Enter</strong>. Done and done.</p><p>From there, you can type an HTTPS URL, open a localhost or loopback development server, go back, go forward, reload, stop loading, or hand the current page to your default browser.</p><p>If you use <strong>yen web open</strong>, the command goes through the same policy. If you choose <strong>Browser Split</strong> or <strong>yen web open --split</strong>, YEN mounts the same preview beside the terminal in an app-owned split. That is it. That is the point.</p><h3>Native First, not Browser-Engine First.</h3><p>The easy way to add a browser-shaped feature is to ship a browser engine. That is also the expensive way.</p><p>Chromium-class runtimes bring subprocesses, GPU behavior, sandboxing complexity, packaging weight, security update pressure, and a huge amount of product gravity. Once you carry that runtime, the feature stops feeling like a preview window and starts pulling the whole app toward becoming a browser shell.</p><p>That is not YEN.</p><p>YEN already has a hard native-first rule: Before adding a dependency or vendored binary, check whether macOS already provides the right API. For this feature, macOS does. The preview uses Apple&#8217;s WebKit stack:</p><ul><li><p>WKWebView</p></li><li><p>WKWebViewConfiguration</p></li><li><p>WKNavigationDelegate</p></li><li><p>WKUIDelegate</p></li><li><p>WKWebsiteDataStore.nonPersistent</p></li><li><p>NSWorkspace.open</p></li></ul><p>That is the right shape for a Mac app. It keeps the feature small, native, reversible, and understandable. It also keeps the terminal engine out of the story. No Metal renderer changes. No swap-chain changes. No renderer-owned terminal-pane integration. No default-on hyperlink interception. No production data changes. No release artifact format changes. No vendored browser runtime.</p><p>Nothing that will get in the way or bloat the app.</p><p>The default browser preview is an app-owned utility window. The optional split is app-owned too. Neither one is a new foundation for the terminal engine.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MfXJ!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f558cda-73e9-4ac3-8ccd-dbff8285acb5_3640x2298.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MfXJ!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f558cda-73e9-4ac3-8ccd-dbff8285acb5_3640x2298.png 424w, https://substackcdn.com/image/fetch/$s_!MfXJ!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f558cda-73e9-4ac3-8ccd-dbff8285acb5_3640x2298.png 848w, https://substackcdn.com/image/fetch/$s_!MfXJ!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f558cda-73e9-4ac3-8ccd-dbff8285acb5_3640x2298.png 1272w, https://substackcdn.com/image/fetch/$s_!MfXJ!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f558cda-73e9-4ac3-8ccd-dbff8285acb5_3640x2298.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MfXJ!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f558cda-73e9-4ac3-8ccd-dbff8285acb5_3640x2298.png" width="1200" height="757.4175824175824" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/8f558cda-73e9-4ac3-8ccd-dbff8285acb5_3640x2298.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:919,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:1282352,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/195181730?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f558cda-73e9-4ac3-8ccd-dbff8285acb5_3640x2298.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MfXJ!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f558cda-73e9-4ac3-8ccd-dbff8285acb5_3640x2298.png 424w, https://substackcdn.com/image/fetch/$s_!MfXJ!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f558cda-73e9-4ac3-8ccd-dbff8285acb5_3640x2298.png 848w, https://substackcdn.com/image/fetch/$s_!MfXJ!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f558cda-73e9-4ac3-8ccd-dbff8285acb5_3640x2298.png 1272w, https://substackcdn.com/image/fetch/$s_!MfXJ!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F8f558cda-73e9-4ac3-8ccd-dbff8285acb5_3640x2298.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>The Trust Boundary is the URL Field</h3><p>The interesting part of this feature is not the toolbar. The interesting part is the policy.</p><p>If I put a web view inside a terminal, I need to be clear about what it is allowed to open.</p><p>The current rule is simple: HTTPS pages can load. Loopback HTTP can load.</p><p>But external schemes like <strong>mailto:</strong> and <strong>tel:</strong> get handed off to macOS from explicit top-level opens. Unsafe or surprising schemes get blocked.</p><p>And, of course, it&#8217;s <strong>private by default</strong>.</p><p>The shipped browser uses a non-persistent WebKit data store.</p><p>That means YEN is not trying to become your browser profile. It is not importing Safari cookies. It is not keeping a long-lived browsing history. It is not turning a preview window into another place where state silently accumulates.</p><p>That choice is partly about privacy. It is also about reversibility.</p><p>If a future expansion does not earn its place, I want to remove that expansion without leaving a weird pile of browser state behind.</p><p>That is one of the standards I keep trying to apply across YEN: New surfaces should stay easy to revert until they prove they belong.</p><p>Persistent browsing state might make sense later for a specific workflow. If it does, I want that to be a deliberate decision with a clear storage policy, a clear user control, and a clear rollback path.</p><p>For now, non-persistent is the right default.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!0Ywu!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcac378be-b1b7-4440-90bb-4d192ce96b69_2400x1624.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!0Ywu!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcac378be-b1b7-4440-90bb-4d192ce96b69_2400x1624.png 424w, https://substackcdn.com/image/fetch/$s_!0Ywu!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcac378be-b1b7-4440-90bb-4d192ce96b69_2400x1624.png 848w, https://substackcdn.com/image/fetch/$s_!0Ywu!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcac378be-b1b7-4440-90bb-4d192ce96b69_2400x1624.png 1272w, https://substackcdn.com/image/fetch/$s_!0Ywu!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcac378be-b1b7-4440-90bb-4d192ce96b69_2400x1624.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!0Ywu!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcac378be-b1b7-4440-90bb-4d192ce96b69_2400x1624.png" width="1200" height="811.8131868131868" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/cac378be-b1b7-4440-90bb-4d192ce96b69_2400x1624.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:985,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:497169,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/195181730?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcac378be-b1b7-4440-90bb-4d192ce96b69_2400x1624.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!0Ywu!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcac378be-b1b7-4440-90bb-4d192ce96b69_2400x1624.png 424w, https://substackcdn.com/image/fetch/$s_!0Ywu!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcac378be-b1b7-4440-90bb-4d192ce96b69_2400x1624.png 848w, https://substackcdn.com/image/fetch/$s_!0Ywu!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcac378be-b1b7-4440-90bb-4d192ce96b69_2400x1624.png 1272w, https://substackcdn.com/image/fetch/$s_!0Ywu!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fcac378be-b1b7-4440-90bb-4d192ce96b69_2400x1624.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>How and Why Does This Fit for YEN?</h3><p>The terminal is already where the work starts. You run the dev server there. You see the port there. You read the failing command there. You open the command palette there. You jump into docs there.</p><p>Cool.</p><p>The browser preview is useful because it respects that center of gravity. It gives YEN a small native window or explicit split for web context without asking the terminal to become a browser, and without asking the browser to become the IDE.</p><p>YEN should absorb useful developer workflow pieces only when they make terminal work feel more coherent. The file browser made sense because navigating files is part of terminal work.</p><p>The command palette made sense because discovery is part of terminal work. The IDE workflows made sense because trust, verification, review, and project context are part of terminal work. The browser preview makes sense only if it stays in that same category: A focused preview for terminal-adjacent web context.</p><p>Not the open web as a lifestyle. Not browser automation. Not a Chromium distribution in disguise. Just a small native bridge between the terminal and the pages developers actually need while working.</p><p>The best part is how little had to change. The core browser code lives in one isolated macOS feature folder. The command palette has two browser actions: <strong>Browser</strong> and <strong>Browser Split</strong>. The CLI and Settings integrations are narrow. The URL policy is a pure testable layer. The WebKit configuration is created up front.</p><p>The external handoff path checks whether macOS accepted the URL instead of pretending every handoff worked. That is the shape I want more YEN features to have.</p><p>Small surface. Clear policy. Native API. Easy rollback. Tests around the weird edges.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!3Xyi!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F078132cd-1919-4243-95d7-30e3234aa1a4_1164x672.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!3Xyi!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F078132cd-1919-4243-95d7-30e3234aa1a4_1164x672.png 424w, https://substackcdn.com/image/fetch/$s_!3Xyi!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F078132cd-1919-4243-95d7-30e3234aa1a4_1164x672.png 848w, https://substackcdn.com/image/fetch/$s_!3Xyi!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F078132cd-1919-4243-95d7-30e3234aa1a4_1164x672.png 1272w, https://substackcdn.com/image/fetch/$s_!3Xyi!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F078132cd-1919-4243-95d7-30e3234aa1a4_1164x672.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!3Xyi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F078132cd-1919-4243-95d7-30e3234aa1a4_1164x672.png" width="1164" height="672" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/078132cd-1919-4243-95d7-30e3234aa1a4_1164x672.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:672,&quot;width&quot;:1164,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:140988,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/195181730?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F078132cd-1919-4243-95d7-30e3234aa1a4_1164x672.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!3Xyi!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F078132cd-1919-4243-95d7-30e3234aa1a4_1164x672.png 424w, https://substackcdn.com/image/fetch/$s_!3Xyi!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F078132cd-1919-4243-95d7-30e3234aa1a4_1164x672.png 848w, https://substackcdn.com/image/fetch/$s_!3Xyi!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F078132cd-1919-4243-95d7-30e3234aa1a4_1164x672.png 1272w, https://substackcdn.com/image/fetch/$s_!3Xyi!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F078132cd-1919-4243-95d7-30e3234aa1a4_1164x672.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>The Bigger Point</h3><p>I think terminal products keep getting pulled in two directions.</p><p>One direction says the terminal should stay dumb forever. The other says the terminal should become a browser-shaped AI workspace with a shell somewhere inside it.</p><p>I do not like either answer.</p><p>The terminal should get smarter, but it should get smarter in a terminal-native way. That means native surfaces where native surfaces make sense. Local-first state where local-first state makes sense.</p><p>Explicit trust boundaries. No surprise capture. No giant runtime unless it truly earns its cost. No feature expansion without a keep-or-revert checkpoint. The browser preview is a small example of that philosophy.</p><p>It is not the centerpiece of YEN. It is not a pivot. It is just a useful native surface that lets the terminal-first workflow breathe a little more easily.</p><p>And sometimes that is exactly the kind of feature a product needs.</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[Focus is a Feature]]></title><description><![CDATA[On removing three whole product surfaces. Dang.]]></description><link>https://blog.yen.chat/p/focus-feature</link><guid isPermaLink="false">https://blog.yen.chat/p/focus-feature</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Mon, 20 Apr 2026 01:03:11 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!i59s!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40a2553b-a0a4-4121-9ea7-65a15cbea220_3640x2298.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>I just removed three whole product surfaces from YEN:</p><ol><li><p>Chat</p></li><li><p>Mail</p></li><li><p>Calendar</p></li></ol><p>This makes me a bit sad but it was as important of an update as many others in the last few months. Focus is a feature and it&#8217;s hard to do.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!i59s!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40a2553b-a0a4-4121-9ea7-65a15cbea220_3640x2298.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!i59s!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40a2553b-a0a4-4121-9ea7-65a15cbea220_3640x2298.png 424w, https://substackcdn.com/image/fetch/$s_!i59s!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40a2553b-a0a4-4121-9ea7-65a15cbea220_3640x2298.png 848w, https://substackcdn.com/image/fetch/$s_!i59s!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40a2553b-a0a4-4121-9ea7-65a15cbea220_3640x2298.png 1272w, https://substackcdn.com/image/fetch/$s_!i59s!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40a2553b-a0a4-4121-9ea7-65a15cbea220_3640x2298.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!i59s!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40a2553b-a0a4-4121-9ea7-65a15cbea220_3640x2298.png" width="1200" height="757.4175824175824" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/40a2553b-a0a4-4121-9ea7-65a15cbea220_3640x2298.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:919,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:1436150,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/194260416?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40a2553b-a0a4-4121-9ea7-65a15cbea220_3640x2298.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!i59s!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40a2553b-a0a4-4121-9ea7-65a15cbea220_3640x2298.png 424w, https://substackcdn.com/image/fetch/$s_!i59s!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40a2553b-a0a4-4121-9ea7-65a15cbea220_3640x2298.png 848w, https://substackcdn.com/image/fetch/$s_!i59s!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40a2553b-a0a4-4121-9ea7-65a15cbea220_3640x2298.png 1272w, https://substackcdn.com/image/fetch/$s_!i59s!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F40a2553b-a0a4-4121-9ea7-65a15cbea220_3640x2298.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>This is, of course, not the usual kind of release story. Most product writing is about what got added. This one is about what I decided not to keep carrying.</p><p>I think that matters, because one of the easiest ways to make a product worse is to confuse activity with progress. Shipping more things is easy to celebrate. Carrying more things forever is the part that gets expensive. </p><p>And it&#8217;s really easy to add features these days which means that the most important decisions is what you decide to not build and ship.</p><p>You see, for a while, YEN had a broader shape. It was not just a terminal-first IDE. It also had a community chat surface, a mail client, and a calendar client living inside the same product. At one level, that was interesting. It proved that the terminal could hold more of a working environment than people usually assume.</p><p>But there is a point where an interesting proof stops being the right product.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!rlAg!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2b7d3cb-1f28-45eb-a398-523814921975_2308x1436.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!rlAg!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2b7d3cb-1f28-45eb-a398-523814921975_2308x1436.png 424w, https://substackcdn.com/image/fetch/$s_!rlAg!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2b7d3cb-1f28-45eb-a398-523814921975_2308x1436.png 848w, https://substackcdn.com/image/fetch/$s_!rlAg!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2b7d3cb-1f28-45eb-a398-523814921975_2308x1436.png 1272w, https://substackcdn.com/image/fetch/$s_!rlAg!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2b7d3cb-1f28-45eb-a398-523814921975_2308x1436.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!rlAg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2b7d3cb-1f28-45eb-a398-523814921975_2308x1436.png" width="1456" height="906" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/e2b7d3cb-1f28-45eb-a398-523814921975_2308x1436.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:906,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:316060,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/194260416?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2b7d3cb-1f28-45eb-a398-523814921975_2308x1436.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!rlAg!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2b7d3cb-1f28-45eb-a398-523814921975_2308x1436.png 424w, https://substackcdn.com/image/fetch/$s_!rlAg!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2b7d3cb-1f28-45eb-a398-523814921975_2308x1436.png 848w, https://substackcdn.com/image/fetch/$s_!rlAg!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2b7d3cb-1f28-45eb-a398-523814921975_2308x1436.png 1272w, https://substackcdn.com/image/fetch/$s_!rlAg!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fe2b7d3cb-1f28-45eb-a398-523814921975_2308x1436.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The point is that I do not want YEN to become one more app that keeps every experiment alive because removing it would feel like admitting something. I would rather be honest about what is actually central.</p><p><strong>The central thing is the terminal-first IDE.</strong></p><p>That means:</p><ul><li><p>Native terminal quality</p></li><li><p>Trustworthy local workflows</p></li><li><p>File and project navigation</p></li><li><p>Build and review tooling</p></li><li><p>Command surfaces that make terminal work faster without making it feel fake</p></li></ul><p>Chat, mail, and calendar were not strengthening that center anymore. They were competing with it. And, to be honest, not many folks were using them but that&#8217;s also because we&#8217;re still pretty small (and growing).</p><p>The deeper problem is surface area. A product feature is not just a button or a command. It is an ongoing obligation. Chat meant backend tables, storage rules, attachment handling, proxy paths, privacy assumptions, moderation-adjacent questions, cleanup rules, and public documentation that had to stay true.</p><p>Mail and calendar meant OAuth flows, keychain assumptions, callback routes, local state contracts, desktop integration residue, notification semantics, legal/privacy copy, and recovery behavior for systems YEN did not control.</p><p>Even when those features are &#8220;done,&#8221; they are not done. They keep charging rent:</p><ul><li><p>Engineering attention</p></li><li><p>Test coverage</p></li><li><p>Release anxiety</p></li><li><p>Documentation maintenance</p></li><li><p>Privacy and legal review</p></li><li><p>Restore-path complexity during unrelated refactors</p></li></ul><p>That is the part people underestimate and certainly not something that anyone non-technical would even think about (although those folks are probably not using YEN).</p><p>A small feature that touches auth, network boundaries, notifications, storage, and public docs is not small. It is a permanent tax. No one likes taxes. Taxes suck.</p><p><strong>But the the non-obvious gain is trust.</strong></p><p>I think product focus is often described too softly, like it is mostly an aesthetic preference. It is not. Focus improves trust. Every feature I remove is one less thing that can silently drift out of sync. One less thing that can break on release day. One less public claim that can become false. One less background system whose edge cases I have to remember when I am changing something that should have been unrelated.</p><p>That matters a lot for a terminal-first IDE, because this kind of product only works if people believe the boundaries are legible.</p><p>Subtraction is part of honesty. YEN does not get stronger by collecting adjacent ideas forever. It gets stronger by becoming more exact about what it is for.</p><p>The best version of YEN is not &#8220;the app that also does everything else.&#8221; It is the app where the terminal is the center of gravity, the desktop integration feels native, the workflows are trustworthy, and the extra surface area earns its place.</p><p>Chat, mail, and calendar stopped earning their place. So I removed them. I think more products should do that.</p><p>There is a lot of pressure in software to act like every shipped feature is sacred. I do not buy that. Sometimes the highest-leverage feature is the one you stop shipping. Sometimes the most user-respecting thing you can do is narrow the promise. Sometimes focus is not what remains after product strategy.</p><p>Focus is the product strategy. That is what this cleanup was really about.</p><p>YEN is better when it is more itself, as it has been and as it should be. Authenticity. Truthfulness. Clarity. Focus. The result? Even greater productivity.</p><p>That&#8217;s the point.</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[CMD + V Should Mean Paste]]></title><description><![CDATA[Making the obvious, obvious. Because, it's obvious.]]></description><link>https://blog.yen.chat/p/paste</link><guid isPermaLink="false">https://blog.yen.chat/p/paste</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Wed, 15 Apr 2026 04:00:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!Slw5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa60fa19e-dd6b-41c7-b046-8b812aa53cf7_1200x700.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>Every other Mac app in my life has trained my hands the same way. <strong>Cmd + C</strong> copies. <strong>Cmd + V</strong> pastes. If a shortcut needs a paragraph of explanation before it makes sense, the shortcut is probably wrong.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>I ran into exactly that problem in YEN. <strong>Ctrl + V</strong> could still move clipboard data through the terminal stack, but <strong>Cmd + V</strong> did not behave like a real Mac app. That sounds small until you remember what YEN is trying to be.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Slw5!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa60fa19e-dd6b-41c7-b046-8b812aa53cf7_1200x700.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Slw5!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa60fa19e-dd6b-41c7-b046-8b812aa53cf7_1200x700.png 424w, https://substackcdn.com/image/fetch/$s_!Slw5!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa60fa19e-dd6b-41c7-b046-8b812aa53cf7_1200x700.png 848w, https://substackcdn.com/image/fetch/$s_!Slw5!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa60fa19e-dd6b-41c7-b046-8b812aa53cf7_1200x700.png 1272w, https://substackcdn.com/image/fetch/$s_!Slw5!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa60fa19e-dd6b-41c7-b046-8b812aa53cf7_1200x700.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Slw5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa60fa19e-dd6b-41c7-b046-8b812aa53cf7_1200x700.png" width="728" height="424.6666666666667" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/a60fa19e-dd6b-41c7-b046-8b812aa53cf7_1200x700.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:700,&quot;width&quot;:1200,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:8321,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/194259533?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa60fa19e-dd6b-41c7-b046-8b812aa53cf7_1200x700.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Slw5!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa60fa19e-dd6b-41c7-b046-8b812aa53cf7_1200x700.png 424w, https://substackcdn.com/image/fetch/$s_!Slw5!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa60fa19e-dd6b-41c7-b046-8b812aa53cf7_1200x700.png 848w, https://substackcdn.com/image/fetch/$s_!Slw5!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa60fa19e-dd6b-41c7-b046-8b812aa53cf7_1200x700.png 1272w, https://substackcdn.com/image/fetch/$s_!Slw5!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fa60fa19e-dd6b-41c7-b046-8b812aa53cf7_1200x700.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Well, this now works in v1.036.</p><p>I have been building YEN around a simple thesis: The terminal-first IDE should feel more like a real desktop app, not less. If I am asking people to live in the terminal for IDE flows and agent work and more, then, I do not get to shrug when one of the most basic desktop behaviors feels off.</p><p>So, why doesn&#8217;t upstream libghostty do this? Because it&#8217;s a terminal emulator while YEN is a terminal -first IDE with path-oriented workflows around Codex, Claude, local tools, and file-aware commands.</p><p>And so that&#8217;s fine since it&#8217;s behaving like any normal, ordinary terminal paste behavior for the kinds of payloads a terminal naturally understands. But, I wanted just a bit more than that.</p><p>That is an important distinction. This is not &#8220;libghostty forgot paste&#8221; or anything funky like that; it&#8217;s just that we have a very different product policy.</p><h3>What Changed and Why This Matters</h3><p>I fixed the hotkey at the right layer first.</p><p>Instead of asking &#8220;is this the <strong>Cmd + </strong>* keystroke shape?&#8221; YEN now asks &#8220;what menu action did YEN resolve this event to?&#8221; If the resolved action is <strong>paste</strong>: or <strong>pasteSelection</strong>:, and the relevant clipboard has contents, the surface routes through AppKit the way a native Mac app should.</p><p>That matters because it avoids stealing unrelated shortcuts.</p><p>If someone remaps a binding or another YEN command happens to share a similar keystroke shape, the bypass stays closed unless the resolved menu action is actually a paste action. That is the difference between a shortcut hack and a native fix.</p><p>So, why does this matter? Well, I think a lot of terminal work gets framed as performance, rendering, tabs, themes, or shell integration. All of that matters.</p><p>But the terminal-first IDE also has to solve a quieter problem: If I am asking you to live in the terminal for more of your day, the terminal has to stop feeling like the place where desktop behavior goes to die.</p><p>That means tiny things matter.</p><p><strong>Cmd + V</strong> should mean paste. And now it behaves like it should on macOS.</p><p>And if the terminal is going to be the IDE, that is the level of care it has to absorb.</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[YEN v1.000 is Here]]></title><description><![CDATA[The story of how YEN became a Terminal-first IDE.]]></description><link>https://blog.yen.chat/p/v1</link><guid isPermaLink="false">https://blog.yen.chat/p/v1</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Mon, 30 Mar 2026 03:59:48 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!1d4f!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35cf4358-a285-468c-a2a8-861ad44196db_2178x1398.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>Well&#8230; we&#8217;ve done it, folks. YEN is officially v1.0! Whoot. &#127881;</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>I do not use version numbers as marketing confetti, though. I mean,  v1.000 &#8212; or how I&#8217;ve been numbering it &#8212; is not me pretending the work is done. It is me saying the thesis is real now. The product I wanted to build is no longer hypothetical. It is in the repo, in the shipped app, in the release harness, in the native macOS surfaces, and in the command surface I use every day.</p><p>I use YEN to build YEN, a fun little personal project &#8212; built on top of <a href="https://libghostty.tip.ghostty.org/index.html">libghostty</a> &#8212;  that a lot of folks have started to use. For that, I am super grateful.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!1d4f!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35cf4358-a285-468c-a2a8-861ad44196db_2178x1398.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!1d4f!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35cf4358-a285-468c-a2a8-861ad44196db_2178x1398.png 424w, https://substackcdn.com/image/fetch/$s_!1d4f!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35cf4358-a285-468c-a2a8-861ad44196db_2178x1398.png 848w, https://substackcdn.com/image/fetch/$s_!1d4f!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35cf4358-a285-468c-a2a8-861ad44196db_2178x1398.png 1272w, https://substackcdn.com/image/fetch/$s_!1d4f!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35cf4358-a285-468c-a2a8-861ad44196db_2178x1398.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!1d4f!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35cf4358-a285-468c-a2a8-861ad44196db_2178x1398.png" width="1200" height="770.6043956043956" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/35cf4358-a285-468c-a2a8-861ad44196db_2178x1398.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:935,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:127743,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/190887539?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35cf4358-a285-468c-a2a8-861ad44196db_2178x1398.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!1d4f!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35cf4358-a285-468c-a2a8-861ad44196db_2178x1398.png 424w, https://substackcdn.com/image/fetch/$s_!1d4f!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35cf4358-a285-468c-a2a8-861ad44196db_2178x1398.png 848w, https://substackcdn.com/image/fetch/$s_!1d4f!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35cf4358-a285-468c-a2a8-861ad44196db_2178x1398.png 1272w, https://substackcdn.com/image/fetch/$s_!1d4f!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F35cf4358-a285-468c-a2a8-861ad44196db_2178x1398.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>The Thesis.</h3><p>Most IDEs are text editors that bolted on a terminal panel. The editor gets the architecture. The terminal gets a rectangle near the bottom of the window. The editor gets search, code intelligence, review, migration, workflow automation, collaboration, and the language about focus and speed. The terminal gets treated like a utility room.</p><p>I wanted the <a href="https://blog.yen.chat/p/ide3">opposite</a>.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;5581c010-e8a7-46fd-8c59-ef8bb67c36c9&quot;,&quot;caption&quot;:&quot;Hey folks!&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;A Terminal-First IDE and Earning Trust&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:54423,&quot;name&quot;:&quot;8Lee&quot;,&quot;bio&quot;:&quot;Designer. Engineer. Master of the selfpwn.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6992612f-3d11-4a2c-83c1-0518674db408_1024x1024.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2026-03-24T15:20:30.551Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!oRXr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff94d3725-efe4-4fd9-9205-12aa19a4b651_2244x1338.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://blog.yen.chat/p/ide3&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:191990324,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:0,&quot;publication_id&quot;:7373375,&quot;publication_name&quot;:&quot;Digital Onigiri&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!Twh4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25857f99-094a-420f-82d0-666a8c7c9f05_1024x1024.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>Because the terminal is where code meets reality. It is where builds fail, services restart, migrations run, diagnostics become useful, containers get launched, review comments turn into actions, and dangerous commands should feel dangerous before you press the &#8220;Enter&#8221; key. </p><p>YEN starts with a fast native terminal on macOS and layers IDE capability around that terminal-first workflow. Keep the core local-first. Use native APIs where they are genuinely better. Stay in the terminal unless a richer native surface is actually justified.</p><p>That is the whole product in one paragraph.</p><div><hr></div><h3>What v1.0 Actually Ships.</h3><p>This is not a terminal with a roadmap attached. It is already a broad terminal-first system. The new IDE layer matters most here. </p><p>YEN now ships project detection, trusted environment loading, local LSP lifecycle and diagnostics, AST fallback, universal project search, verification bundles, approval gates for risky commands, workflow execution, PR review tooling, terminal sharing, local devcontainer control, deterministic VS Code inventory and import, and native macOS PR review and merge-conflict workspaces launched from the command palette. That is the point where &#8220;<strong>terminal-first IDE</strong>&#8221; stopped being a slogan and became a product characteristic.</p><p>But v1.0 is not only an IDE story. It is also a story about making the terminal feel like an environment instead of a blank shell. YEN ships a built-in <a href="https://blog.yen.chat/p/upgrading-the-file-browser-with-native">file browser</a>, <a href="https://blog.yen.chat/p/discover-all-the-things-in-your-terminal">command palette</a>, tab <a href="https://blog.yen.chat/p/your-terminal-has-a-sidebar-now">sidebar</a>, <a href="https://blog.yen.chat/p/your-terminal-has-a-scratchpad-now">scratchpad</a>, split layout presets, split labels, <a href="https://blog.yen.chat/p/save-screenshots-in-your-terminal">screenshot</a> tooling, curated <a href="https://blog.yen.chat/p/450-themes-for-your-terminal">themes</a>, keyboard remapping with conflict detection, managed notification sounds, bundled CLI tools, weather, and a pile of native macOS utility surfaces that make the product feel inhabited on first launch instead of empty.</p><p>It also ships communication where most terminals would not even try. <a href="https://blog.yen.chat/p/safe-chat">Chat</a>, mail, and calendar are all separate Go TUIs. Mail and calendar use OAuth with PKCE and store tokens in the macOS keychain. Chat runs through mediated YEN-owned API surfaces, binds identity server-side, and keeps anonymous direct database access intentionally closed. None of that exists as novelty for novelty&#8217;s sake. It exists because I think the terminal can hold more of a working environment than most tools assume, especially when it removes the lazy default of making you tab back out to a web app for a workflow you were already in the middle of.</p><div><hr></div><h3>The Terminal-First IDE Part.</h3><p>The newest layer is the one I cared about most going into this milestone. I did not want YEN to say &#8220;terminal-first&#8221; and then quietly shove the serious workflows into a browser pane, a cloud dashboard, or a second application model. I wanted the terminal to stay central.</p><p>That is why the IDE layer stays honest about what it is doing. If YEN is using live LSP, it says so. If it falls back to AST, it says so. If a project has not been trusted, it says so. If a share session exists, it is explicit. If a command is risky, the gate should behave like it. The command palette is not just a launcher any more. It is a terminal-native IDE entry point. The native macOS review and merge-conflict windows are not an escape hatch away from the terminal. They are closer-to-the-metal extensions of the same workflow.</p><p>That distinction matters to me. I am not trying to cosplay as a giant editor suite. I am trying to build an IDE around the place where engineers already end up doing the real work.</p><div><hr></div><h3>The Technical Patterns That Made It Work.</h3><p>The most important pattern in YEN is vendor, do not fork. The upstream terminal engine stays mirrored as an exact upstream tree. YEN-specific behavior lives in overlays and integration layers. The same philosophy shows up in bundled tools. If an upstream project already does the job well, I would rather integrate it carefully than reinvent it badly just to preserve some fantasy of purity.</p><p>The second pattern is native-first. If macOS already has the right API, I want to use the OS instead of shipping a giant dependency. That is why YEN uses native helpers for video, PDF, and SVG preview paths, native keychain handling, native notification delivery, native screenshot flows, and native AppKit utility windows. </p><p>It is also why the bundle shed a ridiculous amount of weight: Replacing ffmpeg, poppler, and 7zip-style baggage with native helpers and system tooling saved about 258.8 MB compared with the heavier alternative. That kind of decision is not glamorous, but it changes what the product feels like to install, ship, and maintain.</p><p>The third pattern is trust before convenience. I do not want silent authority. Project trust, environment trust, LSP trust, sharing trust, workflow trust, and release verification all exist because I would rather add a little ceremony than hide risk behind a friendly button label.</p><h3>The Native macOS Bet.</h3><p>YEN is intentionally macOS-first. That is not an accident and it is not a temporary inconvenience I keep apologizing for. It is the product bet.</p><p>The clearest example is <a href="https://blog.yen.chat/p/s2t">speech-to-text</a>. Press <strong>Option + Space</strong> and YEN can capture audio, transcribe it on-device using Apple&#8217;s speech stack, show live state in a floating overlay, recover cleanly when permissions or local speech assets are missing, and insert the result back into the active context. </p><p><strong>That works inside YEN and across other macOS apps</strong>. The same native bet shows up in settings, preview helpers, notifications, launch-at-login behavior, keychain-backed auth, screenshot tooling, and the command-palette-driven utility surfaces.</p><p>The trade-off is obvious. I do not get to claim &#8220;runs everywhere.&#8221; The upside is just as obvious. I get depth instead of pretending that a lowest-common-denominator abstraction is enough.</p><div><hr></div><h3>What the Repo Says.</h3><p>I did not want this post to hand-wave the effort. The numbers below are the repo snapshot as of <strong>March 29, 2026</strong>:</p><ul><li><p><strong>Start:</strong> November 6, 2025</p></li><li><p><strong>Commits:</strong> 4,616</p></li><li><p><strong>Time:</strong> 144 days</p></li><li><p><strong>Average:</strong> 32.06 commits per day</p></li><li><p><strong>Lines of Code:</strong> 136,000</p></li><li><p><strong>Contributors:</strong> 1</p></li></ul><p>And yes, the contributor count is the part that still hits me emotionally. There is no hidden engineering org behind this post. It is just me, the repo, the build system &#8212; <a href="https://blog.yen.chat/p/skills">which is cool af</a> &#8212; and the users, and a stupid number of tiny decisions stacked on top of each other until they started to look like a product.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;5fd597e8-0020-47f5-82b1-9a02769137cd&quot;,&quot;caption&quot;:&quot;A big thank you to Codex SF for hosting an event that inspired this long sermon on agent harnesses, to George for allowing me to speak, to Andrew and George setting the tone, and to Angela who was the first to ask for my presentation!&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;From Makefiles to Agentic Skills: Shipping a 30-Language Desktop App via a Single Command&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:54423,&quot;name&quot;:&quot;8Lee&quot;,&quot;bio&quot;:&quot;Designer. Engineer. Master of the selfpwn.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6992612f-3d11-4a2c-83c1-0518674db408_1024x1024.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2026-03-07T17:01:15.496Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!ERiy!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9dcea0c3-f779-4498-a2fa-b765b5ed9969_2782x1890.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://blog.yen.chat/p/skills&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:190176100,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:3,&quot;comment_count&quot;:2,&quot;publication_id&quot;:7373375,&quot;publication_name&quot;:&quot;Digital Onigiri&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!Twh4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25857f99-094a-420f-82d0-666a8c7c9f05_1024x1024.png&quot;,&quot;belowTheFold&quot;:true,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>But I made it.</p><div><hr></div><h3>The Scope Was Bigger Than One App.</h3><p>YEN stopped being "one app" a while ago. The repo includes the <strong>marketing site</strong>, the release <strong>metadata surface</strong>, the <strong>desktop app</strong>, the <strong>overlay system</strong>, <strong>build and release automation</strong>, the <strong>CLI entrypoint</strong>, <strong>chat</strong>, <strong>mail</strong>, <strong>calendar</strong>, shared <strong>auth</strong> packages, <strong>database</strong> migrations, <strong>docs</strong>, <strong>tests</strong>, and a fairly serious <strong>asset pipeline</strong>.</p><p>Yeah, it&#8217;s a lot.<br><br>That breadth is exactly why I keep describing YEN as a <a href="https://blog.yen.chat/p/skills">system</a>. The desktop app matters, obviously, but the product is also the release harness, the signing discipline, the docs, the migration logic, the auth model, the sound-pack delivery, the updater, the whitepaper, and the public website that stays in sync with what ships.</p><p>I&#8217;m pretty fucking proud of it all, to be honest.</p><div><hr></div><h3>What I Learned Building This Alone.</h3><p>A few thoughts on this topic, while we&#8217;re here:</p><ol><li><p><strong>Scope is survivable if the system is honest.</strong> A repo this broad only stays manageable if the build fails loudly, the trust model stays explicit, the docs remain current enough to lean on, and the release path is deterministic enough that I can sleep after a ship.</p></li><li><p><strong>Shipping teaches faster than theorizing.</strong> I could have spent another six months polishing a grand story about terminal-first computing. That would have been a mistake. The actual product got better because I shipped, watched where friction showed up, fixed it, and repeated that process an embarrassing number of times.</p></li><li><p><strong>Documentation is leverage.</strong> The 15k lines of docs in this repo are not decoration. They are a force multiplier. Once a project gets this broad, undocumented decisions become a tax on every future change, especially when the future developer is still just me.</p></li><li><p><strong>Taste matters.</strong> I do not buy the idea that taste is fluff. Taste is what decides whether a shortcut belongs, whether a command palette feels honest, whether a panel deserves to exist, whether a feature should stay terminal-native, whether a native window is warranted, and whether a clever abstraction is actually making the product worse.</p></li><li><p><strong>Solo does not mean small.</strong> Solo still means constrained. It still means trade-offs. It still means there are things I cannot do yet. But it does not have to mean shallow. With the right architecture, automation, documentation habits, and release discipline, a solo developer can build something wide and deep without pretending it is small.</p></li></ol><p>This has been a very fun trip and one that&#8217;s just beginning since it&#8217;s a daily tool that I need to use to feed and clothe myself. So, I&#8217;ll be here for a while, cranking on YEN every single day because I just really, <em>really</em>, <em><strong>really</strong></em> like it.</p><p>YEN isn&#8217;t just a fast terminal. It is not just a speech-to-text experiment. It is not just a file browser wrapper. It is not just a fun macOS utility surface. It is a terminal-first IDE platform with a clear thesis, a local-first core, explicit trust boundaries, a real shipped IDE layer, native macOS depth, bundled first-launch usefulness, and a release system that can keep up with the ambition of the product.</p><p>And that&#8217;s what the milestone marks.</p><p>Not perfection.</p><p>Not completion.</p><p>Clarity.</p><div><hr></div><h3>What Comes Next.</h3><p>There is still a lot left to do. There is more IDE depth to build, more workflow hardening to do, more collaboration and review ergonomics to refine, more polish to add to the native surfaces, and more places where trust, diagnostics, and context can get sharper.</p><p>But I feel very differently about the project now than I did a few months ago. The shape is clear. The identity is clear. The system can carry the ambition now.</p><p>If you have been following along, testing builds, reading posts, reporting bugs, or just quietly paying attention while I kept shipping into the void, thank you. This milestone has my name on it in git history, but no product gets here in a vacuum. The feedback loops mattered. The curiosity mattered. The pressure to keep the quality bar high mattered. It helps. I&#8217;m grateful.</p><p>YEN v1.0 is here, and I&#8217;m just getting started.</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[Better Terminal Image Background Placements]]></title><description><![CDATA[Now you can chose between the entire Window or Splits.]]></description><link>https://blog.yen.chat/p/wallpaper</link><guid isPermaLink="false">https://blog.yen.chat/p/wallpaper</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Sat, 28 Mar 2026 17:50:47 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!pcN0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e4d1dbc-8f57-445b-8345-3457167410d1_1590x640.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>There&#8217;s a small feature in the latest YEN release that I&#8217;m weirdly proud of, and it took me longer to design than to build: The background image and wallpaper scope toggle.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>This is the second part of the, well, first part about <a href="https://blog.yen.chat/p/your-terminal-feels-more-like-your">wallpapers</a>.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;a6a1507c-78be-4855-a0cd-2bc96ea420ec&quot;,&quot;caption&quot;:&quot;Hey folks!&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Your Terminal Feels More Like Your World&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:54423,&quot;name&quot;:&quot;8Lee&quot;,&quot;bio&quot;:&quot;Engineer. Designer. Really bad dad jokes.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6992612f-3d11-4a2c-83c1-0518674db408_1024x1024.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2026-03-26T23:28:31.677Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!NWjb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c081d-046d-4910-a94d-5260ca806e54_3640x2298.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://blog.yen.chat/p/your-terminal-feels-more-like-your&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:192262123,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:1,&quot;comment_count&quot;:0,&quot;publication_id&quot;:7373375,&quot;publication_name&quot;:&quot;Digital Onigiri&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!Twh4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25857f99-094a-420f-82d0-666a8c7c9f05_1024x1024.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!pcN0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e4d1dbc-8f57-445b-8345-3457167410d1_1590x640.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!pcN0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e4d1dbc-8f57-445b-8345-3457167410d1_1590x640.png 424w, https://substackcdn.com/image/fetch/$s_!pcN0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e4d1dbc-8f57-445b-8345-3457167410d1_1590x640.png 848w, https://substackcdn.com/image/fetch/$s_!pcN0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e4d1dbc-8f57-445b-8345-3457167410d1_1590x640.png 1272w, https://substackcdn.com/image/fetch/$s_!pcN0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e4d1dbc-8f57-445b-8345-3457167410d1_1590x640.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!pcN0!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e4d1dbc-8f57-445b-8345-3457167410d1_1590x640.png" width="1200" height="482.967032967033" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4e4d1dbc-8f57-445b-8345-3457167410d1_1590x640.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:586,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:253243,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/192437626?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e4d1dbc-8f57-445b-8345-3457167410d1_1590x640.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!pcN0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e4d1dbc-8f57-445b-8345-3457167410d1_1590x640.png 424w, https://substackcdn.com/image/fetch/$s_!pcN0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e4d1dbc-8f57-445b-8345-3457167410d1_1590x640.png 848w, https://substackcdn.com/image/fetch/$s_!pcN0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e4d1dbc-8f57-445b-8345-3457167410d1_1590x640.png 1272w, https://substackcdn.com/image/fetch/$s_!pcN0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4e4d1dbc-8f57-445b-8345-3457167410d1_1590x640.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>The Question Nobody Asks but Everyone Has</h3><p>When you set a background image in YEN, what does &#8220;background&#8221; mean?</p><p>If you have three splits open &#8212; one running tests, one tailing logs, one with your editor &#8212; does the image live behind all of them? Just the focused split? The whole window? If you open a new tab, does that tab get the image too?</p><p>This is one of those settings that feels obvious until you try to define it.</p><p>I went through a few different mental models before landing on the one we ship:</p><ol><li><p><strong>Global (all windows)</strong> &#8212; The image is a wallpaper. It&#8217;s yours, not the terminal&#8217;s. Wherever YEN renders, the image is there. Good for people who set one image and forget it.</p></li><li><p><strong>Per-tab</strong> &#8212; The image belongs to the current tab&#8217;s context. Switch tabs, different look. Split panes within a tab share the same image. This is the default because it maps cleanly to how most people think about &#8220;what I&#8217;m working on right now.&#8221;</p></li><li><p><strong>Per-split</strong> &#8212; Maximum granularity. Each pane is its own visual context. You can have a dark ocean render behind your SSH session and a warm linen texture behind your local dev split. This is for people who want their terminal to reflect what each pane is doing.</p></li></ol><p>But, ultimately I wanted to keep it simple. Here&#8217;s the experience:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!kmU9!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42a1770b-4df7-435d-9918-489c5ba3fb11_3640x2298.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!kmU9!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42a1770b-4df7-435d-9918-489c5ba3fb11_3640x2298.png 424w, https://substackcdn.com/image/fetch/$s_!kmU9!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42a1770b-4df7-435d-9918-489c5ba3fb11_3640x2298.png 848w, https://substackcdn.com/image/fetch/$s_!kmU9!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42a1770b-4df7-435d-9918-489c5ba3fb11_3640x2298.png 1272w, https://substackcdn.com/image/fetch/$s_!kmU9!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42a1770b-4df7-435d-9918-489c5ba3fb11_3640x2298.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!kmU9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42a1770b-4df7-435d-9918-489c5ba3fb11_3640x2298.png" width="1456" height="919" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/42a1770b-4df7-435d-9918-489c5ba3fb11_3640x2298.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:919,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:265451,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/192437626?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42a1770b-4df7-435d-9918-489c5ba3fb11_3640x2298.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!kmU9!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42a1770b-4df7-435d-9918-489c5ba3fb11_3640x2298.png 424w, https://substackcdn.com/image/fetch/$s_!kmU9!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42a1770b-4df7-435d-9918-489c5ba3fb11_3640x2298.png 848w, https://substackcdn.com/image/fetch/$s_!kmU9!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42a1770b-4df7-435d-9918-489c5ba3fb11_3640x2298.png 1272w, https://substackcdn.com/image/fetch/$s_!kmU9!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F42a1770b-4df7-435d-9918-489c5ba3fb11_3640x2298.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Start with a blank canvas, your Terminal. And then you can add an image:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!fD1e!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F444aa2b0-3e45-441d-9f9e-434284a148a5_3640x2298.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!fD1e!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F444aa2b0-3e45-441d-9f9e-434284a148a5_3640x2298.png 424w, https://substackcdn.com/image/fetch/$s_!fD1e!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F444aa2b0-3e45-441d-9f9e-434284a148a5_3640x2298.png 848w, https://substackcdn.com/image/fetch/$s_!fD1e!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F444aa2b0-3e45-441d-9f9e-434284a148a5_3640x2298.png 1272w, https://substackcdn.com/image/fetch/$s_!fD1e!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F444aa2b0-3e45-441d-9f9e-434284a148a5_3640x2298.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!fD1e!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F444aa2b0-3e45-441d-9f9e-434284a148a5_3640x2298.png" width="1456" height="919" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/444aa2b0-3e45-441d-9f9e-434284a148a5_3640x2298.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:919,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:8663571,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/192437626?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F444aa2b0-3e45-441d-9f9e-434284a148a5_3640x2298.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!fD1e!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F444aa2b0-3e45-441d-9f9e-434284a148a5_3640x2298.png 424w, https://substackcdn.com/image/fetch/$s_!fD1e!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F444aa2b0-3e45-441d-9f9e-434284a148a5_3640x2298.png 848w, https://substackcdn.com/image/fetch/$s_!fD1e!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F444aa2b0-3e45-441d-9f9e-434284a148a5_3640x2298.png 1272w, https://substackcdn.com/image/fetch/$s_!fD1e!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F444aa2b0-3e45-441d-9f9e-434284a148a5_3640x2298.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Or you can make the images per split:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!MUGa!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03cb11ba-7bd8-4d5f-9a99-fb1a9f35177f_3640x2298.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!MUGa!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03cb11ba-7bd8-4d5f-9a99-fb1a9f35177f_3640x2298.png 424w, https://substackcdn.com/image/fetch/$s_!MUGa!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03cb11ba-7bd8-4d5f-9a99-fb1a9f35177f_3640x2298.png 848w, https://substackcdn.com/image/fetch/$s_!MUGa!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03cb11ba-7bd8-4d5f-9a99-fb1a9f35177f_3640x2298.png 1272w, https://substackcdn.com/image/fetch/$s_!MUGa!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03cb11ba-7bd8-4d5f-9a99-fb1a9f35177f_3640x2298.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!MUGa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03cb11ba-7bd8-4d5f-9a99-fb1a9f35177f_3640x2298.png" width="1456" height="919" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/03cb11ba-7bd8-4d5f-9a99-fb1a9f35177f_3640x2298.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:919,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:9631832,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/192437626?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03cb11ba-7bd8-4d5f-9a99-fb1a9f35177f_3640x2298.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!MUGa!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03cb11ba-7bd8-4d5f-9a99-fb1a9f35177f_3640x2298.png 424w, https://substackcdn.com/image/fetch/$s_!MUGa!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03cb11ba-7bd8-4d5f-9a99-fb1a9f35177f_3640x2298.png 848w, https://substackcdn.com/image/fetch/$s_!MUGa!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03cb11ba-7bd8-4d5f-9a99-fb1a9f35177f_3640x2298.png 1272w, https://substackcdn.com/image/fetch/$s_!MUGa!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F03cb11ba-7bd8-4d5f-9a99-fb1a9f35177f_3640x2298.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Pretty neat and as I&#8217;ve said <a href="https://blog.yen.chat/p/your-terminal-feels-more-like-your">before</a>, it makes it feel so much more personal. And that&#8217;s the update folks. Enjoy.</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[Your Terminal Feels More Like Your World]]></title><description><![CDATA[Background images are here and that's it, that's the announce.]]></description><link>https://blog.yen.chat/p/your-terminal-feels-more-like-your</link><guid isPermaLink="false">https://blog.yen.chat/p/your-terminal-feels-more-like-your</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Thu, 26 Mar 2026 23:28:31 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!NWjb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c081d-046d-4910-a94d-5260ca806e54_3640x2298.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks! </p><p>I built a background image upload that just makes it feel more like your own personal space. It&#8217;s available directly via the Settings Panel and there you go, magic.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TB8M!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205ee187-441c-46bd-8c41-69db01fa888d_2120x1584.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TB8M!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205ee187-441c-46bd-8c41-69db01fa888d_2120x1584.png 424w, https://substackcdn.com/image/fetch/$s_!TB8M!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205ee187-441c-46bd-8c41-69db01fa888d_2120x1584.png 848w, https://substackcdn.com/image/fetch/$s_!TB8M!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205ee187-441c-46bd-8c41-69db01fa888d_2120x1584.png 1272w, https://substackcdn.com/image/fetch/$s_!TB8M!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205ee187-441c-46bd-8c41-69db01fa888d_2120x1584.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TB8M!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205ee187-441c-46bd-8c41-69db01fa888d_2120x1584.png" width="1456" height="1088" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/205ee187-441c-46bd-8c41-69db01fa888d_2120x1584.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:1088,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:383511,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/192262123?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205ee187-441c-46bd-8c41-69db01fa888d_2120x1584.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!TB8M!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205ee187-441c-46bd-8c41-69db01fa888d_2120x1584.png 424w, https://substackcdn.com/image/fetch/$s_!TB8M!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205ee187-441c-46bd-8c41-69db01fa888d_2120x1584.png 848w, https://substackcdn.com/image/fetch/$s_!TB8M!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205ee187-441c-46bd-8c41-69db01fa888d_2120x1584.png 1272w, https://substackcdn.com/image/fetch/$s_!TB8M!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F205ee187-441c-46bd-8c41-69db01fa888d_2120x1584.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>It&#8217;s stored locally in Application Support and is repeated through splits:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!NWjb!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c081d-046d-4910-a94d-5260ca806e54_3640x2298.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!NWjb!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c081d-046d-4910-a94d-5260ca806e54_3640x2298.png 424w, https://substackcdn.com/image/fetch/$s_!NWjb!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c081d-046d-4910-a94d-5260ca806e54_3640x2298.png 848w, https://substackcdn.com/image/fetch/$s_!NWjb!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c081d-046d-4910-a94d-5260ca806e54_3640x2298.png 1272w, https://substackcdn.com/image/fetch/$s_!NWjb!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c081d-046d-4910-a94d-5260ca806e54_3640x2298.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!NWjb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c081d-046d-4910-a94d-5260ca806e54_3640x2298.png" width="1456" height="919" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7a2c081d-046d-4910-a94d-5260ca806e54_3640x2298.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:919,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:2979167,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/192262123?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c081d-046d-4910-a94d-5260ca806e54_3640x2298.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!NWjb!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c081d-046d-4910-a94d-5260ca806e54_3640x2298.png 424w, https://substackcdn.com/image/fetch/$s_!NWjb!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c081d-046d-4910-a94d-5260ca806e54_3640x2298.png 848w, https://substackcdn.com/image/fetch/$s_!NWjb!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c081d-046d-4910-a94d-5260ca806e54_3640x2298.png 1272w, https://substackcdn.com/image/fetch/$s_!NWjb!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7a2c081d-046d-4910-a94d-5260ca806e54_3640x2298.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The Buster Sword is the GOAT:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Kh-P!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de6d703-0fd2-49bc-9c41-b4549343881b_3640x2298.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Kh-P!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de6d703-0fd2-49bc-9c41-b4549343881b_3640x2298.png 424w, https://substackcdn.com/image/fetch/$s_!Kh-P!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de6d703-0fd2-49bc-9c41-b4549343881b_3640x2298.png 848w, https://substackcdn.com/image/fetch/$s_!Kh-P!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de6d703-0fd2-49bc-9c41-b4549343881b_3640x2298.png 1272w, https://substackcdn.com/image/fetch/$s_!Kh-P!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de6d703-0fd2-49bc-9c41-b4549343881b_3640x2298.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Kh-P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de6d703-0fd2-49bc-9c41-b4549343881b_3640x2298.png" width="1456" height="919" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7de6d703-0fd2-49bc-9c41-b4549343881b_3640x2298.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:919,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:3351882,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/192262123?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de6d703-0fd2-49bc-9c41-b4549343881b_3640x2298.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Kh-P!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de6d703-0fd2-49bc-9c41-b4549343881b_3640x2298.png 424w, https://substackcdn.com/image/fetch/$s_!Kh-P!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de6d703-0fd2-49bc-9c41-b4549343881b_3640x2298.png 848w, https://substackcdn.com/image/fetch/$s_!Kh-P!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de6d703-0fd2-49bc-9c41-b4549343881b_3640x2298.png 1272w, https://substackcdn.com/image/fetch/$s_!Kh-P!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7de6d703-0fd2-49bc-9c41-b4549343881b_3640x2298.png 1456w" sizes="100vw"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Have fun with it! There&#8217;s also a setting I&#8217;m building which will make it either work in each and every splits &#8212; repeating, of course&nbsp;&#8212; or to just be a single background across all splits. I&#8217;ll have that posted in the next release soon.</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[A Terminal-First IDE and Earning Trust]]></title><description><![CDATA[An effective IDE is one that you can trust. Here's how I'm building it.]]></description><link>https://blog.yen.chat/p/ide3</link><guid isPermaLink="false">https://blog.yen.chat/p/ide3</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Tue, 24 Mar 2026 15:20:30 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!oRXr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff94d3725-efe4-4fd9-9205-12aa19a4b651_2244x1338.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>The <a href="https://blog.yen.chat/p/ide">first</a> IDE post was about ambition. The <a href="https://blog.yen.chat/p/ide2">second</a> one was about cohesion. This one is about proof (or the burden of proof). Because if you can&#8217;t trust your Terminal and IDE to do what you want, then, what&#8217;s the point?</p><p>It has to work. Or it doesn&#8217;t.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>You see, a Terminal-first IDE cannot stop at having a lot of commands, and it cannot stop at having those commands point at each other in mostly sensible ways. At some point the product has to answer the question that matters more than all of that: When it tells me something about my repo, should I believe it?</p><p>That is the standard that anyone should hold any Terminal to and it&#8217;s the standard that I hold to the work that I do for this tool and our growing community of users.</p><p>I do not want an IDE that performs confidence; I want one that can defend its claims. I want it to be explicit about what it knows, what it does not know, which local facts produced the answer, where the boundary of authority ends, and what has to stay a human judgment call. </p><p>If the terminal is going to remain the center of gravity, it needs to feel less like a loose toolkit and more like a system with a memory, a vocabulary, and a conscience.</p><p>That is what this phase of YEN has been about and what is necessary before I feel comfortable giving this project a real v1.000 stamp.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!oRXr!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff94d3725-efe4-4fd9-9205-12aa19a4b651_2244x1338.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!oRXr!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff94d3725-efe4-4fd9-9205-12aa19a4b651_2244x1338.png 424w, https://substackcdn.com/image/fetch/$s_!oRXr!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff94d3725-efe4-4fd9-9205-12aa19a4b651_2244x1338.png 848w, https://substackcdn.com/image/fetch/$s_!oRXr!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff94d3725-efe4-4fd9-9205-12aa19a4b651_2244x1338.png 1272w, https://substackcdn.com/image/fetch/$s_!oRXr!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff94d3725-efe4-4fd9-9205-12aa19a4b651_2244x1338.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!oRXr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff94d3725-efe4-4fd9-9205-12aa19a4b651_2244x1338.png" width="1456" height="868" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f94d3725-efe4-4fd9-9205-12aa19a4b651_2244x1338.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:868,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:244114,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/191990324?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff94d3725-efe4-4fd9-9205-12aa19a4b651_2244x1338.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!oRXr!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff94d3725-efe4-4fd9-9205-12aa19a4b651_2244x1338.png 424w, https://substackcdn.com/image/fetch/$s_!oRXr!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff94d3725-efe4-4fd9-9205-12aa19a4b651_2244x1338.png 848w, https://substackcdn.com/image/fetch/$s_!oRXr!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff94d3725-efe4-4fd9-9205-12aa19a4b651_2244x1338.png 1272w, https://substackcdn.com/image/fetch/$s_!oRXr!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff94d3725-efe4-4fd9-9205-12aa19a4b651_2244x1338.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Readiness Has to Reuse the Evidence Model</h3><p>The clearest example is <strong>yen ide merge-readiness</strong>.</p><p>Before a branch is ready, I usually already have the evidence somewhere. The repo has a working tree state. </p><p><strong>yen ide doctor</strong> knows whether the workspace is healthy. </p><p><strong>yen ide trust status</strong> knows whether the repo has been explicitly trusted. </p><p><strong>yen ide verify status</strong> knows whether readiness and security gates have actually run. </p><p>Git knows how large the diff is and which files look risky. The local timeline already knows what the recent gates and review surfaces have done. Sometimes GitHub metadata is available too.</p><p>The problem was never missing evidence. The problem was fragmentation.</p><p>Once a repo gets large enough, the cost of answering a simple question like &#8220;is this safe to review?&#8221; is no longer the cost of one command. It is the cost of rebuilding the same mental model from half a dozen surfaces every single time. That is exactly the kind of work I think an IDE should eliminate.</p><p>What I did not want was the obvious fake solution.</p><p>I did not want a separate readiness database. I did not want a second approval workflow. I did not want a new trust vocabulary that would immediately start drifting from doctor, verify, review, and timeline. That is how tools become bureaucratic. They solve a visibility problem by creating a state problem.</p><p>So <strong>merge-readiness</strong> is not another authority surface. It is an aggregation surface over the evidence model that already exists.</p><p>It reads the current doctor state, trust summary, verify readiness and security snapshots, git diff heuristics, risky-file context, local gate and review history, and optional current-branch PR metadata when that exists. Then it gives me one recommendation: <strong>safe to review</strong>, <strong>safe to merge</strong>, or <strong>needs human check</strong>.</p><p>The label matters less than the defense behind it. If checks are missing, it says so. If security is blocked, it says so. If review state is still draft or changes-requested, it says so. If the repo has no baseline evidence at all, it does not pretend a green answer exists. It stays conservative and tells me exactly which facts are making it uncomfortable.</p><p>That is the point. I do not think users want a prettier green badge. I think they want a tool that can justify the badge.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!d7Vz!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b1d3f52-3a58-463a-8ad2-d2c2e458f77c_1532x552.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!d7Vz!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b1d3f52-3a58-463a-8ad2-d2c2e458f77c_1532x552.png 424w, https://substackcdn.com/image/fetch/$s_!d7Vz!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b1d3f52-3a58-463a-8ad2-d2c2e458f77c_1532x552.png 848w, https://substackcdn.com/image/fetch/$s_!d7Vz!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b1d3f52-3a58-463a-8ad2-d2c2e458f77c_1532x552.png 1272w, https://substackcdn.com/image/fetch/$s_!d7Vz!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b1d3f52-3a58-463a-8ad2-d2c2e458f77c_1532x552.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!d7Vz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b1d3f52-3a58-463a-8ad2-d2c2e458f77c_1532x552.png" width="1456" height="525" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/7b1d3f52-3a58-463a-8ad2-d2c2e458f77c_1532x552.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:525,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:98814,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/191990324?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b1d3f52-3a58-463a-8ad2-d2c2e458f77c_1532x552.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!d7Vz!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b1d3f52-3a58-463a-8ad2-d2c2e458f77c_1532x552.png 424w, https://substackcdn.com/image/fetch/$s_!d7Vz!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b1d3f52-3a58-463a-8ad2-d2c2e458f77c_1532x552.png 848w, https://substackcdn.com/image/fetch/$s_!d7Vz!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b1d3f52-3a58-463a-8ad2-d2c2e458f77c_1532x552.png 1272w, https://substackcdn.com/image/fetch/$s_!d7Vz!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F7b1d3f52-3a58-463a-8ad2-d2c2e458f77c_1532x552.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>The Cost Model Has to Stay Honest Too</h3><p>Trust is not only about correctness. It is also about cost.</p><p>An IDE can have a convincing readiness story and still betray the user if every new layer quietly makes the terminal slower, heavier, and harder to reason about. I did not want to argue that the terminal can be the IDE while hand-waving away the performance bill.</p><p>That is why I shipped <strong>yen ide benchmark status</strong> and <strong>yen ide benchmark run</strong>.</p><p>I wanted proof checked into the product instead of folklore. The benchmark harness runs deterministic suites for search latency, LSP startup latency, verify duration, and orchestration control-plane overhead. It records cold and warm timings, captures an environment stamp, writes a latest report, compares against a saved baseline, and fails closed when the proof is missing or when a regression is large enough that I should treat it as real.</p><p>That fail-closed behavior matters. I did not want a benchmark surface that always sounds informative but never has consequences. If YEN is going to claim trust, its performance evidence has to be usable as a gate, not just as dashboard decoration.</p><p>I also wanted the performance story to reuse the same discipline as the readiness story. So the benchmark harness does not invent a separate telemetry universe. Its suite latencies are mirrored into the same non-interference SLO ledger that already exists. Search, LSP startup, verify, and orchestration become explicit entries in one guardrail story instead of becoming a second performance control plane.</p><p>The fixtures matter just as much as the ledger. I did not want these numbers to depend on whichever repo happened to be under my cursor or whichever binaries happened to be installed that morning. </p><p>So the default path uses shipped fixtures under <strong>yen-cli/fixtures/ide-benchmark</strong>. Search and LSP run against a known TypeScript-shaped fixture. Verify runs against a deterministic local package-script fixture. Orchestration runs against mock adapters on a fixture-provided <strong>PATH</strong>. That gives me repeatable proof instead of a moving target.</p><p>The terminal-first bet gets stronger when the cost model is explicit. It gets weaker when the cost disappears into vibes.</p><div><hr></div><h3>A Semantic Target Has to Survive the Handoff</h3><p>There is another way to lose trust that is easier to miss.</p><p>The product can have an honest evidence model and an honest cost model, and still feel unreliable if the moment I try to act on that evidence the target gets lost between surfaces. A diagnostic that cannot land in the right file is not much better than a guess. A review hunk that jumps to the wrong place erodes confidence far faster than a missing feature ever will.</p><p>That is why I shipped <strong>yen ide open</strong>, moved <strong>yen-yazi-edit</strong> onto the same launcher contract, and then pushed that same contract into the native macOS review surfaces.</p><p>The rule is simple: Every semantic target stays <strong>path:line[:col]</strong> all the way through.</p><p>Search results, diagnostics, verify output, PR review hunks, merge-conflict selections, and file-browser edit targets should not each invent their own editor-jump syntax. They should all reduce to one location contract, then let one planner decide how that target becomes a real editor launch.</p><p>That planner now resolves repo-relative paths, preserves quoted <strong>VISUAL</strong> and <strong>EDITOR</strong> argv, understands the editor-family goto matrix, and exposes an explicit dry-run plan so I can test the launch behavior before it surprises a user. </p><p>Code-family editors use <strong>--goto</strong>. Zed takes the direct target shape. Xcode goes through <strong>xed --line</strong>. Terminal editors keep their real line-aware capabilities where they exist. Plain editors fall back to opening the resolved file only, with the loss of line-awareness made explicit instead of being silently swallowed.</p><p>The important part is not the matrix. The important part is the failure behavior.</p><p>This handoff now fails closed when the target no longer exists. It fails closed when the launcher is unavailable. If <strong>nvr</strong> is configured but there is no running server, it falls back to <strong>nvim</strong> instead of pretending a dead attach command counts as parity. Yazi uses the same planner. And on macOS, the native PR review and merge-conflict workspaces now go through the bundled <strong>yen ide open</strong> bridge for recognized GUI editors instead of maintaining a second Swift-only launch matrix with its own drift risks.</p><p>The same rule now applies to live LSP mutation. <strong>yen ide lsp code-actions</strong> takes that same semantic target, forwards matching diagnostics context when the server can actually use it, previews every returned action, and only auto-applies when there is one pure workspace edit to defend. </p><p>If the server returns multiple edit choices, a command-only action, an edit-plus-command action, or a disabled action, YEN stays in preview mode and says why. That is less magical than a universal quick-fix button. It is also much easier to trust.</p><p>That sounds like glue code. I think it is part of the trust model.</p><p>The reason is simple: if the product tells me where to look, it has to prove it can actually take me there.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!Y5mD!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd8edf8e-7e85-4529-812e-e25b40880fc0_1268x640.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!Y5mD!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd8edf8e-7e85-4529-812e-e25b40880fc0_1268x640.png 424w, https://substackcdn.com/image/fetch/$s_!Y5mD!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd8edf8e-7e85-4529-812e-e25b40880fc0_1268x640.png 848w, https://substackcdn.com/image/fetch/$s_!Y5mD!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd8edf8e-7e85-4529-812e-e25b40880fc0_1268x640.png 1272w, https://substackcdn.com/image/fetch/$s_!Y5mD!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd8edf8e-7e85-4529-812e-e25b40880fc0_1268x640.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!Y5mD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd8edf8e-7e85-4529-812e-e25b40880fc0_1268x640.png" width="1268" height="640" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/fd8edf8e-7e85-4529-812e-e25b40880fc0_1268x640.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:640,&quot;width&quot;:1268,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:112375,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/191990324?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd8edf8e-7e85-4529-812e-e25b40880fc0_1268x640.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!Y5mD!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd8edf8e-7e85-4529-812e-e25b40880fc0_1268x640.png 424w, https://substackcdn.com/image/fetch/$s_!Y5mD!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd8edf8e-7e85-4529-812e-e25b40880fc0_1268x640.png 848w, https://substackcdn.com/image/fetch/$s_!Y5mD!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd8edf8e-7e85-4529-812e-e25b40880fc0_1268x640.png 1272w, https://substackcdn.com/image/fetch/$s_!Y5mD!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ffd8edf8e-7e85-4529-812e-e25b40880fc0_1268x640.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Debugging Has to Leave Evidence</h3><p>A debugger is where integrated tools often fall back into folklore.</p><p>A failing test might know the file. A review surface might know the risky hunk. A diagnostic might know the exact line. But the moment I want to cross from evidence into execution, a lot of products suddenly expect me to carry all of that context by hand, rebuild a launch command from memory, and trust that whatever happened in the debugger can somehow be rediscovered later.</p><p>I did not want that split either.</p><p>So the debugger work stayed on the same semantic target contract and the same trust model as everything else. <strong>yen ide debug status</strong> and <strong>yen ide debug start</strong> use the same <strong>path:line[:col]</strong> vocabulary as search, diagnostics, review, and handoff. </p><p>The shipped baseline is intentionally narrow: <strong>python-pdb</strong>, <strong>node-inspect</strong>, and <strong>lldb</strong> for the local, SSH-backed, and tracked-devcontainer cases I can actually defend. The product stays explicit about what is still blocked: attach-to-pid flows, TypeScript direct-file launch, package-debug flows, and any zero-config adapter install story beyond that shipped baseline.</p><p>The more important part is what happens after launch. Real debug runs now write summary, log, and transcript evidence into the same per-workspace state model. <strong>yen ide debug status</strong> can show me the last run. <strong>yen ide trust status</strong> can point back to the same artifacts. Timeline events carry the report paths forward. Managed local, SSH-backed, and tracked-devcontainer sessions all stay on that one surface. The debugger is not a private side quest anymore. It leaves a paper trail the rest of the IDE can reuse.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!95OR!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44e61b7-0168-4868-97f6-8d528e0d2766_1508x414.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!95OR!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44e61b7-0168-4868-97f6-8d528e0d2766_1508x414.png 424w, https://substackcdn.com/image/fetch/$s_!95OR!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44e61b7-0168-4868-97f6-8d528e0d2766_1508x414.png 848w, https://substackcdn.com/image/fetch/$s_!95OR!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44e61b7-0168-4868-97f6-8d528e0d2766_1508x414.png 1272w, https://substackcdn.com/image/fetch/$s_!95OR!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44e61b7-0168-4868-97f6-8d528e0d2766_1508x414.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!95OR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44e61b7-0168-4868-97f6-8d528e0d2766_1508x414.png" width="1456" height="400" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/c44e61b7-0168-4868-97f6-8d528e0d2766_1508x414.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:400,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:69921,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/191990324?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44e61b7-0168-4868-97f6-8d528e0d2766_1508x414.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!95OR!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44e61b7-0168-4868-97f6-8d528e0d2766_1508x414.png 424w, https://substackcdn.com/image/fetch/$s_!95OR!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44e61b7-0168-4868-97f6-8d528e0d2766_1508x414.png 848w, https://substackcdn.com/image/fetch/$s_!95OR!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44e61b7-0168-4868-97f6-8d528e0d2766_1508x414.png 1272w, https://substackcdn.com/image/fetch/$s_!95OR!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fc44e61b7-0168-4868-97f6-8d528e0d2766_1508x414.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>That is also why the visual layer came last. <strong>yen ide debug tui</strong> now renders the same managed-session state, source excerpt, breakpoints, watches, recent output, and transcript tail instead of inventing a second debugger UI with its own hidden state. When the file is local, the source panel is real. When the workspace is remote, the dashboard says so instead of pretending it can render code it does not actually have. The UI inherits the trust model instead of overriding it.</p><p>The same restraint now shows up in the macOS command palette. Empty-query quick IDE actions for <strong>Debug Status</strong>, <strong>Debug TUI</strong>, and <strong>Format / Lint / Fix Status</strong> are just thin launchers over the shipped CLI surfaces. They make the trustworthy path faster to reach without creating a parallel native-only debugger or quality model that would immediately start drifting from the terminal.</p><p>That makes the surrounding surfaces sharper too. <strong>yen ide test status</strong>, <strong>yen ide verify status</strong>, <strong>yen ide search</strong>, <strong>yen ide merge-readiness</strong>, <strong>yen ide pr-review</strong>, and local diagnostics only append a <strong>yen ide debug start ...</strong> handoff when the shipped debugger can genuinely launch that target. If it cannot, YEN stays quiet instead of pretending a button is better than an answer.</p><p>This is the same trust rule again: Do not promise execution where only suggestion exists. A terminal-first IDE should be willing to leave capability on the table if that is what it takes to keep the chain of evidence intact.</p><div><hr></div><h3>Remote Work Needs One Identity and One Vocabulary</h3><p>Remote collaboration is where trust models usually split apart.</p><p>It is very easy to add SSH-backed behavior to a product by quietly inventing a second control plane. Local work starts using one vocabulary. Remote work starts using another. The same repo gets described differently depending on which side of the network boundary I am standing on. Status gets fuzzy. Trust becomes suggestive instead of explicit.</p><p>I did not want that.</p><p>So the remote work extended the existing <strong>yen ide</strong> surfaces instead of branching into a separate remote subsystem. <strong>yen ide detect</strong> accepts <strong>ssh://user@host/abs/path</strong> targets. So do <strong>yen ide doctor</strong>, <strong>yen ide trust status</strong>, and <strong>yen ide verify status</strong>. </p><p>The point is not that everything suddenly runs remotely. The point is that the same workspace identity now anchors both the local and SSH-backed view of the same repo.</p><p>That shared identity matters because it keeps the evidence story coherent. Remote detection reports where execution is actually happening. Trust and verify summaries key their local evidence against that shared workspace identity instead of pretending a remote repo is just another local path. Remote share state does the same thing. <strong>yen ide share host</strong>, <strong>share status</strong>, <strong>share revoke</strong>, <strong>share trust</strong>, and <strong>share untrust</strong> now speak the same target shape and the same identity model.</p><p>The lifecycle language got stricter too, because vague state is what makes remote tooling feel untrustworthy.</p><p>If the host is temporarily unreachable, a session should not suddenly look stale. <strong>Disconnected</strong> and <strong>stale</strong> do not mean the same thing. Disconnected means the runtime may still exist and the control plane has temporarily lost contact. Stale means the runtime is gone. YEN now preserves that distinction, keeps reconnect metadata explicit, and lets <strong>share status</strong> fall back to cached local metadata when the network is the only thing missing.</p><p>That is not a flourish. That is the difference between a system that tells the truth under stress and one that collapses into hand-waving the first time SSH gets weird.</p><div><hr></div><h3>Remote Execution Still Has to Admit Its Limits</h3><p>The last piece of trust is restraint.</p><p>Once a remote identity model exists, it becomes very tempting to make every remote surface sound complete the moment SSH works once. That would have made for a cleaner demo. It also would have been dishonest.</p><p>So I kept the execution story explicit instead.</p><p>Remote workflow discovery is there, and so is real remote execution. <strong>yen ide workflow discover</strong>, <strong>list</strong>, <strong>show</strong>, and <strong>run</strong> all accept the same remote target shape now. Authored workflows and repo-native tasks can execute remotely over SSH on the same workspace identity, with trust, approval, reports, and timeline ownership staying local. </p><p>What is still blocked is the part I cannot defend quite yet: Remote <strong>--watch</strong> loops and any fake suggestion that the remote machine is under a richer control plane than it really is.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!tpYU!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b00ab68-783b-4222-b872-5b97e2dc9a79_2010x674.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!tpYU!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b00ab68-783b-4222-b872-5b97e2dc9a79_2010x674.png 424w, https://substackcdn.com/image/fetch/$s_!tpYU!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b00ab68-783b-4222-b872-5b97e2dc9a79_2010x674.png 848w, https://substackcdn.com/image/fetch/$s_!tpYU!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b00ab68-783b-4222-b872-5b97e2dc9a79_2010x674.png 1272w, https://substackcdn.com/image/fetch/$s_!tpYU!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b00ab68-783b-4222-b872-5b97e2dc9a79_2010x674.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!tpYU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b00ab68-783b-4222-b872-5b97e2dc9a79_2010x674.png" width="1456" height="488" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/9b00ab68-783b-4222-b872-5b97e2dc9a79_2010x674.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:488,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:162660,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/191990324?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b00ab68-783b-4222-b872-5b97e2dc9a79_2010x674.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!tpYU!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b00ab68-783b-4222-b872-5b97e2dc9a79_2010x674.png 424w, https://substackcdn.com/image/fetch/$s_!tpYU!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b00ab68-783b-4222-b872-5b97e2dc9a79_2010x674.png 848w, https://substackcdn.com/image/fetch/$s_!tpYU!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b00ab68-783b-4222-b872-5b97e2dc9a79_2010x674.png 1272w, https://substackcdn.com/image/fetch/$s_!tpYU!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F9b00ab68-783b-4222-b872-5b97e2dc9a79_2010x674.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The same rule applies to devcontainers. <strong>yen ide devcontainer status</strong>, <strong>up</strong>, <strong>shell</strong>, and <strong>down</strong> now work for SSH-backed targets too, and the debugger can reuse that same tracked runtime through <strong>yen ide debug status --devcontainer</strong> and <strong>yen ide debug start --devcontainer</strong> when the separate devcontainer trust and health checks are satisfied. If the remote machine is missing the right CLI, the product says so. </p><p>If the tracked local state and the probed remote state disagree, the product says so. Labels like <strong>spec-drift</strong>, <strong>disconnected</strong>, and <strong>missing-remote-cli</strong> exist because a terminal-first IDE should not imply a healthy runtime it never actually verified.</p><p>That is the restraint I care about now. Ship the remote execution paths that are real. Keep trust and evidence local and explicit. Keep blocked features blocked until the control plane is strong enough that a nicer interface would not just be hiding drift.</p><p>This is the part of terminal-first IDE design I care about most now.</p><p>The product gets better when it becomes more articulate about boundaries, not less. It gets stronger when the same evidence model is reused in more places, when the same semantic target survives more handoffs, when the same workspace identity survives distance, and when the system is willing to say &#8220;I can inspect this, but I cannot honestly claim to control it yet.&#8221;</p><p>That is what earning trust looks like.</p><p>The <a href="https://blog.yen.chat/p/ide">thesis</a> was that the terminal can be the IDE. The <a href="https://blog.yen.chat/p/ide2">second post</a> was about making that IDE hold together. This phase was about something stricter: Making it legible enough, measurable enough, and self-aware enough that I can trust it when the work gets real. That&#8217;s always been the standard.</p><p>And now it&#8217;s the standard for YEN moving forward. As it should be.</p><p>More work to come.</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[Making the Terminal-First IDE Even Stronger]]></title><description><![CDATA[Semantic locations, stronger review flows, clearer trust and health reporting, repo-native execution, honest polyglot intelligence, and more.]]></description><link>https://blog.yen.chat/p/ide2</link><guid isPermaLink="false">https://blog.yen.chat/p/ide2</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Sat, 21 Mar 2026 20:21:19 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!AkQH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1046f7ab-b6a3-4150-a4b8-8807c5f919fe_2562x1122.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>Last week I published an important post about how the <a href="https://blog.yen.chat/p/ide">Terminal is the IDE</a> now and I&#8217;ve been working on making it even better.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;2d520637-057c-4261-882b-c19ee6066c17&quot;,&quot;caption&quot;:&quot;Hey folks!&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;The Terminal IS the IDE Now&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:54423,&quot;name&quot;:&quot;8Lee&quot;,&quot;bio&quot;:&quot;Engineer. Designer. Really bad dad jokes.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6992612f-3d11-4a2c-83c1-0518674db408_1024x1024.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2026-03-17T20:38:21.329Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/fetch/$s_!QMiV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52b36f65-4cf4-4e18-89d9-ee9a0a858bbe_1684x968.png&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://blog.yen.chat/p/ide&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:190885250,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:4,&quot;comment_count&quot;:0,&quot;publication_id&quot;:7373375,&quot;publication_name&quot;:&quot;Digital Onigiri&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!Twh4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25857f99-094a-420f-82d0-666a8c7c9f05_1024x1024.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>You see, that first post was the thesis. The terminal should not be a utility room bolted onto the bottom of an editor. It should be the place where engineering work actually stays coherent. It just makes sense.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>This follow-up is about something slightly less glamorous and much more important: Making that IDE layer behave like one system instead of a pile of unrelated features.</p><p>Because that is the real test.</p><p>Anybody can ship a burst of commands and a few native windows and call it an IDE story. The harder part is preserving context across those surfaces, making trust legible, staying honest about what is actually answering a query, and meeting repos where they already are instead of inventing a second configuration universe.</p><p>So that is what the most recent hardening pass was really about. Here&#8217;s what&#8217;s up and the details of what I&#8217;ve added.</p><div><hr></div><h3>1. Make the Output Survive the Workflow</h3><p>The biggest change was not one flashy feature. It was a contract.</p><p>I wanted YEN to stop flattening useful engineering output back into vague text the moment it crossed a surface boundary. If a result points at a real file and line, that location should survive through the terminal, the command palette, the review flow, and the native macOS windows.</p><p>So the system now leans much harder on one shared semantic location model: <strong>path:line[:col]</strong>.</p><p>That shows up in <strong>yen ide parse --format tsv</strong>, in verify reports, in workflow reports, in the command palette search path, in <strong>yen ide pr-review</strong>, and in the merge-conflict workspace. Content hits, diagnostics, review evidence, workflow output, and conflict selections can all point back to the same kind of target instead of degrading into &#8220;open this file and good luck.&#8221;</p><p>That sounds small until you use it.</p><p>Once the location contract stays intact, the command palette stops feeling like a launcher with some extra sugar on top. It starts feeling like a terminal-first IDE control plane. A search result can still be a real action. A review hunk can still be a real place. A test failure can still be a real jump target.</p><p>That is the difference between &#8220;there is a lot here&#8221; and &#8220;this actually holds together.&#8221;</p><div><hr></div><h3>2. Upgrading Git Review without Becoming Git</h3><p>I also spent a lot of time strengthening the review baseline.</p><p>That did not mean building a separate Git universe inside YEN. I still think that would be the wrong move. The CLI should stay the source of truth. But the review path needed to get more capable and less lossy.</p><p>So the current baseline is now bundled <strong>lazygit</strong> plus bundled <strong>delta</strong> as the shared diff renderer. On top of that, <strong>yen ide pr-review</strong> picked up deterministic hunk inventory and semantic hunk targets, while the macOS PR review workspace and merge-conflict workspace both learned how to stay anchored to those same repo targets.</p><p>That has a few nice and positive effects.</p><p>Focused hunk previews are better. Plain-text fallback is explicit instead of pretending it is the same thing. Selected files and hunks can keep their target identity all the way through a review flow. The PR evidence path can carry the latest verify readiness and security snapshot with it. And the merge-conflict workspace can show a delta-backed patch preview, keep the selected hunk as a real location, and hand that target off to the editor before staging.</p><p>That is exactly the division of labor I want. Keep the terminal-native review flow in the terminal. Use a richer native surface when it genuinely helps and don&#8217;t try to pretend that the native surface is replacing the terminal.</p><p>Makes sense, right?</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!AkQH!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1046f7ab-b6a3-4150-a4b8-8807c5f919fe_2562x1122.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!AkQH!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1046f7ab-b6a3-4150-a4b8-8807c5f919fe_2562x1122.png 424w, https://substackcdn.com/image/fetch/$s_!AkQH!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1046f7ab-b6a3-4150-a4b8-8807c5f919fe_2562x1122.png 848w, https://substackcdn.com/image/fetch/$s_!AkQH!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1046f7ab-b6a3-4150-a4b8-8807c5f919fe_2562x1122.png 1272w, https://substackcdn.com/image/fetch/$s_!AkQH!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1046f7ab-b6a3-4150-a4b8-8807c5f919fe_2562x1122.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!AkQH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1046f7ab-b6a3-4150-a4b8-8807c5f919fe_2562x1122.png" width="1456" height="638" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/1046f7ab-b6a3-4150-a4b8-8807c5f919fe_2562x1122.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:638,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:237621,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/191702413?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1046f7ab-b6a3-4150-a4b8-8807c5f919fe_2562x1122.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!AkQH!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1046f7ab-b6a3-4150-a4b8-8807c5f919fe_2562x1122.png 424w, https://substackcdn.com/image/fetch/$s_!AkQH!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1046f7ab-b6a3-4150-a4b8-8807c5f919fe_2562x1122.png 848w, https://substackcdn.com/image/fetch/$s_!AkQH!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1046f7ab-b6a3-4150-a4b8-8807c5f919fe_2562x1122.png 1272w, https://substackcdn.com/image/fetch/$s_!AkQH!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F1046f7ab-b6a3-4150-a4b8-8807c5f919fe_2562x1122.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>3. Trust, Doctor, and Verify Finally Read Like One Story</h3><p>Another major improvement is that repo state is much easier to inspect before something goes wrong.</p><p>YEN already had a lot of the raw ingredients: Project trust, env trust, LSP trust, share trust, workflow trust, local verify artifacts, devcontainer state, language-server status, and so on. The problem was not missing data. The problem was legibility.</p><p>That is why <strong>yen ide doctor</strong> matters.</p><p>It takes the existing sources of truth and turns them into one repo-health snapshot with project context, toolchain and version signals, trust and runtime summaries, verify readiness, security state, and clear blocker versus warning findings. By default it exits non-zero when blockers exist, and <strong>--strict</strong> can intentionally make warnings fail automation too. It is deliberately direct. A health command that only tells you that it successfully collected state is not useful.</p><p>The same principle drove the workspace trust center. <strong>yen ide trust status</strong> gives one aggregate view over the trust and runtime or session state YEN already had. <strong>yen ide trust revoke</strong> and <strong>yen ide trust reset</strong> delegate back to the owning commands instead of mutating trust state behind their backs. That keeps the control plane honest.</p><p>And then there is the verify path.</p><p><strong>yen ide verify status</strong> is now a read-only snapshot over the latest local verify artifacts, while <strong>yen ide verify</strong> carries explicit local <strong>osv-scanner</strong> coverage. More importantly, that readiness and security state is no longer trapped inside one command. It can surface in doctor and in PR evidence previews too.</p><p>That matters because security is not a separate product. It is part of whether a repo looks ready to act on right now.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!me0k!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff228afb2-94b8-4c49-8965-052c13857dd9_1592x586.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!me0k!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff228afb2-94b8-4c49-8965-052c13857dd9_1592x586.png 424w, https://substackcdn.com/image/fetch/$s_!me0k!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff228afb2-94b8-4c49-8965-052c13857dd9_1592x586.png 848w, https://substackcdn.com/image/fetch/$s_!me0k!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff228afb2-94b8-4c49-8965-052c13857dd9_1592x586.png 1272w, https://substackcdn.com/image/fetch/$s_!me0k!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff228afb2-94b8-4c49-8965-052c13857dd9_1592x586.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!me0k!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff228afb2-94b8-4c49-8965-052c13857dd9_1592x586.png" width="1456" height="536" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/f228afb2-94b8-4c49-8965-052c13857dd9_1592x586.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:536,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:99145,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/191702413?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff228afb2-94b8-4c49-8965-052c13857dd9_1592x586.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!me0k!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff228afb2-94b8-4c49-8965-052c13857dd9_1592x586.png 424w, https://substackcdn.com/image/fetch/$s_!me0k!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff228afb2-94b8-4c49-8965-052c13857dd9_1592x586.png 848w, https://substackcdn.com/image/fetch/$s_!me0k!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff228afb2-94b8-4c49-8965-052c13857dd9_1592x586.png 1272w, https://substackcdn.com/image/fetch/$s_!me0k!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Ff228afb2-94b8-4c49-8965-052c13857dd9_1592x586.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>4. Meet Repos Where They Already Are</h3><p>This is one of the places I care most about not getting cute.</p><p>A lot of developer tools become less trustworthy the moment they stop respecting the repo in front of them. They invent a second workflow system, a second task runner, or a second configuration universe and then ask you to keep both in your head forever.</p><p>I do not want that.</p><p>So a lot of the recent work was about making YEN better at reading the repo&#8217;s existing signals and putting them on one control plane.</p><p><strong>yen ide workflow discover</strong> now inventories package scripts, Make targets, Just recipes, and Taskfile tasks with provenance, category, risk, and conflict visibility. <strong>yen ide workflow run --native</strong> is the explicit path for running one of those discovered tasks without pretending it is an authored YEN workflow, and it reuses the same trust, approval, timeline, and reporting plumbing as the rest of the workflow surface.</p><p>The quality surface follows the same rule. <strong>yen ide format</strong>, <strong>yen ide lint</strong>, and <strong>yen ide fix</strong> prefer repo-native tasks first, fall back narrowly when the repo already implies a toolchain, reuse the existing trust and approval model, and write dedicated quality reports instead of disappearing their behavior into a black box.</p><p>The test surface does too. <strong>yen ide test status</strong> and <strong>yen ide test run</strong> build on the same repo-native runner detection and verify artifacts instead of inventing a second language matrix just for testing. Grouped failures, rerun-failed behavior, and semantic jump targets all sit on that same baseline.</p><p>And the VS Code migration path got more serious in the same spirit. <strong>yen ide vscode inventory</strong> and <strong>yen ide vscode import</strong> now produce richer extension guidance, task and test parity notes, and deterministic local artifacts like <strong>migration-report.json</strong> and <strong>manual-cleanup.txt</strong> under <strong>.yen/vscode-import</strong>.</p><p>The common theme is simple: I want YEN to reduce ambiguity, not replace the repo with a parallel religion.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!yFBP!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F781b2f48-4007-40a3-b069-4bd6b14a7043_1572x452.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!yFBP!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F781b2f48-4007-40a3-b069-4bd6b14a7043_1572x452.png 424w, https://substackcdn.com/image/fetch/$s_!yFBP!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F781b2f48-4007-40a3-b069-4bd6b14a7043_1572x452.png 848w, https://substackcdn.com/image/fetch/$s_!yFBP!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F781b2f48-4007-40a3-b069-4bd6b14a7043_1572x452.png 1272w, https://substackcdn.com/image/fetch/$s_!yFBP!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F781b2f48-4007-40a3-b069-4bd6b14a7043_1572x452.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!yFBP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F781b2f48-4007-40a3-b069-4bd6b14a7043_1572x452.png" width="1456" height="419" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/781b2f48-4007-40a3-b069-4bd6b14a7043_1572x452.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:419,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:77064,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/191702413?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F781b2f48-4007-40a3-b069-4bd6b14a7043_1572x452.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!yFBP!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F781b2f48-4007-40a3-b069-4bd6b14a7043_1572x452.png 424w, https://substackcdn.com/image/fetch/$s_!yFBP!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F781b2f48-4007-40a3-b069-4bd6b14a7043_1572x452.png 848w, https://substackcdn.com/image/fetch/$s_!yFBP!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F781b2f48-4007-40a3-b069-4bd6b14a7043_1572x452.png 1272w, https://substackcdn.com/image/fetch/$s_!yFBP!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F781b2f48-4007-40a3-b069-4bd6b14a7043_1572x452.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>5. Honest Polyglot Intelligence &gt; Pretend Coverage</h3><p>The code-intelligence layer also got sharper, and I am happy about this one because it pushed the product further in a direction I care about a lot: Honesty.</p><p>In the first post about a <a href="https://blog.yen.chat/p/ide">Terminal-first IDE</a> I said I do not want &#8220;smart&#8221; terminal tooling that lies. That rule matters even more once multiple languages and multiple fallback modes are involved.</p><p>So the install and fallback story is much more explicit now.</p><p>JavaScript and TypeScript share one managed baseline. Python and Go have their own managed paths. Rust points at <strong>rustup</strong>. Swift points at the Xcode or Swift toolchain. Zig expects <strong>zls</strong> on <strong>PATH</strong>. YEN does not silently blur those operational models together.</p><p>The AST side got stronger too. <strong>yen ide ast status</strong>, <strong>definition</strong>, and <strong>references</strong> now have real parser-backed fallback for Python, JavaScript and TypeScript, Go, and Swift, and the output says what is actually answering the query: <strong>python-ast</strong>, <strong>typescript-compiler-api</strong>, <strong>go-parser</strong>, or <strong>swiftc-dump-ast-json</strong>. Those results stay clearly labeled <strong>Source: ast</strong> so fallback never masquerades as live LSP.</p><p>Unsupported languages stay explicit instead of getting vague marketing support. Bun-backed JavaScript projects also stop falling off the AST path just because the runtime detection looked slightly different from the normalized JS family.</p><p>That is the kind of improvement I want from this layer. </p><p>Not bigger claims. Clearer contracts.</p><div><hr></div><h3>6. The Boring Internal Work Is Product Work Too</h3><p>There was one other slice in this pass that matters even though it is much less visible from the outside: the IDE CLI modularization work.</p><p>I do not want every future IDE feature to keep piling into one giant Bash entrypoint until the safest answer becomes &#8220;please do not touch this file.&#8221; That is how products slow down. That is how regressions get stickier. That is how shipping momentum dies.</p><p>So the router and bootstrap layer stays stable in <strong>yen-cli/commands/core/ide</strong>, while the shared helpers and capability families live in sourced modules behind explicit loader-contract checks. </p><p>The user-facing CLI did not change. The implementation risk did. </p><p>If you want to feel the current shape of the terminal-first IDE layer, this is a pretty good compact path:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;bfaebaae-68be-4833-877e-9191781e1d14&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">bash
yen ide doctor
yen ide trust status
yen ide lsp status
yen ide ast status
yen ide workflow discover
yen ide workflow run --native package:test --dry-run
yen ide format status
yen ide test status
yen ide verify status
yen ide pr-review 123 --list-hunks</code></pre></div><p>And if you are on macOS, press <strong>Cmd + Shift + P</strong> after that.</p><p>Search the repo. Open a review surface. Inspect diagnostics. Jump to a hunk. Pull up trust state. Notice how often the system can keep the location, the context, and the repo identity intact instead of making you reconstruct it by hand.</p><p>That is what this follow-up post is really about. The <a href="https://blog.yen.chat/p/ide">first post</a> in the series was about saying the terminal is the IDE now.</p><p>This one is about making that sentence even more true.</p><p>There is still more to do. Editor handoff parity, remote parity, merge-readiness reporting, and benchmark work are all still on the table. </p><p>But the IDE layer is already better now in the ways that matter most to me: More coherent, more inspectable, more honest, and more native to the repo that is actually in front of you.</p><p>I like where we&#8217;re going together.</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[The Terminal IS the IDE Now]]></title><description><![CDATA[YEN has a Terminal-first IDE stack with local LSP workflows, encrypted sharing, devcontainer control, deterministic VS Code import, review tooling, and more.]]></description><link>https://blog.yen.chat/p/ide</link><guid isPermaLink="false">https://blog.yen.chat/p/ide</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Tue, 17 Mar 2026 20:38:21 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!QMiV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52b36f65-4cf4-4e18-89d9-ee9a0a858bbe_1684x968.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>There is a pattern I have been watching for years.</p><p>Most developer tools say they love the terminal, then quietly treat it like a basement utility room. And it always kind of feels like it lives in the basement at the bottom of the screen, right?</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!QMiV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52b36f65-4cf4-4e18-89d9-ee9a0a858bbe_1684x968.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!QMiV!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52b36f65-4cf4-4e18-89d9-ee9a0a858bbe_1684x968.png 424w, https://substackcdn.com/image/fetch/$s_!QMiV!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52b36f65-4cf4-4e18-89d9-ee9a0a858bbe_1684x968.png 848w, https://substackcdn.com/image/fetch/$s_!QMiV!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52b36f65-4cf4-4e18-89d9-ee9a0a858bbe_1684x968.png 1272w, https://substackcdn.com/image/fetch/$s_!QMiV!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52b36f65-4cf4-4e18-89d9-ee9a0a858bbe_1684x968.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!QMiV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52b36f65-4cf4-4e18-89d9-ee9a0a858bbe_1684x968.png" width="1456" height="837" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/52b36f65-4cf4-4e18-89d9-ee9a0a858bbe_1684x968.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:837,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:223469,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/190885250?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52b36f65-4cf4-4e18-89d9-ee9a0a858bbe_1684x968.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!QMiV!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52b36f65-4cf4-4e18-89d9-ee9a0a858bbe_1684x968.png 424w, https://substackcdn.com/image/fetch/$s_!QMiV!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52b36f65-4cf4-4e18-89d9-ee9a0a858bbe_1684x968.png 848w, https://substackcdn.com/image/fetch/$s_!QMiV!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52b36f65-4cf4-4e18-89d9-ee9a0a858bbe_1684x968.png 1272w, https://substackcdn.com/image/fetch/$s_!QMiV!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F52b36f65-4cf4-4e18-89d9-ee9a0a858bbe_1684x968.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The editor gets the architecture. The terminal gets a small panel. </p><p>Boohiss.</p><p>The editor gets the first-class search, the code intelligence, the review flows, the collaboration story, the automation surface, and the gentle product language about focus and speed. The terminal gets a rectangle at the bottom and maybe a button that says &#8220;open integrated terminal.&#8221;</p><p>I never thought that that was good enough, at least from my perspective!</p><p>The terminal is not a sidecar for serious engineering work. It is the place where code actually meets reality. It is where builds fail, migrations go sideways, diagnostics become actionable, PRs get reviewed, services get restarted, environment mistakes surface, and dangerous commands should feel dangerous before you press Enter.</p><p>That is why I have been pushing YEN toward a different thesis: <strong>Do not bolt a terminal onto an IDE. Build the IDE around the terminal.</strong></p><p>And the most recent release &#8212; v0.999 &#8212; is the biggest step so far in that direction as YEN now ships a real terminal-first IDE surface.</p><p>Not a concept page.</p><p>Not a chat sidebar pretending to be an IDE.</p><p>Not a cloud account plus a terminal skin. Eww.</p><p>Nope. None of those things. Instead, we have a real, local-first workflow stack that starts in the terminal and stays there unless a richer native macOS surface is actually justified. Here are the 8 major pieces that bring it all together.</p><div><hr></div><h3>1. Project Awareness</h3><p>The first big piece is project awareness.</p><p>YEN now understands enough about the current repository to make terminal workflows feel contextual instead of generic. <strong>yen ide detect</strong> finds the project root and runtime / tooling context. <strong>yen ide env</strong> gives you explicit trust-gated environment loading. <strong>yen ide history</strong>, <strong>replay</strong>, and <strong>profile</strong> turn the terminal into something closer to a project memory instead of a disposable scrollback trench.</p><p>That matters because terminal-first tooling only works if the terminal knows where it is, all the time, even when you forget.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!SWd0!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F866255b7-2fef-42d0-8844-63d8b227b323_1728x464.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!SWd0!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F866255b7-2fef-42d0-8844-63d8b227b323_1728x464.png 424w, https://substackcdn.com/image/fetch/$s_!SWd0!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F866255b7-2fef-42d0-8844-63d8b227b323_1728x464.png 848w, https://substackcdn.com/image/fetch/$s_!SWd0!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F866255b7-2fef-42d0-8844-63d8b227b323_1728x464.png 1272w, https://substackcdn.com/image/fetch/$s_!SWd0!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F866255b7-2fef-42d0-8844-63d8b227b323_1728x464.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!SWd0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F866255b7-2fef-42d0-8844-63d8b227b323_1728x464.png" width="1456" height="391" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/866255b7-2fef-42d0-8844-63d8b227b323_1728x464.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:391,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:92692,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/190885250?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F866255b7-2fef-42d0-8844-63d8b227b323_1728x464.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!SWd0!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F866255b7-2fef-42d0-8844-63d8b227b323_1728x464.png 424w, https://substackcdn.com/image/fetch/$s_!SWd0!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F866255b7-2fef-42d0-8844-63d8b227b323_1728x464.png 848w, https://substackcdn.com/image/fetch/$s_!SWd0!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F866255b7-2fef-42d0-8844-63d8b227b323_1728x464.png 1272w, https://substackcdn.com/image/fetch/$s_!SWd0!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F866255b7-2fef-42d0-8844-63d8b227b323_1728x464.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>2. Search with First-Class Objects</h3><p>The second big piece is search that treats engineering artifacts like first-class objects.</p><p><strong>yen ide search</strong> can rank across files, content, diagnostics, project history, and actions. On macOS, the same contract now powers the desktop command palette. Empty query launches actions. </p><p>A typed query searches built-in actions first, then falls back to project files, content, diagnostics, and recent history for trusted local repos. That means the search surface you invoke with <strong>Cmd + Shift + P</strong> is no longer just a launcher. </p><p>It is a project-aware terminal IDE entry point.</p><div><hr></div><h3>3. Local Code Intelligence</h3><p>The third big piece is local code intelligence.</p><p>YEN now ships an explicit LSP control plane with <strong>yen ide lsp trust</strong>, <strong>start</strong>, <strong>status</strong>, <strong>diagnostics</strong>, <strong>hover</strong>, <strong>definition</strong>, <strong>references</strong>, <strong>rename</strong>, <strong>stop</strong>, and a bounded install matrix. Cool.</p><p>This all includes real resolver-backed supervision when a local language server exists, placeholder guidance when it does not, grouped diagnostics snapshots with freshness labeling, and interactive request surfaces that stay honest about whether they are using live LSP or syntax-aware fallback.</p><p>That last part matters to me a lot. I do not want &#8220;smart&#8221; terminal tooling that lies.</p><p>If YEN is using a live language server, it says so. If it is using AST fallback, it says <strong>Source: ast</strong>. If the language is unsupported or the expected local server is missing, it says that too.</p><p>Honesty is a feature. Who would have thought.</p><div><hr></div><h3>4. Syntax-Aware AST Queries</h3><p>The fallback layer is the fourth piece: Syntax-aware AST queries.</p><p>When live LSP is not available, YEN can still answer useful structural questions with <strong>yen ide ast status</strong>, <strong>definition</strong>, and <strong>references</strong> for the currently shipped languages. </p><p>That means the terminal does not have to collapse all the way down to dumb text search every time a full server is absent.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!6aq7!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cefa876-58f0-49f6-a265-57415c0a1409_1046x630.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!6aq7!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cefa876-58f0-49f6-a265-57415c0a1409_1046x630.png 424w, https://substackcdn.com/image/fetch/$s_!6aq7!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cefa876-58f0-49f6-a265-57415c0a1409_1046x630.png 848w, https://substackcdn.com/image/fetch/$s_!6aq7!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cefa876-58f0-49f6-a265-57415c0a1409_1046x630.png 1272w, https://substackcdn.com/image/fetch/$s_!6aq7!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cefa876-58f0-49f6-a265-57415c0a1409_1046x630.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!6aq7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cefa876-58f0-49f6-a265-57415c0a1409_1046x630.png" width="1046" height="630" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/4cefa876-58f0-49f6-a265-57415c0a1409_1046x630.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:630,&quot;width&quot;:1046,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:86681,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/190885250?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cefa876-58f0-49f6-a265-57415c0a1409_1046x630.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!6aq7!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cefa876-58f0-49f6-a265-57415c0a1409_1046x630.png 424w, https://substackcdn.com/image/fetch/$s_!6aq7!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cefa876-58f0-49f6-a265-57415c0a1409_1046x630.png 848w, https://substackcdn.com/image/fetch/$s_!6aq7!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cefa876-58f0-49f6-a265-57415c0a1409_1046x630.png 1272w, https://substackcdn.com/image/fetch/$s_!6aq7!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F4cefa876-58f0-49f6-a265-57415c0a1409_1046x630.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>5. Execution Discipline</h3><p>The fifth piece is execution discipline.</p><p>This is where terminal-first IDEs have a chance to be better than editor-first ones. Or that&#8217;s the hope!</p><p>YEN now ships <strong>yen ide explain</strong> for failed command analysis, <strong>yen ide verify</strong> for multi-language verification bundles, <strong>yen ide gate</strong> for risk-aware approval checkpoints on dangerous commands, <strong>yen ide workflow</strong> for schema-validated project workflows, <strong>yen ide timeline</strong> for local audit events, and <strong>yen agents</strong> for first-party adapter coordination. Wild.</p><p>There is also <strong>yen ide pr-notify</strong> for GitHub review-request polling and <strong>yen ide pr-review</strong> for focused diff review, evidence bundles, inline comments, and explicit review decisions.</p><p>This is not about adding ceremony.</p><p>It is about making the terminal better at the parts of engineering work where context, the ability to easily review work, and general safety actually matter.</p><div><hr></div><h3>6. Collaboration without Bloat</h3><p>The sixth piece is collaboration without a custom relay empire.</p><p>YEN now ships <strong>yen ide share status</strong>, <strong>host</strong>, <strong>join</strong>, <strong>revoke</strong>, <strong>trust</strong>, and <strong>untrust</strong> using an integration-first transport model: <strong>upterm</strong> first, <strong>tmate</strong> as fallback. Share tokens are encrypted locally. Hosting is per-project and explicitly trusted. Join flows validate the token locally before any transport command runs. Sessions can be read-only or interactive. TTL expiry and immediate revoke are part of the contract.</p><p>This was an important design choice.</p><p>I did not want to build a bespoke terminal-sharing service just to say YEN has collaboration, which would be fun but not entirely useful.</p><p>You see, there are good maintained tools for this job already. The right move was to build the control plane, trust model, audit trail, and operator ergonomics around them instead of pretending every feature needs a net-new backend.</p><div><hr></div><h3>7. Environment Parity and Migration</h3><p>The seventh piece is environment parity and migration.</p><p>YEN now ships <strong>yen ide devcontainer status</strong>, <strong>up</strong>, <strong>shell</strong>, and <strong>down</strong> as a trust-gated wrapper around the reference <strong>devcontainer</strong> CLI. It is intentionally local-workspace scoped. No hidden runtime. No bundled container stack. </p><p>No pretending YEN needs to become Docker Desktop.</p><p>YEN also ships <strong>yen ide vscode inventory</strong> and <strong>import</strong> so teams can inspect existing VS Code workspace config, classify what is supported or partial, and write deterministic YEN-local migration artifacts without mutating the original workspace by surprise. Dry runs emit real diffs. Applied writes are convergent. That is the kind of migration behavior I want from tooling: boring, inspectable, and reversible.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!bJdt!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41cb59b7-4733-440f-855a-f7206b501351_1682x548.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!bJdt!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41cb59b7-4733-440f-855a-f7206b501351_1682x548.png 424w, https://substackcdn.com/image/fetch/$s_!bJdt!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41cb59b7-4733-440f-855a-f7206b501351_1682x548.png 848w, https://substackcdn.com/image/fetch/$s_!bJdt!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41cb59b7-4733-440f-855a-f7206b501351_1682x548.png 1272w, https://substackcdn.com/image/fetch/$s_!bJdt!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41cb59b7-4733-440f-855a-f7206b501351_1682x548.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!bJdt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41cb59b7-4733-440f-855a-f7206b501351_1682x548.png" width="1456" height="474" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/41cb59b7-4733-440f-855a-f7206b501351_1682x548.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:474,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:80199,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/190885250?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41cb59b7-4733-440f-855a-f7206b501351_1682x548.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!bJdt!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41cb59b7-4733-440f-855a-f7206b501351_1682x548.png 424w, https://substackcdn.com/image/fetch/$s_!bJdt!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41cb59b7-4733-440f-855a-f7206b501351_1682x548.png 848w, https://substackcdn.com/image/fetch/$s_!bJdt!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41cb59b7-4733-440f-855a-f7206b501351_1682x548.png 1272w, https://substackcdn.com/image/fetch/$s_!bJdt!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F41cb59b7-4733-440f-855a-f7206b501351_1682x548.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>8. Native macOS IDE Surfaces That Actually Help</h3><p>The eighth piece is native macOS IDE surfaces where they actually help.</p><p>This is the part that makes YEN feel different.</p><p>The command palette now exposes quick IDE actions like <strong>IDE: LSP Status</strong>, <strong>IDE: LSP Diagnostics</strong>, <strong>IDE: LSP Install Matrix</strong>, <strong>IDE: Share Status</strong>, <strong>IDE: Share Host (Read-Only)</strong>, <strong>IDE: Share Revoke</strong>, <strong>IDE: Devcontainer Status</strong>, <strong>IDE: VS Code Inventory</strong>, <strong>IDE: VS Code Import (Dry Run)</strong>, and <strong>IDE: AST Status</strong>.</p><p>On top of that, macOS now has a dedicated desktop PR review workspace and a dedicated desktop merge-conflict workspace launched from the same palette. Those are native surfaces, not browser panes, and they stay anchored to the active repository context instead of trying to replace the terminal.</p><p>That is the pattern I want YEN to keep following.</p><p>If a task is fundamentally terminal-native, keep it in the terminal.</p><p>If a task genuinely benefits from a richer surface, build a native one and keep it close to the terminal instead of escaping into a second application model.</p><p>That is a better division of labor than the one most IDEs settled on.</p><div><hr></div><h3>Bonus: Local First</h3><p>There is also a security and trust story here that I think matters more than the marketing layer most developer tools put on top.</p><p>This IDE stack is <strong>local-first</strong>. Project trust is explicit. The LSP runtime is per project. Sharing trust is per project. Diagnostics snapshots are local.</p><p>Devcontainer orchestration shells out to the reference CLI you already chose to install. VS Code import writes project-local artifacts instead of disappearing into a hidden sync service.</p><p>None of that is as flashy as saying &#8220;agentic workspace intelligence&#8221; in a launch trailer, but I think it is the right way to build tools engineers can actually trust.</p><p>And there is still plenty left to do!</p><p>Debugger work remains future work. Remote devcontainer parity is still a deliberate follow-up instead of a hand-wavy promise. Agent-runtime hardening and context reliability still have room to grow. I am not pretending YEN is finished.</p><p>But the shape is real now. You can feel the product thesis in your hands.</p><p>The command palette is not just a launcher anymore. The terminal is not just an output window anymore. The IDE is not somewhere else anymore.</p><p>It is here.</p><p>If you want a feel for the surface area, this is a compact starting path:</p><div class="highlighted_code_block" data-attrs="{&quot;language&quot;:&quot;plaintext&quot;,&quot;nodeId&quot;:&quot;6a564aba-b584-426d-9dc6-dccdf5f48544&quot;}" data-component-name="HighlightedCodeBlockToDOM"><pre class="shiki"><code class="language-plaintext">bash
yen ide detect
yen ide env list
yen ide lsp status --format json
yen ide lsp diagnostics
yen ide lsp hover src/app.ts:12:3
yen ide share status
yen ide share host --read-only --ttl-minutes 30
yen ide devcontainer status
yen ide vscode inventory
yen ide search verify
yen ide verify --quick
yen ide pr-review 123 --loop
yen ide timeline --limit 20</code></pre></div><p>And if you are on macOS, press <strong>Cmd + Shift + P</strong> and start from there.</p><p>That shortcut has quietly become one of the best ways to feel the whole philosophy of YEN in a few seconds.</p><p>Open the palette. Launch a real IDE action. Search a repo. Review a PR.</p><p>Inspect diagnostics. Start a share session. Import a VS Code workspace in dry-run mode. Then close the palette and notice that you never left the terminal-first workflow to do it.</p><p>That is the point.</p><p>The goal is not to cosplay as a giant editor suite. The goal is to make the terminal powerful enough, contextual enough, and trustworthy enough that you stop needing to flee from it for everyday engineering work.</p><p>That is the release. That is the mission.</p><p>And for the first time, I think it is fair to say it plainly:</p><p><strong>The terminal is the IDE now. </strong>About damn time.</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[Hardening Speech-to-Text in Your Terminal]]></title><description><![CDATA[Obsessing over UX and how Option + Space should feel really, really boring.]]></description><link>https://blog.yen.chat/p/s2t</link><guid isPermaLink="false">https://blog.yen.chat/p/s2t</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Fri, 13 Mar 2026 21:15:46 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!3jBN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fpbs.substack.com%2Fmedia%2FHDMIX3Ka4AADEbe.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>There is a version of speech-to-text that looks great in a demo and still feels wrong in daily use. You hold <strong>Option + Space</strong>. You speak. You release.</p><p>Wow. So much wow.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>And it worked. YEN has had a <strong>strong speech-to-text foundation for a <a href="https://blog.yen.chat/p/talk-to-your-terminal-without-ai">while now</a></strong>. It is on-device. It is native. It works across macOS apps. On macOS 26 and newer it uses Apple&#8217;s modern speech stack with unlimited sessions.</p><p>That part was never the problem.</p><div class="digest-post-embed" data-attrs="{&quot;nodeId&quot;:&quot;6428e8d4-9bdf-4655-9046-daded09c756c&quot;,&quot;caption&quot;:&quot;Hey folks!&quot;,&quot;cta&quot;:&quot;Read full story&quot;,&quot;showBylines&quot;:true,&quot;showDescription&quot;:true,&quot;showImage&quot;:true,&quot;size&quot;:&quot;sm&quot;,&quot;isEditorNode&quot;:true,&quot;title&quot;:&quot;Talk To Your Terminal without AI&quot;,&quot;publishedBylines&quot;:[{&quot;id&quot;:54423,&quot;name&quot;:&quot;8Lee&quot;,&quot;bio&quot;:&quot;Engineer. Designer. Really bad dad jokes.&quot;,&quot;photo_url&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/6992612f-3d11-4a2c-83c1-0518674db408_1024x1024.jpeg&quot;,&quot;is_guest&quot;:false,&quot;bestseller_tier&quot;:null}],&quot;post_date&quot;:&quot;2026-01-24T01:57:41.841Z&quot;,&quot;cover_image&quot;:&quot;https://substackcdn.com/image/youtube/w_728,c_limit/lrdKV8-L10I&quot;,&quot;cover_image_alt&quot;:null,&quot;canonical_url&quot;:&quot;https://blog.yen.chat/p/talk-to-your-terminal-without-ai&quot;,&quot;section_name&quot;:null,&quot;video_upload_id&quot;:null,&quot;id&quot;:185439835,&quot;type&quot;:&quot;newsletter&quot;,&quot;reaction_count&quot;:4,&quot;comment_count&quot;:2,&quot;publication_id&quot;:7373375,&quot;publication_name&quot;:&quot;Digital Onigiri&quot;,&quot;publication_logo_url&quot;:&quot;https://substackcdn.com/image/fetch/$s_!Twh4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F25857f99-094a-420f-82d0-666a8c7c9f05_1024x1024.png&quot;,&quot;belowTheFold&quot;:false,&quot;youtube_url&quot;:null,&quot;show_links&quot;:null,&quot;feed_url&quot;:null}"></div><p>The problem was simpler and more important. The workflow itself needed to be tightened. So, that&#8217;s what I&#8217;ve been working on since we&#8217;re coming up on our official <strong>v1.000 release</strong> &#8212; everything needs to be perfect.</p><div class="twitter-embed" data-attrs="{&quot;url&quot;:&quot;https://x.com/yenFTW/status/2031977100673265932&quot;,&quot;full_text&quot;:&quot;We're almost there. &quot;,&quot;username&quot;:&quot;yenFTW&quot;,&quot;name&quot;:&quot;YEN&quot;,&quot;profile_image_url&quot;:&quot;https://pbs.substack.com/profile_images/2003905513135001602/tYkzH4TU_normal.jpg&quot;,&quot;date&quot;:&quot;2026-03-12T06:14:27.000Z&quot;,&quot;photos&quot;:[{&quot;img_url&quot;:&quot;https://pbs.substack.com/media/HDMIX3Ka4AADEbe.png&quot;,&quot;link_url&quot;:&quot;https://t.co/C73N7MSQ58&quot;}],&quot;quoted_tweet&quot;:{},&quot;reply_count&quot;:0,&quot;retweet_count&quot;:1,&quot;like_count&quot;:2,&quot;impression_count&quot;:28,&quot;expanded_url&quot;:null,&quot;video_url&quot;:null,&quot;video_preview_media_key&quot;:null,&quot;belowTheFold&quot;:false}" data-component-name="Twitter2ToDOM"></div><p>But, there were some over-complications that I&#8217;ve wanted to fix and those fixes should be in as the right version of speech-to-text in a terminal-first IDE should not feel clever. It should feel dependable.</p><p>It should feel boring in the best possible way.</p><p>And, the rest of this post may be boring for most (a bit engineering and tech-heavy, so forgive me) but at the very least it showcases how much I care about this feature that&#8217;s a model for what and how I think about a Terminal-first IDE (platform).</p><p>If you want to geek out, continue on fellow nerd.</p><div><hr></div><h3>Hotkeys and Session Contracts</h3><p>The first part of this hardening was the <strong>hotkey session contract</strong>.</p><p>The old problem space here was subtle. Global hotkeys on macOS are not just about catching one <strong>keyDown</strong> and one <strong>keyUp</strong>. You have to care about modifier-release ordering, event-tap rebuilds, trust loss, key repeat noise, and stop or restart churn when the user presses again quickly.</p><p>That means a sloppy implementation can accidentally treat keyboard-state drift as a real release. It can stop capture because polling noticed a mismatch instead of because the user actually let go. That is exactly the kind of thing that makes a feature feel haunted.</p><p>I tightened that.</p><p>Hotkey-up synthesis is now restricted to explicit recovery paths instead of loose session-state drift. The exact hold contract is deterministic whether <strong>Option</strong> or <strong>Space</strong> releases first. Event-tap rebuilds while the keys are still physically down no longer get to silently terminate a valid capture. Re-press during stop is treated as a queued restart instead of an invitation for stale state to bleed across sessions.</p><p>That sounds like implementation trivia until you use the feature all day.</p><p>Then it becomes the whole feature.</p><div><hr></div><h3>Finalization Contract for Acceptable Input</h3><p>The second part was the <strong>finalization contract</strong>.</p><p>Speech-to-text gets weird when people talk about &#8220;the transcript&#8221; as if there is always only one obvious version of it. In reality there are partials, finalized segments, stop callbacks, error paths, watchdogs, and all the little ways asynchronous systems try to complete more than once or complete in the wrong order.</p><p>That is not acceptable for input.</p><p>YEN now treats stop completion as a proper per-session contract with one, single authoritative result. There is an explicit stop token. Completion is exactly once across normal release, recognizer error, results-stream failure, watchdog fallback, and forced reset paths. I also added more explicit stop telemetry so transcript loss can be diagnosed from logs instead of guessed from UI behavior.</p><p>Just as importantly, I removed &#8220;experimental&#8221; work from the default release-to-paste critical path. That part needed to happen.</p><p>If the user&#8217;s baseline expectation is &#8220;hold <strong>Option + Space</strong>, speak, release, paste,&#8221; then the core path cannot be hostage to optional experiments.</p><p>At that stage, <strong>Live Transcript Preview</strong> and <strong>Translate-on-Dictate</strong> were clearly labeled <strong>EXPERIMENTAL</strong> in Settings, and the default stop path was no longer forced to wait behind translation behavior when translation was off. </p><p>That product boundary was the right intermediate step: stabilize the core workflow first, then graduate optional surfaces only after the contract is clear.</p><p>Oh, fun.</p><div><hr></div><h3>The Contract for The Clipboard</h3><p>The third part was the <strong>clipboard and paste contract</strong>. This was the most important user-facing fix.</p><p>The easy version of cross-app dictation is: Put text on the clipboard, fire <strong>Cmd + V</strong>, restore the old clipboard on a timer, hope for the best.</p><p>That is not a serious delivery contract.</p><p>If the paste target changes, if the synthetic paste does nothing, if the target app is slow, or if delivery simply cannot be proven, a timer-based clipboard restore turns into a data-loss risk. You get the worst combination: No inserted text and no recoverable text. No bueno, so, I tightened that too.</p><p>YEN now captures the insertion target at stop time and treats three cases separately: direct terminal-surface paste inside YEN, same-app responder-chain paste, and cross-app synthetic <strong>Cmd + V</strong>. Those are not the same operation and they should not pretend to be.</p><p>Inside YEN, the old clipboard can be restored after paste with a guarded delay. Same-app responder behavior stays explicit. Cross-app synthetic paste is treated more conservatively because delivery cannot actually be proven by the sender.</p><p>That means when YEN pastes into another app through synthetic <strong>Cmd + V</strong>, the dictated text now stays recoverable on the clipboard until the user replaces it.</p><p>That is a much better failure mode.</p><p>The goal is not to hide every edge case. The goal is to make the safe path the default path and the recovery path obvious when automation cannot honestly guarantee delivery.</p><p>I also tightened stale-target handling so the transcript is bound to the app or split that was focused when you released the hotkey. If that target changes or becomes invalid before insertion, YEN fails closed into manual recovery instead of pasting into the wrong place.</p><p>That is another example of the kind of boring behavior I want.</p><p>Wrong-field paste is worse than no paste.</p><p>Naturally.</p><div><hr></div><h3>Truth-Seeking in Great, Simple Product</h3><p>The fourth part of this pass was simply <strong>telling the truth in the product and docs</strong>.</p><p>There was some confusion around Apple&#8217;s newer speech APIs, so I rechecked the recognizer shape carefully against Apple&#8217;s own documentation. Apparently, on macOS 26+, YEN still used <strong>SpeechAnalyzer</strong> with <strong>DictationTranscriber</strong> for the main dictation path.</p><p>That is the right pairing for what YEN is doing.</p><p>Apple also exposes <strong>SpeechTranscriber</strong> as part of the broader Speech framework stack, and it is useful, but it is not some magic replacement for session-logic bugs. <strong>SpeechAnalyzer</strong> is the container. </p><p>The real question is which speech module belongs in the workflow you are building. For YEN&#8217;s hold-to-talk dictation flow, <strong>DictationTranscriber</strong> remains the correct transcription surface.</p><p>That distinction matters because it keeps the engineering work honest.</p><p>If the problem is race conditions, stop semantics, target routing, and clipboard durability, the answer is not to wave at a nearby API name and hope the complexity disappears. The answer is to harden the workflow contract itself, so, that&#8217;s what the latest release has done.</p><p>And that ties directly back to YEN&#8217;s larger mission.</p><div><hr></div><p>I keep saying YEN is a <strong>Terminal-first IDE</strong>, and I mean it in a very literal way.</p><p>The terminal should not just be fast. It should be trustworthy.</p><p>If a feature belongs in the terminal workflow, it has to clear a higher bar than novelty. It has to feel like something you can build real muscle memory around. It has to be explicit about what is experimental, explicit about what is guaranteed, and conservative when the system cannot actually prove success.</p><p>That is especially true for speech-to-text. Speech-to-text inside a terminal is easy to market as a fun trick. But in practice it is an input primitive.</p><p>It becomes part of how you move through the machine. Part of how you write. Part of how you reply in chat, search, command, annotate, and capture thoughts without breaking flow.</p><p>When something occupies that layer, reliability is the feature and everything else is secondary. So, this hardening pass did not add a dramatic launch trailer bullet point.</p><p>It did something better: It made the core path legible. </p><p>Hold <strong>Option + Space</strong>. Speak. Release. Done.</p><p>YEN should either paste the right final text into the right place exactly once, or leave that text recoverable so nothing is lost.</p><p>That is the bar. That is the contract. </p><p>And that is the kind of boring I want more of in software. Boring software is great software because it does precisely what I, and the community, want.</p><p>Who would have thought.</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[Accessibility and Onboarding for Speech-to-Text in Your Terminal]]></title><description><![CDATA[How YEN&#8217;s new onboarding makes dictation easier to set up, easier to understand, and more accessible from the start.]]></description><link>https://blog.yen.chat/p/accessibility-and-onboarding-for</link><guid isPermaLink="false">https://blog.yen.chat/p/accessibility-and-onboarding-for</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Thu, 12 Mar 2026 15:29:32 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!_940!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8a87d71-d4cc-409d-aa83-78261d0f94c4_1000x944.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>Quick story. I set up a brand new M4 Mac last week as a fresh-start check for YEN. Fresh macOS install, nothing carried over. Downloaded YEN, launched it, pressed Option + Space to dictate something.</p><p>Nothing happened. Damn.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>No error. No popup. No indication of what to do next.</p><p>That moment was a good reminder that onboarding is part of the feature. If speech-to-text is going to be something people rely on, setup has to be clear, guided, and accessible. </p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!_940!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8a87d71-d4cc-409d-aa83-78261d0f94c4_1000x944.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!_940!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8a87d71-d4cc-409d-aa83-78261d0f94c4_1000x944.png 424w, https://substackcdn.com/image/fetch/$s_!_940!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8a87d71-d4cc-409d-aa83-78261d0f94c4_1000x944.png 848w, https://substackcdn.com/image/fetch/$s_!_940!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8a87d71-d4cc-409d-aa83-78261d0f94c4_1000x944.png 1272w, https://substackcdn.com/image/fetch/$s_!_940!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8a87d71-d4cc-409d-aa83-78261d0f94c4_1000x944.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!_940!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8a87d71-d4cc-409d-aa83-78261d0f94c4_1000x944.png" width="1000" height="944" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/d8a87d71-d4cc-409d-aa83-78261d0f94c4_1000x944.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:944,&quot;width&quot;:1000,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:210568,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/190361804?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8a87d71-d4cc-409d-aa83-78261d0f94c4_1000x944.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!_940!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8a87d71-d4cc-409d-aa83-78261d0f94c4_1000x944.png 424w, https://substackcdn.com/image/fetch/$s_!_940!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8a87d71-d4cc-409d-aa83-78261d0f94c4_1000x944.png 848w, https://substackcdn.com/image/fetch/$s_!_940!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8a87d71-d4cc-409d-aa83-78261d0f94c4_1000x944.png 1272w, https://substackcdn.com/image/fetch/$s_!_940!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fd8a87d71-d4cc-409d-aa83-78261d0f94c4_1000x944.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>The dictation feature itself was not broken. What YEN needed was a better way to walk people through the permissions required to register the hotkey and capture audio. On an earlier build, that could leave <strong>Option + Space</strong> looking dead until someone manually dug through System Settings.</p><p>But, you know, onboarding matters. We all know it does.</p><p>YEN&#8217;s speech-to-text needs three macOS permissions to function:</p><ol><li><p>Accessibility &#8212; The Option + Space global hotkey</p></li><li><p>Microphone &#8212; Audio capture for speech recognition</p></li><li><p>Speech Recognition &#8212; Apple&#8217;s on-device transcription engine</p></li></ol><p>When any one of these is missing, speech-to-text can feel unavailable even when the fix is straightforward. That is exactly the kind of first-run experience we want to avoid.</p><p>macOS handles these permissions differently, especially <strong>Accessibility</strong>, so the app cannot assume the system will teach the user what to do. YEN now takes that responsibility more directly: show what is needed, explain why it matters, and make the recovery path obvious.</p><p>For a feature like speech-to-text, the onboarding experience is not separate from the feature. It is the feature. Naturally.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!N-B4!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f329994-a09b-42da-b7a2-0620db515e38_1264x604.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!N-B4!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f329994-a09b-42da-b7a2-0620db515e38_1264x604.png 424w, https://substackcdn.com/image/fetch/$s_!N-B4!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f329994-a09b-42da-b7a2-0620db515e38_1264x604.png 848w, https://substackcdn.com/image/fetch/$s_!N-B4!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f329994-a09b-42da-b7a2-0620db515e38_1264x604.png 1272w, https://substackcdn.com/image/fetch/$s_!N-B4!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f329994-a09b-42da-b7a2-0620db515e38_1264x604.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!N-B4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f329994-a09b-42da-b7a2-0620db515e38_1264x604.png" width="1264" height="604" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/0f329994-a09b-42da-b7a2-0620db515e38_1264x604.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:604,&quot;width&quot;:1264,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:90346,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/190361804?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f329994-a09b-42da-b7a2-0620db515e38_1264x604.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!N-B4!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f329994-a09b-42da-b7a2-0620db515e38_1264x604.png 424w, https://substackcdn.com/image/fetch/$s_!N-B4!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f329994-a09b-42da-b7a2-0620db515e38_1264x604.png 848w, https://substackcdn.com/image/fetch/$s_!N-B4!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f329994-a09b-42da-b7a2-0620db515e38_1264x604.png 1272w, https://substackcdn.com/image/fetch/$s_!N-B4!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F0f329994-a09b-42da-b7a2-0620db515e38_1264x604.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>To make the experience even better I&#8217;ve made sure to expose the permissions in the <strong>Settings Panel</strong> and in the top <strong>macOS menu bar</strong> so the user has confidence that a fundamental part of their (new) workflow is always working.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!mUca!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2160e7ce-12ed-455d-91f2-48332ce89770_1454x596.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!mUca!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2160e7ce-12ed-455d-91f2-48332ce89770_1454x596.png 424w, https://substackcdn.com/image/fetch/$s_!mUca!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2160e7ce-12ed-455d-91f2-48332ce89770_1454x596.png 848w, https://substackcdn.com/image/fetch/$s_!mUca!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2160e7ce-12ed-455d-91f2-48332ce89770_1454x596.png 1272w, https://substackcdn.com/image/fetch/$s_!mUca!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2160e7ce-12ed-455d-91f2-48332ce89770_1454x596.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!mUca!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2160e7ce-12ed-455d-91f2-48332ce89770_1454x596.png" width="1454" height="596" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/2160e7ce-12ed-455d-91f2-48332ce89770_1454x596.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:null,&quot;imageSize&quot;:null,&quot;height&quot;:596,&quot;width&quot;:1454,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:180933,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/190361804?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2160e7ce-12ed-455d-91f2-48332ce89770_1454x596.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:null,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!mUca!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2160e7ce-12ed-455d-91f2-48332ce89770_1454x596.png 424w, https://substackcdn.com/image/fetch/$s_!mUca!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2160e7ce-12ed-455d-91f2-48332ce89770_1454x596.png 848w, https://substackcdn.com/image/fetch/$s_!mUca!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2160e7ce-12ed-455d-91f2-48332ce89770_1454x596.png 1272w, https://substackcdn.com/image/fetch/$s_!mUca!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F2160e7ce-12ed-455d-91f2-48332ce89770_1454x596.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>Not hard to put together but important enough to build and ship. So give it a try!</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[Dictate in One Language, Paste in Another]]></title><description><![CDATA[Translate-on-Dictate is now an experimental opt-in path with strict fallback safety.]]></description><link>https://blog.yen.chat/p/dictate-in-one-language-paste-in</link><guid isPermaLink="false">https://blog.yen.chat/p/dictate-in-one-language-paste-in</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Wed, 11 Mar 2026 14:36:02 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!TxI6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdced1fbd-e960-4954-93d9-b59199654cf1_1102x502.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>We shipped a focused addition to speech-to-text in YEN: <strong>Translate-on-Dictate</strong>.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>The behavior is simple:</p><ol><li><p>Hold <strong>Option + Space</strong> and dictate normally.</p></li><li><p>Release to finalize transcription.</p></li><li><p>If translation is enabled and the selected language pair is ready, YEN pastes translated text.</p></li><li><p>If not, YEN pastes the original transcript.</p></li></ol><p>No extra prompt flow. No cloud dependency requirement from us.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!TxI6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdced1fbd-e960-4954-93d9-b59199654cf1_1102x502.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!TxI6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdced1fbd-e960-4954-93d9-b59199654cf1_1102x502.png 424w, https://substackcdn.com/image/fetch/$s_!TxI6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdced1fbd-e960-4954-93d9-b59199654cf1_1102x502.png 848w, https://substackcdn.com/image/fetch/$s_!TxI6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdced1fbd-e960-4954-93d9-b59199654cf1_1102x502.png 1272w, https://substackcdn.com/image/fetch/$s_!TxI6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdced1fbd-e960-4954-93d9-b59199654cf1_1102x502.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!TxI6!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdced1fbd-e960-4954-93d9-b59199654cf1_1102x502.png" width="1200" height="546.6424682395644" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/dced1fbd-e960-4954-93d9-b59199654cf1_1102x502.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:502,&quot;width&quot;:1102,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:65389,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/190361278?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdced1fbd-e960-4954-93d9-b59199654cf1_1102x502.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!TxI6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdced1fbd-e960-4954-93d9-b59199654cf1_1102x502.png 424w, https://substackcdn.com/image/fetch/$s_!TxI6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdced1fbd-e960-4954-93d9-b59199654cf1_1102x502.png 848w, https://substackcdn.com/image/fetch/$s_!TxI6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdced1fbd-e960-4954-93d9-b59199654cf1_1102x502.png 1272w, https://substackcdn.com/image/fetch/$s_!TxI6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fdced1fbd-e960-4954-93d9-b59199654cf1_1102x502.png 1456w" sizes="100vw" fetchpriority="high"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>Why This Is Experimental</h3><p>Translation is now explicitly positioned as <strong>experimental</strong> and <strong>off by default</strong>.</p><p>That keeps the default dictation path stable while we gather real usage and edge-case feedback from opt-in users.</p><p>Core speech-to-text behavior stays unchanged when translation is disabled. I&#8217;d love feedback on this since I need more folks to try it and see if it works as well as I hope it can! Post your feedback in &#8220;chat&#8221; off your shell.</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;c2124c0f-84d1-4db9-9009-72c959424942&quot;,&quot;duration&quot;:null}"></div><div><hr></div><h3>What We Hardened</h3><p>Translate-on-Dictate only runs as a post-processing step on the final transcript:</p><ul><li><p>Live overlay text remains source-language during capture</p></li><li><p>Source language follows recognizer locale</p></li><li><p>Target language is explicitly selected in Settings</p></li><li><p>Settings now filters the target list to language pairs that are actually compatible with the current recognizer locale</p></li><li><p>When a supported pair is missing assets, YEN can ask macOS to prepare them while YEN is frontmost in Settings</p></li></ul><p>Failure behavior is deterministic:</p><ul><li><p>Translation failed -&gt; paste original transcript</p></li><li><p>Translation timed out, or the translation availability check stalled -&gt; paste original transcript</p></li><li><p>Language pair unsupported, still preparing, or model unavailable -&gt; paste original transcript</p></li><li><p>)lder macOS (no Translation framework runtime) -&gt; paste original transcript</p></li></ul><p>We do not block paste on translation success.</p><p>We also now cover both the availability lookup and the translation session with the timeout guard, and we cancel translation sessions on timeout or cancellation to avoid overlap under rapid dictate cycles.</p><div><hr></div><h3>Where To Enable It</h3><p>Open <strong>Cmd + ,</strong> &#187;&#187;&#187; <strong>Sounds</strong> &#187;&#187;&#187; <strong>Speech Setup</strong> &#187;&#187;&#187; <strong>Translate-on-Dictate</strong>.</p><p>Choose your target language, then test in any app where YEN dictation already works.</p><p>If macOS still needs translation assets for the selected pair, keep YEN frontmost in Settings for the preparation step. Once the pair is ready, dictation uses it. If it is not ready yet, paste still falls back to the original transcript.</p><p>Have fun with it!</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[Terminal Tabs Have Names. Splits Should Too.]]></title><description><![CDATA[plit Labels give each pane its own identity without turning the terminal into UI soup]]></description><link>https://blog.yen.chat/p/split-names</link><guid isPermaLink="false">https://blog.yen.chat/p/split-names</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Tue, 10 Mar 2026 14:30:59 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!KFeN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab77f4af-6019-492d-a1e1-244ab87369a3_2646x1028.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>There is a particular kind of terminal chaos that shows up the moment you stop demoing and start actually working.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>One pane and/or tab runs the dev server. Another one runs tests. And of course you&#8217;ve got one that tails logs. One is a scratch shell you swear is temporary. They all live in the same repo. They all look almost identical. And after a while, your brain is doing bookkeeping the computer should have handled for you.</p><p>Mental. Burn. Out. </p><p>The tabs help, of course, but tabs are too coarse for this problem and there&#8217;s definitely better UX available, right? If your real workflow lives inside a split layout, the unit that needs identity is the pane.</p><p>That is why YEN now has <strong>Split Labels</strong>.</p><div class="captioned-image-container"><figure><a class="image-link image2" target="_blank" href="https://substackcdn.com/image/fetch/$s_!i0ek!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62505ba3-feb7-4a18-9302-cc0b15d8cce3_1608x372.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!i0ek!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62505ba3-feb7-4a18-9302-cc0b15d8cce3_1608x372.png 424w, https://substackcdn.com/image/fetch/$s_!i0ek!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62505ba3-feb7-4a18-9302-cc0b15d8cce3_1608x372.png 848w, https://substackcdn.com/image/fetch/$s_!i0ek!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62505ba3-feb7-4a18-9302-cc0b15d8cce3_1608x372.png 1272w, https://substackcdn.com/image/fetch/$s_!i0ek!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62505ba3-feb7-4a18-9302-cc0b15d8cce3_1608x372.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!i0ek!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62505ba3-feb7-4a18-9302-cc0b15d8cce3_1608x372.png" width="1200" height="277.74725274725273" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/62505ba3-feb7-4a18-9302-cc0b15d8cce3_1608x372.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:337,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:113919,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:false,&quot;topImage&quot;:true,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/190362522?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62505ba3-feb7-4a18-9302-cc0b15d8cce3_1608x372.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!i0ek!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62505ba3-feb7-4a18-9302-cc0b15d8cce3_1608x372.png 424w, https://substackcdn.com/image/fetch/$s_!i0ek!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62505ba3-feb7-4a18-9302-cc0b15d8cce3_1608x372.png 848w, https://substackcdn.com/image/fetch/$s_!i0ek!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62505ba3-feb7-4a18-9302-cc0b15d8cce3_1608x372.png 1272w, https://substackcdn.com/image/fetch/$s_!i0ek!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F62505ba3-feb7-4a18-9302-cc0b15d8cce3_1608x372.png 1456w" sizes="100vw" fetchpriority="high"></picture><div></div></div></a></figure></div><p>Turn them on in <strong>Settings &#187; Workspace &#187; Split Labels</strong>. Once enabled, each split gets a small pill at the bottom-left corner using the active terminal theme colors. </p><p>Click it directly or open <strong>Cmd + Shift + P</strong> and run <strong>Rename Split Label</strong>, and that pane can become anything you want it to be: Server, tests, queue worker, staging ssh, or whatever your future self will thank you for.</p><p>Most terminals let you rename tabs. That is useful, but it is not the same thing.</p><p>If you work in a three-column layout for <strong>client</strong>, <strong>API</strong>, and <strong>tests</strong>, a tab title does not solve the real problem. The panes are still where the context lives. Split Labels are independent from window titles and tab titles, because pretending those are the same thing just moves the confusion around.</p><p>It&#8217;s a simple concept:</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!KFeN!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab77f4af-6019-492d-a1e1-244ab87369a3_2646x1028.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!KFeN!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab77f4af-6019-492d-a1e1-244ab87369a3_2646x1028.png 424w, https://substackcdn.com/image/fetch/$s_!KFeN!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab77f4af-6019-492d-a1e1-244ab87369a3_2646x1028.png 848w, https://substackcdn.com/image/fetch/$s_!KFeN!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab77f4af-6019-492d-a1e1-244ab87369a3_2646x1028.png 1272w, https://substackcdn.com/image/fetch/$s_!KFeN!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab77f4af-6019-492d-a1e1-244ab87369a3_2646x1028.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!KFeN!,w_2400,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab77f4af-6019-492d-a1e1-244ab87369a3_2646x1028.png" width="1200" height="466.4835164835165" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ab77f4af-6019-492d-a1e1-244ab87369a3_2646x1028.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;large&quot;,&quot;height&quot;:566,&quot;width&quot;:1456,&quot;resizeWidth&quot;:1200,&quot;bytes&quot;:417289,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/190362522?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab77f4af-6019-492d-a1e1-244ab87369a3_2646x1028.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-large" alt="" srcset="https://substackcdn.com/image/fetch/$s_!KFeN!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab77f4af-6019-492d-a1e1-244ab87369a3_2646x1028.png 424w, https://substackcdn.com/image/fetch/$s_!KFeN!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab77f4af-6019-492d-a1e1-244ab87369a3_2646x1028.png 848w, https://substackcdn.com/image/fetch/$s_!KFeN!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab77f4af-6019-492d-a1e1-244ab87369a3_2646x1028.png 1272w, https://substackcdn.com/image/fetch/$s_!KFeN!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fab77f4af-6019-492d-a1e1-244ab87369a3_2646x1028.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>And the fallback behavior is intentionally boring.</p><p>Leave the field blank and YEN goes back to an automatic pane label. That path uses the pane title when it is meaningful, otherwise the working-directory leaf, otherwise <strong>Terminal</strong>. No weird placeholder nonsense. No permanent rename required just because you wanted a quick label for one session.</p><p>But, if you want, it&#8217;ll persist.</p><p>A lot of terminal UI tricks feel nice right up until you close the app and discover they were only decorative. In YEN, Split Labels are stored with restore state per pane, so they survive tab switches, window restoration, and full session restarts. </p><p>If you named the left pane <strong>api</strong> and the right pane <strong>web</strong>, YEN should remember that instead of making you rebuild your mental map every morning.</p><p>There is also some deliberate restraint here.</p><p>The label does not force itself onscreen in every situation. If a pane is too small, if a URL hover preview is visible, or if you are dragging panes around, the label hides. That is not the feature failing. That is the feature refusing to become clutter at exactly the moment the space is tight or the interaction is doing something more important.</p><p>No split, no label. Also intentional. UX is how you win minimizing the cognitive load for the user and making the quality of life better. Take a look:</p><div class="native-video-embed" data-component-name="VideoPlaceholder" data-attrs="{&quot;mediaUploadId&quot;:&quot;a32b9c37-a3e3-444b-a9f1-f43481c6134f&quot;,&quot;duration&quot;:null}"></div><p>This is one of those details that sounds small until you use it for a week and then wonder why terminals ever stopped at tab titles.</p><p>A terminal-first IDE lives or dies on whether it respects working memory. Engineers already keep too much state in their heads. Which pane is production logs. Which one is the migration. Which one is safe to kill. Which one has the REPL with the weird local setup. The terminal should carry more of that load.</p><p>That is the philosophy behind <strong>Split Labels</strong>. Not bigger chrome. Not decoration. Just a small, local-first piece of interface that makes multi-pane work easier to read.</p><p>Apparently I needed to build pane name tags because my own split layouts had reached the &#8220;which one of you is the test runner again&#8221; stage of evolution. Ask me how many times I clicked the wrong pane before admitting tabs were not enough.</p><p>If you live in split-heavy terminal layouts, this one should just work.</p><p>&#8212; 8</p>]]></content:encoded></item><item><title><![CDATA[Safety, Privacy, and Security in Terminal Chat]]></title><description><![CDATA[And thoughts on running the first-ever community inside a Terminal.]]></description><link>https://blog.yen.chat/p/safe-chat</link><guid isPermaLink="false">https://blog.yen.chat/p/safe-chat</guid><dc:creator><![CDATA[8Lee]]></dc:creator><pubDate>Mon, 09 Mar 2026 14:16:45 GMT</pubDate><enclosure url="https://substackcdn.com/image/fetch/$s_!ftV6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3bc584-94de-40af-a200-3ce395663980_1572x464.png" length="0" type="image/jpeg"/><content:encoded><![CDATA[<p>Hey folks!</p><p>A lot of people still do not realize this exists in YEN at all.</p><p class="button-wrapper" data-attrs="{&quot;url&quot;:&quot;https://blog.yen.chat/subscribe?&quot;,&quot;text&quot;:&quot;Subscribe now&quot;,&quot;action&quot;:null,&quot;class&quot;:null}" data-component-name="ButtonCreateButton"><a class="button primary" href="https://blog.yen.chat/subscribe?"><span>Subscribe now</span></a></p><p>YEN has a built-in <a href="https://blog.yen.chat/p/a-community-chat-inside-a-terminal">community chat</a> system inside the terminal itself. That was already a strange and important line to cross when we first shipped it. We were not adding a side panel to a browser app. We were building what we believe was the first terminal with chat and community built into the product.</p><p>That is worth reminding people about, because once chat lives inside a terminal, the bar changes. The terminal is not a casual surface. It is where people debug production issues, inspect logs, move around sensitive files, and work inside a higher-trust environment than most ordinary consumer apps. </p><p>So when you say &#8220;chat inside a terminal,&#8221; the obvious reaction from serious users is not just curiosity. It is caution.</p><p>That is a fair reaction.</p><p>If chat inside a terminal is sloppy, it is scary. If file attachments inside terminal chat are sloppy, it gets worse fast. So this post is partly about broader file support, but more importantly it is about the security and privacy posture behind it.</p><div><hr></div><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!ftV6!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3bc584-94de-40af-a200-3ce395663980_1572x464.png" data-component-name="Image2ToDOM"><div class="image2-inset image2-full-screen"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!ftV6!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3bc584-94de-40af-a200-3ce395663980_1572x464.png 424w, https://substackcdn.com/image/fetch/$s_!ftV6!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3bc584-94de-40af-a200-3ce395663980_1572x464.png 848w, https://substackcdn.com/image/fetch/$s_!ftV6!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3bc584-94de-40af-a200-3ce395663980_1572x464.png 1272w, https://substackcdn.com/image/fetch/$s_!ftV6!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3bc584-94de-40af-a200-3ce395663980_1572x464.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!ftV6!,w_5760,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3bc584-94de-40af-a200-3ce395663980_1572x464.png" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/ed3bc584-94de-40af-a200-3ce395663980_1572x464.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;full&quot;,&quot;height&quot;:430,&quot;width&quot;:1456,&quot;resizeWidth&quot;:null,&quot;bytes&quot;:146475,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/190358868?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3bc584-94de-40af-a200-3ce395663980_1572x464.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-fullscreen" alt="" srcset="https://substackcdn.com/image/fetch/$s_!ftV6!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3bc584-94de-40af-a200-3ce395663980_1572x464.png 424w, https://substackcdn.com/image/fetch/$s_!ftV6!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3bc584-94de-40af-a200-3ce395663980_1572x464.png 848w, https://substackcdn.com/image/fetch/$s_!ftV6!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3bc584-94de-40af-a200-3ce395663980_1572x464.png 1272w, https://substackcdn.com/image/fetch/$s_!ftV6!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2Fed3bc584-94de-40af-a200-3ce395663980_1572x464.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><h3>First, The Feature Itself</h3><p>The reason I spent the time building this seem obvious when you first encounter it:</p><ol><li><p>It gives me immediate and direct feedback from the community about what they want and features they need. Total win.</p></li><li><p>It inspires me and keeps me motivated. And I can get lonely too.</p></li></ol><p>So, it was built and it&#8217;s really, really cool.</p><p>And now, I&#8217;ve expanded attachment support in YEN Chat beyond the original image and document flow, including CSV, JSON, ICS, EML on top of existingsupport for images and common document formats.</p><p>That means people can share a quick export, an API payload sample, a calendar invite, a message thread, a markdown note, or a plain text artifact without leaving the terminal workflow.</p><p>That sounds like a convenience feature, but it only works if the delivery path is hardened enough to deserve the trust people place in a terminal. And it is.</p><p>I didn&#8217;t treat this as &#8220;add a few MIME types and move on.&#8221; I treated it as a trust-boundary change. That means the file expansion shipped together with private storage, proxy-only delivery, stricter response headers, mediated access paths, and tighter defaults for how different attachment types open.</p><p>These are things the user will never see. But, I know they&#8217;re air-tight and risk-free. I mean, you shouldn&#8217;t share your <strong>private keys</strong> in chat, but, you can share anything else within reason.</p><div class="captioned-image-container"><figure><a class="image-link image2 is-viewable-img" target="_blank" href="https://substackcdn.com/image/fetch/$s_!8fAF!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18f3deea-d149-4a6b-b0e1-74b4534028ec_976x338.png" data-component-name="Image2ToDOM"><div class="image2-inset"><picture><source type="image/webp" srcset="https://substackcdn.com/image/fetch/$s_!8fAF!,w_424,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18f3deea-d149-4a6b-b0e1-74b4534028ec_976x338.png 424w, https://substackcdn.com/image/fetch/$s_!8fAF!,w_848,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18f3deea-d149-4a6b-b0e1-74b4534028ec_976x338.png 848w, https://substackcdn.com/image/fetch/$s_!8fAF!,w_1272,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18f3deea-d149-4a6b-b0e1-74b4534028ec_976x338.png 1272w, https://substackcdn.com/image/fetch/$s_!8fAF!,w_1456,c_limit,f_webp,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18f3deea-d149-4a6b-b0e1-74b4534028ec_976x338.png 1456w" sizes="100vw"><img src="https://substackcdn.com/image/fetch/$s_!8fAF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18f3deea-d149-4a6b-b0e1-74b4534028ec_976x338.png" width="728" height="252.11475409836066" data-attrs="{&quot;src&quot;:&quot;https://substack-post-media.s3.amazonaws.com/public/images/18f3deea-d149-4a6b-b0e1-74b4534028ec_976x338.png&quot;,&quot;srcNoWatermark&quot;:null,&quot;fullscreen&quot;:false,&quot;imageSize&quot;:&quot;normal&quot;,&quot;height&quot;:338,&quot;width&quot;:976,&quot;resizeWidth&quot;:728,&quot;bytes&quot;:91093,&quot;alt&quot;:null,&quot;title&quot;:null,&quot;type&quot;:&quot;image/png&quot;,&quot;href&quot;:null,&quot;belowTheFold&quot;:true,&quot;topImage&quot;:false,&quot;internalRedirect&quot;:&quot;https://blog.yen.chat/i/190358868?img=https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18f3deea-d149-4a6b-b0e1-74b4534028ec_976x338.png&quot;,&quot;isProcessing&quot;:false,&quot;align&quot;:&quot;center&quot;,&quot;offset&quot;:false}" class="sizing-normal" alt="" srcset="https://substackcdn.com/image/fetch/$s_!8fAF!,w_424,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18f3deea-d149-4a6b-b0e1-74b4534028ec_976x338.png 424w, https://substackcdn.com/image/fetch/$s_!8fAF!,w_848,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18f3deea-d149-4a6b-b0e1-74b4534028ec_976x338.png 848w, https://substackcdn.com/image/fetch/$s_!8fAF!,w_1272,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18f3deea-d149-4a6b-b0e1-74b4534028ec_976x338.png 1272w, https://substackcdn.com/image/fetch/$s_!8fAF!,w_1456,c_limit,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F18f3deea-d149-4a6b-b0e1-74b4534028ec_976x338.png 1456w" sizes="100vw" loading="lazy"></picture><div class="image-link-expand"><div class="pencraft pc-display-flex pc-gap-8 pc-reset"><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container restack-image"><svg aria-hidden="true" width="20" height="20" viewBox="0 0 20 20" fill="none" stroke-width="1.5" stroke="var(--color-fg-primary)" stroke-linecap="round" stroke-linejoin="round" xmlns="http://www.w3.org/2000/svg"><g><path d="M2.53001 7.81595C3.49179 4.73911 6.43281 2.5 9.91173 2.5C13.1684 2.5 15.9537 4.46214 17.0852 7.23684L17.6179 8.67647M17.6179 8.67647L18.5002 4.26471M17.6179 8.67647L13.6473 6.91176M17.4995 12.1841C16.5378 15.2609 13.5967 17.5 10.1178 17.5C6.86118 17.5 4.07589 15.5379 2.94432 12.7632L2.41165 11.3235M2.41165 11.3235L1.5293 15.7353M2.41165 11.3235L6.38224 13.0882"></path></g></svg></button><button tabindex="0" type="button" class="pencraft pc-reset pencraft icon-container view-image"><svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize2 lucide-maximize-2"><polyline points="15 3 21 3 21 9"></polyline><polyline points="9 21 3 21 3 15"></polyline><line x1="21" x2="14" y1="3" y2="10"></line><line x1="3" x2="10" y1="21" y2="14"></line></svg></button></div></div></div></a></figure></div><p>You see? Never share sensitive data! And we&#8217;re good. A few things I worked on:</p><ol><li><p>Private storage and made <strong>files.yen.chat</strong> a tightly-controlled delivery path.</p></li><li><p>Direct anonymous storage upload, list, and read paths are denied.</p></li><li><p>Attachment fetches go through the proxy path instead of straight to storage.</p></li><li><p>Upstream fetches use service-role credentials on the server side only.</p></li><li><p>Proxy host and path are tightly bounded.</p></li><li><p>Upstream redirects are rejected.</p></li><li><p>Attachment responses get <strong>X-Content-Type-Options: nosniff</strong>.</p></li><li><p>Non-image attachments are forced to download with <strong>Content-Disposition: attachment</strong> and <strong>X-Download-Options: noopen</strong> instead of rendering inline in the browser.</p></li></ol><p>And, of course, privacy reigns as a surpreme import &#8212; I am a cypherpunk, after all. Privacy matters more to me than most people could really understand. So, I extend that to everything that I try to do, especially for folks who count on using this wonderful, beautiful thing that is a Terminal.</p><p>You see, security is not only about preventing code execution or bypassing headers. It is also about how much data the system keeps, where identity is bound, and what is exposed by default. YEN Chat is built around mediated access, not direct client trust.</p><p>Sender identity is session-bound on the server side and the client uses a local device ID to request a short-lived chat session, and that device ID is treated as a private credential on disk with tightened permissions, including private directory and file modes for its local storage.</p><p>Messages and attachments are not meant to live forever. Chat messages age out after <strong>80 hours</strong>, and attachments follow the same <strong>80-hour</strong> cleanup window. Nothing is kept beyond ~3 days. It&#8217;s hard delete only. Let&#8217;s go.</p><p>So, on the surface it&#8217;s a simple &#8220;<strong>chat</strong>&#8221; but underneath it&#8217;s everything that I&#8217;ve learned over 20 years of writing enterprise-grade software, inside a simple frame that can be another place to drop emojis.</p><p>Go figure.</p><p>&#8212; 8</p>]]></content:encoded></item></channel></rss>