PageSourceSearch

https://nutchanon.org/_app/immutable/chunks/CXlUuRTq.js

js nutchanon.org collected 2026-09-25 22:47:41 UTC 13,987 bytes, 31 lines download raw bytes

1import{f as o,a}from"./CeOD2e6I.js";import"./Pe96CdxN.js";import{O as n}from"./C5Iyu3w9.js";const l={title:"dev3000: A Dev Server That Your AI Agent Can Actually See",description:"d3k wraps your dev server, launches a monitored browser, and writes everything into a single log file. Now your AI assistant has the full picture.",date:"2026-03-28",published:!1,series:"Frontend AI Dev"},{title:i,description:d,date:h,published:u,series:y}=l;var r=o(`<blockquote><p><strong>Frontend AI Dev</strong> (3/5): <a href="/blog/agent-browser-ai-automation">1. agent-browser</a> | <a href="/blog/portless-localhost-urls">2. portless</a> | dev3000 | <a href="/blog/svelte-grab-component-source">4. svelte-grab</a> | <a href="/blog/d3k-portless-agent-browser">5. The Full Stack</a></p></blockquote> <p>Here’s the gap in AI-assisted development: your AI agent can read your source code, your terminal output, and your error messages. But it can’t see your app. It doesn’t know that the button is overlapping the navbar, that the toast notification is stuck, or that the loading spinner never stops.</p> <p><strong>dev3000</strong> (cli: <code>d3k</code>) bridges this gap. It wraps your dev server, launches a monitored Chrome instance, and writes everything — server logs, browser console, network errors, screenshots — into a single timestamped log file that AI agents can read.</p> <h2>Quick Start</h2> <pre class="shiki github-dark" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#B392F0">npm</span><span style="color:#9ECBFF"> install</span><span style="color:#79B8FF"> -g</span><span style="color:#9ECBFF"> dev3000</span></span>
2<span class="line"></span>
3<span class="line"><span style="color:#6A737D"># Start with an AI agent in split-screen (tmux)</span></span>
4<span class="line"><span style="color:#B392F0">d3k</span><span style="color:#79B8FF"> --with-agent</span><span style="color:#9ECBFF"> claude</span></span>
5<span class="line"></span>
6<span class="line"><span style="color:#6A737D"># Or standalone, no agent</span></span>
7<span class="line"><span style="color:#B392F0">d3k</span><span style="color:#79B8FF"> --no-agent</span></span></code></pre> <p>d3k auto-detects your framework (Next.js, Vite, SvelteKit, Django, Rails, etc.) and starts the appropriate dev command. Override with <code>-c</code>:</p> <pre class="shiki github-dark" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#B392F0">d3k</span><span style="color:#79B8FF"> --no-agent</span><span style="color:#79B8FF"> -c</span><span style="color:#9ECBFF"> 'bun dev'</span></span></code></pre> <h2>What It Captures</h2> <p>Once running, d3k monitors two streams and merges them into <code>~/.d3k/&#123;project&#125;/d3k.log</code>:</p> <p><strong>Server side:</strong></p> <ul><li>stdout/stderr from your dev server</li> <li>Build errors, compilation warnings</li> <li>API request logs</li></ul> <p><strong>Browser side (via Chrome DevTools Protocol):</strong></p> <ul><li>Console messages (log, warn, error)</li> <li>Unhandled exceptions</li> <li>Network request failures (4xx, 5xx, timeouts)</li> <li>Navigation events</li> <li>Screenshots on errors and page transitions</li></ul> <p>The log format is designed for AI consumption:</p> <pre class="shiki github-dark" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span>[14:23:15] [BROWSER] [ERROR] Unhandled TypeError: Cannot read properties of null</span></span>
8<span class="line"><span>[14:23:15] [SERVER]  [INFO]  GET /api/users 200 12ms</span></span>
9<span class="line"><span>[14:23:16] [BROWSER] [NETWORK] POST /api/orders -> 500 Internal Server Error</span></span></code></pre> <p>One file. Both sources. Timestamped. Grep-friendly.</p> <h2>The session.json</h2> <p>Every d3k session writes a metadata file at <code>~/.d3k/&#123;project&#125;/session.json</code>:</p> <pre class="shiki github-dark" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#E1E4E8">&#123;</span></span>
10<span class="line"><span style="color:#79B8FF">  "projectName"</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">"myapp-a1b2c3"</span><span style="color:#E1E4E8">,</span></span>
11<span class="line"><span style="color:#79B8FF">  "appPort"</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">"4782"</span><span style="color:#E1E4E8">,</span></span>
12<span class="line"><span style="color:#79B8FF">  "publicUrl"</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">"http://myapp-a1b2c3.localhost:1355"</span><span style="color:#E1E4E8">,</span></span>
13<span class="line"><span style="color:#79B8FF">  "cdpUrl"</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">"ws://localhost:9222/devtools/page/..."</span><span style="color:#E1E4E8">,</span></span>
14<span class="line"><span style="color:#79B8FF">  "pid"</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">12345</span><span style="color:#E1E4E8">,</span></span>
15<span class="line"><span style="color:#79B8FF">  "serverPid"</span><span style="color:#E1E4E8">: </span><span style="color:#79B8FF">12346</span><span style="color:#E1E4E8">,</span></span>
16<span class="line"><span style="color:#79B8FF">  "chromePids"</span><span style="color:#E1E4E8">: [</span><span style="color:#79B8FF">12400</span><span style="color:#E1E4E8">, </span><span style="color:#79B8FF">12401</span><span style="color:#E1E4E8">],</span></span>
17<span class="line"><span style="color:#79B8FF">  "preferredBrowserTool"</span><span style="color:#E1E4E8">: </span><span style="color:#9ECBFF">"agent-browser"</span></span>
18<span class="line"><span style="color:#E1E4E8">&#125;</span></span></code></pre> <p>This is how other tools discover the running session. The project name includes a hash of the working directory (<code>sha256(cwd)[0:6]</code>), so multiple worktrees of the same project each get their own session. No cross-contamination between your <code>develop</code> branch and a feature worktree.</p> <h2>Diagnostic Commands</h2> <p>These are the commands AI agents (or you) use to understand what’s happening:</p> <h3><code>d3k errors</code></h3> <p>
18Shows recent errors from both server and browser, with the user interactions that preceded each error:</p> <pre class="shiki github-dark" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#B392F0">d3k</span><span style="color:#9ECBFF"> errors</span></span>
19<span class="line"><span style="color:#B392F0">d3k</span><span style="color:#9ECBFF"> errors</span><span style="color:#79B8FF"> -n</span><span style="color:#79B8FF"> 20</span><span style="color:#6A737D">          # last 20 errors</span></span>
20<span class="line"><span style="color:#B392F0">d3k</span><span style="color:#9ECBFF"> errors</span><span style="color:#79B8FF"> --context</span><span style="color:#6A737D">       # include preceding user actions</span></span>
21<span class="line"><span style="color:#B392F0">d3k</span><span style="color:#9ECBFF"> errors</span><span style="color:#79B8FF"> --all</span><span style="color:#6A737D">           # full session history</span></span></code></pre> <h3><code>d3k fix</code></h3> <p>Deep analysis mode. Categorizes errors by severity, identifies patterns, and suggests fixes:</p> <pre class="shiki github-dark" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#B392F0">d3k</span><span style="color:#9ECBFF"> fix</span></span>
22<span class="line"><span style="color:#B392F0">d3k</span><span style="color:#9ECBFF"> fix</span><span style="color:#79B8FF"> --focus</span><span style="color:#9ECBFF"> build</span><span style="color:#6A737D">      # focus on build/compilation errors</span></span>
23<span class="line"><span style="color:#B392F0">d3k</span><span style="color:#9ECBFF"> fix</span><span style="color:#79B8FF"> --time</span><span style="color:#79B8FF"> 30</span><span style="color:#6A737D">          # analyze last 30 minutes</span></span></code></pre> <h3><code>d3k crawl</code></h3> <p>Discovers all URLs in your app by navigating links:</p> <pre class="shiki github-dark" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#B392F0">d3k</span><span style="color:#9ECBFF"> crawl</span></span>
24<span class="line"><span style="color:#B392F0">d3k</span><span style="color:#9ECBFF"> crawl</span><span style="color:#79B8FF"> --depth</span><span style="color:#9ECBFF"> all</span><span style="color:#6A737D">      # exhaustive crawl</span></span></code></pre> <h3><code>d3k find-component</code></h3> <p>Given a DOM selector, finds the source file that renders it:</p> <pre class="shiki github-dark" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#B392F0">d3k</span><span style="color:#9ECBFF"> find-component</span><span style="color:#9ECBFF"> "nav.header"</span></span>
25<span class="line"><span style="color:#B392F0">d3k</span><span style="color:#9ECBFF"> find-component</span><span style="color:#9ECBFF"> "[data-testid='submit-btn']"</span></span></code></pre> <p>Uses the browser to inspect the DOM and trace back to source. Useful when an AI agent sees an element in the accessibility tree but needs to find where it’s defined.</p> <h2>Split-Screen with tmux</h2> <p>The flagship workflow:</p> <pre class="shiki github-dark" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#B392F0">d3k</span><span style="color:#79B8FF"> --with-agent</span><span style="color:#9ECBFF"> claude</span></span></code></pre> <p>This opens a tmux session with two panes:</p> <ul><li><strong>Left</strong>: d3k’s TUI showing live server and browser logs, color-coded by type</li> <li><strong>Right</strong>: Claude Code with full access to d3k commands</li></ul> <p>Claude can:</p> <ol><li>Read <code>d3k errors</code> to understand failures</li> <li>Run <code>d3k find-component</code> to locate source files</li> <li>Edit code and watch d3k for hot-reload results</li> <li>Use <code>agent-browser</code> to interact with the monitored Chrome instance</li></ol> <p>Switch between panes with <code>Ctrl+B</code> then arrow keys. <code>Ctrl+C</code> exits both.</p> <h2>portless Integration</h2> <p>Add <code>--portless</code> to use named <code>.localhost</code> URLs instead of port numbers:</p> <pre class="shiki github-dark" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span style="color:#B392F0">d3k</span><span style="color:#79B8FF"> --no-agent</span><span style="color:#79B8FF"> --portless</span><span style="color:#79B8FF"> -c</span><span style="color:#9ECBFF"> 'bun dev'</span></span></code></pre> <p>Now your app is at <code>http://myapp-a1b2c3.localhost:1355</code> instead of <code>http://localhost:5173</code>. Each worktree gets a unique hash in the URL, preventing collisions.</p> <h2>The TUI</h2> <p>d3k’s terminal interface shows:</p> <ul><li>
25Live log streaming from both server and browser</li> <li>Color-coded messages: errors in red, network in blue, navigation in green</li> <li>Screenshot notifications in cyan</li> <li>Responsive layout that adapts to terminal size</li></ul> <p>Disable the TUI if you prefer plain output: <code>d3k --no-tui</code> or <code>d3k --tail</code> for a <code>tail -f</code> style view.</p> <h2>Chrome Profile Isolation</h2> <p>Each project gets its own Chrome profile at <code>~/.d3k/&#123;project&#125;/chrome-profile/</code>. This means:</p> <ul><li>Login sessions persist between d3k restarts (for the same project)</li> <li>Different projects have different cookies and localStorage</li> <li>No interference with your personal Chrome</li></ul> <h2>Process Management</h2> <p>d3k tracks every process it spawns (dev server PID, Chrome PIDs) in <code>session.json</code>. On shutdown, it kills exactly what it started. No orphaned Chrome processes, no zombie dev servers.</p> <p>If d3k crashes, the PIDs are still in <code>session.json</code> for manual cleanup. But in practice, the signal handlers catch most cases cleanly.</p> <h2>File Structure</h2> <pre class="shiki github-dark" style="background-color:#24292e;color:#e1e4e8" tabindex="0"><code><span class="line"><span>~/.d3k/</span></span>
26<span class="line"><span>  myapp-a1b2c3/</span></span>
27<span class="line"><span>    d3k.log              # unified timestamped log</span></span>
28<span class="line"><span>    session.json         # session metadata (PIDs, ports, URLs)</span></span>
29<span class="line"><span>    chrome-profile/      # Chrome user data</span></span>
30<span class="line"><span>    screenshots/         # timestamped screenshots</span></span>
31<span class="line"><span>    logs/                # rotated log files</span></span></code></pre> <h2>When to Use It</h2> <p>d3k is most valuable when:</p> <ul><li>You’re working with AI agents that need runtime context (not just source code)</li> <li>You’re debugging issues that only manifest in the browser (hydration errors, layout bugs, API failures)</li> <li>You want a single log file that captures everything instead of switching between terminal and DevTools</li> <li>You’re running multiple projects/worktrees and need isolated environments</li></ul> <p>It’s not a replacement for your browser’s DevTools. It’s a bridge between your running app and your AI assistant.</p> <hr/> <blockquote><p><strong>Frontend AI Dev</strong> (3/5): <a href="/blog/agent-browser-ai-automation">1. agent-browser</a> | <a href="/blog/portless-localhost-urls">2. portless</a> | dev3000 | <a href="/blog/svelte-grab-component-source">4. svelte-grab</a> | <a href="/blog/d3k-portless-agent-browser">5. The Full Stack</a></p></blockquote>`,1);function g(s){var e=r();n(128),a(s,e)}export{g as default,l as metadata};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.