<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Sabahattin Kalkan</title>
    <description>The latest articles on Forem by Sabahattin Kalkan (@sabahattink).</description>
    <link>https://forem.com/sabahattink</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%2F3826551%2F6103b15a-e64a-4726-a44c-39f049f899a5.jpeg</url>
      <title>Forem: Sabahattin Kalkan</title>
      <link>https://forem.com/sabahattink</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/sabahattink"/>
    <language>en</language>
    <item>
      <title>I built a permission-first CLAUDE.md + agent stack for Claude Code (free, MIT)</title>
      <dc:creator>Sabahattin Kalkan</dc:creator>
      <pubDate>Thu, 14 May 2026 21:01:45 +0000</pubDate>
      <link>https://forem.com/sabahattink/i-built-a-permission-first-claudemd-agent-stack-for-claude-code-free-mit-4ep6</link>
      <guid>https://forem.com/sabahattink/i-built-a-permission-first-claudemd-agent-stack-for-claude-code-free-mit-4ep6</guid>
      <description>&lt;p&gt;I've been using Claude Code daily for months. And I kept hitting the same wall:&lt;/p&gt;

&lt;p&gt;The agent would just &lt;strong&gt;start doing things&lt;/strong&gt;. No plan. No approval. Just... acting.&lt;/p&gt;

&lt;p&gt;It deleted files I didn't want deleted. It refactored things I didn't ask it to refactor. It made "helpful" assumptions that broke my architecture.&lt;/p&gt;

&lt;p&gt;So I built &lt;strong&gt;Full Stack HQ&lt;/strong&gt; — a configuration kit that enforces a permission-first workflow. Here's what I learned.&lt;/p&gt;




&lt;h2&gt;
  
  
  The core problem with AI coding agents
&lt;/h2&gt;

&lt;p&gt;Most people configure their AI agent once (or never) and just... let it go. The result is an agent that:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Makes assumptions about what you want&lt;/li&gt;
&lt;li&gt;Takes irreversible actions without asking&lt;/li&gt;
&lt;li&gt;Mixes planning and execution in the same step&lt;/li&gt;
&lt;li&gt;Has no consistent code style or architectural awareness&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The agent is powerful but unpredictable. That's the worst combination in software development.&lt;/p&gt;




&lt;h2&gt;
  
  
  The solution: permission-first workflow
&lt;/h2&gt;

&lt;p&gt;Nothing happens without your explicit approval. The agent plans, shows you what it intends to do, and &lt;strong&gt;waits&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;You:    "Add user authentication with JWT"

Agent:  Here's my plan:
        Phase 1: Create auth module + JWT strategy
        Phase 2: Add guards to protected routes  
        Phase 3: Implement refresh token rotation

        [APPROVAL NEEDED] Should I proceed with Phase 1?

You:    PLAN APPROVED

Agent:  [implements Phase 1 only, then stops and reports]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The only valid approval keywords:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PLAN APPROVED
IMPLEMENTATION APPROVED
PROCEED
DO IT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Anything else — the agent waits. No exceptions.&lt;/p&gt;




&lt;h2&gt;
  
  
  What's inside Full Stack HQ
&lt;/h2&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;Count&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;CLAUDE.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Global rules for Claude Code&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GEMINI.md&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;td&gt;Global rules for Google Antigravity IDE&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Agents&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Specialist AI personas&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Skills&lt;/td&gt;
&lt;td&gt;28&lt;/td&gt;
&lt;td&gt;Domain-specific knowledge modules&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Workflows&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;td&gt;Slash command procedures&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  10 Specialist Agents
&lt;/h3&gt;

&lt;p&gt;Instead of one generic agent trying to do everything, you get domain experts:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Agent&lt;/th&gt;
&lt;th&gt;What it handles&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;frontend-specialist&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;React, Next.js, Tailwind&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;backend-specialist&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;NestJS, Node.js, APIs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;database-specialist&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Prisma, PostgreSQL, migrations&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;architect&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;System design, trade-offs, ADRs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;code-reviewer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Quality, patterns, best practices&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;test-engineer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Vitest, Jest, Playwright&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;security-auditor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Auth, OWASP, input validation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;performance-optimizer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Bundle, queries, rendering&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;devops-engineer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Docker, CI/CD&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;documentation-writer&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;READMEs, technical writing&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Calling them 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;Use the database-specialist to design a user schema with soft deletes.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  28 Skills
&lt;/h3&gt;

&lt;p&gt;Deep knowledge modules for the tools you actually use:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend&lt;/strong&gt;: &lt;code&gt;nextjs-app-router&lt;/code&gt;, &lt;code&gt;react-best-practices&lt;/code&gt;, &lt;code&gt;ui-ux-pro-max&lt;/code&gt;, &lt;code&gt;frontend-design&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend&lt;/strong&gt;: &lt;code&gt;nestjs-patterns&lt;/code&gt;, &lt;code&gt;prisma-workflow&lt;/code&gt;, &lt;code&gt;software-architecture&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Testing&lt;/strong&gt;: &lt;code&gt;test-driven-development&lt;/code&gt;, &lt;code&gt;systematic-debugging&lt;/code&gt;, &lt;code&gt;webapp-testing&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Meta&lt;/strong&gt;: &lt;code&gt;brainstorming&lt;/code&gt;, &lt;code&gt;prompt-engineering&lt;/code&gt;, &lt;code&gt;skill-creator&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  10 Workflows (Slash Commands)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/plan       → phased breakdown with approval checkpoints
/brainstorm → explore architecture options
/debug      → systematic root-cause analysis
/create     → implement an approved plan
/enhance    → improve existing code quality
/test       → generate or fix tests
/orchestrate → coordinate multiple agents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Install in 30 seconds
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Mac/Linux:&lt;/strong&gt;&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/sabahattink/antigravity-fullstack-hq/main/install.sh | bash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Windows (PowerShell):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight powershell"&gt;&lt;code&gt;&lt;span class="n"&gt;irm&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;https://raw.githubusercontent.com/sabahattink/antigravity-fullstack-hq/main/install.ps1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;iex&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Options:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./install.sh &lt;span class="nt"&gt;--only-claude&lt;/span&gt;        &lt;span class="c"&gt;# Claude Code only&lt;/span&gt;
./install.sh &lt;span class="nt"&gt;--only-antigravity&lt;/span&gt;   &lt;span class="c"&gt;# Antigravity only&lt;/span&gt;
./install.sh &lt;span class="nt"&gt;--force&lt;/span&gt;              &lt;span class="c"&gt;# Overwrite existing configs&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script detects which IDEs you have installed and configures them automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  What gets installed where
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.claude/
├── CLAUDE.md          ← global rules (Claude Code)
├── agents/            ← 10 specialist agents
└── skills/            ← 28 skill modules

~/.gemini/
├── GEMINI.md          ← global rules (Antigravity)
└── antigravity/
    ├── agents/
    ├── skills/
    └── workflows/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The CLAUDE.md philosophy
&lt;/h2&gt;

&lt;p&gt;The rules file enforces several things I found critical in practice:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Separation of planning and execution&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The agent never does both in the same step. First it plans, you approve, then it executes. This alone eliminates 80% of unwanted surprises.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Role-based reasoning&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before acting, the agent asks: "Who is the right specialist for this?" A database schema question goes to the database specialist, not the frontend agent pretending to know Prisma.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Explicit code style&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;No semicolons. Single quotes. 2-space indentation. Arrow functions. Named exports. These aren't suggestions — they're enforced rules the agent follows on every file, every time.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Security checklist&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Before every commit: no hardcoded secrets, all inputs validated, no unbounded queries, rate limiting on public endpoints. The agent checks these automatically.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why it works
&lt;/h2&gt;

&lt;p&gt;The mental model I was missing: &lt;strong&gt;AI agents should behave like senior engineers, not interns with root access.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Senior engineers don't start typing when you describe a problem. They think, propose a plan, get sign-off, then execute — one reversible step at a time.&lt;/p&gt;

&lt;p&gt;Full Stack HQ enforces this discipline by default.&lt;/p&gt;




&lt;h2&gt;
  
  
  Repo
&lt;/h2&gt;

&lt;p&gt;⭐ &lt;a href="https://github.com/sabahattink/antigravity-fullstack-hq" rel="noopener noreferrer"&gt;github.com/sabahattink/antigravity-fullstack-hq&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;MIT license. Open to PRs — especially new agents and skills.&lt;/p&gt;

&lt;p&gt;What does your current CLAUDE.md look like? I'd love to see what rules others have found valuable.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>claudecode</category>
      <category>devtools</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Building MailTest: An Open Source Email Deliverability Debugger</title>
      <dc:creator>Sabahattin Kalkan</dc:creator>
      <pubDate>Mon, 13 Apr 2026 03:53:52 +0000</pubDate>
      <link>https://forem.com/sabahattink/building-mailtest-an-open-source-email-deliverability-debugger-17hn</link>
      <guid>https://forem.com/sabahattink/building-mailtest-an-open-source-email-deliverability-debugger-17hn</guid>
      <description>&lt;h1&gt;
  
  
  Building MailTest: An Open Source Email Deliverability Debugger
&lt;/h1&gt;

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

&lt;p&gt;[Story about client's 50K emails going to spam]&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Existing Tools Fall Short
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Expensive ($100+/month)&lt;/li&gt;
&lt;li&gt;No explanations&lt;/li&gt;
&lt;li&gt;SaaS lock-in&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;[Demo GIF/screenshots]&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Backend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;NestJS + Fastify (why not Express)&lt;/li&gt;
&lt;li&gt;BullMQ for async jobs&lt;/li&gt;
&lt;li&gt;RS256 JWT (why not HS256)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Frontend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Next.js 15 App Router&lt;/li&gt;
&lt;li&gt;Radix UI primitives&lt;/li&gt;
&lt;li&gt;Real-time updates with SSE&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Infrastructure
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Docker Compose&lt;/li&gt;
&lt;li&gt;PostgreSQL 16&lt;/li&gt;
&lt;li&gt;Redis 7&lt;/li&gt;
&lt;li&gt;Paddle billing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Interesting Challenges
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;IMAP Polling:&lt;/strong&gt; How to catch emails reliably&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Scoring Algorithm:&lt;/strong&gt; Weighted checks (SPF 15%, DKIM 20%, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PDF Generation:&lt;/strong&gt; Server-side with Puppeteer&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Code Snippets
&lt;/h2&gt;

&lt;p&gt;[Show interesting parts]&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;More integrations&lt;/li&gt;
&lt;li&gt;Auto-fix features&lt;/li&gt;
&lt;li&gt;API monetization&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;a href="https://mailtest.scuton.com" rel="noopener noreferrer"&gt;https://mailtest.scuton.com&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Discussion
&lt;/h2&gt;

&lt;p&gt;What features would you want in a deliverability tool?&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>saas</category>
      <category>node</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>I built a CLI that diagnoses your code before you ship</title>
      <dc:creator>Sabahattin Kalkan</dc:creator>
      <pubDate>Sat, 28 Mar 2026 10:45:57 +0000</pubDate>
      <link>https://forem.com/sabahattink/title-i-built-a-cli-that-diagnoses-your-code-before-you-ship-tags-nestjs-typescript-opensource-2208</link>
      <guid>https://forem.com/sabahattink/title-i-built-a-cli-that-diagnoses-your-code-before-you-ship-tags-nestjs-typescript-opensource-2208</guid>
      <description>&lt;p&gt;I built a CLI that diagnoses your code before you ship&lt;br&gt;
Every NestJS project I've worked on had the same problems:&lt;/p&gt;

&lt;p&gt;POST endpoints without auth guards&lt;br&gt;
Hardcoded API keys in source code&lt;br&gt;
.env not in .gitignore&lt;br&gt;
Zero tests&lt;br&gt;
No Swagger documentation&lt;/p&gt;

&lt;p&gt;I was tired of catching these manually in code reviews. So I built codediag.&lt;br&gt;
What it does&lt;br&gt;
bashnpx codediag scan .&lt;br&gt;
One command. It auto-detects your stack and runs 5 analyzers:&lt;br&gt;
  codediag — Diagnostic Report&lt;/p&gt;

&lt;p&gt;Project:  my-nestjs-app&lt;br&gt;
  Stack:    nestjs + typescript + prisma&lt;br&gt;
  Score:    B+ (87/100)&lt;/p&gt;

&lt;p&gt;API Health        ███████████████░░░░░  78&lt;br&gt;
  Security          ██████████████████░░  92&lt;br&gt;
  Dependencies      ██████████████████░░  91&lt;br&gt;
  Testing           ████████████████░░░░  82&lt;br&gt;
  Structure         █████████████████░░░  88&lt;br&gt;
The 5 Analyzers&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;API Health (NestJS)
This is the differentiator. codediag uses ts-morph to do real AST analysis of your NestJS decorators — not regex pattern matching.
It discovers every endpoint from &lt;a class="mentioned-user" href="https://dev.to/get"&gt;@get&lt;/a&gt;(), &lt;a class="mentioned-user" href="https://dev.to/post"&gt;@post&lt;/a&gt;(), @Put(), @Delete(), @Patch() decorators and checks:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Auth guards: Does this endpoint have @UseGuards()? Especially important for mutating endpoints.&lt;br&gt;
DTO validation: Is the &lt;a class="mentioned-user" href="https://dev.to/body"&gt;@body&lt;/a&gt;() parameter typed with a DTO class?&lt;br&gt;
Swagger docs: Are @ApiOperation() and @ApiResponse() present?&lt;br&gt;
Return types: Is there an explicit return type annotation?&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Security
The stuff that ends up on HackerNews for the wrong reasons:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Hardcoded secrets (API keys, Stripe keys, AWS keys, GitHub tokens)&lt;br&gt;
.env in .gitignore&lt;br&gt;
Helmet middleware for HTTP security headers&lt;br&gt;
CORS wildcard (origin: '*') detection&lt;br&gt;
Rate limiting package installed&lt;br&gt;
Password hashing library present&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Dependencies
Your node_modules is a supply chain. codediag treats it like one:&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;npm audit vulnerabilities&lt;br&gt;
Lock file existence&lt;br&gt;
Deprecated packages&lt;br&gt;
Engine specification&lt;br&gt;
Essential scripts&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Testing&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Test file existence and count&lt;br&gt;
Framework detection (Jest, Vitest, Mocha, Ava)&lt;br&gt;
Test-to-source file ratio&lt;br&gt;
E2E test directory&lt;br&gt;
Coverage threshold configuration&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Structure&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;README quality&lt;br&gt;
Linter configuration (ESLint or Biome)&lt;br&gt;
Formatter configuration (Prettier)&lt;br&gt;
TypeScript strict mode&lt;br&gt;
NestJS module organization&lt;br&gt;
.env.example presence&lt;/p&gt;

&lt;p&gt;Scoring&lt;br&gt;
Each analyzer scores 0-100. The total is a weighted average:&lt;br&gt;
AnalyzerWeightAPI Health25%Security30%Dependencies20%Testing15%Structure10%&lt;br&gt;
Security gets the highest weight because shipping vulnerable code is the worst bug.&lt;br&gt;
CI/CD&lt;br&gt;
One line in your GitHub Actions:&lt;br&gt;
yaml- run: npx codediag scan . --ci --threshold 80&lt;br&gt;
Exits with code 1 if the score drops below your threshold.&lt;br&gt;
What's next&lt;/p&gt;

&lt;p&gt;Next.js analyzer&lt;br&gt;
Express route analyzer&lt;br&gt;
Web dashboard with trend tracking&lt;br&gt;
AI-powered fix suggestions&lt;br&gt;
VS Code extension&lt;/p&gt;

&lt;p&gt;Try it&lt;br&gt;
bashnpx codediag scan .&lt;br&gt;
Zero config. MIT licensed. 33KB bundled.&lt;/p&gt;

&lt;p&gt;GitHub: &lt;a href="https://github.com/scuton-technology/codediag" rel="noopener noreferrer"&gt;https://github.com/scuton-technology/codediag&lt;/a&gt;&lt;br&gt;
npm: &lt;a href="https://www.npmjs.com/package/codediag" rel="noopener noreferrer"&gt;https://www.npmjs.com/package/codediag&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'd love to hear what checks you'd want added. Drop a comment or open an issue!&lt;/p&gt;

</description>
      <category>nestjs</category>
      <category>typescript</category>
      <category>opensource</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Stop switching to GitHub.com for standup — I built a CLI for that</title>
      <dc:creator>Sabahattin Kalkan</dc:creator>
      <pubDate>Tue, 17 Mar 2026 09:30:29 +0000</pubDate>
      <link>https://forem.com/sabahattink/stop-switching-to-githubcom-for-standup-i-built-a-cli-for-that-3llk</link>
      <guid>https://forem.com/sabahattink/stop-switching-to-githubcom-for-standup-i-built-a-cli-for-that-3llk</guid>
      <description>&lt;p&gt;Every morning it's the same routine.&lt;/p&gt;

&lt;p&gt;Open GitHub. Filter by author. Scroll through commits. Switch repos. Try&lt;br&gt;
to remember what you did yesterday. Piece together a standup from five&lt;br&gt;
different tabs.&lt;/p&gt;

&lt;p&gt;Or worse — you're juggling three different repos, two orgs, and a&lt;br&gt;
contractor's fork, and the GitHub web UI has no idea you want to see all&lt;br&gt;
of it at once.&lt;/p&gt;

&lt;p&gt;I built &lt;strong&gt;gpulse&lt;/strong&gt; to fix this.&lt;/p&gt;
&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;gpulse is a CLI toolkit that brings the GitHub insights you actually need&lt;br&gt;
into your terminal. Six focused commands, zero browser required.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @sabahattinkalkan/gpulse
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ghp_your_token_here
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;gpulse standup&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;What did you actually do since yesterday?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpulse standup           &lt;span class="c"&gt;# last 24 hours, all repos&lt;/span&gt;
gpulse standup &lt;span class="nt"&gt;-d&lt;/span&gt; 3      &lt;span class="c"&gt;# last 3 days&lt;/span&gt;
gpulse standup &lt;span class="nt"&gt;-u&lt;/span&gt; alice  &lt;span class="c"&gt;# another user's activity&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
Standup for &lt;a class="mentioned-user" href="https://dev.to/sabahattinkalkan"&gt;@sabahattinkalkan&lt;/a&gt;&lt;br&gt;
Since Mar 15, 2026 12:00 AM&lt;br&gt;
Commits&lt;br&gt;
a1b2c3d feat: add user authentication (org/app)&lt;br&gt;
d4e5f6a fix: resolve memory leak in worker (org/api)&lt;br&gt;
Pull Requests&lt;/p&gt;
&lt;h1&gt;
  
  
  42 Add OAuth2 support (org/app)
&lt;/h1&gt;

&lt;p&gt;Reviews&lt;/p&gt;
&lt;h1&gt;
  
  
  41 Refactor database layer (org/api)
&lt;/h1&gt;

&lt;p&gt;──────────────────────────────────────────&lt;br&gt;
Summary: 2 commits, 2 PRs, 1 review&lt;/p&gt;

&lt;p&gt;This is what I actually read out at standup. Copy, paste, done.&lt;/p&gt;
&lt;h2&gt;
  
  
  &lt;code&gt;gpulse health&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Repo health score (A–F). Checks README, LICENSE, CI, stale issues.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpulse health vercel/next.js
&lt;span class="c"&gt;# Score: 90/100 (A)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;gpulse review&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;PR dashboard — review requests, assigned PRs, your open PRs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpulse review
&lt;span class="c"&gt;# Review Requested (2)&lt;/span&gt;
&lt;span class="c"&gt;#   #87 Add rate limiting middleware (org/api)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;gpulse changelog&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Auto-generate changelog from git tags using Conventional Commits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpulse changelog &lt;span class="nt"&gt;-o&lt;/span&gt; CHANGELOG.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;gpulse digest&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Weekly repo digest — commits, issues, merged PRs, contributors.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gpulse digest &lt;span class="nt"&gt;-d&lt;/span&gt; 7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why terminal?
&lt;/h2&gt;

&lt;p&gt;Context switching kills flow. gpulse keeps you in the terminal where&lt;br&gt;
you're already working. Also useful in SSH sessions and CI scripts.&lt;/p&gt;

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



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @sabahattinkalkan/gpulse
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;GITHUB_TOKEN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ghp_...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No config files. No YAML. Just the token and go.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/scuton-technology/ghx" rel="noopener noreferrer"&gt;https://github.com/scuton-technology/ghx&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm&lt;/strong&gt;: &lt;code&gt;npm install -g @sabahattinkalkan/gpulse&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MIT licensed. What would you add to a GitHub CLI toolkit? Drop it in the comments.&lt;/p&gt;

</description>
      <category>github</category>
      <category>cli</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>I built a self-hosted LLM proxy that supports 12 providers (Claude, GPT-4o, Gemini, Ollama...)</title>
      <dc:creator>Sabahattin Kalkan</dc:creator>
      <pubDate>Mon, 16 Mar 2026 10:18:50 +0000</pubDate>
      <link>https://forem.com/sabahattink/i-built-a-self-hosted-llm-proxy-that-supports-12-providers-claude-gpt-4o-gemini-ollama-3ej1</link>
      <guid>https://forem.com/sabahattink/i-built-a-self-hosted-llm-proxy-that-supports-12-providers-claude-gpt-4o-gemini-ollama-3ej1</guid>
      <description>&lt;p&gt;Every time a new LLM comes out, someone on your team adds a new SDK,&lt;br&gt;
a new API key in .env, and a new set of error handling logic. Repeat&lt;br&gt;
for OpenAI, Anthropic, Gemini, Groq, Mistral, Ollama...&lt;/p&gt;

&lt;p&gt;I got tired of this. So I built &lt;strong&gt;llm-gateway&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;p&gt;llm-gateway is a single Go binary that sits between your app and every&lt;br&gt;
LLM provider. Your code sends one request format (OpenAI-compatible),&lt;br&gt;
and the gateway routes it to the right provider based on the model name.&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="c"&gt;# One endpoint for all providers&lt;/span&gt;
curl http://localhost:8080/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"model": "claude-sonnet-4-20250514", "messages": [{"role": "user", "content": "hello"}]}'&lt;/span&gt;

&lt;span class="c"&gt;# Switch provider by changing the model name — zero code changes&lt;/span&gt;
curl http://localhost:8080/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"model": "gpt-4o", "messages": [...]}'&lt;/span&gt;

&lt;span class="c"&gt;# Local model — no API key needed&lt;/span&gt;
curl http://localhost:8080/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"model": "llama3.2", "messages": [...]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Model routing is automatic:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;claude-*&lt;/code&gt; → Anthropic&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gpt-*&lt;/code&gt;, &lt;code&gt;o1&lt;/code&gt;, &lt;code&gt;o3&lt;/code&gt; → OpenAI
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gemini-*&lt;/code&gt; → Google&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;llama*&lt;/code&gt; → Ollama or Groq&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;mistral-*&lt;/code&gt; → Mistral&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;grok-*&lt;/code&gt; → xAI&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;sonar-*&lt;/code&gt; → Perplexity&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;command-*&lt;/code&gt; → Cohere&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Install in 30 seconds
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;docker run &lt;span class="nt"&gt;-p&lt;/span&gt; 8080:8080 &lt;span class="nt"&gt;-v&lt;/span&gt; gateway-data:/data scutontech/llm-gateway
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open &lt;code&gt;http://localhost:8080/admin&lt;/code&gt; → set your admin password → add API&lt;br&gt;
keys from the Settings page. No .env files, no YAML editing.&lt;/p&gt;
&lt;h2&gt;
  
  
  Admin dashboard
&lt;/h2&gt;

&lt;p&gt;The gateway ships with a full admin dashboard:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Real-time stats&lt;/strong&gt; — requests, tokens, latency, error rate, estimated cost&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Provider breakdown&lt;/strong&gt; — which providers you're actually using&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost analytics&lt;/strong&gt; — daily/monthly spend by model, with CSV export&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Request log&lt;/strong&gt; — last 50 requests with model, provider, tokens, cost, latency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dark mode&lt;/strong&gt; — because of course&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Streaming support
&lt;/h2&gt;

&lt;p&gt;SSE streaming works for all providers. The gateway normalizes&lt;br&gt;
Anthropic's stream format to OpenAI's SSE format transparently.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl http://localhost:8080/v1/chat/completions &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{"model": "claude-sonnet-4-20250514", "stream": true, "messages": [...]}'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Supported providers
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Provider&lt;/th&gt;
&lt;th&gt;Models&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic&lt;/td&gt;
&lt;td&gt;claude-opus-4, claude-sonnet-4, claude-haiku-4&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI&lt;/td&gt;
&lt;td&gt;gpt-4o, gpt-4o-mini, o1, o3-mini&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;gemini-2.0-flash, gemini-1.5-pro&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Groq&lt;/td&gt;
&lt;td&gt;llama-3.3-70b, mixtral-8x7b&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Mistral&lt;/td&gt;
&lt;td&gt;mistral-large, codestral&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Cohere&lt;/td&gt;
&lt;td&gt;command-r-plus, command-r&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;xAI&lt;/td&gt;
&lt;td&gt;grok-2, grok-2-mini&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Perplexity&lt;/td&gt;
&lt;td&gt;sonar-large, sonar-small&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Together AI&lt;/td&gt;
&lt;td&gt;50+ open source models&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ollama&lt;/td&gt;
&lt;td&gt;any local model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;LM Studio&lt;/td&gt;
&lt;td&gt;any local model&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;vLLM&lt;/td&gt;
&lt;td&gt;any hosted model&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Why Go?
&lt;/h2&gt;

&lt;p&gt;~15MB binary. Under 100ms cold start. ~20MB memory at idle.&lt;br&gt;
Drop it on a $5 VPS and forget about it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/scuton-technology/llm-gateway" rel="noopener noreferrer"&gt;https://github.com/scuton-technology/llm-gateway&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Docker&lt;/strong&gt;: &lt;code&gt;docker pull scutontech/llm-gateway&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MIT licensed. PRs welcome.&lt;/p&gt;

</description>
      <category>llm</category>
      <category>ai</category>
      <category>opensource</category>
      <category>go</category>
    </item>
    <item>
      <title>Stop writing bad commit messages — I built a free AI CLI for that</title>
      <dc:creator>Sabahattin Kalkan</dc:creator>
      <pubDate>Mon, 16 Mar 2026 07:09:21 +0000</pubDate>
      <link>https://forem.com/sabahattink/stop-writing-bad-commit-messages-i-built-a-free-ai-cli-for-that-2g22</link>
      <guid>https://forem.com/sabahattink/stop-writing-bad-commit-messages-i-built-a-free-ai-cli-for-that-2g22</guid>
      <description>&lt;p&gt;We've all done 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 commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"fix"&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"wip"&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"asdfgh"&lt;/span&gt;
git commit &lt;span class="nt"&gt;-m&lt;/span&gt; &lt;span class="s2"&gt;"changes"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You're deep in flow, you just want to save progress, and writing a meaningful commit message feels like a speed bump. So you write something meaningless and move on.&lt;/p&gt;

&lt;p&gt;The problem? Three months later, you (or your teammate) is trying to understand &lt;em&gt;why&lt;/em&gt; a change was made. The git log is full of "fix" and "update" and tells you nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The solution: let AI read the diff
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;ai-commit&lt;/strong&gt; — a CLI that reads your staged &lt;code&gt;git diff&lt;/code&gt; and generates 3 &lt;a href="https://www.conventionalcommits.org/" rel="noopener noreferrer"&gt;Conventional Commit&lt;/a&gt; suggestions for you to pick from.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @scuton/ai-commit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then just:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;git add &lt;span class="nb"&gt;.&lt;/span&gt;
aic
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get something like:&lt;br&gt;
? Pick a commit message:&lt;br&gt;
❯ feat(auth): add JWT refresh token rotation&lt;br&gt;
feat(auth): implement rotating refresh token with replay protection&lt;br&gt;
chore(auth): update token lifecycle and Redis TTL strategy&lt;br&gt;
✎ Write my own&lt;br&gt;
✗ Cancel&lt;/p&gt;

&lt;p&gt;Pick one, hit enter, done. The whole thing takes 3 seconds.&lt;/p&gt;
&lt;h2&gt;
  
  
  Free option: Ollama (no API key needed)
&lt;/h2&gt;

&lt;p&gt;This is the part I'm most excited about. You can run it completely free using &lt;a href="https://ollama.ai" rel="noopener noreferrer"&gt;Ollama&lt;/a&gt; — a local LLM runner.&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="c"&gt;# Install Ollama and pull a model&lt;/span&gt;
ollama pull llama3.2

&lt;span class="c"&gt;# Use ai-commit with Ollama&lt;/span&gt;
aic &lt;span class="nt"&gt;-p&lt;/span&gt; ollama
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;No API key. No cost per commit. Everything stays on your machine.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supports Claude and GPT-4o too
&lt;/h2&gt;

&lt;p&gt;If you prefer cloud models:&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="c"&gt;# Claude (best quality)&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;ANTHROPIC_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sk-ant-...
aic

&lt;span class="c"&gt;# GPT-4o&lt;/span&gt;
&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;OPENAI_API_KEY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;sk-...
aic &lt;span class="nt"&gt;-p&lt;/span&gt; openai
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cost is around $0.001 per commit with cloud models — basically free.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install as a git hook
&lt;/h2&gt;

&lt;p&gt;If you want it to run automatically on every &lt;code&gt;git commit&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aic hook
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remove it anytime:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aic hook &lt;span class="nt"&gt;--remove&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Other useful flags
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;aic &lt;span class="nt"&gt;--dry-run&lt;/span&gt;        &lt;span class="c"&gt;# Preview suggestions without committing&lt;/span&gt;
aic &lt;span class="nt"&gt;--count&lt;/span&gt; 5        &lt;span class="c"&gt;# Get 5 suggestions instead of 3&lt;/span&gt;
aic &lt;span class="nt"&gt;--lang&lt;/span&gt; &lt;span class="nb"&gt;tr&lt;/span&gt;        &lt;span class="c"&gt;# Generate in Turkish (or any language)&lt;/span&gt;
aic &lt;span class="nt"&gt;--emoji&lt;/span&gt;          &lt;span class="c"&gt;# Add emoji to commit type&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Programmatic API
&lt;/h2&gt;

&lt;p&gt;You can also use it in your own tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;generateCommitMessages&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@scuton/ai-commit&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;suggestions&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;generateCommitMessages&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;anthropic&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;count&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;suggestions&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="c1"&gt;// "feat(auth): add JWT refresh token rotation"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub&lt;/strong&gt;: &lt;a href="https://github.com/scuton-technology/ai-commit" rel="noopener noreferrer"&gt;https://github.com/scuton-technology/ai-commit&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm&lt;/strong&gt;: &lt;code&gt;npm install -g @scuton/ai-commit&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;MIT licensed, open source. PRs welcome — especially for new provider integrations.&lt;/p&gt;

&lt;p&gt;Happy committing.&lt;/p&gt;

</description>
      <category>git</category>
      <category>cli</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
  </channel>
</rss>
