<?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: Daniel Murrell</title>
    <description>The latest articles on Forem by Daniel Murrell (@dsmurrell).</description>
    <link>https://forem.com/dsmurrell</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%2F3644403%2F5141473e-1977-426d-a801-572cf1e8e7c0.jpg</url>
      <title>Forem: Daniel Murrell</title>
      <link>https://forem.com/dsmurrell</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dsmurrell"/>
    <language>en</language>
    <item>
      <title>The Project Nursery</title>
      <dc:creator>Daniel Murrell</dc:creator>
      <pubDate>Sat, 03 Jan 2026 20:29:55 +0000</pubDate>
      <link>https://forem.com/dsmurrell/the-project-nursery-10a5</link>
      <guid>https://forem.com/dsmurrell/the-project-nursery-10a5</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Giving Cursor your own patterns to copy from&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI is pretty good at copying patterns. It’s not as good at inventing them. Give it a blank slate and ask for “a service layer,” and you’ll get something generic... probably fine, but not how you’d do it yourself. Point it at code that already works the way you like, and it’ll copy that instead.&lt;/p&gt;

&lt;p&gt;This is obvious in hindsight, but it took me a while to discover. I kept starting new projects from scratch, describing what I wanted, getting okay-ish results. Meanwhile I had several working projects with patterns I’d refined over time just sitting there.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;The trick that made this click for me was symlinking my existing projects into the same parent folder as my new one:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;mkdir ~/projects/nursery&lt;br&gt;
cd ~/projects/nursery&lt;br&gt;
ln -s ~/projects/flow-myna/mono flow-myna&lt;br&gt;
ln -s ~/projects/leveloh/mono leveloh&lt;br&gt;
ln -s ~/projects/auth-router auth-router&lt;br&gt;
mkdir spikelog  # new project&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Then I opened that folder in Cursor. Now when I say “build the auth context like flow-myna does it” or “use the same alembic migration setup as leveloh,” Cursor can see those folders/files. I’m not sure about other coding agent setups, but this trick made things easy to manage within Cursor.&lt;/p&gt;

&lt;p&gt;One nice thing about symlinks specifically: Cursor will ask for confirmation before editing files in a symlinked folder. So your reference projects are protected... the AI can read them but won’t accidentally modify them, and if you do want them modified, you can just accept.&lt;/p&gt;

&lt;h2&gt;
  
  
  Your Projects as a Style Guide
&lt;/h2&gt;

&lt;p&gt;I think of this folder as a nursery for new projects. The other projects aren’t templates... they’re just real working code that happens to be visible. They’ve diverged in different directions based on what they needed. Some have auth, some don’t. Some have payment processing, others are just static sites.&lt;/p&gt;

&lt;p&gt;This is different from maintaining a boilerplate repo. With a boilerplate, you’re trying to anticipate what you’ll need and abstract it into something reusable. That’s a lot of upfront work, and six months later your preferences have changed anyway.&lt;/p&gt;

&lt;p&gt;Here, there’s nothing to maintain. Each project is just itself. When I start something new, I tell the AI “look at how this other project handles X and do something similar.” It handles the copying, adapted to what I actually need this time.&lt;/p&gt;

&lt;h2&gt;
  
  
  Staying in Your Own Stack
&lt;/h2&gt;

&lt;p&gt;I’ve found this works better than pointing the AI at some popular starter template. When it’s my code, I already know the patterns. I know why things are structured the way they are, where to look when something breaks.&lt;/p&gt;

&lt;p&gt;With someone else’s boilerplate, you’re learning their conventions while trying to build something. The AI doesn’t know which parts are load-bearing and which are just preferences. It’s easier when everything is already familiar.&lt;/p&gt;

&lt;p&gt;My stack for context: Next.js 14 with Tailwind on the frontend, FastAPI with PostgreSQL on the backend. Nothing unusual... just things I’ve used before and have working examples of.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;p&gt;I’d been sitting on a domain for a simple metrics service idea for years. A service where users POST a chart name and value, and charts appear automatically. It felt like a multi-week project, so I kept putting it off.&lt;/p&gt;

&lt;p&gt;With this setup it took about 8 hours spread across a few days. The service is at &lt;a href="https://spikelog.com" rel="noopener noreferrer"&gt;spikelog.com&lt;/a&gt; if you want to take a look.&lt;/p&gt;

&lt;p&gt;I don’t know if this generalises to everyone’s workflow, but the main idea seems sound: the patterns you’ve built up over time are worth reusing, and making them visible to the AI is an easy way to do that.&lt;/p&gt;

&lt;p&gt;I'll be starting my new projects this way from now on.&lt;/p&gt;

&lt;p&gt;--&lt;br&gt;
More like this → &lt;a href="https://dsmurrell.com" rel="noopener noreferrer"&gt;dsmurrell.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>ai</category>
      <category>vibecoding</category>
    </item>
    <item>
      <title>The best improvement I’ve made to my Cursor workflow</title>
      <dc:creator>Daniel Murrell</dc:creator>
      <pubDate>Thu, 04 Dec 2025 19:35:37 +0000</pubDate>
      <link>https://forem.com/dsmurrell/the-best-improvement-ive-made-to-my-cursor-workflow-2pf4</link>
      <guid>https://forem.com/dsmurrell/the-best-improvement-ive-made-to-my-cursor-workflow-2pf4</guid>
      <description>&lt;p&gt;tl;dr: let coding agents access runtime output&lt;/p&gt;

&lt;p&gt;I’m pretty sure this isn’t novel, and I’m almost certain many people already do some flavour of this, but it’s been the single biggest unlock in my local AI-assisted development with Cursor, and it’s so simple I want to share it.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;If your coding agent can’t see what your program is doing, it can’t debug it&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Cursor doesn’t have some magical ability to read everything happening on your machine. Unless you explicitly expose your output, the agent is effectively blind.&lt;/p&gt;

&lt;p&gt;When I let it see my program’s output, I found that it could solve problems that used to take me 30 minutes in about 30 seconds and free up my time to spend on other areas of the startup.&lt;/p&gt;

&lt;p&gt;This post is me sharing how I let Cursor see my program’s outputs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The problem&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Currently, my local dev setup has three moving parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a Python FastAPI backend&lt;/li&gt;
&lt;li&gt;a React frontend&lt;/li&gt;
&lt;li&gt;a Python FastAPI auth router which speaks to WorkOS to allow authentication&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All three emit logs.&lt;br&gt;
All three can fail independently.&lt;br&gt;
All three can require debugging to get back up and running.&lt;/p&gt;

&lt;p&gt;Cursor can run commands you ask for, or even come up with some that it thinks might be useful, but it cannot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;attach to a terminal window you opened yourself&lt;/li&gt;
&lt;li&gt;read real-time stdout/stderr&lt;/li&gt;
&lt;li&gt;watch a hot-reloading server&lt;/li&gt;
&lt;li&gt;magically see your browser’s console logs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And when the agent tries to “fix” something by killing your running server or client, it destroys your whole hot-reloading setup. Now you have to put everything back up again just to continue. This can kill your productivity in a big way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The unlock&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Coding agents can be more capable than you’d expect, and sometimes the best thing you can do is simply ask whether something you’re wondering about is possible. At one point, I asked: “Can you read something inside a screen session?”&lt;/p&gt;

&lt;p&gt;To my surprise, Cursor told me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you run ’screen -X hardcopy’, I can read the output.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Then I asked Cursor if it could check the current screens that were running using screen -ls and find the last 50 lines of the server’s output. It did.&lt;/p&gt;

&lt;p&gt;This gives the agent something to look at beyond just the code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How I set it up&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;I use runnem, a tiny tool I built for a different reason entirely: to remember your run setup and let you switch between multiple projects seamlessly.&lt;/p&gt;

&lt;p&gt;It runs each service inside its own screen session, and that just so happens to make this unlock possible. But you can use anything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;standalone screen&lt;/li&gt;
&lt;li&gt;tmux&lt;/li&gt;
&lt;li&gt;Docker&lt;/li&gt;
&lt;li&gt;setting up logging to a file on disk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The principle is universal.&lt;/p&gt;

&lt;p&gt;With runnem, Cursor can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;list sessions with screen -ls&lt;/li&gt;
&lt;li&gt;identify backend and frontend sessions&lt;/li&gt;
&lt;li&gt;dump the relevant session’s output to disk without interrupting them&lt;/li&gt;
&lt;li&gt;analyse logs while keeping everything up and ready to hot-reload on the next code change&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;My .cursor/rules snippet&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;To guide the agent, I’ve added this to my .cursor/rules file.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;If you need to check backend or frontend logs just ls all the active screens and then use a command like this:&lt;br&gt;
“screen -S 94383.runnem-flow-myna-server -X hardcopy /tmp/backend_logs_200.txt &amp;amp;&amp;amp; tail -200 /tmp/backend_logs_200.txt”&lt;br&gt;
The screen with the ‘-server’ suffix is the backend and with the ‘-app’ suffix is the frontend.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sometimes I still explicitly tell the agent to “check the logs using screen -ls”, and that’s enough for the agent to get into a loop that fixes errors until the server is running again.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do you need runnem?&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;No. Use any setup you like.&lt;/p&gt;

&lt;p&gt;But runnem coincidentally makes this workflow very easy because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;each service has its own named screen&lt;/li&gt;
&lt;li&gt;I run three services across two languages&lt;/li&gt;
&lt;li&gt;the agent needs to cross-check all of them&lt;/li&gt;
&lt;li&gt;everything stays running with hot-reload intact&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I’ve been wanting an excuse to experiment with MCP, so I might try adding an MCP tool for runnem that lets Cursor talk to it more directly (for example, exposing “get backend logs” as a single tool call). But for now, this simple screen-based setup has been more than enough.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The final takeaway&lt;/strong&gt;:&lt;br&gt;
Once your agent can see your program’s output, it goes from:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;editing files based on guesses&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;to something much more powerful:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;responding to reality&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you’re running multiple services locally and want the agent to pull its weight:&lt;/p&gt;

&lt;p&gt;Expose the output. Give it vision.&lt;br&gt;
It’s a tiny setup change, but it has completely transformed how I work with AI.&lt;/p&gt;

&lt;p&gt;Are other coding agents doing this already?&lt;/p&gt;

&lt;p&gt;At the moment I don’t have the bandwidth to experiment with other coding agents. So there may well be setups like this included in those agents, or ways to nudge you into a similar workflow because it’s so powerful.&lt;/p&gt;

&lt;p&gt;On the other hand, maybe they don’t build this in because the languages and frameworks they have to interact with are so varied.&lt;/p&gt;

&lt;p&gt;I’d love to know in the comments what setup you use if you do things in a similar way! Especially if you’ve found a good way to give your agent visibility into the browser console logs that’s reliable and simple to setup.&lt;/p&gt;

&lt;p&gt;A more detailed post can be found here: &lt;a href="https://dsmurrell.com/articles/cursor-runtime-output" rel="noopener noreferrer"&gt;https://dsmurrell.com/articles/cursor-runtime-output&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>A small friction I finally removed</title>
      <dc:creator>Daniel Murrell</dc:creator>
      <pubDate>Wed, 03 Dec 2025 22:33:31 +0000</pubDate>
      <link>https://forem.com/dsmurrell/a-small-friction-i-finally-removed-ida</link>
      <guid>https://forem.com/dsmurrell/a-small-friction-i-finally-removed-ida</guid>
      <description>&lt;p&gt;Whenever I needed to track a number over time, I never even seriously looked at existing metrics tools. They all felt complicated at a glance... dashboards, exporters, configs.&lt;/p&gt;

&lt;p&gt;So instead I kept doing this odd little workaround: store the numbers myself, then ask an LLM to generate a quick script to visualise them.&lt;/p&gt;

&lt;p&gt;It worked.&lt;/p&gt;

&lt;p&gt;But it was also tedious in a way that felt out of proportion with the problem.&lt;/p&gt;

&lt;p&gt;What I really wanted was simpler:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;send a number → see how it changes over time&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I stopped rebuilding the storage and the chart every time and turned that tiny pattern into a single endpoint instead. No dashboards. No setup. No decisions to make.&lt;/p&gt;

&lt;p&gt;One number goes in, again and again. One chart quietly grows.&lt;/p&gt;

&lt;p&gt;Because I already lean on AI for glue code, I also wrote a prompt that drops this kind of tracking straight into an existing codebase. It scans your project, suggests sensible metrics to track, and then wires in calls to a single API.&lt;/p&gt;

&lt;p&gt;The rules are intentionally dull. Fire and forget, fail silently, aggregate anything noisy. Nothing clever. Nothing fragile.&lt;/p&gt;

&lt;p&gt;I’m planning on keeping it free. The 1,000 datapoint rolling limit per chart is the trade-off that makes that possible.&lt;/p&gt;

&lt;p&gt;If you end up wiring it into a side project, I’d genuinely love to see how you use this in the comments.&lt;/p&gt;

&lt;p&gt;And if the problem resonates, the little thing I built from this is at spikelog.com&lt;/p&gt;

</description>
      <category>vibecoding</category>
      <category>analytics</category>
      <category>api</category>
    </item>
  </channel>
</rss>
