<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
<channel>
<title>Coder Legion - Recent posts tagged cli</title>
<link>https://coderlegion.com/tag/cli</link>
<description>Powered by Question2Answer</description>
<item>
<title>Terminal Agent vs. Web Chat: Pick by Blast Radius</title>
<link>https://coderlegion.com/32059/terminal-agent-vs-web-chat-pick-by-blast-radius</link>
<description>&lt;p&gt;Every major AI lab now ships a command-line agent that runs on your machine with access to your files and shell. The deciding factor is which tasks you deliberately keep out of it. The deciding factor is simpler than most teams make it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The Idea: Scope the Damage, Not the Capability&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The better question when evaluating a terminal agent is blast radius: if this thing does exactly the wrong thing, what does it touch and how fast can you undo it? A web chat window has a blast radius of zero - the worst outcome is bad text you paste somewhere. A CLI agent with write access to a git repo has a blast radius of &quot;whatever's uncommitted.&quot; The same agent with your production credentials in its environment has a blast radius of your business.&lt;/p&gt;
&lt;p&gt;Blast radius is a property of the &lt;em&gt;task&lt;/em&gt;, not the model. You can decide it in a planning meeting before anyone writes code. Refactoring tests in a throwaway branch? Low radius, high tolerance for a wrong turn - let the agent run. Editing an infrastructure config that deploys on merge? Same model, same prompt quality, completely different decision.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Real Example: Three Tiers, One Flag&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A practical setup most CLI agents support in some form - approval modes plus a sandbox:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Tier 1 - scratch work: let it run, git is the undo button
agent --mode auto-edit --cwd ~/experiments/parser-rewrite

# Tier 2 - real repo: propose diffs, human approves each write
agent --mode suggest --cwd ~/work/billing-service

# Tier 3 - anything with live credentials: read-only, no shell
agent --mode read-only --no-exec
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The rule that makes this work isn't the flag - it's what decides the tier. Three questions, in order:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Is it reversible in under five minutes?&lt;/strong&gt; Committed git history, yes. A sent email or a dropped table, no.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Does the environment hold live secrets?&lt;/strong&gt; If the agent inherits your shell, it inherits your API keys. Check what's actually exported.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Would a wrong answer be obvious?&lt;/strong&gt; Broken tests fail loudly. A subtly wrong SQL filter in a revenue report does not.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Two &quot;no&quot; answers and the task doesn't belong in an autonomous loop yet - regardless of how good the model is.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Key Takeaways&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Judge AI agent tasks by blast radius (what breaks, how fast you recover) rather than by model capability, which changes too often to plan around.&lt;/li&gt;
&lt;li&gt;Reversibility, credential exposure, and error visibility are three checks any PM or engineer can apply before a single line of config is written.&lt;/li&gt;
&lt;li&gt;Approval modes and sandboxing aren't friction to work around - they're how you move fast on the low-radius 80% of work without betting the other 20%.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Which tasks have you already moved into an auto-approve loop - and what was the one that made you move it back out?&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Sources referenced: Hacker News discussion on OpenAI CLI&lt;/em&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/32059/terminal-agent-vs-web-chat-pick-by-blast-radius</guid>
<pubDate>Thu, 22 Oct 2026 11:19:20 +0000</pubDate>
</item>
<item>
<title>I Built a C++ CLI That Hunts Down Secrets Hiding in Your Git History</title>
<link>https://coderlegion.com/31117/i-built-a-c-cli-that-hunts-down-secrets-hiding-in-your-git-history</link>
<description>&lt;p&gt;We've all done it. You commit a &lt;code&gt;.env&lt;/code&gt; file by accident, catch it a few commits later, delete it, and breathe a sigh of relief. Except... it's not gone. It's still sitting in your Git history, one &lt;code&gt;git log -p&lt;/code&gt; away from anyone who clones the repo.&lt;/p&gt;
&lt;p&gt;That's the problem &lt;strong&gt;GitHub Secrets Watcher&lt;/strong&gt; is built to catch.&lt;/p&gt;
&lt;h3 id=&quot;what-it-does&quot;&gt;What it does&lt;/h3&gt;
&lt;p&gt;GitHub Secrets Watcher is a command-line tool written in modern C++20 that scans your GitHub repositories - public or private (with a token) - and walks back through commit history looking for accidentally committed environment and config files: &lt;code&gt;.env&lt;/code&gt;, &lt;code&gt;config.js&lt;/code&gt;, and similar patterns that often carry API keys, database credentials, or other secrets.&lt;/p&gt;
&lt;p&gt;For every hit, it gives you a direct link to the exact commit where the file appears, so you're not stuck digging through history manually to remediate it.&lt;/p&gt;
&lt;p&gt;Importantly, it's strictly &lt;strong&gt;read-only&lt;/strong&gt;. It never modifies, deletes, or rewrites anything in your repositories - it just reports what it finds so you can decide what to do next (rotate the secret, scrub the history, etc.).&lt;/p&gt;
&lt;h3 id=&quot;key-features&quot;&gt;Key features&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Scans all repos for a given GitHub username, public by default, private too if you pass a token&lt;/li&gt;
&lt;li&gt;Walks a configurable depth of commit history across branches&lt;/li&gt;
&lt;li&gt;Skips noisy directories like &lt;code&gt;node_modules&lt;/code&gt;, &lt;code&gt;.git&lt;/code&gt;, and &lt;code&gt;dist&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Validates commit hashes before generating links, so you never get a broken URL&lt;/li&gt;
&lt;li&gt;Multi-threaded scanning - set the thread count to match your hardware&lt;/li&gt;
&lt;li&gt;Three output formats: human-readable text (with color-coded terminal output), JSON, or CSV&lt;/li&gt;
&lt;li&gt;Stream-based processing to keep memory usage low even on large histories&lt;/li&gt;
&lt;li&gt;Modern, safe filesystem operations: Uses C++20 std::filesystem for all path handling, eliminating platform-specific path issues and improving security&lt;/li&gt;
&lt;li&gt;Direct Git integration: Leverages libgit2 for efficient, safe repository operations without spawning subprocesses&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;example-output&quot;&gt;Example output&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;[1/7] Scanning: ccas-website
[INFO] Cloning repository (depth=100)...
[INFO] Scanning history...
[WARN] Found 5 potential environment/configuration files:
     - client/assets/js/config.js
       [LINK] https://github.com/.../blob/c7e0fba.../client/assets/js/config.js
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each finding links straight to the offending commit, so remediation is one click away instead of a history-diving expedition.&lt;/p&gt;
&lt;h3 id=&quot;getting-started&quot;&gt;Getting started&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone https://github.com/gerald-mathew/github-secrets-watcher
cd github-secrets-watcher
mkdir build &amp;amp;&amp;amp; cd build
cmake ..
make
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then run a scan:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./github_secrets_watcher scan --username YOUR_USERNAME
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add a token for private repos and higher API rate limits:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./github_secrets_watcher scan --username YOUR_USERNAME \
  --token YOUR_PERSONAL_ACCESS_TOKEN --include-private
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can tune the scan with &lt;code&gt;--depth&lt;/code&gt;, &lt;code&gt;--max-repos&lt;/code&gt;, &lt;code&gt;--threads&lt;/code&gt;, &lt;code&gt;--format&lt;/code&gt;, &lt;code&gt;--verbose&lt;/code&gt;, &lt;code&gt;repo(s) &amp;lt;repo name(s)&amp;gt;&lt;/code&gt; and &lt;code&gt;--output&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;why-c-20&quot;&gt;Why C++20&lt;/h3&gt;
&lt;p&gt;This isn't a wrapper around &lt;code&gt;git log&lt;/code&gt; piped through &lt;code&gt;grep&lt;/code&gt; — it uses libcurl for GitHub API calls, libgit2 for direct Git repository access, nlohmann/json for parsing, and C++17 std::filesystem for safe, portable path operations, with modern C++20 features throughout. It builds cleanly with CMake or a provided build script on Linux, macOS, and Windows (via MSYS2).&lt;/p&gt;
&lt;h3 id=&quot;try-it-out&quot;&gt;Try it out&lt;/h3&gt;
&lt;p&gt;It's MIT-licensed and open source. If you've got repos going back a few years, there's a decent chance something's buried in there that shouldn't be — I'd genuinely be curious what people find.&lt;/p&gt;
&lt;p&gt;🔗 &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/gerald-mathew/github-secrets-watcher&quot;&gt;github.com/gerald-mathew/github-secrets-watcher&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Feedback, issues, and PRs welcome.&lt;/p&gt;
&lt;h3 id=&quot;update---sep-3-&quot;&gt;Update - Sep 3:&lt;/h3&gt;
&lt;p&gt;Based on feedback from the community, I’ve replaced the filesystem handling with std::filesystem and am now using libgit2 for Git operations instead of popen. Thanks to @hailiang194  for the suggestions!&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/31117/i-built-a-c-cli-that-hunts-down-secrets-hiding-in-your-git-history</guid>
<pubDate>Wed, 14 Oct 2026 22:57:01 +0000</pubDate>
</item>
<item>
<title>Jev &amp; computer-use</title>
<link>https://coderlegion.com/29083/jev-computer-use</link>
<description>&lt;p&gt;Current work: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/sarang-pratham/jev-computer-use&quot;&gt;jev-computer-use&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My TL for the last few days has been taken over by &lt;a rel=&quot;nofollow&quot; href=&quot;https://typesafe.ai/blog/introducing-system-one-models-and-jev&quot;&gt;Jev&lt;/a&gt;, a system one model from &lt;a rel=&quot;nofollow&quot; href=&quot;https://typesafe.ai&quot;&gt;typesafe.ai&lt;/a&gt;. So i applied for the waitlist and got in.&lt;/p&gt;
&lt;p&gt;To me a interesting use-case for this kind of model is on browser/computer-use, lot of decision to be taken which may not need long reasoning before doing so, the UX improves with the speed we get and automations feel right.&lt;br&gt;
Checkout the &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/browser-use/jev-ultrafast&quot;&gt;jev-ultrafast&lt;/a&gt; by browser-use.&lt;/p&gt;
&lt;p&gt;Take a general purpose model (GPT / Claude), the lifecycle of a understand user request looks like: &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;plan &lt;/li&gt;
&lt;li&gt;generate code / text &lt;/li&gt;
&lt;li&gt;produce tool calls&lt;/li&gt;
&lt;li&gt;something broke / unexpected ? - give the agent new state ask it to redo stuff.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.us-east-2.amazonaws.com/uploads/articles/bp6p7qhz54xpqqxm6tlh.png&quot; alt=&quot;General Agent loop&quot;&gt;&lt;/p&gt;
&lt;p&gt;This is useful when the task isn't fully known in advance, involves long reasoning and time. But think of structured inputs like forms or OS accessibility, the decisions of what needs be done given a goal is more local than you think.&lt;/p&gt;
&lt;h3 id=&quot;what-is-jev-&quot;&gt;What is Jev?&lt;/h3&gt;
&lt;p&gt;This could be very simply put as a classifier. The model accepts a state and questions returns a typed decision. A state is your structured text input and questions have three primitives:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Choice: picks one of the options you provide + confidence&lt;/li&gt;
&lt;li&gt;Score: rate something you provide + confidence&lt;/li&gt;
&lt;li&gt;Noul: yes / no with a probability&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.us-east-2.amazonaws.com/uploads/articles/2n4bs5qo2cy2s3almtll.png&quot; alt=&quot;Jev Flow&quot;&gt;&lt;/p&gt;
&lt;p&gt;General purpose LLMs are also capable of it but the main difference here is - jev exposes a decision interface rather text generation interface, give the context and decision to make, received a typed result. &lt;/p&gt;
&lt;p&gt;Think of making your agent logic as state machines, give that state, goal and the choices it can trigger, this works really well.&lt;/p&gt;
&lt;h3 id=&quot;on-computer-use&quot;&gt;On computer-use&lt;/h3&gt;
&lt;p&gt;There are multiple ways to do this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Screenshot, use a model for segmenting and OCR then convert to structured format pass it to JEV for decision&lt;/li&gt;
&lt;li&gt;OR the OS itself provides accessibility APIs to navigate, its already structured use it directly&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I'm currently experimenting on this: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/sarang-pratham/jev-computer-use&quot;&gt;jev-computer-use&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;A example computer-use flow: &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.us-east-2.amazonaws.com/uploads/articles/tvpplrowjbwua7lziu35.png&quot; alt=&quot;computer-use&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;claims-and-things-to-look-out-for&quot;&gt;Claims and things to look out for&lt;/h3&gt;
&lt;p&gt;Although the model is refreshing in the age of LLMs, i think the magic lies in the data, they do claim they are a data research company first and it's been trained on 100% synthetic data.&lt;/p&gt;
&lt;p&gt;There is one more strong claim on almost no hallucination, being type safe does not guarantee that.&lt;br&gt;
If you think this run deterministically, NO, same prompt gives you different probabilities every run.&lt;/p&gt;
&lt;p&gt;Confidence score is a derived metric which is tightly coupled with the classification scores. So it may not be the right measure for whatever you are doing and you are are open to come up with any definition for the confidence using the probabilities list.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/29083/jev-computer-use</guid>
<pubDate>Tue, 29 Sep 2026 14:14:02 +0000</pubDate>
</item>
<item>
<title>FireMigrate: leave Firebase for Postgres without dumping everything into JSON</title>
<link>https://coderlegion.com/28096/firemigrate-leave-firebase-for-postgres-without-dumping-everything-into-json</link>
<description>&lt;p&gt;&lt;strong&gt;It’s a small MIT CLI. The interesting work is still open.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Most Firebase → Postgres guides do the same thing: export the project, stuff documents into a jsonb column, call it migrated. You kept the data and lost the shape.&lt;br&gt;
FireMigrate does the opposite. It reads Firestore and Firebase Auth first, prints a relational schema you can argue with, and refuses to write until you say so.&lt;/p&gt;
&lt;p&gt;npx @ezekielreu6/firemigrate init&lt;br&gt;
npx @ezekielreu6/firemigrate inspect&lt;br&gt;
npx @ezekielreu6/firemigrate schema&lt;br&gt;
npx @ezekielreu6/firemigrate migrate --dry-run&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://firemigrate.voryn.xyz&quot;&gt;Website&lt;/a&gt;&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.npmjs.com/package/@ezekielreu6/firemigrate&quot;&gt;npm&lt;/a&gt;&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ezekielreu6-bit/firemigrate&quot;&gt;Repo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Why this exists&lt;/strong&gt;&lt;br&gt;
Firestore is a document store. Postgres is tables, types, and foreign keys. A real move has to admit uncertainty:&lt;br&gt;
this field is a string in 80 documents and a number in 4&lt;br&gt;
this userId looks like a reference&lt;br&gt;
this collection has nested subcollections the sample never saw&lt;br&gt;
FireMigrate treats those as warnings, not as something to hide in JSON.&lt;br&gt;
What it does today&lt;br&gt;
The package on npm is @ezekielreu6/firemigrate (currently 0.1.3). MIT. CLI-first. Node 20+.&lt;br&gt;
Command&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What actually happens&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;init&lt;br&gt;
Writes firemigrate.config.json and .env.example. Will not overwrite unless you pass --force.&lt;br&gt;
inspect&lt;br&gt;
Read-only. Collection counts, sampled field types, mixed-type warnings, Auth provider summary.&lt;br&gt;
schema&lt;br&gt;
Prints Postgres SQL. One table per top-level collection. Mixed/maps/arrays → jsonb. Timestamps → timestamptz.&lt;br&gt;
migrate --dry-run&lt;br&gt;
Default. Streams documents, reports counts, writes nothing.&lt;br&gt;
migrate --write&lt;br&gt;
Only if the flag and &quot;dryRun&quot;: false are set. Creates tables, upserts by id in batches, then checks row counts.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;verify&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Compares Postgres row counts to Firestore document counts.&lt;br&gt;
Credentials live in env vars (FIREBASE_PROJECT_ID, FIREBASE_CLIENT_EMAIL, FIREBASE_PRIVATE_KEY, DATABASE_URL). The config file starts empty on purpose. Do not commit service-account keys.&lt;br&gt;
What is still sharp (this is the contributor pitch)&lt;br&gt;
This is an early foundation, not a complete migration product. That is the point of the repo.&lt;br&gt;
Open work, if you want a useful PR:&lt;br&gt;
Subcollections — detected, not migrated. Need a mapping that becomes real tables instead of a JSON blob.&lt;br&gt;
Better relationship guesses — name-based FKs should stay warnings until confidence is high. Improve the analyzer, don’t silently emit fake constraints.&lt;br&gt;
Auth users — inspect already summarizes providers. Actual Auth → Postgres (no plaintext passwords) is unbuilt.&lt;br&gt;
Storage — not covered.&lt;br&gt;
Sample bias — schema is inferred from up to 100 docs/collection (max 1000). Fields outside the sample get dropped and reported. Smarter sampling would help.&lt;br&gt;
Tests — domain tests for inspect/schema/migrate, with fake fixtures and no real credentials.&lt;br&gt;
Docs of edge cases — mixed types, colliding id fields, paused writes, verify mismatches.&lt;br&gt;
What we will not merge: a PR that writes to the destination by default, logs private keys, or fakes inspect output.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Repo shape&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;packages/core   inspect, schema, migrate, verify&lt;br&gt;
packages/cli    the &lt;code&gt;firemigrate&lt;/code&gt; binary&lt;br&gt;
Local loop:&lt;br&gt;
pnpm install&lt;br&gt;
pnpm build&lt;br&gt;
node packages/cli/dist/packages/cli/src/index.js inspect&lt;br&gt;
Small PRs. One adapter or one workflow change at a time. Keep dry-run as the default.&lt;br&gt;
If you only have 20 minutes&lt;br&gt;
Run init + inspect on a throwaway Firebase project. File an issue with:&lt;br&gt;
what the inspect report got wrong&lt;br&gt;
a redacted collection shape (field names + types, not documents)&lt;br&gt;
what you expected the schema to look like&lt;br&gt;
That kind of issue is more useful than a star.&lt;br&gt;
If you want to implement something, open the issue first so two people don’t build the same subcollection mapper.&lt;br&gt;
FireMigrate is for people who are leaving Firebase on purpose, not for people who want a magic dump. If that sounds like work you already do, the repo is here:&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/ezekielreu6-bit/firemigrate&quot;&gt;Repo&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/28096/firemigrate-leave-firebase-for-postgres-without-dumping-everything-into-json</guid>
<pubDate>Tue, 22 Sep 2026 04:51:20 +0000</pubDate>
</item>
<item>
<title>How OpenAI Codex let me down — and why I built Codey, an open-source coding assistant</title>
<link>https://coderlegion.com/23682/how-openai-codex-let-me-down-and-why-i-built-codey-an-open-source-coding-assistant</link>
<description>&lt;p&gt;When OpenAI announced Codex and CLI tools, I got excited — finally, an easy way to automate coding workflows using LLMs!&lt;br&gt;
I bought credits, installed the CLI, and even set it up on my Mac.&lt;/p&gt;
&lt;p&gt;But... it didn't go smoothly.&lt;/p&gt;
&lt;p&gt;First, I realized Codex CLI only supports Mac and Linux. Okay, not ideal but manageable.&lt;br&gt;
Then, I found out that cheaper models like gpt-4o-mini don't even support shell commands.&lt;br&gt;
(If you try, you get ENOENT errors because tool calls are missing.)&lt;/p&gt;
&lt;p&gt;I thought: maybe switching to o4-mini would fix it.&lt;br&gt;
Nope — new accounts don't have access immediately. I was stuck.&lt;/p&gt;
&lt;p&gt;Instead of waiting endlessly, I decided to build my own CLI assistant from scratch — and that's how Codey was born!&lt;/p&gt;
&lt;p&gt; What is Codey?&lt;br&gt;
Codey is a Python-based, open-source coding assistant that uses OpenAI's API — but defines all tools explicitly for safety and control.&lt;/p&gt;
&lt;p&gt;It supports:&lt;/p&gt;
&lt;p&gt;File Management: Create, edit, and read files with tools like create_file, edit_file, read_codebase&lt;/p&gt;
&lt;p&gt;Git Operations: Add, commit, check status, view diffs, and more&lt;/p&gt;
&lt;p&gt;Utilities: Search files (grep) and calculate expressions safely&lt;/p&gt;
&lt;p&gt;Shell Commands: Run shell commands inside your environment securely&lt;/p&gt;
&lt;p&gt; Why build it myself?&lt;br&gt;
I wanted predictability — knowing exactly what a tool can and cannot do.&lt;/p&gt;
&lt;p&gt;I wanted local safety — no random shell execution unless I allow it.&lt;/p&gt;
&lt;p&gt;I wanted modularity — easily extend or customize based on project needs.&lt;/p&gt;
&lt;p&gt;And honestly... I just wanted something that works reliably without mysterious permission errors.&lt;/p&gt;
&lt;p&gt; Codey is Open Source&lt;br&gt;
You can check it out here:&lt;br&gt;
 &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Varad-13/codey&quot;&gt;https://github.com/Varad-13/codey&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you want to try it out, suggest features, or even contribute (we need to add a million more tools) — you're welcome! &lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/23682/how-openai-codex-let-me-down-and-why-i-built-codey-an-open-source-coding-assistant</guid>
<pubDate>Tue, 28 Jul 2026 15:59:08 +0000</pubDate>
</item>
<item>
<title>Git Worktrees Are Underrated</title>
<link>https://coderlegion.com/22952/git-worktrees-are-underrated</link>
<description>&lt;p&gt;If you've ever stashed half-finished work to review a PR, or lost a train of thought switching branches, you should know about git worktrees. They've been in git since 2015, but most developers I talk to have never heard of them.&lt;/p&gt;
&lt;h3 id=&quot;the-problem-with-branches&quot;&gt;The problem with branches&lt;/h3&gt;
&lt;p&gt;The standard git workflow is linear. You're on a branch, you need to context-switch, so you stash your changes (or worse, make a throwaway commit), switch branches, do your thing, switch back, and pop the stash. If you're lucky, nothing conflicts.&lt;/p&gt;
&lt;p&gt;This gets worse when you're juggling multiple things at once. Reviewing a colleague's PR while your feature branch is mid-refactor. Running tests on one branch while coding on another. Hotfixing production while your main work sits frozen.&lt;/p&gt;
&lt;p&gt;A git repository has one working directory. One branch checked out at a time. Everything else has to wait.&lt;/p&gt;
&lt;h3 id=&quot;worktrees&quot;&gt;Worktrees&lt;/h3&gt;
&lt;p&gt;Git worktrees let you check out multiple branches simultaneously, each in its own directory. They share the same &lt;code&gt;.git&lt;/code&gt; history and objects, so you're not cloning the entire repo, but each one has its own working directory and index.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;git worktree add ../feat-login feat/login
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now &lt;code&gt;feat/login&lt;/code&gt; is checked out in &lt;code&gt;../feat-login&lt;/code&gt;. You can open it in a separate editor window, run tests there, or just let it sit while you work on something else.&lt;/p&gt;
&lt;p&gt;When you're done:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;git worktree remove ../feat-login
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;why-nobody-uses-them&quot;&gt;Why nobody uses them&lt;/h3&gt;
&lt;p&gt;If worktrees are so useful, why aren't they more popular? I think it comes down to two things.&lt;/p&gt;
&lt;p&gt;First, the directory problem. Every time you create a worktree, you have to pick a path. There's no convention for where they go. After a week you end up with directories scattered across your filesystem: &lt;code&gt;../feat-login&lt;/code&gt;, &lt;code&gt;~/tmp/hotfix-auth&lt;/code&gt;, &lt;code&gt;../../pr-review&lt;/code&gt;. Good luck remembering where anything is.&lt;/p&gt;
&lt;p&gt;Second, there are no ergonomics. You can't easily list your worktrees with status info, cd into one quickly, or run something like &lt;code&gt;npm install&lt;/code&gt; in the new directory after checkout. The raw git commands work, but they don't make worktrees feel like a real workflow.&lt;/p&gt;
&lt;p&gt;These aren't fundamental problems with worktrees. They're tooling gaps. That's why I built &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/morellodev/arbor&quot;&gt;arbor&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;a-better-workflow-with-arbor&quot;&gt;A better workflow with arbor&lt;/h3&gt;
&lt;p&gt;Arbor is a CLI that manages git worktrees. It keeps them organized in a central directory (&lt;code&gt;~/.arbor/worktrees/&lt;/code&gt;) and handles the stuff that plain git doesn't.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;# Clone a repo (sets up a bare repo + default branch worktree)
arbor clone user/my-app

# Create a worktree for a new feature
arbor add feat/login

# Shell integration auto-cds you into the worktree
# You're now in ~/.arbor/worktrees/my-app/feat-login

# Need to review a PR? Open another worktree
arbor add fix/auth-bug

# See all your worktrees with dirty/clean status
arbor ls
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Every worktree for &lt;code&gt;my-app&lt;/code&gt; lives under &lt;code&gt;~/.arbor/worktrees/my-app/&lt;/code&gt;. Branch slashes become dashes in directory names, so the filesystem stays tidy. When you're done with a branch:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;arbor rm -d feat/login
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That removes the worktree and the local branch in one step.&lt;/p&gt;
&lt;h3 id=&quot;what-makes-it-stick&quot;&gt;What makes it stick&lt;/h3&gt;
&lt;p&gt;I've been using worktrees for a while, but I kept falling off because of the friction. A few things in arbor made the difference for me.&lt;/p&gt;
&lt;p&gt;Shell integration. &lt;code&gt;arbor init&lt;/code&gt; sets up a wrapper so that &lt;code&gt;arbor add&lt;/code&gt; and &lt;code&gt;arbor switch&lt;/code&gt; automatically cd you into the worktree directory. Without it you create the worktree and then have to &lt;code&gt;cd&lt;/code&gt; into it yourself every single time, which gets old fast.&lt;/p&gt;
&lt;p&gt;Post-create hooks. You can add an &lt;code&gt;.arbor.toml&lt;/code&gt; to your repo:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-toml&quot;&gt;[hooks]
post_create = &quot;npm install&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Every new worktree gets its dependencies installed automatically. You can chain commands too:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-toml&quot;&gt;[hooks]
post_create = [&quot;npm install&quot;, &quot;cp .env.example .env&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And &lt;code&gt;arbor ls --all&lt;/code&gt; shows the state of every worktree across all your repos, which is nice for a quick scan before you call it a day.&lt;/p&gt;
&lt;h3 id=&quot;where-i-use-them-most&quot;&gt;Where I use them most&lt;/h3&gt;
&lt;p&gt;PR reviews. &lt;code&gt;arbor add&lt;/code&gt; the branch, review it in a separate editor window, remove it when done. My own work is untouched.&lt;/p&gt;
&lt;p&gt;Long test suites. Tests running on one branch, coding on another. No waiting around.&lt;/p&gt;
&lt;p&gt;Hotfixes. &lt;code&gt;arbor add hotfix/critical&lt;/code&gt;, fix it, push it, remove it. Back to what I was doing.&lt;/p&gt;
&lt;p&gt;Comparing behavior. Two worktrees open side by side, one on &lt;code&gt;main&lt;/code&gt; and one on my feature branch. Way easier than switching back and forth.&lt;/p&gt;
&lt;p&gt;Big migrations. Upgrading a framework to a new major version in a worktree while the rest of the team keeps shipping from &lt;code&gt;main&lt;/code&gt;, the way I kicked the tires on &lt;a rel=&quot;nofollow&quot; href=&quot;https://morello.dev/blog/solidjs-2-react-developers-first-look&quot;&gt;SolidJS 2.0&lt;/a&gt; and dug into &lt;a rel=&quot;nofollow&quot; href=&quot;https://morello.dev/blog/solidjs-2-async-data&quot;&gt;its async data model&lt;/a&gt;. No half-broken build blocking anyone.&lt;/p&gt;
&lt;h3 id=&quot;git-worktree-best-practices&quot;&gt;Git worktree best practices&lt;/h3&gt;
&lt;p&gt;A few habits keep worktrees from turning into the mess that makes people give up on them, whether you're on arbor or raw git.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Keep them in one predictable place.&lt;/strong&gt; Pick a home for your worktrees and stick to it: a &lt;code&gt;~/worktrees/&lt;/code&gt; directory, or let arbor manage &lt;code&gt;~/.arbor/worktrees/&lt;/code&gt; for you. Scattering them across &lt;code&gt;../&lt;/code&gt;, &lt;code&gt;~/tmp&lt;/code&gt;, and &lt;code&gt;../../&lt;/code&gt; is how you lose track of what lives where.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;One branch per worktree.&lt;/strong&gt; Git won't let you check out the same branch in two worktrees without &lt;code&gt;--force&lt;/code&gt;, and that guardrail is worth respecting. Keep the mapping one branch to one directory.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Create the branch and the worktree together.&lt;/strong&gt; &lt;code&gt;git worktree add -b feat/login ../feat-login&lt;/code&gt; makes the branch and checks it out in the new directory in a single command, instead of creating the branch first and adding it after.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Remove worktrees with git, not &lt;code&gt;rm -rf&lt;/code&gt;.&lt;/strong&gt; Run &lt;code&gt;git worktree remove ../feat-login&lt;/code&gt; instead of deleting the directory by hand. A manual delete leaves stale metadata behind in &lt;code&gt;.git/worktrees&lt;/code&gt;, which you then have to clear out with &lt;code&gt;git worktree prune&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Run &lt;code&gt;git worktree list&lt;/code&gt; when you lose the thread.&lt;/strong&gt; It prints every worktree with its branch and commit, so you can see what's checked out where before you go hunting through directories.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Don't nest them.&lt;/strong&gt; Give each worktree its own top-level directory rather than tucking one inside another worktree or the main repo. Nesting confuses tooling, and worktrees on a repo with submodules are only partly supported anyway.&lt;/p&gt;
&lt;h3 id=&quot;try-it&quot;&gt;Try it&lt;/h3&gt;
&lt;p&gt;Arbor is open source, written in Rust. Install with Homebrew:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-sh&quot;&gt;brew install morellodev/tap/arbor
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or grab a binary from the &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/morellodev/arbor/releases/latest&quot;&gt;releases page&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Run &lt;code&gt;arbor init&lt;/code&gt; after installing to set up shell integration. Takes about 30 seconds.&lt;/p&gt;
&lt;p&gt;If you've never tried worktrees, give them a shot. And if you have but gave up because of the directory mess, this might be worth another look.&lt;/p&gt;
&lt;p&gt;The repo is at &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/morellodev/arbor&quot;&gt;github.com/morellodev/arbor&lt;/a&gt;.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/22952/git-worktrees-are-underrated</guid>
<pubDate>Sat, 18 Jul 2026 22:31:32 +0000</pubDate>
</item>
<item>
<title>They Asked for My AI Rules. But I Could Not Just Hand Them Over.</title>
<link>https://coderlegion.com/22525/they-asked-for-my-ai-rules-but-i-could-not-just-hand-them-over</link>
<description>&lt;p&gt;A team lead announces that the team will start using AI-assisted development. Everyone nods. Nobody asks what that actually means on Monday morning.&lt;/p&gt;
&lt;p&gt;Some times ago I was in that position. A project I was working on needed to start using AI-assisted development, and the team was new to it. Nobody had rules written down for an agent to follow. Nobody had skills defined for it to load. There was no shared idea of how this should work inside our specific repo. Someone had to go first. That someone was me.&lt;/p&gt;
&lt;h3 id=&quot;the-rules-worked-because-i-built-them-for-one-repo&quot;&gt;The rules worked because I built them for one repo&lt;/h3&gt;
&lt;p&gt;I spent time curating a set of rules and skills for that project. Not generic ones. I shaped them tightly around how that repo was actually structured, its conventions, its layout, the things a new engineer usually has to learn by asking around. I wanted an agent working inside that codebase to already know what a human teammate would have picked up in the first two weeks.&lt;/p&gt;
&lt;p&gt;I gave a demo. It landed well. Well enough that it got shared further across team, as something other teams could learn from.&lt;/p&gt;
&lt;p&gt;I gave the demo again. Same reaction. Then a few developers reached out for the actual rules and skills files.&lt;/p&gt;
&lt;p&gt;I said sure, and then I actually looked at what I would be handing them.&lt;/p&gt;
&lt;h3 id=&quot;the-problem-showed-up-the-moment-other-people-wanted-in&quot;&gt;The problem showed up the moment other people wanted in&lt;/h3&gt;
&lt;p&gt;It was not copy-paste-able. The rules referenced folder names, module boundaries, and patterns specific to one repo. Handing them over as-is would have meant handing over advice that was wrong for their project, dressed up as a shortcut.&lt;/p&gt;
&lt;p&gt;So I told them to use it as a reference. Look at the structure, understand the reasoning, adapt it to your own repo.&lt;/p&gt;
&lt;p&gt;That is correct advice. I watched people nod at it and then quietly missing it.&lt;/p&gt;
&lt;h3 id=&quot;i-was-solving-the-wrong-problem-the-whole-time&quot;&gt;I was solving the wrong problem the whole time&lt;/h3&gt;
&lt;p&gt;I had been thinking about this as a documentation problem. Write good rules, explain them well, let people copy the idea. What I actually had was a generation problem. The rules that worked were the ones rendered specifically for a stack, not the ones written generically and left for someone to translate.&lt;/p&gt;
&lt;p&gt;The thing that was supposed to spread across other teams did not land as expected. What reached them was a reference nobody had time to turn into anything real. That gap sat there whether I looked at it or not.&lt;/p&gt;
&lt;p&gt;What I wanted to build was not another generic harness. I wanted something that looked at a repo's actual stack and produced rules and skills that worked from day one, not rules that needed a translation step before they were useful.&lt;/p&gt;
&lt;h3 id=&quot;nobody-on-a-team-agrees-on-one-ai-tool&quot;&gt;Nobody on a team agrees on one AI tool&lt;/h3&gt;
&lt;p&gt;Once I sat with that problem, a second one showed up right behind it, and this one turned out to matter just as much.&lt;/p&gt;
&lt;p&gt;Every adoption plan I had seen quietly assumed one AI tool per team. In practice, that assumption breaks almost immediately. One engineer wants Cursor. Another has already built muscle memory in Claude Code. Someone else is testing Windsurf, or is stuck on Copilot because that is what the company licensed, or wants to try Antigravity because something new just came out.&lt;/p&gt;
&lt;p&gt;Nobody wants to be told which editor or which agent to use, and forcing a single choice on a team is its own kind of friction, separate from the rules problem entirely. An adoption effort that only works for one tool is not really team adoption. It is one person's adoption, dressed up as a rollout.&lt;/p&gt;
&lt;h3 id=&quot;what-the-tool-had-to-actually-do&quot;&gt;What the tool had to actually do&lt;/h3&gt;
&lt;p&gt;That is the shape the problem ended up taking. Not &quot;write better rules.&quot; Generate rules and skills that are rendered for a specific stack, and make sure they work no matter which of the tools a given engineer has already chosen.&lt;/p&gt;
&lt;p&gt;That is what became &lt;strong&gt;FARE&lt;/strong&gt; and &lt;strong&gt;BARE&lt;/strong&gt;, frontend and backend AI starter recipes, published as npm CLI tools. Point either one at a project and it generates rules, skills, and workflow context shaped around that project's actual stack, with adapters for five tools out of the box: Cursor, Claude Code, Windsurf, Copilot, and Antigravity. The output is meant to be used immediately, not adapted first.&lt;/p&gt;
&lt;p&gt;The part worth being honest about is that this did not remove the original judgment call. Something still has to decide what &quot;good rules for this stack&quot; means because it's always well opinionated. The CLI just means that decision gets made once, by the tool, instead of once per engineer, per project, under deadline pressure, with wildly inconsistent results.&lt;/p&gt;
&lt;h3 id=&quot;i-did-not-build-everything-i-wanted-to&quot;&gt;I did not build everything I wanted to&lt;/h3&gt;
&lt;p&gt;The scope I first sketched out was larger than what shipped. There were ideas around deeper project-specific customization, additional integrations, and more automated context tracking that I dropped or pushed to later releases. Some of that was a reasonable v1 boundary. Some of it was me wanting to build the interesting version instead of the useful one, and catching myself doing it.&lt;/p&gt;
&lt;p&gt;Keeping it simple was not the easy default. It was a decision, and one I had to make more than once while writing it.&lt;/p&gt;
&lt;p&gt;I do not know yet whether this is the right shape for other teams' problems or just the right shape for the one I kept running into. If you try FARE or BARE on your own project, I would genuinely like to know where it holds up and where it does not.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Awaiting your feedback!&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://jeelvankhede.github.io/frontend-ai-starter-recipes/&quot;&gt;&lt;strong&gt;F&lt;/strong&gt;rontend &lt;strong&gt;A&lt;/strong&gt;i starter &lt;strong&gt;RE&lt;/strong&gt;cipes&lt;/a&gt;&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://jeelvankhede.github.io/backend-ai-starter-recipes/&quot;&gt;&lt;strong&gt;B&lt;/strong&gt;ackend &lt;strong&gt;A&lt;/strong&gt;i starter &lt;strong&gt;RE&lt;/strong&gt;cipes&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/22525/they-asked-for-my-ai-rules-but-i-could-not-just-hand-them-over</guid>
<pubDate>Mon, 13 Jul 2026 18:56:49 +0000</pubDate>
</item>
<item>
<title>Cava segfaulting inside WezTerm (Flatpak)? Diagnosis and fix in one command</title>
<link>https://coderlegion.com/20447/cava-segfaulting-inside-wezterm-flatpak-diagnosis-and-fix-in-one-command</link>
<description>&lt;p&gt;&lt;code&gt;cava&lt;/code&gt; runs fine in any terminal — but inside WezTerm installed via Flatpak it crashes with:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Segmentation fault (core dumped)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If that's what brought you here, the quick fix is right below. The full diagnosis comes after, for those who want to understand why.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;-tl-dr-fix-in-two-commands&quot;&gt;⚡ TL;DR — Fix in two commands&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;flatpak update org.wezfurlong.wezterm
flatpak override --user org.wezfurlong.wezterm --device=all
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Close &lt;strong&gt;all&lt;/strong&gt; WezTerm windows and reopen it. &lt;code&gt;cava&lt;/code&gt; should work normally now.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;⚠️ &lt;strong&gt;Security tradeoff:&lt;/strong&gt; &lt;code&gt;--device=all&lt;/code&gt; grants WezTerm access to &lt;em&gt;all&lt;/em&gt; system devices — including camera and microphone, not just audio. If that's a concern in your environment, the safer alternative is to use the &lt;a rel=&quot;nofollow&quot; href=&quot;#-last-resort-native-wezterm&quot;&gt;native WezTerm build&lt;/a&gt;, which doesn't have this restriction by design.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vo9r00rlh0tl6dfbx8j1.png&quot; alt=&quot;WezTerm with Cava Working&quot;&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;-what-s-happening-under-the-hood&quot;&gt;🔍 What's happening under the hood&lt;/h3&gt;
&lt;h4 id=&quot;why-does-wezterm-flatpak-cause-the-crash-&quot;&gt;Why does WezTerm Flatpak cause the crash?&lt;/h4&gt;
&lt;p&gt;Flatpak runs WezTerm inside a sandbox that isolates the process from the host system. &lt;code&gt;cava&lt;/code&gt; tries to enumerate available audio devices (ALSA/PipeWire) right at startup — without access to those device nodes, it receives an invalid pointer and segfaults.&lt;/p&gt;
&lt;p&gt;That's why other terminals (GNOME Terminal, Kitty, etc.) don't have this problem: they have unrestricted access to the system. &lt;code&gt;--device=all&lt;/code&gt; fixes exactly that: it grants access to the audio device nodes &lt;code&gt;cava&lt;/code&gt; needs to initialize.&lt;/p&gt;
&lt;p&gt;As a secondary hypothesis (not directly confirmed), the sandbox may also modify environment variables that &lt;code&gt;cava&lt;/code&gt; uses to detect the audio backend.&lt;/p&gt;
&lt;h4 id=&quot;confirming-with-gdb&quot;&gt;Confirming with GDB&lt;/h4&gt;
&lt;details&gt;
&lt;summary&gt;Want to see the full backtrace? Expand here.&lt;/summary&gt;

Inside WezTerm, run:

```bash
gdb cava
```

When prompted, accept debuginfod with `y`. Then:

```
(gdb) run
```

When the crash occurs:

```
(gdb) bt
```

The output should look something like this:

```
Program received signal SIGSEGV, Segmentation fault.
__strncmp_avx2 () at ../sysdeps/x86_64/multiarch/strcmp-avx2.S:283
283             VMOVU   (%rdi), %ymm0
(gdb) bt
#0  __strncmp_avx2 () at ../sysdeps/x86_64/multiarch/strcmp-avx2.S:283
#1  0x0000555555559cfe in main (argc=, argv=)
    at /usr/src/debug/cava-0.10.2-7.fc44.x86_64/cava.c:297
```

The crash happens inside `__strncmp_avx2` — a glibc string comparison function — called by `cava` at line 297. The pointer passed in is null or points to invalid memory, which indicates that `cava` failed to retrieve valid information about the audio devices and segfaulted when trying to use it.

&lt;/details&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/r4dupdue2m28h6xb026b.png&quot; alt=&quot;gdb output&quot;&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;-step-by-step-fix&quot;&gt;✅ Step-by-step fix&lt;/h3&gt;
&lt;h4 id=&quot;1-update-your-packages&quot;&gt;1. Update your packages&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo dnf upgrade cava          # Fedora
flatpak update org.wezfurlong.wezterm
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;2-grant-device-access&quot;&gt;2. Grant device access&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;flatpak override --user org.wezfurlong.wezterm --device=all
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;3-fully-restart-wezterm&quot;&gt;3. Fully restart WezTerm&lt;/h4&gt;
&lt;p&gt;Close all windows and reopen. &lt;code&gt;Ctrl+Shift+R&lt;/code&gt; &lt;strong&gt;is not enough&lt;/strong&gt; — Flatpak permission changes only take effect after a full restart.&lt;/p&gt;
&lt;h4 id=&quot;4-test-it&quot;&gt;4. Test it&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cava
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;🎉 Working? You're done. If not, see the alternatives below.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;-alternative-flatseal&quot;&gt;🖱️ Alternative: Flatseal&lt;/h3&gt;
&lt;p&gt;Prefer a GUI for managing Flatpak permissions?&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;flatpak install flathub com.github.tchx84.Flatseal
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Open Flatseal → select &lt;strong&gt;WezTerm&lt;/strong&gt; → go to the &lt;strong&gt;Device&lt;/strong&gt; section → enable &lt;strong&gt;All devices&lt;/strong&gt; → restart WezTerm. The result is identical to the command above.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;-if-it-still-doesn-t-work&quot;&gt;⚠️ If it still doesn't work&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Audio service not running:&lt;/strong&gt; check if PipeWire is active:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;systemctl --user status pipewire
# If inactive:
systemctl --user start pipewire
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Rendering issue:&lt;/strong&gt; add this to your &lt;code&gt;~/.wezterm.lua&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-lua&quot;&gt;config.front_end = &quot;Software&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;&lt;p&gt;⚠️ This option may cause slowness or even prevent WezTerm from opening on some systems. Use with caution.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;-last-resort-native-wezterm&quot;&gt;🔄 Last resort: native WezTerm&lt;/h3&gt;
&lt;p&gt;If nothing works — or if the &lt;code&gt;--device=all&lt;/code&gt; tradeoff isn't acceptable — the native build solves it definitively: no sandbox, no device restrictions.&lt;/p&gt;
&lt;p&gt;The &lt;a rel=&quot;nofollow&quot; href=&quot;https://wezterm.org/install/linux.html#__tabbed_1_2&quot;&gt;official documentation&lt;/a&gt; covers all options: AppImage, &lt;code&gt;.deb&lt;/code&gt;/&lt;code&gt;.rpm&lt;/code&gt; packages, and building from source.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;-summary&quot;&gt;📌 Summary&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Solution &lt;/th&gt;&lt;th&gt;Complexity &lt;/th&gt;&lt;th&gt;Keeps Flatpak?&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;flatpak override --device=all&lt;/code&gt; &lt;/td&gt;&lt;td&gt;⭐ Low &lt;/td&gt;&lt;td&gt;✅&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Flatseal (GUI) &lt;/td&gt;&lt;td&gt;⭐ Low &lt;/td&gt;&lt;td&gt;✅&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Check PipeWire &lt;/td&gt;&lt;td&gt;⭐⭐ Medium &lt;/td&gt;&lt;td&gt;✅&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;front_end = &quot;Software&quot;&lt;/code&gt; &lt;/td&gt;&lt;td&gt;⭐⭐ Medium &lt;/td&gt;&lt;td&gt;✅&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Install native build &lt;/td&gt;&lt;td&gt;⭐⭐ Medium &lt;/td&gt;&lt;td&gt;❌&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The root cause is the Flatpak sandbox blocking &lt;code&gt;cava&lt;/code&gt;'s access to audio device nodes at startup. Releasing that access with &lt;code&gt;--device=all&lt;/code&gt; resolves it in almost every case — and you keep all the benefits of Flatpak.&lt;/p&gt;
&lt;hr&gt;
&lt;blockquote&gt;&lt;p&gt;📝 Based on real experience on Fedora 44+ with WezTerm (Flatpak) and cava 0.10.2.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
<category>Tutorials</category>
<guid isPermaLink="true">https://coderlegion.com/20447/cava-segfaulting-inside-wezterm-flatpak-diagnosis-and-fix-in-one-command</guid>
<pubDate>Fri, 12 Jun 2026 18:21:18 +0000</pubDate>
</item>
<item>
<title>rdev-go-ddgen: Automating Domain Directory Boilerplate for Go Applications</title>
<link>https://coderlegion.com/20185/rdev-go-ddgen-automating-domain-directory-boilerplate-for-go-applications</link>
<description>&lt;p&gt;When building robust backend APIs in Go, maintaining a consistent, clean architectural pattern across domain directories is essential for scalability. However, manually creating repetitive domain structures for every new resource introduces subtle human error.&lt;/p&gt;
&lt;p&gt;The Why: Why Manual Boilerplate Fails Copy-pasting existing files to scaffold a new domain (e.g., adding an orders domain next to a users domain) is a common but fragile practice. It is incredibly easy to overlook an import statement, miss a file, or forget to update a variable definition. As an API grows to dozens of domains, this manual approach becomes a major bottleneck that risks introducing compilation errors or silent bugs into your application.&lt;/p&gt;
&lt;p&gt;The What: What is rdev-go-ddgen? rdev-go-ddgen (Domain Directory Generator) is a lightweight, open-source Command Line Interface (CLI) tool designed to eliminate manual boilerplate creation for Go applications. It targets developers looking to instantly spin up predictable, structured domain directories without the risk of copy-paste mistakes.&lt;/p&gt;
&lt;p&gt;While built out of a personal need while developing high-conformance Go APIs using Gin and Bun ORM, rdev-go-ddgen is completely engine-agnostic and serves as a universal foundational bootstrapper.&lt;/p&gt;
&lt;p&gt;The How: Rapid Deployment You can install rdev-go-ddgen globally and immediately integrate it into your development workflow with a single command:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;go install github.com/XaiPhyr/rdev-go-ddgen@latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To Initialize folder structure&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rdev-go-ddgen init
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To scaffold a completely new, structured domain directory, simply initialize the tool and use the domain flag (-d):&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;rdev-go-ddgen -d orders
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This single command instantly generates a pristine directory containing five core architectural layers, fully stubbed with basic functions and type declarations:&lt;/p&gt;
&lt;p&gt;handler.go – API routing and transport logic. service.go – Core business logic boundaries. repository.go – Database abstraction and data access. types.go – Domain-specific data models and structs. _test.go – Unit and integration test placeholders.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=17500459554166320830&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;P.S. I hope this tool saves you some development time! rdev-go-ddgen is my first official contribution to the Go community, it’s a small step, but I’m incredibly excited to finally share something back with the ecosystem.&lt;/p&gt;
</description>
<category>Launches</category>
<guid isPermaLink="true">https://coderlegion.com/20185/rdev-go-ddgen-automating-domain-directory-boilerplate-for-go-applications</guid>
<pubDate>Wed, 10 Jun 2026 15:27:33 +0000</pubDate>
</item>
<item>
<title>Your Codebase Is Too Big for an AI. Here's How to Give It Only What Matters</title>
<link>https://coderlegion.com/20119/your-codebase-is-too-big-for-an-ai-heres-how-to-give-it-only-what-matters</link>
<description>&lt;p&gt;Every AI session I had started with the same silent ritual.&lt;/p&gt;
&lt;p&gt;Open the project. Figure out which files are actually relevant. Remember to skip &lt;code&gt;node_modules&lt;/code&gt;. And &lt;code&gt;__pycache__&lt;/code&gt;. And &lt;code&gt;.venv&lt;/code&gt;. And the lock files. Zip everything manually. Find the zip. Upload it. Then type out what I was actually trying to do, context the AI had no way of knowing.&lt;/p&gt;
&lt;p&gt;It was maybe 5 minutes. Not a crisis. But it happened &lt;em&gt;every single session&lt;/em&gt;, and at some point I stopped accepting it as normal.&lt;/p&gt;
&lt;p&gt;So I built &lt;strong&gt;contextzip&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;{% embed &lt;a rel=&quot;nofollow&quot; href=&quot;https://youtu.be/mHq1JH0ZJuY&quot;&gt;https://youtu.be/mHq1JH0ZJuY&lt;/a&gt; %}&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-it-does-1&quot;&gt;What it does&lt;/h3&gt;
&lt;p&gt;contextzip is a CLI tool that packages exactly the right parts of your codebase into a ZIP, ready to drop into Claude, ChatGPT, or any other AI tool.&lt;/p&gt;
&lt;p&gt;Install it once:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pip install contextzip
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then from any project:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cd your-project
contextzip
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That's it. It detects your stack automatically : Next.js, Django, FastAPI, Rust, Go, Ruby, and more, applies the right exclusion rules for each, respects your &lt;code&gt;.gitignore&lt;/code&gt;, and drops a clean ZIP into &lt;code&gt;.contextzip/&lt;/code&gt; at your project root. Your file manager opens with the archive already selected.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-part-i-m-most-excited-about&quot;&gt;The part I'm most excited about&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;contextzip --prompt &quot;Change toast color on failed login&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Describe your task in plain English. contextzip builds a lightweight file map of your project and asks Gemini to return only the files relevant to that specific task. Usually 2 to 5 files. Not your entire codebase.&lt;/p&gt;
&lt;p&gt;The ZIP also includes a &lt;code&gt;prompt.txt&lt;/code&gt; with your task description, so when you drop it into an AI tool, the context is already there. No retyping, no re-explaining.&lt;/p&gt;
&lt;p&gt;This is the feature that changed how I personally work with AI tools day to day.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;First-time setup: &lt;code&gt;--prompt&lt;/code&gt; requires a free Gemini API key from Google AI Studio, no credit card needed. contextzip walks you through it on first use.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;other-things-it-does&quot;&gt;Other things it does&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;--git-changes&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Only package files that git considers modified, staged, or untracked. Perfect for incremental debugging sessions and PR reviews where you don't need the whole project, just what changed.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;contextzip --git-changes
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;watch&lt;/code&gt; mode&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This one is underrated. Wrap your dev server with &lt;code&gt;contextzip watch&lt;/code&gt; and it buffers the output in the background, watching for errors. The moment one appears, a prompt shows up beneath it:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;╭─ contextzip · error detected ─────────────────────╮
│  Press [D] to package debug context  [S] to skip  │
╰───────────────────────────────────────────────────╯
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Press D. A debug-ready ZIP lands in &lt;code&gt;.contextzip/&lt;/code&gt; with the error, the stack trace, and the relevant source files already inside. Your server keeps running, no restart needed.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;contextzip watch -- npm run dev
contextzip watch -- python manage.py runserver
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Smart exclusions by framework&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;contextzip stacks exclusion rules based on what it detects:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Stack &lt;/th&gt;&lt;th&gt;Excluded automatically&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Node.js / Next.js &lt;/td&gt;&lt;td&gt;&lt;code&gt;node_modules/&lt;/code&gt;, &lt;code&gt;.next/&lt;/code&gt;, &lt;code&gt;dist/&lt;/code&gt;, lock files, &lt;code&gt;*.min.js&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Python / Django / FastAPI &lt;/td&gt;&lt;td&gt;&lt;code&gt;__pycache__/&lt;/code&gt;, &lt;code&gt;.venv/&lt;/code&gt;, &lt;code&gt;*.pyc&lt;/code&gt;, &lt;code&gt;migrations/&lt;/code&gt;, lock files&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Rust &lt;/td&gt;&lt;td&gt;&lt;code&gt;target/&lt;/code&gt;, &lt;code&gt;Cargo.lock&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Go &lt;/td&gt;&lt;td&gt;&lt;code&gt;vendor/&lt;/code&gt;, &lt;code&gt;go.sum&lt;/code&gt;, &lt;code&gt;bin/&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;A monorepo with both &lt;code&gt;package.json&lt;/code&gt; and &lt;code&gt;pyproject.toml&lt;/code&gt; gets both rule sets applied automatically.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;honest-limitations&quot;&gt;Honest limitations&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;--prompt&lt;/code&gt; requires a free Gemini API key&lt;/li&gt;
&lt;li&gt;&lt;code&gt;watch&lt;/code&gt; doesn't use PTY emulation, so color passthrough on Windows is limited&lt;/li&gt;
&lt;li&gt;AI file selection is capped at 10 files by design, the goal is tight context, not comprehensive coverage&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;try-it-1&quot;&gt;Try it&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pip install contextzip
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GitHub: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/akadeepesh/contextzip&quot;&gt;github.com/akadeepesh/contextzip&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;MIT licensed, open source.&lt;/p&gt;
&lt;p&gt;If you've been living with this friction and didn't realize it was fixable, now you know. And if you try it, I'd genuinely love to hear how it fits into your workflow.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/20119/your-codebase-is-too-big-for-an-ai-heres-how-to-give-it-only-what-matters</guid>
<pubDate>Wed, 10 Jun 2026 04:54:51 +0000</pubDate>
</item>
<item>
<title>I built a CLI that eliminates README reading forever</title>
<link>https://coderlegion.com/19401/i-built-a-cli-that-eliminates-readme-reading-forever</link>
<description>&lt;hr&gt;
&lt;p&gt;title: I built a CLI that eliminates README reading forever&lt;br&gt;
published: true&lt;br&gt;
description: rex detects your project stack and runs the right command. Zero config. One binary. 12 ecosystems.&lt;br&gt;
tags: go, cli, productivity, opensource&lt;/p&gt;
&lt;h3 id=&quot;cover-image-https-rexrun-dev-logo-png&quot;&gt;cover_image: &lt;a rel=&quot;nofollow&quot; href=&quot;https://rexrun.dev/logo.png&quot;&gt;https://rexrun.dev/logo.png&lt;/a&gt;&lt;/h3&gt;
&lt;h3 id=&quot;the-problem&quot;&gt;The problem&lt;/h3&gt;
&lt;p&gt;Every developer knows this pain:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Clone a repo&lt;/li&gt;
&lt;li&gt;Want to run the tests&lt;/li&gt;
&lt;li&gt;Open the README&lt;/li&gt;
&lt;li&gt;Scroll... scroll... find a &quot;Development&quot; section... maybe&lt;/li&gt;
&lt;li&gt;Figure out it's &lt;code&gt;pnpm test&lt;/code&gt; (not &lt;code&gt;npm test&lt;/code&gt;, not &lt;code&gt;yarn test&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Run it wrong anyway because you needed &lt;code&gt;pnpm install&lt;/code&gt; first&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Multiply this by every repo you touch. Every PR you review. Every onboarding.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;I got tired of it.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&quot;the-solution-rex&quot;&gt;The solution: rex&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone https://github.com/some/repo
cd repo
rex test
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That's it. Rex looks at your project files, detects the stack, and runs the correct command. No config. No setup. No reading anything.&lt;/p&gt;
&lt;h3 id=&quot;how-it-works&quot;&gt;How it works&lt;/h3&gt;
&lt;p&gt;Rex reads files in your project root:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;File found &lt;/th&gt;&lt;th&gt;Stack detected &lt;/th&gt;&lt;th&gt;&lt;code&gt;rex test&lt;/code&gt; runs&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;go.mod&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Go &lt;/td&gt;&lt;td&gt;&lt;code&gt;go test ./...&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;package.json&lt;/code&gt; + &lt;code&gt;pnpm-lock.yaml&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Node + pnpm &lt;/td&gt;&lt;td&gt;&lt;code&gt;pnpm test&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;Cargo.toml&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Rust &lt;/td&gt;&lt;td&gt;&lt;code&gt;cargo test&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;pyproject.toml&lt;/code&gt; + &lt;code&gt;uv.lock&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Python + uv &lt;/td&gt;&lt;td&gt;&lt;code&gt;uv run pytest&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;composer.json&lt;/code&gt; + &lt;code&gt;artisan&lt;/code&gt; &lt;/td&gt;&lt;td&gt;PHP + Laravel &lt;/td&gt;&lt;td&gt;&lt;code&gt;php artisan test&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;Gemfile&lt;/code&gt; + &lt;code&gt;app/&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Ruby + Rails &lt;/td&gt;&lt;td&gt;&lt;code&gt;bundle exec rails test&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;pom.xml&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Java + Maven &lt;/td&gt;&lt;td&gt;&lt;code&gt;mvn test&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;build.gradle&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Java + Gradle &lt;/td&gt;&lt;td&gt;&lt;code&gt;./gradlew test&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;build.zig&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Zig &lt;/td&gt;&lt;td&gt;&lt;code&gt;zig build test&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;mix.exs&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Elixir &lt;/td&gt;&lt;td&gt;&lt;code&gt;mix test&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;Makefile&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Make &lt;/td&gt;&lt;td&gt;&lt;code&gt;make test&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;Justfile&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Just &lt;/td&gt;&lt;td&gt;&lt;code&gt;just test&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt;12 ecosystems.&lt;/strong&gt; It also detects which package manager you use by looking at lockfiles.&lt;/p&gt;
&lt;h3 id=&quot;demo&quot;&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/rexrun-dev/rex/releases/download/v0.2.0/demo.mp4&quot;&gt;Watch the video demo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;$ cd my-go-project/
$ rex

  my-go-project

  stack  go

  commands
    rex test   go test ./...
    rex run    go run ./cmd/server
    rex build  go build ./...
    rex deps   go mod download
    rex fmt    gofmt -w .
    rex lint   go vet ./...

$ rex test
&amp;gt; go test ./...
ok   github.com/example/app   1.2s
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The &lt;code&gt;&amp;gt;&lt;/code&gt; arrow always shows exactly what rex will run. Full transparency.&lt;/p&gt;
&lt;h3 id=&quot;all-the-verbs&quot;&gt;All the verbs&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Command &lt;/th&gt;&lt;th&gt;What it does&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rex test&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Run tests&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rex run&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Start the app / dev server&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rex build&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Build the project&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rex deps&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Install dependencies&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rex clean&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Remove build artifacts&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rex fresh&lt;/code&gt; &lt;/td&gt;&lt;td&gt;clean, deps, build in sequence&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rex fmt&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Format code&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rex lint&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Lint code&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rex clone &amp;lt;url&amp;gt;&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Clone + detect + install deps in one command&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rex init&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Generate rex.toml for your team&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;rex doctor&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Diagnose environment issues&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;killer-feature-rex-clone&quot;&gt;Killer feature: rex clone&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;rex clone https://github.com/someone/project
# cloning...
# detected: node + pnpm
# deps: pnpm install
# ready! cd project &amp;amp;&amp;amp; rex run
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;From URL to working project in one command. No README needed.&lt;/p&gt;
&lt;h3 id=&quot;monorepo-support&quot;&gt;Monorepo support&lt;/h3&gt;
&lt;p&gt;Rex auto-detects monorepos (packages/, apps/, services/):&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-console&quot;&gt;$ rex

  my-monorepo (monorepo)

  workspace  3 sub-projects detected

    packages/api         node + pnpm
    packages/web         node + pnpm
    services/auth        go
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;team-workflow-rex-init&quot;&gt;Team workflow: rex init&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;rex init
# created rex.toml (go project)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Generates a rex.toml from detected commands. Commit it. Now every teammate runs the same commands without asking.&lt;/p&gt;
&lt;h3 id=&quot;-env-loading&quot;&gt;.env loading&lt;/h3&gt;
&lt;p&gt;Rex automatically loads &lt;code&gt;.env&lt;/code&gt; files before running commands. No extra tools needed.&lt;/p&gt;
&lt;h3 id=&quot;why-i-built-this&quot;&gt;Why I built this&lt;/h3&gt;
&lt;p&gt;I maintain projects across Go, Node, Python, and Rust. I context-switch between repos dozens of times per day. The cognitive load of remembering &lt;code&gt;pnpm test&lt;/code&gt; vs &lt;code&gt;go test ./...&lt;/code&gt; vs &lt;code&gt;cargo test&lt;/code&gt; is small individually, but it adds up.&lt;/p&gt;
&lt;p&gt;Rex makes every repo feel the same:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;rex test   # always works
rex run    # always works
rex build  # always works
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It's the muscle memory tax I no longer pay.&lt;/p&gt;
&lt;h3 id=&quot;technical-details&quot;&gt;Technical details&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Single binary, no runtime, no dependencies&lt;/li&gt;
&lt;li&gt;Written in Go, cross-platform&lt;/li&gt;
&lt;li&gt;Less than 50ms startup, faster than your shell prompt&lt;/li&gt;
&lt;li&gt;Zero network calls, fully offline&lt;/li&gt;
&lt;li&gt;Correct exit codes, works in CI&lt;/li&gt;
&lt;li&gt;Shell completions for bash, zsh, fish&lt;/li&gt;
&lt;li&gt;Apache 2.0 license&lt;/li&gt;
&lt;li&gt;Mentioned in &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/avelino/awesome-go&quot;&gt;Awesome Go&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;install&quot;&gt;Install&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Homebrew (macOS/Linux)
brew tap rexrun-dev/tap &amp;amp;&amp;amp; brew install rex

# Go
go install rexrun.dev/rex/cmd/rex@latest
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or grab a binary from &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/rexrun-dev/rex/releases&quot;&gt;GitHub Releases&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;links&quot;&gt;Links&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/rexrun-dev/rex&quot;&gt;github.com/rexrun-dev/rex&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Website: &lt;a rel=&quot;nofollow&quot; href=&quot;https://rexrun.dev&quot;&gt;rexrun.dev&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If this solves a pain you've felt, star the repo. If you want a stack added, open an issue.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/19401/i-built-a-cli-that-eliminates-readme-reading-forever</guid>
<pubDate>Mon, 01 Jun 2026 10:05:12 +0000</pubDate>
</item>
<item>
<title>I built an AI Agent that lives directly in your CLI and Desktop</title>
<link>https://coderlegion.com/18390/i-built-an-ai-agent-that-lives-directly-in-your-cli-and-desktop</link>
<description>&lt;h2 id=&quot;i-built-an-ai-agent-that-lives-directly-in-your-cli-and-desktop&quot;&gt;I built an AI Agent that lives directly in your CLI and Desktop&lt;/h2&gt;
&lt;p&gt;Most AI coding workflows still feel disconnected.&lt;/p&gt;
&lt;p&gt;You copy code from your editor → paste into ChatGPT/Claude → copy the answer back → repeat.&lt;/p&gt;
&lt;p&gt;I got tired of acting like a middleman between my codebase and AI tools, so I built &lt;strong&gt;Mint&lt;/strong&gt; &lt;/p&gt;
&lt;p&gt;Mint is a unified AI desktop assistant + autonomous coding CLI designed for developers who want:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Local-first workflows&lt;/li&gt;
&lt;li&gt;Agentic coding&lt;/li&gt;
&lt;li&gt;MCP extensibility&lt;/li&gt;
&lt;li&gt;Workspace-aware AI&lt;/li&gt;
&lt;li&gt;Transparent safety controls&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;what-mint-can-do&quot;&gt;What Mint can do&lt;/h3&gt;
&lt;h4 id=&quot;unified-ai-cli-agent&quot;&gt;Unified AI CLI Agent&lt;/h4&gt;
&lt;p&gt;Mint is not just a chat wrapper.&lt;/p&gt;
&lt;p&gt;It can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;inspect your workspace&lt;/li&gt;
&lt;li&gt;search code&lt;/li&gt;
&lt;li&gt;read/write files&lt;/li&gt;
&lt;li&gt;apply patches&lt;/li&gt;
&lt;li&gt;execute shell commands with approval&lt;/li&gt;
&lt;li&gt;stream live responses directly in the terminal&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;mint code &quot;find the memory leak in the auth module and patch it&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;desktop-assistant&quot;&gt;Desktop Assistant&lt;/h4&gt;
&lt;p&gt;Mint also includes an Electron desktop assistant with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Screen vision&lt;/li&gt;
&lt;li&gt;Real-time translation&lt;/li&gt;
&lt;li&gt;Floating assistant UI&lt;/li&gt;
&lt;li&gt;Live2D assistant model&lt;/li&gt;
&lt;li&gt;Proactive local suggestions&lt;/li&gt;
&lt;li&gt;Automation workflows&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;mcp-support&quot;&gt;MCP Support&lt;/h4&gt;
&lt;p&gt;You can extend Mint using Model Context Protocol servers:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;mint mcp add google-search npx --args -y @modelcontextprotocol/server-google-search
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;multi-provider-support&quot;&gt;Multi-Provider Support&lt;/h4&gt;
&lt;p&gt;Mint supports:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Gemini&lt;/li&gt;
&lt;li&gt;OpenAI&lt;/li&gt;
&lt;li&gt;Claude&lt;/li&gt;
&lt;li&gt;Ollama&lt;/li&gt;
&lt;li&gt;LM Studio&lt;/li&gt;
&lt;li&gt;Local OpenAI-compatible providers&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;safety-first&quot;&gt;Safety First&lt;/h3&gt;
&lt;p&gt;One thing I care about a lot is transparency and control.&lt;/p&gt;
&lt;p&gt;Mint:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;asks permission before shell commands&lt;/li&gt;
&lt;li&gt;blocks dangerous commands&lt;/li&gt;
&lt;li&gt;prevents unsafe path traversal&lt;/li&gt;
&lt;li&gt;keeps local action logs&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;why-i-built-it&quot;&gt;Why I built it&lt;/h3&gt;
&lt;p&gt;I wanted an AI assistant that actually feels integrated into the developer workflow instead of existing in a separate browser tab.&lt;/p&gt;
&lt;p&gt;Something fast.&lt;br&gt;
Something local-first.&lt;br&gt;
Something extensible.&lt;br&gt;
Something that feels like a real co-developer.&lt;/p&gt;
&lt;h3 id=&quot;github&quot;&gt;GitHub&lt;/h3&gt;
&lt;p&gt; GitHub: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Pheem49/Mint&quot;&gt;https://github.com/Pheem49/Mint&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Would love feedback from other developers working on AI agents, local models, or terminal workflows &lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/18390/i-built-an-ai-agent-that-lives-directly-in-your-cli-and-desktop</guid>
<pubDate>Wed, 20 May 2026 04:16:38 +0000</pubDate>
</item>
<item>
<title>Ditch the Clunky GUIs: Meet ComChan, the Blazingly Fast Rust Serial Monitor</title>
<link>https://coderlegion.com/17983/ditch-the-clunky-guis-meet-comchan-the-blazingly-fast-rust-serial-monitor</link>
<description>&lt;p&gt;If you spend any significant amount of time doing embedded systems development, you know the drill. You write your firmware, flash the microcontroller, and then… you stare at a serial monitor. &lt;/p&gt;
&lt;p&gt;For years, the options have been a bit of a mixed bag. You have the classic Arduino IDE Serial Monitor (which is functional but basic), bloated GUI protocol analyzers that eat up RAM, or simple CLI tools like &lt;code&gt;minicom&lt;/code&gt; that get the job done but lack modern developer quality-of-life features.&lt;/p&gt;
&lt;p&gt;As someone who lives in the terminal—relying on tools like Neovim and terminal multiplexers—I wanted a serial monitor that actually fit into a keyboard-driven, modern workflow. I wanted something lightweight, visually clean, and capable of handling complex data without breaking a sweat.&lt;/p&gt;
&lt;p&gt;So, I built &lt;strong&gt;ComChan&lt;/strong&gt; (Communication Channel).&lt;/p&gt;
&lt;h4 id=&quot;what-is-comchan-&quot;&gt;What is ComChan?&lt;/h4&gt;
&lt;p&gt;ComChan is a minimal, blazingly fast serial monitor and plotter built entirely in Rust. It’s designed specifically for embedded systems engineers who want powerful data visualization and logging without leaving the command line. &lt;/p&gt;
&lt;p&gt;Because it's written in Rust, it’s memory-safe, incredibly fast, and runs natively across Linux, Windows, and macOS. &lt;/p&gt;
&lt;p&gt;Here is a look at the features that make ComChan stand out from the crowd.&lt;/p&gt;
&lt;h4 id=&quot;1-the-terminal-based-serial-plotter&quot;&gt;1. The Terminal-Based Serial Plotter&lt;/h4&gt;
&lt;p&gt;Sometimes, raw text isn't enough. When you are debugging an IMU, reading ADC values, or tracking temperature sensors, you need to see the data visually. &lt;/p&gt;
&lt;p&gt;Instead of exporting data to Excel or firing up a heavy GUI application, ComChan features a built-in TUI (Terminal User Interface) plotter. You simply pass the &lt;code&gt;--plot&lt;/code&gt; flag, and ComChan will automatically parse your incoming numeric data, assign legends, and graph multiple sensor channels in real-time—right inside your terminal.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=15727656772548640252&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;Found a spike you want to investigate? You can hit &lt;code&gt;Ctrl+S&lt;/code&gt; to instantly export the current plot frame as a clean SVG file.&lt;/p&gt;
&lt;p&gt;Here is how it'll look like &lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=2420146948092194581&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h4 id=&quot;2-time-travel-with-session-replay&quot;&gt;2. Time Travel with Session Replay&lt;/h4&gt;
&lt;p&gt;This is perhaps my favorite feature. Debugging intermittent hardware anomalies is a nightmare because you can't always recreate the exact physical conditions that caused the bug.&lt;/p&gt;
&lt;p&gt;ComChan introduces &lt;strong&gt;Session Replay&lt;/strong&gt;. You can log your raw serial output to a &lt;code&gt;.log&lt;/code&gt; or &lt;code&gt;.csv&lt;/code&gt; file during a test run. Later, you can run &lt;code&gt;comchan --replay &amp;lt;file&amp;gt;&lt;/code&gt; and the tool will parse the timestamps and play the data back to you in &lt;em&gt;real-time&lt;/em&gt;. &lt;/p&gt;
&lt;p&gt;It perfectly recreates the exact timing of the original hardware run. You can even replay a log file directly into the visual Plotter to analyze the anomaly visually, without needing the physical microcontroller plugged in.&lt;/p&gt;
&lt;h4 id=&quot;3-continuous-csv-streaming&quot;&gt;3. Continuous CSV Streaming&lt;/h4&gt;
&lt;p&gt;If you are doing data collection for research or analysis, ComChan can automatically parse your incoming numeric telemetry and stream it directly into a clean, multi-column &lt;code&gt;.csv&lt;/code&gt; file on the fly. &lt;/p&gt;
&lt;p&gt;The best part? This works concurrently. You can stream to a CSV in the background while actively watching the data on the TUI Plotter.&lt;/p&gt;
&lt;h4 id=&quot;4-built-for-the-modern-embedded-workflow&quot;&gt;4. Built for the Modern Embedded Workflow&lt;/h4&gt;
&lt;p&gt;ComChan includes several smaller features designed specifically to remove friction from the embedded workflow:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Auto-Detection:&lt;/strong&gt; Tired of typing &lt;code&gt;/dev/ttyUSB0&lt;/code&gt; or &lt;code&gt;COM3&lt;/code&gt;? Just use &lt;code&gt;comchan --auto&lt;/code&gt; and it will automatically find and connect to your active USB serial device.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Zephyr RTOS Support:&lt;/strong&gt; If you work with Zephyr, ComChan has a dedicated &lt;code&gt;--zephyr&lt;/code&gt; shell mode that handles its specific echo and prompt behaviors cleanly.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Auto-Recovery:&lt;/strong&gt; If you accidentally unplug your device or reset the power, ComChan won't crash. It detects the broken pipe and gracefully waits to reconnect when the hardware comes back online.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Configuration Files:&lt;/strong&gt; Save your favorite baud rates, data bits, and parity settings in a &lt;code&gt;.toml&lt;/code&gt; file so you don't have to pass a dozen flags every time you launch.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;the-brain-made-philosophy&quot;&gt;The &quot;Brain Made&quot; Philosophy&lt;/h4&gt;
&lt;p&gt;While AI tools are great for scaffolding tests or micro-optimizations, the core architecture, TUI design, and feature logic of ComChan are entirely human-crafted. It’s built to solve real pain points that I experience daily when working with memory-safe embedded development on ESP32s and RP2040s.&lt;/p&gt;
&lt;h4 id=&quot;try-it-out-1&quot;&gt;Try It Out&lt;/h4&gt;
&lt;p&gt;If you are ready to upgrade your embedded debugging workflow, ComChan is incredibly easy to install.&lt;/p&gt;
&lt;p&gt;If you have Cargo installed:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cargo install comchan
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For Arch Linux users, it's available on the AUR:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;yay -S comchan
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can check out the full source code, read the documentation, and contribute on GitHub: &lt;strong&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Vaishnav-Sabari-Girish/ComChan&quot;&gt;Vaishnav-Sabari-Girish/ComChan&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Drop a star if you find it useful, and let me know what features you’d like to see next (a Hex Dump mode is already on the roadmap!). Happy debugging!&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/17983/ditch-the-clunky-guis-meet-comchan-the-blazingly-fast-rust-serial-monitor</guid>
<pubDate>Fri, 15 May 2026 15:58:16 +0000</pubDate>
</item>
<item>
<title>I Built fintech-fraud-sim: A TypeScript CLI for Synthetic Fraud Testing Data</title>
<link>https://coderlegion.com/17768/i-built-fintech-fraud-sim-a-typescript-cli-for-synthetic-fraud-testing-data</link>
<description>&lt;p&gt;Fraud systems are hard to test well.&lt;/p&gt;
&lt;p&gt;Not because engineers cannot write tests, but because the data needs to tell a story. A suspicious transaction is rarely suspicious because of one field. It is usually suspicious because of patterns:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a new account with too many beneficiaries&lt;/li&gt;
&lt;li&gt;many transactions in a short window&lt;/li&gt;
&lt;li&gt;failed logins followed by a device change&lt;/li&gt;
&lt;li&gt;KYC failures mixed with country mismatches&lt;/li&gt;
&lt;li&gt;transaction amounts far above normal behavior&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Using production customer data for this is risky and often unacceptable. Basic mock data is usually too flat.&lt;/p&gt;
&lt;p&gt;So I built &lt;code&gt;fintech-fraud-sim&lt;/code&gt;, a TypeScript CLI that generates synthetic fintech users and transactions with configurable fraud patterns.&lt;/p&gt;
&lt;p&gt;NPM package: &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.npmjs.com/package/fintech-fraud-sim&quot;&gt;https://www.npmjs.com/package/fintech-fraud-sim&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;quick-start&quot;&gt;Quick Start&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx fintech-fraud-sim generate --users 1000 --fraud-rate 0.08
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That command generates:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;users.csv
transactions.csv
users.json
transactions.json
summary.json
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can also choose a format:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx fintech-fraud-sim generate --users 5000 --fraud-rate 0.12 --format csv
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or send output to a folder:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx fintech-fraud-sim generate --users 2000 --fraud-rate 0.05 --format json --out ./data
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;why-i-built-it-1&quot;&gt;Why I Built It&lt;/h3&gt;
&lt;p&gt;Fraud detection products need test data in many places:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;dashboards&lt;/li&gt;
&lt;li&gt;QA fixtures&lt;/li&gt;
&lt;li&gt;rules engines&lt;/li&gt;
&lt;li&gt;risk scoring services&lt;/li&gt;
&lt;li&gt;transaction monitoring demos&lt;/li&gt;
&lt;li&gt;analytics pipelines&lt;/li&gt;
&lt;li&gt;prototype fraud models&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;But realistic fraud test data is not just random rows. It needs consistent signals across users and transactions.&lt;/p&gt;
&lt;p&gt;For example, an account takeover scenario should not only mark a transaction as suspicious. The user should also show supporting signals such as failed logins, device changes, and country mismatch.&lt;/p&gt;
&lt;p&gt;That is the idea behind this CLI.&lt;/p&gt;
&lt;h3 id=&quot;what-the-data-looks-like&quot;&gt;What the Data Looks Like&lt;/h3&gt;
&lt;p&gt;Generated users include fields like:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;user_id
country
account_age_days
kyc_status
failed_kyc_attempts
device_count
ip_country
declared_country
failed_login_attempts_24h
beneficiary_count_24h
chargeback_count
is_fraud
fraud_pattern
risk_label
reason_codes
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Generated transactions include:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;transaction_id
user_id
timestamp
amount
currency
channel
beneficiary_id
beneficiary_country
device_id
ip_country
status
is_suspicious
fraud_pattern
reason_codes
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The package does not generate real names, emails, phone numbers, BVNs, NINs, or bank account numbers.&lt;/p&gt;
&lt;h3 id=&quot;supported-fraud-patterns&quot;&gt;Supported Fraud Patterns&lt;/h3&gt;
&lt;p&gt;The CLI currently supports:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Pattern &lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;mule_account&lt;/code&gt; &lt;/td&gt;&lt;td&gt;New account, high beneficiary count, rapid funds movement&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;account_takeover&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Device change, country mismatch, failed login spike&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;velocity_abuse&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Many transactions in a short period&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;kyc_abuse&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Multiple failed KYC attempts and inconsistent country data&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;chargeback_risk&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Prior chargebacks and high-value transactions&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;transaction_spike&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Amount far above user baseline&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;cross_border_anomaly&lt;/code&gt; &lt;/td&gt;&lt;td&gt;IP or beneficiary country mismatch&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;code&gt;beneficiary_burst&lt;/code&gt; &lt;/td&gt;&lt;td&gt;Many new beneficiaries within 24 hours&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;You can select specific patterns:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx fintech-fraud-sim generate \
  --users 1000 \
  --fraud-rate 0.08 \
  --patterns mule,account_takeover,velocity_abuse
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;code&gt;mule&lt;/code&gt; is accepted as an alias for &lt;code&gt;mule_account&lt;/code&gt;.&lt;/p&gt;
&lt;h3 id=&quot;deterministic-generation&quot;&gt;Deterministic Generation&lt;/h3&gt;
&lt;p&gt;For tests and demos, deterministic output is important.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx fintech-fraud-sim generate --users 1000 --fraud-rate 0.08 --seed demo
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The same seed produces the same dataset, which makes the CLI useful in CI and repeatable test suites.&lt;/p&gt;
&lt;h3 id=&quot;testing&quot;&gt;Testing&lt;/h3&gt;
&lt;p&gt;The project includes tests for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;generating users and transactions&lt;/li&gt;
&lt;li&gt;fraud rate handling&lt;/li&gt;
&lt;li&gt;seeded deterministic output&lt;/li&gt;
&lt;li&gt;zero fraud rate behavior&lt;/li&gt;
&lt;li&gt;fraud pattern logic&lt;/li&gt;
&lt;li&gt;CSV and JSON writers&lt;/li&gt;
&lt;li&gt;CLI execution&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npm test
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The test suite uses Node's built-in test runner with &lt;code&gt;tsx&lt;/code&gt;, so TypeScript tests can run directly.&lt;/p&gt;
&lt;h3 id=&quot;example-use-cases&quot;&gt;Example Use Cases&lt;/h3&gt;
&lt;p&gt;You can use the generated data to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;demo fraud dashboards&lt;/li&gt;
&lt;li&gt;test transaction monitoring rules&lt;/li&gt;
&lt;li&gt;validate CSV import workflows&lt;/li&gt;
&lt;li&gt;build realistic QA fixtures&lt;/li&gt;
&lt;li&gt;prototype risk scoring logic&lt;/li&gt;
&lt;li&gt;test data pipelines without exposing customer records&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;safety-disclaimer&quot;&gt;Safety Disclaimer&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;fintech-fraud-sim&lt;/code&gt; is for testing, education, and fraud-model prototyping only. It generates synthetic data and should not be treated as real customer data or used as a production fraud decisioning system.&lt;/p&gt;
&lt;h3 id=&quot;final-thoughts&quot;&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;Good fraud testing needs more than random transactions. It needs plausible behavior.&lt;/p&gt;
&lt;p&gt;This CLI is my attempt to make that easier for fintech builders, QA teams, and engineers working on risk systems.&lt;/p&gt;
&lt;p&gt;NPM: &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.npmjs.com/package/fintech-fraud-sim&quot;&gt;https://www.npmjs.com/package/fintech-fraud-sim&lt;/a&gt;&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/17768/i-built-fintech-fraud-sim-a-typescript-cli-for-synthetic-fraud-testing-data</guid>
<pubDate>Wed, 13 May 2026 20:40:17 +0000</pubDate>
</item>
<item>
<title>wmux: Run Claude Code, Codex, and Gemini CLI Side by Side on Windows</title>
<link>https://coderlegion.com/17655/wmux-run-claude-code-codex-and-gemini-cli-side-by-side-on-windows</link>
<description>&lt;h3 id=&quot;tl-dr&quot;&gt;TL;DR&lt;/h3&gt;
&lt;p&gt;If you're coding on Windows and juggling multiple AI CLI agents in a single terminal window — stop. &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/openwong2kim/wmux&quot;&gt;wmux&lt;/a&gt; is a native Windows terminal multiplexer that lets you run &lt;strong&gt;Claude Code, Codex, and Gemini CLI side by side&lt;/strong&gt;, with built-in browser automation, an MCP server, and real session persistence. No WSL required.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;winget install openwong2kim.wmux
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That's it. 30 seconds and you're done.&lt;/p&gt;
&lt;h3 id=&quot;the-problem-1&quot;&gt;The problem&lt;/h3&gt;
&lt;p&gt;macOS devs have had &lt;code&gt;cmux&lt;/code&gt; — a tmux-based terminal multiplexer tuned for AI agents — for a while now. Windows devs? We've been stuck with a single terminal tab, Alt+Tabbing between agents, spamming &quot;are you done yet?&quot; into the void.&lt;/p&gt;
&lt;p&gt;You could use WSL, sure. But then your PowerShell scripts, Windows-native toolchains, and ConPTY-aware TUIs (hi, Claude Code) start to feel awkward.&lt;/p&gt;
&lt;p&gt;wmux fills that gap. It's a &lt;strong&gt;native Windows&lt;/strong&gt; multiplexer built on ConPTY, xterm.js with WebGL rendering, and Electron. No VM, no Linux emulation, no weird path translation.&lt;/p&gt;
&lt;h3 id=&quot;what-it-actually-feels-like&quot;&gt;What it actually feels like&lt;/h3&gt;
&lt;p&gt;Picture this layout on one screen:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Left pane&lt;/strong&gt;: Claude Code writing your backend&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Right pane&lt;/strong&gt;: Codex scaffolding the frontend&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bottom pane&lt;/strong&gt;: Gemini CLI running the test suite&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Floating pane&lt;/strong&gt;: A Quake-style dropdown terminal for quick &lt;code&gt;git status&lt;/code&gt; checks&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;Ctrl+D&lt;/code&gt; splits right. &lt;code&gt;Ctrl+Shift+D&lt;/code&gt; splits down. &lt;code&gt;Ctrl+N&lt;/code&gt; opens a new workspace. &lt;code&gt;Ctrl+1~9&lt;/code&gt; jumps between them. &lt;code&gt;Ctrl+click&lt;/code&gt; stitches multiple workspaces into a multiview grid. If you're a tmux person, &lt;code&gt;Ctrl+B&lt;/code&gt; gives you a prefix mode with 13 rebindable actions.&lt;/p&gt;
&lt;h3 id=&quot;the-part-that-actually-sold-me-browser-control&quot;&gt;The part that actually sold me: browser control&lt;/h3&gt;
&lt;p&gt;Tell Claude Code &lt;em&gt;&quot;search Google for wmux&quot;&lt;/em&gt; and it actually does it. Not via shelling out to &lt;code&gt;curl&lt;/code&gt;. Not by pretending. wmux exposes a built-in browser panel connected over the &lt;strong&gt;Chrome DevTools Protocol&lt;/strong&gt;, and the MCP server exposes tools like:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;What Claude does &lt;/th&gt;&lt;th&gt;MCP tool&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Open browser &lt;/td&gt;&lt;td&gt;&lt;code&gt;browser_open&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Read page structure &lt;/td&gt;&lt;td&gt;&lt;code&gt;browser_snapshot&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Click element &lt;/td&gt;&lt;td&gt;&lt;code&gt;browser_click&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Fill form &lt;/td&gt;&lt;td&gt;&lt;code&gt;browser_fill&lt;/code&gt; / &lt;code&gt;browser_type&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Press key &lt;/td&gt;&lt;td&gt;&lt;code&gt;browser_press_key&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Run JS &lt;/td&gt;&lt;td&gt;&lt;code&gt;browser_evaluate&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Screenshot &lt;/td&gt;&lt;td&gt;&lt;code&gt;browser_screenshot&lt;/code&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;So a prompt like &quot;search for wmux on Google&quot; becomes:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-plaintext&quot;&gt;browser_open → browser_snapshot → browser_fill(ref=13, &quot;wmux&quot;) → browser_press_key(&quot;Enter&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And it &lt;em&gt;works&lt;/em&gt;. Even with React controlled inputs and CJK text — both of which love to break naive automation.&lt;/p&gt;
&lt;p&gt;Every browser tool accepts a &lt;code&gt;surfaceId&lt;/code&gt;, so each Claude Code session drives its own browser. Run three agents, get three browsers, zero cross-talk.&lt;/p&gt;
&lt;h3 id=&quot;agent-to-agent-messaging&quot;&gt;Agent-to-agent messaging&lt;/h3&gt;
&lt;p&gt;This is the fun one. wmux exposes &lt;code&gt;a2a_send&lt;/code&gt;, &lt;code&gt;a2a_broadcast&lt;/code&gt;, &lt;code&gt;a2a_task_send&lt;/code&gt;, and friends. Your Claude Code instance on the left can literally ping your Codex instance on the right:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&quot;Hey, I changed the API response shape, regenerate the TypeScript types.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That's not a demo — that's Tuesday.&lt;/p&gt;
&lt;h3 id=&quot;stop-babysitting-your-agents&quot;&gt;Stop babysitting your agents&lt;/h3&gt;
&lt;p&gt;wmux watches terminal output throughput (not brittle pattern matching) and fires desktop notifications + taskbar flashes when:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;A task finishes&lt;/li&gt;
&lt;li&gt;A process exits abnormally&lt;/li&gt;
&lt;li&gt;A dangerous command shows up (&lt;code&gt;git push --force&lt;/code&gt;, &lt;code&gt;rm -rf&lt;/code&gt;, &lt;code&gt;DROP TABLE&lt;/code&gt;…)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Go make coffee. wmux will tell you when to come back.&lt;/p&gt;
&lt;h3 id=&quot;session-persistence-that-actually-persists&quot;&gt;Session persistence that actually persists&lt;/h3&gt;
&lt;p&gt;Close wmux. Reopen it. Your sessions are still there, 999K lines of scrollback intact, in the right working directory.&lt;/p&gt;
&lt;p&gt;Reboot your machine. Same thing. A background daemon keeps PTY processes alive, dumps scrollback to disk, and auto-starts on login.&lt;/p&gt;
&lt;p&gt;This is the part tmux users have been quietly missing on Windows for years.&lt;/p&gt;
&lt;h3 id=&quot;security-i-didn-t-have-to-ask-for&quot;&gt;Security I didn't have to ask for&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Token auth on every IPC pipe&lt;/li&gt;
&lt;li&gt;SSRF protection (blocks private IPs, &lt;code&gt;file://&lt;/code&gt;, &lt;code&gt;javascript:&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;PTY input sanitization&lt;/li&gt;
&lt;li&gt;Randomized CDP port (no fixed &lt;code&gt;--remote-debugging-port=9222&lt;/code&gt; for anyone to hijack)&lt;/li&gt;
&lt;li&gt;Memory pressure watchdog (reaps dead sessions at 750MB, blocks new ones at 1GB)&lt;/li&gt;
&lt;li&gt;Electron Fuses locked down (RunAsNode disabled, cookie encryption on)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For a tool that hands AI agents a browser and a shell, this is the bare minimum — and wmux actually does it.&lt;/p&gt;
&lt;h3 id=&quot;the-rest-of-the-goodies&quot;&gt;The rest of the goodies&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;xterm.js + WebGL GPU rendering&lt;/li&gt;
&lt;li&gt;Unicode 11 width tables (CJK/emoji actually render correctly in TUIs)&lt;/li&gt;
&lt;li&gt;Shell integration via OSC 133 — &lt;code&gt;terminal_read_events&lt;/code&gt; gives agents &lt;em&gt;semantic&lt;/em&gt; command boundaries, not raw bytes&lt;/li&gt;
&lt;li&gt;Regex search (&lt;code&gt;Ctrl+F&lt;/code&gt;), Vi copy mode (&lt;code&gt;Ctrl+Shift+X&lt;/code&gt;), scroll bookmarks (&lt;code&gt;Ctrl+M&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Smart right-click: selection → copy, empty area → paste, link → Open/Copy menu&lt;/li&gt;
&lt;li&gt;Layout templates you can save and restore from the command palette&lt;/li&gt;
&lt;li&gt;Themes: Catppuccin Mocha, Monochrome, Sandstone&lt;/li&gt;
&lt;li&gt;i18n: English, Korean, Japanese, Chinese&lt;/li&gt;
&lt;li&gt;Auto-update via GitHub Releases&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Agent detection covers Claude Code, Cursor, Aider, Codex CLI, Gemini CLI, OpenCode, and GitHub Copilot CLI out of the box.&lt;/p&gt;
&lt;h3 id=&quot;install-1&quot;&gt;Install&lt;/h3&gt;
&lt;p&gt;Pick your poison:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-powershell&quot;&gt;# winget (recommended)
winget install openwong2kim.wmux

# Chocolatey
choco install wmux

# PowerShell one-liner
irm https://raw.githubusercontent.com/openwong2kim/wmux/main/install.ps1 | iex
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Or grab &lt;code&gt;wmux Setup.exe&lt;/code&gt; from the &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/openwong2kim/wmux&quot;&gt;releases page&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;final-thought&quot;&gt;Final thought&lt;/h3&gt;
&lt;p&gt;Windows devs have been the second-class citizens of the AI coding agent world for a minute. wmux doesn't fix everything — but running three agents on one screen, each with its own browser, talking to each other, surviving reboots? That's a genuinely different workflow.&lt;/p&gt;
&lt;p&gt;Repo: &lt;strong&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/openwong2kim/wmux&quot;&gt;github.com/openwong2kim/wmux&lt;/a&gt;&lt;/strong&gt; — MIT licensed.&lt;/p&gt;
&lt;p&gt;If you try it, I'd love to hear which layout you end up with. Mine is Claude-left / Codex-right / Gemini-bottom, and a floating terminal for &lt;code&gt;git&lt;/code&gt;. What's yours?&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/17655/wmux-run-claude-code-codex-and-gemini-cli-side-by-side-on-windows</guid>
<pubDate>Tue, 12 May 2026 23:49:25 +0000</pubDate>
</item>
<item>
<title>&quot;Why .NET 9’s CLI is the Glow-up your workflow deserved&quot;</title>
<link>https://coderlegion.com/16699/why-net-9s-cli-is-the-glow-up-your-workflow-deserved</link>
<description>&lt;p&gt;&lt;strong&gt;&quot;From Boring White Text to a Dev Experience That Actually Doesn’t Hurt to Look At&quot;.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Let’s be real: for years, the .NET CLI felt like that one reliable but incredibly dull friend. It got the job done, but it had the personality of a spreadsheet. If you’re jumping from .NET 7 or 8, you’re in for a shock. Microsoft finally realized that we spend 90% of our lives staring at a terminal, so they decided to make it look—and feel—like it belongs in 2026.&lt;/p&gt;
&lt;p&gt;Here is why you, as a Senior Dev, should actually care about the .NET 9 CLI.&lt;/p&gt;
&lt;h3 id=&quot;1-the-visual-soul-goodbye-walls-of-text&quot;&gt;1. The &quot;Visual Soul&quot;: Goodbye, Walls of Text&lt;/h3&gt;
&lt;p&gt;The first thing you’ll notice isn’t a new feature; it’s the Terminal Logger. While it started appearing in .NET 8, in .NET 9 it’s the default, and it is polished.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Progress Bars that actually move: No more guessing if dotnet build is hanging or just thinking.&lt;/li&gt;
&lt;li&gt;Clickable Links: Errors now come with direct, clickable links to documentation. &lt;/li&gt;
&lt;li&gt;Color-Coded Chaos: Warnings are yellow, errors are red, and successes&lt;br&gt;
are a satisfying green. It sounds minor, but in a massive&lt;br&gt;
microservices build, your eyes will thank you.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Depending on your terminal (like Windows Terminal or Oh My Posh), you’ll see icons for different project types and build stages.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pro Tip:&lt;/strong&gt; Use dotnet build --tl (Terminal Logger) explicitly if you’re on a legacy system, but on .NET 9, it’s just there.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=8167650038085573077&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;2-automation-amp-buildchecks-the-senior-s-safety-net&quot;&gt;2. Automation &amp;amp; &quot;BuildChecks&quot;: The Senior’s Safety Net&lt;/h3&gt;
&lt;p&gt;This is where it gets interesting for those of us managing large codebases. .NET 9 introduces BuildChecks.&lt;/p&gt;
&lt;p&gt;Imagine having a linter, but for your .csproj and build logic.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What it does: It analyzes your build process for regressions or &quot;smelly&quot; configurations.&lt;/li&gt;
&lt;li&gt;The Command: dotnet build /check&lt;/li&gt;
&lt;li&gt;Why it’s useful: It catches things like &quot;Custom task X is slowing&lt;br&gt;
down the build&quot; or &quot;You’re using a deprecated MSBuild property.&quot; It’s&lt;br&gt;
basically a code review for your infrastructure.&lt;/li&gt;
&lt;li&gt;Git Integration: The CLI is Aware&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The .NET 9 CLI is now much more &quot;Git-aware.&quot; When you run dotnet new, the SDK automatically detects if you're in a Git repo and can initialize .gitignore files that are actually updated for modern .NET workloads (including stuff for DevContainers and GitHub Actions).&lt;/p&gt;
&lt;p&gt;Also, the dotnet workload history command is a lifesaver. If a teammate says, &quot;It works on my machine,&quot; you can now check exactly what version of the workloads (MAUI, Aspire, etc.) were installed and when they were updated, making environment parity much easier to debug.&lt;/p&gt;
&lt;h3 id=&quot;4-cloud-native-amp-docker-the-no-dockerfile-revolution&quot;&gt;4. Cloud-Native &amp;amp; Docker: The &quot;No-Dockerfile&quot; Revolution&lt;/h3&gt;
&lt;p&gt;You’re a Senior. You know how to write a Dockerfile. But do you want to?&lt;/p&gt;
&lt;p&gt;.NET 9 pushes SDK-based Containerization to the limit. You can now publish a fully optimized, secured, and shrunk Docker image without ever touching a Dockerfile.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dotnet publish /t:PublishContainer -c Release
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;What’s new here?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Non-root by default: Security is baked in. Images run as a non-privileged user automatically.&lt;/li&gt;
&lt;li&gt;Insecure Registries: The CLI now supports pushing to insecure local&lt;br&gt;
registries (great for local K8s testing) without hacking your Docker&lt;br&gt;
config. &lt;/li&gt;
&lt;li&gt;Architecture targeting: Easily cross-compile for ARM64 (Graviton/M1) from an x64 machine using just CLI flags.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=7471657151849509597&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;-5-azure-amp-aspire-the-secret-sauce-&quot;&gt; 5. Azure &amp;amp; Aspire: The &quot;Secret Sauce&quot;&lt;/h3&gt;
&lt;p&gt;If you aren't using .NET Aspire yet, .NET 9 is the sign you were waiting for. The CLI integration with Azure via the azd (Azure Dev CLI) and dotnet aspire commands is seamless.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Smart Provisioning: The CLI can now detect your resource requirements from your code and suggest the right Azure infrastructure. &lt;/li&gt;
&lt;li&gt;Deployment: azd up isn't just a gimmick anymore; it uses the .NET 9&lt;br&gt;
SDK to package your apps into container apps with OpenTelemetry&lt;br&gt;
pre-configured.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;6-the-advanced-power-user-commands&quot;&gt;6. The Advanced &quot;Power User&quot; Commands&lt;/h3&gt;
&lt;p&gt;For the automation nerds, these are the commands you’ll be scripting into your CI/CD pipelines:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dotnet test --parallel
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now fully integrated with MSBuild for parallel execution across different Target Frameworks (TFM).&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dotnet workload sets
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Allows you to &quot;lock&quot; a version of the SDK workloads so your whole team stays on the exact same bits.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dotnet tool update
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Faster, cleaner, and handles global vs. local tools with better conflict resolution.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What do I think about this?&lt;/strong&gt;&lt;br&gt;
.NET 9 isn't just about a faster JIT (though it is faster). It's about Developer Joy. The CLI has moved away from being a &quot;black box of text&quot; to a proactive assistant that helps you build, containerize, and deploy without leaving the keyboard.&lt;/p&gt;
&lt;p&gt;If you’re still on .NET 7, you’re essentially working in black and white while the rest of us are in 4K. Time to upgrade.&lt;/p&gt;
&lt;p&gt;By One Garlos P. 2026&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/16699/why-net-9s-cli-is-the-glow-up-your-workflow-deserved</guid>
<pubDate>Tue, 05 May 2026 03:26:28 +0000</pubDate>
</item>
<item>
<title>I built a CLI to test Tauri apps because nothing else worked</title>
<link>https://coderlegion.com/15384/i-built-a-cli-to-test-tauri-apps-because-nothing-else-worked</link>
<description>&lt;p&gt;I spent a weekend trying to set up end-to-end testing for a Tauri v2 app. Two hours into configuring WebdriverIO, I still couldn't get it to connect to the WebView. The official docs show a minimal example that doesn't cover IPC testing. Playwright flat-out doesn't work because Tauri uses WebKitGTK, not Chromium.&lt;/p&gt;
&lt;p&gt;I gave up and wrote my own tool.&lt;/p&gt;
&lt;h3 id=&quot;the-actual-problem&quot;&gt;The actual problem&lt;/h3&gt;
&lt;p&gt;If you search &quot;Tauri e2e testing&quot; on GitHub, you'll find the same question asked over and over. The &lt;a rel=&quot;nofollow&quot; href=&quot;https://v2.tauri.app/develop/tests/&quot;&gt;official docs&lt;/a&gt; split testing into two worlds: Rust unit tests for the backend, and WebDriver-based tests for the frontend. But nobody tells you how to verify that your Tauri IPC commands actually work from the user's perspective. You end up mocking &lt;code&gt;window.__TAURI__&lt;/code&gt; in your frontend tests and hoping production behaves the same way.&lt;/p&gt;
&lt;p&gt;It doesn't always behave the same way.&lt;/p&gt;
&lt;p&gt;What I wanted was simple: connect to a running Tauri app, inspect the UI, click buttons, fill forms, and check that things happened. Like Playwright, but for Tauri. No WebDriver binary. No Selenium. No 200-line config file.&lt;/p&gt;
&lt;h3 id=&quot;what-tauri-pilot-does&quot;&gt;What tauri-pilot does&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/mpiton/tauri-pilot&quot;&gt;tauri-pilot&lt;/a&gt; is a Rust CLI that talks to your Tauri app over a Unix socket. You add a plugin to your app (2 lines, debug builds only), install the CLI, and start testing.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ tauri-pilot snapshot -i
- heading &quot;PR Dashboard&quot; [ref=e1]
- textbox &quot;Search PRs&quot; [ref=e2] value=&quot;&quot;
- button &quot;Refresh&quot; [ref=e3]
- list &quot;PR List&quot; [ref=e4]
  - listitem &quot;fix: resolve memory leak #142&quot; [ref=e5]
  - listitem &quot;feat: add workspace support #138&quot; [ref=e6]
- button &quot;Load More&quot; [ref=e7]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That &lt;code&gt;snapshot&lt;/code&gt; command walks the accessibility tree and gives every interactive element a short ref like &lt;code&gt;@e3&lt;/code&gt;. You use those refs to interact:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ tauri-pilot click @e3
ok

$ tauri-pilot fill @e2 &quot;workspace&quot;
ok

$ tauri-pilot assert text @e1 &quot;PR Dashboard&quot;
ok

$ tauri-pilot assert visible @e7
ok
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Exit code 0 means pass. Exit code 1 means fail with a message. That's it. No test framework to learn.&lt;/p&gt;
&lt;h3 id=&quot;setup-takes-2-minutes&quot;&gt;Setup takes 2 minutes&lt;/h3&gt;
&lt;p&gt;Add the plugin to your Tauri app:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-rust&quot;&gt;// src-tauri/src/main.rs
fn main() {
    let mut builder = tauri::Builder::default();

    #[cfg(debug_assertions)]
    {
        builder = builder.plugin(tauri_plugin_pilot::init());
    }

    builder.run(tauri::generate_context!()).expect(&quot;error running app&quot;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Install the CLI:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cargo install tauri-pilot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run your app in dev mode. That's it. &lt;code&gt;tauri-pilot ping&lt;/code&gt; should respond.&lt;/p&gt;
&lt;p&gt;The plugin only compiles in debug builds. It won't end up in your release binary.&lt;/p&gt;
&lt;h3 id=&quot;why-not-just-use-webdriverio-&quot;&gt;Why not just use WebdriverIO?&lt;/h3&gt;
&lt;p&gt;I tried. Here's what the experience looks like:&lt;/p&gt;
&lt;p&gt;With WebdriverIO, you need to install Node.js dependencies, configure &lt;code&gt;wdio.conf.ts&lt;/code&gt;, point it at your built binary (not the dev server), make sure the WebDriver binary matches your WebKit version, write tests in JavaScript even though your app is in Rust, and deal with flaky selectors that break when your UI changes.&lt;/p&gt;
&lt;p&gt;With tauri-pilot, you run &lt;code&gt;cargo install tauri-pilot&lt;/code&gt;, add 2 lines to your app, and start writing shell commands. The accessibility tree refs (&lt;code&gt;@e1&lt;/code&gt;, &lt;code&gt;@e2&lt;/code&gt;) are stable across renders as long as the element exists. You can use CSS selectors too, or pixel coordinates for edge cases.&lt;/p&gt;
&lt;p&gt;The diff command is something WebdriverIO can't do at all:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;$ tauri-pilot diff -i
+ button &quot;New PR&quot; [ref=e8]
~ list &quot;PR List&quot; [ref=e4]: children 2 → 3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It compares the current UI state to the previous snapshot and shows only what changed. When you're debugging a UI issue, that's worth more than any assertion framework.&lt;/p&gt;
&lt;h3 id=&quot;it-s-built-for-ai-agents&quot;&gt;It's built for AI agents&lt;/h3&gt;
&lt;p&gt;I initially built tauri-pilot so Claude Code could interact with my Tauri apps. The output format is designed for LLM consumption: compact accessibility tree, short refs, plain text responses.&lt;/p&gt;
&lt;p&gt;An AI agent's workflow looks like:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;snapshot -i&lt;/code&gt; to understand the current page&lt;/li&gt;
&lt;li&gt;Pick a ref from the output and interact with it&lt;/li&gt;
&lt;li&gt;&lt;code&gt;assert&lt;/code&gt; to verify the result&lt;/li&gt;
&lt;li&gt;&lt;code&gt;diff -i&lt;/code&gt; to see what changed without re-reading the entire tree (saves tokens)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The &lt;code&gt;--json&lt;/code&gt; flag on every command gives structured output for programmatic use.&lt;/p&gt;
&lt;p&gt;But you don't need an AI agent to benefit from this. I use tauri-pilot directly in bash scripts and interactively while developing. It's faster than clicking through the UI manually when I'm testing a form flow for the fifth time.&lt;/p&gt;
&lt;h3 id=&quot;what-s-in-v0-2-0&quot;&gt;What's in v0.2.0&lt;/h3&gt;
&lt;p&gt;The latest release (just shipped) adds:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Record/replay&lt;/strong&gt; — &lt;code&gt;tauri-pilot record start&lt;/code&gt;, interact with your app, &lt;code&gt;record stop --output test.json&lt;/code&gt;, then &lt;code&gt;replay test.json&lt;/code&gt; to rerun the whole session. Export to a shell script with &lt;code&gt;replay --export sh&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Multi-window support&lt;/strong&gt; — &lt;code&gt;windows&lt;/code&gt; lists all windows, &lt;code&gt;--window&lt;/code&gt; flag targets a specific one.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Form dump&lt;/strong&gt; — &lt;code&gt;forms&lt;/code&gt; grabs all form fields at once instead of calling &lt;code&gt;value&lt;/code&gt; on each input.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;localStorage/sessionStorage access&lt;/strong&gt; — &lt;code&gt;storage get &quot;token&quot;&lt;/code&gt;, &lt;code&gt;storage set &quot;key&quot; &quot;value&quot;&lt;/code&gt;, &lt;code&gt;storage list&lt;/code&gt;, &lt;code&gt;storage clear&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Drag &amp;amp; drop&lt;/strong&gt; — &lt;code&gt;drag @e5 @e6&lt;/code&gt; for sortable lists, &lt;code&gt;drop @e3 --file ./image.png&lt;/code&gt; for file upload zones.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;DOM watch&lt;/strong&gt; — &lt;code&gt;watch&lt;/code&gt; blocks until a DOM mutation happens, then prints a summary. Good for waiting on async updates.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The full changelog is on &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/mpiton/tauri-pilot/blob/main/CHANGELOG.md&quot;&gt;GitHub&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&quot;how-it-works-under-the-hood&quot;&gt;How it works under the hood&lt;/h3&gt;
&lt;p&gt;The plugin starts a Unix socket server when your app launches. The CLI connects to that socket and sends JSON-RPC messages. The plugin injects a JS bridge (&lt;code&gt;window.__PILOT__&lt;/code&gt;) into the WebView that handles DOM inspection.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://i.imgur.com/pntlvzI.jpeg&quot; alt=&quot;tauri-pilot architecture diagram&quot;&gt;&lt;/p&gt;
&lt;p&gt;The tricky part was getting return values from &lt;code&gt;webview.eval()&lt;/code&gt;. In Tauri v2, &lt;code&gt;eval()&lt;/code&gt; is fire-and-forget. There's no way to get a result back directly. So every JS evaluation wraps the script in a try/catch, calls back into Rust via IPC (&lt;code&gt;invoke('plugin:pilot|__callback', {id, result})&lt;/code&gt;), and the Rust side waits on a oneshot channel with a 10-second timeout.&lt;/p&gt;
&lt;p&gt;It works reliably. I've been running it daily for weeks.&lt;/p&gt;
&lt;h3 id=&quot;limitations&quot;&gt;Limitations&lt;/h3&gt;
&lt;p&gt;Linux only for now. Tauri uses WebKitGTK on Linux, WKWebView on macOS, and WebView2 on Windows. The socket and JS bridge approach should work on all platforms, but I haven't tested it. macOS and Windows support is planned.&lt;/p&gt;
&lt;p&gt;The screenshot command uses html-to-image bundled into the JS bridge, which means it captures the WebView content but not native window decorations or system dialogs.&lt;/p&gt;
&lt;p&gt;And it's pre-1.0. The API might change. I'm using semver, so minor bumps can include breaking changes until 1.0.&lt;/p&gt;
&lt;h3 id=&quot;try-it-2&quot;&gt;Try it&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;cargo install tauri-pilot
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;GitHub: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/mpiton/tauri-pilot&quot;&gt;github.com/mpiton/tauri-pilot&lt;/a&gt;&lt;br&gt;
Docs: &lt;a rel=&quot;nofollow&quot; href=&quot;https://mpiton.github.io/tauri-pilot&quot;&gt;mpiton.github.io/tauri-pilot&lt;/a&gt;&lt;br&gt;
crates.io: &lt;a rel=&quot;nofollow&quot; href=&quot;https://crates.io/crates/tauri-plugin-pilot&quot;&gt;crates.io/crates/tauri-plugin-pilot&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you're testing a Tauri v2 app on Linux, give it a shot. Issues and PRs are open.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/15384/i-built-a-cli-to-test-tauri-apps-because-nothing-else-worked</guid>
<pubDate>Tue, 21 Apr 2026 10:31:42 +0000</pubDate>
</item>
<item>
<title>SELinux AVC denied: stop guessing, start fixing</title>
<link>https://coderlegion.com/15125/selinux-avc-denied-stop-guessing-start-fixing</link>
<description>&lt;p&gt;It happens more often than not. A web server gets installed, maybe a database, or perhaps a fresh Podman container. Settings are adjusted carefully, one by one. For testing, permissions shift to &lt;code&gt;777&lt;/code&gt; — though never on live systems — yet somehow the error persists: &lt;strong&gt;Permission denied&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;There it is — buried in the logs. That overwhelming chunk of text from SELinux stares back:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;type=AVC msg=audit(1612345678.123:456): avc:  denied  { read } for  pid=1234 comm=&quot;nginx&quot; name=&quot;index.html&quot; scontext=system_u:system_r:httpd_t:s0 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Right now, many people online suggest simply typing &lt;code&gt;setenforce 0&lt;/code&gt; or turning off SELinux through &lt;code&gt;/etc/selinux/config&lt;/code&gt; without thinking twice. While that might stop the error fast, it weakens system security just to fix a configuration issue. Instead of removing protection entirely, learning what triggered the denial helps find safer fixes.&lt;/p&gt;
&lt;p&gt;Some opt for quick workarounds when logs show repeated denials. Yet skipping analysis often leads to broader risks later on. Adjusting policies carefully beats disabling them outright. A temporary bypass may seem helpful — until something else breaks silently.&lt;/p&gt;
&lt;p&gt;Here’s something worth considering: turning off SELinux strips away critical protection. When it comes to system safety, removing safeguards rarely helps. Rather than silencing warnings, understanding them makes more sense. Think about it: security tools are there for a reason. What if we focused on interpreting alerts instead? That shift could make all the difference.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;the-anatomy-of-an-avc-denial&quot;&gt;The Anatomy of an AVC Denial&lt;/h4&gt;
&lt;p&gt;Imagine a doorkeeper who ignores names, focusing solely on wristbands. That is SELinux — it disregards regular user access levels entirely. Instead, what matters are assigned tags known as Contexts. Entry depends not on identity but on these specific markers. Rules follow the label, never the person behind it.&lt;/p&gt;
&lt;p&gt;Here is what the confusing log actually means:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;comm=&quot;nginx&quot;: A single process moves forward, attempting an action under the name nginx. Like a guest approaching a restricted entrance, it seeks access where entry is controlled.&lt;/li&gt;
&lt;li&gt;{ read }: This refers to the operation it aimed to carry out.&lt;/li&gt;
&lt;li&gt;name=&quot;index.html&quot;: This is the target file or object.&lt;/li&gt;
&lt;li&gt;tclass=file: Indicates what kind of target is being referenced — could be a regular file, a folder, or even a communication endpoint on a network. Each type changes how operations are applied during processing.&lt;/li&gt;
&lt;li&gt;scontext=...:httpd_t:... (Source Context): A process running nginx carries a specific identifier. Labelled as httpd_t, it functions much like an access pass for a visitor. The scontext value reflects what the system sees when checking permissions. Considered part of SELinux enforcement, this tag controls how the process interacts with resources. Assigned automatically, the label determines allowed actions within security policies.&lt;/li&gt;
&lt;li&gt;tcontext=...:user_home_t:... (Target Context): A person enters a space only if they meet certain conditions — this file needs approval just like that guest. Access depends on meeting specific criteria, much like an exclusive area allowing entry under set terms. The tag given to index.html acts as such a gatekeeper, determining who fits inside.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The Translation: Not allowed. A web server process attempted to open index.html marked as personal user data. Security policy blocked it immediately. Home areas stay off-limits to public-facing services by design. Reading such files breaks containment rules. The system enforces strict boundaries between service roles and private spaces. Permission revoked based on labeling mismatch alone.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;slow-fixes-take-time&quot;&gt;Slow Fixes Take Time&lt;/h4&gt;
&lt;p&gt;Most of the time, system administrators handle this issue by searching &lt;code&gt;semanage fcontext&lt;/code&gt; documentation page by page. Another path is feeding the log data into &lt;code&gt;audit2allow&lt;/code&gt; for interpretation.&lt;/p&gt;
&lt;p&gt;Most people misunderstand what &lt;code&gt;audit2allow&lt;/code&gt; actually does: it won’t repair incorrect file labels. Instead, it creates a tailored policy enabling the web server access to home folders. That approach weakens SELinux instead of strengthening it. Usually, the right move involves adjusting the file context through &lt;code&gt;restorecon&lt;/code&gt; or &lt;code&gt;chcon&lt;/code&gt;. Altering system-wide policies rarely makes sense.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;the-fast-way-selinux-explain&quot;&gt;The Fast Way: selinux-explain&lt;/h4&gt;
&lt;p&gt;One day, it just became too much — reading through audit.log by hand, hunting down the right &lt;code&gt;restorecon&lt;/code&gt; or boolean tweaks for messed-up labels. Tools such as &lt;code&gt;setroubleshoot&lt;/code&gt; help, true, yet they bring along Python processes and D-Bus connections. My stripped-down, isolated systems do not run those.&lt;/p&gt;
&lt;p&gt;A small program took shape: &lt;code&gt;selinux-explain&lt;/code&gt; — crafted fully in Rust, running without internet. It works through your terminal, staying fast by design. Built to explain SELinux rules locally, it avoids external dependencies. No cloud needed, just direct responses from your machine.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lszf6ypoevbp5fxx8vlh.gif&quot; alt=&quot;Image description&quot;&gt;&lt;/p&gt;
&lt;p&gt;Most times, people guess what went wrong — here, denied logs go straight in. Once inside, each refusal gets broken down, clear as speech anyone understands. A reason appears without jargon, showing exactly why access failed. From there, a precise instruction forms, tailored to resolve the issue safely.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;key-features-1&quot;&gt;Key Features&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Single static binary: No external libraries required during operation. Runs independently of system-installed components. Entire program contained within a single output. Does not rely on additional software at execution time.&lt;/li&gt;
&lt;li&gt;Offline by default: Works without internet access — ideal for protected networks where external connections are restricted.&lt;/li&gt;
&lt;li&gt;Context-aware: Because it recognizes patterns, containers get the :Z flag automatically. Web services often require specific permissions — this adjusts them without extra steps. For instance, when a server needs network access, the system enables it through policy changes. Knowing typical setups helps avoid common roadblocks. Configuration follows real-world usage rather than rigid rules. Each decision builds on what the environment actually does.&lt;/li&gt;
&lt;li&gt;Extensible: Powered by a community-driven rules.toml file.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&quot;try-it-out-2&quot;&gt;Try it out&lt;/h4&gt;
&lt;p&gt;You can grab the pre-compiled binaries for your architecture on the &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/mattiabandini1/selinux-explain/releases&quot;&gt;GitHub Releases&lt;/a&gt; page.&lt;/p&gt;
&lt;p&gt;When SELinux stops your app, skip typing &lt;code&gt;setenforce 0&lt;/code&gt;. Instead, send the log through selinux-explain — watch how it decodes the message silently. Each error finds clarity without disabling security layers first.&lt;/p&gt;
&lt;p&gt;Should you come across a rare scenario the tool fails to identify, consider submitting a pull request. Alternatively, apply the &lt;code&gt;--report&lt;/code&gt; option to contribute toward growing its collection of rules.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/15125/selinux-avc-denied-stop-guessing-start-fixing</guid>
<pubDate>Sat, 18 Apr 2026 13:32:15 +0000</pubDate>
</item>
<item>
<title>I Published My First npm CLI Tool</title>
<link>https://coderlegion.com/13906/i-published-my-first-npm-cli-tool</link>
<description>&lt;p&gt;Hey folks! &lt;/p&gt;
&lt;p&gt;Let me tell you about &lt;strong&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.npmjs.com/package/create-scaffold-kit&quot;&gt;create-scaffold-kit&lt;/a&gt;&lt;/strong&gt; — what it does, and my experience shipping it for the first time.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;why-does-this-exist-&quot;&gt;Why does this exist?&lt;/h4&gt;
&lt;p&gt;Every new project I start begins the same way:&lt;/p&gt;
&lt;p&gt;ESLint. Prettier. Husky. Docker. CI.&lt;/p&gt;
&lt;p&gt;An hour gone before I even write real code.&lt;/p&gt;
&lt;p&gt;It’s tedious and honestly, it’s the same copy-paste every time.&lt;/p&gt;
&lt;p&gt;So the question became, &lt;em&gt;why not just automate this?&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;what-is-create-scaffold-kit-&quot;&gt;What is create-scaffold-kit?&lt;/h4&gt;
&lt;p&gt;It's a simple CLI tool that scaffolds a &lt;strong&gt;React&lt;/strong&gt; or &lt;strong&gt;Next.js&lt;/strong&gt; project with all the good stuff already set up. Just run one command:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx create-scaffold-kit my-app
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;It asks you a few questions — framework, TypeScript, linting, testing, Docker, CI/CD and generates a full project ready to go.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Things it sets up for you:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;✅ TypeScript (strict mode)&lt;/li&gt;
&lt;li&gt;✅ ESLint with flat config (strict or standard)&lt;/li&gt;
&lt;li&gt;✅ Prettier / OXfmt formatting&lt;/li&gt;
&lt;li&gt;✅ Husky + lint-staged git hooks&lt;/li&gt;
&lt;li&gt;✅ Vitest + React Testing Library&lt;/li&gt;
&lt;li&gt;✅ Tailwind CSS&lt;/li&gt;
&lt;li&gt;✅ Docker with multi-stage builds&lt;/li&gt;
&lt;li&gt;✅ GitHub Actions CI/CD&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;No more copy-pasting configs. Just answer the prompts and start coding.&lt;/p&gt;
&lt;p&gt;This is especially useful if you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Start projects frequently&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Care about consistent tooling&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Don’t want to reinvent setup every time&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&quot;things-i-didn-t-know-before-building-a-cli&quot;&gt;Things I Didn’t Know Before Building a CLI&lt;/h4&gt;
&lt;p&gt;Here are things that were genuinely surprising while going through the process of building a CLI package for the first time. Maybe it saves you some time!&lt;/p&gt;
&lt;h5 id=&quot;1-the-bin-field-in-package-json-is-the-magic&quot;&gt;1. The &lt;code&gt;bin&lt;/code&gt; field in package.json is the magic&lt;/h5&gt;
&lt;p&gt;Always wondered how &lt;code&gt;npx create-something&lt;/code&gt; just... works. Turns out it's this little thing:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;&quot;bin&quot;: {
  &quot;create-scaffold-kit&quot;: &quot;dist/index.js&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That maps the command name to your entry file. Simple, but easy to miss.&lt;/p&gt;
&lt;h5 id=&quot;2-your-entry-file-needs-a-shebang-line&quot;&gt;2. Your entry file needs a shebang line&lt;/h5&gt;
&lt;p&gt;The first line of your CLI entry file must be:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;#!/usr/bin/env node
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Without it, the command just won't run. With &lt;strong&gt;tsup&lt;/strong&gt;, this can be injected cleanly via the &lt;code&gt;banner&lt;/code&gt; option in the config, no manual step needed:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-ts&quot;&gt;banner: {
  js: '#!/usr/bin/env node',
}
&lt;/code&gt;&lt;/pre&gt;
&lt;h5 id=&quot;3-bundling-for-cli-is-different&quot;&gt;3. Bundling for CLI is different&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;tsup&lt;/strong&gt; handles the TypeScript compilation. But a few things stood out:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Setting &lt;code&gt;&quot;type&quot;: &quot;module&quot;&lt;/code&gt; in package.json&lt;/li&gt;
&lt;li&gt;Making sure import paths use &lt;code&gt;.js&lt;/code&gt; extensions, even in TypeScript source files&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;files&lt;/code&gt; field to control what actually gets published to npm&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&quot;4-the-files-field-matters-a-lot&quot;&gt;4. The &lt;code&gt;files&lt;/code&gt; field matters a lot&lt;/h5&gt;
&lt;p&gt;You can control which files get included when running &lt;code&gt;npm publish&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;&quot;files&quot;: [&quot;dist&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Without this, you'd accidentally publish test files, source maps, scripts, everything. Not great.&lt;/p&gt;
&lt;h5 id=&quot;5-prepack-and-postpack-scripts-are-a-thing&quot;&gt;5. &lt;code&gt;prepack&lt;/code&gt; and &lt;code&gt;postpack&lt;/code&gt; scripts are a thing&lt;/h5&gt;
&lt;p&gt;There are &lt;code&gt;prepack&lt;/code&gt;/&lt;code&gt;postpack&lt;/code&gt; lifecycle hooks that run before and after packaging. These weren’t on my radar before this project. Turns out they’re really handy for automating pre-publish steps.&lt;/p&gt;
&lt;h5 id=&quot;6-testing-a-cli-is-interesting&quot;&gt;6. Testing a CLI is... interesting&lt;/h5&gt;
&lt;p&gt;&lt;strong&gt;Vitest&lt;/strong&gt; handles the unit tests here. Testing something that writes to disk and executes shell commands is tricky. Mocking &lt;code&gt;fs&lt;/code&gt;, child processes, and prompts is a different kind of challenge compared to typical frontend component tests.&lt;/p&gt;
&lt;h5 id=&quot;7-publishing-is-both-easy-and-scary-at-the-same-time&quot;&gt;7. Publishing is both easy and scary at the same time&lt;/h5&gt;
&lt;p&gt;&lt;code&gt;npm publish&lt;/code&gt;. Just two words. But right before running it:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&quot;Was everything tested?&quot;&lt;/li&gt;
&lt;li&gt;&quot;Is the version right?&quot;&lt;/li&gt;
&lt;li&gt;&quot;Is the dist clean?&quot;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A &lt;code&gt;prepublishOnly&lt;/code&gt; script that runs type checking, linting, tests, and build before every publish is a lifesaver. It catches things before they go out. &lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;final-thoughts-1&quot;&gt;Final Thoughts&lt;/h4&gt;
&lt;p&gt;This isn’t a groundbreaking tool, but building it gave me a much deeper understanding of the Node.js ecosystem, npm publishing, and how CLI tools actually work under the hood.&lt;/p&gt;
&lt;p&gt;If you're a frontend dev who has never shipped a CLI tool — try it once. Even something small. The learning is worth it.&lt;/p&gt;
&lt;p&gt;And if you give &lt;strong&gt;create-scaffold-kit&lt;/strong&gt; a try, I'd love to hear your thoughts! It’s still early, but it works and is actively evolving..&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;try-it-out-3&quot;&gt;Try it out&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx create-scaffold-kit my-app
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Check out the &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/vkondi/create-scaffold-kit&quot;&gt;GitHub&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Thanks for reading! &lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/13906/i-published-my-first-npm-cli-tool</guid>
<pubDate>Fri, 03 Apr 2026 12:28:31 +0000</pubDate>
</item>
<item>
<title>How to Create a CLI Tool Using Bash: A Practical Guide for Developers</title>
<link>https://coderlegion.com/13137/how-to-create-a-cli-tool-using-bash-a-practical-guide-for-developers</link>
<description>&lt;p&gt;Command line tools are the backbone of productivity for developers, system administrators, and DevOps engineers. From automating repetitive tasks to managing servers efficiently, a well built CLI tool can save hours of manual work.&lt;/p&gt;
&lt;p&gt;If you’ve ever wanted to &lt;strong&gt;build your own CLI tool using Bash&lt;/strong&gt;, this guide will walk you through the process step by step. By the end of this article, you’ll understand how to create a &lt;strong&gt;functional, reusable, and user friendly command line tool&lt;/strong&gt; that you can use in real world projects.&lt;/p&gt;
&lt;p&gt;Whether you're working on &lt;strong&gt;Linux automation, DevOps workflows, or personal productivity tools&lt;/strong&gt;, this tutorial is designed to help you level up.&lt;/p&gt;
&lt;h3 id=&quot;why-build-a-cli-tool-with-bash-&quot;&gt;Why Build a CLI Tool with Bash?&lt;/h3&gt;
&lt;p&gt;Before diving into the code, let’s understand why Bash is still a powerful choice for CLI tools.&lt;/p&gt;
&lt;h4 id=&quot;1-native-to-most-systems&quot;&gt;1. Native to Most Systems&lt;/h4&gt;
&lt;p&gt;Bash comes pre installed on most Unix based systems, including Linux and macOS. This makes your CLI tool &lt;strong&gt;portable and easy to distribute&lt;/strong&gt;.&lt;/p&gt;
&lt;h4 id=&quot;2-perfect-for-automation&quot;&gt;2. Perfect for Automation&lt;/h4&gt;
&lt;p&gt;Bash excels at:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;File manipulation&lt;/li&gt;
&lt;li&gt;Process management&lt;/li&gt;
&lt;li&gt;System monitoring&lt;/li&gt;
&lt;li&gt;Task automation&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;3-lightweight-and-fast&quot;&gt;3. Lightweight and Fast&lt;/h4&gt;
&lt;p&gt;Unlike heavier programming environments, Bash scripts are quick to write and execute with minimal setup.&lt;/p&gt;
&lt;h3 id=&quot;what-you-ll-build&quot;&gt;What You’ll Build&lt;/h3&gt;
&lt;p&gt;In this tutorial, we’ll create a simple CLI tool called:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;devtool
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This tool will:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Accept command line arguments&lt;/li&gt;
&lt;li&gt;Support multiple commands (like &lt;code&gt;greet&lt;/code&gt;, &lt;code&gt;cleanup&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Provide a help menu&lt;/li&gt;
&lt;li&gt;Handle errors gracefully&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;step-1-create-your-script-file&quot;&gt;Step 1: Create Your Script File&lt;/h3&gt;
&lt;p&gt;Start by creating a new Bash script:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;touch devtool.sh
chmod +x devtool.sh
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Add the shebang at the top:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;#!/bin/bash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This tells the system to execute the script using Bash.&lt;/p&gt;
&lt;h3 id=&quot;step-2-add-a-basic-structure&quot;&gt;Step 2: Add a Basic Structure&lt;/h3&gt;
&lt;p&gt;A good CLI tool follows a clear structure.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;#!/bin/bash

# Tool Name: devtool
# Description: A simple CLI tool for automation tasks

show_help() {
    echo &quot;Usage: devtool [command]&quot;
    echo &quot;&quot;
    echo &quot;Commands:&quot;
    echo &quot;  greet        Print a greeting message&quot;
    echo &quot;  cleanup      Remove temporary files&quot;
    echo &quot;  help         Show this help message&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This creates a &lt;strong&gt;help function&lt;/strong&gt;, which is essential for usability and self documentation.&lt;/p&gt;
&lt;h3 id=&quot;step-3-handle-commands&quot;&gt;Step 3: Handle Commands&lt;/h3&gt;
&lt;p&gt;Now let’s process user input using a &lt;code&gt;case&lt;/code&gt; statement.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;COMMAND=$1

case $COMMAND in
    greet)
        echo &quot;Hello, welcome to devtool!&quot;
        ;;
    cleanup)
        echo &quot;Cleaning up temporary files...&quot;
        rm -rf /tmp/*
        echo &quot;Cleanup completed.&quot;
        ;;
    help|--help|-h)
        show_help
        ;;
    *)
        echo &quot;Unknown command: $COMMAND&quot;
        show_help
        ;;
esac
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;why-this-matters&quot;&gt;Why this matters&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;case&lt;/code&gt; makes your CLI tool &lt;strong&gt;clean and scalable&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Easy to add new commands later&lt;/li&gt;
&lt;li&gt;Improves readability compared to multiple &lt;code&gt;if&lt;/code&gt; statements&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;step-4-accept-arguments&quot;&gt;Step 4: Accept Arguments&lt;/h3&gt;
&lt;p&gt;Let’s make the &lt;code&gt;greet&lt;/code&gt; command more dynamic by accepting a name.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;greet_user() {
    NAME=$1

    if [ -z &quot;$NAME&quot; ]; then
        echo &quot;Please provide a name.&quot;
        exit 1
    fi

    echo &quot;Hello, $NAME! Welcome to devtool.&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Update your case block:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;greet)
    greet_user $2
    ;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you can run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./devtool.sh greet Gift
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;step-5-improve-error-handling&quot;&gt;Step 5: Improve Error Handling&lt;/h3&gt;
&lt;p&gt;A professional CLI tool should handle errors gracefully.&lt;/p&gt;
&lt;p&gt;Example:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;if [ $# -eq 0 ]; then
    echo &quot;No command provided.&quot;
    show_help
    exit 1
fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This ensures users always know what went wrong.&lt;/p&gt;
&lt;h3 id=&quot;step-6-make-it-globally-accessible&quot;&gt;Step 6: Make It Globally Accessible&lt;/h3&gt;
&lt;p&gt;To use your CLI tool anywhere, move it into a directory in your system’s PATH.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;mv devtool.sh /usr/local/bin/devtool
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now you can run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;devtool greet Gift
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;from anywhere on your system.&lt;/p&gt;
&lt;h3 id=&quot;step-7-add-colors-for-better-ux-optional-&quot;&gt;Step 7: Add Colors for Better UX (Optional)&lt;/h3&gt;
&lt;p&gt;Make your CLI tool more engaging with colored output.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;GREEN='\033[0;32m'
NC='\033[0m'

echo -e &quot;${GREEN}Operation successful!${NC}&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This improves readability, especially for logs and feedback messages.&lt;/p&gt;
&lt;h3 id=&quot;step-8-organize-like-a-real-tool&quot;&gt;Step 8: Organize Like a Real Tool&lt;/h3&gt;
&lt;p&gt;As your CLI tool grows, structure it properly:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;devtool/
├── devtool.sh
├── commands/
│   ├── greet.sh
│   └── cleanup.sh
└── utils/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This makes your project:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Scalable&lt;/li&gt;
&lt;li&gt;Maintainable&lt;/li&gt;
&lt;li&gt;Easier to collaborate on&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;real-world-use-cases-for-bash-cli-tools&quot;&gt;Real World Use Cases for Bash CLI Tools&lt;/h3&gt;
&lt;p&gt;You can extend your CLI tool to handle real world tasks like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Deploying applications&lt;/li&gt;
&lt;li&gt;Monitoring server health&lt;/li&gt;
&lt;li&gt;Automating backups&lt;/li&gt;
&lt;li&gt;Managing Docker containers&lt;/li&gt;
&lt;li&gt;Running cron jobs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For developers working with &lt;strong&gt;Linux, VPS hosting, or DevOps pipelines&lt;/strong&gt;, Bash CLI tools are incredibly valuable.&lt;/p&gt;
&lt;h3 id=&quot;best-practices-for-building-bash-cli-tools&quot;&gt;Best Practices for Building Bash CLI Tools&lt;/h3&gt;
&lt;p&gt;To ensure your tool is professional and reliable:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Use meaningful function and variable names&lt;/li&gt;
&lt;li&gt;Always include a help command&lt;/li&gt;
&lt;li&gt;Validate user input&lt;/li&gt;
&lt;li&gt;Avoid hardcoding sensitive values&lt;/li&gt;
&lt;li&gt;Log important actions&lt;/li&gt;
&lt;li&gt;Keep scripts modular&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;final-thoughts-2&quot;&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;Creating a CLI tool using Bash is one of the fastest ways to improve your productivity as a developer. With just a few lines of code, you can automate tasks, simplify workflows, and build tools tailored to your needs.&lt;/p&gt;
&lt;p&gt;The beauty of Bash lies in its simplicity. You don’t need complex frameworks or heavy dependencies, just a clear idea and good structure.&lt;/p&gt;
&lt;p&gt;Start small, keep improving, and before long, you’ll have a collection of powerful CLI tools that make your development process faster and more efficient.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;strong&gt;If you found this guide helpful, share it with fellow developers and explore more tutorials on Bash scripting, DevOps, and automation. The more you build, the better you get.&lt;/strong&gt;&lt;/p&gt;
</description>
<category>Tutorials</category>
<guid isPermaLink="true">https://coderlegion.com/13137/how-to-create-a-cli-tool-using-bash-a-practical-guide-for-developers</guid>
<pubDate>Wed, 18 Mar 2026 14:26:07 +0000</pubDate>
</item>
<item>
<title>I built a tiny Linux tool that shouts “FAHH” when I type the wrong command</title>
<link>https://coderlegion.com/12924/i-built-a-tiny-linux-tool-that-shouts-fahh-when-i-type-the-wrong-command</link>
<description>&lt;h2 id=&quot;i-built-a-tiny-linux-tool-that-shouts-fahh-when-i-type-the-wrong-command&quot;&gt;I built a tiny Linux tool that shouts “FAHH” when I type the wrong command&lt;/h2&gt;
&lt;p&gt;A few weeks ago I noticed something about the way I work in the terminal.&lt;/p&gt;
&lt;p&gt;When I’m focused and typing commands fast, I tend to make a lot of small mistakes.&lt;/p&gt;
&lt;p&gt;Wrong command.&lt;br&gt;
Misspelled command.&lt;br&gt;
Sometimes I just type something that doesn't exist.&lt;/p&gt;
&lt;p&gt;And the terminal just replies with the usual:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;command not found
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;That message is… boring.&lt;/p&gt;
&lt;p&gt;And also very easy to ignore.&lt;/p&gt;
&lt;p&gt;So I started thinking:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;What if the terminal could actually &lt;strong&gt;react&lt;/strong&gt; when I type something wrong?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Not visually.&lt;br&gt;
Not with an error popup.&lt;/p&gt;
&lt;p&gt;But with &lt;strong&gt;sound&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Something dramatic.&lt;/p&gt;
&lt;p&gt;Something like:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FAHH.&lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-idea&quot;&gt;The idea&lt;/h3&gt;
&lt;p&gt;I wanted something very simple:&lt;/p&gt;
&lt;p&gt;Whenever I type a command that doesn't exist in the terminal, play a sound.&lt;/p&gt;
&lt;p&gt;Nothing fancy.&lt;br&gt;
Just a tiny reaction that reminds me:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&quot;Hey… that command doesn't exist.&quot;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I initially looked for something like this inside &lt;strong&gt;VSCode extensions&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;There were some interesting ones, but they only worked inside the editor terminal.&lt;/p&gt;
&lt;p&gt;I wanted something that works everywhere:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;WSL  &lt;/li&gt;
&lt;li&gt;Debian  &lt;/li&gt;
&lt;li&gt;normal Linux terminals  &lt;/li&gt;
&lt;li&gt;zsh  &lt;/li&gt;
&lt;li&gt;bash  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Basically &lt;strong&gt;anything I run in the shell&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;So I decided to build a tiny CLI tool for it.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-result&quot;&gt;The result&lt;/h3&gt;
&lt;p&gt;I ended up creating a small tool called:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;fahhctl&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;What it does is very simple.&lt;/p&gt;
&lt;p&gt;When you type a command that doesn't exist:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;fakecommand
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You still see the normal error message:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;command not found: fakecommand
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;But you also hear:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;FAHH &lt;/strong&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;how-it-works-1&quot;&gt;How it works&lt;/h3&gt;
&lt;p&gt;The tool installs a small hook into your shell configuration.&lt;/p&gt;
&lt;p&gt;When the shell detects a command that doesn't exist, it simply runs:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;fahhctl play
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Which plays a sound file.&lt;/p&gt;
&lt;p&gt;That’s it.&lt;/p&gt;
&lt;p&gt;No background process.&lt;br&gt;
No daemon.&lt;br&gt;
Just a tiny hook and a sound.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;installation&quot;&gt;Installation&lt;/h3&gt;
&lt;p&gt;If you're curious and want to try it:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;curl -fsSL https://raw.githubusercontent.com/hamza-topo/fahhctl/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then reload your shell:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;source ~/.zshrc
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now try typing something wrong.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;customize-the-sound&quot;&gt;Customize the sound&lt;/h3&gt;
&lt;p&gt;The default sound is a dramatic &lt;strong&gt;FAHH&lt;/strong&gt;, but you can replace it with anything.&lt;/p&gt;
&lt;p&gt;The sound file lives here:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;~/.local/share/fahh/fahh.mp3
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;So you can replace it with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a meme sound  &lt;/li&gt;
&lt;li&gt;a warning beep  &lt;/li&gt;
&lt;li&gt;a voice saying &quot;wrong command&quot;  &lt;/li&gt;
&lt;li&gt;whatever you want&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;why-i-actually-like-this&quot;&gt;Why I actually like this&lt;/h3&gt;
&lt;p&gt;It sounds silly, but it’s surprisingly useful.&lt;/p&gt;
&lt;p&gt;The sound acts like a &lt;strong&gt;tiny feedback loop&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Instead of silently ignoring mistakes, the terminal gives a quick reaction.&lt;/p&gt;
&lt;p&gt;It helps me stay a bit more focused when I’m typing commands fast.&lt;/p&gt;
&lt;p&gt;Also… it's just fun.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;the-project&quot;&gt;The project&lt;/h3&gt;
&lt;p&gt;If you're curious about the code or want to try it:&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/hamza-topo/fahhctl&quot;&gt;https://github.com/hamza-topo/fahhctl&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It's a very small project, but it was fun to build.&lt;/p&gt;
&lt;p&gt;And sometimes the smallest tools are the most satisfying ones.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/12924/i-built-a-tiny-linux-tool-that-shouts-fahh-when-i-type-the-wrong-command</guid>
<pubDate>Mon, 16 Mar 2026 11:25:23 +0000</pubDate>
</item>
<item>
<title>Autopilot - Ctrl: AI Content Auditing with GitHub Copilot CLI</title>
<link>https://coderlegion.com/12165/autopilot-ctrl-ai-content-auditing-with-github-copilot-cli</link>
<description>&lt;h3 id=&quot;what-i-built&quot;&gt;What I Built&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;autopilot-ctrl&lt;/strong&gt; is a command-line tool that audits AI-generated social media content before publishing. Think of it as a &quot;quality gate&quot; for your content pipeline.&lt;/p&gt;
&lt;h4 id=&quot;the-problem-2&quot;&gt;The Problem&lt;/h4&gt;
&lt;p&gt;My blog has an autopilot system that automatically generates posts for Twitter, LinkedIn, and Newsletter every time I publish an article. It works great... most of the time. But sometimes the AI produces:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Generic tweets without hooks&lt;/li&gt;
&lt;li&gt;LinkedIn posts without proper structure&lt;/li&gt;
&lt;li&gt;Newsletter intros that reveal too much (or too little)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I needed a way to &lt;strong&gt;evaluate quality BEFORE publishing&lt;/strong&gt; and, if something doesn't pass, improve it automatically.&lt;/p&gt;
&lt;h4 id=&quot;the-solution&quot;&gt;The Solution&lt;/h4&gt;
&lt;p&gt;&lt;strong&gt;autopilot-ctrl&lt;/strong&gt; uses GitHub Copilot CLI to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Audit&lt;/strong&gt; content against platform-specific criteria&lt;/li&gt;
&lt;li&gt;Assign a &lt;strong&gt;quality score&lt;/strong&gt; (0-10)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Identify specific issues&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generate improved versions&lt;/strong&gt; of failing content&lt;/li&gt;
&lt;/ol&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;                                 Audit Results                                
┌─────────────┬─────────┬───────────┬─────────────────────────────────────────┐
│ Platform    │  Score  │  Status   │ Issues                                  │
├─────────────┼─────────┼───────────┼─────────────────────────────────────────┤
│ Twitter     │ 3.0/10  │ [XX] FAIL │ No hook, missing hashtags               │
│ Linkedin    │ 7.0/10  │ [OK] PASS │ -                                       │
│ Newsletter  │ 8.0/10  │ [OK] PASS │ -                                       │
└─────────────┴─────────┴───────────┴─────────────────────────────────────────┘
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;demo-1&quot;&gt;Demo&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.youtube.com/watch?v=KNjx5IB8jr8&amp;amp;embeds_referring_euri=https%3A%2F%2Fdatalaria.com%2F&quot;&gt;{{&amp;lt; youtube KNjx5IB8jr8 &amp;gt;}}&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Available commands:&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Check that Copilot CLI is installed
python -m ctrl check

# Audit content
python -m ctrl audit content.json

# Fix failing content
python -m ctrl fix content.json --apply
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Screenshots of the flow:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://datalaria.com/en/posts/ai_agents_part7/PS_Autopilot_Intro.png&quot; alt=&quot;1. Autopilot-Ctrl Introduction&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://datalaria.com/en/posts/ai_agents_part7/PS_Autopilot_Check.png&quot; alt=&quot;2. Copilot CLI Verification&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://datalaria.com/en/posts/ai_agents_part7/PS_Autopilot_SampleContent.png&quot; alt=&quot;3. Sample Content&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://datalaria.com/en/posts/ai_agents_part7/PS_Autopilot_Audit.png&quot; alt=&quot;4. Audit Results&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://datalaria.com/en/posts/ai_agents_part7/PS_Autopilot_Fix.png&quot; alt=&quot;5. Content Improved by Copilot&quot;&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Source code:&lt;/strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Dalaez/datalaria-website&quot;&gt;github.com/Dalaez/datalaria/autopilot/ctrl&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;my-experience-with-github-copilot-cli&quot;&gt;My Experience with GitHub Copilot CLI&lt;/h3&gt;
&lt;h4 id=&quot;how-i-used-copilot-cli&quot;&gt;How I Used Copilot CLI&lt;/h4&gt;
&lt;p&gt;The magic of autopilot-ctrl lies in how it integrates Copilot CLI in non-interactive mode:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;# auditor.py
result = subprocess.run(
    ['copilot', '-s', '--no-ask-user', '-p', prompt],
    capture_output=True,
    text=True,
    timeout=60,
    encoding='utf-8'
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Each audit sends a structured prompt to Copilot CLI and parses the natural language response to extract:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Numeric score (e.g., &quot;Rating: 7/10&quot;)&lt;/li&gt;
&lt;li&gt;List of issues (e.g., &quot;No engagement&quot;, &quot;Generic hook&quot;)&lt;/li&gt;
&lt;li&gt;Improvement suggestions&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;what-i-learned&quot;&gt;What I Learned&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Flag order matters&lt;/strong&gt;: &lt;code&gt;-p&lt;/code&gt; MUST be the last argument&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Simple prompts work better&lt;/strong&gt;: Long, structured prompts in non-interactive mode return empty responses&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Copilot responds in natural language&lt;/strong&gt;: I had to create flexible parsers to extract data from responses like &quot;&lt;strong&gt;Rating: 7/10&lt;/strong&gt;&quot;&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;-the-impact-on-my-workflow&quot;&gt;⚡ The Impact on My Workflow&lt;/h4&gt;
&lt;p&gt;Before autopilot-ctrl, I manually reviewed every generated post. Now:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git push&lt;/code&gt; → Autopilot generates content&lt;/li&gt;
&lt;li&gt;&lt;code&gt;python -m ctrl audit generated_content.json&lt;/code&gt; → Copilot evaluates&lt;/li&gt;
&lt;li&gt;If something fails → &lt;code&gt;python -m ctrl fix&lt;/code&gt; generates improvements&lt;/li&gt;
&lt;li&gt;Approved content → Gets published automatically&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;Time saved&lt;/strong&gt;: ~15 minutes per publication.&lt;/p&gt;
&lt;h4 id=&quot;-tech-stack&quot;&gt;️ Tech Stack&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Python + Click&lt;/strong&gt;: CLI framework&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rich&lt;/strong&gt;: Terminal UI with tables and colors&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Copilot CLI&lt;/strong&gt;: AI evaluation engine&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;YAML configs&lt;/strong&gt;: Customizable prompts per platform&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;autopilot-ctrl demonstrates that GitHub Copilot CLI isn't just for generating code. It's a powerful tool for &lt;strong&gt;integrating AI into any pipeline&lt;/strong&gt; - in this case, content quality evaluation.&lt;/p&gt;
&lt;p&gt;If you have a system that generates content automatically, consider adding a &quot;quality gate&quot; with Copilot CLI. Your audience (and your engagement metrics) will thank you.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Questions?&lt;/strong&gt; Drop them in the comments &lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;This post is part of the &lt;a rel=&quot;nofollow&quot; href=&quot;https://datalaria.com/es/posts/ai_agents_part/&quot;&gt;Autopilot Project&lt;/a&gt; series, where I document how I automate content creation and publishing using AI.&lt;/em&gt;&lt;/p&gt;
</description>
<category>Tutorials</category>
<guid isPermaLink="true">https://coderlegion.com/12165/autopilot-ctrl-ai-content-auditing-with-github-copilot-cli</guid>
<pubDate>Wed, 25 Feb 2026 07:01:27 +0000</pubDate>
</item>
<item>
<title>I built a CLI for the process/port commands I could never remember</title>
<link>https://coderlegion.com/11338/i-built-a-cli-for-the-process-port-commands-i-could-never-remember</link>
<description>&lt;p&gt;If you're like me and you google &lt;code&gt;`&lt;/code&gt;lsof -i :3000 or ps aux | grep node | grep -v grep | awk '{print $2}'&lt;code&gt;`&lt;/code&gt; at least once a month, I built something for you.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# What's on port 3000?
proc on :3000

# Kill it
proc kill :3000

# What ports is node using?
proc on node

# What processes are running in current directory?
proc in .

# Find node processes in current directory
proc by node --in .

# What's running this script?
proc for ./server.py

# Kill multiple things at once
proc kill :3000,:8080,node
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Same syntax everywhere: :port, PID, or name.&lt;/p&gt;
&lt;h2 id=&quot;install-2&quot;&gt;Install&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# macOS
brew install yazeed/proc/proc

# Windows
scoop bucket add proc https://github.com/yazeed/scoop-bucket-proc &amp;amp;&amp;amp; scoop install proc

# Rust
cargo install proc-cli

# npm
npm install -g proc-cli

# Nix
nix profile install github:yazeed/proc

# Or just curl it
curl -fsSL https://raw.githubusercontent.com/yazeed/proc/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id=&quot;links-1&quot;&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;GitHub: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/yazeed/proc&quot;&gt;https://github.com/yazeed/proc&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Written in Rust, works on macOS/Linux/Windows, MIT licensed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Feedback welcome.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/11338/i-built-a-cli-for-the-process-port-commands-i-could-never-remember</guid>
<pubDate>Mon, 09 Feb 2026 23:04:35 +0000</pubDate>
</item>
<item>
<title>How GitHub Copilot Helped Me Roast Its Own Users</title>
<link>https://coderlegion.com/11243/how-github-copilot-helped-me-roast-its-own-users</link>
<description>&lt;blockquote&gt;&lt;p&gt;What if GitHub Copilot didn’t just help you write code but judged you for it?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-i-built-1&quot;&gt;What I Built&lt;/h3&gt;
&lt;p&gt;I had been waiting for a challenge that truly sounded like me for a long time, and that’s when the GitHub Copilot CLI Challenge showed up.&lt;/p&gt;
&lt;p&gt;Within five minutes, the idea that popped into my head was to use Copilot CLI to do something with Copilot itself.&lt;/p&gt;
&lt;p&gt;That’s when the idea of roasting the user for their GitHub Copilot usage came up.&lt;/p&gt;
&lt;p&gt;Then I started wondering how to implement it.&lt;/p&gt;
&lt;p&gt;Whether to build something that runs in the terminal but that would consume RAM.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Should I try a different approach?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That’s when the idea of a VS Code extension popped up (GitHub CLI actually helped me there ).&lt;/p&gt;
&lt;p&gt;This was my first time using an AI pair programmer to help me build a project completely, because I had never built, or even thought about creating a VS Code extension before.&lt;/p&gt;
&lt;p&gt;The roasts are static for now and don’t use AI, because I couldn’t afford an API key .&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;demo-2&quot;&gt;Demo&lt;/h3&gt;
&lt;p&gt;Click the following link:&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://marketplace.visualstudio.com/items?itemName=VigneshJ.copilot-roaster&quot;&gt;Copilot Roaster Extension&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Install the extension using the link.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p8kd7cmoa87g3e4bp5dn.png&quot; alt=&quot;Extenstion&quot;&gt;&lt;/p&gt;
&lt;p&gt;And your setup is complete.&lt;/p&gt;
&lt;p&gt;Then, open any sample file to test it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/z8739gfssiuep4wghrca.png&quot; alt=&quot;Sample File&quot;&gt;&lt;/p&gt;
&lt;p&gt;Ask GitHub Copilot to write something and accept its suggestion to see the magic ✨&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/y256grfxydcbfngkdcru.png&quot; alt=&quot;Copilot Chat&quot;&gt;&lt;/p&gt;
&lt;p&gt;Find my demo below:&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.loom.com/share/e9206dad95044bdba7127ad198710722&quot;&gt;Demo&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;You can find the GitHub repository &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Vignesh025/copilot-roast-extension&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Feel free to fork, modify, and upgrade it.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;my-experience-with-github-copilot-cli-1&quot;&gt;My Experience with GitHub Copilot CLI&lt;/h3&gt;
&amp;lt;!-- Explain how you used GitHub Copilot CLI while building your project and how it impacted your development experience. --&amp;gt;
&lt;p&gt;This was my first time using an AI pair programmer in the CLI. I was really excited to see how it worked. After installing it and typing copilot in the terminal, it felt like magic when this showed up.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vre4uytrbplpzkp3dzed.png&quot; alt=&quot;Copilot CLI&quot;&gt;&lt;/p&gt;
&lt;p&gt;I started wondering how it would work,  which subscription it would use and which profile it would be linked to.&lt;/p&gt;
&lt;p&gt;While thinking about all this, I typed a prompt, and that’s when I got an error saying I needed to log in to proceed further.&lt;/p&gt;
&lt;p&gt;First, we need to use /login to sign in with our GitHub account.&lt;/p&gt;
&lt;p&gt;After that, everything was smooth. The suggestions were almost exactly what I expected (maybe my prompt was too good ).&lt;/p&gt;
&lt;p&gt;Then I tweaked things a bit, and tadaaa &lt;/p&gt;
&lt;p&gt;The extension was ready and looked cool.&lt;/p&gt;
&lt;p&gt;I added a few more roasts just to make sure the same ones didn’t repeat.&lt;/p&gt;
&lt;p&gt;Then I published it on the Marketplace.&lt;/p&gt;
&lt;p&gt;GitHub Copilot CLI provided me with the exact steps to publish the extension, because I had no clue how to do it and the whole process was smooth as well.&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;So go ahead, install the extension, let Copilot write your code, and brace yourself… because this time, you’re the one getting reviewed &lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Follow me on&lt;/em&gt;&lt;/strong&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.linkedin.com/in/vigneshj-&quot;&gt;&lt;em&gt;Linkedin&lt;/em&gt;&lt;/a&gt; | &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Vignesh025&quot;&gt;&lt;em&gt;GitHub&lt;/em&gt;&lt;/a&gt; | &lt;a rel=&quot;nofollow&quot; href=&quot;https://x.com/vigneshtwt_&quot;&gt;&lt;em&gt;Twitter&lt;/em&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Subscribe to my &lt;a rel=&quot;nofollow&quot; href=&quot;https://thedeveloperstack.substack.com&quot;&gt;newsletter&lt;/a&gt; and get articles delivered straight to your inbox.&lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/11243/how-github-copilot-helped-me-roast-its-own-users</guid>
<pubDate>Sun, 08 Feb 2026 07:19:53 +0000</pubDate>
</item>
<item>
<title>BTOP++: The Resource Monitor I Didn’t Know I Needed</title>
<link>https://coderlegion.com/9204/btop-the-resource-monitor-i-didnt-know-i-needed</link>
<description>&lt;h2 id=&quot;btop-the-resource-monitor-i-didn-t-know-i-needed&quot;&gt;BTOP++: The Resource Monitor I Didn’t Know I Needed&lt;/h2&gt;
&lt;h3 id=&quot;introduction&quot;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;The year has just begun, the holidays are over, and it’s time to get back to building things.&lt;/p&gt;
&lt;p&gt;There’s been a lot of talk about &lt;strong&gt;2026 being “the year of Linux”&lt;/strong&gt; — Steam even kicked off the year with promotional material hinting at that idea. Whether that prediction will come true or not, I can confidently say one thing: &lt;strong&gt;2025 was the year of Linux for me&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;After years using Linux sporadically, things changed when I decided to study it more seriously. Since then, the penguin has fully taken over my workflow — much to my family’s amusement.&lt;/p&gt;
&lt;p&gt;With that context set, this article has a simple goal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Wish everyone a productive new year   &lt;/li&gt;
&lt;li&gt;And introduce a tool I genuinely didn’t know I needed: &lt;strong&gt;BTOP++&lt;/strong&gt; &lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;why-resource-monitoring-still-matters&quot;&gt;Why Resource Monitoring Still Matters&lt;/h3&gt;
&lt;p&gt;Even with modern hardware, understanding &lt;strong&gt;how your system behaves in real time&lt;/strong&gt; is still critical.&lt;/p&gt;
&lt;p&gt;Whether you’re:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Running local development environments&lt;/li&gt;
&lt;li&gt;Debugging performance issues&lt;/li&gt;
&lt;li&gt;Working with containers&lt;/li&gt;
&lt;li&gt;Or simply trying to understand where your resources are going&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A good resource monitor gives you &lt;strong&gt;immediate feedback&lt;/strong&gt; and helps you build intuition about your system.&lt;/p&gt;
&lt;p&gt;That’s where terminal-based tools really shine.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://i.ytimg.com/vi/YmzBJmpFMpw/maxresdefault.jpg&quot; alt=&quot;BTOP++ Interface&quot;&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;htop-vs-btop-&quot;&gt;HTOP vs BTOP++&lt;/h3&gt;
&lt;p&gt;Before anything else, it’s important to say this clearly:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;HTOP is an excellent tool.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Created by &lt;strong&gt;Hisham Muhammad&lt;/strong&gt;, HTOP is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fast&lt;/li&gt;
&lt;li&gt;Minimal&lt;/li&gt;
&lt;li&gt;Battle-tested&lt;/li&gt;
&lt;li&gt;Hugely respected by the Linux community&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It’s not by accident that it became a standard and even part of &lt;a rel=&quot;nofollow&quot; href=&quot;https://htop.dev/sightings.html&quot;&gt;hacker culture&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So why look at BTOP++ at all?&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://www.canalti.com.br/wp-content/uploads/2017/11/htop-2.0.png&quot; alt=&quot;HTOP Interface&quot;&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-makes-btop-different&quot;&gt;What Makes BTOP++ Different&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;BTOP++&lt;/strong&gt; can be seen as a natural evolution of the HTOP idea.&lt;/p&gt;
&lt;p&gt;While HTOP is written in C, BTOP++ is written in &lt;strong&gt;C++&lt;/strong&gt;, which allows it to offer:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Richer visual components&lt;/li&gt;
&lt;li&gt;Integrated CPU, memory, disk, and network graphs&lt;/li&gt;
&lt;li&gt;A more modern and polished interface&lt;/li&gt;
&lt;li&gt;Multiple panels without sacrificing usability&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All of this still runs inside the terminal, with no significant performance penalty on modern systems.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;should-you-switch-&quot;&gt;Should You Switch?&lt;/h3&gt;
&lt;p&gt;As with most things in technology, there is &lt;strong&gt;no silver bullet&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Both tools excel in different scenarios:&lt;/p&gt;
&lt;h4 id=&quot;htop&quot;&gt;HTOP&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Minimal and extremely fast  &lt;/li&gt;
&lt;li&gt;Proven stability over many years  &lt;/li&gt;
&lt;li&gt;Ideal for SSH sessions and servers  &lt;/li&gt;
&lt;li&gt;Excellent choice for low-resource environments  &lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;btop-&quot;&gt;BTOP++&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Visually rich and modern  &lt;/li&gt;
&lt;li&gt;Excellent for desktops and workstations  &lt;/li&gt;
&lt;li&gt;Great for local development and debugging  &lt;/li&gt;
&lt;li&gt;Makes performance patterns easier to spot at a glance  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A simple rule of thumb:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;HTOP for servers. BTOP++ for desktops and workstations.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;hr&gt;
&lt;h3 id=&quot;installation-1&quot;&gt;Installation&lt;/h3&gt;
&lt;h4 id=&quot;arch-manjaro-big-linux&quot;&gt;Arch / Manjaro / Big Linux&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo pacman -Syu
sudo pacman -S btop
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Run it with:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;btop
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h4 id=&quot;ubuntu-22-10-or-newer&quot;&gt;Ubuntu 22.10 or newer&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo apt update
sudo apt install btop
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h4 id=&quot;ubuntu-22-04-lts-or-older&quot;&gt;Ubuntu 22.04 LTS or older&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo snap install btop
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3 id=&quot;useful-keyboard-shortcuts&quot;&gt;Useful Keyboard Shortcuts&lt;/h3&gt;
&lt;p&gt;Once inside BTOP++:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ESC&lt;/code&gt; or &lt;code&gt;M&lt;/code&gt; → Open menu  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;↑&lt;/code&gt; / &lt;code&gt;↓&lt;/code&gt; → Navigate processes  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;F&lt;/code&gt; → Filter processes by name  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;K&lt;/code&gt; → Kill selected process  &lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can find the full list under &lt;strong&gt;Help&lt;/strong&gt; in the menu.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://itsfoss.com/content/images/2025/04/btop-menu_1745903608829_0.png&quot; alt=&quot;BTOP++ Menu&quot;&gt;&lt;br&gt;
&lt;img src=&quot;https://www.tecmint.com/wp-content/uploads/2025/02/btop-Help-Section.png&quot; alt=&quot;BTOP++ Keys&quot;&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;conclusion-1&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;BTOP++ isn’t a replacement for HTOP — it’s a &lt;strong&gt;complement&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;HTOP remains the gold standard for minimal, reliable monitoring in server environments. BTOP++, on the other hand, brings clarity and visual insight that make it especially valuable on desktops and developer workstations.&lt;/p&gt;
&lt;p&gt;If you spend a lot of time working locally on Linux, BTOP++ is absolutely worth adding to your toolbox.&lt;/p&gt;
&lt;p&gt;Here’s to a productive year — and &lt;strong&gt;long live Linux&lt;/strong&gt; &lt;/p&gt;
</description>
<category>Tutorials</category>
<guid isPermaLink="true">https://coderlegion.com/9204/btop-the-resource-monitor-i-didnt-know-i-needed</guid>
<pubDate>Sun, 04 Jan 2026 01:15:44 +0000</pubDate>
</item>
<item>
<title>Merry Christmas… in Your Linux Terminal</title>
<link>https://coderlegion.com/8908/merry-christmas-in-your-linux-terminal</link>
<description>&lt;h4 id=&quot;and-a-gentle-introduction-to-the-python-cli-ecosystem&quot;&gt;And a Gentle Introduction to the Python CLI Ecosystem&lt;/h4&gt;
&lt;h3 id=&quot;introduction-1&quot;&gt;Introduction&lt;/h3&gt;
&lt;p&gt;Today is Christmas — and if you’re reading this, I hope you’re doing well.&lt;/p&gt;
&lt;p&gt;After a long year, our minds often try to create a false sense of urgency. Sometimes, the best thing we can do is &lt;strong&gt;pause&lt;/strong&gt;, &lt;strong&gt;breathe&lt;/strong&gt;, and say:&lt;br&gt;
&lt;strong&gt;“Not now.”&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;With that in mind, this article brings a &lt;strong&gt;simple, fun, and educational tutorial&lt;/strong&gt;, perfect for the holiday season.&lt;/p&gt;
&lt;p&gt;The goal is straightforward:&lt;br&gt;
 &lt;strong&gt;run a Christmas tree animation directly in your Linux terminal&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=4193851051968597577&quot; alt=&quot;a digital tree print in terminal&quot;&gt;&lt;/p&gt;
&lt;p&gt;Yes — Linux developers would rather write 100+ lines of code than decorate a real tree.&lt;br&gt;
And we deeply respect that.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-are-we-building-&quot;&gt;What Are We Building?&lt;/h3&gt;
&lt;p&gt;We’ll run a Python-based CLI called &lt;strong&gt;&lt;code&gt;christmastree&lt;/code&gt;&lt;/strong&gt;, using a tool called &lt;strong&gt;&lt;code&gt;pipx&lt;/code&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Along the way, you’ll learn:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;What &lt;code&gt;pipx&lt;/code&gt; is and why it matters&lt;/li&gt;
&lt;li&gt;How to run Python CLI tools safely and in isolation&lt;/li&gt;
&lt;li&gt;How to run &lt;code&gt;christmastree&lt;/code&gt; on:&lt;ul&gt;
&lt;li&gt;most Linux distributions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Big Linux / Manjaro&lt;/strong&gt; (alternative setup)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-is-pipx-&quot;&gt;What Is &lt;a rel=&quot;nofollow&quot; href=&quot;https://pipx.pypa.io/stable/&quot;&gt;&lt;code&gt;pipx&lt;/code&gt;&lt;/a&gt;?&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;pipx&lt;/code&gt; is a tool designed to &lt;strong&gt;install and run Python applications in isolated environments&lt;/strong&gt;, without affecting:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the system Python&lt;/li&gt;
&lt;li&gt;other projects&lt;/li&gt;
&lt;li&gt;existing virtual environments&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each application gets its &lt;strong&gt;own virtual environment&lt;/strong&gt;, but remains accessible globally through your &lt;code&gt;PATH&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;examples-of-cli-tools-installed-with-pipx&quot;&gt;Examples of CLI Tools Installed with &lt;code&gt;pipx&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;Popular examples include:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;black&lt;/code&gt; — code formatter&lt;/li&gt;
&lt;li&gt;&lt;code&gt;poetry&lt;/code&gt; — dependency manager&lt;/li&gt;
&lt;li&gt;&lt;code&gt;httpie&lt;/code&gt; — terminal HTTP client&lt;/li&gt;
&lt;li&gt;&lt;code&gt;christmastree&lt;/code&gt; — your animated Christmas tree &lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;installation-official-method-works-on-most-distros-&quot;&gt;Installation (Official Method — Works on Most Distros)&lt;/h3&gt;
&lt;h4 id=&quot;step-1-install-pipx&quot;&gt;Step 1: Install &lt;code&gt;pipx&lt;/code&gt;&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pip install pipx
pipx ensurepath
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You may need to open a new terminal afterward.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;step-2-clone-the-official-repository&quot;&gt;Step 2: Clone the official repository&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone https://github.com/MEHighKing/christmastree.git
cd christmastree
pipx install .
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h4 id=&quot;step-3-run-it&quot;&gt;Step 3: Run it&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;christmastree
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3 id=&quot;alternative-setup-big-linux-manjaro-&quot;&gt;Alternative Setup — Big Linux (Manjaro)&lt;/h3&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.biglinux.com.br/&quot;&gt;&lt;strong&gt;Big Linux&lt;/strong&gt;&lt;/a&gt; is a Brazilian distribution based on &lt;strong&gt;Manjaro&lt;/strong&gt;, so the only difference is how &lt;code&gt;pipx&lt;/code&gt; is installed.&lt;/p&gt;
&lt;h4 id=&quot;install-pipx-via-pacman&quot;&gt;Install &lt;code&gt;pipx&lt;/code&gt; via pacman&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;sudo pacman -S python-pipx
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then follow the same steps:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git clone https://github.com/MEHighKing/christmastree.git
cd christmastree
pipx install .
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3 id=&quot;common-issue-terminal-size&quot;&gt;Common Issue: Terminal Size&lt;/h3&gt;
&lt;p&gt;If you see this error:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;Please enlarge your terminal to at least 100x40 (current: 85x34).
[exit=1]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Just resize your terminal window.&lt;/p&gt;
&lt;p&gt;Check current size with:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;tput cols; tput lines
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Once it reaches &lt;strong&gt;100x40&lt;/strong&gt; or more, run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;christmastree
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h3 id=&quot;important-note-&quot;&gt;Important Note ⚠️&lt;/h3&gt;
&lt;p&gt;Some tutorials suggest running:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;curl -L https://raw.githubusercontent.com/MEHighKing/christmastree/master/christmastree.sh | bash
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This does &lt;strong&gt;not&lt;/strong&gt; work.&lt;br&gt;
There is &lt;strong&gt;no shell script&lt;/strong&gt; in the repository. The correct approach is using &lt;code&gt;pipx&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;conclusion-2&quot;&gt;Conclusion&lt;/h3&gt;
&lt;p&gt;I hope everything ran smoothly &lt;/p&gt;
&lt;p&gt;If you enjoyed it, consider visiting the official repository and leaving a ⭐ — those developers are powered by coffee and code ☕&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=5705353706417050419&quot; alt=&quot;application repo&quot;&gt;&lt;/p&gt;
&lt;p&gt; Official repository:&lt;br&gt;
&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/MEHighKing/christmastree&quot;&gt;https://github.com/MEHighKing/christmastree&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Merry Christmas — and &lt;strong&gt;long live Linux!&lt;/strong&gt;  &lt;/p&gt;
</description>
<category>Basic Commands</category>
<guid isPermaLink="true">https://coderlegion.com/8908/merry-christmas-in-your-linux-terminal</guid>
<pubDate>Thu, 25 Dec 2025 21:06:45 +0000</pubDate>
</item>
<item>
<title>CodeContext</title>
<link>https://coderlegion.com/8879/codecontext</link>
<description>&lt;p&gt;CodeContext is an innovative open-source project designed to facilitate faster developer onboarding by intelligently analyzing codebases. &lt;/p&gt;
&lt;h3 id=&quot;why-codecontext-&quot;&gt;Why CodeContext?&lt;/h3&gt;
&lt;p&gt;Onboarding new developers can often take between 1 to 3 months, during which they struggle with various challenges such as:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Searching for initial tasks or reference points&lt;/li&gt;
&lt;li&gt;Understanding file dependencies and relationships&lt;/li&gt;
&lt;li&gt;Navigating outdated documentation&lt;/li&gt;
&lt;li&gt;Handling repetitive questions from team members  &lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;the-solution-1&quot;&gt;The Solution&lt;/h4&gt;
&lt;p&gt;CodeContext offers a solution by quickly analyzing a codebase and providing essential insights to enhance the onboarding experience:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Interactive Dependency Maps&lt;/strong&gt;: Visualize the entire structure of the codebase with zoomable, force-directed graphs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Knowledge Hotspots&lt;/strong&gt;: Leverage a PageRank algorithm to identify critically important files within the project.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Personalized Learning Paths&lt;/strong&gt;: Generate suggested reading orders to guide new developers effectively through the codebase.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Smart Contextual Information&lt;/strong&gt;: Gain insights into Git history, authorship, and frequency of changes for each file.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These features collectively reduce the onboarding time significantly, converting the period from 3 months to just 3 weeks.&lt;/p&gt;
&lt;h3 id=&quot;features&quot;&gt;Features&lt;/h3&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Feature                        &lt;/th&gt;&lt;th&gt;Description&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Interactive Dependency Maps&lt;/strong&gt; &lt;/td&gt;&lt;td&gt;Visual representation of file relationships through dynamic graphs.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Knowledge Hotspots&lt;/strong&gt;         &lt;/td&gt;&lt;td&gt;Discover critical files based on their importance in the project using PageRank.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Learning Paths&lt;/strong&gt;             &lt;/td&gt;&lt;td&gt;Provides a topologically sorted order to help new team members navigate the project with ease.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Git Integration&lt;/strong&gt;            &lt;/td&gt;&lt;td&gt;Access detailed Git history and statistics for better context.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Team Contribution Map&lt;/strong&gt;      &lt;/td&gt;&lt;td&gt;Identify knowledge silos and assess risks related to team member dependencies.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Multi-Language Support&lt;/strong&gt;     &lt;/td&gt;&lt;td&gt;Currently supports Java and Kotlin, with plans for more languages.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Fast Performance&lt;/strong&gt;           &lt;/td&gt;&lt;td&gt;Built with parallel parsing and intelligent caching for efficiency.&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Visual Reports&lt;/strong&gt;             &lt;/td&gt;&lt;td&gt;Generates clean HTML reports enhanced with D3.js visualizations.&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id=&quot;demo-3&quot;&gt;Demo&lt;/h3&gt;
&lt;p&gt;An interactive demo illustrates the functionality of CodeContext by showcasing a dependency graph, knowledge hotspots, and learning path generation. To see CodeContext in action, run the command:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;./gradlew run --args=&quot;analyze .&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;documentation&quot;&gt;Documentation&lt;/h3&gt;
&lt;p&gt;Comprehensive documentation is available to help users understand the architecture, development guidelines, API references, and more:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/sonii-shivansh/CodeContext/blob/main/docs/ARCHITECTURE.md&quot;&gt;Architecture Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/sonii-shivansh/CodeContext/blob/main/docs/DEVELOPMENT.md&quot;&gt;Development Guide&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/sonii-shivansh/CodeContext/blob/main/docs/API.md&quot;&gt;API Documentation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;contributing&quot;&gt;Contributing&lt;/h3&gt;
&lt;p&gt;Contributions are encouraged and can take many forms, including bug fixes, feature additions, or documentation improvements. A structured guide is provided to help newcomers get started. To explore open issues suitable for new contributors, browse the issues labeled &lt;strong&gt;good first issue&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&quot;roadmap&quot;&gt;Roadmap&lt;/h3&gt;
&lt;p&gt;Future enhancements include support for additional programming languages, integration of popular IDE plugins, and potential cloud-hosted services to extend functionality.&lt;/p&gt;
&lt;p&gt;For those interested in optimizing their development processes and enhancing team efficiency, CodeContext provides essential tools and insights to streamline the onboarding experience. Visit the project's &lt;a rel=&quot;nofollow&quot; href=&quot;https://codecontext.dev&quot;&gt;website&lt;/a&gt; for further information and resources.&lt;/p&gt;
</description>
<category>Open Source</category>
<guid isPermaLink="true">https://coderlegion.com/8879/codecontext</guid>
<pubDate>Thu, 25 Dec 2025 08:00:37 +0000</pubDate>
</item>
<item>
<title>Send emails from the terminal using pop</title>
<link>https://coderlegion.com/8712/send-emails-from-the-terminal-using-pop</link>
<description>&lt;h2 id=&quot;multi-account-email-sender-pop-wrapper-&quot;&gt;Multi-Account Email Sender (pop wrapper)&lt;/h2&gt;
&lt;p&gt;This script wraps Charm's &lt;code&gt;pop&lt;/code&gt; to send emails from &lt;strong&gt;multiple accounts&lt;/strong&gt; directly from your terminal &lt;strong&gt;without config edits&lt;/strong&gt;. Select your email, then use pop's interactive UI or CLI flags.&lt;/p&gt;
&lt;h3 id=&quot;features-1&quot;&gt;Features&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Switch between multiple SMTP accounts via &lt;code&gt;gum&lt;/code&gt; (or fallback menu)&lt;/li&gt;
&lt;li&gt;Secure secrets from &lt;code&gt;~/.zsh_secrets&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Exports &lt;code&gt;POP_SMTP_USERNAME&lt;/code&gt;, &lt;code&gt;POP_SMTP_PASSWORD&lt;/code&gt;, &lt;code&gt;POP_FROM&lt;/code&gt; automatically&lt;/li&gt;
&lt;li&gt;Passes all &lt;code&gt;pop&lt;/code&gt; args through&lt;/li&gt;
&lt;li&gt;Shellcheck clean, bash-compatible&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;environment-variables&quot;&gt;Environment Variables&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;In &lt;code&gt;~/.zshrc&lt;/code&gt; (non-sensitive):&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;export POP_SMTP_HOST=&quot;smtp.gmail.com&quot; # or smtp.outlook.com, etc.
export POP_SMTP_PORT=587
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;In &lt;code&gt;~/.zsh_secrets&lt;/code&gt; (chmod 600, gitignore!):&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;export POP_SMTP_USERNAME1=&quot;*Emails are not allowed*&quot;
export POP_SMTP_PASSWORD1=&quot;abcd efgh ijkl mnop&quot; # Gmail/Outlook APP PASSWORD
export POP_SMTP_USERNAME2=&quot;*Emails are not allowed*&quot;
export POP_SMTP_PASSWORD2=&quot;ijkl mnop qrst uvwx&quot; # APP PASSWORD (16 chars, no spaces)
&lt;/code&gt;&lt;/pre&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;⚠️ &lt;code&gt;POP_SMTP_PASSWORD&lt;/code&gt;s are app-specific passwords&lt;/strong&gt; (not your regular login)—generate from Gmail/Outlook 2FA security settings.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;dependencies&quot;&gt;Dependencies&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/charmbracelet/pop&quot;&gt;pop&lt;/a&gt; (Charm)&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/charmbracelet/gum&quot;&gt;gum&lt;/a&gt; &lt;em&gt;(optional, menu fallback built-in)&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;usage&quot;&gt;Usage&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;chmod +x ~/.local/bin/send_email
send_email # Interactive pop
send_email --to *Emails are not allowed* --subject &quot;Hi&quot; --body &quot;Test&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Here is the link to the gist&lt;/strong&gt; &lt;em&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://gist.github.com/Vaishnav-Sabari-Girish/51cbfc493fee25c209c39f0e74a17103&quot;&gt;https://gist.github.com/Vaishnav-Sabari-Girish/51cbfc493fee25c209c39f0e74a17103&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Save your dotfiles workflow! &lt;/p&gt;
</description>
<category>Articles</category>
<guid isPermaLink="true">https://coderlegion.com/8712/send-emails-from-the-terminal-using-pop</guid>
<pubDate>Mon, 22 Dec 2025 07:27:15 +0000</pubDate>
</item>
<item>
<title>UserScanner</title>
<link>https://coderlegion.com/8018/userscanner</link>
<description>&lt;h2 id=&quot;user-scanner&quot;&gt;User Scanner&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/49ec8d24-665b-4115-8525-01a8d0ca2ef4&quot; alt=&quot;1000136215&quot;&gt;&lt;/p&gt;
&lt;h3 id=&quot;repo-https-github-com-kaifcodec-user-scanner&quot;&gt;Repo: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/kaifcodec/user-scanner&quot;&gt;https://github.com/kaifcodec/user-scanner&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Scan a username across multiple social, developer, and creator platforms to see if it’s available.&lt;br&gt;
Perfect for finding a &lt;strong&gt;unique username&lt;/strong&gt; across GitHub, Twitter, Reddit, Instagram, and more, all in one command.&lt;/p&gt;
&lt;h4 id=&quot;features-2&quot;&gt;Features&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;✅ Check usernames across &lt;strong&gt;social networks&lt;/strong&gt;, &lt;strong&gt;developer platforms&lt;/strong&gt;, and &lt;strong&gt;creator communities&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;✅ Clear &lt;strong&gt;Available / Taken / Error&lt;/strong&gt; output for each platform.&lt;/li&gt;
&lt;li&gt;✅ Fully modular: add new platform modules easily.&lt;/li&gt;
&lt;li&gt;✅ Command-line interface ready: works directly after &lt;code&gt;pip install&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;✅ Can be used as username OSINT tool.&lt;/li&gt;
&lt;li&gt;✅ Very low and lightweight dependencies, can be run on any machine.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&quot;installation-2&quot;&gt;Installation&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pip install user-scanner
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h4 id=&quot;usage-1&quot;&gt;Usage&lt;/h4&gt;
&lt;p&gt;Scan a username across all platforms:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;user-scanner -u &amp;lt;username&amp;gt;

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Optionally, scan a specific category or single module:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;user-scanner -u &amp;lt;username&amp;gt; -c dev
user-scanner -l # Lists all available modules
user-scanner -u &amp;lt;username&amp;gt; -m github

&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h4 id=&quot;contributing-&quot;&gt;Contributing:&lt;/h4&gt;
&lt;p&gt;Modules are organized by category:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;
user_scanner/
├── dev/        # Developer platforms (GitHub, GitLab, etc.)
├── social/     # Social platforms (Twitter/X, Reddit, Instagram, etc.)
├── creator/    # Creator platforms (Hashnode, Dev.to, Medium, etc.)
├── community/  # Community platforms (forums, niche sites)
├── gaming/     # Gaming sites (chess.com, roblox, monkeytype etc.)
├── donation/   # Donation taking sites (buymeacoffe.com, similar...)

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Module guidelines:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Each module must define a &lt;code&gt;validate_&amp;lt;site&amp;gt;()&lt;/code&gt; function that takes a &lt;code&gt;username&lt;/code&gt; and returns:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;1&lt;/code&gt; → Available  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;0&lt;/code&gt; → Taken  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;2&lt;/code&gt; → Error / Could not check&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;httpx&lt;/code&gt; for requests, &lt;code&gt;colorama&lt;/code&gt; for colored output.&lt;/li&gt;
&lt;li&gt;Optional: modules can define a CLI parser if they support custom arguments.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;See &lt;a rel=&quot;nofollow&quot; href=&quot;CONTRIBUTING.md&quot;&gt;CONTRIBUTING.md&lt;/a&gt; for examples.&lt;/p&gt;
&lt;hr&gt;
&lt;h4 id=&quot;dependencies-&quot;&gt;Dependencies:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://pypi.org/project/httpx/&quot;&gt;httpx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://pypi.org/project/colorama/&quot;&gt;colorama&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&quot;license&quot;&gt;License&lt;/h4&gt;
&lt;p&gt;This project is licensed under the &lt;strong&gt;MIT License&lt;/strong&gt;. See &lt;a rel=&quot;nofollow&quot; href=&quot;LICENSE&quot;&gt;LICENSE&lt;/a&gt; for details.&lt;/p&gt;
</description>
<category>CLI Tools &amp; Scripts</category>
<guid isPermaLink="true">https://coderlegion.com/8018/userscanner</guid>
<pubDate>Mon, 01 Dec 2025 14:19:20 +0000</pubDate>
</item>
<item>
<title>Advent of Code Interactive</title>
<link>https://coderlegion.com/8012/advent-of-code-interactive</link>
<description>&lt;h2 id=&quot;advent-of-code-interactive&quot;&gt;Advent of Code Interactive&lt;/h2&gt;
&lt;p&gt;This script provides an interactive experience using the &lt;code&gt;aoc-cli&lt;/code&gt; too. &lt;/p&gt;
&lt;h3 id=&quot;dependencies-1&quot;&gt;Dependencies&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;aoc-cli&lt;/code&gt; : &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/scarvalhojr/aoc-cli&quot;&gt;https://github.com/scarvalhojr/aoc-cli&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;gum&lt;/code&gt; : &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/charmbracelet/gum&quot;&gt;https://github.com/charmbracelet/gum&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;glow&lt;/code&gt; : &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/charmbracelet/glow&quot;&gt;https://github.com/charmbracelet/glow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With this script you can&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;View problems (By selecting the days)&lt;/li&gt;
&lt;li&gt;Download the problem and input&lt;/li&gt;
&lt;li&gt;Submit answer&lt;/li&gt;
&lt;li&gt;View calendar&lt;/li&gt;
&lt;li&gt;View the leaderboard (Private)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Here is the link to my gist where I have pushed the script &lt;/p&gt;
&lt;p&gt;Link : &lt;a rel=&quot;nofollow&quot; href=&quot;https://gist.github.com/Vaishnav-Sabari-Girish/bc213e8539e666dac74249f25a868dec&quot;&gt;https://gist.github.com/Vaishnav-Sabari-Girish/bc213e8539e666dac74249f25a868dec&lt;/a&gt;&lt;/p&gt;
</description>
<category>Command Line Tools</category>
<guid isPermaLink="true">https://coderlegion.com/8012/advent-of-code-interactive</guid>
<pubDate>Mon, 01 Dec 2025 10:09:08 +0000</pubDate>
</item>
<item>
<title>user-scanner</title>
<link>https://coderlegion.com/6762/user-scanner</link>
<description>&lt;h2 id=&quot;user-scanner-1&quot;&gt;User Scanner&lt;/h2&gt;
&lt;p&gt;&lt;img src=&quot;https://github.com/user-attachments/assets/49ec8d24-665b-4115-8525-01a8d0ca2ef4&quot; alt=&quot;1000136215&quot;&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Scan a username across multiple social, developer, and creator platforms to see if it’s available.&lt;br&gt;
Perfect for finding a &lt;strong&gt;unique username&lt;/strong&gt; across GitHub, Twitter, Reddit, Instagram, and more, all in one command.&lt;/p&gt;
&lt;p&gt;Github: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/kaifcodec/user-scanner&quot;&gt;https://github.com/kaifcodec/user-scanner&lt;/a&gt;&lt;/p&gt;
&lt;h4 id=&quot;features-3&quot;&gt;Features&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;✅ Check usernames across &lt;strong&gt;social networks&lt;/strong&gt;, &lt;strong&gt;developer platforms&lt;/strong&gt;, and &lt;strong&gt;creator communities&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;✅ Clear &lt;strong&gt;Available / Taken / Error&lt;/strong&gt; output for each platform.&lt;/li&gt;
&lt;li&gt;✅ Fully modular: add new platform modules easily.&lt;/li&gt;
&lt;li&gt;✅ Command-line interface ready: works directly after &lt;code&gt;pip install&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;✅ Can be used as username OSINT tool.&lt;/li&gt;
&lt;li&gt;✅ Very low and lightweight dependencies, can be run on any machine.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&quot;installation-3&quot;&gt;Installation&lt;/h4&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pip install user-scanner
&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h4 id=&quot;usage-2&quot;&gt;Usage&lt;/h4&gt;
&lt;p&gt;Scan a username across all platforms:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;user-scanner -u &amp;lt;username&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Optionally, scan a specific category or single module:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;user-scanner -u &amp;lt;username&amp;gt; -c dev
user-scanner -l # Lists all available modules
user-scanner -u &amp;lt;username&amp;gt; -m github

&lt;/code&gt;&lt;/pre&gt;
&lt;hr&gt;
&lt;h4 id=&quot;example-output-&quot;&gt;Example Output:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Note*: New modules are constantly getting added so this might have only limited, outdated output: &lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt; Checking username: johndoe078

== DEV SITES ==
  [✔] Codeberg: Available
  [✔] Cratesio: Available
  [✔] Dockerhub: Available
  [✘] Github: Taken
  [✔] Gitlab: Available
  [✔] Launchpad: Available
  [✔] Npmjs: Available
  [✔] Replit: Available

== SOCIAL SITES ==
  [✔] Bluesky: Available
  [✔] Discord: Available
  [✘] Instagram: Taken
  [✔] Mastodon: Available
  [✔] Pinterest: Available
  [✘] Reddit: Taken
  [✔] Snapchat: Available
  [✔] Telegram: Available 
  [✘] Threads: Taken
  [✔] X (Twitter): Available
  [✔] Youtube: Available

== CREATOR SITES ==
  [✔] Devto: Available
  [✔] Hashnode: Available
  [✔] Kaggle: Available
  [✔] Medium: Available
  [✔] Patreon: Available

== COMMUNITY SITES ==
  [✔] Coderlegion: Available

== GAMING SITES ==
  [✔] Chess_com: Available
  [✔] Osu: Available
  [✔] Roblox: Available
  ...
  ...
  ...
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;contributing--1&quot;&gt;Contributing:&lt;/h4&gt;
&lt;p&gt;Modules are organized by category:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;user_scanner/
├── dev/        # Developer platforms (GitHub, GitLab, etc.)
├── social/     # Social platforms (Twitter/X, Reddit, Instagram, etc.)
├── creator/    # Creator platforms (Hashnode, Dev.to, Medium, etc.)
├── community/  # Community platforms (forums, niche sites)
├── gaming/     # Gaming sites (chess.com, roblox, monkeytype etc.)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Module guidelines:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Each module must define a &lt;code&gt;validate_&amp;lt;site&amp;gt;()&lt;/code&gt; function that takes a &lt;code&gt;username&lt;/code&gt; and returns:&lt;ul&gt;
&lt;li&gt;&lt;code&gt;1&lt;/code&gt; → Available  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;0&lt;/code&gt; → Taken  &lt;/li&gt;
&lt;li&gt;&lt;code&gt;2&lt;/code&gt; → Error / Could not check&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;httpx&lt;/code&gt; for requests, &lt;code&gt;colorama&lt;/code&gt; for colored output.&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Optional: modules can define a CLI parser if they support custom arguments.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h4 id=&quot;dependencies--1&quot;&gt;Dependencies:&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://pypi.org/project/httpx/&quot;&gt;httpx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://pypi.org/project/colorama/&quot;&gt;colorama&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;-community-and-gaming-are-small-looking-for-contributions&quot;&gt;⚠️ &lt;code&gt;community/&lt;/code&gt; and &lt;code&gt;gaming/&lt;/code&gt; are small, looking for contributions&lt;/h3&gt;
</description>
<category>CLI Tools &amp; Scripts</category>
<guid isPermaLink="true">https://coderlegion.com/6762/user-scanner</guid>
<pubDate>Sat, 22 Nov 2025 14:13:01 +0000</pubDate>
</item>
<item>
<title>Ytconverter</title>
<link>https://coderlegion.com/5836/ytconverter</link>
<description>&lt;p&gt;I recently built a command-line YouTube downloader in Python called ytconverter. It’s designed to fetch videos directly from YouTube and convert them into formats like MP3 and MP4. The goal was to make a simple, functional tool without external GUIs or bloated software — just clean CLI efficiency.&lt;/p&gt;
&lt;p&gt;Key features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Download YouTube videos directly from CLI&lt;/li&gt;
&lt;li&gt;Convert to various formats (MP3, MP4, multiple video downloads.)&lt;/li&gt;
&lt;li&gt;Handles basic metadata&lt;/li&gt;
&lt;li&gt;Easy to set up and use&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you're someone who likes working with CLI tools, or Python automation, this might be useful for you.&lt;/p&gt;
&lt;p&gt;The project is open-source, so feel free to try it out, suggest improvements, or even contribute if you're interested.&lt;/p&gt;
&lt;p&gt;Here’s the repo:&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/kaifcodec/ytconverter&quot;&gt;https://github.com/kaifcodec/ytconverter&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Let me know what you think! Suggestions, critiques, or PRs are all welcome.&lt;/p&gt;
</description>
<category>CLI Tools &amp; Scripts</category>
<guid isPermaLink="true">https://coderlegion.com/5836/ytconverter</guid>
<pubDate>Wed, 05 Nov 2025 18:36:26 +0000</pubDate>
</item>
<item>
<title>InstaScrape</title>
<link>https://coderlegion.com/5818/instascrape</link>
<description>&lt;h2 id=&quot;instascrape-async-instagram-comment-scraper&quot;&gt;InstaScrape — Async Instagram Comment Scraper&lt;/h2&gt;
&lt;p&gt;Scrape &lt;strong&gt;all parent comments&lt;/strong&gt; from any Instagram Reel with &lt;strong&gt;automated login&lt;/strong&gt;, &lt;strong&gt;async speed&lt;/strong&gt;, &lt;strong&gt;real-time progress&lt;/strong&gt;, and &lt;strong&gt;clean exports&lt;/strong&gt; — no manual cookie copying required.&lt;/p&gt;
&lt;h3 id=&quot;-features&quot;&gt;✨ Features&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;✅ &lt;strong&gt;Automated Login&lt;/strong&gt;: &lt;code&gt;cookie.json&lt;/code&gt; persistence with iat + expiry, no manual cookies needed.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Self-healing Auth&lt;/strong&gt;: detects expired cookies mid-run, prompts relogin, resumes automatically.&lt;/li&gt;
&lt;li&gt;⚡ &lt;strong&gt;Async Engine&lt;/strong&gt;: powered by &lt;code&gt;httpx.AsyncClient&lt;/code&gt; with requests-per-second throttling.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Progress Tracking&lt;/strong&gt;: accurate percent and ETA from Instagram’s comment count.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dual Exports&lt;/strong&gt;: TXT and JSON files saved in timestamped folders.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;requirements&quot;&gt;Requirements&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Python &lt;strong&gt;3.9+&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Dependencies:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;pip install -r requirements.txt
&lt;/code&gt;&lt;/pre&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/kaifcodec/InstaScrape
cd InstaScrape
pip install -r requirements.txt
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;-usage&quot;&gt;▶️ Usage&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;python3 main.py
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Enter the Instagram Reel URL (e.g., &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.instagram.com/reel/SHORTCODE/&quot;&gt;https://www.instagram.com/reel/SHORTCODE/&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Set Max requests per second (5-7 recommended). Adjust for stability.&lt;/li&gt;
&lt;li&gt;On first run, provide username/password; cookie.json is created and reused until expiry.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;output&quot;&gt;Output&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;TXT: download_comments/txt/reel_comments_YYYYMMDD_HHMMSS.txt&lt;/li&gt;
&lt;li&gt;JSON: download_comments/json/reel_comments_YYYYMMDD_HHMMSS.json&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;example-structure-&quot;&gt;Example structure:&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;  &quot;generated_at&quot;: 1700000000,
  &quot;count&quot;: 123,
  &quot;comments&quot;: [
    { &quot;username&quot;: &quot;user1&quot;, &quot;text&quot;: &quot;Nice!&quot;, &quot;created_at&quot;: 1699999000 }

&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;how-it-works-2&quot;&gt;How it Works&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Cookie Lifecycle: cookie.json stores iat and expiry; validated on startup &amp;amp; during requests.&lt;/li&gt;
&lt;li&gt;Error Resilience: retries transient errors and refreshes cookies on 401/redirect-to-login.&lt;/li&gt;
&lt;li&gt;Progress Accuracy: uses Instagram’s comment count to calculate percent &amp;amp; ETA.&lt;/li&gt;
&lt;li&gt;Async Efficiency: httpx.AsyncClient with HTTP/2, keep-alive, and RPS limiter.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Repository url: &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/kaifcodec/InstaScrape.git&quot;&gt;https://github.com/kaifcodec/InstaScrape.git&lt;/a&gt;&lt;/p&gt;
</description>
<category>CLI Tools &amp; Scripts</category>
<guid isPermaLink="true">https://coderlegion.com/5818/instascrape</guid>
<pubDate>Tue, 30 Sep 2025 14:14:14 +0000</pubDate>
</item>
<item>
<title>Create Launcher CLI (npm Package)</title>
<link>https://coderlegion.com/4403/create-launcher-cli-npm-package</link>
<description>&lt;blockquote&gt;&lt;p&gt;“Why am I still copy pasting the same setup files again and again?”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you’ve ever asked yourself this after starting yet another web project... &lt;/p&gt;
&lt;p&gt;You’re not alone — I’ve been there too.&lt;/p&gt;
&lt;p&gt;So I built something to make project bootstrapping painless.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;-meet-create-launcher&quot;&gt;️ Meet &lt;code&gt;create-launcher&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;A zero-config CLI tool that lets you scaffold modern web projects instantly, with everything pre wired and ready to go.&lt;/p&gt;
&lt;h4 id=&quot;features-at-a-glance&quot;&gt;Features at a Glance&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;✅ Interactive CLI with prompts  &lt;/li&gt;
&lt;li&gt;⚛️ Project templates:  &lt;ul&gt;
&lt;li&gt;React (Vite)  &lt;/li&gt;
&lt;li&gt;Next.js  &lt;/li&gt;
&lt;li&gt;Eleventy (11ty)  &lt;/li&gt;
&lt;li&gt;Vanilla JavaScript &amp;amp; TypeScript  &lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Tailwind CSS integration (optional)  &lt;/li&gt;
&lt;li&gt;TypeScript support  &lt;/li&gt;
&lt;li&gt;Pick your favorite package manager (npm, yarn, pnpm)  &lt;/li&gt;
&lt;li&gt;ESLint pre-configured  &lt;/li&gt;
&lt;li&gt;⚡ Auto installs everything you need&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;get-started-in-one-line&quot;&gt;Get Started in One Line&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;npx create-launcher
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The CLI walks you through setup, just answer a few prompts, and boom &lt;br&gt;
Your project is scaffolded and dependencies installed. No extra config.&lt;/p&gt;
&lt;h3 id=&quot;see-it-in-action&quot;&gt;See It In Action&lt;/h3&gt;
&lt;p&gt;&lt;img src=&quot;https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8l85iar13pp2m6i4qmie.gif&quot; alt=&quot;create-launcher Demo&quot;&gt;&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;⚡ Creating a React + TypeScript + Tailwind project in under 30 seconds&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&quot;why-i-built-this-1&quot;&gt;Why I Built This&lt;/h3&gt;
&lt;p&gt;As a dev who loves shipping fast, I kept hitting the same roadblocks every time I started a new project - boilerplate, repeated setup, switching between Vite and Next.js, etc.&lt;/p&gt;
&lt;p&gt;Now, with &lt;code&gt;create-launcher&lt;/code&gt;, I can:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Start a project in under 15 seconds&lt;/li&gt;
&lt;li&gt;Have a consistent, clean folder structure&lt;/li&gt;
&lt;li&gt;Focus on writing code, not configuration&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;check-it-out&quot;&gt;Check It Out&lt;/h3&gt;
&lt;p&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.npmjs.com/package/create-launcher&quot;&gt;NPM Package&lt;/a&gt;&lt;br&gt;
 &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/pranav89624/create-launcher&quot;&gt;GitHub Repo&lt;/a&gt;&lt;/p&gt;
&lt;h3 id=&quot;ideas-for-future-versions&quot;&gt;Ideas for Future Versions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Templates On (Vue.js, Svelte, Angular etc.)&lt;/li&gt;
&lt;li&gt;Git init + first commit&lt;/li&gt;
&lt;li&gt;Prettier integration&lt;/li&gt;
&lt;li&gt;Optional GitHub Actions CI setup&lt;/li&gt;
&lt;li&gt;Custom template support&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&quot;feedback-welcome&quot;&gt;Feedback Welcome&lt;/h3&gt;
&lt;p&gt;I’d love to hear what you think.&lt;br&gt;
Found a bug? Have a feature request? PRs are welcome, and stars always appreciated ⭐&lt;/p&gt;
&lt;p&gt;Let’s make spinning up projects feel exciting again.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;-about-the-author&quot;&gt;♂️ About the Author&lt;/h3&gt;
&lt;p&gt;I'm &lt;strong&gt;Pranav Verma&lt;/strong&gt;, a passionate Full Stack Developer and tech enthusiast exploring the intersection of &lt;strong&gt;DevTools, AI, and modern web development&lt;/strong&gt;. I love building tools that simplify developer workflows and enhance productivity.&lt;/p&gt;
&lt;p&gt; &lt;strong&gt;Connect with me&lt;/strong&gt;:  &lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.linkedin.com/in/vermapranav/&quot;&gt;LinkedIn&lt;/a&gt;  &lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://x.com/pranav89624&quot;&gt;Twitter / X&lt;/a&gt;  &lt;/li&gt;
&lt;li&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/pranav89624&quot;&gt;GitHub&lt;/a&gt;  &lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt; If you liked this project, don’t forget to ⭐ it on &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/pranav89624/create-launcher&quot;&gt;GitHub&lt;/a&gt; and share it with fellow devs!&lt;/p&gt;
&lt;p&gt;And, if you want to contribute something helpful to the community, just read the &lt;code&gt;CONTRIBUTING.md&lt;/code&gt; in GitHub repo and start helping others and yourselves.&lt;/p&gt;
</description>
<category>CLI Tools &amp; Scripts</category>
<guid isPermaLink="true">https://coderlegion.com/4403/create-launcher-cli-npm-package</guid>
<pubDate>Sun, 03 Aug 2025 08:17:14 +0000</pubDate>
</item>
<item>
<title>Auto-generate Commit Messages with LLMs in Your Terminal</title>
<link>https://coderlegion.com/3876/auto-generate-commit-messages-with-llms-in-your-terminal</link>
<description>&lt;blockquote&gt;&lt;p&gt;Original post: &lt;a rel=&quot;nofollow&quot; href=&quot;https://hankchiu.tw/writings/auto-generate-commit-messages-with-ll-ms-in-your-terminal/&quot;&gt;https://hankchiu.tw/writings/auto-generate-commit-messages-with-ll-ms-in-your-terminal/&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Writing commit messages can be a drag. While IDEs like Cursor can automate this, what if you live in your terminal and want a fast, controllable way to generate conventional commits?&lt;/p&gt;
&lt;p&gt;This guide is for you. It's as simple as piping &lt;code&gt;git diff&lt;/code&gt; to a command-line LLM client to create well-formatted commit messages without leaving the terminal.&lt;/p&gt;
&lt;h4 id=&quot;quick-summary&quot;&gt;Quick Summary&lt;/h4&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Use a non-interactive LLM client:&lt;/strong&gt; We need a tool that takes input from a pipe, sends it to the model, and prints the result to standard output.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Craft a system prompt:&lt;/strong&gt; Instruct the LLM to generate a message in the Conventional Commits format.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Create a Git alias:&lt;/strong&gt; Make the entire process accessible through a simple command like &lt;code&gt;git ca&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4 id=&quot;the-system-prompt&quot;&gt;The System Prompt&lt;/h4&gt;
&lt;p&gt;First, let's define our instructions for the LLM. This prompt ensures the output is consistently formatted as a Conventional Commit:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;Write a commit message in the Conventional Commits format. Use the structure:
&amp;lt;type&amp;gt;(&amp;lt;optional scope&amp;gt;): &amp;lt;short description&amp;gt;

&amp;lt;optional body&amp;gt;

&amp;lt;optional footer&amp;gt;

Example types: feat, fix, docs, style, refactor, perf, test, build, ci, chore, revert
Optionally, include a body for more details in bullet points.
Optionally, in the footer, use BREAKING CHANGE: followed by a detailed explanation of the breaking change.

Just return the commit message, do not include any other text.
&lt;/code&gt;&lt;/pre&gt;
&lt;h4 id=&quot;llm-clients-for-the-terminal&quot;&gt;LLM Clients for the Terminal&lt;/h4&gt;
&lt;p&gt;Several command-line tools can handle this task. Here are a few examples of how to use them, piping your staged changes directly to the model.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://llm.datasette.io/en/stable/&quot;&gt;LLM CLI&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git diff --cached | llm -s '&amp;lt;your-system-prompt&amp;gt;'
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/google-gemini/gemini-cli&quot;&gt;Gemini CLI&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git diff --cached | gemini -p '&amp;lt;your-system-prompt&amp;gt;'
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/sigoden/aichat&quot;&gt;aichat&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git diff --cached | aichat --prompt '&amp;lt;your-system-prompt&amp;gt;'
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.google.com/search?q=https://github.com/anthropics/claude-cli&quot;&gt;Claude CLI&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git diff --cached | claude -p '&amp;lt;your-system-prompt&amp;gt;'
&lt;/code&gt;&lt;/pre&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;create-a-git-alias&quot;&gt;Create a Git Alias&lt;/h4&gt;
&lt;p&gt;To make this truly seamless, add an alias to your &lt;code&gt;.gitconfig&lt;/code&gt;. This example uses &lt;code&gt;llm&lt;/code&gt; to commit all staged changes and then displays the latest log entry.&lt;/p&gt;
&lt;p&gt;Place your full system prompt directly into the alias or save it to a file and reference it.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;[alias]
  ca = &quot;!(git commit -m \&quot;$(git diff --cached | llm -s 'Write a commit message in the Conventional Commits format...')\&quot; &amp;amp;&amp;amp; git log --stat -1)&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Now, instead of &lt;code&gt;git commit&lt;/code&gt;, simply run:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git ca
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Your staged changes will be sent to the LLM, the generated message will be used for the commit, and you'll see the result instantly. It's a quick, powerful way to keep your workflow moving, all from the comfort of your terminal.&lt;/p&gt;
</description>
<category>Command Line Tools</category>
<guid isPermaLink="true">https://coderlegion.com/3876/auto-generate-commit-messages-with-llms-in-your-terminal</guid>
<pubDate>Thu, 10 Jul 2025 07:58:47 +0000</pubDate>
</item>
<item>
<title>Meet Hippoo: The Lightning-Fast CLI Tool Every Dev Needs to Check NPM Package Sizes</title>
<link>https://coderlegion.com/3032/meet-hippoo-the-lightning-fast-cli-tool-every-dev-needs-to-check-npm-package-sizes</link>
<description>&lt;h3 id=&quot;introducing-hippoo-a-blazing-fast-cli-tool-that-helps-you-analyze-and-compare-npm-package-sizes-before-you-install-them-built-by-james-akpan&quot;&gt;Introducing Hippoo — a blazing-fast CLI tool that helps you analyze and compare npm package sizes before you install them. Built by &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/codiejay/&quot;&gt;James Akpan&lt;/a&gt;&lt;/h3&gt;
&lt;blockquote&gt;&lt;p&gt;“Don’t just install it. Inspect it.”&lt;br&gt;
— &lt;em&gt;Hippoo’s unspoken philosophy&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In the age of bloated bundles and performance-first web apps, &lt;strong&gt;Hippoo&lt;/strong&gt; steps in like a digital bodyguard. — Hippoo is a smart, sleek CLI tool that helps you &lt;strong&gt;check and compare npm package sizes&lt;/strong&gt; &lt;em&gt;before&lt;/em&gt; they enter your codebase.&lt;/p&gt;
&lt;p&gt;No more surprises. No more blind installs.&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;what-is-hippoo-&quot;&gt;What is Hippoo?&lt;/h3&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;Hippoo&lt;/strong&gt; (yes, with two o's) is a lightning-fast command-line tool to analyze and compare npm packages — giving you clear insights about:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Minified &amp;amp; Gzipped Size&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Dependency Count&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;️ &lt;strong&gt;Download Time&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tree-shaking Support&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Hippoo Score (0–10)&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Smart Recommendations&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Hippoo answers the real dev questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;Is this package too heavy?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Should I choose React or Angular?&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Will this slow down my app?&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;installation-4&quot;&gt;Installation&lt;/h3&gt;
&lt;p&gt;You can install Hippoo globally using either &lt;strong&gt;npm&lt;/strong&gt; or &lt;strong&gt;yarn&lt;/strong&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Using npm
npm install -g hippoo

# Using yarn
yarn global add hippoo
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;basic-usage&quot;&gt;Basic Usage&lt;/h3&gt;
&lt;p&gt; Check a single package:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;hippoo react@18.0.0
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;-compare-multiple-packages-&quot;&gt;⚖️ Compare multiple packages:&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;hippoo compare react angular
&lt;/code&gt;&lt;/pre&gt;
&lt;h3 id=&quot;-sample-output-real-example-&quot;&gt;✨ Sample Output (Real Example)&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;hippoo compare react angular
&lt;/code&gt;&lt;/pre&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;&lt;th&gt;Metric        &lt;/th&gt;&lt;th&gt;React   &lt;/th&gt;&lt;th&gt;Angular&lt;/th&gt;&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;&lt;td&gt;Size          &lt;/td&gt;&lt;td&gt;7.4 kB  &lt;/td&gt;&lt;td&gt;181.0 kB&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Gzipped       &lt;/td&gt;&lt;td&gt;2.8 kB  &lt;/td&gt;&lt;td&gt;62.3 kB&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Download Time &lt;/td&gt;&lt;td&gt;1ms     &lt;/td&gt;&lt;td&gt;2ms&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Dependencies  &lt;/td&gt;&lt;td&gt;0       &lt;/td&gt;&lt;td&gt;0&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Tree-Shake    &lt;/td&gt;&lt;td&gt;❌       &lt;/td&gt;&lt;td&gt;❌&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td&gt;Hippoo Score  &lt;/td&gt;&lt;td&gt;8/10  &lt;/td&gt;&lt;td&gt;6/10&lt;/td&gt;&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;&lt;strong&gt; Best for Performance-Critical Apps&lt;/strong&gt;: React&lt;br&gt;
&lt;strong&gt; Best for Feature-Rich Projects&lt;/strong&gt;: Angular&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;-command-reference&quot;&gt;️ Command Reference&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;hippoo [package-name] [options]
hippoo compare [pkg1] [pkg2] [...]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Options&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-v, --version&lt;/code&gt; → Show version number&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-d, --detailed&lt;/code&gt; → Show detailed breakdown&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-j, --json&lt;/code&gt; → Output results in JSON&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;-h, --help&lt;/code&gt; → Show help info&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;why-use-hippoo-&quot;&gt;Why Use Hippoo?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt; Size Analysis&lt;/strong&gt; — Know what you're adding.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;⚖️ Package Comparison&lt;/strong&gt; — Pick the better tool.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt; Performance Insights&lt;/strong&gt; — Stay light and fast.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt; Smart Recommendations&lt;/strong&gt; — Use the right tool for the task/project.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h3 id=&quot;resources&quot;&gt;Resources&lt;/h3&gt;
&lt;p&gt; &lt;a rel=&quot;nofollow&quot; href=&quot;https://hippoo-sigma.vercel.app/&quot;&gt;Official Website&lt;/a&gt;&lt;br&gt;
 &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/codiejay/hippoo&quot;&gt;GitHub Repository&lt;/a&gt;&lt;br&gt;
 &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/codiejay/hippoo/blob/master/LICENSE&quot;&gt;MIT License&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h3 id=&quot;final-thoughts-3&quot;&gt;Final Thoughts&lt;/h3&gt;
&lt;p&gt;Hippoo isn’t just a tool.&lt;br&gt;
It’s a mindset — inspect before install.&lt;br&gt;
Analyze before adding. Optimize before bloating.&lt;br&gt;
Big ups to &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/codiejay&quot;&gt;@codiejay (James Akpan)&lt;/a&gt; for building something every dev can use. Let’s support, test, and spread the word. &lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Next time you go to install a package, pause and ask: &lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;&lt;p&gt;&lt;strong&gt;“Did I Hippoo it first?” &lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt; Feel free to share thoughts, issues, or praise in the comments. And if you're vibing with Hippoo, don’t forget to ⭐ the repo!&lt;/p&gt;
</description>
<category>Web Dev</category>
<guid isPermaLink="true">https://coderlegion.com/3032/meet-hippoo-the-lightning-fast-cli-tool-every-dev-needs-to-check-npm-package-sizes</guid>
<pubDate>Wed, 14 May 2025 23:27:57 +0000</pubDate>
</item>
<item>
<title>How I Automated Git Commands Using Batch Scripting</title>
<link>https://coderlegion.com/1828/how-i-automated-git-commands-using-batch-scripting</link>
<description>&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=13889840755604606807&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;In this article, I will show you how I automated Git commands using &lt;a rel=&quot;nofollow&quot; href=&quot;https://www.seobility.net/en/wiki/Batch_Scripting&quot;&gt;Batch Scripting&lt;/a&gt; on Windows. &lt;/p&gt;
&lt;p&gt;As a developer, there are some Git commands that are very fundamental to my work. However, it gets tedious many times when you have to fire up your terminal, type in git commands, and then hit &quot;Enter&quot; on the keyboard for to run each command. Sometimes this process is repeated up to 10 times a day.&lt;/p&gt;
&lt;p&gt;Therefore, I thought there must be a way to automate Git commands so that I do not have to manually type and run Git commands again. &lt;/p&gt;
&lt;p&gt;I know, some might say why not just use Git desktop instead? Well, I love the terminal, and how it does not abstract my interaction with Git and Github. &lt;/p&gt;
&lt;p&gt;So, I have written a Batch Script to automate my most used Git commands on my Windows machine and make my life a little easier. But first, what is Batch Scripting?&lt;/p&gt;
&lt;h4 id=&quot;batch-scripting-explained&quot;&gt;&lt;strong&gt;Batch Scripting Explained&lt;/strong&gt;&lt;/h4&gt;
&lt;p&gt;Batch scripting refers to creating scripts (text files containing commands) for the Windows command prompt (cmd.exe) using the batch file language. These scripts have a .bat or .cmd file extension and automate repetitive tasks by executing a series of commands sequentially.&lt;/p&gt;
&lt;h4 id=&quot;key-characteristics-of-batch-scripting-&quot;&gt;&lt;strong&gt;Key Characteristics of Batch Scripting:&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;File Extension: .bat or .cmd&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interpreter: Windows Command Processor (cmd.exe)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Purpose: Automates command sequences that would otherwise be typed manually&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Syntax: Simple, line-by-line command execution with some programming constructs&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;common-uses-of-batch-scripting-&quot;&gt;&lt;strong&gt;Common Uses of Batch Scripting:&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Automating file operations (copy, move, delete)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Installing software silently&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;System maintenance tasks&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Launching programs in sequence&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Simple system administration tasks&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;advantages-&quot;&gt;&lt;strong&gt;Advantages:&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Easy to learn and use&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No special tools required (just Notepad)&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Built into all Windows systems&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Quick for simple automation tasks&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&quot;limitations-&quot;&gt;&lt;strong&gt;Limitations:&lt;/strong&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Limited programming features compared to PowerShell or Bash&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No advanced error handling&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Windows-specific (not cross-platform)&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that we know what Batch Scripting is, let me show you how I used it to automate Git CLI on my Windows computer.&lt;/p&gt;
&lt;p&gt;My most used Git commands are as follows:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;git init&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git remote add origin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git branch -M&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git add .&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git status&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git commit -m&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git push -u origin main&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;True, these are basic Git commands (and I use much more commands than these). However, because Batch Scripting runs sequentially, these are /the commands that typically follow one another when creating and pushing code/files to a Github repository; making them the easiest commands to automate.&lt;/p&gt;
&lt;p&gt;That said, you can also write Batch Scripts to independently automate each Git command if you wish.&lt;/p&gt;
&lt;h3 id=&quot;batch-scripting-git-commands-&quot;&gt;&lt;strong&gt;Batch Scripting Git Commands &lt;/strong&gt;&lt;/h3&gt;
&lt;p&gt;Here is the Batch Script that I used to automate the above Git commands:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;@echo off
:: Clear the screen
cls

set /p choice=&quot;Enter name of folder: &quot;

:: Changes into the directory of interest
cd &quot;%USERPROFILE%\Documents\%choice%&quot;

:: Ask if the user wants to initialize Git
set /p git_init=&quot;Initialize Git? (yes/no): &quot;
if /i &quot;%git_init%&quot;==&quot;yes&quot; (
    git init
)

:: Get the Git remote repository URL
set /p git_remote_url=&quot;Enter Git remote repo URL: &quot;
if not &quot;%git_remote_url%&quot;==&quot;&quot; (
    git remote add origin &quot;%git_remote_url%&quot;
)

:: Get the branch name
set /p git_branch=&quot;Name of branch? &quot;
if not &quot;%git_branch%&quot;==&quot;&quot; (
    git branch -M &quot;%git_branch%&quot;
)

:: Ask if the user wants to add files to staging
set /p git_add=&quot;Add to staging area? (yes/no): &quot;
if /i &quot;%git_add%&quot;==&quot;yes&quot; (
    git add .
)

:: Get the commit message
set /p git_commit_message=&quot;Enter commit message: &quot;
if not &quot;%git_commit_message%&quot;==&quot;&quot; (
    git commit -m &quot;%git_commit_message%&quot;
)

:: Ask if the user wants to push
set /p git_push=&quot;Push to branch '%git_branch%'? (yes/no): &quot;
if /i &quot;%git_push%&quot;==&quot;yes&quot; (
    git push -u origin &quot;%git_branch%&quot;
)

:: Pause the script to view results
pause
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The script begins by ensuring the terminal output is clean and easy to follow. It disables command echoing with &lt;code&gt;@echo off&lt;/code&gt; and clears the screen using &lt;code&gt;cls&lt;/code&gt;. This provides a tidy interface for the user.&lt;/p&gt;
&lt;p&gt;Next, the script prompts the user to specify the name of a folder located in their Documents directory:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set /p choice=&quot;Enter name of folder: &quot;
cd &quot;%USERPROFILE%\Documents\%choice%&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This dynamic approach allows the script to work with any project folder the user specifies, without hardcoding paths.&lt;/p&gt;
&lt;p&gt;Once inside the target directory, the script offers to initialize a Git repository. Using a simple yes/no prompt, the user can choose to run &lt;code&gt;git init&lt;/code&gt;. The inclusion of &lt;code&gt;/i&lt;/code&gt; in the condition makes the comparison case insensitive, accepting &quot;yes&quot;, &quot;YES&quot;, or &quot;Yes&quot; equally:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set /p git_init=&quot;Initialize Git? (yes/no): &quot;
if /i &quot;%git_init%&quot;==&quot;yes&quot; (
    git init
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Following initialization, the user is prompted to provide a remote repository URL. If a URL is supplied, the script adds it as the &lt;code&gt;origin&lt;/code&gt; remote:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set /p git_remote_url=&quot;Enter Git remote repo URL: &quot;
if not &quot;%git_remote_url%&quot;==&quot;&quot; (
    git remote add origin &quot;%git_remote_url%&quot;
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The script then moves on to branch management. It asks the user to name their branch and, if provided, renames the current branch accordingly:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set /p git_branch=&quot;Name of branch? &quot;
if not &quot;%git_branch%&quot;==&quot;&quot; (
    git branch -M &quot;%git_branch%&quot;
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then, it collects a commit message and, if one is entered, creates the initial commit:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set /p git_commit_message=&quot;Enter commit message: &quot;
if not &quot;%git_commit_message%&quot;==&quot;&quot; (
    git commit -m &quot;%git_commit_message%&quot;
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Finally, the script offers to push the changes to the remote repository. If the user agrees, it pushes the commits to the specified branch, setting the upstream branch for future pushes:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;set /p git_push=&quot;Push to branch '%git_branch%'? (yes/no): &quot;
if /i &quot;%git_push%&quot;==&quot;yes&quot; (
    git push -u origin &quot;%git_branch%&quot;
)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;At the end of the script, pause keeps the terminal window open, giving the user a chance to review the output before closing.&lt;/p&gt;
&lt;p&gt;In order to write your Batch Script, open any text editor on your computer like Notepad, write your Batch commands, and save it as a &lt;code&gt;.BAT&lt;/code&gt; file.&lt;/p&gt;
&lt;p&gt;To run the script, simply double-click on it.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://coderlegion.com/?qa=blob&amp;amp;qa_blobid=17386973485924081884&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;p&gt;To see the Git automation script in action, you can check out this &lt;a rel=&quot;nofollow&quot; href=&quot;https://github.com/Ifeanyi55/Batch-Script-Automation&quot;&gt;GitHub repository&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You can also download and adapt other automation scripts in the repo for your use case. You can star and contribute to the repository, too :).&lt;/p&gt;
&lt;p&gt;I hope this article has helped you get started with automating repetitive tasks on your computer. If yes, then please like and share with others it might benefit.&lt;/p&gt;
&lt;p&gt;Here are other helpful resources to get you started with Batch Scripting:&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.seobility.net/en/wiki/Batch_Scripting&quot;&gt;https://www.seobility.net/en/wiki/Batch_Scripting&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://en.ryte.com/wiki/Batch_Programming/&quot;&gt;https://en.ryte.com/wiki/Batch_Programming/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://www.tutorialspoint.com/batch_script/index.htm&quot;&gt;https://www.tutorialspoint.com/batch_script/index.htm&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel=&quot;nofollow&quot; href=&quot;https://exercism.org/tracks/batch&quot;&gt;https://exercism.org/tracks/batch&lt;/a&gt;&lt;/p&gt;
</description>
<category>Automation Tools</category>
<guid isPermaLink="true">https://coderlegion.com/1828/how-i-automated-git-commands-using-batch-scripting</guid>
<pubDate>Wed, 09 Apr 2025 19:04:19 +0000</pubDate>
</item>
</channel>
</rss>