<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Nasrul Hazim Bin Mohamad</title>
    <description>The latest articles on DEV Community by Nasrul Hazim Bin Mohamad (@nasrulhazim).</description>
    <link>https://dev.to/nasrulhazim</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F47230%2Fc062b1f5-2c98-4750-8877-6991f248b4bf.jpg</url>
      <title>DEV Community: Nasrul Hazim Bin Mohamad</title>
      <link>https://dev.to/nasrulhazim</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nasrulhazim"/>
    <language>en</language>
    <item>
      <title>Here's How I Build Products Without Losing My Mind.</title>
      <dc:creator>Nasrul Hazim Bin Mohamad</dc:creator>
      <pubDate>Tue, 07 Apr 2026 00:58:17 +0000</pubDate>
      <link>https://dev.to/nasrulhazim/heres-how-i-build-products-without-losing-my-mind-1mi1</link>
      <guid>https://dev.to/nasrulhazim/heres-how-i-build-products-without-losing-my-mind-1mi1</guid>
      <description>&lt;p&gt;I've been building software for over a decade.&lt;/p&gt;

&lt;p&gt;Laravel trainer. Package author. Solution architect. Juggling multiple products at once — G8Stack, G8ID, Nadi, GatherHub, Warung POS, and more.&lt;/p&gt;

&lt;p&gt;And for a long time, I had the same problem every developer has.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;I'd jump into code before the thinking was done.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Half-built features. Scope creep. Vague requirements that sounded clear in my head but turned into a mess the moment I opened my editor. I wasn't building products — I was chasing ideas.&lt;/p&gt;

&lt;p&gt;Something had to change.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Shift: Blueprint Before Code
&lt;/h2&gt;

&lt;p&gt;The turning point wasn't a new framework or a new tool. It was a mindset shift.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Build the blueprint first. Code later.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Sounds obvious. But most of us don't actually do it. We treat planning as a formality — something we rush through so we can get to the "real" work.&lt;/p&gt;

&lt;p&gt;I stopped doing that. And everything changed.&lt;/p&gt;

&lt;p&gt;Here's the workflow I landed on.&lt;/p&gt;




&lt;h2&gt;
  
  
  Phase 1 — Idea to Clear Direction
&lt;/h2&gt;

&lt;p&gt;Every product starts with a brainstorm. No filters. No structure. Just dumping everything out of my head.&lt;/p&gt;

&lt;p&gt;But I don't do this alone.&lt;/p&gt;

&lt;p&gt;I bring Claude into the conversation early — not to generate ideas, but to stress-test them. I'll describe what I'm thinking and let Claude push back: &lt;em&gt;Who exactly is this for? What happens if the user does X? Have you considered this edge case?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;It's like having a thinking partner available at 2am who never gets tired of your half-formed ideas and isn't afraid to point out the holes.&lt;/p&gt;

&lt;p&gt;By the end of this phase I can answer clearly: &lt;em&gt;what exactly am I building, for who, and why does it matter?&lt;/em&gt; And more importantly — what are the constraints, the risks, and the things I hadn't thought of yet.&lt;/p&gt;

&lt;p&gt;Only then do I move forward.&lt;/p&gt;

&lt;p&gt;This phase sounds simple. But skipping it — or rushing through it alone — is the number one reason products stall. You can't build what you haven't clearly thought through.&lt;/p&gt;




&lt;h2&gt;
  
  
  Phase 2 — Name It. Own the Domain.
&lt;/h2&gt;

&lt;p&gt;Before any file is created, before any command is run — I name the project.&lt;/p&gt;

&lt;p&gt;This sounds like a small thing. It isn't.&lt;/p&gt;

&lt;p&gt;The name shapes everything: the repo, the folder structure, the domain, the brand, the way you talk about it to clients. Getting it wrong early means renaming things later, and renaming things is painful.&lt;/p&gt;

&lt;p&gt;So I take the time. I discuss naming options with Claude — checking for clarity, memorability, and whether it communicates what the product actually does. Then I check domain availability immediately. If the domain isn't available, I keep going until I find a name where both the name &lt;em&gt;and&lt;/em&gt; the domain work together.&lt;/p&gt;

&lt;p&gt;Only when the name is locked and the domain is secured do I move to the next step.&lt;/p&gt;




&lt;h2&gt;
  
  
  Phase 3 — Kickoff
&lt;/h2&gt;

&lt;p&gt;With a name in hand, I scaffold the project using &lt;a href="https://kickoff.my" rel="noopener noreferrer"&gt;kickoff.my&lt;/a&gt; — my own tool for getting Laravel projects started with the right foundation.&lt;/p&gt;

&lt;p&gt;The project name drives everything here: folder name, repo name, namespace, environment config. It all flows from that one decision made in Phase 2.&lt;/p&gt;




&lt;h2&gt;
  
  
  Phase 4 — The CLAUDE.md (The Blueprint)
&lt;/h2&gt;

&lt;p&gt;Now I write the &lt;code&gt;CLAUDE.md&lt;/code&gt; — inside the project that was just created.&lt;/p&gt;

&lt;p&gt;Think of it as a structured brief — not for a client, but for Claude Code (my AI coding assistant). It covers what I'm building, the tech stack, the architecture decisions, naming conventions, and phase-by-phase plan.&lt;/p&gt;

&lt;p&gt;Hard cap: &lt;strong&gt;40KB&lt;/strong&gt;. That constraint keeps me honest. If I can't describe the product in 40KB of structured markdown, I probably don't understand it well enough yet.&lt;/p&gt;

&lt;p&gt;Everything that doesn't fit goes into a &lt;code&gt;REFERENCE.md&lt;/code&gt; — detailed data models, edge cases, compliance requirements, anything I need visible but not in the main file.&lt;/p&gt;

&lt;p&gt;Between the two files, Claude Code has everything it needs to understand the project &lt;em&gt;cold&lt;/em&gt; — without me explaining context every single session.&lt;/p&gt;

&lt;p&gt;From there, Claude Code reads the blueprint and fills in the &lt;code&gt;docs/&lt;/code&gt; folder — expanding on specs, documenting the data model, breaking down each phase in detail. Full visibility. Nothing hidden.&lt;/p&gt;




&lt;h2&gt;
  
  
  Phase 5 — GitHub Setup (Before a Single Line of App Code)
&lt;/h2&gt;

&lt;p&gt;This is the part most developers skip entirely.&lt;/p&gt;

&lt;p&gt;Before I write any application code, Claude Code creates the GitHub repo and auto-generates Issues based on the phases in my plan. Milestones. Labels. Everything organised.&lt;/p&gt;

&lt;p&gt;Now I have a project board that reflects the actual plan — not something I backfilled after the fact.&lt;/p&gt;

&lt;p&gt;This alone has saved me hours of context-switching and "wait, what was I building next?"&lt;/p&gt;




&lt;h2&gt;
  
  
  Phase 6 — Build Phase by Phase
&lt;/h2&gt;

&lt;p&gt;Only now do I start coding.&lt;/p&gt;

&lt;p&gt;Each phase has defined deliverables. Each GitHub Issue maps to a real milestone. Claude Code works within the documented context — so there's no guesswork, no AI hallucinations about what I "probably meant", and far fewer errors.&lt;/p&gt;

&lt;p&gt;When I finish a phase, I close the issues, review what changed, and update the docs before moving to the next one.&lt;/p&gt;

&lt;p&gt;It feels slow at first. It isn't. It's the fastest way I've ever shipped a product that actually works the way I intended.&lt;/p&gt;




&lt;h2&gt;
  
  
  Bonus: Agent Skills
&lt;/h2&gt;

&lt;p&gt;On top of all this, I maintain a personal library of Claude Code skills — reusable patterns that encode &lt;em&gt;my&lt;/em&gt; way of doing things.&lt;/p&gt;

&lt;p&gt;Pest testing. Livewire/Flux patterns. API lifecycle. CI/CD pipelines. Package development. Each skill is a structured file that tells Claude Code exactly how I want a thing done.&lt;/p&gt;

&lt;p&gt;If you're curious: &lt;a href="https://github.com/nasrulhazim/agent-skills" rel="noopener noreferrer"&gt;github.com/nasrulhazim/agent-skills&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Lesson
&lt;/h2&gt;

&lt;p&gt;The reason this workflow works isn't Claude. It's not the tools. It's the &lt;em&gt;constraint&lt;/em&gt; of having to think clearly before building.&lt;/p&gt;

&lt;p&gt;When you write a proper blueprint, you catch the problems that would have killed your project at phase 3. You make architecture decisions consciously instead of by accident. You know — before you write a line of code — what done looks like.&lt;/p&gt;

&lt;p&gt;AI just makes the execution faster. The clarity still has to come from you.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feiz6hj3bw71hhrdl3dm8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feiz6hj3bw71hhrdl3dm8.png" alt="Figure 1. A structured product development lifecycle emphasising pre-implementation specification and AI-augmented planning." width="800" height="890"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Want to Learn This or Work With Me?
&lt;/h2&gt;

&lt;p&gt;If you're a developer or founder who wants to build smarter — not just faster — here's how we can work together:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;→ Learn:&lt;/strong&gt; I run Laravel training sessions covering architecture, clean code patterns, and production-grade development. &lt;a href="https://devhub.my" rel="noopener noreferrer"&gt;Reach out to me&lt;/a&gt; and ask about upcoming sessions or custom workshops for your team.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;→ Hire:&lt;/strong&gt; Need a solution architect who can take your idea from zero to structured, shippable product? That's exactly what I do. See what I've built at &lt;a href="https://nasrulhazim.com/projects" rel="noopener noreferrer"&gt;nasrulhazim.com/projects&lt;/a&gt; and reach out at &lt;a href="https://nasrulhazim.com" rel="noopener noreferrer"&gt;nasrulhazim.com&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;→ Follow along:&lt;/strong&gt; I document the journey — products, patterns, and lessons learned — right here on dev.to. Hit follow so you don't miss the next post.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Blueprint first, code later. Build the map before you start the journey.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>ai</category>
      <category>productivity</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Laravel Artisan Runner — Run Artisan Commands from the Browser, Safely</title>
      <dc:creator>Nasrul Hazim Bin Mohamad</dc:creator>
      <pubDate>Mon, 30 Mar 2026 08:49:32 +0000</pubDate>
      <link>https://dev.to/nasrulhazim/laravel-artisan-runner-run-artisan-commands-from-the-browser-safely-123m</link>
      <guid>https://dev.to/nasrulhazim/laravel-artisan-runner-run-artisan-commands-from-the-browser-safely-123m</guid>
      <description>&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Every Laravel developer knows the drill. Someone on the team needs to clear the cache, run migrations, or trigger a seeder — but they don't have SSH access. So they ping you on Slack. You SSH in, run the command, confirm the output, and go back to what you were doing.&lt;/p&gt;

&lt;p&gt;Multiply that by a dozen teammates and a handful of environments, and it becomes a real productivity drain.&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;Laravel Artisan Runner&lt;/strong&gt; to solve this. It's a package that lets you expose pre-approved Artisan commands through a clean, Livewire-powered web interface — with full audit logging, queued execution, and notifications baked in.&lt;/p&gt;

&lt;h2&gt;
  
  
  What It Does
&lt;/h2&gt;

&lt;p&gt;At its core, Artisan Runner gives you three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;A web UI&lt;/strong&gt; to browse, configure, and execute Artisan commands&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;An allowlist system&lt;/strong&gt; so only approved commands can be run&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A complete audit trail&lt;/strong&gt; of every execution — who ran what, when, with what parameters, and what happened&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Every command runs through a queued job. No blocking HTTP requests. No timeouts on long-running migrations.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftrdc0cs0s869prdvnj3m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftrdc0cs0s869prdvnj3m.png" alt="Artisan Runner"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require cleaniquecoders/laravel-artisan-runner

php artisan artisan-runner:install

php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Three commands and you're up.&lt;/p&gt;

&lt;p&gt;The install command publishes the config, migrations, views, and assets in one shot. Then drop the component into any Blade view:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;livewire:artisan-runner::command-runner /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The default route is &lt;code&gt;/artisan-runner&lt;/code&gt;, protected by &lt;code&gt;web&lt;/code&gt; and &lt;code&gt;auth&lt;/code&gt; middleware.&lt;/p&gt;

&lt;h2&gt;
  
  
  Configuration: Three Discovery Modes
&lt;/h2&gt;

&lt;p&gt;The package supports three ways to determine which commands are available.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manual (Default — Safest)
&lt;/h3&gt;

&lt;p&gt;Only commands you explicitly list in &lt;code&gt;allowed_commands&lt;/code&gt; are available:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="c1"&gt;// config/artisan-runner.php&lt;/span&gt;

&lt;span class="s1"&gt;'discovery_mode'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'manual'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="s1"&gt;'allowed_commands'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'cache:clear'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'label'&lt;/span&gt;       &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Clear Cache'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Flush the application cache.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'group'&lt;/span&gt;       &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Cache'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'parameters'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s1"&gt;'migrate'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'label'&lt;/span&gt;       &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Run Migrations'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'description'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Run database migrations.'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'group'&lt;/span&gt;       &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Database'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'parameters'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'--force'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'boolean'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'label'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Force (production)'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'default'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
            &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'--seed'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="s1"&gt;'type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'boolean'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'label'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Run seeders'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;        &lt;span class="s1"&gt;'default'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Auto Discovery
&lt;/h3&gt;

&lt;p&gt;Surfaces all Artisan commands minus your exclusion list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="s1"&gt;'discovery_mode'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'auto'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

&lt;span class="s1"&gt;'excluded_commands'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'down'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'up'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'serve'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'tinker'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'db:wipe'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="s1"&gt;'excluded_namespaces'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'make'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'schedule'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'queue'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'stub'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Good for development. I wouldn't recommend this for production without a tight exclusion list.&lt;/p&gt;

&lt;h3&gt;
  
  
  Selection
&lt;/h3&gt;

&lt;p&gt;A middle ground — only explicitly included commands are discovered, then merged with your manual entries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="s1"&gt;'discovery_mode'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'selection'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="s1"&gt;'included_commands'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'cache:clear'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'migrate'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'config:cache'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'route:cache'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's also a CLI tool to help you build your command list:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan artisan-runner:discover
php artisan artisan-runner:discover &lt;span class="nt"&gt;--output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;json
php artisan artisan-runner:discover &lt;span class="nt"&gt;--dry-run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How It Works Under the Hood
&lt;/h2&gt;

&lt;p&gt;The architecture follows a clean action-based pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User clicks "Run"
  → Livewire CommandRunner component
    → RunCommandAction (validates against allowlist)
      → Dispatches RunArtisanCommandJob to queue
        → Job calls Artisan::call()
          → Output + exit code saved to CommandLog
            → Notification dispatched (if enabled)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The Audit Log
&lt;/h3&gt;

&lt;p&gt;Every execution creates a &lt;code&gt;CommandLog&lt;/code&gt; record:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;CommandLog&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;create&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="s1"&gt;'uuid'&lt;/span&gt;       &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Str&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="s1"&gt;'command'&lt;/span&gt;     &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'migrate'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'parameters'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'--force'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s1"&gt;'status'&lt;/span&gt;      &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'pending'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;// pending → running → completed/failed&lt;/span&gt;
    &lt;span class="s1"&gt;'ran_by_type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'App\Models\User'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'ran_by_id'&lt;/span&gt;   &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;42&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The status lifecycle is simple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;pending → running → completed
                  → failed
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each log tracks start time, finish time, full output, and exit code. The Livewire component polls every 5 seconds, so you see status updates in real time.&lt;/p&gt;

&lt;p&gt;Query your logs programmatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;CleaniqueCoders\ArtisanRunner\Models\CommandLog&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;CleaniqueCoders\ArtisanRunner\Enums\CommandStatus&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// Recent failures&lt;/span&gt;
&lt;span class="nc"&gt;CommandLog&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'status'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;CommandStatus&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nc"&gt;Failed&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;recent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="c1"&gt;// Who's been running commands&lt;/span&gt;
&lt;span class="nc"&gt;CommandLog&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;with&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ranBy'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;latest&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;take&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Smart Parameter Rendering
&lt;/h3&gt;

&lt;p&gt;The UI automatically renders the right input type based on parameter definitions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Arguments&lt;/strong&gt; (positional) → text inputs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boolean flags&lt;/strong&gt; (&lt;code&gt;--force&lt;/code&gt;, &lt;code&gt;--seed&lt;/code&gt;) → checkboxes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Numeric options&lt;/strong&gt; (&lt;code&gt;--step=5&lt;/code&gt;) → number inputs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;String options&lt;/strong&gt; → text inputs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One gotcha I hit early: Livewire doesn't play well with &lt;code&gt;wire:model&lt;/code&gt; bindings that have &lt;code&gt;--&lt;/code&gt; prefixes (like &lt;code&gt;parameterValues.--force&lt;/code&gt;). The fix was to use index-based keys internally and map them back to parameter names when dispatching. Small detail, but it would've bitten anyone building this.&lt;/p&gt;

&lt;h2&gt;
  
  
  Notifications
&lt;/h2&gt;

&lt;p&gt;When a command completes or fails, the package can notify a configurable user via any Laravel notification channel:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="s1"&gt;'notification'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'enabled'&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'channels'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'database'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'mail'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s1"&gt;'notifiable'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'model'&lt;/span&gt;      &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;\App\Models\User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'identifier'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'email'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="s1"&gt;'value'&lt;/span&gt;      &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;env&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ARTISAN_RUNNER_NOTIFY_EMAIL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ops@yourdomain.com'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The notification includes the command name, status, exit code, and execution duration. Wire it up to Slack, Discord, or whatever your team uses.&lt;/p&gt;

&lt;h2&gt;
  
  
  Security: Built Paranoid by Default
&lt;/h2&gt;

&lt;p&gt;This is a package that runs shell commands from a web interface. Security isn't optional.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Allowlist-first.&lt;/strong&gt; The default mode is &lt;code&gt;manual&lt;/code&gt;. Nothing runs unless you explicitly approve it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Auth-protected routes.&lt;/strong&gt; Default middleware is &lt;code&gt;['web', 'auth']&lt;/code&gt;. Tighten it further:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="s1"&gt;'route'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'middleware'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'web'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'auth'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'role:admin'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Dangerous commands pre-excluded.&lt;/strong&gt; Even in auto-discovery mode, commands like &lt;code&gt;down&lt;/code&gt;, &lt;code&gt;db:wipe&lt;/code&gt;, &lt;code&gt;migrate:fresh&lt;/code&gt;, &lt;code&gt;tinker&lt;/code&gt;, and &lt;code&gt;serve&lt;/code&gt; are excluded out of the box.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Full audit trail.&lt;/strong&gt; Every execution is logged with who triggered it (polymorphic relation — works with any model, not just &lt;code&gt;User&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No retries.&lt;/strong&gt; Failed jobs stay failed. You investigate, you don't auto-retry &lt;code&gt;migrate --force&lt;/code&gt; in production.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Timeout protection.&lt;/strong&gt; Commands are killed after 300 seconds. No runaway processes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Livewire 3 + 4 Compatibility
&lt;/h2&gt;

&lt;p&gt;The package supports both Livewire 3 and 4. The service provider handles registration automatically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;method_exists&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Livewire&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'addNamespace'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Livewire 4&lt;/span&gt;
    &lt;span class="nc"&gt;Livewire&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;addNamespace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'artisan-runner'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'/Livewire'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Livewire 3&lt;/span&gt;
    &lt;span class="nc"&gt;Livewire&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'artisan-runner::command-runner'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;CommandRunner&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No feature flags. No config toggles. It just works.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Should You Use This?
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Great fit:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Admin dashboards where non-technical staff need to trigger maintenance tasks&lt;/li&gt;
&lt;li&gt;Deployment pipelines where you want a "run post-deploy tasks" button&lt;/li&gt;
&lt;li&gt;Multi-tenant apps with per-tenant cache clearing or migrations&lt;/li&gt;
&lt;li&gt;Teams where not everyone has SSH access but everyone needs to clear caches&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Not ideal for:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Interactive commands (&lt;code&gt;tinker&lt;/code&gt;, &lt;code&gt;make:model&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Long-running batch jobs that exceed 5 minutes&lt;/li&gt;
&lt;li&gt;Anything that needs real-time streaming output (it captures output after completion)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Stack Compatibility
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Supported&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;PHP&lt;/td&gt;
&lt;td&gt;8.3+&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Laravel&lt;/td&gt;
&lt;td&gt;11, 12, 13&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Livewire&lt;/td&gt;
&lt;td&gt;3, 4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tailwind&lt;/td&gt;
&lt;td&gt;4 (via CDN)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Try It Out
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require cleaniquecoders/laravel-artisan-runner
php artisan artisan-runner:install
php artisan migrate
php artisan queue:work
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then visit &lt;code&gt;/artisan-runner&lt;/code&gt; in your browser.&lt;/p&gt;

&lt;p&gt;Source code: &lt;a href="https://github.com/cleaniquecoders/laravel-artisan-runner" rel="noopener noreferrer"&gt;github.com/cleaniquecoders/laravel-artisan-runner&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I'm Nasrul Hazim, a software engineer from Malaysia building Laravel packages and tools. Find more of my work at &lt;a href="https://nasrulhazim.com" rel="noopener noreferrer"&gt;nasrulhazim.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>php</category>
      <category>livewire</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I Built a Claude Code Skill to Sync CLAUDE.md Across 12+ Laravel Projects</title>
      <dc:creator>Nasrul Hazim Bin Mohamad</dc:creator>
      <pubDate>Sat, 14 Mar 2026 00:06:27 +0000</pubDate>
      <link>https://dev.to/nasrulhazim/i-built-a-claude-code-skill-to-sync-claudemd-across-12-laravel-projects-5apo</link>
      <guid>https://dev.to/nasrulhazim/i-built-a-claude-code-skill-to-sync-claudemd-across-12-laravel-projects-5apo</guid>
      <description>&lt;p&gt;You know that feeling when you update something important in one place, then you realise — &lt;em&gt;oh no, I need to propagate this to like 10 other projects&lt;/em&gt;?&lt;/p&gt;

&lt;p&gt;Yeah. That was me last week.&lt;/p&gt;




&lt;h2&gt;
  
  
  A Bit of Background
&lt;/h2&gt;

&lt;p&gt;I maintain a Laravel kickstart project called &lt;a href="https://kickoff.my" rel="noopener noreferrer"&gt;Kickoff&lt;/a&gt;. Every Laravel project I start — personal, client, internal — starts from this base. It contains my opinionated project structure, conventions, Docker setup, and one particularly important file:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;code&gt;stubs/CLAUDE.md&lt;/code&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If you're using Claude Code, this file matters a lot. It's the instruction manual Claude reads before it touches your codebase. Stack, conventions, patterns, boundaries — it's all there. Without it, Claude guesses. With it, Claude codes like it already knows your project.&lt;/p&gt;

&lt;p&gt;Problem: I have multiple projects built on top of Kickoff. Every time I update &lt;code&gt;stubs/CLAUDE.md&lt;/code&gt; in Kickoff, those changes need to flow downstream. Into every project. One by one.&lt;/p&gt;

&lt;p&gt;I did it manually twice. Third time, I refused.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Boring Fix vs The Right Fix
&lt;/h2&gt;

&lt;p&gt;The boring fix: write a bash script that loops through directories and overwrites &lt;code&gt;CLAUDE.md&lt;/code&gt;. Quick. Fragile. Dumb.&lt;/p&gt;

&lt;p&gt;The problem with dumb scripts? They don't understand &lt;em&gt;context&lt;/em&gt;. My projects aren't identical. Each one has project-specific sections in &lt;code&gt;CLAUDE.md&lt;/code&gt; — custom domain notes, environment variables, Docker services, known issues, client-specific conventions. A dumb overwrite nukes all of that.&lt;/p&gt;

&lt;p&gt;What I actually need is something that can:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Scan a parent directory for projects&lt;/li&gt;
&lt;li&gt;Figure out which ones are based on Kickoff&lt;/li&gt;
&lt;li&gt;Diff their &lt;code&gt;CLAUDE.md&lt;/code&gt; against the latest from Kickoff&lt;/li&gt;
&lt;li&gt;Merge the changes &lt;em&gt;without&lt;/em&gt; destroying project-specific content&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That's not a bash script. That's judgment. And Claude Code is actually good at that — &lt;em&gt;if&lt;/em&gt; you give it the right structure upfront.&lt;/p&gt;

&lt;p&gt;So I built a Claude Code skill.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's a Claude Code Skill?
&lt;/h2&gt;

&lt;p&gt;A skill in Claude Code is a &lt;code&gt;SKILL.md&lt;/code&gt; file that provides Claude with structured context, instructions, and a defined workflow for a specific repeatable task.&lt;/p&gt;

&lt;p&gt;Think of it like this — instead of you typing a long prompt every single time, you encode the decision tree once into a skill file. Claude reads it, understands what it's supposed to do, and executes consistently every time.&lt;/p&gt;

&lt;p&gt;I've been building these skills in my own repo: &lt;a href="https://github.com/nasrulhazim/agent-skills" rel="noopener noreferrer"&gt;&lt;code&gt;nasrulhazim/agent-skills&lt;/code&gt;&lt;/a&gt;. I already have skills for testing, Livewire components, API lifecycle, CI/CD pipelines, and more. This new one — &lt;code&gt;project-sync&lt;/code&gt; — joins the collection.&lt;/p&gt;

&lt;p&gt;A skill is just a directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;skills/project-sync/
├── SKILL.md                              # The instructions
└── references/
    ├── merge-algorithm.md                # How to merge sections
    ├── section-classification.md         # What's shared vs project-specific
    ├── detection-markers.md              # How to identify Kickoff projects
    └── registry-schema.md               # Registry file format
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No runtime. No API. No build step. Just markdown that Claude reads and follows.&lt;/p&gt;




&lt;h2&gt;
  
  
  What the Skill Actually Does
&lt;/h2&gt;

&lt;p&gt;Here's the workflow, broken into commands:&lt;/p&gt;

&lt;h3&gt;
  
  
  Scan: Find All Kickoff Projects
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/project-sync scan ~/Projects &lt;span class="nt"&gt;--since&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2025
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude scans the directory tree, finds Laravel projects (checks for &lt;code&gt;artisan&lt;/code&gt; + &lt;code&gt;composer.json&lt;/code&gt;), then verifies Kickoff-specific markers:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;app/Models/Base.php&lt;/code&gt; exists&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;composer.json&lt;/code&gt; requires &lt;code&gt;cleaniquecoders/traitify&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;support/helpers.php&lt;/code&gt; in autoload&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;CLAUDE.md&lt;/code&gt; mentions "Kickoff"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;At least one marker must match. This avoids false positives from vanilla Laravel projects.&lt;/p&gt;

&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Scanned: ~/Projects
Found: 12 Kickoff Laravel projects (filtered: --since=2025)

~/Projects/2025/ — 8 projects
  ✓ project-alpha          CLAUDE.md: 18.2 KB
  ✓ project-beta           CLAUDE.md: 22.1 KB
  ✗ project-gamma          No CLAUDE.md

~/Projects/2026/ — 4 projects
  ✓ project-delta          CLAUDE.md: 19.8 KB
  ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It can also scan a GitHub account without cloning anything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/project-sync scan gh:cleaniquecoders &lt;span class="nt"&gt;--since&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;2025
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything gets saved to a registry at &lt;code&gt;~/.claude/projects/.project-sync.json&lt;/code&gt; — persistent across Claude Code sessions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Status: What Needs Updating?
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/project-sync status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Source: kickoff/stubs/CLAUDE.md (fetched from GitHub)

Project                 Status      Size     Last Synced
─────────────────────────────────────────────────────────
project-alpha           ✓ current   18.2 KB  2026-03-10
project-beta            ✗ outdated  22.1 KB  2026-02-15
project-gamma           ⚠ missing   —        never
project-delta           ✗ outdated  19.8 KB  2026-03-01

Summary: 1 current, 2 outdated, 1 missing CLAUDE.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instantly see which projects have drifted.&lt;/p&gt;

&lt;h3&gt;
  
  
  Diff: Preview Before You Touch Anything
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/project-sync diff project-beta
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Dry-run merge. No files changed. Just shows what &lt;em&gt;would&lt;/em&gt; happen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="gu"&gt;## Sections to UPDATE (from source):&lt;/span&gt;
&lt;span class="p"&gt;  -&lt;/span&gt; Architecture &amp;amp; Key Concepts &amp;gt; Models - CRITICAL  [changed]
&lt;span class="p"&gt;  -&lt;/span&gt; Architecture &amp;amp; Key Concepts &amp;gt; Enums  [changed]
&lt;span class="p"&gt;  -&lt;/span&gt; Livewire Patterns &amp;gt; Toast Notifications  [changed]

&lt;span class="gu"&gt;## Sections to MERGE (combine items):&lt;/span&gt;
&lt;span class="p"&gt;  -&lt;/span&gt; DO list: +2 new items from source, 3 project-only preserved
&lt;span class="p"&gt;  -&lt;/span&gt; DON'T list: +1 new item from source, 1 project-only preserved

&lt;span class="gu"&gt;## Sections PRESERVED (project-specific):&lt;/span&gt;
&lt;span class="p"&gt;  -&lt;/span&gt; Project Overview
&lt;span class="p"&gt;  -&lt;/span&gt; Common Commands
&lt;span class="p"&gt;  -&lt;/span&gt; Packages
&lt;span class="p"&gt;  -&lt;/span&gt; Docker Services
&lt;span class="p"&gt;  -&lt;/span&gt; Environment Variables
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No surprises. You see exactly what gets replaced, what gets merged, and what stays untouched.&lt;/p&gt;

&lt;h3&gt;
  
  
  Update: Do the Thing
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/project-sync update all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Sync complete:
  ✓ Updated: 8 projects
  — Skipped: 2 projects (already current)
  ✗ Failed: 1 project (git working tree dirty)

Report saved: ~/.claude/projects/reports/20260314.0600/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each updated project gets a clean commit: &lt;code&gt;docs: sync CLAUDE.md with kickoff conventions&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Secret Sauce: Section-Level Merging
&lt;/h2&gt;

&lt;p&gt;This is the part that makes it actually work. Not line-level diffing — &lt;em&gt;section-level&lt;/em&gt; merging.&lt;/p&gt;

&lt;p&gt;A &lt;code&gt;CLAUDE.md&lt;/code&gt; built from Kickoff has a predictable structure. Every H2/H3 section falls into one of four categories:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Type&lt;/th&gt;
&lt;th&gt;Action&lt;/th&gt;
&lt;th&gt;Examples&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;SHARED&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Replace from source&lt;/td&gt;
&lt;td&gt;Model conventions, testing rules, Livewire patterns&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;PROJECT-SPECIFIC&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Never touch&lt;/td&gt;
&lt;td&gt;Project overview, packages, env vars, Docker config&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;MERGE&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Combine both lists&lt;/td&gt;
&lt;td&gt;DO/DON'T — keep source items + project-only items&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;CONDITIONAL&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Check each subsection&lt;/td&gt;
&lt;td&gt;Important Conventions (mixed shared + project-specific)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  How a DO List Merge Works
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Source&lt;/strong&gt; (from Kickoff):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt; ✅ DO extend App&lt;span class="se"&gt;\M&lt;/span&gt;odels&lt;span class="se"&gt;\B&lt;/span&gt;ase for all models
&lt;span class="p"&gt;-&lt;/span&gt; ✅ DO use dual-key pattern
&lt;span class="p"&gt;-&lt;/span&gt; ✅ DO use Pest syntax for tests
&lt;span class="p"&gt;-&lt;/span&gt; ✅ DO use Form Requests for validation     ← NEW
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Target&lt;/strong&gt; (project-beta has custom items):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt; ✅ DO extend App&lt;span class="se"&gt;\M&lt;/span&gt;odels&lt;span class="se"&gt;\B&lt;/span&gt;ase for all models
&lt;span class="p"&gt;-&lt;/span&gt; ✅ DO use Pest syntax for tests
&lt;span class="p"&gt;-&lt;/span&gt; ✅ DO use PostgreSQL for all new tables     ← PROJECT-ONLY
&lt;span class="p"&gt;-&lt;/span&gt; ✅ DO prefix admin routes with /admin       ← PROJECT-ONLY
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Merged result&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt; ✅ DO extend App&lt;span class="se"&gt;\M&lt;/span&gt;odels&lt;span class="se"&gt;\B&lt;/span&gt;ase for all models
&lt;span class="p"&gt;-&lt;/span&gt; ✅ DO use dual-key pattern                   ← RESTORED FROM SOURCE
&lt;span class="p"&gt;-&lt;/span&gt; ✅ DO use Pest syntax for tests
&lt;span class="p"&gt;-&lt;/span&gt; ✅ DO use Form Requests for validation       ← NEW FROM SOURCE
&lt;span class="p"&gt;-&lt;/span&gt; ✅ DO use PostgreSQL for all new tables       ← PRESERVED
&lt;span class="p"&gt;-&lt;/span&gt; ✅ DO prefix admin routes with /admin         ← PRESERVED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Source items are updated and new ones added. Project-only items are preserved. Nobody loses anything.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Section Classification Map
&lt;/h3&gt;

&lt;p&gt;Here's the actual map encoded in the skill:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Section&lt;/th&gt;
&lt;th&gt;Classification&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;## Project Overview&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PROJECT-SPECIFIC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;## Common Commands&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PROJECT-SPECIFIC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;## Architecture &amp;amp; Key Concepts&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SHARED&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;## File Organization&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SHARED&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;## Testing with Pest&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SHARED&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;## Livewire Patterns&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SHARED&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;## Important Conventions&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CONDITIONAL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;## Code Quality Checklist&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SHARED&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;## Packages&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PROJECT-SPECIFIC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;## Docker Services&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PROJECT-SPECIFIC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;## Environment Variables&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;PROJECT-SPECIFIC&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;## Gotchas&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;CONDITIONAL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Any unlisted H2 section&lt;/td&gt;
&lt;td&gt;PROJECT-SPECIFIC&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;That last row is important — if a project adds a custom section like &lt;code&gt;## Deployment Notes&lt;/code&gt; or &lt;code&gt;## Client Requirements&lt;/code&gt;, the skill automatically preserves it because it's not in the source.&lt;/p&gt;




&lt;h2&gt;
  
  
  Edge Cases
&lt;/h2&gt;

&lt;p&gt;Because real-world projects are messy:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Scenario&lt;/th&gt;
&lt;th&gt;What Happens&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Project has no &lt;code&gt;CLAUDE.md&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Creates one from source + &lt;code&gt;composer.json&lt;/code&gt; metadata&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Dirty git working tree&lt;/td&gt;
&lt;td&gt;Skips the project, reports as failed&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Source URL unreachable&lt;/td&gt;
&lt;td&gt;Falls back to cache, or asks for &lt;code&gt;--source&lt;/code&gt; override&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Custom H2 sections in project&lt;/td&gt;
&lt;td&gt;Always preserved — if it's not in source, it's yours&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Merged file exceeds 40 KB&lt;/td&gt;
&lt;td&gt;Auto-refines (trims whitespace, condenses examples), then asks if still over&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Sections in different order&lt;/td&gt;
&lt;td&gt;Preserves project's order — merge is content-based, not position-based&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Why This Matters Beyond CLAUDE.md
&lt;/h2&gt;

&lt;p&gt;The real point here isn't about &lt;code&gt;CLAUDE.md&lt;/code&gt; specifically. It's about a pattern shift.&lt;/p&gt;

&lt;p&gt;Every time I find myself doing something tedious and repetitive — especially something that involves &lt;em&gt;judgment&lt;/em&gt;, not just mechanics — I now ask one question:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Can I encode this into a skill?&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Same instinct that makes me write packages instead of copy-pasting code. Same instinct that makes me extract traits and contracts instead of duplicating logic. Except now, instead of PHP abstractions, I'm building AI workflow abstractions.&lt;/p&gt;

&lt;p&gt;The mental model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tedious thing detected
  → Solve it once manually, understand the decision tree
    → Encode the decision tree into a skill
      → Never think about it again
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Practical Steps If You Want to Do This
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Start with the boring problem.&lt;/strong&gt; What do you keep doing manually that involves some judgment?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Map out the decision tree&lt;/strong&gt; before writing anything. What are the conditions? What are the outputs? What needs human review vs what's automatable?&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Write the SKILL.md.&lt;/strong&gt; Phases, inputs, workflow, edge cases. Be explicit. Claude follows structure well.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Keep it in version control.&lt;/strong&gt; I keep mine in &lt;a href="https://github.com/nasrulhazim/agent-skills" rel="noopener noreferrer"&gt;&lt;code&gt;nasrulhazim/agent-skills&lt;/code&gt;&lt;/a&gt;. Commit it, tag it, evolve it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Test it on a safe project first.&lt;/strong&gt; Dry run. Verify the output before letting it touch 10 projects.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;

&lt;p&gt;Install all my skills:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/nasrulhazim/agent-skills/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or just this one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/nasrulhazim/agent-skills.git
&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; agent-skills/skills/project-sync ~/.claude/skills/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then in Claude Code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/project-sync scan ~/Projects
/project-sync status
/project-sync diff project-name
/project-sync update all
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Final Thought
&lt;/h2&gt;

&lt;p&gt;AI tools aren't magic. But when you invest time designing &lt;em&gt;how&lt;/em&gt; you use them — giving them structure, context, repeatable workflows — they become serious force multipliers.&lt;/p&gt;

&lt;p&gt;The leverage isn't in using AI. The leverage is in &lt;strong&gt;designing how you use AI.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Working smart isn't about working faster. It's about doing the tedious thing once, then letting the system carry it forward. &lt;/p&gt;

&lt;p&gt;That's the whole game.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;My agent skills collection (26 skills, MIT licensed) → &lt;a href="https://github.com/nasrulhazim/agent-skills" rel="noopener noreferrer"&gt;github.com/nasrulhazim/agent-skills&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Kickoff (Laravel kickstart) → &lt;a href="https://kickoff.my" rel="noopener noreferrer"&gt;kickoff.my&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>ai</category>
      <category>productivity</category>
      <category>php</category>
    </item>
    <item>
      <title>Teaching Claude Code to Think Like a Laravel Developer: Introducing agent-skills</title>
      <dc:creator>Nasrul Hazim Bin Mohamad</dc:creator>
      <pubDate>Sat, 28 Feb 2026 00:23:32 +0000</pubDate>
      <link>https://dev.to/nasrulhazim/teaching-claude-code-to-think-like-a-laravel-developer-introducing-agent-skills-58cm</link>
      <guid>https://dev.to/nasrulhazim/teaching-claude-code-to-think-like-a-laravel-developer-introducing-agent-skills-58cm</guid>
      <description>&lt;p&gt;I've been building with Claude Code for a while now, and one thing kept bothering me: every new project started from zero context. Claude doesn't know I use Pest over PHPUnit, that I'm opinionated about Action classes, or that my baseline stack is Livewire 4 + Flux UI. I had to re-explain the same things across sessions, every time.&lt;/p&gt;

&lt;p&gt;The fix wasn't to write longer prompts. It was to build &lt;strong&gt;skills&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Are Claude Code Skills?
&lt;/h2&gt;

&lt;p&gt;Claude Code supports a &lt;code&gt;SKILL.md&lt;/code&gt; convention — a structured Markdown file that tells Claude &lt;em&gt;how&lt;/em&gt; to behave in a specific domain before it starts generating code. Think of it like a system prompt scoped to a task, packaged as a reusable module.&lt;/p&gt;

&lt;p&gt;A skill lives at either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;~/.claude/skills/&lt;/code&gt; — globally available across all your projects&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;.claude/skills/&lt;/code&gt; — scoped to a specific project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When Claude Code encounters a relevant request, it reads the matching skill and follows its instructions. The skill can include frontmatter metadata, trigger phrases, step-by-step workflows, and even reference files like templates and pattern libraries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why I Built agent-skills
&lt;/h2&gt;

&lt;p&gt;I maintain 20+ open-source Laravel packages and have been training Laravel developers since 2015. After years of writing the same architecture — contracts, traits, action classes, service providers — I realized I wasn't just repeating &lt;em&gt;code&lt;/em&gt;. I was repeating &lt;em&gt;decisions&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/nasrulhazim/agent-skills" rel="noopener noreferrer"&gt;agent-skills&lt;/a&gt; is my way of encoding those decisions into Claude Code. Instead of prompting Claude from scratch, I give it the same mental model I use when I sit down to build something.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's Inside
&lt;/h2&gt;

&lt;p&gt;The repo currently covers four areas:&lt;/p&gt;

&lt;h3&gt;
  
  
  Development &amp;amp; Quality
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;pest-testing&lt;/strong&gt; — Generates Pest tests with Livewire support, architecture testing, and factory patterns. It knows I want &lt;code&gt;arch()-&amp;gt;preset()-&amp;gt;laravel()&lt;/code&gt; checks, not just feature tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;code-quality&lt;/strong&gt; — Automates the PHPStan + Pint + Rector workflow. Run it before a PR, not after.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;php-best-practices&lt;/strong&gt; — PHP 8.2+ modernization and code review, flagging things like missing readonly properties, untyped parameters, and constructor promotion opportunities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;design-patterns&lt;/strong&gt; — Laravel-specific pattern guidance with a decision matrix. Should this be a Job, an Action, or a Pipeline? The skill helps Claude answer that in context.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;livewire-flux&lt;/strong&gt; — Component patterns for Livewire 4 with Flux UI. No more explaining my component structure from scratch.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Project Lifecycle
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;project-docs&lt;/strong&gt; — Full SDLC documentation toolchain, from product spec to post-mortem.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;project-requirements&lt;/strong&gt; — SRS, user stories, proposals, and wireframes. Useful when a client brief arrives and you need structured output fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;roadmap-generator&lt;/strong&gt; — Phase-based roadmaps in Markdown and styled HTML. I use this when pitching to clients or planning sprints.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;api-lifecycle&lt;/strong&gt; — API design through governance. Covers versioning, deprecation policies, and OpenAPI documentation patterns.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Deployment &amp;amp; Ops
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ci-cd-pipeline&lt;/strong&gt; — GitHub Actions + Docker workflow automation. Includes Laravel-specific steps like &lt;code&gt;php artisan optimize&lt;/code&gt; and migration safety checks.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;package-dev&lt;/strong&gt; — Laravel package scaffolding, testing, and release automation. This one's personal — it encodes the same structure I use across all my Cleanique Coders packages.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Business &amp;amp; Design
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;sales-planner&lt;/strong&gt; — Pricing, quotation generation, marketing copy, and financial planning. Especially handy for solopreneurs who need to go from client brief to proposal quickly.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;svg-logo-system&lt;/strong&gt; — SVG logo design with multi-platform export. Useful when you're the dev &lt;em&gt;and&lt;/em&gt; the designer.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Meta
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;self-update&lt;/strong&gt; — Auto-updates &lt;code&gt;CLAUDE.md&lt;/code&gt; with corrections, preferences, and gotchas learned during a session. This one compounds over time.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Skill Structure
&lt;/h2&gt;

&lt;p&gt;Every skill follows a consistent format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;skills/[skill-name]/
├── SKILL.md              # Skill definition with YAML frontmatter + instructions
└── references/           # Templates, patterns, examples
    ├── template-a.md
    └── patterns-b.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;SKILL.md&lt;/code&gt; frontmatter looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;pest-testing&lt;/span&gt;
&lt;span class="na"&gt;metadata&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;compatible_agents&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;claude-code&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
  &lt;span class="na"&gt;tags&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;testing&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;pest&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;laravel&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;livewire&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;&amp;gt;"&lt;/span&gt;
  &lt;span class="s"&gt;Generates Pest PHP tests for Laravel applications.&lt;/span&gt;
  &lt;span class="s"&gt;Trigger phrases&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;write&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;tests"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;generate&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;test"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;tulis&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;test"...&lt;/span&gt;
&lt;span class="nn"&gt;---&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice the &lt;code&gt;description&lt;/code&gt; includes trigger phrases in both English and Bahasa Malaysia. That's intentional — I code-switch constantly, and I want my skills to respond to either.&lt;/p&gt;

&lt;h2&gt;
  
  
  Installing in 30 Seconds
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install all skills globally&lt;/span&gt;
curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/nasrulhazim/agent-skills/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This drops everything into &lt;code&gt;~/.claude/skills/&lt;/code&gt;, making all skills available across every project on your machine. If you only need one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; skills/pest-testing /path/to/your-project/.claude/skills/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The Kickoff.my Baseline
&lt;/h2&gt;

&lt;p&gt;Many skills assume the &lt;a href="https://kickoff.my" rel="noopener noreferrer"&gt;Kickoff.my&lt;/a&gt; bootstrap stack as a starting point:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Livewire 4 + Flux UI&lt;/li&gt;
&lt;li&gt;Pest with arch testing&lt;/li&gt;
&lt;li&gt;PHPStan / Larastan&lt;/li&gt;
&lt;li&gt;Rector + Laravel Pint&lt;/li&gt;
&lt;li&gt;GitHub Actions CI&lt;/li&gt;
&lt;li&gt;Spatie Permission, Activity Log, Media Library&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Rather than re-scaffolding what Kickoff already provides, skills build &lt;em&gt;on top&lt;/em&gt; of it. If you're not using Kickoff, the skills still work — you'll just want to adjust a few assumptions in the reference files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Seeing It in Action
&lt;/h2&gt;

&lt;p&gt;Here are three skills I ran this morning — no extra prompting, just invoking the slash command and letting the skill do its job.&lt;/p&gt;

&lt;h3&gt;
  
  
  project-docs: Documentation Health Report
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujcxfdu6aco2btpy7ta8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fujcxfdu6aco2btpy7ta8.png" alt="Documentation Health Report" width="659" height="759"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the &lt;code&gt;project-docs&lt;/code&gt; skill running a health check on the &lt;code&gt;agent-skills&lt;/code&gt; repo itself. It scored 18/100 — which sounds brutal, but that's exactly the point. It audited the folder structure, badge compliance, SDLC coverage, and surfaced &lt;em&gt;specific&lt;/em&gt; HIGH priority gaps: missing &lt;code&gt;docs/&lt;/code&gt; directory, no product spec, no API docs, no support workflow. And then it handed me a prioritized action list.&lt;/p&gt;

&lt;p&gt;No vague "your docs could be better." Just a score, a breakdown, and five concrete next steps. That's a skill doing real work.&lt;/p&gt;

&lt;h3&gt;
  
  
  /svg-logo-system: Brand Brief Intake
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcescp8imv15sql54874n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcescp8imv15sql54874n.png" alt="Claude Code terminal showing /svg-logo-system slash command being invoked" width="800" height="297"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I ran &lt;code&gt;/svg-logo-system&lt;/code&gt; inside the Kickoff project. The skill immediately launched into brand brief intake — asking about name, audience, personality keywords, color direction, and style preference. I answered casually in a paragraph (mixing English and Bahasa Malaysia, as usual), and it extracted everything it needed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Brand Brief Extraction → 25 SVG Concepts
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhhe5121jv7gqdh3s2nkr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhhe5121jv7gqdh3s2nkr.png" alt="Claude Code showing brand brief extraction with emerald color palette and dark mode direction" width="800" height="249"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;From my casual paragraph, the skill structured a complete brand brief: Kickoff, Laravel developers, minimal + developer-focused personality, Emerald &lt;code&gt;#059669&lt;/code&gt; primary, &lt;code&gt;#0B1120&lt;/code&gt; dark background, clean sans-serif inspired by Figtree. Then it went straight to generating 25 SVG logo concepts in parallel.&lt;/p&gt;

&lt;p&gt;That's the workflow: one slash command, one casual brief, 25 concepts ready to review. No back-and-forth, no re-explaining the stack.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Output: 25 Concepts in an Interactive Gallery
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7fes5f4zb1yw6zo1dwb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc7fes5f4zb1yw6zo1dwb.png" alt="Kickoff — 25 logo concepts displayed in a dark-mode interactive grid" width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is what the skill generated — a fully interactive HTML gallery with 25 distinct concepts, all respecting the emerald + dark navy palette. Rocket Wordmark, Bracket Code, Terminal Prompt, Abstract K Paths, Terminal Window showing actual &lt;code&gt;composer&lt;/code&gt; commands — every concept is on-brand and developer-native. You can toggle between dark and light mode right in the preview.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faj3n34upkl6ip36g208b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Faj3n34upkl6ip36g208b.png" alt="Same gallery with #21 Speed Lines selected, status bar showing refinement prompt" width="800" height="415"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click a concept and the skill tells you exactly what to say next: &lt;em&gt;"Selected: #21 — Speed Lines. Tell Claude 'go with #21' to proceed to refinement."&lt;/em&gt; The entire workflow — brief intake, concept generation, selection, refinement — is guided by the skill with zero ambiguity about the next step.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bigger Picture
&lt;/h2&gt;

&lt;p&gt;Skills are how I'm thinking about AI-assisted development going forward. &lt;strong&gt;Not give Claude a long prompt, but give Claude a reusable module of expertise.&lt;/strong&gt; &lt;/p&gt;

&lt;p&gt;The same way we don't write raw SQL when we have Eloquent, we shouldn't re-explain our conventions every time we open a new session.&lt;/p&gt;

&lt;p&gt;This also feeds directly into my 2026 training program on Claude Code for solopreneurs. The goal is to show that AI isn't just a code autocomplete — it's a system you can configure to reflect your own architectural judgment.&lt;/p&gt;

&lt;p&gt;If you're a Laravel developer who's tired of re-explaining your stack, give &lt;a href="https://github.com/nasrulhazim/agent-skills" rel="noopener noreferrer"&gt;agent-skills&lt;/a&gt; a try. And if you have skills of your own worth sharing, PRs are open.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Repository:&lt;/strong&gt; &lt;a href="https://github.com/nasrulhazim/agent-skills" rel="noopener noreferrer"&gt;github.com/nasrulhazim/agent-skills&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>claudecode</category>
      <category>ai</category>
      <category>php</category>
    </item>
    <item>
      <title>I Built a Claude Code Slash Command That Designs Complete SVG Logo Systems</title>
      <dc:creator>Nasrul Hazim Bin Mohamad</dc:creator>
      <pubDate>Thu, 26 Feb 2026 16:40:51 +0000</pubDate>
      <link>https://dev.to/nasrulhazim/i-built-a-claude-code-slash-command-that-designs-complete-svg-logo-systems-2jbc</link>
      <guid>https://dev.to/nasrulhazim/i-built-a-claude-code-slash-command-that-designs-complete-svg-logo-systems-2jbc</guid>
      <description>&lt;p&gt;Ever spent hours going back and forth with design tools trying to nail down a logo? I built a Claude Code slash command that turns logo design into a structured, repeatable process — from initial brainstorming to production-ready SVG files. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Logo design is messy. You start with a vague idea, sketch a few concepts, pick one, then spend forever tweaking it for dark mode, light mode, favicons, mobile, and every other context your logo needs to live in.&lt;/p&gt;

&lt;p&gt;What if you could condense that entire workflow into a single command?&lt;/p&gt;

&lt;h2&gt;
  
  
  What &lt;code&gt;/design-logo&lt;/code&gt; Does
&lt;/h2&gt;

&lt;p&gt;The command walks through a proven three-phase methodology:&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 1: Discovery &amp;amp; Mass Exploration
&lt;/h3&gt;

&lt;p&gt;Instead of starting with one idea and hoping it works, the command generates &lt;strong&gt;25 diverse SVG concepts&lt;/strong&gt; — mixing icon-only marks, wordmarks, and combination marks across different shapes (circles, shields, hexagons) and styles (lettermarks, abstract, symbolic, typographic).&lt;/p&gt;

&lt;p&gt;All 25 concepts get dropped into a &lt;code&gt;tinker/&lt;/code&gt; directory with an interactive preview gallery featuring a dark/light mode toggle. You browse them like a mood board.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 2: Selection &amp;amp; Refinement
&lt;/h3&gt;

&lt;p&gt;Pick your favorite direction. The command then creates four production variants:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Wordmark&lt;/strong&gt; — dark and light background versions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Icon mark&lt;/strong&gt; — dark and light background versions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then it builds a comprehensive preview page with real-world mockups: navigation bars, browser frames, mobile splash screens, favicon sizes (64/32/16px), footer placements, and your brand color palette with hex codes.&lt;/p&gt;

&lt;p&gt;This is where you see if the logo actually works in context, not just in isolation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 3: Iteration
&lt;/h3&gt;

&lt;p&gt;Feedback loop. Need the icon simplified for small sizes? The command generates 3-4 icon alternatives and shows them at every relevant size (80px down to 16px) in both dark and light mode, side by side. Pick the winner, and the final preview updates automatically.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design Principles Baked In
&lt;/h2&gt;

&lt;p&gt;The command enforces good practices:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dark mode first&lt;/strong&gt; — designs start on navy (#0B1120), then adapt for light&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Size-aware rendering&lt;/strong&gt; — wordmarks at 140px+, icons at 80px and below&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contrast checking&lt;/strong&gt; — text must be legible in both modes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Simplicity that scales&lt;/strong&gt; — fewer elements survive better at small sizes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Installation
&lt;/h2&gt;

&lt;p&gt;One line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/nasrulhazim/claude-design-logo/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or clone it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/nasrulhazim/claude-design-logo.git
&lt;span class="nb"&gt;cd &lt;/span&gt;claude-design-logo
bash install.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The installer copies the slash command to &lt;code&gt;~/.claude/commands/design-logo.md&lt;/code&gt;. That's it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;Open any project in Claude Code and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/design-logo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude walks you through brand discovery, asks your style preference, then starts generating. You can also jump to specific phases:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/design-logo refine&lt;/code&gt; — skip discovery, work with existing concepts&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/design-logo icons&lt;/code&gt; — generate icon alternatives for an existing logo&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How It's Built
&lt;/h2&gt;

&lt;p&gt;The entire thing is a single Markdown file (&lt;code&gt;design-logo.md&lt;/code&gt;) that serves as a Claude Code slash command. No dependencies, no build step, no runtime. Just a well-structured prompt that Claude follows step by step.&lt;/p&gt;

&lt;p&gt;The file structure it produces:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;tinker/
├── logo-{01..25}-{name}.svg           # 25 concepts
├── preview.html                        # Gallery preview
├── logo-dark.svg                       # Final wordmark (dark bg)
├── logo-light.svg                      # Final wordmark (light bg)
├── logo-icon-dark.svg                  # Final icon (dark bg)
├── logo-icon-light.svg                 # Final icon (light bg)
├── logo-preview.html                   # Comprehensive preview
├── icon-{a..d}-{name}-{dark|light}.svg # Icon alternatives
└── icon-compare.html                   # Icon comparison
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why This Approach Works
&lt;/h2&gt;

&lt;p&gt;The key insight is &lt;strong&gt;volume first, then narrow&lt;/strong&gt;. Starting with 25 concepts instead of 1 removes the pressure of getting it right on the first try. You explore the design space broadly, then focus.&lt;/p&gt;

&lt;p&gt;The structured phases also mean you never skip important steps like testing at small sizes or checking dark/light contrast — things that are easy to forget when designing ad hoc.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try It
&lt;/h2&gt;

&lt;p&gt;The repo is public: &lt;a href="https://github.com/nasrulhazim/claude-design-logo" rel="noopener noreferrer"&gt;github.com/nasrulhazim/claude-design-logo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you use Claude Code, give &lt;code&gt;/design-logo&lt;/code&gt; a spin on your next project. The whole process — from brand discovery to production SVGs — happens in your terminal.&lt;/p&gt;

&lt;h2&gt;
  
  
  Results
&lt;/h2&gt;

&lt;p&gt;One of my latest works, as following:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwzt1yxwck7x0xn4xg57m.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwzt1yxwck7x0xn4xg57m.png" alt="Primary &amp;amp; Icon Marks" width="800" height="432"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2mzpwq1pwfj3313xmqx0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2mzpwq1pwfj3313xmqx0.png" alt="Size Scale" width="800" height="528"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9whicviwkst5b2884qaz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9whicviwkst5b2884qaz.png" alt="Navigation &amp;amp; Desktop Browser" width="800" height="412"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F220pza92ei5n0mq06lou.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F220pza92ei5n0mq06lou.png" alt="Mobile, Favicon &amp;amp; App Icon, Footer" width="800" height="595"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9onkzc2db9jr4wrbxs2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk9onkzc2db9jr4wrbxs2.png" alt="On Colored Backgrounds &amp;amp; Brand Colors" width="800" height="478"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Tips
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Give a good information about your products&lt;/li&gt;
&lt;li&gt;Keep it as SVG, because you always can ask for Claude to render in different sizes and for different purposes.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>claude</category>
      <category>ai</category>
    </item>
    <item>
      <title>From Guidelines to Toolchain: Rebuilding claude-docs in One Day</title>
      <dc:creator>Nasrul Hazim Bin Mohamad</dc:creator>
      <pubDate>Tue, 03 Feb 2026 08:45:26 +0000</pubDate>
      <link>https://dev.to/nasrulhazim/from-guidelines-to-toolchain-rebuilding-claude-docs-in-one-day-11c0</link>
      <guid>https://dev.to/nasrulhazim/from-guidelines-to-toolchain-rebuilding-claude-docs-in-one-day-11c0</guid>
      <description>&lt;p&gt;I maintain 20+ open-source packages. Every one of them needs documentation. And every time I start a new project, I solve the same problems — folder structure, linting rules, release notes, badge standards.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/nasrulhazim/claude-docs" rel="noopener noreferrer"&gt;&lt;code&gt;claude-docs&lt;/code&gt;&lt;/a&gt; was supposed to fix that. But until today, it was just a set of guidelines and a slash command. Helpful, not enough.&lt;/p&gt;

&lt;p&gt;So I blocked out a day to turn it into a proper toolchain. 8 commits, 20 files changed, +2,083 / -449 lines. Here's the before and after.&lt;/p&gt;

&lt;h2&gt;
  
  
  Documentation Guidelines
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; Abstract rules about how docs should look. You read them, nodded, then did your own thing anyway.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt; Rewritten from scratch with concrete examples for 5 project types — Laravel packages, APIs, full-stack apps, CLI tools, and SDKs. Numbered folder conventions, progressive detail structure, ADR support, MermaidJS diagrams. Over 700 lines changed in the first commit alone.&lt;/p&gt;

&lt;p&gt;The goal: if you can't figure out how to structure your docs after reading the guidelines, that's a bug.&lt;/p&gt;

&lt;h2&gt;
  
  
  Markdown Linting
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; &lt;code&gt;markdownlint&lt;/code&gt; was configured, but you had to run it file by file. Most of the time, people just skipped it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt; One script, one command. &lt;code&gt;lint.sh&lt;/code&gt; finds all markdown files, auto-detects your config, and lints everything in one pass. Add &lt;code&gt;--fix&lt;/code&gt; to auto-correct.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/.claude/lint.sh           &lt;span class="c"&gt;# lint everything&lt;/span&gt;
~/.claude/lint.sh &lt;span class="nt"&gt;--fix&lt;/span&gt;     &lt;span class="c"&gt;# lint &amp;amp; auto-fix&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If linting takes effort, nobody lints. Now it doesn't.&lt;/p&gt;

&lt;h2&gt;
  
  
  Release Notes
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; Manual. Copy commits from git log, reformat into markdown, paste into CHANGELOG. Every. Single. Time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt; &lt;code&gt;release-note.sh&lt;/code&gt; — a 300+ line script that parses your git log, categorizes commits by conventional prefixes, and generates structured markdown with summary tables and contributor lists.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;~/.claude/release-note.sh                        &lt;span class="c"&gt;# today's release note&lt;/span&gt;
~/.claude/release-note.sh &lt;span class="nt"&gt;--tldr&lt;/span&gt;                 &lt;span class="c"&gt;# summary version&lt;/span&gt;
~/.claude/release-note.sh &lt;span class="nt"&gt;--since&lt;/span&gt; &lt;span class="s2"&gt;"1 week ago"&lt;/span&gt;   &lt;span class="c"&gt;# custom date range&lt;/span&gt;
~/.claude/release-note.sh &lt;span class="nt"&gt;--output&lt;/span&gt; CHANGELOG.md  &lt;span class="c"&gt;# write to file&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This one went through three iterations in a single session — build, refactor, extend. The first version showed me what the second version needed. That's the natural rhythm for tooling work.&lt;/p&gt;

&lt;h2&gt;
  
  
  Badge Standards
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; Some projects had badges, some didn't. No consistency.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt; Mandatory version and license badges for every project README. Copy-paste templates for 10 package registries (Packagist, npm, PyPI, crates.io, and more). Badge compliance tracked in the &lt;code&gt;/docs health&lt;/code&gt; report.&lt;/p&gt;

&lt;p&gt;Badges are the first thing people see on your repo. They signal you care. Making the standard easy to follow is what makes people actually follow it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Project Auto-Detection
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Before:&lt;/strong&gt; PHP and Node only.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;After:&lt;/strong&gt; Supports Python, Ruby, Rust, Go, .NET, Java, Dart/Flutter, and Elixir. Run &lt;code&gt;/docs scaffold &amp;lt;type&amp;gt;&lt;/code&gt; and get the right structure for your stack.&lt;/p&gt;

&lt;h2&gt;
  
  
  What &lt;code&gt;/docs&lt;/code&gt; Can Do Now
&lt;/h2&gt;

&lt;p&gt;After today's update, here's everything available under the &lt;code&gt;/docs&lt;/code&gt; slash command in Claude Code:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&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;/docs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Create new documentation structure (auto-detects your project type)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/docs reorganize&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Reorganize existing docs into the numbered standard&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/docs validate&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Validate against standards and report issues&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/docs update-toc&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Update all README.md table of contents&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/docs health&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Generate documentation health report with badge compliance&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/docs scaffold &amp;lt;type&amp;gt;&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Scaffold from template: &lt;code&gt;laravel&lt;/code&gt;, &lt;code&gt;api&lt;/code&gt;, &lt;code&gt;cli&lt;/code&gt;, &lt;code&gt;sdk&lt;/code&gt;, &lt;code&gt;fullstack&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/docs release-note&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Generate full release note from today's git log&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/docs release-note --tldr&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Generate summary release note&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;One command to rule them all. Pick what you need.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Full Picture
&lt;/h2&gt;

&lt;p&gt;One install command gets you everything:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/nasrulhazim/claude-docs/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;What You Get&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;Guidelines&lt;/td&gt;
&lt;td&gt;Concrete examples for 5 project types&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;lint.sh&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Batch markdown linting with auto-fix&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;release-note.sh&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Git log → structured release notes&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;code&gt;/docs&lt;/code&gt; command&lt;/td&gt;
&lt;td&gt;Scaffold, validate, health report, auto-detect&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Badge templates&lt;/td&gt;
&lt;td&gt;10 registries, 13 project types&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;I'm a solo founder running &lt;a href="https://github.com/cleaniquecoders" rel="noopener noreferrer"&gt;Cleanique Coders&lt;/a&gt;. No docs team, no technical writer. What I have is tooling that enforces standards so I don't have to remember them.&lt;/p&gt;

&lt;p&gt;Every hour spent on this saves ten hours of "how did we do docs in &lt;em&gt;that&lt;/em&gt; project?" across the next year. If you maintain multiple repos — especially alone — standardize the boring stuff first.&lt;/p&gt;

&lt;p&gt;The repo is open source. Take it, use it, tell me what's missing.&lt;/p&gt;

&lt;p&gt;👉 &lt;a href="https://github.com/nasrulhazim/claude-docs" rel="noopener noreferrer"&gt;github.com/nasrulhazim/claude-docs&lt;/a&gt;&lt;/p&gt;

</description>
      <category>documentation</category>
      <category>automation</category>
      <category>devex</category>
    </item>
    <item>
      <title>Stop Guessing Your Product's Worth: A Claude Code Skill for Pricing, Sales &amp; Financial Planning</title>
      <dc:creator>Nasrul Hazim Bin Mohamad</dc:creator>
      <pubDate>Tue, 03 Feb 2026 02:02:39 +0000</pubDate>
      <link>https://dev.to/nasrulhazim/stop-guessing-your-products-worth-a-claude-code-skill-for-pricing-sales-financial-planning-3g1</link>
      <guid>https://dev.to/nasrulhazim/stop-guessing-your-products-worth-a-claude-code-skill-for-pricing-sales-financial-planning-3g1</guid>
      <description>&lt;p&gt;I've been building software for over a decade. Laravel packages, enterprise systems, SaaS tools — you name it.&lt;/p&gt;

&lt;p&gt;But here's the thing nobody talks about: &lt;strong&gt;most developers are terrible at pricing their own work.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I know because I was one of them.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Problem: We Build Great Software, Then Guess the Price
&lt;/h2&gt;

&lt;p&gt;You spend weeks — sometimes months — building a product. You know every line of code, every edge case, every architectural decision.&lt;/p&gt;

&lt;p&gt;Then someone asks, "How much?"&lt;/p&gt;

&lt;p&gt;And suddenly, you're stuck.&lt;/p&gt;

&lt;p&gt;You look at competitors. You check some blog posts. You ask in a Telegram group. Someone says "just charge RM 500/month" and someone else says "bro, that's too cheap."&lt;/p&gt;

&lt;p&gt;So you pick a number that &lt;em&gt;feels&lt;/em&gt; right. No structure. No breakdown. No financial plan.&lt;/p&gt;

&lt;p&gt;I've done this myself more times than I'd like to admit. And I've watched other developers do the same — talented people undercharging because they've never sat down to properly think through their pricing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why I Built claude-sales
&lt;/h2&gt;

&lt;p&gt;I was working on the pricing strategy for one of my products — &lt;a href="https://g8stack.com" rel="noopener noreferrer"&gt;G8Stack&lt;/a&gt;, an API management platform built on Kong Gateway. I needed to figure out:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What should the base license cost?&lt;/li&gt;
&lt;li&gt;What about add-ons like monitoring, SSO, training?&lt;/li&gt;
&lt;li&gt;How do I structure partner channels? Reseller vs referrer vs affiliate?&lt;/li&gt;
&lt;li&gt;What's a realistic government project quotation?&lt;/li&gt;
&lt;li&gt;What marketing copy works for different audiences?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I ended up having long conversations with Claude about all of this. And the output was genuinely useful — proper pricing breakdowns, partner margin calculations, quotation templates, even social media copy.&lt;/p&gt;

&lt;p&gt;Then I thought: &lt;strong&gt;why am I keeping this in a single conversation?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;What if I could package this into a reusable Claude Code skill — something I could use across any product, anytime?&lt;/p&gt;

&lt;p&gt;That's how &lt;a href="https://github.com/nasrulhazim/claude-sales" rel="noopener noreferrer"&gt;claude-sales&lt;/a&gt; was born.&lt;/p&gt;




&lt;h2&gt;
  
  
  What claude-sales Does
&lt;/h2&gt;

&lt;p&gt;It's a set of Claude Code slash commands that give you instant access to your product's sales and pricing information:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/get-pricing license
/get-pricing via reseller
/get-pricing government full project

/get-marketing taglines
/get-marketing social casual

/get-quotation enterprise
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But the real value isn't the commands — it's the &lt;strong&gt;thinking framework&lt;/strong&gt; behind them.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Framework: Think Like a Business, Not Just a Developer
&lt;/h2&gt;

&lt;p&gt;When you install claude-sales, you get a &lt;code&gt;product-config-template.md&lt;/code&gt; file. Filling it in forces you to answer questions most developers skip:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. What's Your Base Price?
&lt;/h3&gt;

&lt;p&gt;Not "what feels right" — but what's the actual value?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;base_price&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;25000&lt;/span&gt;
&lt;span class="na"&gt;unit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;one-time"&lt;/span&gt;
&lt;span class="na"&gt;includes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Unlimited&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;nodes"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Unlimited&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;users"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Remote&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;deployment"&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;1&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;year&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;updates&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;&amp;amp;&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;support"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you write this down, you start thinking about what's included, what's extra, and what your minimum viable offering looks like.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. What Are Your Add-ons?
&lt;/h3&gt;

&lt;p&gt;Most products have a core and optional extras. Defining them separately helps you create flexible packages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;addons&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Monitoring&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Integration"&lt;/span&gt;
    &lt;span class="na"&gt;price_min&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20000&lt;/span&gt;
    &lt;span class="na"&gt;price_max&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30000&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;SSO&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Integration"&lt;/span&gt;
    &lt;span class="na"&gt;price_min&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10000&lt;/span&gt;
    &lt;span class="na"&gt;price_max&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;25000&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Training"&lt;/span&gt;
    &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5000&lt;/span&gt;
    &lt;span class="na"&gt;unit&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;per&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;day"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This isn't just for quotations. This is your &lt;strong&gt;product strategy&lt;/strong&gt;. Each add-on is a revenue stream.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. How Will You Sell Through Partners?
&lt;/h3&gt;

&lt;p&gt;If you're a solo founder or small team, you can't be everywhere. Partners extend your reach — but you need clear margins:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;channels&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;referrer&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;margin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt;    &lt;span class="c1"&gt;# Just introduces a lead&lt;/span&gt;
  &lt;span class="na"&gt;affiliate&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;margin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;20&lt;/span&gt;    &lt;span class="c1"&gt;# Markets and qualifies leads&lt;/span&gt;
  &lt;span class="na"&gt;reseller&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;margin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;30&lt;/span&gt;    &lt;span class="c1"&gt;# Handles full sales cycle&lt;/span&gt;
  &lt;span class="na"&gt;fronting&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;margin&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;15&lt;/span&gt;    &lt;span class="c1"&gt;# PM &amp;amp; finance only&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I learned this the hard way. Without defined margins, every partner conversation becomes an awkward negotiation. With a clear framework, it becomes a professional discussion.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. What Does a Typical Project Cost?
&lt;/h3&gt;

&lt;p&gt;Government and enterprise clients don't buy "a license." They buy projects. You need to break down what a full implementation looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;packages&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Government&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Full"&lt;/span&gt;
    &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Requirement&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;Study"&lt;/span&gt;     &lt;span class="s"&gt;→ RM 15,000&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Product&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;License"&lt;/span&gt;       &lt;span class="s"&gt;→ RM 40,000&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Integration"&lt;/span&gt;           &lt;span class="s"&gt;→ RM 30,000&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Customization"&lt;/span&gt;         &lt;span class="s"&gt;→ RM 20,000&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;item&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Training"&lt;/span&gt;              &lt;span class="s"&gt;→ RM 15,000&lt;/span&gt;
    &lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;135,000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a prospect asks "how much for the whole thing?", you have an answer ready. Not a guess — a structured breakdown.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Financial Planning Side
&lt;/h2&gt;

&lt;p&gt;Here's where it gets interesting for solo founders and small teams.&lt;/p&gt;

&lt;p&gt;Once you have your pricing defined, you can start asking real business questions:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"How many direct sales do I need this year to hit RM 300,000?"&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;RM 300,000 ÷ RM 25,000 = 12 direct sales
That's 1 sale per month.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;"What if half come through resellers?"&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;6 direct × RM 25,000 = RM 150,000
6 reseller × RM 17,500 = RM 105,000
Total: RM 255,000

Need 2 more reseller sales to hit target.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;"What's my revenue if I land 2 government projects?"&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;2 × RM 135,000 = RM 270,000
Plus maintenance Year 2: 2 × RM 5,000 = RM 10,000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These aren't complex calculations. But most developers never do them because they never structured their pricing in the first place.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to Use It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Quick Install
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/nasrulhazim/claude-sales/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure Your Product
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cp&lt;/span&gt; ~/.claude/product-config-template.md ./product-config.md
&lt;span class="c"&gt;# Edit with your product details&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use the Commands
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/get-pricing license              &lt;span class="c"&gt;# Base pricing&lt;/span&gt;
/get-pricing via reseller         &lt;span class="c"&gt;# Partner calculations&lt;/span&gt;
/get-quotation government         &lt;span class="c"&gt;# Quotation template&lt;/span&gt;
/get-marketing elevator pitch     &lt;span class="c"&gt;# 30-second pitch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The template is generic — it works for any product, SaaS, on-premise software, or service. Fill in your numbers, and Claude Code becomes your sales assistant.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's Inside the Repo
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;claude-sales/
├── install.sh                     # One-line installer
├── get-pricing.md                 # /get-pricing command
├── get-marketing.md               # /get-marketing command
├── get-quotation.md               # /get-quotation command
├── sales-reference.md             # Pricing logic &amp;amp; patterns
├── product-config-template.md     # Your product config
└── examples/
    └── g8stack-config.md          # Real-world example
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The G8Stack example is a real configuration I use for my own product. It includes actual pricing, partner margins, social media copy (yes, even the Malay casual posts), and quotation templates.&lt;/p&gt;




&lt;h2&gt;
  
  
  Who This Is For
&lt;/h2&gt;

&lt;p&gt;This isn't just for people selling software. If you're:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A &lt;strong&gt;developer with a side project&lt;/strong&gt; that you want to monetise&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;freelancer&lt;/strong&gt; who packages services into products&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;small agency&lt;/strong&gt; that needs consistent quotations&lt;/li&gt;
&lt;li&gt;A &lt;strong&gt;solo founder&lt;/strong&gt; trying to figure out pricing strategy&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;open-source maintainer&lt;/strong&gt; exploring commercial offerings&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;...then having a structured pricing framework saves you from the "I'll figure it out later" trap that never actually gets figured out.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bigger Picture
&lt;/h2&gt;

&lt;p&gt;I've been building Claude Code skills like &lt;a href="https://github.com/nasrulhazim/claude-docs" rel="noopener noreferrer"&gt;claude-docs&lt;/a&gt; for documentation and &lt;a href="https://github.com/nasrulhazim/claude-analyze-repo" rel="noopener noreferrer"&gt;claude-analyze-repo&lt;/a&gt; for repository analysis. Each one tackles a specific pain point developers face.&lt;/p&gt;

&lt;p&gt;claude-sales tackles the business side — because building a great product is only half the battle. Knowing how to price it, sell it, and plan around it is the other half.&lt;/p&gt;

&lt;p&gt;And honestly? That other half is what separates a side project from a business.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;If you've ever caught yourself saying "I don't know how much to charge" or "I'll figure out the pricing later", this is for you.&lt;/p&gt;

&lt;p&gt;The template forces you to think about your product as a business:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What's the core offering worth?&lt;/li&gt;
&lt;li&gt;What can be sold separately?&lt;/li&gt;
&lt;li&gt;Who are your partners and what do they earn?&lt;/li&gt;
&lt;li&gt;What does a full project look like?&lt;/li&gt;
&lt;li&gt;How do you talk about your product?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It takes maybe 30 minutes to fill in. But the clarity it gives you lasts much longer than that.&lt;/p&gt;

&lt;p&gt;Check it out: &lt;a href="https://github.com/nasrulhazim/claude-sales" rel="noopener noreferrer"&gt;github.com/nasrulhazim/claude-sales&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;If you find this useful, give it a ⭐ on GitHub. And if you end up defining your product pricing with it, I'd love to hear how it went.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>claude</category>
      <category>entrepreneurship</category>
      <category>ai</category>
    </item>
    <item>
      <title>Dokufy: Generate PDFs your way — Gotenberg, LibreOffice, or native PHP.</title>
      <dc:creator>Nasrul Hazim Bin Mohamad</dc:creator>
      <pubDate>Thu, 15 Jan 2026 10:08:03 +0000</pubDate>
      <link>https://dev.to/nasrulhazim/dokufy-generate-pdfs-your-way-gotenberg-libreoffice-or-native-php-2c58</link>
      <guid>https://dev.to/nasrulhazim/dokufy-generate-pdfs-your-way-gotenberg-libreoffice-or-native-php-2c58</guid>
      <description>&lt;p&gt;I'm excited to share my latest Laravel package - a driver-based document generation and PDF conversion tool.&lt;/p&gt;

&lt;p&gt;The problem it solves: You shouldn't have to rewrite your document generation code just because you switched from local development to production, or moved from shared hosting to Kubernetes.&lt;/p&gt;

&lt;p&gt;Key features:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unified API across 5 drivers (Gotenberg, LibreOffice, Chromium, PhpWord)&lt;/li&gt;
&lt;li&gt;DOCX &amp;amp; HTML template support with placeholder processing&lt;/li&gt;
&lt;li&gt;First-class testing support with FakeDriver&lt;/li&gt;
&lt;li&gt;Integrates with cleaniquecoders/placeholdify
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require cleaniquecoders/dokufy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More details documentation can be found &lt;a href="https://github.com/cleaniquecoders/dokufy" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Feedback and contributions welcome!&lt;/p&gt;

</description>
      <category>laravel</category>
    </item>
    <item>
      <title>Introducing Claude Code Documentation Standards: Automated Documentation with Built-in Linting</title>
      <dc:creator>Nasrul Hazim Bin Mohamad</dc:creator>
      <pubDate>Wed, 10 Dec 2025 01:23:18 +0000</pubDate>
      <link>https://dev.to/nasrulhazim/introducing-claude-code-documentation-standards-automated-documentation-with-built-in-linting-51c</link>
      <guid>https://dev.to/nasrulhazim/introducing-claude-code-documentation-standards-automated-documentation-with-built-in-linting-51c</guid>
      <description>&lt;p&gt;Keeping documentation tidy, readable, and easy to navigate shouldn’t feel like a chore. But in most projects, it eventually becomes one. Different people write differently, folders get messy, and soon no one knows where anything lives.&lt;/p&gt;

&lt;p&gt;So I built something to fix that.&lt;/p&gt;

&lt;p&gt;Introducing &lt;strong&gt;Claude Code Documentation Standards&lt;/strong&gt; — a framework that helps you write better documentation with less effort, using a consistent structure, automated checks, and a simple one-line install.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Documentation Usually Feels Hard
&lt;/h2&gt;

&lt;p&gt;If you’ve ever joined or handed over a project, you’ve probably faced one (or all) of these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Every project stores documentation differently&lt;/li&gt;
&lt;li&gt;It's difficult to figure out “where to start” reading&lt;/li&gt;
&lt;li&gt;Markdown formatting isn’t consistent&lt;/li&gt;
&lt;li&gt;No quality control — mistakes slip through&lt;/li&gt;
&lt;li&gt;Setting up documentation tools takes time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;None of this should be your problem. You just want your documentation to look good, stay organised, and help people find what they need quickly.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Framework Does For You
&lt;/h2&gt;

&lt;p&gt;Claude Code Documentation Standards gives you:&lt;/p&gt;

&lt;p&gt;✅ A clean, numbered folder structure so you always know where things belong&lt;br&gt;
✅ Automatic markdown linting so everything stays consistent&lt;br&gt;
✅ A simple &lt;code&gt;/docs&lt;/code&gt; command that generates and organises your documentation&lt;br&gt;
✅ One-line installation — truly plug-and-play&lt;br&gt;
✅ CI/CD examples for teams&lt;br&gt;
✅ Pre-commit hooks so docs stay clean before they’re even committed&lt;/p&gt;

&lt;p&gt;It’s designed to save you time, reduce confusion, and make your project look polished — with almost no setup.&lt;/p&gt;


&lt;h2&gt;
  
  
  What You’ll Love About It
&lt;/h2&gt;
&lt;h3&gt;
  
  
  &lt;strong&gt;1. A Structure That Actually Makes Sense&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Your documentation is grouped by &lt;em&gt;context&lt;/em&gt;, not by random categories.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docs/
├── 01-architecture/
├── 02-development/
├── 03-deployment/
└── 04-api/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The numbering tells you the order things should be read — so new contributors always start in the right place.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;2. Your Documentation Cleans Itself&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;With built-in markdown linting, you don’t have to worry about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Odd formatting&lt;/li&gt;
&lt;li&gt;Incorrect heading levels&lt;/li&gt;
&lt;li&gt;Missing code block labels&lt;/li&gt;
&lt;li&gt;Extra whitespace&lt;/li&gt;
&lt;li&gt;Long, unreadable lines&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Write normally — the tools help keep it clean.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;3. A Single Command That Builds Everything For You&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Just type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/docs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Claude Code will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Scan your project&lt;/li&gt;
&lt;li&gt;Create the correct folder structure&lt;/li&gt;
&lt;li&gt;Generate READMEs with tables of contents&lt;/li&gt;
&lt;li&gt;Lint everything&lt;/li&gt;
&lt;li&gt;Fix formatting issues&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Documentation setup becomes a 5-second task instead of a weekend chore.&lt;/p&gt;




&lt;h3&gt;
  
  
  &lt;strong&gt;4. Easy-to-Understand Flow&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;Your docs now guide readers naturally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Overview&lt;/strong&gt; — What this project is&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Getting Started&lt;/strong&gt; — How to use it immediately&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Deep Dives&lt;/strong&gt; — How it works behind the scenes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reference&lt;/strong&gt; — APIs, endpoints, commands, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This keeps your project beginner-friendly &lt;em&gt;and&lt;/em&gt; expert-friendly.&lt;/p&gt;




&lt;h2&gt;
  
  
  Installation (Takes Only One Line)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-fsSL&lt;/span&gt; https://raw.githubusercontent.com/nasrulhazim/claude-docs/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That’s all. The installer sets up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Documentation templates&lt;/li&gt;
&lt;li&gt;Markdown linting&lt;/li&gt;
&lt;li&gt;Slash commands&lt;/li&gt;
&lt;li&gt;Default linting rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you prefer manual install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git clone https://github.com/nasrulhazim/claude-docs.git
&lt;span class="nb"&gt;cd &lt;/span&gt;claude-docs
./install.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Using It
&lt;/h2&gt;

&lt;p&gt;In any Claude Code project, run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/docs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Analyse your project&lt;/li&gt;
&lt;li&gt;Generate all documentation folders&lt;/li&gt;
&lt;li&gt;Create READMEs&lt;/li&gt;
&lt;li&gt;Lint your files&lt;/li&gt;
&lt;li&gt;Automatically fix issues&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Additional commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/docs reorganize
/docs validate
/docs update-toc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Need to lint manually?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;markdownlint docs/**/*.md
markdownlint --fix docs/**/*.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  A Documentation Layout That Stays Consistent
&lt;/h2&gt;

&lt;p&gt;Example structure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;docs/
├── README.md
├── 01-getting-started/
│   ├── README.md
│   ├── 01-installation.md
│   ├── 02-authentication.md
│   └── 03-first-request.md
├── 02-endpoints/
│   ├── README.md
│   ├── 01-users.md
│   ├── 02-posts.md
│   └── 03-comments.md
└── 03-guides/
    ├── README.md
    ├── 01-pagination.md
    ├── 02-filtering.md
    └── 03-rate-limiting.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your readers will never wonder where to look again.&lt;/p&gt;




&lt;h2&gt;
  
  
  Works Beautifully in CI/CD
&lt;/h2&gt;

&lt;p&gt;Add automatic documentation linting to your workflows with a few lines. This keeps your project polished even as more contributors join in.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why This Matters (Even If You’re a Solo Developer)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;For Developers&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Faster onboarding&lt;/li&gt;
&lt;li&gt;Cleaner, more readable docs&lt;/li&gt;
&lt;li&gt;Less manual formatting&lt;/li&gt;
&lt;li&gt;A consistent experience across projects&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;For Teams&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Everyone follows the same structure&lt;/li&gt;
&lt;li&gt;Automated checks mean fewer review headaches&lt;/li&gt;
&lt;li&gt;Clearer documentation means fewer repeated questions&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;For Open Source&lt;/strong&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Your project looks more mature&lt;/li&gt;
&lt;li&gt;Contributors instantly understand where to add docs&lt;/li&gt;
&lt;li&gt;Easier discovery = more engagement&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Customise It Your Way
&lt;/h2&gt;

&lt;p&gt;Want shorter line lengths?&lt;br&gt;
Want different contexts?&lt;br&gt;
Working on mobile apps, microservices, or data science?&lt;/p&gt;

&lt;p&gt;You can adjust everything:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add new contexts&lt;/li&gt;
&lt;li&gt;Update linting rules&lt;/li&gt;
&lt;li&gt;Modify folder structure&lt;/li&gt;
&lt;li&gt;Create your own templates&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The framework is opinionated — but flexible.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Writing documentation shouldn’t drain your energy or slow down your project. With Claude Code Documentation Standards, you get:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A clean structure&lt;/li&gt;
&lt;li&gt;Automatic quality control&lt;/li&gt;
&lt;li&gt;One-command generation&lt;/li&gt;
&lt;li&gt;Consistent formatting&lt;/li&gt;
&lt;li&gt;A beginner-friendly experience&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Let your tools handle the boring parts — so you can focus on building great software.&lt;/p&gt;

</description>
      <category>claude</category>
      <category>documentation</category>
      <category>ai</category>
      <category>programming</category>
    </item>
    <item>
      <title>Laravel Running Number v3.0 — A Practical, Powerful Upgrade for Real-World Systems</title>
      <dc:creator>Nasrul Hazim Bin Mohamad</dc:creator>
      <pubDate>Thu, 13 Nov 2025 11:33:21 +0000</pubDate>
      <link>https://dev.to/nasrulhazim/laravel-running-number-v30-a-practical-powerful-upgrade-for-real-world-systems-1op9</link>
      <guid>https://dev.to/nasrulhazim/laravel-running-number-v30-a-practical-powerful-upgrade-for-real-world-systems-1op9</guid>
      <description>&lt;p&gt;Laravel Running Number v3.0 is finally here, and this release introduces the kind of improvements that make a difference in real systems—where concurrency matters, audit trails need to be trustworthy, and developers just want a clean, predictable API to generate running numbers.&lt;/p&gt;

&lt;p&gt;If you haven't seen the release notes yet, you can check them out here:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/cleaniquecoders/laravel-running-number/releases/tag/3.0.0" rel="noopener noreferrer"&gt;&lt;strong&gt;Release v3.0.0&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/cleaniquecoders/laravel-running-number/tree/main/docs" rel="noopener noreferrer"&gt;&lt;strong&gt;Documentation&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before we dive in, one quick reminder:&lt;br&gt;
Make sure your types are declared in &lt;code&gt;config/running-number.php&lt;/code&gt; or exposed via your enum.&lt;/p&gt;

&lt;p&gt;More in the &lt;a href="https://github.com/cleaniquecoders/laravel-running-number/blob/main/docs/02-configuration/01-overview.md" rel="noopener noreferrer"&gt;Configuration Overview&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, let’s talk about what’s new and why these updates actually matter in day-to-day application development.&lt;/p&gt;


&lt;h2&gt;
  
  
  Native PHP Enums — Cleaner, Safer, Less Guesswork
&lt;/h2&gt;

&lt;p&gt;I’ve wanted proper enum support for a long time, and v3.0 finally brings it in.&lt;br&gt;
Enums help reduce typos, give you IDE autocompletion, and make your code more expressive.&lt;/p&gt;

&lt;p&gt;With Traitify behind the scenes, you also get helpers like &lt;code&gt;values()&lt;/code&gt;, &lt;code&gt;labels()&lt;/code&gt;, and &lt;code&gt;options()&lt;/code&gt; automatically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;CleaniqueCoders\RunningNumber\Enums\Organization&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// config/running-number.php&lt;/span&gt;
&lt;span class="s1"&gt;'types'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;Organization&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;values&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nv"&gt;$number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;running_number&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;Organization&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;PROFILE&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// PROFILE001&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  UUID Identifiers — Because Debugging Shouldn’t Be a Guessing Game
&lt;/h2&gt;

&lt;p&gt;Every generated sequence now comes with a UUID.&lt;br&gt;
This is incredibly helpful when:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You’re syncing with external services&lt;/li&gt;
&lt;li&gt;You want stronger audit trails&lt;/li&gt;
&lt;li&gt;You need to debug inconsistencies
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$rn&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;RunningNumber&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;where&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'type'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'PROFILE'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$rn&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It’s small, but it’s the kind of practical addition you appreciate once you need it.&lt;/p&gt;


&lt;h2&gt;
  
  
  Reset Periods — Daily, Monthly, Yearly, or Fully Manual
&lt;/h2&gt;

&lt;p&gt;Reset periods make your identifiers predictable.&lt;br&gt;
Think invoices that restart monthly or reports that refresh every year.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="s1"&gt;'reset_period'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'default'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;ResetPeriod&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;MONTHLY&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'types'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="s1"&gt;'invoice'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nc"&gt;ResetPeriod&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;YEARLY&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And if you ever need to reset manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan running-number:reset INVOICE &lt;span class="nt"&gt;--scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;retail
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives you full control without cluttering your code.&lt;/p&gt;




&lt;h2&gt;
  
  
  Date-Based Presenters — Human-Readable, Business-Friendly Numbers
&lt;/h2&gt;

&lt;p&gt;Sometimes the business team wants to see the date &lt;em&gt;inside&lt;/em&gt; the number.&lt;br&gt;
Presenters let you customise formatting cleanly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;CleaniqueCoders\RunningNumber\Presenters\YearMonthPresenter&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nv"&gt;$number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;running_number&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'invoice'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;formatter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;YearMonthPresenter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'-'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="c1"&gt;// INVOICE-2025-11-001&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Readable, structured, and consistent.&lt;/p&gt;




&lt;h2&gt;
  
  
  Scopes — Multiple Independent Sequences for the Same Type
&lt;/h2&gt;

&lt;p&gt;One of my favourite additions.&lt;br&gt;
Scopes let you maintain separate sequences for different "segments"—branches, stores, departments, etc.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nf"&gt;running_number&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'invoice'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'retail'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;    &lt;span class="c1"&gt;// INVOICE001&lt;/span&gt;
&lt;span class="nf"&gt;running_number&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'invoice'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'wholesale'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// INVOICE001&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No more juggling prefixes or custom logic just to keep numbers separated.&lt;/p&gt;




&lt;h2&gt;
  
  
  Custom Starting Numbers — Perfect for Migrations
&lt;/h2&gt;

&lt;p&gt;For teams migrating from legacy systems, this is a lifesaver.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;running_number&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'ticket'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;startFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// TICKET1001&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CLI option is also available:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan running-number:create ticket &lt;span class="nt"&gt;--start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Max Number Limits — Fail Fast, Fail Safe
&lt;/h2&gt;

&lt;p&gt;If a sequence should never go beyond a certain range, you can enforce it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="k"&gt;try&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;running_number&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'voucher'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;maxNumber&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;generate&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;MaxNumberReachedException&lt;/span&gt; &lt;span class="nv"&gt;$e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// graceful handling&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Especially useful for voucher books, serial allocations, and compliance-driven systems.&lt;/p&gt;




&lt;h2&gt;
  
  
  Preview Mode — Know the Next Number Without Updating Anything
&lt;/h2&gt;

&lt;p&gt;Great for UI previews and displaying "Upcoming Order Number".&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$next&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;running_number&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'order'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;preview&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No DB writes. No side effects.&lt;/p&gt;




&lt;h2&gt;
  
  
  Batch Generation — Atomic, Fast, and Fully Safe
&lt;/h2&gt;

&lt;p&gt;Sometimes you need to generate multiple numbers in one go—shipping labels, voucher sheets, batch allocations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$numbers&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;running_number&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;type&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'shipment'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;generateBatch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This happens inside a single transaction with locking, so everything remains safe.&lt;/p&gt;




&lt;h2&gt;
  
  
  Model Trait — Zero Boilerplate Number Generation
&lt;/h2&gt;

&lt;p&gt;If you want a field to auto-populate when a model is created, this trait does all the heavy lifting.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="kd"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Invoice&lt;/span&gt; &lt;span class="kd"&gt;extends&lt;/span&gt; &lt;span class="nc"&gt;Model&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;use&lt;/span&gt; &lt;span class="nc"&gt;InteractsWithRunningNumber&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$runningNumberField&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'invoice_number'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="nv"&gt;$runningNumberType&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'invoice'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;protected&lt;/span&gt; &lt;span class="kt"&gt;?string&lt;/span&gt; &lt;span class="nv"&gt;$runningNumberScope&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'$store_id'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clean. Minimal. Reliable.&lt;/p&gt;




&lt;h2&gt;
  
  
  Artisan Commands — Handy Tools for Ops and Developers
&lt;/h2&gt;

&lt;p&gt;You can create, list, and reset sequences directly from the CLI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;php artisan running-number:create invoice &lt;span class="nt"&gt;--scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;retail &lt;span class="nt"&gt;--start&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;100 &lt;span class="nt"&gt;--reset&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;yearly
php artisan running-number:list
php artisan running-number:reset INVOICE &lt;span class="nt"&gt;--scope&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;retail &lt;span class="nt"&gt;--force&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ops teams will appreciate this.&lt;/p&gt;




&lt;h2&gt;
  
  
  Optional REST API — Use It Across Services
&lt;/h2&gt;

&lt;p&gt;If you’re running microservices or integrating with external apps, the optional API is a straightforward solution.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://localhost/api/running-numbers/generate &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"type":"invoice","scope":"retail"}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://github.com/cleaniquecoders/laravel-running-number/blob/main/docs/03-usage/08-rest-api.md" rel="noopener noreferrer"&gt;Full API docs&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Events — Integrate with Logging, Notifications, or External Systems
&lt;/h2&gt;

&lt;p&gt;Hook into &lt;code&gt;RunningNumberGenerated&lt;/code&gt; to push updates where you need them.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Event&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;RunningNumberGenerated&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Number generated'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$event&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Simple and effective.&lt;/p&gt;




&lt;h2&gt;
  
  
  Documentation
&lt;/h2&gt;

&lt;p&gt;See full documentation &lt;a href="https://github.com/cleaniquecoders/laravel-running-number/tree/main/docs" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Upgrade Guide
&lt;/h3&gt;

&lt;p&gt;Refer to &lt;a href="https://github.com/cleaniquecoders/laravel-running-number/blob/main/docs/07-upgrade/01-upgrade-guide.md" rel="noopener noreferrer"&gt;upgrade guide&lt;/a&gt; for upgrading from version 2.3 to 3.0.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;v3.0 is a solid upgrade. It’s the kind of release that doesn’t just add features—it improves the fundamentals of how running numbers should behave in a production-grade system.&lt;/p&gt;

&lt;p&gt;Whether you're building a billing engine, logistics workflow, multi-tenant SaaS, or internal ERP module, this version gives you the flexibility and reliability you need.&lt;/p&gt;




&lt;p&gt;Photo by Francesco Ungaro: &lt;a href="https://www.pexels.com/photo/blue-sky-281260/" rel="noopener noreferrer"&gt;https://www.pexels.com/photo/blue-sky-281260/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
    </item>
    <item>
      <title>Eligify v1.4.0: We Made Your Rules Organized (And Auditable)</title>
      <dc:creator>Nasrul Hazim Bin Mohamad</dc:creator>
      <pubDate>Fri, 07 Nov 2025 17:17:30 +0000</pubDate>
      <link>https://dev.to/nasrulhazim/eligify-v140-we-made-your-rules-organized-and-auditable-372a</link>
      <guid>https://dev.to/nasrulhazim/eligify-v140-we-made-your-rules-organized-and-auditable-372a</guid>
      <description>&lt;p&gt;You know that moment when you're building eligibility rules and realize you've got 15 different checks all mixed together? Identity stuff, financial stuff, contact verification... it's a mess.&lt;/p&gt;

&lt;p&gt;We felt that pain too. So we built two features to fix it.&lt;/p&gt;




&lt;h2&gt;
  
  
  Rule Groups: Stop the Rule Chaos
&lt;/h2&gt;

&lt;p&gt;Here's the thing about eligibility decisions—they're rarely "check everything the same way."&lt;/p&gt;

&lt;p&gt;A loan approval needs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Identity checks&lt;/strong&gt;: All must pass (you can't approve someone without proper ID)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Financial checks&lt;/strong&gt;: All must pass (they need sufficient income and good credit)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Contact verification&lt;/strong&gt;: At least 2 out of 3 methods need to work (we just need to reach them somehow)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before v1.4.0, you'd list all 15 rules in one giant pile. Good luck explaining to someone why their loan got rejected when 8 different checks got mixed together.&lt;/p&gt;

&lt;p&gt;With Rule Groups, you organize related rules into logical buckets with clear logic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Identity group? &lt;strong&gt;All must pass&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Financial group? &lt;strong&gt;All must pass&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Verification group? &lt;strong&gt;At least 2 must pass&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9s49h6xrm6x77b8c69v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy9s49h6xrm6x77b8c69v.png" alt="Rule Groups" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That's it. Your code now reads like your actual business logic. When someone asks "why was this rejected?" you can point to the group that failed instead of wading through spaghetti.&lt;/p&gt;

&lt;p&gt;Plus, you can weight groups differently. Maybe identity is critical, financial is important, but nice-to-haves are just bonus points.&lt;/p&gt;




&lt;h2&gt;
  
  
  Rule Versioning: Never Lose Track Again
&lt;/h2&gt;

&lt;p&gt;Here's another common headache: "Did we change the credit score requirement last month?"&lt;/p&gt;

&lt;p&gt;Rule Versioning solves this by creating snapshots of your rules at key moments. Think of it like Git for your eligibility rules.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fe7sgparwoe0okjcbz3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1fe7sgparwoe0okjcbz3.png" alt="Rule Versioning" width="800" height="376"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;When you update your rules, you create a version: &lt;em&gt;"Q4 2025 - Stricter credit requirements"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Now you can:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Look back&lt;/strong&gt;: "What rules were we using in October?"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Prove it&lt;/strong&gt;: Auditors ask if a decision was fair? Show them exactly which rules were applied.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Test it&lt;/strong&gt;: Want to see how people would have qualified under the old rules? Evaluate against version 2 instead of the current version.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Compare changes&lt;/strong&gt;: See exactly what rules were added, removed, or modified between versions.&lt;/p&gt;

&lt;p&gt;This is huge for regulated industries—loan companies, insurance, benefits programs. You're not just making decisions, you're making &lt;em&gt;defensible&lt;/em&gt; decisions.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Means For You
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;If you build eligibility systems:&lt;/strong&gt;&lt;br&gt;
Your code gets cleaner, your decisions get clearer, your audits get easier.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you work with compliance:&lt;/strong&gt;&lt;br&gt;
You now have a built-in audit trail. Who changed what? When? What were the rules at decision time? It's all tracked.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you're managing stakeholders:&lt;/strong&gt;&lt;br&gt;
Rule Groups make it easy to explain your logic. No more "well, we check 15 things"—you can say "we verify identity, check finances, and confirm contact" and people understand immediately.&lt;/p&gt;




&lt;h2&gt;
  
  
  Real Talk: A Day in the Life
&lt;/h2&gt;

&lt;p&gt;Let's say you're building a scholarship program.&lt;/p&gt;

&lt;p&gt;You need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Academic performance (GPA + test scores)&lt;/li&gt;
&lt;li&gt;Financial need&lt;/li&gt;
&lt;li&gt;Citizenship requirements&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of one rule list, you set it up like:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Academic group&lt;/strong&gt; (must pass) → GPA above 3.5 AND test score above 1400&lt;br&gt;
&lt;strong&gt;Financial group&lt;/strong&gt; (weighted importance) → Family income below $150k&lt;br&gt;
&lt;strong&gt;Citizenship group&lt;/strong&gt; (must pass) → Must be citizen or permanent resident&lt;/p&gt;

&lt;p&gt;Three groups. Clear intent. Easy to test. Easy to explain. Easy to audit.&lt;/p&gt;

&lt;p&gt;Then next year when requirements tighten? Create a new version. Your 2025 rules stay on record.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bottom Line
&lt;/h2&gt;

&lt;p&gt;v1.4.0 gives you two superpowers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Organization&lt;/strong&gt;: Rules that make sense to humans, not just computers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auditability&lt;/strong&gt;: A complete history of how decisions were made&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Both feel like they should have been there from day one. We're glad they're here now.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try It Out
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer update cleaniquecoders/eligify
php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. Your existing code still works. Rule Groups are there when you're ready to use them.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Questions?&lt;/strong&gt; Check the &lt;a href="https://github.com/cleaniquecoders/eligify" rel="noopener noreferrer"&gt;full documentation&lt;/a&gt; or &lt;a href="https://github.com/cleaniquecoders/eligify/tree/main/docs/07-advanced-features" rel="noopener noreferrer"&gt;read the detailed guides&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Eligify v1.4.0 – Define criteria. Enforce rules. Decide eligibility.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>eligify</category>
    </item>
    <item>
      <title>Eligify — The Criteria and Rule Engine for Explainable Decisions</title>
      <dc:creator>Nasrul Hazim Bin Mohamad</dc:creator>
      <pubDate>Tue, 28 Oct 2025 02:12:01 +0000</pubDate>
      <link>https://dev.to/nasrulhazim/eligify-the-criteria-and-rule-engine-for-explainable-decisions-3jbe</link>
      <guid>https://dev.to/nasrulhazim/eligify-the-criteria-and-rule-engine-for-explainable-decisions-3jbe</guid>
      <description>&lt;p&gt;Business eligibility logic has a habit of hiding in plain sight.&lt;/p&gt;

&lt;p&gt;It starts with a few &lt;code&gt;if&lt;/code&gt; statements in a controller, a couple more in a form request — and before long, the logic has spread across jobs, listeners, and policies.&lt;/p&gt;

&lt;p&gt;And then the inevitable happens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Different parts of the system &lt;strong&gt;disagree&lt;/strong&gt; on what “eligible” means.&lt;/li&gt;
&lt;li&gt;Making changes becomes &lt;strong&gt;risky&lt;/strong&gt; because rules are scattered.&lt;/li&gt;
&lt;li&gt;When someone asks, “&lt;strong&gt;Why was this rejected?&lt;/strong&gt;” there’s no single, auditable answer.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Eligibility determines who qualifies — for a loan, a scholarship, a feature upgrade, or access to a service.&lt;br&gt;
It’s too important to be buried inside conditional statements.&lt;/p&gt;

&lt;p&gt;That’s where &lt;strong&gt;Eligify&lt;/strong&gt; comes in.&lt;/p&gt;


&lt;h2&gt;
  
  
  Introducing Eligify — A Criteria and Rule Engine for Explainable Decisions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Eligify&lt;/strong&gt; turns eligibility from hidden code into a &lt;strong&gt;first-class decision engine&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It gives you a &lt;strong&gt;declarative&lt;/strong&gt;, &lt;strong&gt;data-driven&lt;/strong&gt;, and &lt;strong&gt;auditable&lt;/strong&gt; way to define and evaluate business rules — making decisions predictable and explainable.&lt;/p&gt;

&lt;p&gt;Instead of scattering logic across your application, you define &lt;strong&gt;criteria&lt;/strong&gt; (the decision context) and &lt;strong&gt;rules&lt;/strong&gt; (the conditions). Each evaluation produces a clear outcome — with the “why” built in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$criteria&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Eligify&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;criteria&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'loan_approval'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'income'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&amp;gt;='&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'credit_score'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&amp;gt;='&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;650&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;passThreshold&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;75&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

&lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Eligify&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'loan_approval'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="s1"&gt;'income'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'credit_score'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;720&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example result&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="s1"&gt;'passed'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'score'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;90&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'failed_rules'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt;
  &lt;span class="s1"&gt;'decision'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Approved'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Whether you run it in a controller, background job, or policy — Eligify ensures every decision follows the same consistent logic.&lt;/p&gt;




&lt;h2&gt;
  
  
  How Eligify Works — The Core Architecture
&lt;/h2&gt;

&lt;p&gt;Eligify separates &lt;strong&gt;definition&lt;/strong&gt;, &lt;strong&gt;data extraction&lt;/strong&gt;, &lt;strong&gt;evaluation&lt;/strong&gt;, and &lt;strong&gt;audit&lt;/strong&gt; — so every layer is clear, testable, and reusable.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;🧠 &lt;strong&gt;Criteria &amp;amp; Rules&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Define logical conditions with a fluent DSL. Supports AND/OR/XOR/MAJORITY groups, weights, and thresholds.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;🔍 &lt;strong&gt;Model Data Extractor&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Normalises attributes and relationships into a flat structure. Keeps business logic &lt;strong&gt;decoupled from model internals&lt;/strong&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;⚙️ &lt;strong&gt;Evaluator Engine&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Runs rules, computes scores, and triggers callbacks (&lt;code&gt;onPass&lt;/code&gt;, &lt;code&gt;onFail&lt;/code&gt;, &lt;code&gt;onExcellent&lt;/code&gt;).&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;📜 &lt;strong&gt;Audit Trail&lt;/strong&gt;
&lt;/td&gt;
&lt;td&gt;Stores every evaluation: what ran, what passed, what failed, and why — critical for transparency and compliance.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h3&gt;
  
  
  Architecture Flow (Text Diagram)
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13cbz78o4zufe1f1nwd1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F13cbz78o4zufe1f1nwd1.png" alt="Eligify Sequence Diagram" width="800" height="730"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can see more details architecture design from &lt;a href="https://github.com/cleaniquecoders/eligify/blob/main/docs/model-data-extractor-architecture.md" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  Practical Usage — From Definition to Decision
&lt;/h2&gt;

&lt;p&gt;Eligify makes complex logic readable and repeatable. Here’s how it fits naturally into any application flow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 1: Define Your Criteria
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nc"&gt;Eligify&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;criteria&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'membership_upgrade'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'account_age_days'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&amp;gt;='&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'total_purchases'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&amp;gt;='&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;addRule&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'support_tickets'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;='&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nf"&gt;save&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Extract Model Data
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;ModelDataExtractor&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;forModel&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;User&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="n"&gt;class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nb"&gt;extract&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$user&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Evaluate and Act
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="nv"&gt;$result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Eligify&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;evaluate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'membership_upgrade'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$data&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'passed'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Upgrade membership&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nc"&gt;Log&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nf"&gt;info&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'User not eligible'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'failed_rules'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each evaluation is &lt;strong&gt;audited&lt;/strong&gt;, giving you a full history of what happened, when, and why — no more guesswork.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Eligify Matters
&lt;/h2&gt;

&lt;p&gt;Eligify isn’t just a rules engine — it’s a mindset shift.&lt;/p&gt;

&lt;p&gt;Instead of burying decisions inside conditionals, it makes them &lt;strong&gt;transparent, explainable, and reusable&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;✅ &lt;strong&gt;Centralised&lt;/strong&gt; rule definitions — one source of truth&lt;br&gt;
✅ &lt;strong&gt;Consistent&lt;/strong&gt; outcomes across systems&lt;br&gt;
✅ &lt;strong&gt;Auditable&lt;/strong&gt; results for compliance and debugging&lt;br&gt;
✅ &lt;strong&gt;Extensible&lt;/strong&gt; design for any domain — finance, education, HR, SaaS, government&lt;/p&gt;

&lt;p&gt;When decisions impact real people, &lt;strong&gt;clarity and fairness matter&lt;/strong&gt;.&lt;br&gt;
Eligify helps you build both into your software.&lt;/p&gt;




&lt;h3&gt;
  
  
  🌟 Get Started
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;composer require cleaniquecoders/eligify
php artisan vendor:publish &lt;span class="nt"&gt;--tag&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"eligify-config"&lt;/span&gt;
php artisan migrate
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;🔗 &lt;a href="https://github.com/cleaniquecoders/eligify" rel="noopener noreferrer"&gt;View on GitHub → cleaniquecoders/eligify&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Stop scattering your eligibility logic. Centralise it. Audit it. Trust it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Eligify&lt;/strong&gt; — make decisions explainable.&lt;/p&gt;

</description>
      <category>laravel</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
