<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Saket Anand on Medium]]></title>
        <description><![CDATA[Stories by Saket Anand on Medium]]></description>
        <link>https://medium.com/@saketananddotme?source=rss-9343932b9795------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*MuobZUnSQit3HvK-JIt5UA.jpeg</url>
            <title>Stories by Saket Anand on Medium</title>
            <link>https://medium.com/@saketananddotme?source=rss-9343932b9795------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 29 May 2026 18:19:19 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@saketananddotme/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[I Built a Package Manager for AI Skills — Because Context Window Bloat Was Killing My Productivity]]></title>
            <link>https://saketananddotme.medium.com/i-built-a-package-manager-for-ai-skills-because-context-window-bloat-was-killing-my-productivity-3b9889b7e61b?source=rss-9343932b9795------2</link>
            <guid isPermaLink="false">https://medium.com/p/3b9889b7e61b</guid>
            <category><![CDATA[ai]]></category>
            <category><![CDATA[mcps]]></category>
            <category><![CDATA[agentic-ai]]></category>
            <category><![CDATA[rules]]></category>
            <category><![CDATA[ai-skills]]></category>
            <dc:creator><![CDATA[Saket Anand]]></dc:creator>
            <pubDate>Fri, 22 May 2026 20:52:27 GMT</pubDate>
            <atom:updated>2026-05-22T20:52:27.501Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*msT2SAp8W7hkb6XwYCY3sw.jpeg" /><figcaption>Photo by <a href="https://unsplash.com/@johnmoeses?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">John Moeses Bauan</a> on <a href="https://unsplash.com/photos/a-cat-wearing-a-harness-sleeping-on-a-computer-desk-6mQLmJtLkEM?utm_source=unsplash&amp;utm_medium=referral&amp;utm_content=creditCopyText">Unsplash</a></figcaption></figure><p><em>The AI tooling ecosystem has a dependency problem. Here’s how I solved it.</em></p><p>If you use Cursor, Claude Code, or Codex seriously, you’ve probably done this: found a great collection of AI skills on GitHub, copied the files into your project, and congratulated yourself on a productivity upgrade.</p><p>Three weeks later, you open a new chat and wonder why the AI seems slower and vaguer than usual. You check the token count. Your context window is 60% full before you’ve typed a single word.</p><p>That was me. And it led me to build adt.</p><h3>The Problem with Vendoring AI Skills</h3><p>The standard advice for adding AI skills to your workflow is essentially “just copy the files.” Drop them in .cursor/rules/, or point Claude at a directory, and you’re done.</p><p>This works fine with five skills. It stops working when:</p><ul><li>You’re pulling from multiple upstream repos: Addy Osmani’s codebase safety rules, Matt Pocock’s shortcuts, Jesse Thorn’s superpowers…</li><li>Those repos keep updating, and your copies go stale.</li><li>You want to try a different set of skills for a different project.</li><li>You work at a company that maintains their internal skills.</li></ul><p>Every skill you vendor is loaded into context on every single chat. Most of the time, most of those skills are irrelevant to what you’re doing right now. You’re paying the context tax for all of them, all the time.</p><p>The deeper problem: there was no standard way to manage AI skills as dependencies. No install. No remove. No update. No list. Just cp -r.</p><h3>What I Built</h3><p>adt — AI Dev Toolkit — is an npm package that works like brew for AI tools.</p><pre>npm install -g @saketananddotme/adt<br>adt init</pre><p>That’s it. It detects your installed harnesses — Cursor, Claude Code, Codex — fetches a catalog of curated skill sources, and gets you set up in under a minute.</p><p>Then you install skills exactly how you’d install a package:</p><pre>adt install obra # 14 skills from obra/superpowers<br>adt install addy/spec-driven-development # just one specific skill<br>adt install myteam # your team&#39;s internal skills</pre><p>And remove them just as cleanly:</p><pre>adt remove obra<br>adt uninstall # removes everything adt ever created</pre><h3>How It Works Under the Hood</h3><h3>Sources, Not Copies</h3><p>Instead of copying skill files into your repo, adt clones the upstream Git repo into ~/.adt/sources/. It then creates individual symlinks from that clone into your harness directories: ~/.cursor/skills/, ~/.claude/skills/, and so on.</p><pre>~/.adt/sources/obra/skills/brainstorming/ ← actual files<br>~/.cursor/skills/brainstorming ← symlink<br>~/.claude/skills/brainstorming ← symlink</pre><p>The skills appear exactly where each AI tool expects them. Updating is just a git pull on the source — no manual copying ever again.</p><pre>adt source update obra # pulls latest from upstream<br>adt update # updates all sources</pre><h3>The Manifest</h3><p>The thing I’m most careful about: adt never touches files it didn’t create.</p><p>Every symlink is recorded in ~/.adt/.manifest.json. When you run adt remove or adt uninstall, it only removes entries from that manifest. Your own rules and skills are never at risk.</p><p>This was the failure mode of the alias approach I tried first:</p><pre># This DELETES your entire .cursor/rules directory<br>alias ai-addy=&quot;ln -sfn ~/.claude/skills/addyosmani/agent-skills .cursor/rules&quot;</pre><p>ln -sfn on a directory replaces the entire target. I learned this the hard way. The manifest-based approach means adt remove obra removes exactly the 17 things it installed, nothing else.</p><h3>Auto-Discovery</h3><p>adt doesn’t require any special configuration in your skill repo. It just looks for familiar conventions:</p><pre>your-skills/<br>├── skills/    # dirs containing SKILL.md<br>├── agents/    # .md files<br>├── rules/     # .mdc files (Cursor only)<br>├── hooks/     # hook scripts<br>└── CLAUDE.md  # inserted as a marker block in ~/.claude/CLAUDE.md</pre><p>Run adt source add yourname https://github.com/you/skills.git, and it clones, scans, and tells you what it found.</p><h3>CLAUDE.md Without Clobbering</h3><p>One tricky piece: Claude Code reads a ~/.claude/CLAUDE.md file as persistent memory. Multiple skill sources may all want to contribute to it. adt handles this with marker blocks:</p><pre>&lt;!-- ADT:obra:START --&gt;<br>…obra&#39;s CLAUDE.md content…<br>&lt;!-- ADT:obra:END --&gt;</pre><p>Each source gets its own block. Removing a source removes its block. If you manually edit inside a block, adt detects the change and asks before overwriting.</p><h3>The Repo Split</h3><p>Part of building this was realizing the original repo was trying to be too many things at once: the CLI tool, my personal skills, upstream skills from other people, all vendored together.</p><p>I split it into three:</p><p>RepoPurposesaketananddotme/ai-dev-toolkitThe adt CLI — 48KB, no dependenciessaketananddotme/ai-skillsMy personal skills, agents, and rulessaketananddotme/adt-catalogRemote catalog of curated sources</p><p>The CLI ships lean. Your skills live in your own repo, versioned separately. The catalog is community-maintained.</p><h3>Try It</h3><pre>npm install -g @saketananddotme/adt<br>adt init<br>adt install obra<br>adt list --installed</pre><p>Built-in sources to try:</p><ul><li>obra — <a href="https://github.com/obra/superpowers">obra/superpowers</a></li><li>: rapid prototyping and agentic workflows</li><li>addy — <a href="https://github.com/addyosmani/agent-skills">addyosmani/agent-skills</a></li><li>: codebase safety</li><li>matt — <a href="https://github.com/mattpocock/skills">mattpocock/skills</a></li><li>: daily debugging shortcuts</li></ul><p>To add your own team’s skills:</p><pre>adt source add myteam https://github.com/myteam/ai-skills.git<br>adt install myteam</pre><p>The catalog is open for contributions at <a href="https://github.com/saketananddotme/adt-catalog">saketananddotme/adt-catalog</a></p><p>. If you maintain a skill collection worth sharing, open a PR.</p><p><em>The code is at</em> <a href="https://github.com/saketananddotme/ai-dev-toolkit"><em>github.com/saketananddotme/ai-dev-toolkit</em></a><em>. Zero runtime dependencies, pure Node stdlib, ~650 lines.</em></p><p>Tags: AI, Developer Tools, Productivity, Claude, Cursor</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3b9889b7e61b" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How Cursor Works Under The Hood, Understands Your Code (and Why It Feels Like Magic)]]></title>
            <link>https://saketananddotme.medium.com/how-cursor-really-understands-your-code-and-why-it-feels-like-magic-21b6bc447c1d?source=rss-9343932b9795------2</link>
            <guid isPermaLink="false">https://medium.com/p/21b6bc447c1d</guid>
            <category><![CDATA[rags]]></category>
            <category><![CDATA[ai-tools]]></category>
            <category><![CDATA[cursor-ide]]></category>
            <category><![CDATA[cursor]]></category>
            <category><![CDATA[ai]]></category>
            <dc:creator><![CDATA[Saket Anand]]></dc:creator>
            <pubDate>Fri, 06 Feb 2026 10:32:50 GMT</pubDate>
            <atom:updated>2026-02-07T06:48:20.635Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*wipjUk7UALFM2weI" /><figcaption>Photo by <a href="https://unsplash.com/@almoya?utm_source=medium&amp;utm_medium=referral">Aerps.com</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3>How Cursor Works Under The Hood, Really Understands Your Code (and Why It Feels Like Magic)</h3><p>If you’ve used Cursor for more than a few days, you’ve probably felt it.</p><ul><li>You ask <strong>“Where is auth handled?”<br></strong>→ Cursor jumps straight to the right files.</li><li>You ask <strong>“Show all usages of OrdersService”<br></strong>→ It understands intent, not just text.</li></ul><p>This isn’t autocomplete.<br>It isn’t just grep.</p><p>It’s <strong>Retrieval-Augmented Generation (RAG)</strong>, built specifically for code.</p><ul><li><strong>RAG in one line:<br></strong>Retrieve relevant chunks → add them to the prompt → generate the answer.<br>The model never sees the whole repo, only what matters.</li></ul><h3>The Problem Cursor Is Solving</h3><ul><li>Large repositories do <strong>not</strong> fit into an AI’s context window.</li><li>Even the biggest models can’t read:<br>• an entire monorepo<br>• all services<br>• configs<br>• docs</li><li>Trying to dump everything into context makes answers worse:<br>• attention spreads thin<br>• important details get lost in the middle<br>• responses become vague or incorrect</li></ul><p>Cursor avoids this entirely.</p><ul><li>Instead of asking <em>“How do I show everything?”</em></li><li>It asks:<br><strong>“What small pieces of this codebase matter right now?”</strong></li></ul><h3>Step 1: Watching Your Code Without Uploading It</h3><p>When you open a workspace, Cursor <strong>does not upload your codebase</strong>.</p><p>What it does instead:</p><ul><li>Builds a <strong>Merkle tree</strong> locally</li><li>Every file gets a hash</li><li>Every folder hash depends on its children</li><li>Change one file → only one branch changes</li></ul><p>This lets Cursor:</p><ul><li>detect exactly what changed</li><li>sync only those changes</li><li>avoid reprocessing the whole repo</li></ul><p>Practical impact:</p><ul><li>In a 50,000-file repo, editing one file might sync only a few KB</li><li>Your code stays local</li><li>Sync stays fast</li></ul><h3>Step 2: Chunking Code the Right Way</h3><p>Cursor does <strong>not</strong> split code by token count.</p><p>Instead:</p><ul><li>Uses <strong>tree-sitter</strong>, a real parser</li><li>Understands syntax and structure</li></ul><p>Chunks are:</p><ul><li>one function</li><li>one class</li><li>one logical block</li></ul><p>Why this matters:</p><ul><li>Embeddings work better on <strong>meaningful units</strong></li><li>Functions describe intent</li><li>Random text slices don’t</li></ul><p>Edge cases:</p><ul><li>Very large or complex files may be skipped or partially indexed</li><li>Tree-sitter can struggle with very large files (~32KB in some environments), so those get different handling</li></ul><h3>Step 3: Turning Code Into Meaning (Embeddings)</h3><p>Each chunk becomes a <strong>vector embedding</strong> — numbers that represent meaning.</p><p>Important detail:</p><ul><li>This is <strong>not</strong> a generic text embedding</li><li>Cursor trains its own <strong>code-specific embedding model</strong></li></ul><p>How it’s trained:</p><ul><li>Uses real agent sessions</li><li>What people searched</li><li>What files they opened</li><li>What actually helped solve the task</li><li>An LLM ranks “what would have been most helpful”</li><li>The embedding model learns from those rankings</li></ul><p>Result:</p><ul><li>Cursor learns how developers <em>actually</em> explore code</li><li>Not just theoretical similarity</li></ul><p>Efficiency:</p><ul><li>If a chunk hasn’t changed, the embedding is reused</li><li>No wasted compute</li></ul><h3>Step 4: Privacy by Design</h3><p>Before anything leaves your machine:</p><ul><li>File paths are <strong>obfuscated</strong></li><li>Directory structure is preserved, names are hidden</li><li>Source code is <strong>never stored</strong> on Cursor servers</li></ul><p>What is stored:</p><ul><li>embeddings</li><li>metadata (encrypted paths, line ranges)</li></ul><p>Even if someone accessed the vector DB:</p><ul><li>They would not see your code</li></ul><h3>Step 5: Where the Vectors Live (Turbopuffer)</h3><p>Cursor stores embeddings in <strong>Turbopuffer</strong>, a high-throughput vector database.</p><p>Key ideas:</p><ul><li>Each (user_id, codebase) has its own <strong>namespace</strong></li><li>Active namespaces:<br>- live in RAM / NVMe<br>- fast (single-digit ms)</li><li>Inactive namespaces:<br>- move to object storage<br>- cheap, slightly slower when reactivated</li></ul><p>Result:</p><ul><li>Your current repo feels instant</li><li>Old repos don’t waste memory</li></ul><h3>Index reuse with simhash</h3><p>When two people in the same org open the same repo:</p><ul><li>Cursor computes a <strong>simhash</strong> from the Merkle tree</li><li>Finds a teammate’s existing index</li><li>Reuses embeddings instead of recomputing</li></ul><p>Numbers that matter:</p><ul><li>Codebases in the same org are ~<strong>92% similar</strong></li><li>Time-to-first-query on large repos:<br>• from <strong>4+ hours<br></strong>• down to <strong>~21 seconds</strong></li></ul><p>Privacy preserved:</p><ul><li>Client uploads its Merkle tree</li><li>Server only returns results for code you actually have</li><li>No cross-user leakage</li></ul><p>Summary:</p><ul><li>Same code → same embeddings</li><li>Different users → isolated namespaces</li></ul><h3>Step 6: When You Ask a Question</h3><p>When you type:</p><p><strong>“Where is user authentication handled?”</strong></p><p>Cursor does all of this:</p><ul><li>Converts your question into an embedding</li><li>Searches for similar code chunks</li><li>Runs grep for exact matches</li><li>Pulls in:<br>• open files<br>• semantic chunks<br>• symbolic connections<br>• lint<br>• git history<br>• docs<br>• typing history</li></ul><p>Total candidate context:</p><ul><li>Up to <strong>~500k tokens</strong></li></ul><h3>Hybrid search (why it feels precise)</h3><p>Cursor uses both:</p><ul><li><strong>Semantic search<br></strong>for intent (“where is auth handled?”)</li><li><strong>Grep<br></strong>for exact matches (“OrdersService”)</li></ul><p>The agent:</p><ul><li>chooses which to use</li><li>often combines them</li></ul><p>This hybrid approach is a big reason Cursor feels so accurate.</p><h3>Step 7: The Reranker (The Real Brain)</h3><p>Cursor can’t send 500k tokens to an LLM.</p><p>So it uses a <strong>custom reranker</strong>:</p><ul><li>Scores all candidate context</li><li>Filters it down to the most relevant <strong>~8k tokens</strong></li><li>Selects, not compresses</li></ul><p>Important:</p><ul><li>Context selection is still an open research problem</li><li>Cursor keeps improving this layer</li></ul><h3>Step 8: Final Answer Generation</h3><p>Only now does the LLM step in.</p><p>What it sees:</p><ul><li>just the right parts of your codebase</li><li>not too much</li><li>not too little</li></ul><p>That’s why Cursor:</p><ul><li>explains existing code well</li><li>answers “how does this work?” clearly</li><li>scales to very large repositories</li></ul><h3>Why You Can’t “Doc the Whole Repo” in One Shot</h3><p>Common request:</p><ul><li>“Generate documentation for the entire repo”</li></ul><p>Why this fails:</p><ul><li>Context windows are finite</li><li>Attention weakens as context grows</li><li>Content in the middle gets ignored (“lost in the middle”)</li></ul><p>Cursor avoids this by design:</p><ul><li>No single giant context</li><li>Retrieval happens per question, per moment</li></ul><p>That’s why it works.</p><h3>Known Limitations</h3><p>Cursor isn’t magic.</p><p>Things to know:</p><ul><li>Index refresh is about <strong>5 minutes</strong></li><li>Recent edits may not be searchable yet</li><li>Unsaved buffer edits aren’t indexed<br>→ <strong>Pro tip:</strong> save before asking, or use @ filename</li><li>Query latency depends on cache:<br>• warm: <strong>~8–10ms<br></strong>• cold: <strong>~500–600ms</strong></li><li>Generic queries can surface generic utility code</li><li>Large or auto-generated files may be skipped</li><li>Retrieval quality depends heavily on .cursorignore</li></ul><p>Still, Cursor’s A/B tests show:</p><ul><li><strong>~12.5%</strong> higher accuracy on code questions</li><li><strong>~2.6%</strong> better retention on large codebases (1,000+ files)</li><li><strong>~2.2%</strong> fewer dissatisfied follow-ups</li></ul><p>The gains are modest overall — but much larger where it matters: <strong>big repos</strong>.</p><h3>Why This Feels So Good for Vibe Coding</h3><p>Cursor doesn’t just search code.</p><p>It matches how developers think:</p><ul><li>jump between files</li><li>follow call chains</li><li>skim instead of reading everything</li><li>ask fuzzy questions</li></ul><p>It’s less like grep.</p><p>More like a very fast teammate who’s already explored the repo.</p><h3>Learn to Use Cursor Better for Vibe Coding</h3><p>In the next post, I’ll focus less on how Cursor works and more on how to <em>use it well</em>: prompts that work, common mistakes, and workflows that actually speed you up.</p><p>Follow if that sounds useful.</p><p>About Me: <a href="https://www.saketanand.me/">https://www.saketanand.me/</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=21b6bc447c1d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How I Automated My Terminal Setup with One Command (And You Can Too)]]></title>
            <link>https://saketananddotme.medium.com/how-i-automated-my-terminal-setup-with-one-command-and-you-can-too-d81f265f932d?source=rss-9343932b9795------2</link>
            <guid isPermaLink="false">https://medium.com/p/d81f265f932d</guid>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[productivity]]></category>
            <category><![CDATA[automation]]></category>
            <category><![CDATA[terminal]]></category>
            <category><![CDATA[zsh]]></category>
            <dc:creator><![CDATA[Saket Anand]]></dc:creator>
            <pubDate>Thu, 29 Jan 2026 11:01:03 GMT</pubDate>
            <atom:updated>2026-02-06T11:46:47.401Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Gf7tXOxZL76AMpp7OXos3w.png" /></figure><p>If you’re new to development, this might surprise you: developers spend a <strong>huge amount of time</strong> inside the terminal. If you’re a veteran, you already know the struggle 😄.</p><p>The terminal is our daily workbench. It’s where we run code, manage projects, install tools, and debug complex problems. But there is a recurring “tax” we all pay: <strong>The Setup.</strong></p><p>Every time you get a new laptop or change your system, you have to set up the terminal all over again. It’s slow, boring, and repetitive.</p><h3>The Problem: Manual Setup is Tedious (Especially for Beginners)</h3><p>If you Google “best terminal setup,” you usually end up down a rabbit hole of manual steps:</p><ul><li>Installing <strong>Zsh</strong></li><li>Installing <strong>Oh My Zsh</strong></li><li>Finding a theme (like Powerlevel10k)</li><li>Manually cloning plugins for suggestions and highlighting</li><li>Editing hidden files like .zshrc (which is honestly scary the first time)</li></ul><p>For beginners, this is confusing. For experienced developers, it’s just <strong>wasted time.</strong> Either way, it’s not how you want to spend your afternoon.</p><h3>The Idea: One-Command Bootstrap</h3><p>I wanted a world where I could open a fresh terminal, run <strong>one command</strong>, and have everything ready to go. No searching, no manual cloning, no mistakes.</p><p>That’s why I created <a href="https://github.com/saketananddotme/awesome-terminal"><strong>awesome-terminal</strong></a>.</p><p>Now, I can go from a boring default terminal to a clean, powerful, and informative setup in <strong>seconds.</strong></p><h3>What’s Under the Hood?</h3><p>The script doesn’t just “beautify” the shell; it adds intelligence to it. Here is what you get:</p><h3>🧠 Oh My Zsh</h3><p>The industry-standard framework that makes managing your Zsh configuration easy.</p><h3>🎨 Powerlevel10k</h3><p>The fastest and most flexible terminal theme available. It shows you exactly what you need — like your current Git branch or execution time — without any lag.</p><h3>⚡ Productivity Plugins</h3><ul><li><strong>zsh-autosuggestions:</strong> Predicts your next command based on your history (huge time saver!).</li><li><strong>zsh-syntax-highlighting:</strong> Colors your commands so you spot typos before you hit Enter.</li><li><strong>you-should-use:</strong> A “coach” that reminds you of better aliases while you work.</li></ul><h3>🎛 The “Choice” Factor</h3><p>During the setup, the script gives you a choice:</p><ol><li><strong>The Saket Setup:</strong> Use my pre-configured, ready-to-go layout.</li><li><strong>The Fresh Start:</strong> Skip my config and let the Powerlevel10k wizard guide you through your own custom look.</li></ol><h3>How to Use It (Super Simple)</h3><p>You don’t need to download anything manually. Just copy and paste this command into your terminal:</p><p>Bash</p><pre>sh -c &quot;$(curl -fsSL https://raw.githubusercontent.com/saketananddotme/awesome-terminal/main/setup.sh)&quot;</pre><p><strong>That’s it. The script handles the rest.</strong></p><h3>Built for Developers, Not Just for Me</h3><p>This project isn’t meant to be “my way or the highway.” It’s designed so you can <strong>own</strong> it.</p><h3>Customize It (The Developer Way)</h3><ol><li><strong>Fork the Repo:</strong> Go to the <a href="https://github.com/saketananddotme/awesome-terminal">GitHub repo</a> and click <strong>Fork</strong>. Now you have your own version.</li><li><strong>Add Your Own Config:</strong> If you have a custom .p10k.zsh or favorite aliases, upload them to your repo and update the CONFIG_URL in setup.sh.</li><li><strong>Change Plugins:</strong> Want docker, kubectl, or terraform support? Just edit the plugins=(...) line in the script.</li></ol><h3>Your Environment is Now “Cloud-Native”</h3><p>Once it’s in your GitHub repo, your terminal setup is portable. Any laptop, any machine — one command and you’re home.</p><h3>Why This Matters</h3><p>As developers, we automate builds, tests, and deployments. We should also automate our environment. Forking and owning your setup lets you:</p><ul><li>Keep your terminal config in <strong>Version Control</strong>.</li><li>Share a <strong>standardized setup</strong> with your team.</li><li><strong>Experiment safely</strong> and roll back if something breaks.</li></ul><blockquote><strong><em>Your environment should be reproducible, just like your code.</em></strong></blockquote><h3>Final Thoughts</h3><p>As engineers, we should always look for ways to automate repetitive tasks. Setting up your environment shouldn’t be a chore.</p><p>Feel free to check out the repo, star it if it helps you, or even contribute to make it better!</p><p><strong>Check out the project here:</strong> <a href="https://github.com/saketananddotme/awesome-terminal">https://github.com/saketananddotme/awesome-terminal</a></p><p>If this helps you save time, feel free to ⭐ the repo!</p><p><strong>Tags:</strong> Software Development, Productivity, Automation, Zsh, and Coding.</p><p>About Me: <a href="https://www.saketanand.me/">https://www.saketanand.me/</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d81f265f932d" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Setup Husky Prettier & ES Lint?]]></title>
            <link>https://saketananddotme.medium.com/how-to-setup-husky-prettier-es-lint-0d5e072f8c10?source=rss-9343932b9795------2</link>
            <guid isPermaLink="false">https://medium.com/p/0d5e072f8c10</guid>
            <category><![CDATA[prettier]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[coding]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Saket Anand]]></dc:creator>
            <pubDate>Sat, 16 Mar 2024 06:18:48 GMT</pubDate>
            <atom:updated>2026-02-06T11:47:17.027Z</atom:updated>
            <content:encoded><![CDATA[<p>When working on a project with a team, maintaining code quality and consistency becomes paramount. Tools like ESLint, Prettier, and Husky, along with lint-staged, play a crucial role in automating and enforcing coding standards across the codebase. This blog post will guide you through setting up these tools to ensure your project’s code is clean, formatted correctly, and free of linting errors before it even reaches your repository.</p><h4>Why Use ESLint, Prettier, Husky, and lint-staged?</h4><p><strong>ESLint</strong> is a static code analysis tool that identifies problematic patterns in JavaScript code. It helps maintain code quality and enforce coding standards by highlighting syntax and style issues.</p><p><strong>Prettier</strong> is an opinionated code formatter that supports many languages and integrates with most editors. It removes all original styling and ensures that all outputted code conforms to a consistent style.</p><p><strong>Husky</strong> makes dealing with Git hooks easy. Git hooks are scripts that run automatically every time a particular event occurs in a Git repository. Husky allows you to use these hooks to run scripts before committing or pushing code, ensuring that your codebase remains error-free and adheres to your coding standards.</p><p><strong>lint-staged</strong> runs linters on staged git files. This tool is beneficial in projects where you want to ensure that only files that are part of the commit are linted and formatted, making the commit process faster and more efficient.</p><h4>Setting Up the Environment</h4><p><strong>Installation</strong>: Start by installing Husky, Prettier, ESLint, and lint-staged as development dependencies in your project. This ensures that these tools are available to everyone working on the project without needing global installation.</p><p>Husky is for git pre hooks (Hooks are something which runs on event)</p><blockquote>npm install husky prettier eslint lint-staged — save-dev</blockquote><p>Initialise ESLint and husky</p><blockquote>npx eslint — init<br> npx husky install</blockquote><p>### Package JSON</p><p>Make sure this is present in your `package.json`</p><blockquote>”scripts”: { “prepare”: “husky install” }</blockquote><p>Configure Prettier to format your staged file</p><blockquote>“lint-staged”: {<br> “*.{js,jsx}”: [<br> “prettier — write”,<br> “eslint — fix”,<br> “git add”<br> ],<br> “*.{html,css,less,ejs}”: [<br> “prettier — write”,<br> “git add”<br> ]<br>}</blockquote><h4>ESLint Config</h4><p>Create a file named `.eslintrc.js` in your root folder</p><blockquote>module.exports = { <br> parser: ‘<a href="http://twitter.com/typescript">@typescript</a>-eslint/parser’, <br> parserOptions: { <br> project: ‘tsconfig.json’, <br> tsconfigRootDir: __dirname, <br> sourceType: ‘module’, <br> }, <br> plugins: [‘<a href="http://twitter.com/typescript">@typescript</a>-eslint/eslint-plugin’], <br> extends: [ <br> ‘plugin:<a href="http://twitter.com/typescript">@typescript</a>-eslint/recommended’, <br> ‘plugin:prettier/recommended’, <br> ], <br> root: true, <br> env: { <br> node: true, <br> jest: true, <br> }, <br> ignorePatterns: [‘.eslintrc.js’], <br> rules: { <br> ‘<a href="http://twitter.com/typescript">@typescript</a>-eslint/interface-name-prefix’: ‘off’, <br> ‘<a href="http://twitter.com/typescript">@typescript</a>-eslint/explicit-function-return-type’: ‘off’, <br> ‘<a href="http://twitter.com/typescript">@typescript</a>-eslint/explicit-module-boundary-types’: ‘off’, <br> ‘<a href="http://twitter.com/typescript">@typescript</a>-eslint/no-explicit-any’: ‘off’, <br> }, <br> };</blockquote><h4>Prettier Config</h4><p>Create a filename `.prettierrc` in your root directory</p><blockquote>{ <br> “singleQuote”: true, <br> “trailingComma”: “all” <br>}</blockquote><h4>Initialise Husky</h4><p>If you haven’t already, you need to initialise Husky in your project. This step is crucial because it sets up the necessary Git hooks in the `.husky/` directory. Depending on your Husky version, the command might differ. For Husky v4, the setup is included in the `package.json`. For Husky v5 and above, you need to run an initialisation command:</p><p>`npx husky install`</p><h4>Setting Up Hooks with Newer Versions of Husky</h4><p>If you’re using Husky v5 or above, the way to add hooks has changed from the configuration in `package.json` to creating hook files in the `.husky/` directory. For example, to add a `pre-push` hook, you would:</p><p>`npx husky add .husky/pre-push “npm test”`</p><p>or</p><p>`npx husky add .husky/pre-commit “npx lint-staged”`</p><p><strong>You may choose to edit these files and add your new commands on a separate line</strong></p><h4>Ensure the Git Hooks are Executable</h4><p>Make sure that the hook scripts in the `.husky/` directory are executable. You can change the permission of the hook scripts using the `chmod` command:</p><p>`chmod +x .husky/*`</p><p>Husky hooks might not run if there’s a local Git configuration overriding the hook path. You can check your current Git configuration for the `core.hooksPath` setting by running:</p><p>`git config — get core.hooksPath`</p><h4>Benefits of This Setup</h4><p>- <strong>Code Quality</strong>: Automatically ensures that your codebase adheres to defined coding standards and styles, reducing the time spent on code reviews.<br>- <strong>Efficiency</strong>: Catches and fixes errors early in the development process, significantly reducing the time and effort required for debugging and testing.<br>- <strong>Consistency</strong>: Enforces a consistent coding style across the entire codebase, making it easier to read and maintain.<br>- <strong>Automation</strong>: Automates repetitive tasks, allowing developers to focus on writing code rather than fixing styling or formatting issues.</p><p>By integrating ESLint, Prettier, Husky, and lint-staged into your development workflow, you create a robust environment that promotes writing high-quality code. This setup not only enhances productivity but also fosters a culture of collaboration and continuous improvement among development teams.</p><p>About Me: <a href="https://www.saketanand.me/">https://www.saketanand.me/</a></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=0d5e072f8c10" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Charges explained about metal credit card by OneCard / OneScore / FPL Technologies.]]></title>
            <link>https://saketananddotme.medium.com/charges-explained-about-metal-credit-card-by-onecard-onescore-fpl-technologies-3002e69a4a11?source=rss-9343932b9795------2</link>
            <guid isPermaLink="false">https://medium.com/p/3002e69a4a11</guid>
            <category><![CDATA[credit-cards]]></category>
            <category><![CDATA[indian-bank]]></category>
            <category><![CDATA[credit-repair]]></category>
            <category><![CDATA[personal-finance]]></category>
            <category><![CDATA[credit-score]]></category>
            <dc:creator><![CDATA[Saket Anand]]></dc:creator>
            <pubDate>Sun, 25 Sep 2022 10:37:12 GMT</pubDate>
            <atom:updated>2022-09-25T10:37:12.358Z</atom:updated>
            <content:encoded><![CDATA[<h3>Charges explained about metal credit card by OneCard / OneScore / FPL Technologies. Should you take one?</h3><p>The One Card looks very attractive in the beginning but owing this is only results in financial loss and mental pressure. It is based on a concept. “Let people do something and we snatch their money”</p><p>In this post I will only explain charges of OneCard for the activity people mostly do in regular life. I am writing other blogs to make people aware of this company.</p><p>The joining fees for the metal card is FREE as they know that people will not pay 3000 for just a metal card.</p><p>Once you open an Credit card account with OneCard / OneScore, You can close the card by paying a total of 3000 + GST ( Approx 3500) within 6 months</p><p>If you ever lost this card, OneCard cost you around 3000 + GST (Approx 3500) to get a new card delivered to your home.</p><p>For <strong>EMI Transactions</strong>: Interest Rate is <strong>29% annual </strong>on a reducing basis which is equivalent to 1.33 percent flat per month. They charge you <strong>1% processing fees</strong> apart from interest and if you want to close your EMI loan then there is a <strong>3% of foreclosure charge</strong>.</p><p>There is one more catch in EMI Transaction. Suppose, You purchased a iPhone latest model around 1 lac on Amazon/Flipkart with Metal OneCard / One Score Card on EMI. And after placing the order your mood changed and you wanted to cancel the order for any reason. Everyone knows that the Flipkart/Amazon doesn’t charge cancellation fee. But this <strong>Metal</strong> <strong>OneCard</strong> will charge you interest for 1 month around 1333 + 1% processing fee i.e 1000 rupees + GST which totals to be around Rs.3000.</p><p>When you will experience these you will try to close the card and then they will collect 3500 rupees for closure.</p><p>Credit card itself is money making product for banks, so a person should avoid using it unless very necessary. Still if you want to get a credit card, choose any bank like HDFC or ICICI. As per my knowledge ICICI also offers credit card on FD.</p><p>Be wise and avoid OneCard / OneScore / FPL Technologies as much as possible.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=3002e69a4a11" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to start programming / coding?]]></title>
            <link>https://saketananddotme.medium.com/how-to-start-programming-coding-a6806a28e699?source=rss-9343932b9795------2</link>
            <guid isPermaLink="false">https://medium.com/p/a6806a28e699</guid>
            <category><![CDATA[start]]></category>
            <category><![CDATA[programming]]></category>
            <dc:creator><![CDATA[Saket Anand]]></dc:creator>
            <pubDate>Tue, 28 May 2019 19:47:34 GMT</pubDate>
            <atom:updated>2019-05-28T20:15:15.708Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IwREW0P3iN8bCvq_th6Prw.png" /></figure><p>Where there’s a will there’s a way. The only thing you need to start programming is determination (and of course PC with Internet Connection). Every expert was once a beginner. The direction you go in will depend in large part on why you want to learn to code in the first place and how much time you have to devote to learning.</p><p>There is no one “best” programming language. If you are a beginner, you may start with Python as it is very easy to learn and also it is in high demand in market. Start with any good online video tutorial. I would suggest you to go with NPTEL (A project funded by MHRD. Govt of India). I have attached the link below.</p><p><a href="https://nptel.ac.in/courses/106106182/">NPTEL :: Computer Science and Engineering - NOC:The Joy of Computing using Python</a></p><p>After taking the tutorial, start reading the python docs. Go through <a href="https://docs.python.org/3/tutorial/index.html">https://docs.python.org/3/tutorial/index.html</a>, if you want to dig deeper into the language read <a href="https://docs.python.org/3/library/index.html">Library Reference</a> and <a href="https://docs.python.org/3/reference/index.html">Language Reference</a> respectively. These docs are going to help you a lot in polishing your skills.<br>Programming is not something you watch, read and learn, so you have to practice a lot. Start with writing small programs, Get some example question here.</p><p><a href="https://www.programiz.com/python-programming/examples">Python Examples</a></p><p>Congratulations you have successfully written, compiled and run some programs, and this is called procedural / functional programming. You may want to learn intermediate concepts like Object Oriented Programming, Design Patterns etc. Python is in high demand now a days, It has various scope. If you are interested in website / web application you can start learning frameworks like Django, Flask, Pyramid, Bottle and Cherrypy. Or you may start courses on Machine Learning, Artificial Intelligence or Internet of Things.</p><p>You are about to become a programmer. And I promise you are going to love your skills. Your age doesn’t matter, your previous qualification doesn’t matter. Start learning today and I am always open to help you grow. If you need any guidance or support you can get my contact from the given link.</p><p><a href="http://saketanand.com/">Official Website of Saket Anand</a></p><p>Thanks for spending your time to read this article. Good Luck.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a6806a28e699" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>