<?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: Sabahattin Kalkan</title>
    <description>The latest articles on DEV Community by Sabahattin Kalkan (@sabahattink).</description>
    <link>https://dev.to/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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3826551%2F6103b15a-e64a-4726-a44c-39f049f899a5.jpeg</url>
      <title>DEV Community: Sabahattin Kalkan</title>
      <link>https://dev.to/sabahattink</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sabahattink"/>
    <language>en</language>
    <item>
      <title>Every Coding Agent Session Starts by Rediscovering Your Repository</title>
      <dc:creator>Sabahattin Kalkan</dc:creator>
      <pubDate>Tue, 11 Aug 2026 05:29:15 +0000</pubDate>
      <link>https://dev.to/sabahattink/every-coding-agent-session-starts-by-rediscovering-your-repository-2i9e</link>
      <guid>https://dev.to/sabahattink/every-coding-agent-session-starts-by-rediscovering-your-repository-2i9e</guid>
      <description>&lt;p&gt;I've been using coding agents heavily across real projects.&lt;br&gt;
Claude Code. Codex. Cursor.&lt;br&gt;
They are getting remarkably good at making changes.&lt;br&gt;
But I kept noticing the same thing at the beginning of new sessions.&lt;br&gt;
The agent starts exploring.&lt;br&gt;
It reads package.json.&lt;br&gt;
It looks for entry points.&lt;br&gt;
It walks through directories.&lt;br&gt;
It checks configuration.&lt;br&gt;
It tries to understand conventions.&lt;br&gt;
It finds the important files.&lt;br&gt;
Then the session ends.&lt;br&gt;
A new session starts later, and a surprising amount of that work happens again.&lt;br&gt;
That bothered me.&lt;br&gt;
Not because repository exploration is useless — an agent should inspect the source before making important changes.&lt;br&gt;
The problem is that there is a difference between:&lt;br&gt;
verifying the current source&lt;/p&gt;

&lt;p&gt;and:&lt;br&gt;
rediscovering the basic shape of the repository from zero.&lt;/p&gt;

&lt;p&gt;I wanted to see whether that second part could become persistent.&lt;br&gt;
So I built Recall.&lt;br&gt;
What Recall is&lt;br&gt;
Recall is a local CLI that derives structured context from a repository and stores it inside the repository itself.&lt;br&gt;
It isn't another coding agent.&lt;br&gt;
It doesn't call an LLM to understand your codebase.&lt;br&gt;
It doesn't require an AI API key.&lt;br&gt;
It doesn't require a cloud account.&lt;br&gt;
The basic idea is:&lt;br&gt;
repository&lt;br&gt;
    ↓&lt;br&gt;
deterministic scan&lt;br&gt;
    ↓&lt;br&gt;
.recall/&lt;br&gt;
    ↓&lt;br&gt;
persistent repository context&lt;br&gt;
    ↓&lt;br&gt;
Claude Code / Codex / Cursor / any Markdown-capable agent&lt;br&gt;
The generated context can describe things Recall can derive from the repository, including:&lt;br&gt;
architecture&lt;br&gt;
entry points&lt;br&gt;
project conventions&lt;br&gt;
relevant files&lt;br&gt;
risks&lt;br&gt;
workspace structure&lt;br&gt;
repository state&lt;br&gt;
The important word there is derive.&lt;br&gt;
I deliberately didn't want Recall inventing architectural explanations using another model.&lt;br&gt;
If Recall says something about the repository, I want that information to be traceable back to repository evidence.&lt;br&gt;
Why not just use CLAUDE.md or AGENTS.md?&lt;br&gt;
I use these files too.&lt;br&gt;
They solve a different problem.&lt;br&gt;
A file like CLAUDE.md or AGENTS.md is excellent for things such as:&lt;br&gt;
Use pnpm.&lt;/p&gt;

&lt;p&gt;Run this command before committing.&lt;/p&gt;

&lt;p&gt;Never modify generated migrations manually.&lt;/p&gt;

&lt;p&gt;Our API errors follow this convention.&lt;br&gt;
Those are instructions and human knowledge.&lt;br&gt;
But there is another category of context:&lt;br&gt;
Where are the entry points?&lt;/p&gt;

&lt;p&gt;How is this monorepo structured?&lt;/p&gt;

&lt;p&gt;Which workspace owns this functionality?&lt;/p&gt;

&lt;p&gt;Which files appear relevant to this task?&lt;/p&gt;

&lt;p&gt;Has the repository changed since this context was generated?&lt;br&gt;
Much of that can be derived from the repository.&lt;br&gt;
I don't want to manually maintain it if a tool can reconstruct it deterministically.&lt;br&gt;
So my mental model became:&lt;br&gt;
AGENTS.md / CLAUDE.md&lt;br&gt;
        ↓&lt;br&gt;
human intent + instructions&lt;/p&gt;

&lt;p&gt;Recall&lt;br&gt;
        ↓&lt;br&gt;
repository-derived context&lt;/p&gt;

&lt;p&gt;Source code + tests&lt;br&gt;
        ↓&lt;br&gt;
ultimate source of truth&lt;br&gt;
Recall isn't supposed to replace the source.&lt;br&gt;
It's supposed to provide a better map to the source.&lt;br&gt;
The first command&lt;br&gt;
Recall is published as an npm CLI.&lt;br&gt;
Node.js 22+ is currently required.&lt;br&gt;
npx recall-context@latest init&lt;br&gt;
That initializes Recall for the repository.&lt;br&gt;
You can inspect its state with:&lt;br&gt;
npx recall-context@latest status&lt;br&gt;
And generate task-focused context:&lt;br&gt;
npx recall-context@latest context \&lt;br&gt;
  --task "Understand the CLI release and packaging workflow" \&lt;br&gt;
  --max-tokens 1200 \&lt;br&gt;
  --stdout&lt;br&gt;
The result is Markdown, so there is no vendor-specific protocol required.&lt;br&gt;
You can give it to Claude Code.&lt;br&gt;
Or Codex.&lt;br&gt;
Or Cursor.&lt;br&gt;
Or another tool capable of consuming Markdown.&lt;br&gt;
That portability was intentional.&lt;br&gt;
Task-focused context&lt;br&gt;
Generating a giant repository dump isn't particularly interesting.&lt;br&gt;
The harder question is:&lt;br&gt;
What parts of this repository are likely to matter for the task I'm about to perform?&lt;/p&gt;

&lt;p&gt;Recall uses deterministic signals to rank relevant files.&lt;br&gt;
Today that includes things such as file paths, names, symbols, workspace relationships and a bounded import graph.&lt;br&gt;
There are no embeddings involved.&lt;br&gt;
There is no semantic model secretly deciding what your application means.&lt;br&gt;
That has an obvious trade-off.&lt;br&gt;
The ranking isn't magically intelligent.&lt;br&gt;
But it is predictable, local and inspectable.&lt;br&gt;
For this version of the project, I prefer that property.&lt;br&gt;
Context has an expiration problem&lt;br&gt;
Persistent context introduces another problem:&lt;br&gt;
stale context can be worse than no context.&lt;br&gt;
Suppose an agent receives a beautiful architectural summary generated three weeks ago.&lt;br&gt;
The repository has changed since then.&lt;br&gt;
The summary still looks authoritative.&lt;br&gt;
Now the context is actively misleading the agent.&lt;br&gt;
Recall therefore keeps a snapshot and exposes repository/context state through commands such as:&lt;br&gt;
npx recall-context@latest status&lt;br&gt;
The goal isn't to pretend generated context is permanently true.&lt;br&gt;
The goal is to know when it should no longer be trusted without checking the repository again.&lt;br&gt;
This area still has limitations. The current implementation is not a perfect semantic change detector, and I don't want to present it as one.&lt;br&gt;
Which leads to something I've been trying to do differently with this project.&lt;br&gt;
What Recall does not prove&lt;br&gt;
I could put several attractive claims on the README:&lt;br&gt;
Saves tokens.&lt;/p&gt;

&lt;p&gt;Makes coding agents faster.&lt;/p&gt;

&lt;p&gt;Improves accuracy.&lt;/p&gt;

&lt;p&gt;Reduces tool calls.&lt;/p&gt;

&lt;p&gt;I haven't proven any of them.&lt;br&gt;
So I'm not claiming them.&lt;br&gt;
Recall currently proves something much narrower:&lt;br&gt;
I can deterministically derive reusable repository context, persist it, inspect it, and give it to different coding agents.&lt;br&gt;
Whether doing that materially improves a real agent workflow is an empirical question.&lt;br&gt;
And that's the question I'm interested in now.&lt;br&gt;
There are already other approaches&lt;br&gt;
Repository context and agent memory are becoming an active area.&lt;br&gt;
Some approaches use persistent memory.&lt;br&gt;
Some use embeddings and semantic search.&lt;br&gt;
Some maintain module knowledge.&lt;br&gt;
Others intercept file reads and replace raw files with structural summaries.&lt;br&gt;
Those are valid approaches.&lt;br&gt;
Recall is intentionally narrower.&lt;br&gt;
Its current constraints are:&lt;br&gt;
local&lt;br&gt;
deterministic&lt;br&gt;
repository-derived&lt;br&gt;
inspectable&lt;br&gt;
agent-agnostic&lt;br&gt;
no AI provider required&lt;br&gt;
I don't know yet whether those constraints are enough to make it useful.&lt;br&gt;
But they make the experiment interesting to me.&lt;br&gt;
The limitations are real&lt;br&gt;
Recall is early.&lt;br&gt;
Some important limitations today:&lt;br&gt;
The import graph isn't a full semantic program analysis system.&lt;br&gt;
Task ranking is deterministic rather than semantic.&lt;br&gt;
The current ecosystem support is primarily focused on JavaScript/TypeScript and related Node.js frameworks.&lt;br&gt;
Token estimation is approximate rather than based on each model's tokenizer.&lt;br&gt;
There is no native MCP integration.&lt;br&gt;
There is no editor plugin.&lt;br&gt;
There is no cloud memory layer.&lt;br&gt;
And I'm deliberately not building those things yet.&lt;br&gt;
I'm stopping feature development&lt;br&gt;
This is probably the most important decision I've made around Recall.&lt;br&gt;
Normally this is where I would start adding:&lt;br&gt;
MCP.&lt;br&gt;
Editor integrations.&lt;br&gt;
More languages.&lt;br&gt;
Embeddings.&lt;br&gt;
Team synchronization.&lt;br&gt;
A dashboard.&lt;br&gt;
And six weeks later I would have a much larger product without knowing whether the original idea mattered.&lt;br&gt;
I'm not doing that this time.&lt;br&gt;
Version 0.2.0 is released.&lt;br&gt;
The next phase is validation.&lt;br&gt;
I want to measure real coding tasks with and without Recall and look at things like:&lt;br&gt;
time to first correct edit&lt;br&gt;
repository exploration time&lt;br&gt;
tool calls before the first correct edit&lt;br&gt;
context/token usage&lt;br&gt;
correctness&lt;br&gt;
whether someone voluntarily uses Recall again&lt;br&gt;
That last metric may be the most important one.&lt;br&gt;
If somebody tries Recall once and never reaches for it again, it doesn't matter how sophisticated I make the scanner.&lt;br&gt;
Try it on a real repository&lt;br&gt;
If you regularly use coding agents on non-trivial JavaScript or TypeScript repositories, that's the environment I'm most interested in testing.&lt;br&gt;
Start with:&lt;br&gt;
npx recall-context@latest init&lt;br&gt;
Then try:&lt;br&gt;
npx recall-context@latest context \&lt;br&gt;
  --task "Describe the task you're about to give your coding agent" \&lt;br&gt;
  --stdout&lt;br&gt;
The project is open source:&lt;br&gt;
GitHub:&lt;br&gt;
&lt;a href="https://github.com/sabahattink/Recall" rel="noopener noreferrer"&gt;https://github.com/sabahattink/Recall&lt;/a&gt;&lt;br&gt;
I'm particularly interested in failures.&lt;br&gt;
If the generated context points you toward the wrong files, misses something important, becomes stale incorrectly, or simply doesn't improve your workflow, that's more useful to me right now than another feature request.&lt;br&gt;
Because the question isn't:&lt;br&gt;
How much can I add to Recall?&lt;/p&gt;

&lt;p&gt;It's:&lt;br&gt;
Is persistent, deterministic repository context useful enough that you want it again in your next coding-agent session?&lt;/p&gt;

&lt;p&gt;That's what I'm trying to find out.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
    <item>
      <title>How I Automated My Obsidian Vault with Claude — It Now Works the Night Shift</title>
      <dc:creator>Sabahattin Kalkan</dc:creator>
      <pubDate>Thu, 28 May 2026 20:21:28 +0000</pubDate>
      <link>https://dev.to/sabahattink/how-i-automated-my-obsidian-vault-with-claude-it-now-works-the-night-shift-3gjl</link>
      <guid>https://dev.to/sabahattink/how-i-automated-my-obsidian-vault-with-claude-it-now-works-the-night-shift-3gjl</guid>
      <description>&lt;h2&gt;
  
  
  I was drowning in my own notes
&lt;/h2&gt;

&lt;p&gt;For about two years, I lived inside Obsidian. Daily notes, fleeting thoughts, meeting takeaways, half-formed ideas at 2am, voice memos I'd transcribe by hand. My vault had over 3,000 notes.&lt;/p&gt;

&lt;p&gt;And I remembered almost none of it.&lt;/p&gt;

&lt;p&gt;Every morning I'd open my laptop and stare at yesterday's daily note, trying to reconstruct where I was. The vault was full — full of captures that were never synthesized, tasks that were never carried forward, ideas that died in a folder called &lt;code&gt;_inbox&lt;/code&gt;. I was doing the work of a knowledge worker but getting none of the compounding returns. Notes went in. Nothing came out.&lt;/p&gt;

&lt;p&gt;What made it worse: I knew I was supposed to do the synthesis. Review your notes. Write a morning brief. Connect the dots. But after a full day of work, the last thing I wanted to do was sit down and play editor. So I didn't. And the vault stayed a graveyard.&lt;/p&gt;




&lt;h2&gt;
  
  
  The real problem isn't note-taking
&lt;/h2&gt;

&lt;p&gt;Here's what I eventually figured out: I wasn't failing at note-taking. I was failing at synthesis — and I was expecting myself to do it at the worst possible time.&lt;/p&gt;

&lt;p&gt;Synthesis requires cognitive distance. You need to look at what you captured with fresh eyes. The problem is that "fresh eyes" happen in the morning, and the synthesis work needs to happen after the day is over. That's a structural mismatch, and no productivity system fixes it because it's not a productivity problem.&lt;/p&gt;

&lt;p&gt;It's a timing problem. And timing problems are exactly what automation solves.&lt;/p&gt;

&lt;p&gt;The thought that changed everything: Claude doesn't get tired at 11pm. It doesn't need cognitive distance — it can read the whole day in one pass and pull out what matters. So I built vault-os to hand that job off.&lt;/p&gt;




&lt;h2&gt;
  
  
  What vault-os actually does
&lt;/h2&gt;

&lt;p&gt;vault-os has two main jobs: capture anything, anywhere, and synthesize everything while you sleep.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Capture via Telegram bot.&lt;/strong&gt; I wanted to send notes from my phone without opening Obsidian. The bot uses tag-based routing — anything you send gets sorted into the right section of your daily note automatically. &lt;code&gt;#idea&lt;/code&gt; goes into Content Ideas. &lt;code&gt;#signal&lt;/code&gt; goes into Research Signals. &lt;code&gt;#link&lt;/code&gt; or a bare URL goes into Links to Process. Plain text goes to Captures. Voice messages get transcribed locally and then routed the same way.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Nightly agent at 23:00.&lt;/strong&gt; A PowerShell script runs 12 phases: it reads your day, runs Claude over your captures, synthesizes patterns, writes an evening review, prepares your morning brief, and carries forward any unfinished tasks. By the time you wake up, your daily note for the new day already has context loaded.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Morning digest API.&lt;/strong&gt; A REST endpoint serves the morning brief so you can display it anywhere — a home screen widget, a terminal script, a Raycast extension, whatever fits your setup.&lt;/p&gt;




&lt;h2&gt;
  
  
  Architecture: the two components
&lt;/h2&gt;

&lt;h3&gt;
  
  
  server.js — Node.js + Express + Telegraf
&lt;/h3&gt;

&lt;p&gt;The server handles Telegram and the REST API. The core of it is a routing function that decides where each message goes in your daily note:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;routeMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&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;t&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;trim&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="sr"&gt;/^#&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;idea|fikir&lt;/span&gt;&lt;span class="se"&gt;)\b&lt;/span&gt;&lt;span class="sr"&gt;/i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;## Content Ideas&lt;/span&gt;&lt;span class="dl"&gt;'&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="sr"&gt;/^#&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;signal|research|sinyal&lt;/span&gt;&lt;span class="se"&gt;)\b&lt;/span&gt;&lt;span class="sr"&gt;/i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;## Research Signals&lt;/span&gt;&lt;span class="dl"&gt;'&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="sr"&gt;/^#link&lt;/span&gt;&lt;span class="se"&gt;\b&lt;/span&gt;&lt;span class="sr"&gt;/i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="sr"&gt;/^https&lt;/span&gt;&lt;span class="se"&gt;?&lt;/span&gt;&lt;span class="sr"&gt;:&lt;/span&gt;&lt;span class="se"&gt;\/\/&lt;/span&gt;&lt;span class="sr"&gt;/i&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;test&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;t&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;## Links to Process&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;## Captures&lt;/span&gt;&lt;span class="dl"&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;Simple regex matching. I added Turkish/Azerbaijani aliases (&lt;code&gt;fikir&lt;/code&gt;, &lt;code&gt;sinyal&lt;/code&gt;) because I switch languages mid-thought constantly. You can extend this to whatever tags your brain uses.&lt;/p&gt;

&lt;p&gt;Multi-line messages are handled per-line — if you paste a block of text with five ideas, each line gets routed independently. This matters more than it sounds; it means you can dump a brain dump into Telegram and it lands sorted.&lt;/p&gt;

&lt;p&gt;The voice pipeline runs: OGG (Telegram's format) → ffmpeg converts to 16kHz mono WAV → whisper-cli transcribes → text goes through the same routing function. The whole thing is synchronous on my machine and takes about 4 seconds for a 30-second voice memo.&lt;/p&gt;

&lt;p&gt;REST endpoints are minimal: &lt;code&gt;GET /morning-brief&lt;/code&gt; returns the prepared brief as JSON, &lt;code&gt;POST /capture&lt;/code&gt; lets other tools push content directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  nightly-agent.ps1 — PowerShell, 12 phases
&lt;/h3&gt;

&lt;p&gt;I wrote this in PowerShell because it runs as a Windows Task Scheduler job and I didn't want a dependency on a running Node process. The phases are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;FAZ 1-2:&lt;/strong&gt; Environment check, date setup, locate today's note&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FAZ 3 (Claude Think):&lt;/strong&gt; Read all captured content, run a synthesis prompt, extract key themes, identify what was actually important vs. noise&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FAZ 4-5:&lt;/strong&gt; Task extraction, carry-forward logic for incomplete items&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FAZ 6 (Morning Brief):&lt;/strong&gt; Write tomorrow's opening section — not a summary of yesterday, but a launch pad for tomorrow. What's the one thing that matters. What task deserves first attention. What idea is worth developing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FAZ 7-10:&lt;/strong&gt; Link processing, research signal digestion, content angle extraction&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FAZ 11 (Evening Review):&lt;/strong&gt; Appended to today's note — a short human-readable synthesis of the day that you can read before sleep&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;FAZ 12:&lt;/strong&gt; Cleanup, log rotation, error reporting&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Claude API calls follow a consistent pattern: write the prompt to a temp file, call &lt;code&gt;claude --print&lt;/code&gt; with &lt;code&gt;--max-turns 1&lt;/code&gt;, capture stdout, clean up.&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="nv"&gt;$prompt&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;Out-File&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-FilePath&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$tmpFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-Encoding&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;UTF8&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nv"&gt;$result&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="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;claude&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--print&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;--max-turns&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;1&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$tmpFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;2&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;&lt;/span&gt;&lt;span class="bp"&gt;$null&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="n"&gt;Remove-Item&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nv"&gt;$tmpFile&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-ErrorAction&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;SilentlyContinue&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I use &lt;code&gt;--max-turns 1&lt;/code&gt; everywhere in the nightly agent because I don't want back-and-forth — I want one focused output per phase. This also keeps costs predictable. A full nightly run on a moderately active day costs me about $0.04.&lt;/p&gt;




&lt;h2&gt;
  
  
  What a daily note actually looks like
&lt;/h2&gt;

&lt;p&gt;The daily note template has fixed sections that the automation respects:&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="gh"&gt;# 2026-05-29&lt;/span&gt;

&lt;span class="gu"&gt;## Morning Brief&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- written by nightly agent from previous night --&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;## Captures&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- plain Telegram messages land here --&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;## Content Ideas&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- #idea tags land here --&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;## Research Signals&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- #signal tags land here --&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;## Links to Process&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- #link tags and bare URLs land here --&amp;gt;&lt;/span&gt;

&lt;span class="gu"&gt;## Evening Review&lt;/span&gt;
&lt;span class="c"&gt;&amp;lt;!-- written by nightly agent at 23:00 --&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;During the day, you're just sending messages. The structure fills itself in. The Morning Brief is already there when you open Obsidian. The Evening Review appears after the agent runs. You never touch the note directly unless you want to.&lt;/p&gt;

&lt;p&gt;This matters for adoption: if the automation requires you to maintain the structure, you'll break it within two weeks. The structure has to be robust enough to survive a messy day where you just dump text into Telegram without thinking.&lt;/p&gt;




&lt;h2&gt;
  
  
  Voice capture and why local matters
&lt;/h2&gt;

&lt;p&gt;I almost used OpenAI Whisper API for transcription. It's easier to set up and the accuracy is excellent. I switched to whisper.cpp for one reason: the content of voice notes.&lt;/p&gt;

&lt;p&gt;When you're thinking out loud into your phone, you're not performing. You're rough-drafting decisions, processing frustrations, working through half-formed ideas that you wouldn't put in a document. That content is genuinely private — not in a paranoid way, but in the way that a sketchbook is private. It's your unedited thinking.&lt;/p&gt;

&lt;p&gt;Sending that audio to an API means it transits servers you don't control. Running whisper.cpp locally means the audio never leaves your machine. The model is a file on disk (&lt;code&gt;ggml-small.bin&lt;/code&gt;, 466MB), the process runs in a subprocess, and nothing goes over the network.&lt;/p&gt;

&lt;p&gt;Accuracy with &lt;code&gt;small&lt;/code&gt; is good enough for most voice notes — I get the occasional mishearing on proper nouns and mixed-language sentences, but the meaning survives. If you mostly dictate in a single language, &lt;code&gt;small&lt;/code&gt; is the right tradeoff. &lt;code&gt;medium&lt;/code&gt; (1.5GB) is noticeably better for multilingual.&lt;/p&gt;




&lt;h2&gt;
  
  
  What I wake up to
&lt;/h2&gt;

&lt;p&gt;Here's what the Morning Brief section looks like on a real morning:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## Morning Brief

Carry-forward: Finish the vault-os README (started yesterday, left at setup section).

Yesterday's thread: Three captures around API cost optimization clustered
with a research signal on context caching. Worth developing.

Content angle ready: "Local-first AI tools" — #idea from Tuesday still
unaddressed, now has supporting signals from two separate sources.

Today's open question: The routing logic handles single-line captures well
but breaks on multi-paragraph pastes. Worth fixing or acceptable?
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The brief is not a summary. It's a launch pad. There's a difference: a summary tells you what happened, a launch pad tells you where to start.&lt;/p&gt;




&lt;h2&gt;
  
  
  Getting started
&lt;/h2&gt;

&lt;p&gt;Prerequisites: Node.js 18+, PowerShell 7+, Claude CLI authenticated, ffmpeg on PATH, whisper.cpp compiled.&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/sabahattink/vault-os
&lt;span class="nb"&gt;cd &lt;/span&gt;vault-os
./setup.sh
&lt;span class="c"&gt;# Edit .env: VAULT_PATH, TELEGRAM_BOT_TOKEN, ANTHROPIC_API_KEY&lt;/span&gt;
node dashboard/server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For the nightly agent, register &lt;code&gt;scripts/nightly-agent.ps1&lt;/code&gt; as a Windows Task Scheduler job at 23:00:&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;pwsh&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;-File&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nx"&gt;scripts/install-scheduler.ps1&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






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

&lt;p&gt;I'm building this in public. Three things on the roadmap I actually need:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Decision intelligence endpoint.&lt;/strong&gt; Extract decisions from a date range — not summaries, but actual choices made and the reasoning captured around them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Weekly synthesis agent.&lt;/strong&gt; Look across seven days of evening reviews and find the thread — what was I actually working on this week vs. what I said I was working on.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Mobile shortcut integration.&lt;/strong&gt; An iOS Shortcut that records audio and POSTs directly to the capture endpoint, bypassing Telegram entirely for voice-only workflows.&lt;/p&gt;




&lt;p&gt;If you use Obsidian and your vault isn't working for you — not because you're bad at it, but because synthesis is genuinely hard to sustain — vault-os might be worth trying.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/sabahattink/vault-os" rel="noopener noreferrer"&gt;github.com/sabahattink/vault-os&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Star it if it looks useful. Issues and PRs welcome.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Tags: obsidian, productivity, ai, opensource&lt;/em&gt;&lt;/p&gt;

</description>
      <category>obsidian</category>
      <category>productivity</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <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://dev.to/sabahattink/i-built-a-permission-first-claudemd-agent-stack-for-claude-code-free-mit-4ep6</link>
      <guid>https://dev.to/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://dev.to/sabahattink/building-mailtest-an-open-source-email-deliverability-debugger-17hn</link>
      <guid>https://dev.to/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://dev.to/sabahattink/title-i-built-a-cli-that-diagnoses-your-code-before-you-ship-tags-nestjs-typescript-opensource-2208</link>
      <guid>https://dev.to/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://dev.to/sabahattink/stop-switching-to-githubcom-for-standup-i-built-a-cli-for-that-3llk</link>
      <guid>https://dev.to/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://dev.to/sabahattink/i-built-a-self-hosted-llm-proxy-that-supports-12-providers-claude-gpt-4o-gemini-ollama-3ej1</link>
      <guid>https://dev.to/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://dev.to/sabahattink/stop-writing-bad-commit-messages-i-built-a-free-ai-cli-for-that-2g22</link>
      <guid>https://dev.to/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>
