Puppet Core 8.19 and PDK 3.7: Security Updates, Dependency Changes, and Windows Fixes

Puppet Core 8.19.0 focuses largely on security hardening, with some dependency cleanup and a small but important fix for Windows user management.

If you already run Puppet Core 8, this release is primarily about keeping your runtime secure and predictable, rather than introducing new workflows or configuration changes.

➡️ Full details: Puppet Core 8.19.0 release notes

PDK 3.7.0 was also released to improve performance on Windows, update dependencies, and provide other updates for security and known issues.

➡️ Full details: PDK 3.7.0 release notes

CSV gem dependency removed

Puppet Core no longer depends on the CSV Ruby gem.

  • Removes an external dependency from the Puppet runtime
  • Reduces overall dependency surface area
  • Simplifies installation and long-term maintenance

This change does not alter Puppet DSL behavior or require configuration changes.

Security updates

Puppet Core 8.19.0 updates several bundled runtime components to address recently disclosed security vulnerabilities. These updates apply automatically when you upgrade.

  • Ruby updated to 3.2.11 (CVE-2026-27820)
  • OpenSSL updated to 3.0.20 (CVE-2026-28387, CVE-2026-28388, CVE-2026-28389, CVE-2026-28390, CVE-2026-31789, CVE-2026-31790)
  • libxml2 updated to 2.15.3 (CVE-2026-6732)
  • curl updated to 8.20.0 (CVE-2026-6253, CVE-2026-6276, CVE-2026-6429, CVE-2026-7009, CVE-2026-7168)
  • net-imap updated to 0.4.24 (CVE-2026-42245, CVE-2026-42246, CVE-2026-42256, CVE-2026-42257, CVE-2026-42258)
  • erb updated to 6.0.4 (CVE-2026-41316)

ℹ️ Important note for net-imap users

If you use net-imap directly in custom Ruby code, the updated version enforces stricter argument validation. Check the release notes for some details on how to manage this gem if you cannot use the upgraded version of net-imap.

Windows user passwords now allow colons

When managing user resources on Windows, Puppet Core no longer rejects passwords containing colons (:).

  • Affects Windows platforms only
  • Behavior on other platforms is unchanged

This prevents unnecessary failures when managing Windows accounts with valid password formats.

Installation safeguards for Ruby versions

Puppet Core now prevents installation on unsupported Ruby versions.

  • Puppet Core 8 enforces a maximum supported Ruby version of 3.x
  • Prevents installation attempts using unsupported versions (such as Ruby 4)
  • Protects against installation failures like can't modify frozen Hash

This applies when installing Puppet Core via bundler or gem commands.

PDK 3.7.0 changes

This version of PDK was updated to help prevent security issues and reduce test failures, and made macOS 15 downloads available.

  • Rexml updated to version 3.4.4 to address CVE-2025-58767
  • macOS 15 downloads now available
  • Windows performance has been improved
  • YAML file validation issues should be resolved
  • Several puppet_forge gems and dependencies were updated

Should you upgrade?

Upgrading to Puppet Core 8.19.0 is recommended for Puppet Core 8.x users if:

  • You want current security fixes for bundled runtime dependencies
  • You manage Windows users with complex passwords
  • You want to avoid accidental installation on unsupported Ruby versions

Want to get started? Here are the install/upgrade guides:

For full details and CVE listings, see the release notes:

➡️ Puppet Core 8.19.0 release notes
➡️ PDK 3.7.0 release notes

10 Linux Commands That Made the Terminal Less Scary for Me

I still remember the exact moment I opened the Linux terminal for the first time.

Black screen. Blinking cursor. Absolute silence.

No icons, no buttons, no “click here to continue.” Just this tiny blinking thing waiting for me to type something — anything — and I had absolutely no idea what to say to it.

My first reaction, honestly? I closed it.

Then I opened it again because I felt embarrassed closing it, even though I was alone.

I ended up doing what every beginner does: copying random commands from Stack Overflow without really understanding what they did. Sometimes things worked. Sometimes I’d accidentally delete a file I needed. Once I somehow broke my entire home directory setup and had to reinstall things.

But here’s what I eventually figured out — Linux wasn’t hard because it was complicated. It was hard because it was unfamiliar. Once a few commands started making sense, the whole thing clicked differently.

If you’re a CS student, a beginner dev, or someone just getting into backend or DevOps, here are the 10 commands that genuinely made the terminal less terrifying for me.

First, Why Does Linux Even Matter?

Honestly, for a while I thought Linux was one of those “nice to have” skills that senior devs recommend but you can probably skip.

You can’t really skip it.

Servers run Linux. Cloud infrastructure runs Linux. Docker, DevOps pipelines, most backend environments — Linux is just quietly everywhere. At some point it stops being optional and becomes part of your actual workflow.

The good news is you don’t need to learn hundreds of commands to feel comfortable. You just need a solid handful to start.

1. pwd — “Wait, Where Am I?”

The terminal doesn’t show you where you are by default. That’s confusing at first.

pwd

This prints your current working directory — basically your location in the file system. It stands for print working directory.

I used this constantly when I was learning. Still use it more than I’d like to admit.

2. ls — See What’s Around You

Want to see what files and folders are in your current location?

ls

Want more details like file sizes and permissions?

ls -l

Want to also see hidden files (files that start with a dot)?

ls -la

ls becomes muscle memory pretty fast. You’ll type it without thinking after a week.

3. cd — Actually Move Around

Navigation. This one’s essential.

cd Documents

Go back one level:

cd ..

Jump straight to your home directory:

cd ~

Once you get used to cd, clicking through folders in a file manager starts feeling weirdly slow. It’s one of those small things that makes the terminal feel worth it.

4. mkdir — Create a Folder Without the Right-Click

mkdir my-project

That’s it. New folder, done.

No right-clicking, no naming dialog box, no confirmation window. Just instant. Linux really does value speed and efficiency, and mkdir is a small example of that.

5. touch — Create an Empty File

Need a new file quickly?

touch index.html
touch app.py

It creates an empty file with that name. Nothing fancy, but when you’re setting up a project structure, this saves you a surprising amount of time.

6. cp and mv — Copy, Move, and Rename

Copy a file:

cp notes.txt notes-backup.txt

Move a file to a different folder:

mv notes.txt ~/Documents/notes.txt

Rename a file (it’s the same command, just staying in the same place):

mv old-name.txt new-name.txt

The rename thing tripped me up for a bit — I kept looking for a separate rename command. Turns out mv just does it.

7. rm — Delete Things (Carefully)

Delete a file:

rm file.txt

Delete a folder and everything inside it:

rm -r foldername

Important heads-up: Linux usually won’t ask if you’re sure. It just deletes. No trash bin, no undo.

This is how beginners learn to be careful. Usually after losing something they needed.

If you want it to prompt you before deleting, you can use rm -i, but honestly most people just learn the habit of double-checking before they run it.

8. cat — Read a File Without Opening an Editor

cat notes.txt

This just prints the file contents straight into your terminal. Super useful for quickly checking configs, reading log files, or just seeing what’s in something without bothering to open a text editor.

It’s one of those commands that seems almost too simple at first, then you realize you’re using it constantly.

9. grep — Search Inside Files

This one felt like a superpower once I actually understood it.

grep "error" logs.txt

This searches through logs.txt and shows you every line that contains the word “error.”

Once you start debugging real applications or reading through server logs, grep becomes one of your most-used tools. You can search through hundreds of lines instantly instead of scrolling through everything manually.

You can also combine it with other commands using pipes, but that’s a rabbit hole for another day.

10. history — Your Terminal Remembers Everything

Forgot a command you typed earlier?

history

This shows your command history. Every command you’ve run, listed out.

You can also press the Up arrow to cycle through recent commands one by one, which I use constantly.

history has saved me more times than I can count — especially when I’ve run some complex command that worked, and then immediately forgot what I typed.

🎁 Bonus: man — The Manual That’s Actually Built Into the Terminal

This one I wish someone had told me about on day one.

Every time I didn’t understand what a command did or what flags were available, I’d go Google it. That works fine, but there’s a faster option that’s always right there:

man ls
man grep

man stands for manual. It opens the official documentation for whatever command you pass it — right inside the terminal, no browser needed.

So instead of searching “ls command options linux,” you can just type man ls and get the full breakdown: what the command does, every available flag, examples, all of it.

Use the arrow keys to scroll, and press q to quit and go back to your terminal.

Fair warning: man pages are pretty dense and not exactly written for beginners. But once you get used to the format, it’s genuinely useful — especially when you’re working on a remote server with no internet access and need to look something up.

It’s also just a good habit. Gets you comfortable reading documentation instead of always reaching for a tutorial.

What the Terminal Actually Teaches You

When I started, I thought learning Linux was about memorizing commands. The more time I spent in the terminal, the more I realized it’s teaching you something else.

It teaches you how computers actually work. Files, permissions, processes, how things are structured under the hood. GUI applications hide all of this. The terminal just shows it to you directly.

You don’t need to become an expert overnight. Just open the terminal, use it a little every day, and experiment. Break things, fix them, look stuff up. It gets less intimidating pretty quickly.

Everyone who looks comfortable in the terminal today was once staring at that same blinking cursor thinking, “I have no idea what I’m doing.”

The cursor was just waiting for a first command.

What was your first terminal experience like? Was there a command that finally made things click for you? Drop it in the comments — I’d love to know.

Trace Continuity vs Mem0 vs Zep: AI Memory Governance Compared

Mem0 and Zep are solid memory retrievers. But neither solves governance. Here’s the technical breakdown of what that gap means if you’re building AI agents in regulated environments.

The question developers are actually asking in 2026

The AI memory market has consolidated. Mem0 and Zep are the two best-known players. Well-funded, well-documented, widely used.

But there’s a different question under the surface in enterprise evaluations: “What happens to the data?”

  • Who has access to what agents remember?
  • Can we prove we deleted a user’s data when they asked?
  • Is PII getting stored in our AI memory layer without us knowing?
  • Can our compliance team audit what the agent knew and when?

Mem0 and Zep don’t have great answers to those questions. That’s not a knock — it’s a design choice. They built memory retrieval infrastructure. Governance was not the problem they were solving.

This comparison is for developers evaluating all three options with compliance in the picture.

The short version

Trace Continuity Mem0 Zep
Best for Regulated industries, compliance-first teams Fast onboarding, broad ecosystem Temporal reasoning, knowledge graphs
PII auto-redaction ✅ Pre-storage, 15+ types ❌ Not a feature ❌ Not a feature
Retention policies ✅ Configurable TTL, auto-expiry ❌ Not available ❌ Not a feature
Audit logging ✅ Every read/write/delete ❌ None ❌ None
Multi-tenant isolation ✅ Architecture-level ⚠️ Namespace-level ⚠️ Application-level
GDPR deletion proof ✅ Immutable deletion record ❌ Manual ❌ Manual
Free tier ✅ Generous ✅ 10K memories ⚠️ 1,000 credits (minimal)

Memory storage: all three solve the same retrieval problem

Mem0

Mem0’s core is a vector store with an extraction layer. When you call client.add(), it runs the conversation through an LLM that extracts key facts, stores them as embeddings, and resolves conflicts. client.search() retrieves by semantic similarity.

const client = new MemoryClient({ api_key: process.env.MEM0_API_KEY });
await client.add("User prefers concise responses and hates jargon", { user_id: "alice" });
const memories = await client.search("communication style", { user_id: "alice" });

Excellent for personalization. The ecosystem breadth — 21 framework integrations, MCP server, AWS Bedrock, LangChain, CrewAI — is unmatched. Graph memory (Pro tier, $249/mo) is the most-cited developer complaint.

Zep

Zep’s differentiator is Graphiti — a temporal knowledge graph where every fact has a validity window. “Alice is the project lead” becomes a node with a start time. When Alice steps down, the old fact is invalidated (not deleted). This enables temporal reasoning: “What did the agent know about Alice’s role last quarter?”

await zep_client.thread.add_messages(thread_id, messages=[
    Message(name="Alice", role="user", content="I'm stepping down as project lead next month.")
])
context = zep_client.thread.get_user_context(thread_id="thread_id", mode="basic")

Zep scores 63.8% on LongMemEval vs Mem0’s 49.0% — a real gap for temporal reasoning tasks. Trade-off: Community Edition deprecated April 2025, self-hosting now requires Graphiti + graph database operational overhead.

Trace Continuity

Trace Continuity stores memories as text with semantic search for retrieval. The focus is what happens to data before and after storage: who redacted what, who accessed what, when things expire.

const response = await fetch('https://tracecontinuity.com/v1/memories', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${process.env.TCL_API_KEY}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({
    content: "Patient John Smith (SSN 078-05-1120) prefers morning appointments.",
    agent_id: "intake-bot",
    ttl_days: 365
  })
});
// What gets stored: "Patient [REDACTED] prefers morning appointments."
// Governance events logged: PII_REDACTED (SSN), PII_REDACTED (name)
// TTL set: auto-expires after 365 days

One API call. Every governance action happens automatically.

The governance gap: what neither competitor solves

PII redaction

In a healthcare or fintech context, your AI agents receive inputs that may contain SSNs, credit card numbers, email addresses, dates of birth, names — and that context gets stored as memory.

Neither Mem0 nor Zep runs a PII scan before storage. If your agent passes “Patient DOB: 1978-04-15, SSN: 078-05-1120” to Mem0’s add(), that data enters the vector store as-is.

Trace Continuity runs PII redaction as part of the write path — before anything touches storage. The original text never reaches the database.

Retention policies

Neither Mem0 nor Zep has configurable retention policies as a product feature. You can delete memories manually, but there’s no “expire memories after 90 days” capability built in.

Trace Continuity enforces TTL at the infrastructure layer. Set ttl_days: 90 and the memory auto-purges. Per-tenant policies can enforce maximum retention regardless of what individual agents specify.

Audit logging

With Mem0 or Zep, the answer to “show me every time an AI agent accessed patient memory records last quarter” is: “We don’t have that.”

With Trace Continuity, every read, write, and delete generates an immutable governance event: agent ID, tenant, timestamp, action type, what was redacted.

Multi-tenant isolation

Mem0 uses namespace-level isolation (user_id or app_id parameters). If the application layer passes the wrong user ID — memories can leak across tenants.

Trace Continuity enforces isolation at the architecture layer. The API key itself is scoped to a tenant. A mismatch returns a 403 — not a filtered result, a hard rejection.

The code comparison

Mem0 — writing memory:

await client.add([{ role: "user", content: userInput }], { user_id: userId });
// Stored as-is. No PII scan. No TTL. No audit record.

Zep — writing memory:

await zep.thread.add_messages(thread_id, messages=[Message(role="user", content=user_input)])
# Stored in temporal knowledge graph. No PII scan. No TTL. No audit record.

Trace Continuity — writing memory:

const res = await fetch('https://tracecontinuity.com/v1/memories', {
  method: 'POST',
  headers: { 'Authorization': `Bearer ${apiKey}`, 'Content-Type': 'application/json' },
  body: JSON.stringify({ content: userInput, agent_id: agentId, ttl_days: 90 })
});
// PII scanned and redacted before storage.
// TTL set: auto-purge after 90 days.
// Governance event logged: who wrote what, when, what was redacted.
// Tenant isolation enforced at the API key layer.

The code differences reflect the architecture. You can’t bolt these capabilities onto Mem0 or Zep in application code and get the same guarantee — the guarantee comes from the infrastructure running before your code can make mistakes.

When to use each

Choose Mem0 if: You need the fastest path to production, building a consumer product with no regulated data, need ecosystem breadth (LangChain, CrewAI, AWS Bedrock, Vercel AI). ~52K GitHub stars. The default choice when governance isn’t a constraint.

Choose Zep if: Temporal reasoning is core to your use case — facts that change over time, validity windows, superseded facts. Research tools or knowledge graph applications. LongMemEval advantage (63.8% vs 49.0%).

Choose Trace Continuity if: Building in healthcare, fintech, HR tech, legal, insurance, or government. Your compliance team is involved. You need PII handled before storage — not cleaned up afterward. You’ve been asked “how do we handle memory deletion requests?” by a lawyer or auditor.

Pricing summary

Trace Continuity Mem0 Zep
Free 500 memories, full governance 10K memories 1,000 credits
Entry paid $99/mo $19/mo (no graph) Usage-based
Graph memory Vector + semantic $249/mo (Pro) Included (Graphiti)
BAA available ✅ Enterprise ✅ Enterprise ✅ Enterprise

Governance is included at every Trace Continuity tier, not sold separately.

Bottom line

Mem0 = best-in-class general-purpose memory with minimal setup friction. Dominates on ecosystem and ease of use.

Zep = best-in-class for temporal knowledge graphs. When you need to model how facts evolve over time.

Trace Continuity = built for the question neither competitor was designed to answer: what happens to the data? If your answer to that question affects your company’s legal and compliance posture, it’s the right infrastructure.

Try the Playground to test PII redaction in 30 seconds — no API key required. Or get started free →.

Originally published on Trace Continuity Labs

Claude-ITect-Skills

I’ve been trying to make a personalized skill pack (but it’s all timey-whimey) and would love to hear from everyone’s feedback. I am trying to make this skill pack customize itself to the project you place it in. When you install, then run the /audit command, it executes a series of commands in the background (and foreground), to update itself and your other skills to be aligned with your actual project goals and ensure you have what you need. There are other personality features as well but let’s not give it away here….spoilers!

GitHub logo

jchildree
/
Claud-itect-Skill

A curated skill pack for Claude Code. Installs 48 skills, 4 agent definitions, caveman session hooks into any project in one command, and thefuck fixes any mistakes that occur….when you need it.

v2_watermarked-b7140b17-61e1-49ca-91d1-951ab140b39b

Claude-ITect-Skill

A personalized curated skill pack for Claude Code. Installs 48 skills, 4 agent definitions, caveman session hooks into any project in one command, and thefuck fixes any mistakes that occur….when you need it. But the real magic happens during setup. So give it a shot, and let me know what could be better!

After installation start with running:

  • audit

Prerequisites

Install

Windows

  1. Open PowerShell (search “PowerShell” in the Start menu).
  2. Navigate to your project:
    cd "C:pathtoyourproject"
  3. Run the installer — replace the path with wherever you saved the skill pack:
    powershell -ExecutionPolicy Bypass -File "C:pathtoClaude-ITect-Skill-2install.ps1"

    To install into a specific project instead of the current directory:

    powershell -ExecutionPolicy Bypass -File "C:pathtoClaude-ITect-Skill-2install.ps1" -ProjectPath "C:pathtoyourproject"
Flag Effect
-Force Overwrite skills that already exist
-SkipHooks

…

Authentication Looks Easy – Until You Build It for Real Users

Most authentication systems don’t fail because developers can’t implement login. They fail because production security is very different from tutorial security.

What I learned after moving beyond tutorial-style authentication systems.

Every developer thinks authentication is easy.

Until they build it for real users.

The tutorials make it feel simple:

  • create JWT,
  • verify token,
  • protect routes,
  • done.

And technically?

That works.

But production authentication is not just about making login functional.

It’s about:

  • managing trust,
  • controlling sessions,
  • handling compromise,
  • preventing abuse,
  • and designing systems that remain secure after things go wrong.

That’s the part most tutorials never teach.

And that’s where most authentication systems quietly fail.

“A login system that works is not the same thing as a secure authentication system.”

The Tutorial Trap

Most developers learn authentication from tutorials.

Which makes sense.

Tutorials are optimized for:

  • simplicity,
  • speed,
  • and getting something working quickly.

But production systems operate under completely different constraints.

Real authentication systems need to handle:

  • stolen tokens,
  • leaked sessions,
  • password reset abuse,
  • brute force attacks,
  • session revocation,
  • suspicious devices,
  • and compromised accounts.

Tutorial authentication teaches:

“How to sign users in.”

Production authentication asks:

“What happens after trust is compromised?”

That is a completely different mindset.

Storing JWTs in localStorage

This is still one of the most common mistakes in modern web applications.

And it usually happens because localStorage feels convenient.

You login.

Store the token.

Read it later.

Simple.

The problem is that anything running JavaScript on your page can access it.

That includes:

  • malicious scripts,
  • compromised third-party libraries,
  • XSS vulnerabilities,
  • browser extensions,
  • or injected analytics code.

If attackers gain JavaScript execution inside your application, they can silently extract authentication tokens and impersonate users.

The application still appears normal.

The user never notices.

That’s what makes it dangerous.

A safer approach is using httpOnly cookies.

These cookies:

  • cannot be accessed by JavaScript,
  • are automatically handled by the browser,
  • and significantly reduce token theft risks from XSS attacks.

Yes, this introduces CSRF considerations.

But modern protections like:

  • SameSite,
  • secure cookies,
  • and CSRF tokens

make this a far safer tradeoff.

“Most authentication systems are not broken in obvious ways. They’re broken in ways teams discover only after incidents happen.”

Logout That Doesn’t Actually Log Users Out

This is one of the most misunderstood parts of JWT authentication.

A user clicks logout.

The frontend removes the token.

The UI redirects to the login page.

Everything looks correct.

Except the token itself may still be completely valid.

Because JWTs are stateless.

The server usually doesn’t “remember” them.

It simply validates the signature and expiration.

Which means:

  • stolen tokens can continue working,
  • copied sessions remain usable,
  • and logout often becomes a frontend illusion.

JWT solves authentication verification.

It does not automatically solve:

  • session revocation,
  • logout control,
  • or session management.

Production systems usually fix this using:

  • short-lived access tokens,
  • refresh token rotation,
  • token revocation,
  • or server-side session tracking.

Real logout means:

the session is no longer trusted by the server.

Not just hidden from the UI.

Refresh Tokens Are Often Implemented Without Understanding the Security Model

Many developers use refresh tokens mechanically.

Access token expires.

Refresh token generates a new one.

Done.

But the important question is:

what happens if the refresh token itself gets stolen?

If refresh tokens live for 30 days and there’s no revocation mechanism, attackers may retain access for an entire month without detection.

That’s why mature systems use refresh token rotation.

Every refresh:

  • issues a new refresh token,
  • invalidates the previous one,
  • and tracks suspicious reuse attempts.

This limits damage during token compromise and creates visibility into abnormal behavior.

Authentication systems should not just validate trust.

They should monitor trust.

“Forgot Password” Is a Massive Attack Surface

Password reset systems are often treated like convenience features.

They are not.

They are one of the most security-sensitive flows in any application.

And weak implementations are everywhere.

Common Problems

Reset tokens that live too long

Password reset links should expire quickly.

Not tomorrow.

Not next week.

Usually:

  • 15 minutes,
  • maybe 30.

Anything longer unnecessarily increases risk.

Reusable reset tokens

A password reset token should work once.

Only once.

If reset tokens remain reusable, they become persistent backdoors.

After a successful password reset:

  • the token should immediately expire,
  • active sessions should be revoked,
  • and refresh tokens should become invalid.

User enumeration vulnerabilities

Many systems accidentally reveal whether an account exists.

Responses like:

  • “Email not found”
  • “User does not exist”

allow attackers to discover registered accounts.

Production systems should always respond generically:

“If an account exists, a reset link has been sent.”

Regardless of whether the user actually exists.

“Most security problems begin where tutorials end.”

OTP Systems Are Harder Than They Look

OTP authentication appears simple.

Generate code.

Send code.

Verify code.

Done.

Except production OTP systems need to handle:

  • brute force attempts,
  • replay attacks,
  • abuse prevention,
  • expiration handling,
  • and delivery risks.

Without rate limiting, attackers can automate OTP guessing surprisingly quickly.

That’s why production systems need:

  • retry limits,
  • verification throttling,
  • expiration windows,
  • and lockout rules.

OTP reuse is another common issue.

Once an OTP is successfully verified:

it should immediately become invalid.

Not later.

Immediately.

And while SMS OTP is common, it’s also vulnerable to SIM swap attacks.

For higher-security systems:

  • authenticator apps,
  • TOTP,
  • and hardware security keys

are significantly safer options.

Session Tracking Should Be a First-Class Feature

Many applications have no visibility into active sessions.

Users cannot:

  • view logged-in devices,
  • revoke suspicious sessions,
  • monitor account activity,
  • or control session access.

That’s not just missing functionality.

It’s missing security visibility.

Production systems should track:

  • session IDs,
  • devices,
  • timestamps,
  • IP addresses,
  • refresh token mappings,
  • and revocation state.

This enables:

  • device-level logout,
  • anomaly detection,
  • suspicious session monitoring,
  • and better account recovery flows.

Purely stateless authentication sounds elegant.

Until you need actual control.

The Biggest Missing Layer: Security Thinking

Most authentication failures are not caused by poor coding skills.

They happen because developers design for the happy path.

Users login.

Users logout.

Users reset passwords.

Everything works.

But attackers don’t follow happy paths.

Real authentication design starts with uncomfortable questions:

  • What happens if tokens get stolen?
  • What happens if someone brute forces OTP verification?
  • What happens if refresh tokens leak?
  • What happens if sessions never expire?
  • What happens if attackers abuse password reset endpoints?

If those questions were never considered during system design, the application probably has dangerous gaps.

security

backend

webdev

authentication

jwt

“Authentication is not just about verifying identity. It’s about controlling trust securely over time.”

Closing Thoughts

Authentication is one of the few engineering areas where users pay the price for developer shortcuts.

A broken UI might frustrate users.

A broken authentication system can compromise identities, expose sensitive data, and permanently damage trust.

And the dangerous part is that insecure authentication often appears perfectly functional.

The login works.

The JWT validates.

The session continues.

Everything looks fine.

Until it isn’t.

The good news is that secure authentication practices are already well understood:

  • short-lived access tokens,
  • refresh token rotation,
  • secure cookie handling,
  • session revocation,
  • OTP rate limiting,
  • reset token expiration,
  • and security event logging.

None of this is exotic engineering.

It simply requires treating authentication as a real security system instead of a checklist item before building “real features.”

“Authentication is not a feature. It is a long-term trust contract between your system and your users.”

The difference between tutorial authentication and production authentication is the difference between building a demo and building something people can safely trust with their identity.

I Built a Free Stock Market Game You Can Play Right Now — No Login, No Download

What if you could play the stock market like a game without risking a single dollar?

That is exactly what I built. It is a free online stock market game that runs right in your browser — no login, no download, no signup wall.

Just open it and start trading: vinish.dev/stock-market-game-online

The Concept

The idea is simple.

You start with virtual cash and your goal is to grow your portfolio by buying and selling stocks.

Prices move, the market shifts, and you have to make decisions fast. It feels a lot like a strategy game, except everything is based on how real stock markets actually work.

Why It Feels Like a Game

Most finance simulators feel like homework.

This one does not.

Here is what makes the experience feel more like gameplay:

  • You start fresh every session with a set amount of virtual money
  • Stock prices move dynamically so the market is always changing
  • You can buy and sell with a single click — no complex order forms
  • Your portfolio value updates in real time as prices shift
  • There is a competitive angle — you can challenge yourself to beat your previous best

“The stock market is a device for transferring money from the impatient to the patient.” — Warren Buffett

The game actually teaches you that lesson firsthand. Rush in without a plan and your portfolio tanks. Think strategically and you start to see real gains.

Who Is This For

This game is a good fit for a few different types of players:

Player Type Why They Will Enjoy It
Gamers curious about finance Learn how stocks work through actual gameplay
Beginners afraid to invest real money Practice without any financial risk
Students studying economics Hands-on simulation with no setup required
Competitive types Try to beat your high score each session
Anyone who is just bored It is genuinely fun to watch your virtual money grow

How to Play

Getting started takes about 10 seconds.

  1. Go to vinish.dev/stock-market-game-online
  2. You get a starting amount of virtual cash automatically
  3. Browse the available stocks and their current prices
  4. Buy shares in the ones you think will go up
  5. Sell when the price rises to lock in your profit
  6. Watch your portfolio value in real time

No tutorials, no lengthy onboarding. You figure it out by playing, which is the best way to learn anything.

What You Actually Learn While Playing

The game sneaks in some real finance knowledge while you are just having fun.

After a few sessions you start to naturally understand:

  • What a portfolio is and how diversification helps
  • Why timing matters when buying and selling
  • How market volatility can work for you or against you
  • The difference between a gain and a loss on paper vs locking it in
  • Why patience usually beats panic selling

It is surprisingly educational without ever feeling like a lecture.

The Best Part: No Login Required

A lot of browser games hit you with an account wall before you can even see what the game looks like.

This one has zero friction.

You land on the page and you are already playing. No email address, no password, no cookie consent walls that take forever to dismiss.

Just open it and go.

A Quick Comparison

Feature This Game Most Finance Simulators
Login required No Yes
Download needed No Sometimes
Free to play Yes Sometimes freemium
Mobile friendly Yes Hit or miss
Fun factor High Usually low

Conclusion

If you have ever been curious about how the stock market works but never wanted to risk real money, this is the perfect place to start.

And if you already know how trading works, it is still a fun way to kill 20 minutes and see if your instincts hold up under pressure.

Give it a shot and let me know your best portfolio return in the comments — I want to see who can grow their virtual cash the most.

Play it here: vinish.dev/stock-market-game-online

GitHub Agentic Workflows: Building Self-Healing CI for .NET

Agentic Platform Engineering: Self-Healing CI/CD Pipelines

Demo Repository: Check the complete project on GitHub to see the full setup.

My CI failures are usually not dramatic. But they are still annoying.

A test breaks with a NullReferenceException. A Helm chart release failed. I open the logs, trace the problem, fix a tiny mistake, push, and wait for CI again. That is a lot of delay for bugs that are often small.

So I built a workflow for that exact loop. When CI fails, a GitHub Agentic Workflow reads the logs and uploaded artifacts, traces the root cause, and asks for a draft pull request with the fix. I still review it. I still merge it. The agent does the investigation work that normally takes the first 15 minutes.

In this article, I will show you how I built that setup in a standard .NET project, how I fed the agent the evidence it needed, and what happened when I tested it with two deliberate bugs.

What Are GitHub Agentic Workflows?

Getting started: Install the CLI and set up your first workflow by following the official quick start guide.

GitHub Agentic Workflows let you define automation in Markdown with YAML frontmatter. That sounds really simple. The YAML part tells GitHub when the workflow runs, which permissions it gets, and which safe write actions it may request. The Markdown body tells the agent what job to do.

Here is a tiny example:

---
on:
  issues:
    types: [opened]
permissions: read-all
safe-outputs:
  add-comment:
---

# Issue Clarifier

Analyze the current issue and ask for additional details if the issue is unclear.

You compile that file with:

gh aw compile

This creates a .lock.yml file that GitHub Actions can execute. The Markdown file is the source you maintain. The compiled workflow is what runs in CI.

Here, I am not using agentic workflows for summaries or changelogs. Those are straightforward to automate. I care about practical use cases where a failure is easy to address, yet if the CI build fails, someone still has to dig through it.

Setting Up the Project

I used a plain .NET 10 Web API and an xUnit test project. No custom starter kit. Just the templates you already know.

Scaffold the Project

dotnet new sln -n DemoAiPipelines
dotnet new webapi -n OrdersApi -o src/OrdersApi
dotnet new xunit -n OrdersApi.Tests -o tests/OrdersApi.Tests

dotnet sln add src/OrdersApi/OrdersApi.csproj
dotnet sln add tests/OrdersApi.Tests/OrdersApi.Tests.csproj

cd tests/OrdersApi.Tests
dotnet add reference ../../src/OrdersApi/OrdersApi.csproj

Then I added two deliberate bugs.

Bug One: Guest Checkout Crash

This service throws when Customer is null:

public class OrderService
{
    public decimal CalculateDiscount(Order order)
    {
        // BUG: throws NullReferenceException when Customer is null
        var rate = order.Customer.LoyaltyTier switch
        {
            "gold" => 0.15m,
            "silver" => 0.10m,
            _ => 0.05m
        };
        return order.Total * rate;
    }
}

And the test that exposes it:

[Fact]
public void CalculateDiscount_GuestCheckout_ReturnsZero()
{
    var order = new Order(200m, 1, Customer: null);
    var result = _sut.CalculateDiscount(order); // crash here
    Assert.Equal(0m, result);
}

Bug Two: Wrong Port in Helm

The app listens on 8080, but the chart still points at 80:

containers:
  - name: orders-api
    ports:
      - containerPort: 80
    readinessProbe:
      httpGet:
        port: 80

That is enough to make Kubernetes restart the pod forever.

Capture the Evidence

If you want an agent to investigate failures, you need to upload the same logs you would need as a human. For test failures, that means the test output. For deploy failures, that means enough cluster state to explain why the pod never became healthy.

Here is the CI workflow:

# .github/workflows/ci.yml
jobs:
  build-and-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Test
        id: test
        run: dotnet test --logger "trx;LogFileName=results.trx" 2>&1 | tee test-output.txt
        continue-on-error: true
      - name: Upload test evidence
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: test-results
          path: "**/test-output.txt"

  deploy-to-kind:
    needs: build-and-test
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Create KinD cluster
        uses: helm/[email protected]
      - name: Deploy with Helm
        id: helm
        run: |
          helm upgrade --install orders-api ./deploy/helm 
            --wait --timeout 2m 2>&1 | tee helm-output.txt
        continue-on-error: true
      - name: Capture Kubernetes state
        if: steps.helm.outcome == 'failure'
        run: |
          kubectl get pods -o wide > k8s-debug.txt
          kubectl describe pods >> k8s-debug.txt
          kubectl logs -l app=orders-api --tail=50 >> k8s-debug.txt
      - name: Upload deploy evidence
        uses: actions/upload-artifact@v4
        if: always()
        with:
          name: deploy-results
          path: k8s-debug.txt

Writing the Self-Healing Workflow

Now we can define the workflow that reacts to a failed CI run.

Create .github/workflows/self-heal.md:

---
engine:
  id: copilot
  version: latest # defaults to latest
  model: gpt-5
on:
  workflow_run:
    workflows: ["CI"]
    types: [completed]
permissions:
  contents: read
  actions: read
safe-outputs:
  create-pull-request:
    title-prefix: "fix: "
    labels: [ai-fix, self-healing]
    draft: true
    expires: 7
---

# Self-Healing: Fix Failed CI

You are a .NET and DevOps engineer. A CI run has just failed.

## Your Mission

Analyze the failure, find the root cause, and submit a fix as a
pull request.

## Step-by-Step Instructions

1. Check which job failed: `build-and-test` or `deploy-to-kind`.
2. Download the relevant artifact (`test-results` or `deploy-results`).
3. Read the logs to identify the root cause.
4. For test failures: find the exception and fix the source code.
5. For deploy failures: read `k8s-debug.txt` to trace the issue.
   - Cross-reference with the Dockerfile and Helm chart.
6. Open a PR explaining what went wrong and why the fix is correct.

You do not need to overdo the prompt. You do need to tell the agent where the failure lives, which artifact to read, and what kind of output you want back.

Watching It Fix Real Failures

The normal CI workflow ran first. That workflow built the code, ran tests, tried the Helm deployment, and uploaded evidence whether it passed or failed. After that finished, GitHub triggered the compiled agentic workflow through workflow_run.

So the order looked like this:

  1. the regular CI workflow ran
  2. one job failed: test or deploy
  3. CI uploaded the relevant artifact
  4. the compiled self-heal workflow started
  5. the agent downloaded the artifact and investigated
  6. the agent proposed a draft PR

That means the self-healing workflow only woke up after the normal pipeline had already failed and produced evidence. It was not polling. It was not scanning on a schedule. It reacted to a failed run automatically.

For the test failure, the agent downloaded the test-results artifact, found the NullReferenceException, followed the stack trace into OrderService.cs, and proposed the missing null check.

For the deploy failure, it downloaded the deployment evidence, read k8s-debug.txt, saw that the app was listening on 8080 while the probe was still hitting 80, and changed the Helm config to match.

In both cases the result was a draft PR, not a silent commit to the branch.

That was important for me because I wanted to see the exact diff, the explanation, and the reasoning path. I was not trying to hide the process. I wanted the same review surface I would expect from a teammate.

This also made testing the idea straightforward. Break the pipeline on purpose, let the normal CI fail, and watch whether the follow-up workflow can read the evidence and get back to the right fix.

The Real Cost of Self-Healing

The extra cost starts only after CI fails and the self-heal workflow wakes up. You pay for the agent run, the model tokens used to read logs and repo files, and whatever artifact storage and transfer that investigation needs.

So the real way to think about it is cost per failed run. If failures are rare and the artifacts are small, the cost stays low. If builds fail often and every failure uploads huge logs, the bill grows.

A Practical Rollout Plan

If I were rolling this out for a real team, I would keep the scope narrow:

  1. run only after failed CI workflows
  2. restrict it to one or two common failure types
  3. require uploaded evidence before the workflow can act
  4. allow only draft pull requests as output
  5. review every proposed diff manually

That keeps the workflow predictable. It also gives you a clean way to measure the return on cost. I would track three basic numbers from day one:

  1. how many failed runs triggered the workflow
  2. how many proposed PRs were actually correct
  3. how much engineer time those investigations would normally have taken

If the workflow costs a few dollars but saves hours of senior engineering time on repeatable failures, the tradeoff is obvious. If it produces noisy PRs that nobody merges, the token bill is a waste of money.

Where Self-Healing Gets More Interesting

I would not jump straight to “AI fixes everything.” I would expand the triggers one by one.

For example:

  • after deployment, scan pod logs for restart loops or obvious startup exceptions
  • after a health check job, inspect the logs if the app never became ready
  • after a scheduled smoke test, investigate if an endpoint starts failing

That is where self-healing gets interesting. Not a magic system that pushes to production on its own, but a continuous investigator that notices a broken deployment, reads the evidence, and hands you a draft PR.

I still would not let it merge for me. But I would absolutely let it do the boring first pass on failures.

If you want to try the full setup yourself, the demo repo and workflow files are here:

Tip:
Demo Repository:
github.com/bgener/demo-ai-github-pipelines

This article is part of The Modern DevEx Stack series. The next post looks at using MegaLinter in a polyglot repo without turning every pull request into a waiting game.

Building a No-Code AI Agent for WooCommerce Order Analytics with Flowise & HPOS

Flowchart showing the connection between WooCommerce, Flowise AI, and the Mistral LLM

tags: woocommerce, ai, lowcode, wordpress

Introduction

Imagine managing your WooCommerce store by simply asking:

  • “Show me all orders placed by [email protected]“
  • “Products stock level”
  • “What were today’s sales?”

No SQL queries. No complex dashboards. Just plain English.

That’s what I built: a no-code AI agent that connects directly to WooCommerce’s database and answers questions about your store in real-time. In this article, I’ll show you how it works, the challenges with WooCommerce’s new HPOS (High-Performance Order Storage) system, and how to deploy it yourself.

The Problem: WooCommerce Data is Buried

WooCommerce stores order data across multiple MySQL tables with complex relationships. Extracting insights usually requires deep knowledge of:

  • Orders: wp_wc_orders (HPOS) or wp_posts (legacy)
  • Customer Info: wp_wc_order_addresses
  • Order Items: wp_woocommerce_order_items
  • Product Metadata: wp_postmeta (using key-value pairs)
  • Stock Levels: wp_postmeta (meta_key = ‘_stock’)

The Technical Gap: Most store owners aren’t SQL experts. They struggle with JOINs, handling HPOS vs legacy storage differences, and WordPress’s unique meta_key pattern.

The Solution: Natural Language + AI + Direct Database Access

Architecture Overview

Flowchart showing the connection between WooCommerce, Flowise AI, and the Mistral LLM

Discussion & Feedback

I’m curious to hear from the community:

  1. Are you currently using HPOS in your WooCommerce builds, or sticking to legacy storage?
  2. What other “No-Code” AI integrations would be useful for e-commerce?

Let me know in the comments!
Explore the Source Code on GitHub

Watch the AI MySQL Expert handle complex WooCommerce queries in real-time.

Your AI Coding Agent Has Been Flying Blind. Google I/O 2026 Just Fixed That

We have spent the last two years acting as high-priced data messengers between our browsers and our LLMs. At Google I/O 2026, Chrome quietly closed that loop, fundamentally changing how software gets built and verified locally.

Every developer who uses an AI coding agent knows this exact feeling.

The agent writes a beautiful new UI component. You pull it into Chrome. It immediately breaks. The console lights up with a wall of angry red text. You copy the stack trace, paste it back into your LLM chat client, explain what went wrong, and ask it to try again. The agent refines the code. It breaks again, just differently this time. You copy that error and paste it back.

You are the messenger. You are carrying runtime execution realities back to a model that is completely isolated from the environment it’s targeting. The model can write code faster than any human in history, but the part that slows everything down is its complete lack of operational visibility.

At Google I/O 2026, Google announced the structural fix for this disconnect. And almost all the mainstream coverage completely missed it.

The Shiny Future vs. The Immediate Reality

The absolute headline story from the developer keynote has been WebMCP: an open web standard proposal designed to let frontend web apps expose native JavaScript functions directly to browser-based AI agents. Instead of an agent trying to parse HTML structures to click a checkout button, your application explicitly declares its functional endpoint schemas.

It’s an incredible architectural shift, and enterprise giants like Expedia, Shopify, and Instacart are already jumping into the origin trials. But it is exactly that—an origin trial starting in Chrome 149 this June. You cannot ship a web app using it to production today.

Meanwhile, two other developer-focused updates dropped during the technical tracks that are live right now, cost nothing, and immediately fix that exhausting copy-paste feedback loop:

  • Chrome DevTools for Agents (Stable)
  • Modern Web Guidance (Early Preview)

Closing the Feedback Loop: DevTools for Agents

Before this update, your local AI coding assistant was essentially code-deaf and blind. It could generate files, but it had no way of knowing what actually happened when the browser interpreted them.

Chrome DevTools for Agents provides models with direct, programmatic access to the active browser tab sandbox using an optimized, hardened layer of the Chrome DevTools Protocol (CDP).

📊 How the Engineering Workflow Shifts

Execution Metrics The Old Messenger Loop The Closed-Loop DevTools Loop
Error Isolation Manual copying of console stack traces Native, real-time exception hook reading
Network Auditing Guessing why an API payload failed Direct inspection of response codes & headers
Verification Gate Human refreshes page and runs checks Agent triggers autonomous Lighthouse testing
Security Context High risk of clipboard credential leakage Isolated runtime sandbox with credential masking

Instead of acting as a manual bridge, your local IDE assistant hooks into the browser, tracks active state machines, inspects failed fetch calls, and runs its own accessibility tree audits.

LY Corporation—one of the largest web platforms in Japan—integrated this closed-loop runtime into their internal pipeline blocks and managed to reduce manual frontend performance analysis overhead by 96% to 98%.

The new operational flow is simple: the agent generates a feature branch, executes it inside the local browser container, catches its own console errors, updates the layout patterns, and only flags you when the target feature clears a clean execution run.

Guardrails on Silicon: Modern Web Guidance

The second major update addressing quality of execution is Modern Web Guidance.

Left to their own devices, LLMs often write code that technically runs but relies on outdated APIs, non-standard layout behaviors, or accessibility patterns that fail basic WCAG audits.

Modern Web Guidance provides over 100 expert-vetted architectural skills directly to your local model. Crucially, it links directly into Baseline, the cross-browser metric framework. This allows your agent to immediately understand your project’s browser support targets and apply the correct legacy fallbacks dynamically.

It drops into your local workflow with a single terminal command:

npx modern-web-guidance install

This ensures that your agent stops generating code that only works on an isolated machine, and starts outputting web code that is safe to ship to real production clusters.

The Subtext: The Deprecation of Gemini CLI

There is a major breaking pipeline update that has gone entirely unmentioned in the tech press: the official retirement of the Gemini CLI binary.

If your engineering setup relies on build scripts or local CI automations calling the standard gemini command-line tools, those pipelines face a hard stop. The legacy CLI is being phased out completely in favor of the Antigravity 2.0 engine.

While your custom plugins, skills, and subagent scripts will migrate cleanly, the core execution philosophy is different. The legacy tool required step-by-step user instructions. Antigravity 2.0 acts as a self-directed runtime engine: you define the structural code state goal, and the system coordinates the local file manipulation and sandbox testing loops on its own. If you have active automation scripts running, now is the time to open your code editor and update your execution syntax.

Moving Past the Architecture Fluff

When WebMCP was introduced, commentators rushed to label it as “Chrome turning into an operating system for machines.” It’s a great marketing hook, but it glosses over a massive engineering challenge: User legibility.

WebMCP is an opt-in contract designed for programmatic efficiency. It makes it incredibly simple for an automated software system to complete an action inside a browser tab using the user’s active cookie state. But as developers, we have to ask the hard user-experience questions: When a client-side agent executes a financial transaction or structural change silently behind the window shell, how do we surface that step clearly to the human user who initiated it?

The engineering challenge over the next year isn’t going to be making our frontends more efficient for AI engines to crawl—it’s going to be designing the UI guardrails and visible verification steps that ensure users actually trust what their client-side software is doing on their behalf.

Action Items for This Week

You don’t have to wait for experimental web standards to go mainstream to change how you work. You can optimize your local workflow today:

  • Expose the DevTools Port: Connect your preferred local IDE agent to Chrome’s stable developer preview. Let the model parse its own front-end layout bugs instead of manually triaging…
  • Run the Guidance Bundle: Initialize the modern-web-guidance footprint in your workspace to clean up legacy code generation workarounds and enforce baseline accessibility rules automatically.
  • Refactor Build Pipelines: Audit your backend deployment scripts for any dependencies on the old gemini CLI binary and switch those system instances to the unified Antigravity framework.

The Bottom Line

Google I/O 2026 launched a lot of raw processing milestones—larger context sizes, multi-modal video parsing, and faster cloud inferences.

But the real transformation is taking place locally inside the client browser. By removing the friction from local development loops and providing open models with direct runtime visibility, Chrome has eliminated the plumbing overhead of building software with AI. The era of acting as a manual copy-paste messenger between your code editor and your browser console is officially over.

🔗 Resources & Official Tracking

🤖 AI Transparency Disclosure

In full alignment with the challenge transparency rules, this entry utilized an AI programming companion (Gemini) to optimize markdown structural layouts, streamline code snippet styling contracts, and refine semantic prose density. All underlying system critiques, pipeline tracking evaluations, and technical workflow comparisons represent original engineering assessments.

I built a CLI that eliminates README reading forever

The problem

Every developer knows this pain:

  1. Clone a repo
  2. Want to run the tests
  3. Open the README
  4. Scroll… scroll… find a “Development” section… maybe
  5. Figure out it’s pnpm test (not npm test, not yarn test)
  6. Run it wrong anyway because you needed pnpm install first

Multiply this by every repo you touch. Every PR you review. Every onboarding.

I got tired of it.

The solution: rex

git clone https://github.com/some/repo
cd repo
rex test

That’s it. Rex looks at your project files, detects the stack, and runs the correct command. No config. No setup. No reading anything.

How it works

Rex reads files in your project root:

File found Stack detected rex test runs
go.mod Go go test ./...
package.json + pnpm-lock.yaml Node + pnpm pnpm test
Cargo.toml Rust cargo test
pyproject.toml + uv.lock Python + uv uv run pytest
composer.json + artisan PHP + Laravel php artisan test
Gemfile + app/ Ruby + Rails bundle exec rails test
pom.xml Java + Maven mvn test
build.gradle Java + Gradle ./gradlew test
build.zig Zig zig build test
mix.exs Elixir mix test
Makefile Make make test
Justfile Just just test

12 ecosystems. It also detects which package manager you use by looking at lockfiles.

Demo

Watch the video demo

$ 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
> go test ./...
ok   github.com/example/app   1.2s

The > arrow always shows exactly what rex will run. Full transparency.

All the verbs

Command What it does
rex test Run tests
rex run Start the app / dev server
rex build Build the project
rex deps Install dependencies
rex clean Remove build artifacts
rex fresh clean, deps, build in sequence
rex fmt Format code
rex lint Lint code
rex clone <url> Clone + detect + install deps in one command
rex init Generate rex.toml for your team
rex doctor Diagnose environment issues

Killer feature: rex clone

rex clone https://github.com/someone/project
# cloning...
# detected: node + pnpm
# deps: pnpm install
# ready! cd project && rex run

From URL to working project in one command. No README needed.

Monorepo support

Rex auto-detects monorepos (packages/, apps/, services/):

$ rex

  my-monorepo (monorepo)

  workspace  3 sub-projects detected

    packages/api         node + pnpm
    packages/web         node + pnpm
    services/auth        go

Team workflow: rex init

rex init
# created rex.toml (go project)

Generates a rex.toml from detected commands. Commit it. Now every teammate runs the same commands without asking.

.env loading

Rex automatically loads .env files before running commands. No extra tools needed.

Why I built this

I maintain projects across Go, Node, Python, and Rust. I context-switch between repos dozens of times per day. The cognitive load of remembering pnpm test vs go test ./... vs cargo test is small individually, but it adds up.

Rex makes every repo feel the same:

rex test   # always works
rex run    # always works
rex build  # always works

It’s the muscle memory tax I no longer pay.

Technical details

  • Single binary, no runtime, no dependencies
  • Written in Go, cross-platform
  • Less than 50ms startup, faster than your shell prompt
  • Zero network calls, fully offline
  • Correct exit codes, works in CI
  • Shell completions for bash, zsh, fish
  • Apache 2.0 license
  • Mentioned in Awesome Go

Install

# Homebrew (macOS/Linux)
brew tap rexrun-dev/tap && brew install rex

# Go
go install rexrun.dev/rex/cmd/rex@latest

Or grab a binary from GitHub Releases.

Links

If this solves a pain you’ve felt, star the repo. If you want a stack added, open an issue.