<?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: Ripon C Malo</title>
    <description>The latest articles on DEV Community by Ripon C Malo (@riponcm).</description>
    <link>https://dev.to/riponcm</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%2F3943129%2Fd37c3122-26cb-40b9-a3fe-0e0bbc19fea5.jpeg</url>
      <title>DEV Community: Ripon C Malo</title>
      <link>https://dev.to/riponcm</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/riponcm"/>
    <language>en</language>
    <item>
      <title>We Built a Free, Open Source Alternative to Topaz for Image and Video Upscaling</title>
      <dc:creator>Ripon C Malo</dc:creator>
      <pubDate>Tue, 25 Aug 2026 20:41:33 +0000</pubDate>
      <link>https://dev.to/riponcm/we-built-a-free-open-source-alternative-to-topaz-for-image-and-video-upscaling-16e9</link>
      <guid>https://dev.to/riponcm/we-built-a-free-open-source-alternative-to-topaz-for-image-and-video-upscaling-16e9</guid>
      <description>&lt;p&gt;Most of my AI-generated videos come out at 720p. The tools that upscale them well are either subscription software at around $199 per year, or open source models that need a command line, separate weight downloads, and a lot of patience.&lt;/p&gt;

&lt;p&gt;So we built &lt;a href="https://github.com/riponcm/nextgenUp" rel="noopener noreferrer"&gt;NextGenUp&lt;/a&gt;: a free, open source AI upscaler for both images and video, with a point-and-click interface. Everything runs locally. Nothing you upscale ever leaves your machine.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvjvd5u5aw7ah2qkipyvp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2Fvjvd5u5aw7ah2qkipyvp.png" alt="Before and after comparison slider" width="800" height="600"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What it does
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Images up to 8K&lt;/strong&gt; with four modes: Quick (browser AI), Quality (FFmpeg Lanczos plus CAS sharpening), Enhance (same resolution, AI cleanup), and Ultra (server-side AI that works from any device)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Video up to 4K&lt;/strong&gt;, with audio preserved and portrait or landscape handled automatically&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Face restoration&lt;/strong&gt; with GFPGAN: detected faces are aligned, restored, and blended back seamlessly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Batch processing&lt;/strong&gt; with a zip download, a before/after slider on every result, and cancellable jobs&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Desktop apps&lt;/strong&gt; for macOS, Windows, and Linux, with FFmpeg and the models bundled, so there is no setup&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It is MIT licensed. There is no account, no watermark, and no telemetry.&lt;/p&gt;

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

&lt;p&gt;The architecture is a local Flask server plus a web UI, wrapped in Tauri for the desktop:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Super-resolution&lt;/strong&gt; uses Real-ESRGAN (the compact realesr-general-x4v3 model, about 5 MB as ONNX). In the browser it runs through ONNX Runtime Web on WebGPU, with a WASM fallback. On the server it runs through ONNX Runtime on CPU.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Tiling&lt;/strong&gt; keeps memory bounded: images are processed in overlapping tiles (64 to 128 px with padding), then stitched. This is why a 6000 px photo works on modest hardware.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Face restoration&lt;/strong&gt; chains YuNet detection, a similarity transform to the FFHQ template, GFPGAN v1.4 inference at 512x512, and a feathered paste-back.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The desktop app&lt;/strong&gt; is a thin Rust shell that spawns the Python server as a PyInstaller sidecar and points a webview at it. Auto-updates are handled by the Tauri updater with signed releases on GitHub.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;h2&gt;
  
  
  Three bugs worth sharing
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The 95 percent hang.&lt;/strong&gt; Video encoding kept freezing near the end. Cause: I piped both stdout and stderr from FFmpeg but only read stdout. FFmpeg filled the 64 KB stderr pipe buffer, blocked on writing, and we deadlocked. Fix: drain stderr in a background thread. If you spawn FFmpeg from any language, you have probably hit this.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The orphaned server.&lt;/strong&gt; Quitting the desktop app left the backend running. PyInstaller one-file binaries run as a bootloader that spawns the real process as a child, so killing the direct child orphans the grandchild. Fix: put the sidecar in its own process group on Unix and kill the group; use taskkill /T on Windows.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The relocated FFmpeg.&lt;/strong&gt; I bundled the ffmpeg binary from my own machine and every server feature silently broke in the packaged app. It was a dynamically linked build that only works from its original install directory. Always bundle static builds.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest limitations
&lt;/h2&gt;

&lt;p&gt;The compact Real-ESRGAN model does not beat Topaz on extreme fine detail like hair at 4x. Pro video mode is slow without WebGPU. The macOS builds are not notarized yet, so the first launch needs right-click and Open. A max-quality tier with larger models (Real-ESRGAN x4plus or HAT) is on the roadmap.&lt;/p&gt;

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

&lt;p&gt;Installers for macOS, Windows, and Linux are on the &lt;a href="https://github.com/riponcm/nextgenUp/releases/latest" rel="noopener noreferrer"&gt;releases page&lt;/a&gt;, or run it from source with Python and FFmpeg. If it is useful to you, a star on &lt;a href="https://github.com/riponcm/nextgenUp" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt; helps other people find it.&lt;/p&gt;

&lt;p&gt;I would love feedback, especially from anyone who has compared upscaling models in practice.&lt;/p&gt;

&lt;p&gt;NextGenUp is a &lt;a href="https://matily.org" rel="noopener noreferrer"&gt;matily.org&lt;/a&gt; product, MIT licensed.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>upscaling</category>
      <category>videoupscal</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How to Free Up Disk Space as a Developer: Clear Hugging Face, npm, conda, and Docker Caches</title>
      <dc:creator>Ripon C Malo</dc:creator>
      <pubDate>Sun, 26 Jul 2026 19:00:41 +0000</pubDate>
      <link>https://dev.to/riponcm/how-to-free-up-disk-space-as-a-developer-clear-hugging-face-npm-conda-and-docker-caches-3h21</link>
      <guid>https://dev.to/riponcm/how-to-free-up-disk-space-as-a-developer-clear-hugging-face-npm-conda-and-docker-caches-3h21</guid>
      <description>&lt;p&gt;If you write code — and especially if you work with machine learning — your disk&lt;br&gt;
is quietly filling up with data you downloaded once and forgot about. A model&lt;br&gt;
you tried for an afternoon. Package caches from five virtualenvs. Docker images&lt;br&gt;
from a project you finished months ago. This guide covers where that space&lt;br&gt;
goes, how to reclaim it manually, and how to do it all from one place.&lt;/p&gt;
&lt;h2&gt;
  
  
  Where a developer's disk space actually goes
&lt;/h2&gt;

&lt;p&gt;The biggest offenders almost never show up in Finder or Explorer, because&lt;br&gt;
they're hidden in cache directories:&lt;/p&gt;
&lt;h3&gt;
  
  
  Machine learning model caches
&lt;/h3&gt;

&lt;p&gt;These are the heavyweights. A single large language model can be several&lt;br&gt;
gigabytes, and most people accumulate dozens.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Hugging Face&lt;/strong&gt; — &lt;code&gt;~/.cache/huggingface&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ollama&lt;/strong&gt; — &lt;code&gt;~/.ollama/models&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;PyTorch hub&lt;/strong&gt; — &lt;code&gt;~/.cache/torch&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Whisper&lt;/strong&gt; — &lt;code&gt;~/.cache/whisper&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To clear the Hugging Face cache manually:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-rf&lt;/span&gt; ~/.cache/huggingface/hub
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The catch: this deletes &lt;strong&gt;every&lt;/strong&gt; model, including the ones you actually use.&lt;br&gt;
They'll re-download on demand, but that's a lot of bandwidth if you only wanted&lt;br&gt;
to remove one abandoned model.&lt;/p&gt;
&lt;h3&gt;
  
  
  Package manager caches
&lt;/h3&gt;

&lt;p&gt;Every language ecosystem keeps a cache to speed up reinstalls. They regenerate&lt;br&gt;
automatically, so they're safe to clear:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm cache clean &lt;span class="nt"&gt;--force&lt;/span&gt;            &lt;span class="c"&gt;# ~/.npm/_cacache&lt;/span&gt;
pip cache purge                    &lt;span class="c"&gt;# pip download cache&lt;/span&gt;
conda clean &lt;span class="nt"&gt;--all&lt;/span&gt;                  &lt;span class="c"&gt;# conda packages and tarballs&lt;/span&gt;
cargo cache &lt;span class="nt"&gt;--autoclean&lt;/span&gt;            &lt;span class="c"&gt;# Rust crate registry (needs cargo-cache)&lt;/span&gt;
go clean &lt;span class="nt"&gt;-cache&lt;/span&gt;                    &lt;span class="c"&gt;# Go build cache&lt;/span&gt;
docker system prune &lt;span class="nt"&gt;-a&lt;/span&gt;             &lt;span class="c"&gt;# dangling images, containers, build cache&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Build artifacts and IDE caches
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Xcode DerivedData&lt;/strong&gt; — &lt;code&gt;~/Library/Developer/Xcode/DerivedData&lt;/code&gt; (can hit tens of GB)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gradle&lt;/strong&gt; — &lt;code&gt;~/.gradle/caches&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;JetBrains IDEs&lt;/strong&gt; — &lt;code&gt;~/Library/Caches/JetBrains&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;node_modules&lt;/strong&gt; in dead projects — often gigabytes each&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  The stuff manual commands miss
&lt;/h3&gt;

&lt;p&gt;Two categories that no &lt;code&gt;clean&lt;/code&gt; command touches:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Duplicated Python packages.&lt;/strong&gt; Install &lt;code&gt;torch&lt;/code&gt; in eight virtualenvs and you
have eight copies — often 2–3 GB each.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;App leftovers.&lt;/strong&gt; Uninstalling an app on macOS usually leaves its
&lt;code&gt;Application Support&lt;/code&gt;, &lt;code&gt;Caches&lt;/code&gt;, and &lt;code&gt;Preferences&lt;/code&gt; behind forever.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The problem with cleaning it manually
&lt;/h2&gt;

&lt;p&gt;Running these commands works, but it has real downsides:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You have to &lt;strong&gt;remember every location&lt;/strong&gt; across every tool you use.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;rm -rf&lt;/code&gt; on a cache is &lt;strong&gt;all or nothing&lt;/strong&gt; — you can't keep the models you use.&lt;/li&gt;
&lt;li&gt;You can't easily see &lt;strong&gt;what's actually taking up space&lt;/strong&gt; before deleting.&lt;/li&gt;
&lt;li&gt;It's &lt;strong&gt;different on Windows&lt;/strong&gt;, where the paths change (&lt;code&gt;%LOCALAPPDATA%\pip\Cache&lt;/code&gt;, the registry-based uninstaller, etc.).&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Doing it all from one place: Jharu
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://jharu.matily.org" rel="noopener noreferrer"&gt;Jharu&lt;/a&gt; is a free, open-source disk cleaner built&lt;br&gt;
specifically for this problem. It runs on macOS and Windows and understands the&lt;br&gt;
developer and AI locations above — but instead of blunt deletion, it tells you&lt;br&gt;
what each thing is and whether you've used it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Per-model ML cleanup.&lt;/strong&gt; Jharu lists every Hugging Face, Ollama, PyTorch, and&lt;br&gt;
Whisper model &lt;em&gt;individually&lt;/em&gt;, with its size and — crucially — whether you've&lt;br&gt;
actually loaded it since downloading. So you can reclaim the 6 GB model you&lt;br&gt;
tried once without touching the ones you use daily. Shared Ollama layers are&lt;br&gt;
preserved, so removing one model never breaks another.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deep cache scan.&lt;/strong&gt; It scans 25+ known locations (npm, pip, uv, yarn, pnpm,&lt;br&gt;
conda, Cargo, Go, Gradle, Maven, NuGet, Docker, Xcode, JetBrains, Playwright,&lt;br&gt;
and more), each rated &lt;em&gt;safe to clear&lt;/em&gt;, &lt;em&gt;re-downloadable&lt;/em&gt;, or &lt;em&gt;review first&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Python environment analyzer.&lt;/strong&gt; It finds every virtualenv and conda&lt;br&gt;
environment and quantifies duplication across them — the "torch is installed&lt;br&gt;
eleven times" problem, in one view.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;A treemap of your whole disk.&lt;/strong&gt; See every folder sized by what it holds, so&lt;br&gt;
the biggest space-eater is literally the biggest block. Click to drill in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Clean uninstaller.&lt;/strong&gt; Removes an app &lt;em&gt;and&lt;/em&gt; the leftovers it scattered across&lt;br&gt;
your system.&lt;/p&gt;

&lt;h3&gt;
  
  
  Safe by design
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Nothing is ever permanently deleted — everything goes to the Trash or Recycle
Bin, and a dialog tells you the real consequence first.&lt;/li&gt;
&lt;li&gt;No telemetry, no tracking, no subscription.&lt;/li&gt;
&lt;li&gt;No registry "cleaner" (it doesn't work), and if Jharu can't read a folder it
says so instead of silently hiding it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Get it
&lt;/h2&gt;

&lt;p&gt;Jharu is free and open source under Apache 2.0.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Download:&lt;/strong&gt; &lt;a href="https://jharu.matily.org" rel="noopener noreferrer"&gt;jharu.matily.org&lt;/a&gt; (macOS Apple
Silicon + Intel, and Windows 64-bit)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source:&lt;/strong&gt; &lt;a href="https://github.com/riponcm/Jharu" rel="noopener noreferrer"&gt;github.com/riponcm/Jharu&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run one scan and you'll usually find tens of gigabytes you didn't know were&lt;br&gt;
there. If you reclaim some space, drop a comment with how much.&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>machinelearning</category>
      <category>python</category>
      <category>rust</category>
    </item>
    <item>
      <title>OSSDrop — a curated, community-ranked directory of open-source tools</title>
      <dc:creator>Ripon C Malo</dc:creator>
      <pubDate>Mon, 20 Jul 2026 03:16:53 +0000</pubDate>
      <link>https://dev.to/riponcm/ossdrop-a-curated-community-ranked-directory-of-open-source-tools-g15</link>
      <guid>https://dev.to/riponcm/ossdrop-a-curated-community-ranked-directory-of-open-source-tools-g15</guid>
      <description>&lt;p&gt;Finding a good open-source tool is mostly luck. You catch it in a buried Hacker News thread, or a coworker mentions it, or you trip over a repo with 300 stars that does exactly what you needed six months ago. Meanwhile thousands of genuinely useful projects sit unseen because discovery is noisy and nobody's curating it.&lt;/p&gt;

&lt;p&gt;We built &lt;strong&gt;OSSDrop&lt;/strong&gt; to make that less random.&lt;/p&gt;

&lt;h2&gt;
  
  
  What OSSDrop is
&lt;/h2&gt;

&lt;p&gt;OSSDrop is a curated, community-ranked directory of open-source tools, live at &lt;strong&gt;&lt;a href="https://ossdrop.com" rel="noopener noreferrer"&gt;ossdrop.com&lt;/a&gt;&lt;/strong&gt;. Every listing points to a real repository with a verified license and star count — no dead links, no vaporware. You can browse by category, upvote the tools you actually use, and submit your own project in a single step.&lt;/p&gt;

&lt;p&gt;It runs across three places:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://ossdrop.com" rel="noopener noreferrer"&gt;ossdrop.com&lt;/a&gt;&lt;/strong&gt; — the ranked directory, plus a forum for the people building and using these tools.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/OSSDrop/OSSDrop" rel="noopener noreferrer"&gt;OSSDrop/OSSDrop&lt;/a&gt;&lt;/strong&gt; on GitHub — an open list you can add your tool to with a pull request.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.reddit.com/r/OSSDrop/" rel="noopener noreferrer"&gt;r/OSSDrop&lt;/a&gt;&lt;/strong&gt; — the subreddit for discussion and finds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The list and the site share the same data, so anything on the GitHub list flows into the directory.&lt;/p&gt;

&lt;h2&gt;
  
  
  How the ranking works — and what doesn't buy you rank
&lt;/h2&gt;

&lt;p&gt;This is the part we care most about getting right, so we made it public. There's a full &lt;strong&gt;&lt;a href="https://ossdrop.com/how-it-works" rel="noopener noreferrer"&gt;How OSSDrop works&lt;/a&gt;&lt;/strong&gt; page that spells out the ranking, but the short version:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Tools rank on community votes and recency.&lt;/strong&gt; People upvote what they use; fresh, well-received tools rise. It's the same intuition as a link aggregator, applied to a directory.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Karma is earned, not handed out.&lt;/strong&gt; You build it by posting and voting like a normal member. Admins can't gift it, and there's no way to buy it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Boosts and promotion don't move ranking scores.&lt;/strong&gt; If we ever offer paid visibility, it's clearly labeled placement — it will never quietly reorder the rankings. The vote-based order stays honest.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We wrote it down partly so you can hold us to it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What you'll actually find on it
&lt;/h2&gt;

&lt;p&gt;A good chunk of the early catalog is the kind of tool developers pass around by word of mouth. If you live in a terminal, a few that are already listed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;lazygit&lt;/strong&gt; — a terminal UI for git that makes staging, branching, and rebasing genuinely fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ripgrep&lt;/strong&gt; — recursive search that's absurdly quick and respects your &lt;code&gt;.gitignore&lt;/code&gt; by default.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;fzf&lt;/strong&gt; — a fuzzy finder that plugs into your shell, history, and just about everything else.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;bat&lt;/strong&gt; — &lt;code&gt;cat&lt;/code&gt; with syntax highlighting, line numbers, and git integration.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;httpie&lt;/strong&gt; — a human-friendly HTTP client for testing APIs without wrestling curl flags.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Beyond the terminal, the catalog spans everything from projects out of large labs to tools maintained by one person on weekends. Notable and verified projects carry a &lt;strong&gt;Curated&lt;/strong&gt; badge so it's clear what's been checked.&lt;/p&gt;

&lt;h2&gt;
  
  
  Adding your tool takes about a minute
&lt;/h2&gt;

&lt;p&gt;If you maintain something open source, submitting is one step: paste the repository URL and OSSDrop auto-fetches the name, description, license, and stars from the forge so you're not filling out a long form. If your tool is already on the list, you can &lt;strong&gt;claim it&lt;/strong&gt; — that request goes to a human, and once it's verified you own the listing and can keep it up to date.&lt;/p&gt;

&lt;p&gt;That's the whole point of the "drop" in the name: drop your open-source tool and let people find it.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why it's built this way
&lt;/h2&gt;

&lt;p&gt;OSSDrop is made by &lt;a href="https://matily.org" rel="noopener noreferrer"&gt;Matily&lt;/a&gt;, a nonprofit open-source studio. That shapes the rules: it's free, it's privacy-respecting, and it's neutral. We list other people's tools — including things that compete with each other, and things that compete with us — fairly. A directory is only worth anything if it isn't gatekept, and if you can trust that what's near the top got there honestly.&lt;/p&gt;

&lt;p&gt;No fake metrics, no dark patterns, no "best tool ever." Just an accurate, community-ranked home for open-source work.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Is OSSDrop free?&lt;/strong&gt;&lt;br&gt;
Yes. Browsing, voting, submitting, and claiming a tool are all free.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;How is it different from Awesome lists or a GitHub topic?&lt;/strong&gt;&lt;br&gt;
Awesome lists are static and unranked, and topics are just tag pages. OSSDrop is ranked by the people using the tools, kept current, and it's a place to discuss them — not only a list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Do I have to use GitHub?&lt;/strong&gt;&lt;br&gt;
You can sign in with GitHub or Google, and the GitHub list accepts pull requests. Support for tools hosted on other forges is on the roadmap.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Can I list a tool I didn't build?&lt;/strong&gt;&lt;br&gt;
Yes — the directory is meant to be generous. If you're the maintainer and want to manage the listing, use the claim flow to take ownership after a quick verification.&lt;/p&gt;




&lt;p&gt;Have a tool you rely on that more people should know about? Add it, or upvote the ones already there: &lt;strong&gt;&lt;a href="https://ossdrop.com" rel="noopener noreferrer"&gt;ossdrop.com&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>resources</category>
      <category>development</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Open-source Grammarly alternatives in 2026 — and why I built another one</title>
      <dc:creator>Ripon C Malo</dc:creator>
      <pubDate>Tue, 14 Jul 2026 16:44:22 +0000</pubDate>
      <link>https://dev.to/riponcm/open-source-grammarly-alternatives-in-2026-and-why-i-built-another-one-4ljk</link>
      <guid>https://dev.to/riponcm/open-source-grammarly-alternatives-in-2026-and-why-i-built-another-one-4ljk</guid>
      <description>&lt;p&gt;If you search "Grammarly alternative," you get listicles full of freemium tools that are just smaller subscriptions. What I actually wanted was simpler: &lt;strong&gt;grammar checking in every text field of my browser, without a subscription and without my text being routed through a company's servers.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/3w7-aDIMQiM"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;I went through the open-source options first. Here's the honest rundown — and then the tool I ended up building, which is also free and open source.&lt;/p&gt;

&lt;h2&gt;
  
  
  The open-source landscape, honestly
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;LanguageTool&lt;/strong&gt; — the most mature open-source grammar checker (the core is open source and self-hostable via Docker). Rule-based, supports 40+ languages, solid browser extension. The catch: the &lt;em&gt;hosted&lt;/em&gt; extension most people install is freemium with premium rules paywalled, and rule-based checking misses things an LLM catches easily — run-on sentences, agreement across clauses, awkward phrasing. Self-hosting fixes the privacy question but means running a Java server.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Harper&lt;/strong&gt; — a modern grammar engine in Rust, compiled to WASM, running fully locally. Genuinely private (nothing leaves your machine) and fast. The trade-off is the flip side of being local and rule-based: English-focused, and it won't judge whether your whole sentence &lt;em&gt;makes sense&lt;/em&gt; the way an LLM does.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Vale&lt;/strong&gt; — not really a Grammarly alternative; it's a style linter for docs-as-code (enforcing style guides in CI). Great at what it does, different problem.&lt;/p&gt;

&lt;p&gt;So the field splits into two camps: &lt;strong&gt;rule-based and private&lt;/strong&gt; (Harper, self-hosted LanguageTool) or &lt;strong&gt;LLM-smart but subscription-and-server-based&lt;/strong&gt; (Grammarly, QuillBot). I wanted the third quadrant: &lt;strong&gt;LLM-smart &lt;em&gt;and&lt;/em&gt; private &lt;em&gt;and&lt;/em&gt; free.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The trick that makes the third quadrant possible
&lt;/h2&gt;

&lt;p&gt;The insight behind GemType is almost embarrassingly simple: Google's Gemini API has a genuinely usable &lt;strong&gt;free tier&lt;/strong&gt;, and modern flash-tier models are more than good enough for grammar work. So instead of running a paid middleman server between the user and the model, the extension talks &lt;strong&gt;directly from the browser to Google's API using the user's own free key&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;That single architectural decision cascades into everything people actually want:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Free&lt;/strong&gt; — the user's free-tier key covers daily writing comfortably&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Private&lt;/strong&gt; — there is no vendor server; I never see anyone's text or key&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auditable&lt;/strong&gt; — no backend means the entire data path is in the extension source&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Any language&lt;/strong&gt; — the model checks whatever language you write in, auto-detected&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The parts that were actually hard to build
&lt;/h2&gt;

&lt;p&gt;The LLM plumbing is the easy 10%. The hard 90% is the same thing that makes Grammarly's engineering interesting:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Underlines without touching the page's DOM.&lt;/strong&gt; If you wrap flagged words in &lt;code&gt;&amp;lt;span&amp;gt;&lt;/code&gt;s inside a React/ProseMirror editor, you corrupt its internal state (Grammarly abandoned exactly this approach years ago). GemType draws wavy underlines on a &lt;strong&gt;transparent overlay in a shadow root&lt;/strong&gt;, positioned via &lt;code&gt;Range.getClientRects()&lt;/code&gt; for rich editors and a hidden mirror element for plain &lt;code&gt;&amp;lt;textarea&amp;gt;&lt;/code&gt;s.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Snippets, not offsets.&lt;/strong&gt; LLMs are unreliable at reporting character offsets. Instead, Gemini returns structured JSON (&lt;code&gt;responseSchema&lt;/code&gt;) with the &lt;em&gt;exact erroneous snippet&lt;/em&gt; and its correction; the client locates snippets with substring search and re-anchors them live as you type.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Undo-safe fixes.&lt;/strong&gt; Corrections are applied with &lt;code&gt;document.execCommand('insertText')&lt;/code&gt;, which preserves the native undo stack and fires real &lt;code&gt;input&lt;/code&gt; events — so frameworks treat the fix as a user edit.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Sentence re-checks.&lt;/strong&gt; After every accepted fix, the surrounding sentence is automatically re-checked (scoped to that sentence, not the document — token-frugal). Word-level fixes stop leaving broken sentences behind.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. The bug I'll remember:&lt;/strong&gt; on Reddit everything worked — invisibly. Reddit ships CSS that hides unknown custom elements (&lt;code&gt;visibility:hidden&lt;/code&gt;), which nuked my overlay host. Fix: every host style set inline with &lt;code&gt;!important&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It's all vanilla JavaScript, Manifest V3, no build step. If you're building an extension that has to coexist with hostile editors, the source may save you some scars: &lt;strong&gt;&lt;a href="https://github.com/riponcm/GemType" rel="noopener noreferrer"&gt;github.com/riponcm/GemType&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where each tool actually fits
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Tool&lt;/th&gt;
&lt;th&gt;Engine&lt;/th&gt;
&lt;th&gt;Privacy&lt;/th&gt;
&lt;th&gt;Languages&lt;/th&gt;
&lt;th&gt;Cost&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;LanguageTool (self-hosted)&lt;/td&gt;
&lt;td&gt;Rules&lt;/td&gt;
&lt;td&gt;Local&lt;/td&gt;
&lt;td&gt;40+&lt;/td&gt;
&lt;td&gt;Free + your server&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Harper&lt;/td&gt;
&lt;td&gt;Rules (Rust/WASM)&lt;/td&gt;
&lt;td&gt;Fully local&lt;/td&gt;
&lt;td&gt;English-focused&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vale&lt;/td&gt;
&lt;td&gt;Style rules&lt;/td&gt;
&lt;td&gt;Local/CI&lt;/td&gt;
&lt;td&gt;n/a (style)&lt;/td&gt;
&lt;td&gt;Free&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Grammarly / QuillBot&lt;/td&gt;
&lt;td&gt;LLM + rules&lt;/td&gt;
&lt;td&gt;Vendor servers&lt;/td&gt;
&lt;td&gt;English + few&lt;/td&gt;
&lt;td&gt;Freemium → $12–30/mo&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;GemType&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;LLM (Gemini)&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Direct to Google with your key; no vendor server&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Any, auto-detected&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;Free (your free-tier key)&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Honest trade-offs of GemType: you spend two clicks getting a free API key from &lt;a href="https://aistudio.google.com/apikey" rel="noopener noreferrer"&gt;Google AI Studio&lt;/a&gt; (no card), you need an internet connection, and Google Docs isn't supported (it renders to canvas and gates its annotation API to whitelisted vendors — the one place only Grammarly-tier companies can go).&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Website / live demo:&lt;/strong&gt; &lt;a href="https://gemtype.matily.org" rel="noopener noreferrer"&gt;gemtype.matily.org&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Chrome:&lt;/strong&gt; &lt;a href="https://chromewebstore.google.com/detail/linnnamnhkciekgpnegkcajcafmjlhgh" rel="noopener noreferrer"&gt;Chrome Web Store&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Edge:&lt;/strong&gt; &lt;a href="https://microsoftedge.microsoft.com/addons/detail/edbehlnmfcjhlbdlnmklicdoaopobbel" rel="noopener noreferrer"&gt;Edge Add-ons&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Firefox:&lt;/strong&gt; &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/gemtype-ai-writing-assistant/" rel="noopener noreferrer"&gt;Firefox Add-ons&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Source (Apache-2.0):&lt;/strong&gt; &lt;a href="https://github.com/riponcm/GemType" rel="noopener noreferrer"&gt;github.com/riponcm/GemType&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2-minute tutorial:&lt;/strong&gt;   &lt;iframe src="https://www.youtube.com/embed/j7Su-4hvigU"&gt;
  &lt;/iframe&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One more thing that only an open-source tool can offer: don't trust my privacy claims — paste the repo into ChatGPT/Claude/Gemini and ask it to audit where your text and key are sent. The answer should be "generativelanguage.googleapis.com and nowhere else."&lt;/p&gt;

&lt;p&gt;It's a solo project under my studio, &lt;a href="https://matily.org" rel="noopener noreferrer"&gt;Matily&lt;/a&gt;. Issues and PRs welcome — editor-compatibility reports are gold. And if it's useful, a GitHub star genuinely helps people find it.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Disclosure: I'm the author of GemType. It's an independent project, not affiliated with or endorsed by Grammarly, QuillBot, LanguageTool, or Google. "Grammarly" is a trademark of Grammarly, Inc.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>webdev</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
    <item>
      <title>🚀 Solo dev, months of work, launching today on Product Hunt.
projectmem — local memory + judgment layer for AI coding agents.
Open source. MIT. Free forever. 5 seconds of support means the world 🙏
https://producthunt.com/products/projectmem</title>
      <dc:creator>Ripon C Malo</dc:creator>
      <pubDate>Thu, 21 May 2026 16:28:06 +0000</pubDate>
      <link>https://dev.to/riponcm/solo-dev-months-of-work-launching-today-on-product-hunt-projectmem-local-memory-judgment-jo</link>
      <guid>https://dev.to/riponcm/solo-dev-months-of-work-launching-today-on-product-hunt-projectmem-local-memory-judgment-jo</guid>
      <description>&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
      &lt;div class="c-embed__body flex items-center justify-between"&gt;
        &lt;a href="https://producthunt.com/products/projectmem" rel="noopener noreferrer" class="c-link fw-bold flex items-center"&gt;
          &lt;span class="mr-2"&gt;producthunt.com&lt;/span&gt;
          

        &lt;/a&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>agents</category>
      <category>ai</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
    <item>
      <title>How I built projectmem — an MCP server that gives Claude, Cursor, and Codex persistent memory</title>
      <dc:creator>Ripon C Malo</dc:creator>
      <pubDate>Thu, 21 May 2026 02:30:29 +0000</pubDate>
      <link>https://dev.to/riponcm/how-i-built-projectmem-an-mcp-server-that-gives-claude-cursor-and-codex-persistent-memory-54b3</link>
      <guid>https://dev.to/riponcm/how-i-built-projectmem-an-mcp-server-that-gives-claude-cursor-and-codex-persistent-memory-54b3</guid>
      <description>&lt;p&gt;Few months back, my AI coding agent confidently suggested this fix:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.header-preview&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;contain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;layout&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;I'd tried that exact thing the previous Friday. It didn't work. The agent had no memory of the failure — different chat, fresh context, same dead-end.&lt;/p&gt;

&lt;p&gt;This happens every Monday. Across Claude, Cursor, Codex, Antigravity — agents are stateless between sessions. Each new conversation pays 5,000–20,000 tokens to rebuild context that existed yesterday. The model isn't broken; &lt;strong&gt;the architecture is.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;So I built &lt;code&gt;projectmem&lt;/code&gt;. This post walks through what it actually does — five killer features, a four-view D3 dashboard, the architecture, and the conda/venv hook bug that nearly shipped v0.1.3 broken. It's open source, MIT, runs 100% local, ships as a single &lt;code&gt;pip install&lt;/code&gt;.&lt;/p&gt;




&lt;h2&gt;
  
  
  What projectmem is, in 60 seconds
&lt;/h2&gt;

&lt;p&gt;A small Python package that does three things:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Captures development events&lt;/strong&gt; — bugs, fix attempts, fixes, decisions, gotchas — into plain-text JSONL inside your repo (&lt;code&gt;.projectmem/events.jsonl&lt;/code&gt;). You commit it. You can &lt;code&gt;git diff&lt;/code&gt; it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Exposes 14 MCP tools&lt;/strong&gt; so any MCP-capable AI client (Claude Desktop, Claude Code, Cursor, Antigravity, Codex) reads and writes that memory directly. One config block per client, works in all of them.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Runs git hooks&lt;/strong&gt; that warn you at commit time before you repeat a logged failed approach.&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;projectmem
pjm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's the install. &lt;code&gt;pjm init&lt;/code&gt; writes the memory directory, drops a &lt;code&gt;CLAUDE.md&lt;/code&gt; bridge file, installs the git hooks, pre-populates &lt;code&gt;PROJECT_MAP.md&lt;/code&gt; from your stack manifests, and prints a ready-to-paste MCP client config block. No cloud, no daemon, no telemetry.&lt;/p&gt;




&lt;h2&gt;
  
  
  The five killer features
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Pre-commit warnings (the differentiator)
&lt;/h3&gt;

&lt;p&gt;The git pre-commit hook checks your staged file against memory. If there's a logged failed approach on that file, it warns you before the commit lands.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;projectmem: Pre-Commit Check
────────────────────────────────────────────────────────────

  styles.css
    WARN  1 failed attempt on this file
           Last failure: tried contain: layout — preview still jumps
             (3 days ago)

────────────────────────────────────────────────────────────
1 warning(s). Review before committing.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Most "AI memory" tools are &lt;em&gt;retrieval engines&lt;/em&gt; — they store conversations and surface them when asked. projectmem is a &lt;em&gt;judgment layer&lt;/em&gt; — it captures events with explicit outcomes (&lt;code&gt;worked&lt;/code&gt; / &lt;code&gt;failed&lt;/code&gt; / &lt;code&gt;partial&lt;/code&gt;) and uses git context to interrupt you before you waste another afternoon. &lt;strong&gt;The pre-commit hook is the unlock.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Cross-project memory
&lt;/h3&gt;

&lt;p&gt;Lessons in one repo automatically surface in others on the same stack. Library gotchas, framework decisions, patterns you only had to learn once.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;~/.projectmem/global/
├── library_gotchas.jsonl
├── patterns.jsonl
└── .promotable.json    ← self-curating cache
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you &lt;code&gt;pjm init&lt;/code&gt; a new project, projectmem detects your stack from &lt;code&gt;pyproject.toml&lt;/code&gt; / &lt;code&gt;package.json&lt;/code&gt; / &lt;code&gt;Cargo.toml&lt;/code&gt; / &lt;code&gt;go.mod&lt;/code&gt; and injects relevant cross-project gotchas into &lt;code&gt;AI_INSTRUCTIONS.md&lt;/code&gt;. Stack-aware filtering, so a &lt;code&gt;vite&lt;/code&gt; project's mention of "next" doesn't pollute Next.js gotchas in your actual Next.js repos.&lt;/p&gt;

&lt;p&gt;100% local — &lt;code&gt;~/.projectmem/global/&lt;/code&gt; stays on your machine. No cloud sync, no account, no telemetry. A &lt;code&gt;gin&lt;/code&gt; gotcha you log in &lt;code&gt;proj-go&lt;/code&gt; shows up in your next Go repo. A &lt;code&gt;vite&lt;/code&gt; gotcha in &lt;code&gt;proj-react&lt;/code&gt; shows up in your next React repo.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Provable ROI (&lt;code&gt;pjm score&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;An A+ → F letter grade backed by concrete numbers. The first AI memory tool with metrics a CTO can verify.&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="nv"&gt;$ &lt;/span&gt;pjm score

projectmem Prevention Score: A- &lt;span class="o"&gt;(&lt;/span&gt;87/100&lt;span class="o"&gt;)&lt;/span&gt;
  Failed approaches on record: 8
  Decisions documented: 14
  Fixes with context: 12
  Debugging hours saved: ~12h
  Tokens saved: 47,500
  Estimated USD saved: &lt;span class="nv"&gt;$4&lt;/span&gt;.75
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output as terminal, JSON for CI (&lt;code&gt;pjm score --format json&lt;/code&gt;), or a shields.io badge for your README. Lets you put a number on the value the memory layer is actually producing — instead of a marketing claim.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Smart context injection (&lt;code&gt;pjm wrap&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Launches your AI agent with a token-budgeted context block already loaded — so the agent starts with your project memory inherited, instead of blank.&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="nv"&gt;$ &lt;/span&gt;pjm wrap claude &lt;span class="nt"&gt;--tokens&lt;/span&gt; 2000
&lt;span class="c"&gt;# launches Claude with a 2000-token context block of:&lt;/span&gt;
&lt;span class="c"&gt;# - your project summary&lt;/span&gt;
&lt;span class="c"&gt;# - recent decisions&lt;/span&gt;
&lt;span class="c"&gt;# - relevant cross-project gotchas&lt;/span&gt;
&lt;span class="c"&gt;# - any failed approaches on files you'll likely touch&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Works with Claude Code, Cursor (writes to &lt;code&gt;.cursorrules&lt;/code&gt;), Aider, and clipboard-paste for everything else. The AI session begins &lt;em&gt;experienced&lt;/em&gt;, not from zero.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Real-time file watcher (&lt;code&gt;pjm watch&lt;/code&gt;)
&lt;/h3&gt;

&lt;p&gt;Auto-starts on &lt;code&gt;pjm init&lt;/code&gt; in interactive terminals. Detects rapid edits to the same file (debugging sessions) and logs churn events automatically. Battery-aware, gitignore-aware. Catches what AI silently misses — the &lt;em&gt;between-commits&lt;/em&gt; iteration where most actual debugging happens.&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="nv"&gt;$ &lt;/span&gt;pjm watch &lt;span class="nt"&gt;--status&lt;/span&gt;
projectmem watcher: active &lt;span class="o"&gt;(&lt;/span&gt;PID 47891&lt;span class="o"&gt;)&lt;/span&gt;
  Watching: /Users/me/repos/your-project
  Events captured today: 12 churn, 3 commit
  Battery: AC power &lt;span class="o"&gt;(&lt;/span&gt;full speed&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  The visualization: four D3 dashboards from one command
&lt;/h2&gt;

&lt;p&gt;This is the part I think most projects skip and shouldn't.&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="nv"&gt;$ &lt;/span&gt;pjm visualize
&lt;span class="c"&gt;# opens localhost:8765 in your browser&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get an interactive D3 dashboard with four views, all auto-generated from your memory — &lt;strong&gt;zero extra AI tokens.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Story Map
&lt;/h3&gt;

&lt;p&gt;The complete narrative of your project — every decision, milestone, and failure visualized as an interactive force-directed graph. Failed files glow red in the heatmap. Drag nodes around. Zoom into problem areas. &lt;strong&gt;Your AI reads this to understand not just what your project is, but how it got here.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ROI Dashboard
&lt;/h3&gt;

&lt;p&gt;Live visualization of how much projectmem actually saves you. Animated counters for tokens prevented and USD protected. Capture-source donut showing manual vs auto-captured events. File churn heatmap surfacing your most-debugged files. Cumulative savings area chart over time.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture Map
&lt;/h3&gt;

&lt;p&gt;Toggle between a horizontal dendrogram (clean, hierarchical) and a force-directed graph (relationships, churn). Both auto-generated from &lt;code&gt;PROJECT_MAP.md&lt;/code&gt;. Zoom, pan, color-coded by folder.&lt;/p&gt;

&lt;h3&gt;
  
  
  Event Timeline
&lt;/h3&gt;

&lt;p&gt;Every event in your memory rendered chronologically — with &lt;code&gt;AUTO&lt;/code&gt; badges distinguishing auto-captured events from manual ones. Filter by Manual / Auto-captured / event type. Activity bar chart shows the rhythm of your project.&lt;/p&gt;

&lt;p&gt;The whole thing is one HTTP server, vanilla D3.js, no React, no framework. Loads instantly. The view your AI agent reads in &lt;code&gt;summary.md&lt;/code&gt; is the same view you can scrub through interactively when you open the dashboard.&lt;/p&gt;




&lt;h2&gt;
  
  
  The architecture (for the engineers in the room)
&lt;/h2&gt;

&lt;p&gt;Stack:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Python 3.10+&lt;/strong&gt;, ~600 LOC core&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependencies:&lt;/strong&gt; &lt;code&gt;mcp&lt;/code&gt;, &lt;code&gt;typer&lt;/code&gt;, &lt;code&gt;watchdog&lt;/code&gt;. That's it. No frameworks, no daemon, no port.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Storage:&lt;/strong&gt; append-only JSONL inside the repo, distilled into Markdown.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Transport:&lt;/strong&gt; stdio MCP. The AI client spawns the server as a subprocess; no network, no localhost binding, no process to babysit.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The 14 tools:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;get_instructions     get_summary        get_project_map
get_context          get_score          get_global_gotchas
get_issue            search_events      precheck_file
log_issue            record_attempt     record_fix
add_decision         add_note
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Every parameter has a Pydantic &lt;code&gt;Field(description=…)&lt;/code&gt; annotation, and where it matters, a schema-level constraint:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;record_attempt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;summary&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;One-line description of what you tried.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)],&lt;/span&gt;
    &lt;span class="n"&gt;outcome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Annotated&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;Field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;Result of the attempt.&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;pattern&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;^(worked|failed|partial)$&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;)]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;failed&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="bp"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The schema literally rejects &lt;code&gt;outcome="maybe"&lt;/code&gt; before the tool body runs. Cleanest way I've found to add real guardrails to LLM-generated tool calls.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why stdio, not HTTP
&lt;/h3&gt;

&lt;p&gt;agentmemory (the most-starred competitor) runs a Node daemon on three ports (3111 / 3112 / 3113) with a separate iii-engine binary and ~21,800 LOC. Excellent retrieval. Heavy install.&lt;/p&gt;

&lt;p&gt;projectmem stays stdio-only on purpose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No port to babysit&lt;/li&gt;
&lt;li&gt;No daemon to remember to start&lt;/li&gt;
&lt;li&gt;No conflict with existing infra&lt;/li&gt;
&lt;li&gt;The AI client manages the subprocess lifecycle for free&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tradeoff: no cross-process state. For single-developer-per-project workflows, that's not a real tradeoff — every benefit goes to "one less thing to debug."&lt;/p&gt;




&lt;h2&gt;
  
  
  The privacy guardrail
&lt;/h2&gt;

&lt;p&gt;projectmem stores event text verbatim in your repo. That's the whole point — the memory is plain text you can &lt;code&gt;git diff&lt;/code&gt;. The downside: a careless paste in an AI chat — &lt;em&gt;"the bug repros when I set &lt;code&gt;OPENAI_API_KEY=sk-...&lt;/code&gt;"&lt;/em&gt; — would otherwise land that key on disk.&lt;/p&gt;

&lt;p&gt;v0.1.3 closes that hole. Before any event hits disk, &lt;code&gt;storage.append_event&lt;/code&gt; runs a conservative pattern scrubber across the user-supplied text fields. Matches against high-confidence patterns get replaced with &lt;code&gt;[REDACTED:&amp;lt;kind&amp;gt;]&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Patterns: OpenAI sk-, GitHub PAT, AWS AKIA, Google AIza,
          Slack tokens, Stripe live/test keys, JWTs (eyJ...),
          Bearer tokens, PEM private-key blocks.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Patterns are intentionally narrow. Ordinary debugging prose — &lt;em&gt;"tried contain: layout"&lt;/em&gt;, &lt;em&gt;"forgot password reset flow"&lt;/em&gt; — is never touched. &lt;strong&gt;29 unit tests&lt;/strong&gt; pin both true-positive and false-positive behavior.&lt;/p&gt;

&lt;p&gt;Default-on. &lt;code&gt;PROJECTMEM_NO_REDACT=1&lt;/code&gt; opts out for the rare contexts where you genuinely want the raw text.&lt;/p&gt;

&lt;p&gt;Either it's there from day one or users learn not to trust the tool. v0.1.3 makes it day one.&lt;/p&gt;




&lt;h2&gt;
  
  
  How to try it
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;projectmem
&lt;span class="nb"&gt;cd &lt;/span&gt;your-project
pjm init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;pjm init&lt;/code&gt; ends by printing a ready-to-paste MCP config block (absolute &lt;code&gt;sys.executable&lt;/code&gt; baked in to dodge the Claude-Desktop / Cursor PATH-inheritance gotcha). Paste it into your client's config file:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Claude Desktop:&lt;/strong&gt; &lt;code&gt;~/Library/Application Support/Claude/claude_desktop_config.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cursor:&lt;/strong&gt; &lt;code&gt;~/.cursor/mcp.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Antigravity legacy IDE:&lt;/strong&gt; &lt;code&gt;~/.gemini/antigravity/mcp_config.json&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Codex&lt;/strong&gt; (TOML, not JSON): &lt;code&gt;~/.codex/config.toml&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Cold-start your client and the 14 projectmem tools appear in the MCP panel.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Links:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Repo: &lt;a href="https://github.com/riponcm/projectmem" rel="noopener noreferrer"&gt;https://github.com/riponcm/projectmem&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;60-second demo: &lt;a href="https://youtu.be/YCqfJ8-XVqY" rel="noopener noreferrer"&gt;https://youtu.be/YCqfJ8-XVqY&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Step-by-step tutorial: &lt;a href="https://github.com/riponcm/projectmem/blob/main/TUTORIAL.md" rel="noopener noreferrer"&gt;https://github.com/riponcm/projectmem/blob/main/TUTORIAL.md&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;PyPI: &lt;a href="https://pypi.org/project/projectmem" rel="noopener noreferrer"&gt;https://pypi.org/project/projectmem&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Official MCP Registry: &lt;a href="https://registry.modelcontextprotocol.io" rel="noopener noreferrer"&gt;https://registry.modelcontextprotocol.io&lt;/a&gt; (search &lt;code&gt;projectmem&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;The v0.2 roadmap:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Stale-memory detection&lt;/strong&gt; — flag, never delete. Cross-reference each decision's referenced file against recent git activity; surface decisions that predate heavy churn as "possibly stale, confirm or supersede."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Explicit &lt;code&gt;--supersedes&lt;/code&gt;&lt;/strong&gt; on &lt;code&gt;add_decision&lt;/code&gt; — the honest version of memory decay. Old decision retired with a back-reference; nothing destroyed; full audit trail.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Semantic search&lt;/strong&gt; as an opt-in extra (sentence-transformers + sqlite-vec). Default install stays dependency-light.&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Honest about the rough edges
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Search is exact substring today, not semantic&lt;/li&gt;
&lt;li&gt;API may still shift before 1.0&lt;/li&gt;
&lt;li&gt;The precheck heuristics are simple right now (file-name match → surface failed attempts)&lt;/li&gt;
&lt;li&gt;Recall benchmarks are unpublished (the equivalent for "judgment accuracy" hasn't been defined yet)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But: &lt;strong&gt;58 unit tests&lt;/strong&gt;, end-to-end verified across Claude Desktop / Claude Code / Cursor / Antigravity / Codex, the conda gotcha properly fixed, the privacy guardrail real and tested, the visualization dashboard genuinely useful.&lt;/p&gt;

&lt;p&gt;If you build with AI coding agents every day, try it once on a real project. The pre-commit hook usually catches its first real failure within the first week.&lt;/p&gt;

&lt;p&gt;What's the worst &lt;em&gt;"I already told you this last week"&lt;/em&gt; moment you've had with your AI agent? Reply below — that's exactly the pattern the precheck heuristics need to learn from.&lt;/p&gt;

&lt;p&gt;Thanks for reading.&lt;/p&gt;

&lt;p&gt;— Ripon&lt;/p&gt;

</description>
      <category>agents</category>
      <category>ai</category>
      <category>mcp</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
