<?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: Sourabh Kumar Dubey</title>
    <description>The latest articles on DEV Community by Sourabh Kumar Dubey (@ab_33).</description>
    <link>https://dev.to/ab_33</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%2F4153118%2F32eb64a4-51a8-418b-b524-b76d1549730c.png</url>
      <title>DEV Community: Sourabh Kumar Dubey</title>
      <link>https://dev.to/ab_33</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/ab_33"/>
    <language>en</language>
    <item>
      <title>DocsPulse: Run Your README's Install Steps and Verify the Fixes</title>
      <dc:creator>Sourabh Kumar Dubey</dc:creator>
      <pubDate>Mon, 19 Oct 2026 06:55:53 +0000</pubDate>
      <link>https://dev.to/ab_33/docspulse-run-your-readmes-install-steps-and-verify-the-fixes-16o0</link>
      <guid>https://dev.to/ab_33/docspulse-run-your-readmes-install-steps-and-verify-the-fixes-16o0</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week2-2026-10-12"&gt;Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;DocsPulse&lt;/strong&gt; runs the install steps in a README, finds the ones that no longer work, and calls a fix "verified" only after it has been re-run and passed.&lt;/p&gt;

&lt;p&gt;Setup instructions go out of date. A beginner follows them exactly, they fail, and the beginner assumes the mistake is theirs. DocsPulse checks the instructions instead of trusting them.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Who would pay (an idea I have not tested yet):&lt;/strong&gt; a freelancer or small agency could offer a "README health check" report on client repositories before handoff, running DocsPulse on a throwaway machine through the GitHub Action. I have not tried selling this, so this is my guess at the market and not a result.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;I do not have a hosted app, because a public website that runs strangers' README commands would be a remote-code-execution risk. You can try it with no setup in three ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Open the repo in &lt;strong&gt;GitHub Codespaces&lt;/strong&gt; (badge in the README) and run &lt;code&gt;docspulse demo/broken-repo --provider none&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Add six lines of YAML to any repo to run it as a &lt;strong&gt;GitHub Action&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;pip install git+https://github.com/skd-33/docspulse&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On my demo repo, &lt;code&gt;pip install requests==99.0.0&lt;/code&gt; failed. DocsPulse read pip's list of available versions, chose the highest, ran it, and only then reported a verified fix (&lt;code&gt;requests==2.34.2&lt;/code&gt;). &lt;code&gt;curl http://x | sh&lt;/code&gt; was skipped and never run. The README has the full real output, a report format guide and results on four public repos.&lt;/p&gt;

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


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/skd-33" rel="noopener noreferrer"&gt;
        skd-33
      &lt;/a&gt; / &lt;a href="https://github.com/skd-33/docspulse" rel="noopener noreferrer"&gt;
        docspulse
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;DocsPulse&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Run the install steps in a README, find the ones that no longer work, and fix them. A fix is called "verified" only after it has been tested.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://codespaces.new/skd-33/docspulse" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://github.com/codespaces/badge.svg" alt="Open in GitHub Codespaces"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e"&gt;&lt;img src="https://camo.githubusercontent.com/f8df3091bbe1149f398a5369b2c39e896766f9f6efba3477c63e9b4aa940ef14/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d677265656e" alt="License: MIT"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/e801a66299d2c15286fe0fee660d9ffa666c1c5576e5e1536acc07b49ce8ac8f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d332e31302532422d626c7565"&gt;&lt;img src="https://camo.githubusercontent.com/e801a66299d2c15286fe0fee660d9ffa666c1c5576e5e1536acc07b49ce8ac8f/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f707974686f6e2d332e31302532422d626c7565" alt="Python 3.10+"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/2e7335ac36e73e3008de51759b29de1f8155bdb7ade828067bd6536471d6b0c8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646570656e64656e636965732d6e6f6e652d627269676874677265656e"&gt;&lt;img src="https://camo.githubusercontent.com/2e7335ac36e73e3008de51759b29de1f8155bdb7ade828067bd6536471d6b0c8/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f646570656e64656e636965732d6e6f6e652d627269676874677265656e" alt="Dependencies: none"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Built for &lt;strong&gt;Hacktoberfest Hack Day&lt;/strong&gt; (BMSCE IEEE Computer Society), &lt;strong&gt;Theme 1: Use AI to Build Developer Tools&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;At a glance&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The problem:&lt;/strong&gt; setup instructions in READMEs go out of date. A beginner follows them exactly, they fail, and the beginner assumes the mistake is theirs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;What DocsPulse does:&lt;/strong&gt; it reads the README, runs the commands in a clean environment, reports which ones fail, proposes a fix, and &lt;strong&gt;re-runs the fix&lt;/strong&gt; before calling it verified.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;How to use it:&lt;/strong&gt; open it in Codespaces, add six lines of YAML to a repository, or run one command. Nothing needs to be configured, and AI is optional.&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Contents&lt;/h2&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/docspulse#try-it-in-60-seconds" rel="noopener noreferrer"&gt;Try it in 60 seconds&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/docspulse#my-story" rel="noopener noreferrer"&gt;My story&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/docspulse#the-problem" rel="noopener noreferrer"&gt;The problem&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/docspulse#what-docspulse-does" rel="noopener noreferrer"&gt;What DocsPulse does&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/docspulse#real-output" rel="noopener noreferrer"&gt;Real output&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/skd-33/docspulse#how-to-read-the-report" rel="noopener noreferrer"&gt;How to&lt;/a&gt;…&lt;/li&gt;
&lt;/ol&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/skd-33/docspulse" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;MIT licensed, Python standard library only.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Pipeline:&lt;/strong&gt; parser, safety allowlist, fresh-venv runner, fixer, report. Python, no dependencies, 36 unit tests.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in rules first:&lt;/strong&gt; common pip version errors are fixed with no model at all.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open-source AI as an optional layer:&lt;/strong&gt; a local model (Qwen2.5-Coder 3B through Ollama) can suggest fixes for errors the rules do not cover. Every suggestion goes through the same safety check and is run before it is called verified. A hosted Gemini option also exists, and the model is swappable with one flag.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built with&lt;/strong&gt; the Antigravity coding agent, one module at a time. Testing installs from a clean environment found a packaging bug that my unit tests had missed, and I fixed it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I want to be direct about where the model sits: AI is not the core of this project, and the tool works without it. In an early test a small model repeated the broken command, so I added deterministic rules first. In my demo, the verified fix came from a rule, not the model. The model path is implemented and covered by unit tests, but it is the weaker part.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;The local model path matters for one practical reason: the failed command and its error text stay on your machine, which counts for private repositories. It runs on my 8GB laptop, costs nothing per call, needs no API key, and I can swap the model without changing code. A closed API would add a key, a bill and a data-sharing decision to a tool whose whole point is to be easy to try.&lt;/p&gt;

&lt;h2&gt;
  
  
  Limits
&lt;/h2&gt;

&lt;p&gt;Python and pip only for now. On four real repos (bottle, httpx, starlette, urllib3), 24 of 32 commands were skipped by the safety allowlist, and testing found a bug where inline &lt;code&gt;# comments&lt;/code&gt; are passed to pip. Both are documented in the README.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>Look Up: an offline AI that nudges you to go see tonight’s sky</title>
      <dc:creator>Sourabh Kumar Dubey</dc:creator>
      <pubDate>Mon, 12 Oct 2026 04:58:49 +0000</pubDate>
      <link>https://dev.to/ab_33/look-up-an-offline-ai-that-nudges-you-to-go-see-tonights-sky-1653</link>
      <guid>https://dev.to/ab_33/look-up-an-offline-ai-that-nudges-you-to-go-see-tonights-sky-1653</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week1-2026-10-05"&gt;Hacktoberfest Open-Source AI Challenge Week 1: Touch Grass&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;The first time I noticed Venus, I thought it was just a very bright star. My internet had stopped working, so I went up to the roof, and there it was, far brighter than anything around it. I stood there longer than I meant to.&lt;/p&gt;

&lt;p&gt;That one star turned into a habit. Now I go outside most days and spend an hour or two in the open, feeling the wind and watching the sky change. It all started with a single bright dot I didn't understand.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Look Up&lt;/strong&gt; is my attempt to hand that moment to someone else. It's a small website that runs entirely on your own computer. It works out what is actually in the sky tonight where you are (Bengaluru by default), and a local open-weight AI model turns that into a short, friendly nudge: what to look at, where, and when.&lt;/p&gt;

&lt;p&gt;Then there's one button, &lt;strong&gt;"I'm going out."&lt;/strong&gt; It starts a timer and dims the page, so the screen becomes the shortest part of the experience.&lt;/p&gt;

&lt;p&gt;It's for anyone curious about the sky but never sure what they're looking at: beginners, space lovers, and people who need a small reason to step outside tonight.&lt;/p&gt;

&lt;p&gt;You can set your own location, choose how long you want to stay outside, and pick the voice of the nudge (Calm, Excited or Poetic). While the timer runs, it shows a gentle prompt every few minutes, like "notice how quiet it is". When you come back, you can tell it what you saw and it replies.&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Video demo: &lt;a href="https://drive.google.com/file/d/1Y58dX_Pt7r3UHUGbwwvtSQheFb6ssVPI/view?usp=sharing" rel="noopener noreferrer"&gt;https://drive.google.com/file/d/1Y58dX_Pt7r3UHUGbwwvtSQheFb6ssVPI/view?usp=sharing&lt;/a&gt;&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%2Fnoqnyejhyg66i0dn3sky.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%2Fnoqnyejhyg66i0dn3sky.png" alt="The Look Up website showing tonight's visible planets and a friendly nudge" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It runs on localhost. To try it yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/skd-33/look-up.git
cd look-up
pip install skyfield
python setup.py
ollama pull qwen2.5:1.5b
python server.py
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then open &lt;code&gt;http://127.0.0.1:8000&lt;/code&gt;. You need internet only once, to download the model and a 17 MB NASA ephemeris file. After that, everything works with Wi-Fi off.&lt;/p&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/skd-33" rel="noopener noreferrer"&gt;
        skd-33
      &lt;/a&gt; / &lt;a href="https://github.com/skd-33/look-up" rel="noopener noreferrer"&gt;
        look-up
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Look Up&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;An offline stargazing website that tells you what to look at in the sky tonight and nudges you to go outside.&lt;/p&gt;

&lt;p&gt;It runs entirely on your own computer. Python works out what is really in the sky, and a small open-weight AI model (Qwen2.5 1.5B, via Ollama) turns that into a short, friendly nudge. No server, no API key, no internet after setup.&lt;/p&gt;

&lt;p&gt;Built for the DEV Hacktoberfest Open-Source AI Challenge, Week 1: &lt;strong&gt;Touch Grass&lt;/strong&gt;.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;Tonight's visible planets: direction, best time and altitude, calculated for your location over the whole night, from sunset to sunrise&lt;/li&gt;
&lt;li&gt;A short AI-written nudge in a voice you choose: Calm, Excited or Poetic&lt;/li&gt;
&lt;li&gt;Location picker: Bengaluru by default, a city list, custom coordinates, or browser location&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;"I'm going out"&lt;/strong&gt; button: pick 10, 20, 30, 60 or custom minutes, the page dims, and gentle prompts appear every few minutes until a soft…&lt;/li&gt;
&lt;/ul&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/skd-33/look-up" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Skyfield&lt;/strong&gt; and a NASA JPL ephemeris file calculate which planets are above the horizon, in which direction, and when they peak. No network needed.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ollama running Qwen2.5 1.5B&lt;/strong&gt; turns those facts into a warm two-sentence nudge. I started with Gemma 3 1B and moved to Qwen by changing one setting.&lt;/li&gt;
&lt;li&gt;The site is plain HTML, CSS and JavaScript with a hand-drawn SVG night scene and a small Python server. It makes no external requests.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The part I like most is a bug. My first version told me Venus was "shining bright" while the same page listed Venus as not visible. The model made it up.&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%2F5xwjqms1r50fu899ymkz.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%2F5xwjqms1r50fu899ymkz.png" alt="The old nudge calling Venus bright while the list beside it says Venus is not visible" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A 1.5B model is good at tone and unreliable with facts, so I stopped asking it for facts. Now Python picks the target object and passes only that object's data, and the model only rewrites it. The app then checks the sentence. If it names an object that isn't in the data, or leaves out the time, the app throws it away and uses a plain template. The AI gets to be warm and the code gets to be right.&lt;/p&gt;

&lt;p&gt;I wrote the spec first, and when I added things later (location, timer, voices) I did each as its own small step and committed it before moving on. I used coding agents in Antigravity (Claude Opus first, then Gemini Flash when my quota ran out) to write the code. The agents are closed models. The product itself runs only on open weights.&lt;/p&gt;

&lt;p&gt;The agent didn't always follow the plan either. It wrote most of the project in one pass instead of one step at a time, and the first page it produced had headings hidden under the header, a clipped "Custom" button, and a night scene too faint to see. I caught these by opening the page and sending screenshots back for fixes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;It works with no signal.&lt;/strong&gt; A stargazing tool is most useful where the sky is darkest, which is usually where the internet is worst.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your location never leaves your computer.&lt;/strong&gt; There is no server and no API key.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It costs nothing to run.&lt;/strong&gt; Anyone with a laptop can use it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;I could swap and change it.&lt;/strong&gt; I switched models by changing one setting, and I can rewrite how the assistant talks without paying per call.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is where open worked better than a closed API: a closed model would need internet, an account, and my location sent to someone else's server. A bigger closed model would probably write prettier sentences, but I'll take slightly plainer sentences in exchange for something that works on a hilltop.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What's next:&lt;/strong&gt; starting the sky nudge automatically at login so it reaches you without opening the site, more voices and models, and more things to spot, like the ISS.&lt;/p&gt;

&lt;p&gt;If you have never really looked at the sky, tonight is a good night to start.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>BuildFolio: From Arduino Builds to Shareable Portfolios</title>
      <dc:creator>Sourabh Kumar Dubey</dc:creator>
      <pubDate>Sun, 04 Oct 2026 22:28:18 +0000</pubDate>
      <link>https://dev.to/ab_33/buildfolio-from-arduino-builds-to-shareable-portfolios-1h0j</link>
      <guid>https://dev.to/ab_33/buildfolio-from-arduino-builds-to-shareable-portfolios-1h0j</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-weekend-2026-10-01"&gt;Hacktoberfest Weekend Challenge: Build for a Friend&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;BuildFolio&lt;/strong&gt; helps you build, track, understand and showcase technical projects.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Give BuildFolio your project information → AI understands it → it generates an editable portfolio → you publish it as a shareable link.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  The friend and the problem
&lt;/h3&gt;

&lt;p&gt;I built this for a friend who makes Arduino projects. Every project has code, wiring, photos and demo videos. When he tried to share his work, GitHub didn't fit: it's good for code, but awkward for showing a build with images and video. He needed a proper website for his projects, and building and maintaining one by hand for every project is slow.&lt;/p&gt;

&lt;h3&gt;
  
  
  What it does for him
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Project workspace:&lt;/strong&gt; he records each project's description, status, technologies, deadline, budget and links (GitHub, KiCad, Fusion 360, Arduino, docs, demo).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Task tracking:&lt;/strong&gt; tasks move through &lt;code&gt;Pending&lt;/code&gt;, &lt;code&gt;In Progress&lt;/code&gt; and &lt;code&gt;Completed&lt;/code&gt;, and overall progress is calculated automatically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Components / BOM:&lt;/strong&gt; parts with quantity and unit price, with automatic totals, remaining budget and an over-budget warning.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI-drafted portfolio:&lt;/strong&gt; a local model reads the project data and drafts these sections: Summary, Problem, Solution, Hardware, Software, Architecture, Challenges and Future Improvements.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Full editing:&lt;/strong&gt; he can edit any section, add, remove or reorder sections, and attach media URLs.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Publish:&lt;/strong&gt; one toggle makes the portfolio public at a unique (or custom) slug. Anyone can open it without an account.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Design decisions I care about
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The tracker is the source of truth, and AI only reads it.&lt;/strong&gt; Generating a portfolio never changes the underlying project, task or component data.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Every AI-written fact is tagged&lt;/strong&gt; &lt;code&gt;confirmed&lt;/code&gt;, &lt;code&gt;inferred&lt;/code&gt; or &lt;code&gt;unknown&lt;/code&gt;, so the author knows what to verify before publishing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The model never writes HTML.&lt;/strong&gt; It returns structured data and React handles all rendering.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Current limitation
&lt;/h3&gt;

&lt;p&gt;The AI works from &lt;strong&gt;text only&lt;/strong&gt;. It can't look at photos or videos, and media is attached as URLs rather than uploaded. For an Arduino builder, that's the biggest gap. I had limited time for this challenge, so I built the core pipeline first. The plan for closing the gap is in "What's Next".&lt;/p&gt;

&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;🎥 &lt;strong&gt;Demo video:&lt;/strong&gt; &lt;a href="https://drive.google.com/file/d/1J1rTq3zL7wLleuO3bpQsb5aTdoxqSgfs/view?usp=sharing" rel="noopener noreferrer"&gt;https://drive.google.com/file/d/1J1rTq3zL7wLleuO3bpQsb5aTdoxqSgfs/view?usp=sharing&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;🚀 &lt;strong&gt;Live app:&lt;/strong&gt; &lt;a href="https://projectpulse-1-mjqh.onrender.com" rel="noopener noreferrer"&gt;https://projectpulse-1-mjqh.onrender.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The live deployment has everything except AI generation: project workspace, tasks, components, portfolio editor and public portfolio pages. Ollama doesn't run on Render, so the generate endpoint returns a service-unavailable error there. The video shows generation running locally.&lt;/p&gt;

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


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/skd-33" rel="noopener noreferrer"&gt;
        skd-33
      &lt;/a&gt; / &lt;a href="https://github.com/skd-33/BuildFolio" rel="noopener noreferrer"&gt;
        BuildFolio
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      AI-powered workspace to build, track, understand, and showcase technical projects
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;BuildFolio&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;BuildFolio helps you build, track, understand, and showcase technical projects.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Give BuildFolio your project information → AI understands it → generates an editable portfolio → publish it as a shareable link.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://projectpulse-1-mjqh.onrender.com" rel="nofollow noopener noreferrer"&gt;🚀 Live Demo&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;div class="markdown-alert markdown-alert-important"&gt;
&lt;p class="markdown-alert-title"&gt;Important&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;AI portfolio generation runs locally using Ollama.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The public Render deployment provides the full application — project workspace, task tracking, component management, portfolio editor, and public portfolio experience — but Ollama is &lt;strong&gt;not&lt;/strong&gt; running on Render.&lt;/p&gt;
&lt;p&gt;To use the AI generation feature, run Ollama on the same machine as the BuildFolio backend and pull the model before starting. See &lt;a href="https://github.com/skd-33/BuildFolio#7-ai-setup" rel="noopener noreferrer"&gt;AI Setup&lt;/a&gt; for details.&lt;/p&gt;
&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Table of Contents&lt;/h2&gt;
&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#1-overview" rel="noopener noreferrer"&gt;Overview&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#2-features" rel="noopener noreferrer"&gt;Features&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#3-how-it-works" rel="noopener noreferrer"&gt;How It Works&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#4-architecture" rel="noopener noreferrer"&gt;Architecture&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#5-tech-stack" rel="noopener noreferrer"&gt;Tech Stack&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#6-local-setup" rel="noopener noreferrer"&gt;Local Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#7-ai-setup" rel="noopener noreferrer"&gt;AI Setup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#8-using-buildfolio" rel="noopener noreferrer"&gt;Using BuildFolio&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#9-project-structure" rel="noopener noreferrer"&gt;Project Structure&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#10-deployment" rel="noopener noreferrer"&gt;Deployment&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#11-testing" rel="noopener noreferrer"&gt;Testing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#12-contributing" rel="noopener noreferrer"&gt;Contributing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#13-future-ideas" rel="noopener noreferrer"&gt;Future Ideas&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/skd-33/BuildFolio#14-license" rel="noopener noreferrer"&gt;License&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;1. Overview&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;BuildFolio combines four things that engineers typically manage in separate tools:&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Project tracker&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Source of truth for your actual engineering&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/skd-33/BuildFolio" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Quick start (details in the README):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# backend (from repo root, after creating a venv and installing requirements)&lt;/span&gt;
&lt;span class="nv"&gt;AI_PROVIDER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ollama &lt;span class="nv"&gt;AI_MODEL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;gemma3:1b python &lt;span class="nt"&gt;-m&lt;/span&gt; uvicorn backend.main:app &lt;span class="nt"&gt;--reload&lt;/span&gt; &lt;span class="nt"&gt;--port&lt;/span&gt; 8000

&lt;span class="c"&gt;# frontend&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;frontend &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; npm run dev

&lt;span class="c"&gt;# model&lt;/span&gt;
ollama pull gemma3:1b
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Stack
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;React 19, Vite, React Router v7, Lucide icons&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;FastAPI (Python), SQLAlchemy 2, Pydantic v2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Auth&lt;/td&gt;
&lt;td&gt;JWT in &lt;code&gt;httpOnly&lt;/code&gt; cookies&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;SQLite locally, PostgreSQL in production&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI runtime&lt;/td&gt;
&lt;td&gt;Ollama&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Open model&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;gemma3:1b&lt;/code&gt; (configurable via &lt;code&gt;AI_MODEL&lt;/code&gt;)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hosting&lt;/td&gt;
&lt;td&gt;Render&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The AI pipeline
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Project data (description, tasks, components, notes)
   ↓  FastAPI assembles a context string
AI service → provider abstraction → Ollama (localhost:11434)
   ↓  gemma3:1b
Structured JSON (ProjectKnowledge)
   ↓  validated by Pydantic
Portfolio sections saved to the database
   ↓  user edits and publishes
Public portfolio page at a shareable URL
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Making a small model dependable
&lt;/h3&gt;

&lt;p&gt;A 1B model doesn't always follow instructions, so the pipeline doesn't trust it blindly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Schema-constrained output:&lt;/strong&gt; the model must return JSON matching a &lt;code&gt;ProjectKnowledge&lt;/code&gt; schema, which Pydantic validates.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Retries:&lt;/strong&gt; invalid or empty output is retried up to 3 times.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confidence tagging:&lt;/strong&gt; each fact is marked &lt;code&gt;confirmed&lt;/code&gt;, &lt;code&gt;inferred&lt;/code&gt; or &lt;code&gt;unknown&lt;/code&gt;, so weak output is visible, not hidden.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Human in the loop:&lt;/strong&gt; the result is a draft the user reviews and edits before anything is published.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Provider abstraction
&lt;/h3&gt;

&lt;p&gt;The inference layer lives in its own module (&lt;code&gt;backend/ai/providers.py&lt;/code&gt;). Ollama is the tested setup. The layer also accepts an OpenAI-compatible endpoint through &lt;code&gt;AI_BASE_URL&lt;/code&gt; and &lt;code&gt;AI_API_KEY&lt;/code&gt;, but I haven't tested that path.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;There's an end-to-end backend API test covering auth, projects, tasks and progress, components and costs, portfolio editing and publishing, sections and media, and unauthenticated public access. The frontend has a build check.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Does Open Innovation Matter?
&lt;/h2&gt;

&lt;p&gt;An open-weight model I can run myself gave me things a closed API wouldn't:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Local inference.&lt;/strong&gt; &lt;code&gt;gemma3:1b&lt;/code&gt; runs through Ollama on my own CPU-only machine, so project text is never sent to an external AI provider during generation. To be precise, the deployed app still stores projects on its own server and database. Only the AI step stays local.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No per-call cost.&lt;/strong&gt; I can regenerate drafts as often as I like, with no API key or billing. That matters for a student project and for a friend who just wants to try it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Control.&lt;/strong&gt; I can swap models with one env var and constrain the output to a schema I validate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Room to grow.&lt;/strong&gt; Moving to a vision-capable open model for photos is a configuration and pipeline change, not a vendor decision.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;Direct image and video uploads&lt;/li&gt;
&lt;li&gt;A vision model that reads photos of hardware builds&lt;/li&gt;
&lt;li&gt;Pulling context straight from a GitHub repo or README&lt;/li&gt;
&lt;li&gt;Document ingestion for project docs&lt;/li&gt;
&lt;li&gt;Project-specific AI Q&amp;amp;A&lt;/li&gt;
&lt;li&gt;Themes and drag-and-drop section ordering&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Prize Categories
&lt;/h2&gt;

&lt;h3&gt;
  
  
  🟣 Best Use of Render
&lt;/h3&gt;

&lt;p&gt;BuildFolio's whole production stack runs on Render:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; the React + Vite app is built and served as a static site.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; the FastAPI service runs as a Render web service.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database:&lt;/strong&gt; production uses a managed PostgreSQL database through the &lt;code&gt;DATABASE_URL&lt;/code&gt; environment variable. Local development uses SQLite, so nothing changes in the code between the two.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configuration:&lt;/strong&gt; &lt;code&gt;SECRET_KEY&lt;/code&gt;, &lt;code&gt;CORS_ORIGINS&lt;/code&gt; and &lt;code&gt;COOKIE_SECURE&lt;/code&gt; are set as Render environment variables, so auth cookies are HTTPS-only and the CORS allow-list is locked down.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Public sharing:&lt;/strong&gt; published portfolios are served from Render without login, which is what lets my friend send a link to anyone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Live app: &lt;a href="https://projectpulse-1-mjqh.onrender.com" rel="noopener noreferrer"&gt;https://projectpulse-1-mjqh.onrender.com&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Render gave me a full-stack deployment with a database in one place, which mattered with a weekend deadline.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔷 Best Use of Gemma
&lt;/h3&gt;

&lt;p&gt;Gemma is the model behind portfolio generation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Model:&lt;/strong&gt; &lt;code&gt;gemma3:1b&lt;/code&gt;, run locally through Ollama and configured with &lt;code&gt;AI_MODEL&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Job:&lt;/strong&gt; it reads a project's description, tasks, components and notes, and returns a structured &lt;code&gt;ProjectKnowledge&lt;/code&gt; JSON object. The backend validates it and maps it to portfolio sections.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Making a 1B model dependable:&lt;/strong&gt; schema-validated output, up to 3 automatic retries on invalid or empty responses, and a &lt;code&gt;confirmed&lt;/code&gt; / &lt;code&gt;inferred&lt;/code&gt; / &lt;code&gt;unknown&lt;/code&gt; tag on every fact, so the author can see what to verify.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Why a small model:&lt;/strong&gt; it runs on my CPU-only machine with no API key and no per-call cost.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gemma runs locally and is not part of the Render deployment. The demo video shows generation working end to end.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>hf26challenge</category>
    </item>
  </channel>
</rss>
