<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: 崮生</title>
    <description>The latest articles on Forem by 崮生 (@llej).</description>
    <link>https://forem.com/llej</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2009505%2F8962540b-5e92-42f7-93c6-04644d3c8e1e.png</url>
      <title>Forem: 崮生</title>
      <link>https://forem.com/llej</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/llej"/>
    <language>en</language>
    <item>
      <title>Chrome DevTools MCP but from the inside — a Vite plugin that lets AI debug your frontend in any browser</title>
      <dc:creator>崮生</dc:creator>
      <pubDate>Thu, 26 Mar 2026 02:50:38 +0000</pubDate>
      <link>https://forem.com/llej/chrome-devtools-mcp-but-from-the-inside-a-vite-plugin-that-lets-ai-debug-your-frontend-in-any-5g29</link>
      <guid>https://forem.com/llej/chrome-devtools-mcp-but-from-the-inside-a-vite-plugin-that-lets-ai-debug-your-frontend-in-any-5g29</guid>
      <description>&lt;p&gt;Chrome DevTools MCP is great, but it doesn't work if you're building browser extensions, embedded Webviews, or any non-standard runtime. Found an open source alternative: &lt;a href="https://github.com/2234839/vite-plugin-pilot" rel="noopener noreferrer"&gt;vite-plugin-pilot&lt;/a&gt; — live demo: &lt;a href="https://2234839.github.io/vite-plugin-pilot/" rel="noopener noreferrer"&gt;https://2234839.github.io/vite-plugin-pilot/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Instead of connecting through Chrome's debugging protocol (the official backdoor), it plants an agent inside your page (the insider approach). So it works anywhere a browser runs — extensions, Webviews, custom clients, even regular frontend development.&lt;/p&gt;

&lt;p&gt;The core idea is simple: it lets AI agents eval JS in the browser, so they can check their own frontend code for bugs, interact with the page, and verify that everything looks right.&lt;/p&gt;

&lt;p&gt;It's also useful for exploring how to implement things in weird runtime environments. The agent can explore on its own, and these are places where Chrome DevTools MCP and similar tools just don't work.&lt;/p&gt;

&lt;p&gt;Some things it can do:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Standalone server mode&lt;/strong&gt; — &lt;code&gt;npx pilot server&lt;/code&gt;, no Vite required. Connect to any website through a Tampermonkey userscript or a console bridge script. Not tied to Vite projects anymore.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Browser-to-Claude Code channel&lt;/strong&gt; — Alt+Click any element on the page, and it generates a prompt you can send directly back to Claude Code. No more copy-pasting between browser and terminal. (Full disclosure: this feature requires a Claude Code Pro/Max account, haven't tested it myself)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multi-tab support&lt;/strong&gt; — agent can switch between tabs, each tracked independently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vue/React aware&lt;/strong&gt; — handles v-model, scheduler quirks, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One thing that's kind of interesting: this whole project was iterated on by AI (glm5-turbo + Claude Code). It started as a single &lt;code&gt;vite-plugin.ts&lt;/code&gt; file, and the project itself used its own &lt;a href="https://github.com/2234839/vite-plugin-pilot/tree/master/playground" rel="noopener noreferrer"&gt;playground&lt;/a&gt; to test and improve itself. Since it was built by an agent using the plugin, it's pretty well tuned for how agents actually use it.&lt;/p&gt;

&lt;p&gt;MIT licensed, TypeScript, works with any Vite project.&lt;/p&gt;

&lt;p&gt;P.S. Sorry if the English is a bit off — my English isn't great, so this post was translated and polished by AI from my original Chinese notes. If anything reads weird, that's on me (and my AI translator 😅)&lt;/p&gt;

</description>
      <category>ai</category>
      <category>frontend</category>
      <category>javascript</category>
      <category>mcp</category>
    </item>
    <item>
      <title>Backend API Design with Effect</title>
      <dc:creator>崮生</dc:creator>
      <pubDate>Thu, 24 Apr 2025 03:50:19 +0000</pubDate>
      <link>https://forem.com/llej/backend-api-design-with-effect-h60</link>
      <guid>https://forem.com/llej/backend-api-design-with-effect-h60</guid>
      <description>&lt;p&gt;Recently while developing &lt;a href="https://shenzilong.cn/index/TsFullStack.html#20250413211142-d533spm" rel="noopener noreferrer"&gt;TsFullStack&lt;/a&gt;, I deeply integrated Effect into the backend API design.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;a href="https://shenzilong.cn/index/effect-ts.html#20250326094349-86z2zw4" rel="noopener noreferrer"&gt;Why Effect-TS?&lt;/a&gt;
&lt;/h2&gt;

&lt;p&gt;Consider this file upload API example - it internally depends on authService (user authentication). If we were to pass auth through parameters, it would become extremely cumbersome in nested call scenarios, especially when new dependencies need to be added later (requiring full-chain modifications).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1u333pxtxvh3ei3ndr5m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1u333pxtxvh3ei3ndr5m.png" alt="Dependency Injection Example" width="749" height="69"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Traditional solutions like thread-local variables (&lt;a href="https://shenzilong.cn/index/%E5%AF%B9%E4%BA%8E%E4%BE%9D%E8%B5%96%E6%B3%A8%E5%85%A5%E7%9A%84%E6%80%9D%E8%80%83-%E4%BA%8C.html#20250202170436-xsqbs5h" rel="noopener noreferrer"&gt;CLS&lt;/a&gt; in Node.js), InversifyJS, or Vue's provide/inject all share one critical limitation: you can't know a program's dependencies until runtime (or after reading the entire codebase).&lt;/p&gt;

&lt;p&gt;Effect solves this elegantly through its type system. In this &lt;a href="https://shenzilong.cn/index/TsFullStack.html#20250413211142-d533spm" rel="noopener noreferrer"&gt;TsFullStack&lt;/a&gt; example running our upload API, if I manually comment out the authService provider, TypeScript immediately flags the missing AuthService dependency:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvd19n4yr1s877bjjvnpd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvd19n4yr1s877bjjvnpd.png" alt="Type Safety Example" width="800" height="216"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This gives us compile-time knowledge of all dependencies. Why is this revolutionary?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Writing robust systems&lt;/strong&gt;: Eliminates whole categories of dependency-related bugs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Unit testing&lt;/strong&gt;: No more guessing what dependencies a component needs - they're explicitly declared in the type system&lt;/li&gt;
&lt;/ol&gt;

</description>
      <category>typescript</category>
    </item>
  </channel>
</rss>
