<?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: Nadun Jayaweera</title>
    <description>The latest articles on DEV Community by Nadun Jayaweera (@nadunjayaweera).</description>
    <link>https://dev.to/nadunjayaweera</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%2F971686%2Fdb81c529-3c53-4797-8a1e-993dad50adaf.jpeg</url>
      <title>DEV Community: Nadun Jayaweera</title>
      <link>https://dev.to/nadunjayaweera</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/nadunjayaweera"/>
    <language>en</language>
    <item>
      <title>LazyDesk AI: Let Local AI Clean Up Your Digital Mess</title>
      <dc:creator>Nadun Jayaweera</dc:creator>
      <pubDate>Thu, 22 Oct 2026 18:39:30 +0000</pubDate>
      <link>https://dev.to/nadunjayaweera/lazydesk-ai-let-local-ai-clean-up-your-digital-mess-nlp</link>
      <guid>https://dev.to/nadunjayaweera/lazydesk-ai-let-local-ai-clean-up-your-digital-mess-nlp</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/hacktoberfest-week3-2026-10-19"&gt;Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;I built &lt;strong&gt;LazyDesk AI&lt;/strong&gt;, a local AI-powered file cleanup assistant that helps organize messy filenames without making the user do all the boring decision-making.&lt;/p&gt;

&lt;p&gt;The idea is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your files are messy. Your weekend doesn't have to be.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A lot of us have folders like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Downloads
Desktop
Documents
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;filled with files such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;invoice-final2.pdf
project-final-final-v3.docx
IMG_9988.jpg
meeting_notes_latest.txt
expense-receipt-copy.pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cleaning this manually means deciding:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;what each file probably is&lt;/li&gt;
&lt;li&gt;what a better filename would be&lt;/li&gt;
&lt;li&gt;which folder it belongs in&lt;/li&gt;
&lt;li&gt;whether the filename is already good enough&lt;/li&gt;
&lt;li&gt;whether two similarly named files are actually related&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is exactly the kind of small task people keep putting off.&lt;/p&gt;

&lt;p&gt;LazyDesk AI reduces that effort.&lt;/p&gt;

&lt;p&gt;The user simply pastes a list of filenames and clicks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Organize with AI
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The app then uses a local Gemma model to generate a cleanup plan containing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;original filename&lt;/li&gt;
&lt;li&gt;suggested filename&lt;/li&gt;
&lt;li&gt;suggested folder&lt;/li&gt;
&lt;li&gt;reason for the suggestion&lt;/li&gt;
&lt;li&gt;confidence level&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;invoice-ioc-oct.pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;might become:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ioc-October-Invoice.pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;with a suggested folder:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Finance/Invoices
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and an explanation such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;The filename appears to describe an invoice for Ioc.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Who gets to be a little lazier?
&lt;/h3&gt;

&lt;p&gt;LazyDesk is useful for anyone who regularly deals with messy digital folders, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;developers&lt;/li&gt;
&lt;li&gt;project managers&lt;/li&gt;
&lt;li&gt;freelancers&lt;/li&gt;
&lt;li&gt;office staff&lt;/li&gt;
&lt;li&gt;students&lt;/li&gt;
&lt;li&gt;small business owners&lt;/li&gt;
&lt;li&gt;anyone whose Downloads folder has become a graveyard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of manually organizing everything one file at a time, the user lets AI make the first set of decisions.&lt;/p&gt;




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

&lt;p&gt;Here is my video demo:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/Edtroqk8eAY" rel="noopener noreferrer"&gt;https://youtu.be/Edtroqk8eAY&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The demo shows the full workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Paste messy filenames
        ↓
Enable Lazy Mode
        ↓
Organize with AI
        ↓
Review filename suggestions
        ↓
Review folder suggestions
        ↓
Edit suggestions if needed
        ↓
Approve cleanup plan
        ↓
Save cleanup history locally
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One important design choice is that LazyDesk does &lt;strong&gt;not&lt;/strong&gt; automatically rename, move, or delete real files in the current version.&lt;/p&gt;

&lt;p&gt;It creates a cleanup plan first.&lt;/p&gt;

&lt;p&gt;That keeps the experience safe while still removing most of the decision-making.&lt;/p&gt;




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

&lt;p&gt;The full source code is available here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/nadunjayaweera/lazydesk-ai.git" rel="noopener noreferrer"&gt;https://github.com/nadunjayaweera/lazydesk-ai.git&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React frontend&lt;/li&gt;
&lt;li&gt;Node.js / Express backend&lt;/li&gt;
&lt;li&gt;Ollama integration&lt;/li&gt;
&lt;li&gt;Gemma 3 1B local inference&lt;/li&gt;
&lt;li&gt;Local JSON persistence&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;LazyDesk AI uses a simple architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;React Frontend
      ↓
Node.js / Express
      ↓
Ollama
      ↓
Gemma 3 1B
      ↓
Structured Cleanup Plan
      ↓
User Review / Edit
      ↓
Approve
      ↓
Local JSON Storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Frontend
&lt;/h3&gt;

&lt;p&gt;The frontend is built with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Vite&lt;/li&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The main screen contains:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Workspace name&lt;/li&gt;
&lt;li&gt;Lazy Mode toggle&lt;/li&gt;
&lt;li&gt;Filename input&lt;/li&gt;
&lt;li&gt;AI-generated cleanup plan&lt;/li&gt;
&lt;li&gt;Editable filename suggestions&lt;/li&gt;
&lt;li&gt;Editable folder suggestions&lt;/li&gt;
&lt;li&gt;Confidence indicators&lt;/li&gt;
&lt;li&gt;Approval button&lt;/li&gt;
&lt;li&gt;Cleanup history&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal was to make the interface feel like a small productivity utility rather than a chatbot.&lt;/p&gt;




&lt;h3&gt;
  
  
  Lazy Mode
&lt;/h3&gt;

&lt;p&gt;Lazy Mode is the main feature that matches the theme of the challenge.&lt;/p&gt;

&lt;p&gt;When it is enabled, the user does not need to manually configure categories or folder rules first.&lt;/p&gt;

&lt;p&gt;The concept is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You provide the mess. AI makes the decisions.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The user pastes something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;invoice-ioc-oct.pdf
IMG_1234.jpg
Apex-agreement-final.docx
meeting_notes.txt
expense-receipt.pdf
project-final-final-v2.docx
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;and LazyDesk decides how the files could be organized.&lt;/p&gt;




&lt;h3&gt;
  
  
  Local AI
&lt;/h3&gt;

&lt;p&gt;LazyDesk currently uses:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemma 3 1B&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;running locally through:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ollama&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The backend sends Gemma the list of filenames with instructions such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Do not delete any file.
- Do not invent file contents.
- Preserve file extensions.
- Suggest clearer filenames.
- Suggest practical folder paths.
- Preserve client or project names.
- Avoid overly long filenames.
- Return valid JSON only.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gemma returns structured JSON.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"summary"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Organized 4 files into practical folders."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"files"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"original_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"invoice-ioc-oct.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"suggested_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Ioc-October-Invoice.pdf"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"folder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Finance/Invoices"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"reason"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"The filename appears to describe an invoice for Ioc."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"confidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"high"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The response is normalized by the backend before being displayed in React.&lt;/p&gt;




&lt;h3&gt;
  
  
  Confidence Levels
&lt;/h3&gt;

&lt;p&gt;Each AI suggestion also includes a confidence value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;high
medium
low
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This helps the user understand when the model is reasonably confident about a filename versus when the suggestion may need more review.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;invoice-ioc-oct.pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;may have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;high confidence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;IMG_9988.jpg
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;may have:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;low confidence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;because the filename itself does not explain what the image contains.&lt;/p&gt;

&lt;p&gt;That is important because LazyDesk currently works from filenames only.&lt;/p&gt;

&lt;p&gt;It does not pretend to know what is inside a file.&lt;/p&gt;




&lt;h3&gt;
  
  
  Editable AI Suggestions
&lt;/h3&gt;

&lt;p&gt;I also wanted to avoid treating every AI suggestion as automatically correct.&lt;/p&gt;

&lt;p&gt;The user can edit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;suggested filename&lt;/li&gt;
&lt;li&gt;suggested folder&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;before approving the plan.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;AI suggestion:
Projects/Reports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can be changed to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Clients/Apex/Reports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;before approval.&lt;/p&gt;

&lt;p&gt;When the cleanup plan is approved, the edited version is saved locally.&lt;/p&gt;

&lt;p&gt;This gives the AI the boring first-pass work while keeping the user in control.&lt;/p&gt;




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

&lt;p&gt;The current version intentionally does not perform destructive actions.&lt;/p&gt;

&lt;p&gt;LazyDesk does not automatically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;delete files&lt;/li&gt;
&lt;li&gt;rename real files&lt;/li&gt;
&lt;li&gt;move real files&lt;/li&gt;
&lt;li&gt;inspect file contents&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The current workflow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Recommend
   ↓
Review
   ↓
Edit
   ↓
Approve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A future version could continue with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Execute
   ↓
Undo
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;but I wanted the Hacktoberfest version to focus on safe AI-assisted planning first.&lt;/p&gt;




&lt;h3&gt;
  
  
  Local JSON Storage
&lt;/h3&gt;

&lt;p&gt;Cleanup plans are stored locally in JSON.&lt;/p&gt;

&lt;p&gt;The backend saves them in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;server/data/cleanup-plans.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each saved plan contains:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Workspace
Mode
Summary
Status
Files
Created date
Approved date
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Because of this, the user can refresh the frontend and still reopen previous cleanup plans.&lt;/p&gt;

&lt;p&gt;No database is required for the current MVP.&lt;/p&gt;




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

&lt;p&gt;Open innovation matters a lot for LazyDesk because file organization often involves private or work-related information.&lt;/p&gt;

&lt;p&gt;Even filenames can reveal information such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;salary-report-october.xlsx
client-contract-final.docx
internal-meeting-notes.txt
customer-invoice.pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this kind of utility, I wanted the core AI inference to run locally.&lt;/p&gt;

&lt;h3&gt;
  
  
  Privacy
&lt;/h3&gt;

&lt;p&gt;Gemma runs locally through Ollama.&lt;/p&gt;

&lt;p&gt;That means the filename list does not need to be sent to a third-party cloud AI service for the core cleanup workflow.&lt;/p&gt;

&lt;p&gt;This is particularly useful for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;client documents&lt;/li&gt;
&lt;li&gt;financial files&lt;/li&gt;
&lt;li&gt;internal work files&lt;/li&gt;
&lt;li&gt;personal documents&lt;/li&gt;
&lt;li&gt;company project folders&lt;/li&gt;
&lt;/ul&gt;




&lt;h3&gt;
  
  
  No Per-Request AI Cost
&lt;/h3&gt;

&lt;p&gt;File organization is something a person might use repeatedly.&lt;/p&gt;

&lt;p&gt;Today it might be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Downloads
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Tomorrow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Desktop
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Next week:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Old Projects
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a paid cloud AI API, each cleanup request can create additional usage cost.&lt;/p&gt;

&lt;p&gt;With a local open-weight model, once the model is installed, there is no per-request AI provider charge for the core inference.&lt;/p&gt;

&lt;p&gt;That makes LazyDesk practical as a small utility someone can run whenever the digital clutter gets out of control.&lt;/p&gt;




&lt;h3&gt;
  
  
  Offline-Friendly
&lt;/h3&gt;

&lt;p&gt;Once Ollama and Gemma are installed, the AI inference can run locally without requiring a cloud AI service.&lt;/p&gt;

&lt;p&gt;That means LazyDesk can still generate cleanup plans even without an internet connection.&lt;/p&gt;




&lt;h3&gt;
  
  
  Model Flexibility
&lt;/h3&gt;

&lt;p&gt;LazyDesk is also not permanently tied to one commercial AI provider.&lt;/p&gt;

&lt;p&gt;Because it uses Ollama, another compatible open-weight model could be tested later.&lt;/p&gt;

&lt;p&gt;For example, different models could be compared for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;filename understanding&lt;/li&gt;
&lt;li&gt;folder categorization&lt;/li&gt;
&lt;li&gt;inference speed&lt;/li&gt;
&lt;li&gt;memory usage&lt;/li&gt;
&lt;li&gt;larger context windows&lt;/li&gt;
&lt;li&gt;better structured output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That flexibility is one of the main reasons open-weight AI works well for a small utility like this.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Lazy Payoff
&lt;/h2&gt;

&lt;p&gt;The theme for this challenge is &lt;strong&gt;Slow and Steady&lt;/strong&gt;, and LazyDesk is intentionally designed around doing less manual work.&lt;/p&gt;

&lt;p&gt;Without LazyDesk, organizing a messy folder usually looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Open folder
↓
Look at first file
↓
Decide what it is
↓
Think of a better name
↓
Choose a folder
↓
Repeat for every file
↓
Get bored
↓
Close the folder
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With LazyDesk:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Paste filenames
↓
Click Organize with AI
↓
Review
↓
Approve
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI handles the repetitive first-pass decisions.&lt;/p&gt;

&lt;p&gt;The user only spends time correcting suggestions that actually need attention.&lt;/p&gt;

&lt;p&gt;That is the lazy payoff:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;less deciding, less renaming, less folder planning.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;For a small batch of files, the time saved may only be a few minutes.&lt;/p&gt;

&lt;p&gt;But for a large Downloads folder or project archive, removing the repeated decision-making can save much more effort.&lt;/p&gt;

&lt;p&gt;More importantly, it lowers the mental barrier to starting the cleanup at all.&lt;/p&gt;

&lt;p&gt;Sometimes the biggest productivity improvement is simply making an annoying task easy enough that you finally do it.&lt;/p&gt;




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

&lt;p&gt;Building LazyDesk helped me explore AI as a tool for reducing repetitive decision-making rather than just generating text.&lt;/p&gt;

&lt;p&gt;I practiced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;running Gemma locally with Ollama&lt;/li&gt;
&lt;li&gt;connecting React to local AI&lt;/li&gt;
&lt;li&gt;building structured prompts&lt;/li&gt;
&lt;li&gt;validating JSON output&lt;/li&gt;
&lt;li&gt;building confidence indicators&lt;/li&gt;
&lt;li&gt;creating editable AI recommendations&lt;/li&gt;
&lt;li&gt;building an approval workflow&lt;/li&gt;
&lt;li&gt;persisting data using JSON&lt;/li&gt;
&lt;li&gt;designing safer AI automation&lt;/li&gt;
&lt;li&gt;keeping the user in control&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of the biggest lessons from this project was that useful automation does not need to be fully autonomous.&lt;/p&gt;

&lt;p&gt;For something involving files, it can be better to let AI prepare the work while the human makes the final decision.&lt;/p&gt;

&lt;p&gt;That is the balance I tried to build into LazyDesk.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;LazyDesk AI is intentionally simple.&lt;/p&gt;

&lt;p&gt;It does not try to become a complete file management system.&lt;/p&gt;

&lt;p&gt;It focuses on one annoying problem:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;deciding how messy files should be organized.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The user provides the filenames.&lt;/p&gt;

&lt;p&gt;Gemma provides the first-pass cleanup plan.&lt;/p&gt;

&lt;p&gt;The user reviews it.&lt;/p&gt;

&lt;p&gt;Then LazyDesk remembers the decision.&lt;/p&gt;

&lt;p&gt;For the &lt;strong&gt;Slow and Steady&lt;/strong&gt; challenge, that felt like the right approach:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Let AI do the boring part so you can be a little lazier.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>MenuBridge AI: Local AI Menu Translation That Preserves the Identity of Local Dishes</title>
      <dc:creator>Nadun Jayaweera</dc:creator>
      <pubDate>Sat, 17 Oct 2026 17:16:46 +0000</pubDate>
      <link>https://dev.to/nadunjayaweera/menubridge-ai-local-ai-menu-translation-that-preserves-the-identity-of-local-dishes-4g6n</link>
      <guid>https://dev.to/nadunjayaweera/menubridge-ai-local-ai-menu-translation-that-preserves-the-identity-of-local-dishes-4g6n</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;I built &lt;strong&gt;MenuBridge AI&lt;/strong&gt;, a local AI-powered restaurant menu translation assistant.&lt;/p&gt;

&lt;p&gt;The idea came from a practical problem in the hospitality industry.&lt;/p&gt;

&lt;p&gt;Restaurants, cafés, hotels, villas, and other hospitality businesses often serve international guests and need multilingual menus. Translating normal text is relatively straightforward, but restaurant menus are different.&lt;/p&gt;

&lt;p&gt;Local dishes such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Kottu&lt;/li&gt;
&lt;li&gt;Pol Sambol&lt;/li&gt;
&lt;li&gt;Hoppers&lt;/li&gt;
&lt;li&gt;Lamprais&lt;/li&gt;
&lt;li&gt;Watalappan&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;have cultural meaning that can easily be lost when they are translated literally.&lt;/p&gt;

&lt;p&gt;For example, a restaurant probably does not want &lt;strong&gt;Kottu&lt;/strong&gt; converted into an awkward literal translation.&lt;/p&gt;

&lt;p&gt;Instead, it may want something like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Seafood Kottu
→
Kottu aux fruits de mer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;while translating the description naturally for French-speaking customers.&lt;/p&gt;

&lt;p&gt;That is what MenuBridge AI is designed to do.&lt;/p&gt;

&lt;p&gt;It allows the restaurant to enter:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Restaurant name&lt;/li&gt;
&lt;li&gt;Source language&lt;/li&gt;
&lt;li&gt;Target language&lt;/li&gt;
&lt;li&gt;Dish name&lt;/li&gt;
&lt;li&gt;Description&lt;/li&gt;
&lt;li&gt;Category&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The restaurant can also maintain its own &lt;strong&gt;Restaurant Dictionary&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Term:
Kottu

Rule:
Keep the word Kottu in the translated menu name.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Another example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Term:
Pol Sambol

Rule:
Keep Pol Sambol as the original dish name and describe it as a Sri Lankan coconut relish.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These rules are automatically included when the local AI model generates the translation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Who would pay for it?
&lt;/h3&gt;

&lt;p&gt;The target users are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Restaurants&lt;/li&gt;
&lt;li&gt;Cafés&lt;/li&gt;
&lt;li&gt;Hotels&lt;/li&gt;
&lt;li&gt;Villas&lt;/li&gt;
&lt;li&gt;Guest houses&lt;/li&gt;
&lt;li&gt;Food delivery businesses&lt;/li&gt;
&lt;li&gt;Tourism businesses&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A small hospitality business may regularly need menu translations but may not have an in-house translator.&lt;/p&gt;

&lt;p&gt;MenuBridge AI could therefore work as either:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;a one-time menu translation service, or&lt;/li&gt;
&lt;li&gt;a low-cost recurring menu translation tool.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The important part is that the restaurant can define how its own dishes should be handled instead of relying completely on a generic translator.&lt;/p&gt;




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

&lt;p&gt;Here is my video demonstration of MenuBridge AI:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/TvbMEBuHEhk" rel="noopener noreferrer"&gt;https://youtu.be/TvbMEBuHEhk&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The demo shows the complete workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Restaurant Setup
        ↓
Add Menu Item
        ↓
Restaurant Dictionary
        ↓
Translate with Local AI
        ↓
Review Translation
        ↓
Approve
        ↓
Translation History
        ↓
Export Approved Menu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The application also keeps generated translations and terminology rules locally so they remain available after refreshing the application.&lt;/p&gt;




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

&lt;p&gt;The complete source code is available on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/nadunjayaweera/OrderInRestaurant-ai.git" rel="noopener noreferrer"&gt;https://github.com/nadunjayaweera/OrderInRestaurant-ai.git&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The project contains both the React frontend and Node.js/Express backend.&lt;/p&gt;




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

&lt;p&gt;MenuBridge AI uses a relatively simple architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;React Frontend
      ↓
Node.js / Express
      ↓
Restaurant Dictionary
      ↓
Ollama
      ↓
Gemma 3 1B
      ↓
Structured JSON Translation
      ↓
Review / Approve
      ↓
Local JSON Storage
      ↓
CSV Export
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Frontend
&lt;/h3&gt;

&lt;p&gt;The frontend is built with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Vite&lt;/li&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The interface contains three main areas.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Restaurant Setup
&lt;/h3&gt;

&lt;p&gt;The user selects:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Restaurant Name
Source Language
Target Language
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Restaurant: Ceylon Kitchen
Source: English
Target: French
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Menu Item
&lt;/h3&gt;

&lt;p&gt;The restaurant enters the existing menu item.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dish:
Seafood Kottu

Description:
Chopped roti mixed with prawns, cuttlefish,
vegetables, egg, spring onions, and house spices.

Category:
Main Course
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Restaurant Dictionary
&lt;/h3&gt;

&lt;p&gt;This is one of the most important parts of the project.&lt;/p&gt;

&lt;p&gt;Instead of asking a generic translation model to decide everything itself, the restaurant can provide terminology instructions.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Kottu
Keep the word Kottu in the translated menu name.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Hoppers
Keep the original word Hoppers and explain that it
is a Sri Lankan bowl-shaped pancake.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These instructions are stored locally and sent to the AI when a menu item is translated.&lt;/p&gt;




&lt;h3&gt;
  
  
  Local AI
&lt;/h3&gt;

&lt;p&gt;MenuBridge AI currently uses:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemma 3 1B&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;running locally through:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ollama&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The backend sends Gemma information about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the restaurant&lt;/li&gt;
&lt;li&gt;source language&lt;/li&gt;
&lt;li&gt;target language&lt;/li&gt;
&lt;li&gt;menu item&lt;/li&gt;
&lt;li&gt;description&lt;/li&gt;
&lt;li&gt;category&lt;/li&gt;
&lt;li&gt;restaurant terminology rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also instruct the model to follow several important rules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Preserve culturally important dish names.
- Follow the restaurant terminology rules.
- Never invent ingredients.
- Never remove ingredients.
- Do not change allergen or dietary information.
- Avoid awkward literal translations.
- Keep descriptions concise.
- Return valid JSON only.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Gemma then returns a structured result such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"original_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Seafood Kottu"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"translated_name"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Kottu aux fruits de mer"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"translated_description"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Roti haché sauté avec des crevettes, de la seiche, des légumes, un œuf et des épices maison."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"cultural_note"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Kottu is a Sri Lankan dish name and has been preserved."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"kept_original_term"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using JSON output makes it much easier for the frontend to reliably display the generated translation.&lt;/p&gt;




&lt;h3&gt;
  
  
  Translation Review and Approval
&lt;/h3&gt;

&lt;p&gt;I did not want the application to treat every AI-generated translation as automatically correct.&lt;/p&gt;

&lt;p&gt;Every generated result is initially stored as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GENERATED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The restaurant can review it and then approve it.&lt;/p&gt;

&lt;p&gt;After approval:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;APPROVED
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;is stored with the translation.&lt;/p&gt;

&lt;p&gt;This gives the restaurant control over what eventually gets published.&lt;/p&gt;

&lt;p&gt;That matters because even a good AI translation can sometimes choose terminology differently from what the business prefers.&lt;/p&gt;




&lt;h3&gt;
  
  
  Local JSON Storage
&lt;/h3&gt;

&lt;p&gt;I intentionally kept the project lightweight.&lt;/p&gt;

&lt;p&gt;Instead of adding MySQL or another database, MenuBridge stores its current data in local JSON files.&lt;/p&gt;

&lt;p&gt;It stores:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Restaurant terminology rules
Generated translations
Approved translations
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means that refreshing the React application does not remove the restaurant's terminology or translation history.&lt;/p&gt;

&lt;p&gt;It also keeps the MVP simple enough for a small business use case.&lt;/p&gt;




&lt;h3&gt;
  
  
  CSV Export
&lt;/h3&gt;

&lt;p&gt;Approved menu translations can be exported as CSV.&lt;/p&gt;

&lt;p&gt;The export includes information such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Restaurant
Category
Source Language
Target Language
Original Name
Original Description
Translated Name
Translated Description
Cultural Note
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This makes the translated data easier to move into other workflows such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Excel&lt;/li&gt;
&lt;li&gt;Google Sheets&lt;/li&gt;
&lt;li&gt;restaurant POS systems&lt;/li&gt;
&lt;li&gt;online menus&lt;/li&gt;
&lt;li&gt;QR menus&lt;/li&gt;
&lt;li&gt;printed menus&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Testing with Sri Lankan Dishes
&lt;/h2&gt;

&lt;p&gt;I tested MenuBridge with several Sri Lankan dishes because they are good examples of why restaurant translation needs context.&lt;/p&gt;

&lt;p&gt;Some of the test items included:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Seafood Kottu
Pol Sambol
Egg Hoppers
String Hoppers
Lamprais
Isso Wade
Watalappan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For culturally important terms, I used restaurant dictionary rules to tell the AI when the original name should remain.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Lamprais
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;can remain &lt;strong&gt;Lamprais&lt;/strong&gt;, while the menu description explains what it is to an international customer.&lt;/p&gt;

&lt;p&gt;That is more useful than replacing the culturally recognized name with an overly literal translation.&lt;/p&gt;




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

&lt;p&gt;Open innovation is particularly important for MenuBridge AI because this is intended to be useful for small businesses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Lower Operating Cost
&lt;/h3&gt;

&lt;p&gt;A restaurant may translate hundreds of menu items over time.&lt;/p&gt;

&lt;p&gt;It may also repeatedly update:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;seasonal dishes&lt;/li&gt;
&lt;li&gt;descriptions&lt;/li&gt;
&lt;li&gt;ingredients&lt;/li&gt;
&lt;li&gt;menu categories&lt;/li&gt;
&lt;li&gt;promotional menus&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If every translation requires a paid cloud AI request, the operational cost grows with usage.&lt;/p&gt;

&lt;p&gt;With MenuBridge AI, Gemma runs locally through Ollama.&lt;/p&gt;

&lt;p&gt;Once the model is installed, the application does not need to pay an AI provider for every translation request.&lt;/p&gt;

&lt;p&gt;That makes a low-cost side-hustle product much more realistic.&lt;/p&gt;




&lt;h3&gt;
  
  
  Privacy
&lt;/h3&gt;

&lt;p&gt;Restaurants may also have menu information they would prefer to keep internally.&lt;/p&gt;

&lt;p&gt;That could include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;upcoming dishes&lt;/li&gt;
&lt;li&gt;recipe descriptions&lt;/li&gt;
&lt;li&gt;ingredient information&lt;/li&gt;
&lt;li&gt;internal terminology&lt;/li&gt;
&lt;li&gt;restaurant-specific naming conventions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Running the model locally means the core AI translation can happen on the restaurant's own machine rather than requiring the menu data to be sent to a remote AI service.&lt;/p&gt;




&lt;h3&gt;
  
  
  Restaurant-Specific Customization
&lt;/h3&gt;

&lt;p&gt;This is probably the biggest advantage for this project.&lt;/p&gt;

&lt;p&gt;A generic translator does not know how every restaurant wants its dishes represented.&lt;/p&gt;

&lt;p&gt;MenuBridge allows a business to define instructions such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Kottu
→ Keep Kottu in the name
&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;Pol Sambol
→ Keep the original term and explain that it is
a Sri Lankan coconut relish
&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;Hoppers
→ Keep Hoppers and explain the type of dish
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The open-weight AI model can then use these instructions as context.&lt;/p&gt;

&lt;p&gt;This gives the restaurant more control over how its menu is translated.&lt;/p&gt;




&lt;h3&gt;
  
  
  Model Flexibility
&lt;/h3&gt;

&lt;p&gt;The application is also not permanently tied to one commercial AI provider.&lt;/p&gt;

&lt;p&gt;Because the inference layer runs through Ollama, I can experiment with other compatible open-weight models later.&lt;/p&gt;

&lt;p&gt;That means MenuBridge could eventually evaluate different models for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;translation quality&lt;/li&gt;
&lt;li&gt;language support&lt;/li&gt;
&lt;li&gt;speed&lt;/li&gt;
&lt;li&gt;hardware requirements&lt;/li&gt;
&lt;li&gt;restaurant terminology handling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;without redesigning the entire product around one proprietary API.&lt;/p&gt;




&lt;h2&gt;
  
  
  Could This Become a Real Side Hustle?
&lt;/h2&gt;

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

&lt;p&gt;The project is intentionally small and focused on one business problem.&lt;/p&gt;

&lt;p&gt;A possible service could be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Restaurant provides their existing menu
        ↓
MenuBridge translates it
        ↓
Restaurant reviews translations
        ↓
Approved multilingual menu is exported
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It could be offered as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;One-Time Menu Translation
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for a restaurant that only needs an existing menu translated.&lt;/p&gt;

&lt;p&gt;Or it could later become:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Monthly Menu Translation Service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;for restaurants that regularly add or change dishes.&lt;/p&gt;

&lt;p&gt;Future commercial features could include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Bulk Excel upload&lt;/li&gt;
&lt;li&gt;Multiple target languages at once&lt;/li&gt;
&lt;li&gt;Restaurant accounts&lt;/li&gt;
&lt;li&gt;Multiple restaurant profiles&lt;/li&gt;
&lt;li&gt;Translation editing&lt;/li&gt;
&lt;li&gt;QR menu generation&lt;/li&gt;
&lt;li&gt;POS integration&lt;/li&gt;
&lt;li&gt;Menu publishing&lt;/li&gt;
&lt;li&gt;Translation history&lt;/li&gt;
&lt;li&gt;AI-assisted allergen checks&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this challenge, however, I intentionally kept the MVP focused on the central problem.&lt;/p&gt;




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

&lt;p&gt;This was another step in my journey of learning how open-weight AI can be integrated into real applications.&lt;/p&gt;

&lt;p&gt;I practiced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running Gemma locally with Ollama&lt;/li&gt;
&lt;li&gt;Connecting local AI to Node.js&lt;/li&gt;
&lt;li&gt;Building structured prompts&lt;/li&gt;
&lt;li&gt;Requesting predictable JSON output&lt;/li&gt;
&lt;li&gt;Validating model-generated data&lt;/li&gt;
&lt;li&gt;Connecting React to an AI backend&lt;/li&gt;
&lt;li&gt;Persisting application data with JSON&lt;/li&gt;
&lt;li&gt;Building review and approval workflows&lt;/li&gt;
&lt;li&gt;Exporting generated content to CSV&lt;/li&gt;
&lt;li&gt;Designing AI around a specific industry problem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One of my biggest takeaways from this project is that the model itself does not need to solve everything.&lt;/p&gt;

&lt;p&gt;Giving the restaurant control through terminology rules makes the overall system much more useful.&lt;/p&gt;

&lt;p&gt;The AI provides flexibility, while the restaurant provides domain knowledge.&lt;/p&gt;

&lt;p&gt;That combination is what makes MenuBridge different from simply putting a generic translation box inside an application.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The goal of MenuBridge AI is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Translate the menu, not the identity of the food.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A restaurant should be able to make its menu understandable to international customers while still keeping the names and cultural meaning that make its dishes unique.&lt;/p&gt;

&lt;p&gt;Using Gemma locally through Ollama made it possible to build this without requiring a paid AI API or sending every menu item to an external AI provider.&lt;/p&gt;

&lt;p&gt;For a small hospitality business, that combination of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Local AI
+
Restaurant-specific terminology
+
Human review
+
Simple export
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;could become a practical and affordable menu translation workflow.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>OutsideFlow AI: Spend Less Time Planning and More Time Outside</title>
      <dc:creator>Nadun Jayaweera</dc:creator>
      <pubDate>Fri, 09 Oct 2026 19:44:11 +0000</pubDate>
      <link>https://dev.to/nadunjayaweera/outsideflow-ai-spend-less-time-planning-and-more-time-outside-5211</link>
      <guid>https://dev.to/nadunjayaweera/outsideflow-ai-spend-less-time-planning-and-more-time-outside-5211</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;h1&gt;
  
  
  OutsideFlow AI: Spend Less Time Planning and More Time Outside
&lt;/h1&gt;

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

&lt;p&gt;I built &lt;strong&gt;OutsideFlow AI&lt;/strong&gt;, a local AI-powered outdoor activity planner designed to do something slightly unusual for an AI application:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;get people away from the screen.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;A lot of apps are designed to increase engagement and keep users inside the application for as long as possible.&lt;/p&gt;

&lt;p&gt;OutsideFlow does the opposite.&lt;/p&gt;

&lt;p&gt;The user opens the app, tells it how much free time they have, how they are feeling, and what kind of outdoor environment is available.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Available time: 30 minutes
Mood: Relax
Environment: Neighborhood

Extra preference:
I want something quiet and I don't want to spend money.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;OutsideFlow then uses a locally running open-weight AI model to create a short outdoor plan.&lt;/p&gt;

&lt;p&gt;A generated plan might look like this:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;30-Minute Neighborhood Reset

1. Walk outside without headphones — 10 min
2. Notice three things you normally ignore — 7 min
3. Sit somewhere quiet and observe your surroundings — 8 min
4. Walk home at a comfortable pace — 5 min
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The user then clicks:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start Outdoor Session
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;and the app displays one final message:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Put your phone away and go 🌿&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the main idea behind the project.&lt;/p&gt;

&lt;p&gt;The screen should be the shortest part of the experience.&lt;/p&gt;
&lt;h3&gt;
  
  
  Who is it for?
&lt;/h3&gt;

&lt;p&gt;OutsideFlow is for people who want to spend more time outdoors but sometimes get stuck deciding what to do.&lt;/p&gt;

&lt;p&gt;Someone may only have 15 or 30 minutes available.&lt;/p&gt;

&lt;p&gt;They may want to relax, exercise, explore, or do something social.&lt;/p&gt;

&lt;p&gt;Instead of spending another 20 minutes searching online for ideas, OutsideFlow creates a simple plan in seconds and encourages the user to leave the screen.&lt;/p&gt;


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

&lt;p&gt;Here is a short video showing OutsideFlow AI in action:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;YouTube Demo:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
  &lt;iframe src="https://www.youtube.com/embed/1mkiWU1VdSM" width="710" height="399"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The demo shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Selecting available time&lt;/li&gt;
&lt;li&gt;Selecting a mood&lt;/li&gt;
&lt;li&gt;Choosing an outdoor environment&lt;/li&gt;
&lt;li&gt;Adding an optional preference&lt;/li&gt;
&lt;li&gt;Generating an outdoor plan with Gemma&lt;/li&gt;
&lt;li&gt;Starting the outdoor session&lt;/li&gt;
&lt;li&gt;Reaching the final "Put your phone away and go" screen&lt;/li&gt;
&lt;/ul&gt;


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

&lt;p&gt;The complete source code is available on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub Repository:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
&lt;/p&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/nadunjayaweera" rel="noopener noreferrer"&gt;
        nadunjayaweera
      &lt;/a&gt; / &lt;a href="https://github.com/nadunjayaweera/outsideflow-ai" rel="noopener noreferrer"&gt;
        outsideflow-ai
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      A local AI outdoor activity planner built with React, Node.js, Ollama and Gemma for Hacktoberfest 2026 Touch Grass.
    &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;OutsideFlow AI&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;OutsideFlow AI is a local AI-powered outdoor activity planner built for the &lt;strong&gt;Hacktoberfest 2026 Open-Source AI Challenge Week 1: Touch Grass&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The goal is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Spend less time planning. Spend more time outside.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;OutsideFlow asks the user for a few preferences, generates a personalized outdoor plan using a locally running open-weight AI model, and then encourages the user to put the phone away and actually go outside.&lt;/p&gt;




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

&lt;p&gt;This project was built for the Hacktoberfest 2026 theme:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Touch Grass&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The challenge asks participants to build something with open-source AI that gets people off the screen and into the real world.&lt;/p&gt;

&lt;p&gt;OutsideFlow is designed specifically around that idea.&lt;/p&gt;

&lt;p&gt;The screen is only used for a short planning step.&lt;/p&gt;

&lt;p&gt;After the outdoor plan is generated, the user starts the session and is encouraged to:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Put your phone away and go 🌿&lt;/p&gt;
&lt;/blockquote&gt;




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

&lt;p&gt;People often want to take…&lt;/p&gt;&lt;/div&gt;


&lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/nadunjayaweera/outsideflow-ai" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;
&lt;br&gt;


&lt;p&gt;OutsideFlow is a small full-stack application built with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Vite&lt;/li&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;Express&lt;/li&gt;
&lt;li&gt;Ollama&lt;/li&gt;
&lt;li&gt;Gemma 3 1B&lt;/li&gt;
&lt;/ul&gt;




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

&lt;p&gt;OutsideFlow follows a simple architecture:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Preferences
       ↓
React Frontend
       ↓
Node.js / Express Backend
       ↓
Ollama
       ↓
Gemma 3 1B
       ↓
Structured Outdoor Plan
       ↓
React Session Screen
       ↓
Put the phone away and go outside
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Frontend
&lt;/h3&gt;

&lt;p&gt;The frontend is built with React and Vite.&lt;/p&gt;

&lt;p&gt;The user selects:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Available time: 15, 30, or 60 minutes&lt;/li&gt;
&lt;li&gt;Mood: Relax, Exercise, Explore, or Social&lt;/li&gt;
&lt;li&gt;Environment: Neighborhood, Park, Garden, Beach, or Anywhere&lt;/li&gt;
&lt;li&gt;Optional extra preferences&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The frontend sends those values to the backend.&lt;/p&gt;

&lt;h3&gt;
  
  
  Backend
&lt;/h3&gt;

&lt;p&gt;The backend is built with Node.js and Express.&lt;/p&gt;

&lt;p&gt;It receives the user's preferences and creates a prompt for the AI model.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"time"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"30"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mood"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Relax"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"environment"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Neighborhood"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"note"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"I want something peaceful and I don't want to spend money."&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend asks Gemma to return structured JSON.&lt;/p&gt;

&lt;p&gt;Example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"30-Minute Quiet Neighborhood Reset"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"goal"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Relax outside with a calm and simple walking session."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"activities"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"step"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"activity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Walk slowly around your neighborhood without headphones"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"10 min"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"step"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"activity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Notice three plants or details you usually ignore"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"7 min"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"step"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"activity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Sit somewhere quiet and observe your surroundings"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"8 min"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"step"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"activity"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Walk home at a comfortable pace"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"duration"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"5 min"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend validates and normalizes the response before returning it to React.&lt;/p&gt;

&lt;h3&gt;
  
  
  AI
&lt;/h3&gt;

&lt;p&gt;OutsideFlow uses:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Gemma 3 1B&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;running locally through:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ollama&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I chose a small model because this project does not need a huge cloud-based model.&lt;/p&gt;

&lt;p&gt;The AI only needs to understand a few user preferences and generate a practical, structured outdoor plan.&lt;/p&gt;

&lt;h3&gt;
  
  
  Session Mode
&lt;/h3&gt;

&lt;p&gt;One part I specifically added for the challenge theme was the outdoor session screen.&lt;/p&gt;

&lt;p&gt;After generating the plan, the user clicks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Start Outdoor Session
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The normal planning UI disappears.&lt;/p&gt;

&lt;p&gt;The session screen shows only the essential steps and tells the user:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your plan is ready. The rest happens outside.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That was important because I did not want to build an outdoor app that still required the user to stare at the screen throughout the whole experience.&lt;/p&gt;




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

&lt;p&gt;Open innovation matters a lot for OutsideFlow because the AI is not simply an optional feature.&lt;/p&gt;

&lt;p&gt;It is what makes the personalized planning possible.&lt;/p&gt;

&lt;p&gt;A hard-coded application could display a list of generic outdoor ideas.&lt;/p&gt;

&lt;p&gt;But it would struggle to adapt naturally to combinations such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;15 minutes + Exercise + Beach
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;60 minutes + Explore + Park + no spending
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using an open-weight model makes the application much more flexible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Local Inference
&lt;/h3&gt;

&lt;p&gt;Gemma runs locally on the user's machine through Ollama.&lt;/p&gt;

&lt;p&gt;That means the core AI functionality does not need to send every request to a cloud AI service.&lt;/p&gt;

&lt;h3&gt;
  
  
  Privacy
&lt;/h3&gt;

&lt;p&gt;A user's preferences can contain personal information.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;I am feeling stressed today.
I only have 20 minutes.
I want somewhere quiet.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With local inference, those preferences can remain on the user's own computer.&lt;/p&gt;

&lt;h3&gt;
  
  
  No Per-Request AI Cost
&lt;/h3&gt;

&lt;p&gt;OutsideFlow does not need a paid AI API every time someone generates a plan.&lt;/p&gt;

&lt;p&gt;Once Gemma is installed locally, the user can generate plans without paying for each request.&lt;/p&gt;

&lt;h3&gt;
  
  
  Model Flexibility
&lt;/h3&gt;

&lt;p&gt;The application is not permanently tied to one AI provider.&lt;/p&gt;

&lt;p&gt;Because the AI layer runs through Ollama, another supported open-weight model could be tested or swapped in later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Offline-Friendly
&lt;/h3&gt;

&lt;p&gt;Once Ollama and the model are installed, the core planning feature can run locally without depending on an external AI API.&lt;/p&gt;

&lt;p&gt;That fits the idea behind OutsideFlow especially well.&lt;/p&gt;

&lt;p&gt;An application that encourages people to go outside should not require constant cloud connectivity just to create a simple activity plan.&lt;/p&gt;




&lt;h2&gt;
  
  
  Touch Grass
&lt;/h2&gt;

&lt;p&gt;The challenge theme made me think differently about how AI applications are usually designed.&lt;/p&gt;

&lt;p&gt;Many AI products encourage users to stay inside the interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Ask another question
↓
Generate another response
↓
Keep scrolling
↓
Repeat
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;OutsideFlow intentionally changes that pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Choose preferences
       ↓
Generate plan
       ↓
Start session
       ↓
Put phone away
       ↓
Go outside
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AI is there to remove the planning friction, not become the activity itself.&lt;/p&gt;

&lt;p&gt;That is the part of the project I like most.&lt;/p&gt;




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

&lt;p&gt;OutsideFlow was my second Hacktoberfest 2026 project using open-weight AI.&lt;/p&gt;

&lt;p&gt;My first challenge project helped me learn how to run Gemma locally and connect it to a React and Node.js application.&lt;/p&gt;

&lt;p&gt;For this challenge, I focused more on how AI can shape the actual product experience.&lt;/p&gt;

&lt;p&gt;I practiced:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Running Gemma locally through Ollama&lt;/li&gt;
&lt;li&gt;Sending structured user preferences to an AI model&lt;/li&gt;
&lt;li&gt;Designing prompts that return predictable JSON&lt;/li&gt;
&lt;li&gt;Validating AI-generated results in Node.js&lt;/li&gt;
&lt;li&gt;Connecting local inference to React&lt;/li&gt;
&lt;li&gt;Designing around limited screen interaction&lt;/li&gt;
&lt;li&gt;Using AI to encourage a real-world activity instead of more screen time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One thing I found interesting is that AI does not always have to increase digital engagement.&lt;/p&gt;

&lt;p&gt;It can also be used to help people leave the screen.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;p&gt;I did not use a DevRelay agent session for this project.&lt;/p&gt;

&lt;p&gt;The application uses a straightforward local AI architecture with Gemma running through Ollama.&lt;/p&gt;




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

&lt;p&gt;I am entering OutsideFlow AI in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Best Use of Gemma&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gemma 3 1B is the core AI model responsible for creating the personalized outdoor activity plans.&lt;/p&gt;




&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The idea behind OutsideFlow is intentionally simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Use the screen just long enough to decide what to do, then go do it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI is often used to keep people inside digital experiences.&lt;/p&gt;

&lt;p&gt;For this challenge, I wanted to try the opposite.&lt;/p&gt;

&lt;p&gt;OutsideFlow uses AI to remove the small amount of planning that can stop someone from taking a break, walking outside, exploring somewhere nearby, or simply getting some fresh air.&lt;/p&gt;

&lt;p&gt;The app creates the plan.&lt;/p&gt;

&lt;p&gt;The actual experience happens outside. 🌿&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
    </item>
    <item>
      <title>FriendFlow AI: Turning Messy Thoughts into Clear Tasks with Local AI</title>
      <dc:creator>Nadun Jayaweera</dc:creator>
      <pubDate>Fri, 02 Oct 2026 20:05:43 +0000</pubDate>
      <link>https://dev.to/nadunjayaweera/friendflow-ai-turning-messy-thoughts-into-clear-tasks-with-local-ai-2ecn</link>
      <guid>https://dev.to/nadunjayaweera/friendflow-ai-turning-messy-thoughts-into-clear-tasks-with-local-ai-2ecn</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;h1&gt;
  
  
  FriendFlow AI: Turning Messy Thoughts into Clear Tasks with Local AI
&lt;/h1&gt;

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

&lt;p&gt;I built &lt;strong&gt;FriendFlow AI&lt;/strong&gt;, a privacy-first local AI task organizer for my friend &lt;strong&gt;Sandaru&lt;/strong&gt;, who is a software engineer.&lt;/p&gt;

&lt;p&gt;Like many developers, Sandaru has a heavy daily workload. He has meetings, development tasks, code reviews, personal errands, reminders, and other responsibilities happening at the same time.&lt;/p&gt;

&lt;p&gt;Because of that workload, he sometimes forgets small daily tasks.&lt;/p&gt;

&lt;p&gt;The usual solution would be to use a task management application, but I noticed another problem: traditional task managers can actually create more friction for someone who is already busy.&lt;/p&gt;

&lt;p&gt;To create a single task, you may need to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type the task title&lt;/li&gt;
&lt;li&gt;Choose a priority&lt;/li&gt;
&lt;li&gt;Select a date&lt;/li&gt;
&lt;li&gt;Add details&lt;/li&gt;
&lt;li&gt;Save the task&lt;/li&gt;
&lt;li&gt;Repeat the same process for every other task&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When someone already has many things on their mind, organizing everything manually can become another task by itself.&lt;/p&gt;

&lt;p&gt;I wanted to make that process much simpler.&lt;/p&gt;

&lt;p&gt;That is where &lt;strong&gt;FriendFlow&lt;/strong&gt; comes in.&lt;/p&gt;

&lt;p&gt;Instead of manually creating tasks one by one, Sandaru can simply write or paste everything that is on his mind in one messy paragraph.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Tomorrow I need to review the API PR, buy milk,
send the project report today, and call Kasun.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;FriendFlow sends that unstructured text to a locally running open-weight AI model.&lt;/p&gt;

&lt;p&gt;The AI then turns the note into structured tasks such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Review the API PR
Tomorrow
High Priority

Buy milk
No date
Medium Priority

Send the project report
Today
High Priority

Call Kasun
No date
Medium Priority
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The user can then mark tasks as completed, and finished tasks are moved into a completed-task history.&lt;/p&gt;

&lt;p&gt;The goal is simple:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Dump your thoughts first. Organize them later with AI.&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Here is a short video showing FriendFlow in action:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://youtu.be/4JgI4OzFFLs" rel="noopener noreferrer"&gt;https://youtu.be/4JgI4OzFFLs&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The demo shows:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entering an unstructured note&lt;/li&gt;
&lt;li&gt;Sending the note to the local AI model&lt;/li&gt;
&lt;li&gt;Automatically generating structured tasks&lt;/li&gt;
&lt;li&gt;Detecting priorities and deadlines&lt;/li&gt;
&lt;li&gt;Marking a task as completed&lt;/li&gt;
&lt;li&gt;Saving completed tasks in local history&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The complete project is available on GitHub:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/nadunjayaweera/friendflow-ai" rel="noopener noreferrer"&gt;https://github.com/nadunjayaweera/friendflow-ai&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;FriendFlow is built as a small full-stack application with a React frontend and a Node.js/Express backend.&lt;/p&gt;

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

&lt;p&gt;FriendFlow uses the following stack:&lt;/p&gt;

&lt;h3&gt;
  
  
  Frontend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;React&lt;/li&gt;
&lt;li&gt;Vite&lt;/li&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Backend
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Node.js&lt;/li&gt;
&lt;li&gt;Express&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  AI
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Ollama&lt;/li&gt;
&lt;li&gt;Gemma 3 1B&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Storage
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Local JSON storage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The basic architecture looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;User Note
    ↓
React Frontend
    ↓
Node.js / Express Backend
    ↓
Ollama
    ↓
Gemma 3 1B
    ↓
Structured JSON Tasks
    ↓
React Task List
    ↓
Local JSON Storage
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The React frontend sends the user's note to an Express API endpoint.&lt;/p&gt;

&lt;p&gt;The backend creates a prompt asking Gemma to extract actionable tasks from the note.&lt;/p&gt;

&lt;p&gt;Gemma returns structured task information including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Task title&lt;/li&gt;
&lt;li&gt;Due date&lt;/li&gt;
&lt;li&gt;Priority&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The backend validates and normalizes the AI response before saving the tasks locally.&lt;/p&gt;

&lt;p&gt;The generated tasks are then returned to the frontend and displayed to the user.&lt;/p&gt;

&lt;p&gt;When a task is completed, it is removed from the active task list and moved into completed-task history.&lt;/p&gt;

&lt;p&gt;One of the interesting parts of this project was making the AI output reliable enough for the frontend.&lt;/p&gt;

&lt;p&gt;Instead of allowing the model to return free-form text, I instructed it to return structured JSON.&lt;/p&gt;

&lt;p&gt;For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"tasks"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"title"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Send project report"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"dueDate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Today"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"priority"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"High"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The backend also handles different possible response structures and normalizes them before sending the final task data to React.&lt;/p&gt;

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

&lt;p&gt;Open innovation is not just something I added to FriendFlow to meet the challenge requirement.&lt;/p&gt;

&lt;p&gt;It directly influenced how I designed the application.&lt;/p&gt;

&lt;p&gt;Personal notes can contain a lot of private information.&lt;/p&gt;

&lt;p&gt;A user may write about:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Work projects&lt;/li&gt;
&lt;li&gt;Client names&lt;/li&gt;
&lt;li&gt;Personal plans&lt;/li&gt;
&lt;li&gt;Family matters&lt;/li&gt;
&lt;li&gt;Deadlines&lt;/li&gt;
&lt;li&gt;Private reminders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For FriendFlow, I did not want every personal note to automatically be sent to an external AI provider.&lt;/p&gt;

&lt;p&gt;Instead, I used &lt;strong&gt;Gemma 3 1B running locally through Ollama&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;This means the AI inference can happen directly on the user's machine.&lt;/p&gt;

&lt;p&gt;The note does not need to be sent to a third-party AI API.&lt;/p&gt;

&lt;p&gt;That gives FriendFlow several advantages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Privacy
&lt;/h3&gt;

&lt;p&gt;The user's notes can remain on their own machine.&lt;/p&gt;

&lt;p&gt;This is especially important for work-related or personal information.&lt;/p&gt;

&lt;h3&gt;
  
  
  No AI API Cost
&lt;/h3&gt;

&lt;p&gt;There is no per-request cost for organizing tasks.&lt;/p&gt;

&lt;p&gt;Once the model is installed locally, FriendFlow can use it without paying for every prompt.&lt;/p&gt;

&lt;h3&gt;
  
  
  Model Flexibility
&lt;/h3&gt;

&lt;p&gt;The application is not permanently tied to a single AI provider.&lt;/p&gt;

&lt;p&gt;Because Ollama supports multiple models, I can experiment with or replace the model later without rebuilding the entire application.&lt;/p&gt;

&lt;h3&gt;
  
  
  User Control
&lt;/h3&gt;

&lt;p&gt;The user controls both the AI runtime and the task data.&lt;/p&gt;

&lt;p&gt;FriendFlow stores task information locally instead of depending on an external cloud database.&lt;/p&gt;

&lt;h3&gt;
  
  
  Local Inference
&lt;/h3&gt;

&lt;p&gt;The most interesting part for me was seeing that a small open-weight model could perform a useful everyday task directly from my own computer.&lt;/p&gt;

&lt;p&gt;Before this challenge, I had very little experience working with AI models.&lt;/p&gt;

&lt;p&gt;Building FriendFlow helped me understand that integrating an open-weight model does not always require training a model or having deep machine-learning knowledge.&lt;/p&gt;

&lt;p&gt;Sometimes, the most useful approach is simply giving a model a clear responsibility inside an application.&lt;/p&gt;

&lt;p&gt;In FriendFlow, that responsibility is turning messy human thoughts into structured tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building for Sandaru
&lt;/h2&gt;

&lt;p&gt;The theme of this challenge was &lt;strong&gt;Build for a Friend&lt;/strong&gt;, and that changed how I approached the project.&lt;/p&gt;

&lt;p&gt;Instead of trying to build a large general-purpose AI application, I focused on one small problem that someone I know actually experiences.&lt;/p&gt;

&lt;p&gt;Sandaru does not need another complicated productivity platform.&lt;/p&gt;

&lt;p&gt;He needs a faster way to capture what is already in his head.&lt;/p&gt;

&lt;p&gt;That is why FriendFlow intentionally keeps the interaction simple:&lt;/p&gt;

&lt;p&gt;Sandaru said the most useful part was being able to dump several thoughts at once instead of creating tasks one by one.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Write everything
        ↓
Click Organize with AI
        ↓
Get clear tasks
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The project is small, but the problem is real.&lt;/p&gt;

&lt;p&gt;That was one of my favorite parts of this challenge.&lt;/p&gt;

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

&lt;p&gt;This was also my first real experience building an application around an open-weight AI model.&lt;/p&gt;

&lt;p&gt;I learned how to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Run Gemma locally using Ollama&lt;/li&gt;
&lt;li&gt;Send prompts to a local model from Node.js&lt;/li&gt;
&lt;li&gt;Request structured JSON output from an AI model&lt;/li&gt;
&lt;li&gt;Validate AI-generated responses&lt;/li&gt;
&lt;li&gt;Connect local AI inference to a React application&lt;/li&gt;
&lt;li&gt;Persist AI-generated task data locally&lt;/li&gt;
&lt;li&gt;Design an application where AI performs a specific useful function&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The biggest lesson for me was that I did not need to understand model training before I could start building useful applications with open models.&lt;/p&gt;

&lt;p&gt;As a web developer, I could treat the model as another service inside my application and gradually learn how it behaves.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Agent Session
&lt;/h2&gt;

&lt;p&gt;I did not use an agent session for this submission.&lt;/p&gt;

&lt;p&gt;The project was built using a simple local AI architecture with Gemma running through Ollama.&lt;/p&gt;

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

&lt;p&gt;I am entering FriendFlow in:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Best Use of Gemma&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Gemma 3 1B is the core AI model responsible for converting unstructured user notes into structured tasks.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;Hacktoberfest 2026 pushed me into an area I had not explored much before: open-weight AI.&lt;/p&gt;

&lt;p&gt;I started this challenge without much knowledge about AI models.&lt;/p&gt;

&lt;p&gt;By the end, I had a working application where a locally running Gemma model was solving a real problem for someone I know.&lt;/p&gt;

&lt;p&gt;FriendFlow may be a small project, but that is also what I like about it.&lt;/p&gt;

&lt;p&gt;It takes one repetitive part of task management and removes it.&lt;/p&gt;

&lt;p&gt;Instead of carefully organizing every thought before saving it, the user can simply write naturally and let the AI handle the structure.&lt;/p&gt;

&lt;p&gt;Sometimes the most useful tools are not the biggest ones.&lt;/p&gt;

&lt;p&gt;They are the ones that remove a little bit of friction from someone's day.&lt;/p&gt;

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