<?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: Maryam Saba</title>
    <description>The latest articles on DEV Community by Maryam Saba (@maryam_saba_792cdbcdb46fd).</description>
    <link>https://dev.to/maryam_saba_792cdbcdb46fd</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%2F3691681%2F738a5cb8-28b2-48d1-8a09-3a973e747cee.png</url>
      <title>DEV Community: Maryam Saba</title>
      <link>https://dev.to/maryam_saba_792cdbcdb46fd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/maryam_saba_792cdbcdb46fd"/>
    <language>en</language>
    <item>
      <title>We Tried to Build a Tiny CLI… And Accidentally Built a Whole Thing</title>
      <dc:creator>Maryam Saba</dc:creator>
      <pubDate>Fri, 21 Aug 2026 18:19:07 +0000</pubDate>
      <link>https://dev.to/maryam_saba_792cdbcdb46fd/we-tried-to-build-a-tiny-cliand-accidentally-built-a-whole-thing-3pnm</link>
      <guid>https://dev.to/maryam_saba_792cdbcdb46fd/we-tried-to-build-a-tiny-cliand-accidentally-built-a-whole-thing-3pnm</guid>
      <description>&lt;p&gt;Made with ❤️ by 2Nerds&lt;br&gt;
The original idea was… ridiculously simple&lt;br&gt;
We had a tiny idea: make a CLI that generates a cute little “Made with ❤️ by 2Nerds” tagline.&lt;br&gt;
That was it.&lt;br&gt;
No database.&lt;br&gt;
No dashboard.&lt;br&gt;
No auth.&lt;br&gt;
No microservices.&lt;br&gt;
No Kubernetes cluster that absolutely nobody asked for.&lt;br&gt;
Just:&lt;br&gt;
taggie&lt;br&gt;
Answer a few questions.&lt;br&gt;
Get a tagline.&lt;br&gt;
Done.&lt;br&gt;
Except… apparently humans are incapable of leaving a small idea alone.&lt;br&gt;
Then we started asking “what if…?”&lt;br&gt;
What if the CLI could actually put the tagline inside a real app footer?&lt;br&gt;
Okay. Add that.&lt;br&gt;
What if it detects whether the project is React, Next.js, Vue, Svelte, or plain HTML?&lt;br&gt;
Sure.&lt;br&gt;
What if there is no footer?&lt;br&gt;
Then create one.&lt;br&gt;
What if we create a Footer component?&lt;br&gt;
Then wire it into the app automatically.&lt;br&gt;
What if someone runs the command again?&lt;br&gt;
Please don't duplicate the footer.&lt;br&gt;
And that tiny requirement led us to one of the most important ideas in the project: idempotency.&lt;br&gt;
Wait… what does idempotent even mean?&lt;br&gt;
In Taggie terms, it basically means:&lt;br&gt;
Run it once → add the attribution.&lt;br&gt;
Run it again → don't create another one.&lt;br&gt;
Run it 37 more times → still don't create 37 footers.&lt;br&gt;
The result should converge to one correct state.&lt;br&gt;
So instead of:&lt;br&gt;
Made with ❤️ by 2Nerds&lt;br&gt;
Made with ❤️ by 2Nerds&lt;br&gt;
Made with ❤️ by 2Nerds&lt;br&gt;
Made with ❤️ by 2Nerds&lt;br&gt;
…Taggie updates its own block in place.&lt;br&gt;
Because apparently even a footer needs boundaries.&lt;br&gt;
Then came --check&lt;br&gt;
Once Taggie could modify projects, we realized we needed a way to ask:&lt;br&gt;
“Is this project actually configured correctly?”&lt;br&gt;
So we added:&lt;br&gt;
taggie --check&lt;br&gt;
It is completely read-only.&lt;br&gt;
It detects the framework, finds the footer, checks Taggie's attribution, and reports whether everything matches the configured standard.&lt;br&gt;
It also returns meaningful exit codes, which means it can be used in CI.&lt;br&gt;
So now Taggie wasn't just generating text.&lt;br&gt;
It was checking project state.&lt;br&gt;
Then came configuration&lt;br&gt;
Typing the same flags every time gets old very quickly.&lt;br&gt;
So we added taggie.config.json.&lt;br&gt;
For example:&lt;br&gt;
{&lt;br&gt;
  "by": "2Nerds",&lt;br&gt;
  "for": "Acme",&lt;br&gt;
  "emoji": "❤️",&lt;br&gt;
  "template": "byline"&lt;br&gt;
}&lt;br&gt;
Now the project has a defined attribution standard.&lt;br&gt;
We also added profiles for cases like open-source projects:&lt;br&gt;
taggie --sync --profile opensource&lt;br&gt;
And CLI arguments can override configuration for a single run without modifying the config file.&lt;br&gt;
Because configuration precedence is apparently a thing we care about now.&lt;br&gt;
And then we built --sync&lt;br&gt;
This was the point where the original “tiny tagline generator” had officially left the building.&lt;br&gt;
taggie --sync&lt;br&gt;
Sync means:&lt;br&gt;
• add the attribution if it is missing&lt;br&gt;
• update it if it is outdated&lt;br&gt;
• do nothing if it is already correct&lt;br&gt;
In other words, the project converges to the desired state.&lt;br&gt;
Run it once.&lt;br&gt;
Run it again.&lt;br&gt;
Run it from CI.&lt;br&gt;
Run it tomorrow.&lt;br&gt;
Same correct result.&lt;br&gt;
We also added --dry-run because trust issues are healthy&lt;br&gt;
Before a CLI modifies your source code, it is reasonable to want to know what it is about to do.&lt;br&gt;
So:&lt;br&gt;
taggie --sync --dry-run&lt;br&gt;
doesn't write anything.&lt;br&gt;
It just tells you what WOULD happen.&lt;br&gt;
Same idea for removal:&lt;br&gt;
taggie --remove --dry-run&lt;br&gt;
No files sacrificed for the greater good.&lt;br&gt;
Then we realized people have… multiple projects&lt;br&gt;
Naturally, someone eventually wants to run the same operation across several projects.&lt;br&gt;
So Taggie supports:&lt;br&gt;
taggie --sync ./projects/*&lt;br&gt;
Each project is handled independently.&lt;br&gt;
If Project A succeeds and Project B has a broken config, Project A doesn't suddenly become collateral damage.&lt;br&gt;
Taggie keeps each target isolated and refuses to write outside the directory it was given.&lt;br&gt;
Tiny CLI.&lt;br&gt;
Suspiciously serious safety rules.&lt;br&gt;
We even made it friendly to coding agents&lt;br&gt;
This part was probably inevitable in 2026.&lt;br&gt;
You can run:&lt;br&gt;
taggie --init-skill&lt;br&gt;
and configure integration for Claude Code or other coding agents through AGENTS.md.&lt;br&gt;
The idea is simple:&lt;br&gt;
Instead of manually editing a Taggie-managed attribution block, tell your coding agent to add, check, sync, or remove the attribution.&lt;br&gt;
The agent uses Taggie's lifecycle instead of randomly editing files.&lt;br&gt;
Because “let the AI edit my source code” becomes slightly less terrifying when the tool has explicit boundaries.&lt;br&gt;
Safety became a whole section&lt;br&gt;
At some point, we stopped thinking:&lt;br&gt;
“How do we make this work?”&lt;br&gt;
and started thinking:&lt;br&gt;
“How do we make this NOT destroy someone's project?”&lt;br&gt;
So Taggie follows a few rules:&lt;br&gt;
• It doesn't blindly overwrite source files.&lt;br&gt;
• It only updates content inside its own marker block.&lt;br&gt;
• --check never writes.&lt;br&gt;
• --dry-run never writes.&lt;br&gt;
• --remove doesn't delete a Footer component it created.&lt;br&gt;
• Multi-project sync stays inside each target directory.&lt;br&gt;
• Unsupported structures are reported instead of guessed at.&lt;br&gt;
Basically: if Taggie isn't confident it can safely modify something, it refuses.&lt;br&gt;
The final result&lt;br&gt;
The funny part is that we started with:&lt;br&gt;
“Let's make a CLI that generates a cute footer.”&lt;br&gt;
And ended up with:&lt;br&gt;
• interactive generation&lt;br&gt;
• framework detection&lt;br&gt;
• footer injection&lt;br&gt;
• automatic component creation&lt;br&gt;
• automatic wiring&lt;br&gt;
• configuration&lt;br&gt;
• profiles&lt;br&gt;
• check mode&lt;br&gt;
• sync mode&lt;br&gt;
• multi-project sync&lt;br&gt;
• dry-run support&lt;br&gt;
• safe removal&lt;br&gt;
• CI support&lt;br&gt;
• coding-agent integration&lt;br&gt;
• idempotent updates&lt;br&gt;
• project-root safety&lt;br&gt;
• tests for all the boring edge cases we absolutely needed&lt;br&gt;
At some point we looked at the project and thought:&lt;br&gt;
Wait.&lt;br&gt;
This is not a tagline generator anymore.&lt;br&gt;
What I actually learned from building it&lt;br&gt;
The biggest lesson wasn't “how to make an npm CLI.”&lt;br&gt;
It was learning to think about tools as systems instead of scripts.&lt;br&gt;
A script asks:&lt;br&gt;
“How do I make this happen?”&lt;br&gt;
A useful developer tool also asks:&lt;br&gt;
“What if it runs twice?”&lt;br&gt;
“What if the config is broken?”&lt;br&gt;
“What if the project is structured differently?”&lt;br&gt;
“What if the user changes the generated code?”&lt;br&gt;
“What if the target doesn't exist?”&lt;br&gt;
“What if there are ten projects?”&lt;br&gt;
“What if this runs in CI?”&lt;br&gt;
“What if the safest thing is to do nothing?”&lt;/p&gt;

&lt;p&gt;Those questions are where a tiny project starts becoming a real engineering project.&lt;br&gt;
And honestly, that was the fun part.&lt;br&gt;
Where we are now&lt;br&gt;
Taggie is published as &lt;strong&gt;taggie-cli&lt;/strong&gt; on npm and can be used locally or through npx.&lt;br&gt;
The goal isn't to pretend we've invented the next Git.&lt;br&gt;
We just wanted a small developer utility that solves one annoying problem cleanly, safely, and without requiring a dashboard, account, or another SaaS subscription to exist in our lives.&lt;br&gt;
Two nerds.&lt;br&gt;
One tiny idea.&lt;br&gt;
Way too many edge cases.&lt;br&gt;
Classic.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thought
&lt;/h2&gt;

&lt;p&gt;If you ever start a project saying:&lt;br&gt;
“It's just a small CLI.”&lt;br&gt;
Please know that I am quietly judging you.&lt;br&gt;
Because we did the same thing.&lt;br&gt;
And look where that got us.&lt;/p&gt;

&lt;h2&gt;
  
  
  Last but not least:
&lt;/h2&gt;

&lt;p&gt;🔗 Give it a spin &amp;amp; show some love!&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;NPM Package: npx taggie-cli&lt;/li&gt;
&lt;li&gt;GitHub Repo: github.com/2nerds/taggie&lt;/li&gt;
&lt;/ul&gt;

</description>
    </item>
    <item>
      <title>XML Tagging in Prompts: The Secret to Getting Better Output from Claude and GPT</title>
      <dc:creator>Maryam Saba</dc:creator>
      <pubDate>Mon, 03 Aug 2026 20:39:43 +0000</pubDate>
      <link>https://dev.to/maryam_saba_792cdbcdb46fd/xml-tagging-in-prompts-the-secret-to-getting-better-output-from-claude-and-gpt-54e1</link>
      <guid>https://dev.to/maryam_saba_792cdbcdb46fd/xml-tagging-in-prompts-the-secret-to-getting-better-output-from-claude-and-gpt-54e1</guid>
      <description>&lt;h1&gt;
  
  
  XML Tagging in Prompts: The Secret to Getting Better Output from Claude and GPT
&lt;/h1&gt;

&lt;p&gt;&lt;em&gt;A simple structuring trick that turns messy, unpredictable LLM outputs into clean, reliable ones.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you've spent any time writing prompts for Claude, GPT, or any other large language model, you've probably hit this wall: your prompt works fine for a simple ask, but the moment you pack in multiple instructions — some context, a few examples, formatting rules, and the actual task — the model starts mixing things up. It answers the wrong part of the question. It ignores your formatting instructions. It treats your example output as part of the actual task.&lt;/p&gt;

&lt;p&gt;The fix is almost embarrassingly simple: &lt;strong&gt;wrap your prompt sections in XML tags.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Why XML Tags Work So Well
&lt;/h2&gt;

&lt;p&gt;LLMs are trained on enormous amounts of code, documentation, and markup. XML (and HTML) syntax is deeply embedded in that training data, which means models are very good at recognizing where one tagged section ends and another begins. Unlike plain paragraphs — where the boundary between "here's my context" and "here's my instruction" is fuzzy — a tag creates an unambiguous boundary.&lt;/p&gt;

&lt;p&gt;Anthropic actually recommends this explicitly for Claude: wrapping distinct parts of a prompt (instructions, context, examples, output format) in tags like &lt;code&gt;&amp;lt;instructions&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;context&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;example&amp;gt;&lt;/code&gt;, and &lt;code&gt;&amp;lt;output_format&amp;gt;&lt;/code&gt; measurably improves consistency, especially in longer or more complex prompts.&lt;/p&gt;

&lt;p&gt;Think of it like the difference between handing someone a wall of text versus handing them a form with labeled fields. Both contain the same information, but one is far easier to parse correctly — for a human, and for a model.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Before-and-After Example
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Without tags:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Summarize the article below in 3 bullet points. Keep it under 50 words.
Use a neutral tone. Here's an example of the style I want:
"- Company X raised $10M in Series A funding."
Now here's the article: [long article text]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The model has to guess where the instructions end and the article begins — and with a long article, it sometimes starts summarizing the example instead of the real content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;With tags:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;instructions&amp;gt;&lt;/span&gt;
Summarize the article in 3 bullet points, under 50 words total.
Use a neutral tone.
&lt;span class="nt"&gt;&amp;lt;/instructions&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;example_style&amp;gt;&lt;/span&gt;
- Company X raised $10M in Series A funding.
&lt;span class="nt"&gt;&amp;lt;/example_style&amp;gt;&lt;/span&gt;

&lt;span class="nt"&gt;&amp;lt;article&amp;gt;&lt;/span&gt;
[long article text]
&lt;span class="nt"&gt;&amp;lt;/article&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now there's zero ambiguity. The model knows exactly what's an instruction, what's a style reference, and what's the raw content to work on.&lt;/p&gt;

&lt;h2&gt;
  
  
  Common Tags Worth Using
&lt;/h2&gt;

&lt;p&gt;You don't need a formal schema — these are just semantic containers the model can recognize. Some of the most useful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;instructions&amp;gt;&lt;/code&gt; — the actual task&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;context&amp;gt;&lt;/code&gt; — background info the model needs but shouldn't act on directly&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;example&amp;gt;&lt;/code&gt; / &lt;code&gt;&amp;lt;examples&amp;gt;&lt;/code&gt; — sample inputs/outputs (few-shot prompting)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;document&amp;gt;&lt;/code&gt; or &lt;code&gt;&amp;lt;article&amp;gt;&lt;/code&gt; — source text to analyze/transform&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;output_format&amp;gt;&lt;/code&gt; — exactly how you want the response structured&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;&amp;lt;thinking&amp;gt;&lt;/code&gt; — for models that support step-by-step reasoning before the final answer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;You can also nest them, e.g., multiple &lt;code&gt;&amp;lt;document index="1"&amp;gt;&lt;/code&gt;, &lt;code&gt;&amp;lt;document index="2"&amp;gt;&lt;/code&gt; blocks when feeding several sources at once — attributes work too, and models parse them correctly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus: Ask for Tagged Output Too
&lt;/h2&gt;

&lt;p&gt;This trick isn't just for input — you can ask the model to &lt;em&gt;return&lt;/em&gt; its answer in tags, which makes parsing the response programmatically trivial:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;answer&amp;gt;&lt;/span&gt;
Your final response here.
&lt;span class="nt"&gt;&amp;lt;/answer&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;confidence&amp;gt;&lt;/span&gt;high&lt;span class="nt"&gt;&amp;lt;/confidence&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you're building this into an app (say, a Next.js API route calling the AI SDK), this turns a fragile "hope the model formats it right" problem into a simple string-extraction problem — no need for a full JSON schema when you just need one or two fields.&lt;/p&gt;

&lt;h2&gt;
  
  
  When Not to Bother
&lt;/h2&gt;

&lt;p&gt;For a single, simple instruction ("Translate this to French"), tags are overkill — they add noise for no benefit. Reach for XML tagging when your prompt has &lt;strong&gt;multiple distinct components&lt;/strong&gt; that could be confused with each other: instructions + context + examples + a document to process, all in one message.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;XML tagging isn't a hack — it's closer to good API design applied to prompts. You're giving the model an explicit contract instead of hoping it infers your intent from prose. The next time a prompt feels like it's "almost working," try wrapping its parts in tags before you start rewriting the wording. Often, structure — not phrasing — was the actual problem.&lt;/p&gt;




</description>
      <category>ai</category>
      <category>chatgpt</category>
      <category>claude</category>
      <category>llm</category>
    </item>
    <item>
      <title>I built an AI bestie for my Dad’s morning routine ⚡️☀️</title>
      <dc:creator>Maryam Saba</dc:creator>
      <pubDate>Sat, 03 Jan 2026 17:50:03 +0000</pubDate>
      <link>https://dev.to/maryam_saba_792cdbcdb46fd/i-built-an-ai-bestie-for-my-dads-morning-routine-1d86</link>
      <guid>https://dev.to/maryam_saba_792cdbcdb46fd/i-built-an-ai-bestie-for-my-dads-morning-routine-1d86</guid>
      <description>&lt;p&gt;Main Character Energy for your Mornings! ☕️✨&lt;/p&gt;

&lt;p&gt;I lowkey got tired of seeing my Dad head to the office stressed, so I built something special. I created an AI Morning Reminder n8n template that sends a healthy, motivational, and straight-up high-vibe quote every morning before he leaves.&lt;/p&gt;

&lt;p&gt;It’s basically a daily dose of "You got this!" delivered straight to his phone. 📈&lt;/p&gt;

&lt;p&gt;Why you need this in your life:&lt;/p&gt;

&lt;p&gt;Parental W: Set it up for your parents to make their day. 🧿&lt;/p&gt;

&lt;p&gt;Main Character Vibes: Use it for yourself to stay locked in on your goals. 🎯&lt;/p&gt;

&lt;p&gt;Fully Automated: Set it once and let the AI do the heavy lifting while you sleep. 😴&lt;/p&gt;

&lt;p&gt;No More Boring Mornings: Start the day with clarity and energy instead of a random notification dump.&lt;/p&gt;

&lt;p&gt;I’m dropping the template so you guys can use it too! Whether it’s for your own growth or to make your family smile, this is the ultimate productivity + mood hack. 🥂&lt;/p&gt;

&lt;p&gt;Grab it here: &lt;a href="https://maryamshine5.gumroad.com/l/ai-morning-reminder-n8n-template" rel="noopener noreferrer"&gt;AI Morning Reminder&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I lowkey got tired of seeing my Dad head to the office stressed, so I built something special. I created an AI Morning Reminder n8n template that sends a healthy, motivational, and straight-up high-vibe quote every morning before he leaves.&lt;/p&gt;

&lt;p&gt;It’s basically a daily dose of "You got this!" delivered straight to his phone. 📈&lt;/p&gt;

&lt;p&gt;Why you need this in your life:&lt;/p&gt;

&lt;p&gt;Parental W: Set it up for your parents to make their day. 🧿&lt;/p&gt;

&lt;p&gt;Main Character Vibes: Use it for yourself to stay locked in on your goals. 🎯&lt;/p&gt;

&lt;p&gt;Fully Automated: Set it once and let the AI do the heavy lifting while you sleep. 😴&lt;/p&gt;

&lt;p&gt;No More Boring Mornings: Start the day with clarity and energy instead of a random notification dump.&lt;/p&gt;

&lt;p&gt;I’m dropping the template so you guys can use it too! Whether it’s for your own growth or to make your family smile, this is the ultimate productivity + mood hack. 🥂&lt;/p&gt;

</description>
      <category>emailautomation</category>
      <category>webdev</category>
      <category>ai</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
