<?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: M N Mustakul Amin Talukdar</title>
    <description>The latest articles on DEV Community by M N Mustakul Amin Talukdar (@mrnowshirwan).</description>
    <link>https://dev.to/mrnowshirwan</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%2F4174788%2Fa288cae9-5a34-4de9-b6fc-3f95cc43f189.png</url>
      <title>DEV Community: M N Mustakul Amin Talukdar</title>
      <link>https://dev.to/mrnowshirwan</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mrnowshirwan"/>
    <language>en</language>
    <item>
      <title>haunted-shell: a tiny local ghost that whispers about my shell commands</title>
      <dc:creator>M N Mustakul Amin Talukdar</dc:creator>
      <pubDate>Thu, 29 Oct 2026 13:11:22 +0000</pubDate>
      <link>https://dev.to/mrnowshirwan/haunted-shell-a-tiny-local-ghost-that-whispers-about-my-shell-commands-4kp0</link>
      <guid>https://dev.to/mrnowshirwan/haunted-shell-a-tiny-local-ghost-that-whispers-about-my-shell-commands-4kp0</guid>
      <description>&lt;p&gt;Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine Submission 👻&lt;/p&gt;

&lt;p&gt;This is a submission for the Hacktoberfest Open-Source AI Challenge: Week 4.&lt;/p&gt;

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

&lt;p&gt;haunted-shell is a tiny ghost that possesses my terminal. A shell hook watches each command I run, and a small open-weight model on my own machine whispers back one short, eerie comment. It never touches the command itself - it only watches and whispers.&lt;/p&gt;

&lt;p&gt;Real ghost output from the build's test runs. Each line below is a sample command string fed to the tool as text input (never executed), with an exit code passed alongside (2-core VM, model on CPU, no API key, no account):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git push origin main
👻 your code is spreading like a plague... across the night

$ rm -rf build/
👻 ridding yourself of the unwanted... but beware, there's no going back now

$ grep -r TODO .
👻 letting the shadows whisper through the files

$ sudo systemctl restart nginx   (sample string; exit code 1 passed as input)
👻 nginx's head is stuck in a wall, you need a wrench.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last one is technically nonsense, but a 1.5B ghost doing its best is pretty much the Halloween brief.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9mcponjvjz63qv8d42hb.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto/https%3A%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Farticles%2F9mcponjvjz63qv8d42hb.gif" alt="Demo of haunted-shell whispering in a real terminal" width="790" height="560"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the Halloween sibling of &lt;a href="https://github.com/MRNOWSHIRWAN/lazycommit" rel="noopener noreferrer"&gt;lazycommit&lt;/a&gt;, my Week 3 project. Same machine, same idea of a small local model doing one fun job, new costume.&lt;/p&gt;

&lt;h2&gt;
  
  
  The ghost needed a bigger brain
&lt;/h2&gt;

&lt;p&gt;The first version used the exact same model as lazycommit: Qwen2.5-Coder 0.5B Instruct, about 400 MB. For commit messages it worked well in the Week 3 tests, where it picked the right Conventional Commit type on all three real commits. In the ghost test runs it just repeated the input back like a court stenographer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ git push origin main
👻 A mortal ran: `git push origin main`.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So the ghost moved into Qwen2.5 1.5B Instruct, about 1 GB, still tiny, still running on plain CPU, and the whispers started sounding like whispers.&lt;/p&gt;

&lt;p&gt;The second fix reused a pattern from the Week 3 project: a small model follows a few concrete examples much better than a paragraph of instructions. My first prompt was rules only, and the model kept retelling the command instead of commenting on it. With four short example whispers in the prompt (one about &lt;code&gt;ls&lt;/code&gt;, one about &lt;code&gt;git commit&lt;/code&gt;, one about &lt;code&gt;ping&lt;/code&gt;, one about &lt;code&gt;mv&lt;/code&gt;), it imitated the format right away.&lt;/p&gt;

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

&lt;p&gt;The pipeline is small on purpose:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A &lt;code&gt;PROMPT_COMMAND&lt;/code&gt; hook captures the last command and its exit code after each command finishes.&lt;/li&gt;
&lt;li&gt;It calls &lt;code&gt;haunt whisper -- "$last_cmd" "$exit_code"&lt;/code&gt; in the background, detached. Your typing never waits for inference, and if anything fails the CLI exits silently with code 0. A lock file keeps it to one ghost at a time - if you type faster than it thinks, extra whispers are dropped instead of stacking up. A ghost must never break a shell.&lt;/li&gt;
&lt;li&gt;Boring commands (&lt;code&gt;ls&lt;/code&gt;, &lt;code&gt;cd&lt;/code&gt;, &lt;code&gt;pwd&lt;/code&gt;, ...) are skipped, and &lt;code&gt;--every N&lt;/code&gt; throttles it to every Nth command so it stays funny instead of noisy.&lt;/li&gt;
&lt;li&gt;Commands that look like they contain credentials (passwords, tokens, keys) are skipped entirely - the ghost never sees them.&lt;/li&gt;
&lt;li&gt;The command is trimmed to 120 characters and sent, as data, with the ghost persona plus the four examples. Nothing is ever evaluated or executed - the ghost only reads.&lt;/li&gt;
&lt;li&gt;The reply is squashed to one line and printed dim and italic with a 👻 prefix.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The CLI is plain Python with zero dependencies for the default backend. It talks to a local server that speaks the OpenAI chat API. Verified in testing: the HTTP backend against a mock server, and the in-process llama.cpp backend that produced every whisper quoted above. Ollama and LM Studio speak the same API and are expected to work, but are not verified yet. The endpoint is loopback-only by default and the client refuses to follow HTTP redirects, so a misconfigured local server cannot bounce your commands somewhere remote. A deliberate &lt;code&gt;HAUNT_ALLOW_REMOTE=1&lt;/code&gt; override exists for people who run the model on another machine of their own. There is also an optional in-process backend using llama-cpp-python if you do not want to run a server at all.&lt;/p&gt;

&lt;p&gt;On a 2-core VM with the model on CPU, one whisper took about 2 to 5 seconds. That is one measured result on that VM, not a benchmark. The ghost runs detached, so you never sit waiting for a reply - but it does spend those few CPU-seconds per whisper in the background, so on a weak machine you will want &lt;code&gt;--every N&lt;/code&gt; rather than a comment on everything.&lt;/p&gt;

&lt;p&gt;The project has 17 pytest tests covering the prompt builder, the throttling, the fail-silent behavior, the secret filter, the loopback guard, redirect refusal, and the HTTP backend against a mock server. All pass. I also tested the hook in an isolated shell: it whispers on real commands, stays quiet for &lt;code&gt;ls&lt;/code&gt;, preserves the exit code of a failed command, and disappears cleanly when you remove the line from your shell config.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why open innovation matters here
&lt;/h2&gt;

&lt;p&gt;Shell commands are some of the most sensitive text on a machine. They carry folder names, project names, hostnames, sometimes worse. A ghost that sends your command history to a cloud API is not a ghost, it is spyware with a Halloween costume.&lt;/p&gt;

&lt;p&gt;Because the model is open-weight and runs on my own machine:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Private&lt;/strong&gt;: with the default configuration, whispers are generated on loopback only and the tool never writes command text to disk. Your shell's own history behaves exactly as it always has - that part is unchanged by this tool. And to be clear about the limit: local processing is not secret-proof, which is why likely-credential commands are filtered out before the model ever sees them.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Offline after setup&lt;/strong&gt;: installing the package and downloading the model need the internet, once. After that, whispers need no network at all. The tool itself needs no API key and no account.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Free&lt;/strong&gt;: no per-token bill for a toy, no subscription.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swappable&lt;/strong&gt;: when the 0.5B coder model turned out to be a bad ghost in testing, I swapped in a 1.5B instruct model by changing one string. No vendor migration, no new SDK, no new pricing tier. The same OpenAI-compatible interface meant the whole tool kept working.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That swap is the open-ecosystem advantage in miniature: not just free as in money, but cheap to change your mind.&lt;/p&gt;

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

&lt;p&gt;Source code on GitHub: &lt;a href="https://github.com/MRNOWSHIRWAN/haunted-shell" rel="noopener noreferrer"&gt;https://github.com/MRNOWSHIRWAN/haunted-shell&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The application code is MIT licensed. The model weights keep their own Apache-2.0 license.&lt;/p&gt;

&lt;p&gt;Setup, if you have Ollama:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;git+https://github.com/MRNOWSHIRWAN/haunted-shell.git
ollama pull qwen2.5:1.5b-instruct
haunt install-hook &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; ~/.bashrc
&lt;span class="nb"&gt;exec&lt;/span&gt; &lt;span class="nv"&gt;$SHELL&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Uninstall is deleting that one line from your &lt;code&gt;~/.bashrc&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Happy Halloween. Check your shell before you type 👻&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
    <item>
      <title>lazycommit: a tiny local model writes my commit messages so I don't have to</title>
      <dc:creator>M N Mustakul Amin Talukdar</dc:creator>
      <pubDate>Thu, 22 Oct 2026 04:23:58 +0000</pubDate>
      <link>https://dev.to/mrnowshirwan/lazycommit-a-tiny-local-model-writes-my-commit-messages-so-i-dont-have-to-k4p</link>
      <guid>https://dev.to/mrnowshirwan/lazycommit-a-tiny-local-model-writes-my-commit-messages-so-i-dont-have-to-k4p</guid>
      <description>&lt;p&gt;Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission 🦥&lt;/p&gt;

&lt;p&gt;This is a submission for the Hacktoberfest Open-Source AI Challenge: Week 3.&lt;/p&gt;

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

&lt;p&gt;lazycommit is a small CLI that writes git commit messages for me. I stage my changes, run &lt;code&gt;lazycommit&lt;/code&gt;, and a small open-weight model running on a server VM reads the diff and answers with one Conventional Commit message, like &lt;code&gt;feat: add timeout option to portscan&lt;/code&gt;. With &lt;code&gt;lazycommit --commit&lt;/code&gt; it commits right away.&lt;/p&gt;

&lt;p&gt;I commit to GitHub every day. Writing the message is the part I always want to skip, and "fix stuff" as a message helps nobody. This is the laziest useful thing I could build: one command, and the boring part is done.&lt;/p&gt;

&lt;p&gt;The whole tool is plain Python with zero dependencies. It talks to any local server that speaks the OpenAI chat API: Ollama, llama.cpp, LM Studio. The default model is Qwen2.5-Coder 0.5B Instruct, about 400 MB, which runs fine on a laptop CPU.&lt;/p&gt;

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

&lt;p&gt;Here is a real run in a demo repository. I staged a change that adds a &lt;code&gt;timeout&lt;/code&gt; option to a small port scanner:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ lazycommit
lazycommit: 1 staged file(s): portscan.py
lazycommit: asking qwen2.5-coder:0.5b-instruct at http://127.0.0.1:18090/v1 ...
feat: add timeout option to portscan
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then two more real commits, fully written by the model:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;git log &lt;span class="nt"&gt;--oneline&lt;/span&gt;
106f562 &lt;span class="nb"&gt;test&lt;/span&gt;: add &lt;span class="nb"&gt;test &lt;/span&gt;&lt;span class="k"&gt;for &lt;/span&gt;localhost closed port
4595f1b docs: add README with project description
b8f5cf6 feat: add &lt;span class="nb"&gt;timeout &lt;/span&gt;option to portscan
0010f18 feat: basic tcp connect scanner
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model picked the right Conventional Commit type all three times: feat for the feature, docs for the README, test for the test file. Each message took about 2 seconds on a 2-core VM with the model on CPU. That is one measured result on that VM, not a benchmark.&lt;/p&gt;

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

&lt;p&gt;Source code on GitHub: &lt;a href="https://github.com/MRNOWSHIRWAN/lazycommit" rel="noopener noreferrer"&gt;https://github.com/MRNOWSHIRWAN/lazycommit&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The application code is MIT licensed. The model weights keep their own Apache-2.0 license.&lt;/p&gt;

&lt;p&gt;Setup takes two commands if you have Ollama:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;pip &lt;span class="nb"&gt;install &lt;/span&gt;git+https://github.com/MRNOWSHIRWAN/lazycommit.git
ollama pull qwen2.5-coder:0.5b-instruct
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then &lt;code&gt;lazycommit&lt;/code&gt; inside any git repo with staged changes.&lt;/p&gt;

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

&lt;p&gt;The pipeline is small on purpose:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Read &lt;code&gt;git diff --cached&lt;/code&gt;, staged changes only.&lt;/li&gt;
&lt;li&gt;Trim very large diffs so a small model stays inside its context window, keeping every changed file's name visible.&lt;/li&gt;
&lt;li&gt;Ask for one message with three tiny examples (a feat, a docs, a test diff). I found that a 0.5B model follows one concrete example much better than a paragraph of instructions. Without the docs example it called a README change a feat; with it, it gets the type right.&lt;/li&gt;
&lt;li&gt;Clean the output: strip quotes, markdown fences, and "Commit message:" lead-ins, lowercase the summary. If nothing usable remains, it says so and asks you to write the message yourself. It never invents one.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The default mode only prints the suggestion. &lt;code&gt;--commit&lt;/code&gt; is a separate, deliberate flag. There are 15 pytest tests covering the cleanup rules, the diff trimming, the HTTP client against a fake local server, and the full flow in a temporary git repository. All pass.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Open Innovation Matters
&lt;/h2&gt;

&lt;p&gt;A commit message generator that sends your diff to a hosted API is a strange product. Your staged diff is exactly the code you have not published yet. With an open-weight model, the diff never leaves the machine: no account, no API key, no terms of service, no per-request cost. It works offline, on a train, and it will still work in five years because the weights sit on my disk.&lt;/p&gt;

&lt;p&gt;Open weights also made the engineering honest. I could read the model card, check the license, download the exact file, and run it with an open-source server (llama.cpp). If a bigger model writes better messages tomorrow, I change one environment variable and keep everything else.&lt;/p&gt;

&lt;p&gt;The tradeoff is real and I want to name it: a 0.5B model is not a genius. It gets the type and the subject right far more often than not, but I still read the message before I push. That is why the default mode only prints. Being lazy is the goal; being careless is not.&lt;/p&gt;

&lt;p&gt;For me this was also a first real step from using AI through chat windows to running AI as a local component in my own tool, and that shift only happened because the model and the server are open.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>DukaanDraft: a local AI writing helper for small shops</title>
      <dc:creator>M N Mustakul Amin Talukdar</dc:creator>
      <pubDate>Sun, 18 Oct 2026 20:21:51 +0000</pubDate>
      <link>https://dev.to/mrnowshirwan/dukaandraft-a-local-ai-writing-helper-for-small-shops-nn2</link>
      <guid>https://dev.to/mrnowshirwan/dukaandraft-a-local-ai-writing-helper-for-small-shops-nn2</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;DEV Hacktoberfest Week 2 Challenge&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;DukaanDraft is an English-only prototype that turns a local shop's short offer facts into an editable post draft.&lt;/p&gt;

&lt;p&gt;The workflow is simple: enter a shop name and offer facts, generate a rewrite, compare it with the original facts, edit, and copy. Nothing is posted automatically. The destination labels help organize a draft for WhatsApp, Google Business Profile, or Instagram; they do not change the model prompt yet.&lt;/p&gt;

&lt;p&gt;The side-hustle idea is a human-reviewed post-writing service for local shops. It is an idea to test, not an existing business. There are no customer, revenue, or willingness-to-pay claims.&lt;/p&gt;

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

&lt;p&gt;The fictional test input was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Shop: Fictional Store&lt;/li&gt;
&lt;li&gt;Offer facts: rice for Rs 50 per kg.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The model returned:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Fictional Store sells Rice at Rs 50 per Kg.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The complete local browser-to-Node-to-model test returned this draft in 3.8 seconds on the test computer. This is one measured result, not a performance guarantee. First use also downloads model weights.&lt;/p&gt;

&lt;p&gt;The interface keeps the original facts under the editable draft, alongside a warning to check every claim. A small model can still invent details or change a name. In other tests it added "affordable" or changed a shop name, which is why human review is part of the product rather than an afterthought.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://github.com/MRNOWSHIRWAN/dukaandraft" rel="noopener noreferrer"&gt;Source code on GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The application code is MIT licensed. The model weights keep their own Apache-2.0 license.&lt;/p&gt;

&lt;p&gt;To run locally with Node.js 20+:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install
&lt;/span&gt;npm start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then open &lt;code&gt;http://127.0.0.1:8787&lt;/code&gt; on the same computer. The prototype was tested with Node 22 on Linux. It is not publicly deployed.&lt;/p&gt;

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

&lt;p&gt;The app uses plain HTML and JavaScript for the form, a small Node HTTP server, and &lt;a href="https://huggingface.co/docs/transformers.js" rel="noopener noreferrer"&gt;Transformers.js&lt;/a&gt; for local inference.&lt;/p&gt;

&lt;p&gt;The AI core is &lt;a href="https://huggingface.co/HuggingFaceTB/SmolLM2-360M-Instruct" rel="noopener noreferrer"&gt;SmolLM2-360M-Instruct&lt;/a&gt;, using the &lt;a href="https://huggingface.co/onnx-community/SmolLM2-360M-Instruct-ONNX" rel="noopener noreferrer"&gt;ONNX community conversion&lt;/a&gt;. The quantized model runs on the CPU in Node, not through a hosted inference API. No API key or new account is needed to run the app.&lt;/p&gt;

&lt;p&gt;The server listens only on the local loopback address and accepts local same-origin browser requests. Model files are downloaded from Hugging Face; shop text is processed locally by this application. The first download is hundreds of MB, and model loading needs enough free memory. This is not a phone-only or low-memory-device promise.&lt;/p&gt;

&lt;p&gt;I kept the scope small: English rewriting, an editable result, original facts for comparison, and an explicit copy action. Earlier API-hosted and browser-only inference approaches were explored but were not verified as working routes and are not the shipped version.&lt;/p&gt;

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

&lt;p&gt;Open weights make it possible to test this idea without an inference-service account or a per-request API dependency. The model can be downloaded, inspected through its published documentation, and run locally. Open-source application code lets someone else change the workflow or replace the model without starting from scratch.&lt;/p&gt;

&lt;p&gt;That freedom also makes the tradeoffs visible. A small local model is accessible, but it is not automatically accurate enough to write a shop's public claims. The useful next step is to test with real shop owners, measure factual errors, and find out whether a reviewed writing service saves them enough time to pay for it.&lt;/p&gt;

&lt;p&gt;For now, DukaanDraft is a working local experiment with a clear review step, not a claim of a finished commercial product.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>hf26challenge</category>
      <category>opensource</category>
      <category>ai</category>
    </item>
  </channel>
</rss>
