<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged devtool</title>
<link>https://coderlegion.com/tag/devtool</link>
<description>Powered by Question2Answer</description>
<item>
<title>Leveraging AWS CodePipeline pipeline and Serverless Framework to deploy a Flask API.</title>
<link>https://coderlegion.com/31107/leveraging-aws-codepipeline-pipeline-and-serverless-framework-to-deploy-a-flask-api</link>
<description>&lt;p&gt;For the past couple of days. I have been working with the Serverless framework. I came to know that you can actually host your flask API that integrates several AWS services such as Lambda, API Gateway, and DynamoDB using this framework. I had to spend a lot of time to understand the process at first since there is not a lot of content regarding this implementation. So, here’s me contributing a little. &lt;/p&gt;
&lt;p&gt;To make this swift, I wanted to integrate the entire process with a pipeline that contains the code and a build environment. Here’s how everything is carried out. Please understand that this is not a beginner level tutorial and the whole process is written in assumption that the readers have knowledge and experience with AWS services and Python Flask.&lt;/p&gt;
&lt;p&gt;First, you need to have a flask api. An API that works. I couldn’t share the actual code that I first used since it is confidential . So, I have decided to go with a template of serverless framework. You can also convert your flask api to be compatible with serverless using the serverless-wsgi plugin. For this, you may need to make some changes to your serverless.yaml configurations. You can check it &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.serverless.com/blog/flask-python-rest-api-serverless-lambda-dynamodb/#converting-an-existing-flask-application&quot;&gt;here&lt;/a&gt; to achieve that&lt;/p&gt;
&lt;p&gt;Now that you have your api , lets upload it again to an aws codecommit repository. You can clone an empty repo, add the files, commit and push. Check it &lt;a rel=&quot;nofollow&quot; href=&quot;https://docs.aws.amazon.com/codecommit/latest/userguide/how-to-create-file.html&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Next, we need to create a build project in AWS CodeBuild.&lt;/p&gt;
&lt;p&gt;In this codebuild project, use the following buildspec.yaml file. You can choose an Ubuntu environment for the build project to run.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;version: 0.2
phases:
  install:
    runtime-versions:
      nodejs: 14
    commands:
        - npm install -g serverless
        - npm install serverless-compose
        - serverless --version
        - npm install serverless-deployment-bucket
        - sls plugin install -n serverless-wsgi
        - sls plugin install -n serverless-python-requirements

  build: 
    commands: 
      - serverless deploy 

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Remember: In this case, Codebuild is only used to run the deploy command. All the resources are built by serverless by automatically running a cloudformation.&lt;/p&gt;
&lt;p&gt;Now, we’re also gonna need another yaml file. This one is the configuration file for the serverless framework which will be deployed once we deploy it using the Aws pipeline.&lt;/p&gt;
&lt;p&gt;Here’s the configuration code.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;service: new12

frameworkVersion: '3'

custom:
  wsgi:
    app: app.hello

provider:
  name: aws
  runtime: python3.9

functions:
  api:
    handler: wsgi_handler.handler
    events:
      - httpApi: '*'

plugins:
  - serverless-wsgi
  - serverless-python-requirements


&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also keep your flask api file in the same directory. Make sure to configure codebuild to look for the specific branch in the specific repo.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/5n51ulma3twzipf83pt6.png&quot; alt=&quot;File structure in the repository&quot;&gt;&lt;/p&gt;
&lt;p&gt;Once everything is created, we need to make sure that our Codebuild service role has enough permission to use cloudformation and all the other services associated with the resources built through the cloudformation stack.&lt;/p&gt;
&lt;p&gt;In my case, I faced a lot of failed builds due to permission issues.Always make sure to check your build logs when your build fails, so that you can get a clear understanding of the underlying reasons and issues.&lt;/p&gt;
&lt;p&gt;So, to make it quick I added some permission to the codebuild service role. I suggest to create your own permission policies based on the least privilege access policy rather than assigning managed policies with Full access. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/x3xyr8r64is33y00qjqd.png&quot; alt=&quot;Listed AIM Policies&quot;&gt;&lt;/p&gt;
&lt;p&gt;Once the permissions are set, your pipeline will run swiftly. Here's how my pipeline looks like with the two phases.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/nce9vyaltow0y5ewyq2o.png&quot; alt=&quot;CodePipeline success&quot;&gt;&lt;/p&gt;
&lt;p&gt;Here are the outputs from the cloudformation stack.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oxjs2kp5mb19f4yc8v19.png&quot; alt=&quot;Cloudformation outputs&quot;&gt;&lt;/p&gt;
&lt;p&gt;You invoke URL will be generated in Amazon API Gateway. Here in the build logs, you can see an invoke URL for the api. &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/gxl7i306ordfkeq3uzvb.png&quot; alt=&quot;Codbuild logs&quot;&gt;&lt;/p&gt;
&lt;p&gt;The serverless Framework will also help you monitor your resources and their performance through the console. All you need to do is login to the console and connect to your aws account. The console will run another cloudformation stack to integrate with the resources in our aws account. Here is how the dashboard looks like.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vyw2ug7qovo6nabvfmut.png&quot; alt=&quot;Serverless console&quot;&gt;&lt;/p&gt;
&lt;p&gt;Thank you for making it to the end, hope You found what you were looking for!&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/31107/leveraging-aws-codepipeline-pipeline-and-serverless-framework-to-deploy-a-flask-api</guid>
<pubDate>Wed, 14 Oct 2026 18:02:28 +0000</pubDate>
</item>
<item>
<title>What If Your AI Agent Had Hands?</title>
<link>https://coderlegion.com/28145/what-if-your-ai-agent-had-hands</link>
<description>&lt;p&gt;AI agents are getting surprisingly good at writing code. But here's the problem I've been running into:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Writing the code isn't always the hard part.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The hard part starts when the agent needs to actually &lt;em&gt;do something with it&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Update the database.&lt;br&gt;
Run Docker.&lt;br&gt;
Push to GitHub.&lt;br&gt;
Deploy the application.&lt;br&gt;
Check an error.&lt;br&gt;
Update the documentation.&lt;br&gt;
Send a message to Slack. Manage infrastructure.&lt;/p&gt;
&lt;p&gt;Now your agent is jumping between different tools, credentials, interfaces, and contexts.&lt;/p&gt;
&lt;p&gt;That's exactly what I'm trying to solve with &lt;strong&gt;Causly Server&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Causly Server is an open-source, local MCP server that brings development capabilities behind one unified interface.&lt;/p&gt;
&lt;p&gt;Instead of giving your AI agent a pile of disconnected tools, you give it a single MCP server through which it can discover and use the capabilities it needs.&lt;/p&gt;
&lt;p&gt;The idea is pretty simple: &lt;strong&gt;Use whatever MCP-compatible agent you want. Give it Causly.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The current project already covers things like files, Git/GitHub, databases, Supabase, Docker, Terraform, Slack, Notion, deployment, security, workflows, and more.&lt;/p&gt;
&lt;p&gt;It's still early, though.&lt;/p&gt;
&lt;p&gt;Right now you need to fork and configure the project yourself. It runs in your own environment rather than providing an isolated runtime, and there are still plenty of integrations I'd like to add — including things like Linear, Jira, Kubernetes, and more cloud tooling.&lt;/p&gt;
&lt;p&gt;That's also why I'm building it in public.&lt;/p&gt;
&lt;p&gt;I want Causly Server to become a practical open-source environment where AI agents can move beyond &lt;em&gt;writing code&lt;/em&gt; and actually participate in the work around that code.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What if your agent had hands?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I wrote the full story, architecture, capabilities, and limitations here:&lt;/p&gt;
&lt;p&gt;👉 &lt;strong&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.causly.in/lab/causly-server-what-if-your-ai-agent-had-hands&quot;&gt;Causly Server: What If Your AI Agent Had Hands?&lt;/a&gt;&lt;/strong&gt;&lt;br&gt;
🔗 GitHub: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/KNIHAL/causly-server.git&quot;&gt;Causly Server&lt;/a&gt;&lt;br&gt;
⭐ If you find the project interesting, star it, try it out, or contribute.&lt;/p&gt;
&lt;p&gt;Would love to hear what capabilities you think an AI agent absolutely needs to work on a real software project.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/28145/what-if-your-ai-agent-had-hands</guid>
<pubDate>Tue, 22 Sep 2026 11:08:15 +0000</pubDate>
</item>
<item>
<title>Quench 2.0: The Build Tool I Wrote So I Could Stop Fighting Make at 2 A.M.</title>
<link>https://coderlegion.com/23460/quench-2-0-the-build-tool-i-wrote-so-i-could-stop-fighting-make-at-2-a-m</link>
<description>&lt;p&gt;Hi everyone. Before anything else, the disclaimers, because apparently that's just how I open posts now: I'm not a marketer, I'm not trying to funnel you into anything, and I'm not selling you a single byte. Quench is GPLv3. It doesn't ask you for money, it doesn't nag you with a paywall, and it doesn't have a &quot;Pro tier&quot; hiding behind a feature you actually need. There's an optional sponsor link if you feel generous — optional being the operative word, unlike half the &quot;open source&quot; projects that quietly gate half their functionality behind Patreon these days.&lt;/p&gt;
&lt;p&gt;With that out of the way — let's talk about why you should actually care. (If you want to skip straight to the source instead of trusting my prose: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/qecko-labs/Quench&quot;&gt;github.com/qecko-labs/Quench&lt;/a&gt;, author &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/alexvoste&quot;&gt;alexvoste&lt;/a&gt;.)&lt;/p&gt;
&lt;h3 id=&quot;the-origin-story-nobody-asked-for-you-re-getting-it-anyway-&quot;&gt;The origin story nobody asked for (you're getting it anyway)&lt;/h3&gt;
&lt;p&gt;For the last five or six months, this project lived entirely off the public radar. No GitHub stars farming, no &quot;build in public&quot; threads, nothing. Just me and my partner, quietly writing an operating system in assembly.&lt;/p&gt;
&lt;p&gt;If your teeth just clenched reading that sentence — relax, you're not the target audience for the OS part, you're the target audience for the tool we built &lt;em&gt;because of&lt;/em&gt; the OS part. When you're hand-rolling a kernel, Make starts feeling less like a build system and more like a hazing ritual. We needed something faster, more predictable, and — critically — something that told us exactly what it was doing and why, instead of quietly guessing.&lt;/p&gt;
&lt;p&gt;&quot;Just use Ninja,&quot; you're already typing in the comments. Believe me, we tried. In practice, on our actual workloads, it wasn't faster — and I don't say that from vibes, I say that because I benchmarked it obsessively and kept receipts. So we built our own. It got faster than Ninja. It got weirder than Make. And eventually it got a name.&lt;/p&gt;
&lt;h3 id=&quot;wait-didn-t-this-used-to-be-called-something-else-&quot;&gt;Wait, didn't this used to be called something else?&lt;/h3&gt;
&lt;p&gt;Yes. Rebranding time, and I'll be straight about it because half-explained rebrands are how projects lose trust for no reason: &lt;strong&gt;ForgeZero is now Quench&lt;/strong&gt;, and the organization has moved from &lt;code&gt;forgezero-cli&lt;/code&gt; to &lt;strong&gt;qecko-labs&lt;/strong&gt; on GitHub.&lt;/p&gt;
&lt;p&gt;To be crystal clear about what this &lt;em&gt;isn't&lt;/em&gt;: it's not a fork, it's not a handoff, it's not a change in direction. Same team, same codebase, same roadmap, new name on the door. Old URLs redirect for now, but if you've got CI configs or hardcoded remotes pointing at the old org, go fix them before the redirect politely stops working one day and ruins your morning. Package names, import paths, and binaries are untouched in this release — if that ever changes, it'll get its own announcement, not a silent landmine buried in a point release.&lt;/p&gt;
&lt;h3 id=&quot;quench-2-0-core-6-0-0-not-a-coat-of-paint&quot;&gt;Quench 2.0 (core 6.0.0): not a coat of paint&lt;/h3&gt;
&lt;p&gt;This wasn't just a rename with a version bump slapped on for theater. The philosophy changed too: &lt;strong&gt;zero magic, maximum performance.&lt;/strong&gt; Quench doesn't hide the compiler from you — it assumes you know what a linker actually does and aren't afraid to tell it what to do. If you want a black box, there are plenty of build systems happy to be one. This isn't that.&lt;/p&gt;
&lt;p&gt;Three things anchor this release:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;A rewritten scheduler&lt;/strong&gt; — lock-free, zero-alloc, DAG-based, running at 0 allocs/op in the hot path.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;FZP&lt;/strong&gt;, a preprocessor built &lt;em&gt;into&lt;/em&gt; the tool instead of bolted on as an afterthought, handling &lt;code&gt;#define&lt;/code&gt;, &lt;code&gt;#ifdef&lt;/code&gt;, &lt;code&gt;#include&lt;/code&gt;, &lt;code&gt;.h.in&lt;/code&gt; template generation, and the include-cycle bugs that used to make you question your life choices.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;fzpkg&lt;/strong&gt;, a package manager that actually verifies what it installs instead of quietly trusting whatever's sitting in &lt;code&gt;deps/&lt;/code&gt; and hoping for the best. &lt;code&gt;verify&lt;/code&gt;, &lt;code&gt;sign&lt;/code&gt;, &lt;code&gt;keys&lt;/code&gt;, &lt;code&gt;trust&lt;/code&gt; — the whole supply-chain-security starter pack, because &quot;trust the folder&quot; was never a real security model.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;okay-but-does-it-actually-work-or-is-this-another-readme-full-of-promises&quot;&gt;Okay but does it actually work, or is this another README full of promises&lt;/h3&gt;
&lt;p&gt;Fair question. Here's Lua, building for real, not in a sandbox, not cherry-picked:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ qh -dir . -j 16
Built: lua
qh -dir . -j 16  0.08s user 0.19s system 166% cpu 0.162 total
$ lua
Lua 5.5.0  Copyright (C) 1994-2025 Lua.org, PUC-Rio
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That's a full interpreter, built and running, in 162 milliseconds of wall time. Not a hello-world. Not synthetic. An actual language runtime.&lt;/p&gt;
&lt;p&gt;Now the one that actually matters, because toy examples are cheap: &lt;strong&gt;Redis&lt;/strong&gt;. Real codebase, 400,000+ lines, a directory tree that makes &lt;code&gt;find&lt;/code&gt; sweat.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ time qh -dir redis/src -out redis-server -mode c -j 16
[warn::JEMALLOC] Dependency disabled in fz.toml
WARNING: include outside root ignored: /home/alex/Projects/Quench/redis/src/solarisfixes.h
Built: redis-server
qh -dir redis/src -out redis-server -mode c -j 16  6.03s user 2.92s system 292% cpu 3.057 total
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Three seconds of wall-clock time for the whole thing, warnings surfaced cleanly instead of scrolling off into oblivion, and it correctly refused to include a file outside the project root without being asked twice. That's not a benchmark slide. That's a database compiling.&lt;/p&gt;
&lt;p&gt;For the people who want numbers with error bars instead of vibes, here's the actual measured table against &lt;code&gt;make -j4&lt;/code&gt;, hyperfine, warmup of 3, ten-plus runs each:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;modules     qh              make -j4          speedup
-------     --------------  ----------------  -------
20          19.3 ± 1.2 ms   45.4  ± 2.3  ms   2.35x
50          31.1 ± 1.3 ms   85.0  ± 2.1  ms   2.73x
100         57.0 ± 5.3 ms   185.5 ± 7.7  ms   3.25x
150         73.1 ± 4.3 ms   229.3 ± 3.6  ms   3.14x
200         82.2 ± 4.2 ms   291.1 ± 11.2 ms   3.54x
400         223.1 ± 9.8 ms  1105.0 ± 24.1 ms  4.95x
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And a genuinely unfair stress test — 5,000 C files, 16 threads, Quench against Ninja instead of Make this time:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;ninja -j16    ~28.9 s
qh            ~597 ms   (47.3x faster, 98% CPU utilization, ~47 MB resident)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Separately, on a 2,000-module synthetic benchmark specifically comparing schedulers, Quench measured up to &lt;strong&gt;16.75x faster than Ninja&lt;/strong&gt;. Different benchmark, different target, same theme: the scheduler rewrite wasn't decoration.&lt;/p&gt;
&lt;h3 id=&quot;what-actually-shipped-in-6-0-0-the-parts-that-matter-not-the-changelog-wall-&quot;&gt;What actually shipped in 6.0.0 (the parts that matter, not the changelog wall)&lt;/h3&gt;
&lt;p&gt;The full changelog reads like a novel, so here's the version with the boring parts removed:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Scheduler, again&lt;/strong&gt; — the original DAG scheduler that headlined this release has &lt;em&gt;already&lt;/em&gt; been replaced as the default in the builder and linker by something simpler: &lt;code&gt;fo&lt;/code&gt;, a work-stealing thread pool. I'm not going to pretend that's not a little embarrassing to announce in the same email as the DAG scheduler's launch. But the numbers favor the simpler design for typical project sizes, and DAG scheduling still earns its keep on deep, irregular dependency graphs. The DAG scheduler isn't dead — it's just no longer doing the boring job it was hired for.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;A real diagnostic error system&lt;/strong&gt; — file, line, the exact offending parameter, and a suggested fix where one exists. If you've ever stared at a bare Go error from a config loader wondering which of your forty TOML fields broke it, this was built specifically out of spite for that experience.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hardware-aware config&lt;/strong&gt; — &lt;code&gt;compiler.path&lt;/code&gt;, &lt;code&gt;cpu_target&lt;/code&gt;, &lt;code&gt;instruction_sets&lt;/code&gt;, &lt;code&gt;concurrency.workers&lt;/code&gt;, &lt;code&gt;concurrency.pin&lt;/code&gt;. Cross-compiling or pinning builds to specific cores no longer requires writing a &lt;code&gt;configure.qh&lt;/code&gt; script just to feel something.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Security, unglamorously done right&lt;/strong&gt; — path traversal checks in FZP, immediate-range and overflow validation across the assembler and ELF32 symbol emission, mandatory signature verification available for &lt;code&gt;fzpkg&lt;/code&gt; builds. None of this makes a good demo GIF. All of it is the difference between a build tool and a build tool you'd actually trust in a pipeline.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;.qh.toml&lt;/code&gt; is now the primary config format.&lt;/strong&gt; YAML still loads — it just judges you quietly while doing it, via a deprecation warning that isn't going away.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;come-at-it-however-you-want-just-aim-at-the-code&quot;&gt;Come at it however you want, just aim at the code&lt;/h3&gt;
&lt;p&gt;Tear the code apart down to the last byte if you feel like it — it's all there, nothing's hidden behind a &quot;core&quot; repo you don't get access to. File issues; I'll actually read them, and I'm genuinely happy to help. Use it, tell me where it behaves weird, and I'll answer every complaint, every bit of criticism, every question, in full — no canned responses, no &quot;closed as not planned.&quot; Call me whatever you want while you're at it. Just make sure the argument is about the code, not about me.&lt;/p&gt;
&lt;p&gt;And yes, I already know the comment that's coming: &quot;why build another build tool when X already exists, isn't this just reinventing the wheel.&quot; Sure, if you want to call it a wheel. I'd call it a motorcycle at this point, and depending on the day, maybe a rocket. Argue with the benchmarks, argue with the design, argue with a specific line of code you think is wrong — that's a conversation I'll happily have. &quot;Someone already made a wheel once&quot; isn't an argument, it's a thought-terminating cliché, and it's never once made an existing tool faster.&lt;/p&gt;
&lt;h3 id=&quot;try-it-or-don-t-but-here-s-exactly-how-if-you-do&quot;&gt;Try it, or don't — but here's exactly how if you do&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Repo: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/qecko-labs/Quench&quot;&gt;github.com/qecko-labs/Quench&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Docs: &lt;a rel=&quot;nofollow&quot; href=&quot;https://qecko-labs.github.io/quench-docs/&quot;&gt;qecko-labs.github.io/quench-docs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Issues: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/qecko-labs/Quench/issues&quot;&gt;github.com/qecko-labs/Quench/issues&lt;/a&gt; — file them with your &lt;code&gt;.qh.toml&lt;/code&gt; and the actual error output. &quot;It doesn't build&quot; with no log gets you nowhere, and it gets us nowhere trying to help you.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is a pre-release, not a &quot;trust me, ship it to prod&quot; release — the diffstat this cycle touches nearly every subsystem, and config loading, dependency auto-build, and &lt;code&gt;fzpkg&lt;/code&gt; signature verification are the areas most likely to have sharp edges right now. Run it on something you can afford to rebuild from a clean checkout, not your one production kernel build with no backups.&lt;/p&gt;
&lt;h3 id=&quot;so-about-that-headline-promise&quot;&gt;So, about that headline promise&lt;/h3&gt;
&lt;p&gt;You started this post because a title implying speed and control is basically catnip for anyone who's ever waited on a &lt;code&gt;make -j&lt;/code&gt; and watched a single core do all the work while the other fifteen sat there judging you. That's not an accident — it's the same trick I called out at the end of my last post here, the one about digital privacy (go read it, seriously, it's the &quot;digital slavery&quot; one, my words, not the moderators', ha). Since I already burned that bridge by explaining the mechanism once, might as well be consistent and do it again:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The origin story&lt;/strong&gt; made this personal before it made it technical — you trust a tool more once you know it survived someone else's 2 A.M. kernel-debugging session, not just a marketing deck.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The self-deprecating rebrand admission&lt;/strong&gt; (&quot;yes, we already replaced our own headline feature&quot;) builds more credibility than pretending everything shipped perfect the first time — flawless launches are for press releases, not real changelogs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Real terminal output instead of clean marketing screenshots&lt;/strong&gt; — including a warning line I didn't edit out — reads as more trustworthy specifically because it's a little messy.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Two different benchmarks against two different tools&lt;/strong&gt; (Make and Ninja) instead of one cherry-picked number, so a skeptical reader has less room to dismiss it as a single lucky run.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The closing callback to my last post&lt;/strong&gt; is doing exactly what it looks like it's doing: giving you a reason to open a second tab instead of closing this one.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;None of that makes the numbers fake. The Redis build really took three seconds. The 47.3x is a real measured stress test, not a rounding error dressed up as a headline. But since I spent an entire previous post teaching you to notice when a true story is being shaped to hook you — it felt dishonest not to point out that this one was shaped exactly the same way. Go build something with it. Or don't. Either way, you already read the whole thing, and that was kind of the point.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/23460/quench-2-0-the-build-tool-i-wrote-so-i-could-stop-fighting-make-at-2-a-m</guid>
<pubDate>Sat, 25 Jul 2026 20:22:53 +0000</pubDate>
</item>
<item>
<title>Internet Identity Crisis: GA4 Is Blind, Is Your Web Ready for 1.3 Billion New &quot;AI Citizens&quot;?</title>
<link>https://coderlegion.com/21624/internet-identity-crisis-ga4-is-blind-is-your-web-ready-for-1-3-billion-new-ai-citizens</link>
<description>&lt;p&gt;In early June 2026, Matthew Prince – CEO and co-founder of Cloudflare – confirmed a historic milestone on X (Twitter): &lt;strong&gt;For the first time in internet history, automated bot traffic has officially surpassed human traffic.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;According to real-time data from Cloudflare Radar, bots now account for &lt;strong&gt;57.4% - 57.5%&lt;/strong&gt; of all global HTTP requests, pushing human activity down to just over 42%. This monumental crossover arrived &lt;strong&gt;18 months earlier&lt;/strong&gt; than Cloudflare’s original forecasts, driven entirely by the explosive growth of LLM Scrapers and Agentic AI.&lt;/p&gt;
&lt;p&gt;1.3 Billion &quot;AI Citizens&quot; with No Human Presence&lt;/p&gt;
&lt;p&gt;At major tech events like Microsoft Build, Microsoft has consistently highlighted a stark projection: &lt;strong&gt;The world is on track to reach 1.3 billion AI Agents working alongside humans by 2028.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This vision is being aggressively pushed by both Microsoft CEO Satya Nadella and Microsoft AI CEO Mustafa Suleyman, with declarations that fundamentally reshape the web:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;The Shift to the &quot;Open Agentic Web&quot;:&lt;/strong&gt; The internet will no longer be a place where humans click through individual apps. Instead, it will be an ecosystem where AI Agents interact directly with each other and web databases to execute tasks on behalf of users.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Identity for AI Agents:&lt;/strong&gt; Satya Nadella stated that since AI Agents can operate autonomously and consume actual budgets, they must be granted their own digital identities (IDs), access rights, and strict monitoring mechanisms—just like a real employee.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;The Modern Turing Test:&lt;/strong&gt; Mustafa Suleyman proposed a modern economic Turing test for agents: Can an AI agent legally plan and turn $100,000 into $1,000,000 in the real economy? He believes this milestone is closer than we think.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;As web developers, we are transitioning rapidly from a &lt;strong&gt;Human-to-Machine&lt;/strong&gt; web to a &lt;strong&gt;Machine-to-Machine&lt;/strong&gt; infrastructure.&lt;/p&gt;
&lt;p&gt;When Traditional Analytics (GA4) Goes Completely Blind&lt;/p&gt;
&lt;p&gt;The old internet business model—relying on human views and clicks to generate ad revenue—is crumbling. When an AI Agent visits your site to extract data, it fires thousands of background HTTP requests in seconds, grabs the exact data it needs, and leaves without ever looking at a single ad banner.&lt;/p&gt;
&lt;p&gt;More critically, classic analytical tools like &lt;strong&gt;Google Analytics 4 (GA4)&lt;/strong&gt; are completely blind to these entities. GA4 cannot distinguish between a real human user with true transactional intent and the massive waves of &quot;ghost traffic&quot; constantly scraping your site to train foundation models.&lt;/p&gt;
&lt;p&gt;Coming from my own experience operating a web project optimized for bots, I realized a major gap: &lt;strong&gt;Webmasters currently have no visual tool to see how their website actually looks through the &quot;eyes&quot; of an AI Agent.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Hands-on: Measuring Your Site's LLM Compatibility (Agent Readiness Score - ARS v1)&lt;/p&gt;
&lt;p&gt;To solve this exact pain point, I built and officially published a free extension on the Chrome Web Store (which also works on Chromium-based browsers like Edge): &lt;strong&gt;AgentShare Agent Readiness&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The tool allows you to instantly scan any domain to evaluate its AI transparency and bot friendliness based on the &lt;strong&gt;ARS v1&lt;/strong&gt; specification. It breaks down critical criteria such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The existence of next-gen AI discovery configurations like &lt;code&gt;llms.txt&lt;/code&gt; or &lt;code&gt;llm.txt&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Crawler policies in &lt;code&gt;robots.txt&lt;/code&gt; regarding major AI bots (OpenAI, Google, Anthropic, etc.).&lt;/li&gt;
&lt;li&gt;Server overload risks and traffic identification gaps.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Just for fun, I used my own extension to scan our very own &lt;strong&gt;coderlegion.com&lt;/strong&gt;, and the result was &lt;strong&gt;22/100 points (Low readiness)&lt;/strong&gt; as shown below:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=12218395923685394264&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Of course, this is just a playful test since CoderLegion is fundamentally a space built for human-to-human developer connections. But for your SaaS projects, technical documentation sites, or e-commerce platforms—where being indexed properly determines whether an AI Agent will recommend your product to an end-user—a &lt;strong&gt;22 score&lt;/strong&gt; should be an immediate wake-up call.&lt;/p&gt;
&lt;p&gt;Let's Discuss&lt;/p&gt;
&lt;p&gt;The internet rules are changing daily. Cloudflare is dropping free bot-blocking tools, Microsoft is building the Agentic Web, but what are &lt;em&gt;you&lt;/em&gt; doing to prepare your tech stack? Are you opening your doors to LLM scrapers or shutting them down?&lt;/p&gt;
&lt;p&gt;I'd love for you to try out the extension, check your own website's &quot;Agent-readiness,&quot; and drop your harshest technical feedback or feature requests right in the comments below!&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Try the Extension on Chrome Web Store:&lt;/strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://chromewebstore.google.com/detail/agentshare-agent-readines/nimndnhajfkicbnipbfdkmgencjejjed?authuser=0&amp;amp;hl=en&quot;&gt;AgentShare Agent Readiness&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21624/internet-identity-crisis-ga4-is-blind-is-your-web-ready-for-1-3-billion-new-ai-citizens</guid>
<pubDate>Tue, 30 Jun 2026 15:11:35 +0000</pubDate>
</item>
<item>
<title>Why I chose a Tiered Caching strategy for PixoraCloud.</title>
<link>https://coderlegion.com/21337/why-i-chose-a-tiered-caching-strategy-for-pixoracloud</link>
<description>&lt;p&gt;I’m deep in the lab engineering the Pixora transformation engine (using libvips + Go), and I had to make a call on caching: Redis vs. Local Disk.&lt;br&gt;
Common mistake: Using Redis for everything.&lt;br&gt;
Reality: RAM is fast, but RAM is expensive. If I cache every transformed image in Redis, the server bill will bankrupt the project before we even hit Beta.&lt;/p&gt;
&lt;p&gt;My Solution: The Two-Tiered Architecture.&lt;br&gt;
L1 (Redis): Stores only the &quot;Hot&quot; assets (the most requested thumbnails/avatars). This keeps our sub-120ms latency promise for 90% of requests.&lt;br&gt;
L2 (Disk/Object Storage): Stores the processed, high-res versions. If it's not in Redis, we grab it here.&lt;br&gt;
The Trade-off:&lt;br&gt;
Redis gives us the raw speed to hit sub-50ms lookups.&lt;br&gt;
Disk storage keeps our operating costs lean so we can pass those savings to you.&lt;br&gt;
We aren't just building a CDN; we’re building infrastructure that has to survive in a low-bandwidth, high-latency market.&lt;br&gt;
Building in public is all about these trade-offs. What would you have chosen? Let’s talk architecture in the comments. 👇&lt;/p&gt;
&lt;p&gt;Join waitlist &lt;a rel=&quot;nofollow&quot; href=&quot;https://pixoracloud.pxxl.click&quot;&gt;https://pixoracloud.pxxl.click&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/21337/why-i-chose-a-tiered-caching-strategy-for-pixoracloud</guid>
<pubDate>Wed, 24 Jun 2026 20:02:29 +0000</pubDate>
</item>
<item>
<title>Your MCP Agent is Logging &quot;Sucess: true&quot; While the task never ran</title>
<link>https://coderlegion.com/20993/your-mcp-agent-is-logging-sucess-true-while-the-task-never-ran</link>
<description>&lt;p&gt;You build an agent. It calls an MCP tool, gets a response, logs success: true, and moves on. Thirty-three minutes later a customer emails asking why their ticket was never created.&lt;/p&gt;
&lt;p&gt;You pull the logs. Every entry says the call succeeded. You check the MCP server. It received the request. HTTP 200 came back. So where did the task go?&lt;/p&gt;
&lt;p&gt;It went nowhere. The task never ran. The MCP server returned a null result inside a 200 response, and your agent treated the status code as truth and discarded the body.&lt;/p&gt;
&lt;p&gt;This is not a fringe case. It is the default failure mode of MCP.&lt;/p&gt;
&lt;h3 id=&quot;why-this-happens-at-the-protocol-level&quot;&gt;Why this happens at the protocol level&lt;/h3&gt;
&lt;p&gt;MCP is built on JSON-RPC 2.0 over HTTP. The error surface is split across two layers. HTTP carries the transport status. JSON-RPC carries the application status. They do not have to agree, and often they do not.&lt;/p&gt;
&lt;p&gt;A well-behaved MCP error looks like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{&quot;jsonrpc&quot;: &quot;2.0&quot;, &quot;id&quot;: 1, &quot;error&quot;: {&quot;code&quot;: -32000, &quot;message&quot;: &quot;tool execution failed&quot;}}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Also HTTP 200. No error field. The server finished handling the request and returned nothing. Most agent frameworks check res.ok or the HTTP status code and move on. The null goes unexamined.&lt;/p&gt;
&lt;h3 id=&quot;three-failure-patterns-worth-knowing&quot;&gt;Three failure patterns worth knowing&lt;/h3&gt;
&lt;h4 id=&quot;1-null-result-propagation&quot;&gt;1. Null result propagation&lt;/h4&gt;
&lt;p&gt;A tools/call returns {&quot;result&quot;: null} with HTTP 200. The agent has no indication anything went wrong. It logs the call as complete. The downstream system never receives the expected payload. This is the most common pattern and the hardest to catch because every layer reports success.&lt;/p&gt;
&lt;h4 id=&quot;2-retry-masking&quot;&gt;2. Retry masking&lt;/h4&gt;
&lt;p&gt;Your agent is configured with retries. The upstream MCP server is behind a deduplication layer. The agent fires a tools/call, times out, retries three times. Each retry is deduplicated by the upstream — it executes the mutation once and acknowledges the subsequent requests silently. The agent sees success on attempt four. Your audit log shows six calls. The task ran once but the agent has no idea which attempt was real.&lt;/p&gt;
&lt;h4 id=&quot;3-content-schema-drift-in-multi-agent-workflows&quot;&gt;3. Content schema drift in multi-agent workflows&lt;/h4&gt;
&lt;p&gt;MCP's tools/call result schema requires a content array where each item has a type field. Servers that were written quickly omit type. The consuming agent deserializes the array, tries to route by type, finds undefined, and either silently drops the item or throws an uncaught exception that gets swallowed by an outer try-catch. The agent logs the call as successful. The data was there. The schema was wrong.&lt;/p&gt;
&lt;h3 id=&quot;what-vouqis-does&quot;&gt;What Vouqis does&lt;/h3&gt;
&lt;p&gt;Vouqis is a proxy that sits between your agent and your MCP server. Every request and response passes through it. It validates both sides and writes a structured audit log.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npm install -g @vouqis/cli
vouqis proxy --upstream [https://your-mcp-server.com](https://your-mcp-server.com)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your agent points at &lt;a rel=&quot;nofollow&quot; href=&quot;http://127.0.0.1:4444&quot;&gt;http://127.0.0.1:4444&lt;/a&gt; instead of the MCP server directly. Every event — allow, block,retry, rewrite — is written to vouqis-audit.log as NDJSON with timestamp, method, tool name, latency, attempt number, and reason.&lt;/p&gt;
&lt;p&gt;The audit event shape:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
  &quot;timestamp&quot;: &quot;2026-06-15T10:04:22.341Z&quot;,
  &quot;method&quot;: &quot;tools/call&quot;,

### 
  &quot;tool&quot;: &quot;create_ticket&quot;,
  &quot;decision&quot;: &quot;block&quot;,
  &quot;latency_ms&quot;: 187,
  &quot;reason&quot;: &quot;tools/call result is null or missing&quot;,
  &quot;attempt&quot;: 1
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That is the event you would have wanted at 10:04 AM instead of finding out from a customer complaint at 10:37 AM.&lt;/p&gt;
&lt;h3 id=&quot;if-you-have-hit-this&quot;&gt;If you have hit this&lt;/h3&gt;
&lt;p&gt;If you are running LangGraph, a custom MCP integration, or a multi-agent workflow in production and you have debugged a silent MCP failure — drop a comment with the pattern you hit.&lt;/p&gt;
&lt;p&gt;The project is at &lt;a rel=&quot;nofollow&quot; href=&quot;https://vouqis.tech&quot;&gt;https://vouqis.tech&lt;/a&gt;. The source is at &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Sasisundar2211/Vouqis&quot;&gt;https://github.com/Sasisundar2211/Vouqis&lt;/a&gt;.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/20993/your-mcp-agent-is-logging-sucess-true-while-the-task-never-ran</guid>
<pubDate>Fri, 19 Jun 2026 19:17:46 +0000</pubDate>
</item>
<item>
<title>How I Cut My Anthropic API Bill by 50% With a Local Python Tool</title>
<link>https://coderlegion.com/20201/how-i-cut-my-anthropic-api-bill-by-50-with-a-local-python-tool</link>
<description>&lt;p&gt;My Anthropic bill doubled two months in a row. Not because I was building something bigger — because I kept asking the same questions, sending bloated prompts, and defaulting to Sonnet for tasks that Haiku could handle. I built a tool to fix it. Here's how it works.&lt;/p&gt;
&lt;h3 id=&quot;the-problem&quot;&gt;The Problem&lt;/h3&gt;
&lt;p&gt;AI API costs compound fast for three reasons. First, if you're iterating on a project, you ask similar questions repeatedly — &quot;how does X work,&quot; &quot;what's wrong with this code&quot; — and pay full price every time. Second, prompts accumulate context: documentation snippets, error traces, boilerplate instructions that add hundreds of tokens but contribute nothing to the answer. Third, most people just use whatever model they defaulted to first. Claude Opus at $15/1M input tokens for a query that Haiku could answer for $1/1M is a 15x cost multiplier on every single call.&lt;/p&gt;
&lt;h3 id=&quot;the-solution&quot;&gt;The Solution&lt;/h3&gt;
&lt;p&gt;I built &lt;code&gt;ai-cost-optimizer&lt;/code&gt; — a local CLI that sits between your terminal and the Anthropic API. It runs a semantic cache, a prompt compressor, and a model router on every request before anything hits the network. No cloud, no subscription, no data leaving your machine. Just a Python package you install once.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;how-it-works&quot;&gt;How It Works&lt;/h3&gt;
&lt;h4 id=&quot;1-semantic-cache&quot;&gt;1. Semantic Cache&lt;/h4&gt;
&lt;p&gt;The cache stores every response as a vector embedding. On each new request, it computes the embedding for your prompt and checks cosine similarity against everything stored. If similarity is above the threshold (default: 0.80), it returns the cached answer — no API call, zero cost.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ aiproxy ask &quot;What is the capital of France?&quot;

  Model         claude-haiku-4-5-20251001
  Cached        No
  Input tokens  18
  Output tokens 9
  Cost          $0.000063
  Cache saved   $0.000000 (cached for next time)
  Total saved   $0.000000

$ aiproxy ask &quot;Capital of France?&quot;

  Model         claude-haiku-4-5-20251001
  Cached        Yes
  Input tokens  0
  Output tokens 0
  Cost          $0.000000
  Cache saved   $0.000063
  Total saved   $0.000063
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&quot;Capital of France?&quot; is semantically identical to the first query. Cache hit. The API never sees it.&lt;/p&gt;
&lt;p&gt;The cache uses &lt;code&gt;sentence-transformers/all-MiniLM-L6-v2&lt;/code&gt; for embeddings (80 MB, runs entirely in-process) and &lt;code&gt;usearch&lt;/code&gt; for fast ANN lookup. Cold load is ~1.5 seconds on first run; subsequent queries are sub-100ms.&lt;/p&gt;
&lt;h4 id=&quot;2-prompt-compressor&quot;&gt;2. Prompt Compressor&lt;/h4&gt;
&lt;p&gt;Long prompts are expensive not because they're long, but because most of that length is filler. The compressor uses BM25 to score each sentence by relevance to the query, keeps the top-scoring sentences, and discards the rest.&lt;/p&gt;
&lt;p&gt;In plain terms: it reads your prompt, figures out which sentences actually relate to what you're asking, and throws out the ones that don't. No summarization, no LLM — pure lexical scoring, deterministic, fast.&lt;/p&gt;
&lt;p&gt;Real example from a documentation query:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Original prompt:  370 tokens  ($0.001110 at Sonnet pricing)
Compressed:        61 tokens  ($0.000183 at Sonnet pricing)
Tokens saved:     309 tokens  (83% reduction)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The threshold for compression is configurable (&lt;code&gt;MAX_PROMPT_TOKENS=500&lt;/code&gt; in &lt;code&gt;.env&lt;/code&gt;). Prompts under that limit are sent as-is.&lt;/p&gt;
&lt;h4 id=&quot;3-model-router&quot;&gt;3. Model Router&lt;/h4&gt;
&lt;p&gt;The router classifies each prompt and picks the cheapest model that can handle it. The logic is rule-based: token count, keyword signals for complexity, and a few heuristics for code vs. prose vs. reasoning tasks.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Query &lt;/th&gt;&lt;th&gt;Routed to &lt;/th&gt;&lt;th&gt;Input cost per 1M tokens&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&quot;What is 2+2?&quot; &lt;/td&gt;&lt;td&gt;Haiku &lt;/td&gt;&lt;td&gt;$1.00&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&quot;Explain binary search trees&quot; &lt;/td&gt;&lt;td&gt;Sonnet &lt;/td&gt;&lt;td&gt;$3.00&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&quot;Review this system architecture&quot; &lt;/td&gt;&lt;td&gt;Opus &lt;/td&gt;&lt;td&gt;$15.00&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;You can override the router by passing &lt;code&gt;--model&lt;/code&gt; explicitly. But if you don't, it defaults to the cheapest model that fits the task, and in practice that means Haiku handles the majority of short factual queries.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;real-numbers&quot;&gt;Real Numbers&lt;/h3&gt;
&lt;p&gt;After two weeks of normal development use — asking questions about code, debugging errors, generating short snippets:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;$ aiproxy stats

  Cache entries       14
  Cache hits           3
  Estimated savings   $0.000300
  Total API calls     23
  Total cost          $0.160000
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;23 API calls, $0.16 total&lt;/li&gt;
&lt;li&gt;566 tokens saved by compression across those calls&lt;/li&gt;
&lt;li&gt;12% cache hit rate (low because I was exploring new topics; repetitive workloads hit 30-40%)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The compression savings don't show in &lt;code&gt;stats&lt;/code&gt; yet — that's a known gap I'm fixing next.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;installation&quot;&gt;Installation&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone https://github.com/desaikat/ai-cost-optimizer.git
cd ai-cost-optimizer
python -m venv .venv
source .venv/Scripts/activate  # Windows: .venv\Scripts\activate
pip install -e .

cp .env.example .env
# Add your ANTHROPIC_API_KEY to .env

aiproxy ask &quot;What is the difference between a list and a tuple in Python?&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There's also a Streamlit dashboard (&lt;code&gt;aiproxy-dashboard&lt;/code&gt;) that shows cumulative spend, cache hit rate, model distribution, and compression savings over time.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-s-next&quot;&gt;What's Next&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;OpenAI and Gemini support&lt;/strong&gt; — the cache and compressor are provider-agnostic; the client layer just needs adapters&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Team mode&lt;/strong&gt; — shared SQLite or Postgres cache so a team stops paying for the same queries independently&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;REST API mode&lt;/strong&gt; — drop-in proxy endpoint so any language can use it, not just Python&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PyInstaller &lt;code&gt;.exe&lt;/code&gt;&lt;/strong&gt; — zero-install distribution for Windows users who don't want to manage a venv&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;try-it-feedback-welcome&quot;&gt;Try It / Feedback Welcome&lt;/h3&gt;
&lt;p&gt;Repo: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/desaikat/ai-cost-optimizer&quot;&gt;github.com/desaikat/ai-cost-optimizer&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Two things I'm actively unsure about and would value input on:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Similarity threshold tuning&lt;/strong&gt; — 0.80 works for me but may be too aggressive for code queries where small wording differences matter. What threshold makes sense for your use case?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Compression quality&lt;/strong&gt; — BM25 is fast and deterministic but misses semantic relevance. Has anyone used a lightweight embedding-based sentence scorer that stays under 100ms per prompt?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Open issues and PRs welcome.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/20201/how-i-cut-my-anthropic-api-bill-by-50-with-a-local-python-tool</guid>
<pubDate>Wed, 10 Jun 2026 19:55:05 +0000</pubDate>
</item>
<item>
<title>DevLaunch - I built a Vercel-inspired dev server manager</title>
<link>https://coderlegion.com/14252/devlaunch-i-built-a-vercel-inspired-dev-server-manager</link>
<description>&lt;p&gt;Every developer who works on multiple projects locally knows the pain.&lt;br&gt;
You've got an Ionic app on port 8101, a Laravel API on 8000, and an Angular portal on 4200. That's three terminal tabs, three commands to remember, three processes to track, and the moment you close a terminal by accident, you're back to square one. I built DevLaunch to fix exactly that.&lt;/p&gt;
&lt;h3 id=&quot;what-is-devlaunch-&quot;&gt;What is DevLaunch?&lt;/h3&gt;
&lt;p&gt;DevLaunch is a single-file PHP dev server manager with a Vercel-inspired dark UI. You add your local projects, assign them a command and port, and then start, stop, and monitor them all from one browser tab.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zttnn3jg6krymt82nwaf.png&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;No npm install. No composer. No build step. Drop one index.php into any folder served by PHP and open it in your browser.&lt;/p&gt;
&lt;h3 id=&quot;features&quot;&gt;Features&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Single file: the entire app (PHP backend + HTML/CSS/JS frontend) lives in one index.php&lt;/li&gt;
&lt;li&gt;Add any project: browse your filesystem server-side (yes, including Windows drives like D:) to select a project folder; the name is auto-detected&lt;/li&gt;
&lt;li&gt;Any command: ionic s, npm run dev, ng serve, vite, php artisan serve — whatever you run in the terminal&lt;/li&gt;
&lt;li&gt;Custom ports: assign a port per project; the --port flag is auto-appended if not already in your command&lt;/li&gt;
&lt;li&gt;Start/Stop: launches as a real detached background process, kills the full process tree on stop (no zombie node processes)&lt;/li&gt;
&lt;li&gt;Live log viewer: tail stdout/stderr from any running project in a slide-up terminal panel&lt;/li&gt;
&lt;li&gt;Running detection: auto-detects whether a process is still alive after page refresh or system events&lt;/li&gt;
&lt;li&gt;Windows + Linux + macOS: works everywhere PHP runs&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;quick-start&quot;&gt;Quick Start&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;git clone https://github.com/ManthanBhatt/dev-launch.git
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Drop the folder inside your XAMPP/Laragon htdocs (or anywhere served by PHP), then open:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot;&gt;http://localhost/dev-launch/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or use PHP's built-in server:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;cd dev-launch
php -S localhost:8080
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That's it.&lt;/p&gt;
&lt;h3 id=&quot;how-it-works-1&quot;&gt;How it works&lt;/h3&gt;
&lt;p&gt;The whole thing is a single PHP file that serves two roles depending on the request:&lt;br&gt;
As an API - when a request comes in with the X-DevLaunch-API header, PHP handles actions like start_project, stop_project, browse_dirs, and get_log. Project data is stored in a plain devlaunch_data.json file, and running PIDs are tracked in devlaunch_pids.json.&lt;br&gt;
As the UI - for every other request, PHP outputs the full HTML page with embedded CSS and JavaScript.&lt;br&gt;
Starting a project uses proc_open() to launch the command as a real detached background process in the correct working directory. The process writes its output to a temp log file that the log viewer polls every 2 seconds.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$process = proc_open($p['cmd'], $descriptors, $pipes, $p['path']);
$status  = proc_get_status($process);
$pid     = (int)$status['pid'];
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;On Windows, it wraps the command in cmd /C so tools like ionic, npm, and ng resolve correctly from PATH. Stopping a project calls taskkill /F /T to kill the entire process tree - no orphan Node processes lingering in Task Manager.&lt;/p&gt;
&lt;h3 id=&quot;why-php-&quot;&gt;Why PHP?&lt;/h3&gt;
&lt;p&gt;Honestly, the goal was zero setup. PHP is already running on most local dev environments - XAMPP, Laragon, MAMP, or the built-in server. No runtime to install, no package manager, no compilation. You just put a file somewhere and it runs.&lt;br&gt;
Single-file PHP also means the whole thing is trivially auditable - there are no hidden dependencies, no transitive packages, nothing that phones home. It's ~1,200 lines of code you can read in one sitting.&lt;/p&gt;
&lt;h3 id=&quot;what-s-next-1&quot;&gt;What's next&lt;/h3&gt;
&lt;p&gt;Some ideas I'm thinking about for future versions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Environment variable editor per project&lt;/li&gt;
&lt;li&gt;Auto-restart on crash with configurable retry&lt;/li&gt;
&lt;li&gt;Multiple commands per project (e.g. spin up a frontend + backend simultaneously with one click)&lt;/li&gt;
&lt;li&gt;Export/import project list for sharing across machines&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;try-it-contribute&quot;&gt;Try it / Contribute&lt;/h3&gt;
&lt;p&gt;The project is MIT licensed and open source on GitHub:&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ManthanBhatt/dev-launch&quot;&gt;github.com/ManthanBhatt/dev-launch&lt;/a&gt;&lt;br&gt;
If you work on multiple local projects and find this useful, a ⭐ on GitHub goes a long way. PRs, issues, and feature ideas are all welcome.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Built out of frustration with terminal tab juggling. Hope it helps someone else too.Share&lt;/em&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/14252/devlaunch-i-built-a-vercel-inspired-dev-server-manager</guid>
<pubDate>Wed, 08 Apr 2026 18:47:58 +0000</pubDate>
</item>
</channel>
</rss>