<?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: Rohit Madas</title>
    <description>The latest articles on DEV Community by Rohit Madas (@rohit_madas_81dc4f9256f28).</description>
    <link>https://dev.to/rohit_madas_81dc4f9256f28</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3389257%2Fadbfba4f-058c-4d38-a2db-55ebb1254b5d.jpg</url>
      <title>DEV Community: Rohit Madas</title>
      <link>https://dev.to/rohit_madas_81dc4f9256f28</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rohit_madas_81dc4f9256f28"/>
    <language>en</language>
    <item>
      <title>I built an open source context layer for AI coding tools — here's how it works</title>
      <dc:creator>Rohit Madas</dc:creator>
      <pubDate>Sun, 15 Mar 2026 04:55:06 +0000</pubDate>
      <link>https://dev.to/rohit_madas_81dc4f9256f28/i-built-an-open-source-context-layer-for-ai-coding-tools-heres-how-it-works-44ii</link>
      <guid>https://dev.to/rohit_madas_81dc4f9256f28/i-built-an-open-source-context-layer-for-ai-coding-tools-heres-how-it-works-44ii</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffjonc08r7gndmqn3a4om.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffjonc08r7gndmqn3a4om.png" alt=" " width="800" height="424"&gt;&lt;/a&gt;## The problem&lt;/p&gt;

&lt;p&gt;Every AI coding session starts blank.&lt;/p&gt;

&lt;p&gt;You open Cursor or Claude Code and before you can ask anything &lt;br&gt;
useful, you spend five minutes re-explaining your project. Same &lt;br&gt;
stack. Same goals. Same conventions. Every time.&lt;/p&gt;

&lt;p&gt;I built ctxpilot to fix this permanently.&lt;/p&gt;

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

&lt;p&gt;ctxpilot is a CLI tool and MCP server that:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Scans your codebase with AI and builds a Living Context Document&lt;/li&gt;
&lt;li&gt;Injects that document into Cursor, Claude Code, Codex, and Windsurf via MCP&lt;/li&gt;
&lt;li&gt;Auto-updates the document after every git commit via a background daemon&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The demo that convinced me
&lt;/h2&gt;

&lt;p&gt;Fresh Codex session. Private React Native project. Zero context pasted.&lt;/p&gt;

&lt;p&gt;Asked: "What is this project and what am I working on?"&lt;/p&gt;

&lt;p&gt;Codex answered with exact file paths, line numbers, and identified &lt;br&gt;
a specific bug in the cart validation logic — minimum quantity &lt;br&gt;
hardcoded in multiple places, silently coerced with &lt;br&gt;
Math.max(quantity, 6) in cart.ts#L40.&lt;/p&gt;

&lt;p&gt;That answer came from the LCD. Not from Codex exploring files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three commands
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;\&lt;/code&gt;`bash&lt;br&gt;
npm install -g @ctxpilot/ctxpilot&lt;/p&gt;

&lt;p&gt;ctx init    # scan codebase, generate LCD&lt;br&gt;
ctx setup   # configure all AI clients&lt;br&gt;
ctx watch   # start auto-update daemon&lt;br&gt;
`&lt;code&gt;\&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How the auto-update works
&lt;/h2&gt;

&lt;p&gt;ctx watch starts a background daemon that watches &lt;br&gt;
.git/refs/heads/ via Chokidar. When a new commit is detected, &lt;br&gt;
it waits 30 seconds then runs ctx update.&lt;/p&gt;

&lt;p&gt;ctx update:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reads git diff since last update&lt;/li&gt;
&lt;li&gt;Extracts signals (decisions, completed work, new patterns)&lt;/li&gt;
&lt;li&gt;Calls Claude to rewrite the LCD incorporating new signals&lt;/li&gt;
&lt;li&gt;Archives any removed content&lt;/li&gt;
&lt;li&gt;Writes the updated LCD&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The result: every session starts with fresh context. Zero manual work.&lt;/p&gt;

&lt;h2&gt;
  
  
  How ctx setup works
&lt;/h2&gt;

&lt;p&gt;Running ctx setup inside a project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Writes MCP server config to ~/.claude/claude_desktop_config.json&lt;/li&gt;
&lt;li&gt;Writes MCP server config to ~/.codex/config.toml&lt;/li&gt;
&lt;li&gt;Writes MCP server config to ~/.cursor/mcp.json&lt;/li&gt;
&lt;li&gt;Writes MCP server config to ~/.windsurf/mcp.json&lt;/li&gt;
&lt;li&gt;Creates CLAUDE.md with "read LCD first" instructions&lt;/li&gt;
&lt;li&gt;Creates .cursor/rules/ctxpilot.mdc with alwaysApply: true&lt;/li&gt;
&lt;li&gt;Creates .windsurf/rules/ctxpilot.md&lt;/li&gt;
&lt;li&gt;Creates .agents/skills/ctxpilot/SKILL.md for Codex&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All upsert-safe — existing configs are never overwritten, only &lt;br&gt;
the ctxpilot entry is added or updated.&lt;/p&gt;

&lt;h2&gt;
  
  
  The LCD structure
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;\&lt;/code&gt;`markdown&lt;/p&gt;

&lt;h1&gt;
  
  
  Living Context Document
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Project Identity
&lt;/h2&gt;

&lt;p&gt;GiftExpress - React Native mobile e-commerce app...&lt;/p&gt;

&lt;h2&gt;
  
  
  Active Goal
&lt;/h2&gt;

&lt;p&gt;Cart validation refactoring...&lt;/p&gt;

&lt;h2&gt;
  
  
  Technology Stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;React Native 0.80.0 with TypeScript 5.0.4&lt;/li&gt;
&lt;li&gt;Zustand 5.0.6 for state management
...&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architecture Patterns
&lt;/h2&gt;

&lt;p&gt;...&lt;/p&gt;

&lt;h2&gt;
  
  
  In Progress
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Cart validation constants extraction&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Recently Completed
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Secure session management
...&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Code Conventions
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Strict TypeScript&lt;/li&gt;
&lt;li&gt;Named exports
...
`&lt;code&gt;\&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Technical stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;TypeScript, Node.js 20, ESM&lt;/li&gt;
&lt;li&gt;Commander.js for CLI&lt;/li&gt;
&lt;li&gt;Chokidar for file watching&lt;/li&gt;
&lt;li&gt;simple-git for git integration&lt;/li&gt;
&lt;li&gt;@modelcontextprotocol/sdk for MCP server&lt;/li&gt;
&lt;li&gt;Anthropic SDK + OpenAI SDK (user's choice of provider)&lt;/li&gt;
&lt;li&gt;
&lt;a class="mentioned-user" href="https://dev.to/iarna"&gt;@iarna&lt;/a&gt;/toml for safe TOML merging&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;&lt;code&gt;\&lt;/code&gt;&lt;code&gt;bash&lt;br&gt;
npm install -g @ctxpilot/ctxpilot&lt;br&gt;
\&lt;/code&gt;&lt;code&gt;\&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;GitHub: github.com/fewknowme/ctxpilot&lt;br&gt;
Website: fewknowme.github.io/ctxpilot&lt;/p&gt;

&lt;p&gt;Open source, MIT license. Issues and PRs welcome.&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>typescript</category>
      <category>ai</category>
      <category>devtools</category>
    </item>
    <item>
      <title>Versioning! and Versioning?</title>
      <dc:creator>Rohit Madas</dc:creator>
      <pubDate>Mon, 10 Nov 2025 14:49:18 +0000</pubDate>
      <link>https://dev.to/rohit_madas_81dc4f9256f28/versioning-and-versioning-2cij</link>
      <guid>https://dev.to/rohit_madas_81dc4f9256f28/versioning-and-versioning-2cij</guid>
      <description>&lt;p&gt;Look, versioning isn't just some administrative checkbox. It's actually how you keep your sanity when building software. Whether you're working with React, React Native, or juggling multiple services, good versioning is what saves you from the "wait, what changed?" moments at 2 AM.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Git: Your Project's Memory&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Think of Git as your project's diary. Every commit tells a story about what you were trying to do and why. When you connect it properly with JIRA (or whatever you use), suddenly your code history becomes readable.&lt;/p&gt;

&lt;p&gt;Here's what a solid workflow looks like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;JIRA Ticket → WEB-214 | Add password validation&lt;br&gt;
Branch → feature/WEB-214-password-validation&lt;br&gt;
Commit → feat(WEB-214): added dynamic error handling for password&lt;br&gt;
Pull Request → references the ticket and explains what you did&lt;br&gt;
Merge + Tag → marks the release&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Why bother? Because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can actually trace why that line of code exists&lt;/li&gt;
&lt;li&gt;QA knows exactly what to test&lt;/li&gt;
&lt;li&gt;When something breaks, you can find the culprit fast&lt;/li&gt;
&lt;li&gt;Code reviews stay focused instead of turning into archaeology expeditions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Without this structure, your repo becomes a mystery novel where nobody knows the plot.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;npm Versioning: Making Releases Meaningful&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Running npm version isn't just bumping numbers. It's you saying "this is a real release, and here's what it means."&lt;/p&gt;

&lt;p&gt;When you run it, npm:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Updates your package.json and package-lock.json&lt;/li&gt;
&lt;li&gt;Creates a Git commit and tag (like v1.4.2)&lt;/li&gt;
&lt;li&gt;Can trigger your CI/CD to actually deploy it&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use Semantic Versioning (SemVer) so people know what to expect:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;MAJOR (2.0.0) – "Heads up, things will break"&lt;br&gt;
MINOR (1.3.0) – "New stuff, but your code still works"&lt;br&gt;
PATCH (1.3.4) – "Bug fixes, nothing scary"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For React and React Native projects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Libraries: This version is what people see on npm&lt;/li&gt;
&lt;li&gt;Apps: Keep this in sync with what you deploy, so your versions actually mean something&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Tools like &lt;em&gt;standard-version&lt;/em&gt;, &lt;em&gt;changesets&lt;/em&gt;, or &lt;em&gt;release-please&lt;/em&gt; can automate this once your team gets bigger.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;App Versioning: What Users Actually See&lt;/strong&gt;&lt;br&gt;
Code versioning is for engineers. App versioning is for humans using your app.&lt;/p&gt;

&lt;p&gt;For React Native:&lt;/p&gt;

&lt;p&gt;iOS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CFBundleShortVersionString is what users see (like 1.5.2)&lt;/li&gt;
&lt;li&gt;CFBundleVersion is your internal build number&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Android:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;versionName is the public version&lt;/li&gt;
&lt;li&gt;&lt;p&gt;versionCode increments with every release&lt;br&gt;
Before each production release:&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bump your version numbers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Update the changelog&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Tag it in Git so everything lines up&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Automating this in CI/CD means you won't forget to do it when you're rushing to ship.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Changelogs: The Unsung Hero&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A changelog is basically your "what we did" log. It's not busywork—it's how you prove things got done.&lt;/p&gt;

&lt;p&gt;A good changelog helps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Engineers remember what was in each release&lt;/li&gt;
&lt;li&gt;QA know what actually needs testing&lt;/li&gt;
&lt;li&gt;Product managers track what shipped when&lt;/li&gt;
&lt;li&gt;New team members understand the project's journey&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Simple rule: If it's not in the changelog, you can't prove it happened.&lt;/p&gt;

&lt;p&gt;You can auto-generate it from commits or write it manually-just be consistent.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Connecting the Dots&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The magic happens when everything links together:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;JIRA Ticket → Git Branch → Commit → npm Version → App Version → Changelog&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Real example:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;JIRA: WEB-312 | Optimize image loading&lt;br&gt;
Branch: feature/WEB-312-image-optimization&lt;br&gt;
Commit: perf(WEB-312): improved lazy loading for carousel&lt;br&gt;
npm version: minor → v1.6.0&lt;br&gt;
App Version: 1.6.0 (build 90)&lt;br&gt;
Changelog: "Improved performance for image-heavy pages."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now you have a complete trail. Anyone can understand what changed, why, and when.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Why This Actually Matters&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Good versioning discipline gives you:&lt;/li&gt;
&lt;li&gt;Predictable releases instead of chaos&lt;/li&gt;
&lt;li&gt;Fast rollbacks when things go wrong&lt;/li&gt;
&lt;li&gt;Automation you can trust&lt;/li&gt;
&lt;li&gt;Clear audit trails&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It makes handovers smoother, reduces confusion between teams, and lets dev, staging, and production environments make sense.&lt;/p&gt;

&lt;p&gt;Versioning isn't a side quest. It's the bridge between the code you write and the product people use.&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Teams that take versioning seriously ship more reliably and with way less drama.&lt;/p&gt;

&lt;p&gt;Your version history isn't just metadata—it's the story of your product. Treat it like it matters, because it does.&lt;/p&gt;

</description>
      <category>coding</category>
      <category>softwareengineering</category>
      <category>backtracking</category>
      <category>codeversioning</category>
    </item>
    <item>
      <title>Sanity V3: Display an Array of References as a Checklist</title>
      <dc:creator>Rohit Madas</dc:creator>
      <pubDate>Mon, 11 Aug 2025 14:29:30 +0000</pubDate>
      <link>https://dev.to/rohit_madas_81dc4f9256f28/sanity-v3-display-an-array-of-references-as-a-checklist-57oe</link>
      <guid>https://dev.to/rohit_madas_81dc4f9256f28/sanity-v3-display-an-array-of-references-as-a-checklist-57oe</guid>
      <description>&lt;h2&gt;
  
  
  Sanity IO ( Co-author credits to - RD Pennell for v2 Version as base )
&lt;/h2&gt;

&lt;p&gt;If you're building a Sanity Studio and want to display an array of reference fields as a multi-select checklist, here's a full working solution tailored for Sanity V3.&lt;br&gt;
You’ll define:&lt;/p&gt;

&lt;p&gt;A custom input component ReferenceSelect&lt;/p&gt;

&lt;p&gt;A schema using this component via the components.input override&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Schema.js
{
 name: "ReferenceMultiSelect",
 description: "Select categories",
 title: "Category Type",
 type: "array",
 of: [
 {
 type: "reference",
 to: { type: "categories" },
 },
 ],
 components: {
 input: ReferenceSelect,
 },
 },

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

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// ReferenceSelect.jsx
import React, { useEffect, useState } from "react";
import { Card, Flex, Checkbox, Box, Text } from "@sanity/ui";
import client from "./client";
import { useId } from "@reach/auto-id";
import { FormField, PatchEvent, set } from "sanity";

const ReferenceSelect = React.forwardRef((props, ref) =&amp;gt; {
 const [categories, setCategories] = useState([]);

 useEffect(() =&amp;gt; {
 const fetchCountries = async () =&amp;gt; {
 await client
 .fetch(
 `*[_type == 'categories']{
 ...,
 _id,
 category
 }`
 )
 .then(setCategories);
 };
 fetchCountries();
 }, []);

 const {
 type, // Schema information
 value, // Current field value
 readOnly, // Boolean if field is not editable
 markers, // Markers including validation rules
 presence, // Presence information for collaborative avatars
 compareValue, // Value to check for "edited" functionality
 onFocus, // Method to handle focus state
 onBlur, // Method to handle blur state
 onChange, // Method to handle patch events,
 } = props;

 const handleClick = React.useCallback(
 (e) =&amp;gt; {
 const inputValue = {
 _key: e.target.value.slice(0, 10),
 _type: "reference",
 _ref: e.target.value,
 };

 if (value) {
 if (value.some((country) =&amp;gt; country._ref === inputValue._ref)) {
 onChange(
 PatchEvent.from(
 set(value.filter((item) =&amp;gt; item._ref != inputValue._ref))
 )
 );
 } else {
 onChange(PatchEvent.from(set([...value, inputValue])));
 }
 } else {
 onChange(PatchEvent.from(set([inputValue])));
 }
 },
 [value]
 );

 const inputId = useId();

 return (
 &amp;lt;FormField
 description={type?.schemaType.description} // Creates description from schema
 title={type?.schemaType.title} // Creates label from schema title
 __unstable_markers={markers} // Handles all markers including validation
 __unstable_presence={presence} // Handles presence avatars
 compareValue={compareValue} // Handles "edited" status
 inputId={inputId} // Allows the label to connect to the input field
 readOnly={readOnly}
 &amp;gt;
 {categories.map((cat, index) =&amp;gt; (
 &amp;lt;Card key={index} padding={2}&amp;gt;
 &amp;lt;Flex align="center"&amp;gt;
 &amp;lt;Checkbox
 id={cat._id}
 style={{ display: "block" }}
 onClick={handleClick}
 onChange={() =&amp;gt; console.log("changed")}
 value={cat._id}
 checked={
 value ? value.some((item) =&amp;gt; item._ref === cat._id) : false
 }
 /&amp;gt;
 &amp;lt;Box flex={1} paddingLeft={3}&amp;gt;
 &amp;lt;Text&amp;gt;
 &amp;lt;label htmlFor={cat._id}&amp;gt;{cat.category}&amp;lt;/label&amp;gt;
 &amp;lt;/Text&amp;gt;
 &amp;lt;/Box&amp;gt;
 &amp;lt;/Flex&amp;gt;
 &amp;lt;/Card&amp;gt;
 ))}
 &amp;lt;/FormField&amp;gt;
 );
});

export default ReferenceSelect;

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

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;🧩 Notes for Integration&lt;br&gt;
🔁 _key is derived from the _ref value to keep the array diff-friendly for Sanity.&lt;br&gt;
⚠️ onClick is used instead of onChange to maintain toggle behavior due to Sanity’s event handling.&lt;br&gt;
💾 This assumes you have a working Sanity V3 setup and a categories document type defined.&lt;br&gt;
Link to my original article on &lt;a href="https://www.sanity.io/recipes/v3-version-of-display-an-array-of-references-as-a-checklist-ecfa271a" rel="noopener noreferrer"&gt;Sanity&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>webdev</category>
      <category>sanitycms</category>
      <category>programming</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
