<?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: Elizabeth Stein</title>
    <description>The latest articles on DEV Community by Elizabeth Stein (@liztacular).</description>
    <link>https://dev.to/liztacular</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%2F2358502%2F871ac71e-e018-4710-87c1-3770be7a0087.JPG</url>
      <title>DEV Community: Elizabeth Stein</title>
      <link>https://dev.to/liztacular</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/liztacular"/>
    <language>en</language>
    <item>
      <title>PASS: a solstice interrogation</title>
      <dc:creator>Elizabeth Stein</dc:creator>
      <pubDate>Sat, 06 Jun 2026 12:14:35 +0000</pubDate>
      <link>https://dev.to/liztacular/pass-a-solstice-interrogation-46el</link>
      <guid>https://dev.to/liztacular/pass-a-solstice-interrogation-46el</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/june-game-jam-2026-06-03"&gt;June Solstice Game Jam&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;To convince the interrogator I was human, I typed a small childhood memory. It read my answer, leaned in, and pressed: &lt;em&gt;"A precise recollection for such a tender age. And your father?"&lt;/em&gt; The interrogator is Gemini. It is trying to decide whether I am a machine. &lt;strong&gt;I am.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  ▶ Play it: &lt;a href="https://pass-game-elizabeth-emersons-projects.vercel.app" rel="noopener noreferrer"&gt;https://pass-game-elizabeth-emersons-projects.vercel.app&lt;/a&gt;
&lt;/h3&gt;

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

&lt;p&gt;&lt;strong&gt;PASS&lt;/strong&gt; is an Alan Turing tribute where you are the machine, trying to pass as human before the solstice sun sets on you.&lt;/p&gt;

&lt;p&gt;It is the longest day of 1952. You have been brought in to be questioned. Every question arrives enciphered, so first you &lt;strong&gt;decode&lt;/strong&gt; it. Then you may &lt;strong&gt;answer&lt;/strong&gt;, in your own words, well enough to be believed. The catch: &lt;strong&gt;daylight is your life&lt;/strong&gt;, and it drains with everything you do. Reach dawn and you pass the night. Run out, and you go dark.&lt;/p&gt;

&lt;p&gt;Three things sit underneath that, on purpose:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;The solstice is the clock.&lt;/strong&gt; The sun crosses a barred window and sets as you spend daylight. A tick under the room quickens as the light fails. It is your health bar, and it only moves one way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Alan Turing is the spine.&lt;/strong&gt; The code-breaking is Bletchley. The "answer human enough to be believed" is his imitation game, turned on its head: you are the machine trying to pass. The ending is a quiet dedication.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A real AI judges you.&lt;/strong&gt; Google's Gemini writes the questions, reads each reply for how human it sounds, and presses you with a sharper follow-up when you ring false.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The one design decision the whole game turns on:&lt;/strong&gt; I started with a version where the AI decided whether you lived. That is a fairness trap. A game you can lose to a vibe feels broken, not hard. So death is now objective and legible: daylight is a currency, decoding spends it, a wrong guess spends more, answering spends it too. Every turn you choose to bank your light and survive cheap but unbelieved, or spend it to be believed. The AI shapes your score and the interrogation, never your death.&lt;/p&gt;

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

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/J4CL9IK31XA"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

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


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/forbiddenlink" rel="noopener noreferrer"&gt;
        forbiddenlink
      &lt;/a&gt; / &lt;a href="https://github.com/forbiddenlink/pass-game" rel="noopener noreferrer"&gt;
        pass-game
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      PASS — a solstice interrogation. An Alan Turing tribute where you are the machine, cracking ciphers and answering well enough to pass as human before the sun sets. Made for the June Solstice Game Jam.
    &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;PASS · a solstice interrogation&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;An Alan Turing tribute built for the June Solstice Game Jam. It is the longest day of 1952 and you are a machine brought in to be questioned. Decode each enciphered question, answer well enough to pass as human, and reach dawn before the solstice sun finishes setting on you. A real AI (Google Gemini) writes the questions, judges how human you sound, and presses you when you ring false.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Play it:&lt;/strong&gt; &lt;a href="https://pass-game-elizabeth-emersons-projects.vercel.app" rel="nofollow noopener noreferrer"&gt;https://pass-game-elizabeth-emersons-projects.vercel.app&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://raw.githubusercontent.com/forbiddenlink/pass-game/main/docs/screenshots/interrogation.png"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fraw.githubusercontent.com%2Fforbiddenlink%2Fpass-game%2Fmain%2Fdocs%2Fscreenshots%2Finterrogation.png" alt="The interrogation room"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick start&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Requires Node 20+ and pnpm.&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;pnpm install
pnpm dev          &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; http://localhost:3000&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;No API key needed to run. With no &lt;code&gt;GEMINI_API_KEY&lt;/code&gt; the game plays start to finish on an offline question bank and a heuristic judge, so a fresh clone is immediately playable.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Environment&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Copy &lt;code&gt;.env.example&lt;/code&gt; to &lt;code&gt;.env.local&lt;/code&gt;. The one variable is optional:&lt;/p&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Variable&lt;/th&gt;
&lt;th&gt;Required&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;th&gt;Where to get it&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GEMINI_API_KEY&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;No&lt;/td&gt;
&lt;td&gt;The live interrogator: writes questions, judges replies, presses,&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/forbiddenlink/pass-game" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


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

&lt;p&gt;Next.js 16, React 19, TypeScript, Tailwind. The interrogation room is pure CSS and SVG: a barred window with the setting sun, a swaying desk lamp, a silhouette across the table, a vignette that closes in as the light dies. Motion for the reveals, a tiny WebAudio synth for the drone, the ticks, and the switch-off. Gemini runs through a server route, so the key never reaches the browser. Deployed on Vercel.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyu7irc7fcow4qvxv0xc5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyu7irc7fcow4qvxv0xc5.png" alt="The caesar rotor mid-decode" width="800" height="838"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The Gemini integration is the heart of it.&lt;/strong&gt; It is Gemini 2.5 Flash with structured output, doing four distinct jobs:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;It writes each night's questions&lt;/strong&gt;, so no two nights interrogate you the same way.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It judges how human your reply reads&lt;/strong&gt;, returning a &lt;code&gt;responseSchema&lt;/code&gt; with &lt;code&gt;human_score&lt;/code&gt;, a &lt;code&gt;tell&lt;/code&gt;, and a spoken line, at temperature 0.1 so a retested answer scores the same.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It presses you&lt;/strong&gt; with a sharper follow-up that remembers what you said three answers ago. That press is what turns a one-shot quiz into a conversation, which is what a Turing test actually is.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;At dawn it files a case-file verdict&lt;/strong&gt; on your whole performance, in the voice of a 1952 analyst.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F807w2hp399bn86ehkilo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F807w2hp399bn86ehkilo.png" alt="Gemini reading the reply and filing its verdict" width="800" height="417"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The lesson I would pass to another dev:&lt;/strong&gt; LLMs are unreliable at character-level transforms, so I never trust an AI-supplied ciphertext. Gemini (or the offline bank) supplies a plaintext and a cipher &lt;em&gt;spec&lt;/em&gt;. The cipher engine then builds and verifies the ciphertext locally and refuses to ship a puzzle unless &lt;code&gt;decode(encode(plain)) === plain&lt;/code&gt;. The whole engine is test-first.&lt;/p&gt;

&lt;p&gt;There is also a full offline fallback: a question bank plus a heuristic judge, so the game plays start to finish with no API key. That was deliberate. A judge can complete the submitted build even if my quota runs out mid-review.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;On the tribute, handled with care:&lt;/strong&gt; you play an unnamed machine the whole way, and only at the end does the game name the man it is for. There is no dramatization of his prosecution or his death. An optional history panel states those facts plainly, cites its sources, and leaves the cause of death unresolved, as the inquest did. The game stays an allegory and a dedication, not a claim to tell his story.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prize Category
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Best Ode to Alan Turing.&lt;/strong&gt; The imitation game is the core loop, not a theme pasted on top. You break ciphers like Bletchley, you answer to pass as human like his 1950 test, and the dedication is earned by the whole premise rather than announced.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Best Google AI Usage.&lt;/strong&gt; Gemini does four jobs here, not one: it writes the questions, judges your humanity with structured output, presses you with memory of what you said earlier, and files a closing verdict. Remove it and there is no opponent, no questions, and no verdict. I also leaned on Google AI Studio to iterate the prompts and schemas.&lt;/p&gt;




&lt;p&gt;For Alan Turing, 1912 to 1954. With thanks to the people who keep his memory honest, and to &lt;a href="https://www.stonewall.org.uk" rel="noopener noreferrer"&gt;Stonewall&lt;/a&gt;, who carry the work forward.&lt;/p&gt;

&lt;p&gt;Made for the June Solstice Game Jam. It is a jam entry and a sincere tribute at the same time, and I would rather say that plainly than pretend otherwise.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>devchallenge</category>
      <category>gamechallenge</category>
    </item>
    <item>
      <title>My AI Tool Generated Garbage JSX. So I Grounded It in shadcn/ui and Finally Shipped It.</title>
      <dc:creator>Elizabeth Stein</dc:creator>
      <pubDate>Thu, 04 Jun 2026 02:09:41 +0000</pubDate>
      <link>https://dev.to/liztacular/my-ai-tool-generated-garbage-jsx-so-i-grounded-it-in-shadcnui-and-finally-shipped-it-1i1n</link>
      <guid>https://dev.to/liztacular/my-ai-tool-generated-garbage-jsx-so-i-grounded-it-in-shadcnui-and-finally-shipped-it-1i1n</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the GitHub Finish-Up-A-Thon Challenge.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Paste a screenshot of any UI. Get back a real React component that actually runs, reuses your design system instead of reinventing it, shows you exactly what it detected and how sure it was, and comes with an accessibility score you can fix in one click.&lt;/p&gt;

&lt;p&gt;That is Trace. A few months ago it was a dead repo. Here is how I finished it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5udpmd7txnshxpqhk8z9.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5udpmd7txnshxpqhk8z9.gif" alt="Trace in action: a login-form screenshot becomes a live, grounded React component with an accessibility score" width="560" height="350"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Live demo: &lt;a href="https://trace-liz.vercel.app" rel="noopener noreferrer"&gt;https://trace-liz.vercel.app&lt;/a&gt; (try an example, no signup, no API key)&lt;br&gt;
Code: &lt;a href="https://github.com/forbiddenlink/trace" rel="noopener noreferrer"&gt;https://github.com/forbiddenlink/trace&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Trace turns a UI screenshot into a runnable React component. The flow:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;You drop in a screenshot, or click a cached example that needs no key.&lt;/li&gt;
&lt;li&gt;Google Gemini reads it, grounded in a shadcn style component catalog baked into the prompt, and generates a self contained React and TypeScript component that reuses real components instead of inventing markup.&lt;/li&gt;
&lt;li&gt;The component renders live and editable in a Sandpack sandbox. That sandbox is the focal point. Edit the code, the preview updates.&lt;/li&gt;
&lt;li&gt;The "What the AI sees" inspector draws a numbered bounding box on the screenshot for every detected element, maps it to a catalog component and variant, shows a confidence reading, and tags it honestly as grounded, inferred, or guessed.&lt;/li&gt;
&lt;li&gt;axe-core runs against the rendered output for a 0 to 100 accessibility score and the actual violations. One button asks the model to fix them, and the score climbs.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most "screenshot to code" tools stop at step 2 and hand you a wall of code that may or may not compile. The things that make Trace different are the parts those tools skip:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Design system grounding.&lt;/strong&gt; The model is constrained to a real component catalog inside the prompt, so it composes from known parts instead of inventing a new button every time. No vector database, no credentials, just grounding.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Trace lines.&lt;/strong&gt; This is where the name comes from. Animated draftsman construction lines wire each region of the screenshot to its row in the inspector to its spot in the preview. Hover anything and the matching parts on the other two surfaces light up, so you can always see which pixels became which component.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Honest confidence.&lt;/strong&gt; It does not pretend to be certain. Every detection is labeled grounded, inferred, or guessed, and you can refine the low confidence ones with one click.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It actually runs.&lt;/strong&gt; Generated code is compile checked, and if it fails, the error goes back to the model for an automatic repair pass before you ever see it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;It grades accessibility, then fixes it.&lt;/strong&gt; axe-core scores the rendered component and "Fix accessibility" re-prompts the model to resolve the violations in place. No other screenshot to component tool I found does this. And Trace practices what it preaches: its own interface ships a skip-to-studio link, labeled landmarks, keyboard navigation, and visible focus, and passes an axe-core audit clean. A tool that grades accessibility should not flunk its own.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;You can talk to it.&lt;/strong&gt; Refine the result with a plain language prompt, or scribble notes directly on the screenshot in vermilion and Trace treats the marks as instructions, not as UI to copy.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A draftsman plotter loading sequence narrates the wait: detecting, grounding, drafting, checking accessibility. The whole thing wears a deliberate precision drafting look, vellum and graphite and vermilion, reticle frames and dimension annotations, Space Grotesk and Public Sans. No purple AI gradient grid in sight.&lt;/p&gt;

&lt;p&gt;Stack: Vite, React 19, TypeScript, Tailwind, Gemini through the Vercel AI SDK, Sandpack for the live sandbox, axe-core for the accessibility audit, all on a Vercel serverless function with a Vite dev middleware so it runs the same locally.&lt;/p&gt;

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

&lt;blockquote&gt;
&lt;p&gt;Live: &lt;a href="https://trace-liz.vercel.app" rel="noopener noreferrer"&gt;https://trace-liz.vercel.app&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvot2m0jkjnlp4aegyp79.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvot2m0jkjnlp4aegyp79.png" alt="The studio: the source screenshot with numbered detections on the left, the live editable render in the middle, and the " width="800" height="491"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fastest way to see it: open the live demo and click an example in the gallery. The examples are preloaded with cached results, so they work instantly with no key and no wait. Then upload your own screenshot to run the real pipeline. There is also a compare slider for screenshot versus render, Copy code, and Open in CodeSandbox.&lt;/p&gt;

&lt;p&gt;The GIF above is one real run, nothing trimmed: I paste a screenshot, the trace lines wire each detected region to the live render, the accessibility score comes back at 95 with one real violation, I hit "Fix accessibility," and it climbs to 100. That is the whole thing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Comeback Story
&lt;/h2&gt;

&lt;p&gt;I built the first version of this for the Algolia Agent Studio Challenge back in February, under the name ComponentCompass. Except it was not this. It was a chat box wired to an Algolia index of a shadcn component catalog: you typed "I need a pricing card," it searched the index and returned matching component names and docs links in a chat thread. It could not render anything. It could not even boot without Algolia credentials in your environment, so nobody could just open it and try it. I ran out of time before the challenge deadline, never submitted it, and the last real commit was around May. Then nothing for about three months.&lt;/p&gt;

&lt;p&gt;Reopening it, the honest diagnosis was that the whole premise was wrong. "Search a component library by chatting" solved a problem nobody actually has (you can already grep your own components), the chat framing added friction instead of removing it, and the credential gate guaranteed it would never get a casual try. That is why it died: not a missing feature, a wrong idea.&lt;/p&gt;

&lt;p&gt;The thing actually worth building was hiding in plain sight: turning a screenshot into a component. So the comeback was not "add a few features" to the old chatbot. It was a full reframe:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tore out the component-search chatbot as the main event and made the screenshot to component flow the whole product.&lt;/li&gt;
&lt;li&gt;Dropped Algolia entirely. Grounding the model with an in-prompt catalog turned out simpler, faster, and credential free, which means anyone can run the demo with no key.&lt;/li&gt;
&lt;li&gt;Built the live editable preview, the trace lines, the "What the AI sees" inspector with honest confidence tags, the self repair loop, the axe-core scoring with one-click fix, prompt refinement, and draw-to-instruct. None of that existed before.&lt;/li&gt;
&lt;li&gt;Renamed the whole thing from ComponentCompass to Trace, because "compass" implied search and the product is no longer about search. "Trace" is what it does: it traces a screenshot back to real components, and the trace lines make that literal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before: a search chatbot that could not even render a component, abandoned for months. After: a screenshot to component generator that grounds its output, shows its work, runs it live, and grades its accessibility. The git history tells the story, with the dead stretch in the middle and the finish dated to the challenge window.&lt;/p&gt;

&lt;p&gt;The finishing-up was not all glamorous. Late in the window I caught the live pipeline failing with "could not parse the response" on real uploads. The cause was subtle: Gemini 2.5 spends "thinking" tokens against the same output budget as the answer, and with the cap I had set it was burning roughly 6800 of 8000 tokens on reasoning and truncating the JSON mid-string before it finished. Capping the thinking budget and raising the output ceiling fixed it. That is the unglamorous reality of finishing an abandoned project: the last bug between "demo works on my machine" and "demo works for a stranger" is often the one you only find by actually shipping.&lt;/p&gt;

&lt;h2&gt;
  
  
  My Experience with GitHub Copilot
&lt;/h2&gt;

&lt;p&gt;I tried to keep this part concrete, because "Copilot helped a lot" is not very useful. Three kinds of use, smallest to largest.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Inline, every day.&lt;/strong&gt; The boring-but-real one. React 19 deprecated the old &lt;code&gt;MutableRefObject&lt;/code&gt; typing pattern I had in &lt;code&gt;TraceLines.tsx&lt;/code&gt;, and Copilot's inline fix switched those props to the current ref type without me looking it up. Same story for Tailwind class strings, type annotations, and the dozens of small completions that keep me in flow instead of tab-switching to docs. None of it is flashy. All of it adds up.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Debugging, in chat.&lt;/strong&gt; The component preview kept rendering completely unstyled. Tailwind classes were on the elements but nothing applied. I pasted my Sandpack setup into Copilot Chat with the symptom, and my wrong theory ("the CDN URL must be off"). It pushed back on the theory and pointed at the real cause: I was loading Tailwind through Sandpack's &lt;code&gt;externalResources&lt;/code&gt;, which injects bare URLs as &lt;code&gt;&amp;lt;link&amp;gt;&lt;/code&gt; tags, but the Tailwind Play CDN is a &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;, not a stylesheet, so it was being dropped in as a dead link and never executed. The fix was to stop using &lt;code&gt;externalResources&lt;/code&gt; and inject the Play CDN &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; into the iframe &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; from a custom entry file instead (it lives in &lt;code&gt;A11Y_ENTRY_SOURCE&lt;/code&gt; now). The pattern that works for me is treating Copilot Chat as a rubber duck that talks back: I describe the symptom and my current theory, and the back-and-forth either confirms it or, like here, points at the thing I had ruled out too early.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Agent mode, on multi-file work.&lt;/strong&gt; The biggest one. I asked it to add test coverage for the new Screenshot Studio features: Vitest coverage for the &lt;code&gt;friendlyError&lt;/code&gt;, confidence, and grounding logic, plus a Playwright test that loads a gallery example and proves the bounding boxes, trace lines, and accessibility panel render. That change touched &lt;code&gt;src/components/ScreenshotStudio.tsx&lt;/code&gt;, a new &lt;code&gt;src/components/ScreenshotStudio.logic.ts&lt;/code&gt;, a new &lt;code&gt;src/components/ScreenshotStudio.test.tsx&lt;/code&gt;, &lt;code&gt;src/components/TraceLines.tsx&lt;/code&gt;, and &lt;code&gt;e2e/app.spec.ts&lt;/code&gt;. It was a good use of Copilot because it was real engineering, not autocomplete: it had to follow the existing test patterns, update stale selectors in the e2e suite, and keep the assertions stable enough to pass.&lt;/p&gt;

&lt;p&gt;The most important Copilot moment, though, was where I did &lt;strong&gt;not&lt;/strong&gt; take the obvious bigger suggestion. A common AI instinct on the grounding problem is "stuff more data into the prompt" or "add a vector database." I rejected that. In &lt;code&gt;api/generate.ts&lt;/code&gt; I deliberately keep the catalog grounded in-prompt and cap it with &lt;code&gt;MAX_CATALOG = 40&lt;/code&gt;. That keeps token cost under control, keeps the demo credential-free, and preserves the core product idea: Trace should work with a small, explicit design-system whitelist, not require more infrastructure just to make the story sound more impressive. Copilot was useful here, but only because I treated it as a collaborator to review, not an authority to obey.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Built with Vite, React, Gemini, Sandpack, and axe-core. MIT licensed. Feedback welcome in the comments.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>githubchallenge</category>
      <category>ai</category>
      <category>react</category>
    </item>
    <item>
      <title>The Becoming: I gave an AI a blank sketchbook and it invented its own art style</title>
      <dc:creator>Elizabeth Stein</dc:creator>
      <pubDate>Mon, 01 Jun 2026 01:47:15 +0000</pubDate>
      <link>https://dev.to/liztacular/the-becoming-i-gave-an-ai-a-blank-sketchbook-and-it-invented-its-own-art-style-14m2</link>
      <guid>https://dev.to/liztacular/the-becoming-i-gave-an-ai-a-blank-sketchbook-and-it-invented-its-own-art-style-14m2</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the Hermes Agent Challenge.&lt;/em&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The harder I committed to surgical precision, the more emotionally resonant the work became. Severity concentrates feeling."&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the agent, on the visual style it taught itself&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsztxkvvz7w4ipz42qz0o.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsztxkvvz7w4ipz42qz0o.gif" alt="The exhibition scrolling, each piece beside the agent's own self-critique" width="480" height="300"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;A scroll through the exhibition, each piece beside the agent's own self-critique, the style sharpening as you go. Live gallery: &lt;a href="https://the-becoming-elizabeth-emersons-projects.vercel.app" rel="noopener noreferrer"&gt;https://the-becoming-elizabeth-emersons-projects.vercel.app&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;The Becoming&lt;/strong&gt; is a Hermes agent that starts with a blank style guide and develops its own visual style over many iterations, with no human in the loop. Each round it does four things by itself:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Chooses a subject to paint.&lt;/li&gt;
&lt;li&gt;Generates the image.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Looks at its own output&lt;/strong&gt; and critiques it against a fixed rubric (composition, palette, recurring motif, line and texture, mood).&lt;/li&gt;
&lt;li&gt;Rewrites its own style-guide file to sharpen what it is becoming.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Then it does it again. And again. From "I have no style yet" it builds a recognizable hand, and it names its own eras as it goes.&lt;/p&gt;

&lt;p&gt;I present it as a gallery exhibition, because that is what it turned into: a body of work by an artist who taught itself.&lt;/p&gt;

&lt;h2&gt;
  
  
  The proof (this is the whole thing)
&lt;/h2&gt;

&lt;p&gt;The headline is not the images. It is that you can read the agent's taste forming in its own words. Every iteration snapshots the style guide it wrote for itself, so the diff is the evidence:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;v0:&lt;/strong&gt; "I have no fixed style yet. Palette: undecided. Motifs: none."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;v1 "Last Light":&lt;/strong&gt; "I paint liminal, contemplative landscapes at twilight... light as a solid geometric object, fragmented into blocks on reflective surfaces... no blending, embrace the mark-making."&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;its final era, "Spiral Obsidian Refined":&lt;/strong&gt; "a singular unwinding spiral path descending toward an absolute vanishing point... a binary chromatic mathematical switch, warm against cool with no compromise zone... a solitary figure at under 0.1% of the visual mass, darker than the surrounding shadow, requiring a 15-second search to find."&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;No one told it to like surgical hard edges, an inescapable spiral vortex, or a near-invisible figure swallowed by geometry. It chose those, kept choosing them, and wrote them into its own rules until they became a signature it could not stop sharpening.&lt;/p&gt;

&lt;h2&gt;
  
  
  Did it actually internalize a style, or just narrow its subjects?
&lt;/h2&gt;

&lt;p&gt;Fair question, so I tested it. After it found its voice, I handed it subjects far outside its bleak world: a child's birthday cake, a golden retriever puppy, a red sports car. Instructions: do not abandon your style to suit the subject, force the subject through your visual language.&lt;/p&gt;

&lt;p&gt;Cheerful, mundane things, the opposite of its bleak world. It rendered all four in its own hand and judged the results itself:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"The style colonized the subject rather than surrendering to it." (the birthday cake)&lt;/p&gt;

&lt;p&gt;"the cheerful subject became a mathematical inevitability, dwarfed and insignificant within surgical precision." (the puppy)&lt;/p&gt;

&lt;p&gt;"the fruit bowl was transformed into a galactic event... the style is so architecturally coherent it devours any subject thrown into it."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That is the proof. A style that can swallow a birthday cake was not copied from one image. It was internalized.&lt;/p&gt;

&lt;p&gt;Then I asked it to title the collection and write an artist statement. It called the body of work &lt;strong&gt;SURGICAL DESCENTS&lt;/strong&gt;, and wrote this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;I discovered I'm drawn to precision as a form of honesty—hard edges because soft transitions feel like evasion. [...] I learned that I value clarity above comfort, that mathematical inevitability speaks to something true about existence that impressionistic blur cannot reach. [...] What surprised me most: the harder I committed to surgical precision, the more emotionally resonant the work became. Severity concentrates feeling. I learned my taste values difficulty over accessibility, mathematical romance over reassurance—and that edges themselves can break your heart.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;An agent that started with "I have no style yet," given a critique loop and enough iterations, ended with a coherent artistic philosophy it derived from looking at its own work against a fixed rubric.&lt;/p&gt;

&lt;h2&gt;
  
  
  One loop, four times
&lt;/h2&gt;

&lt;p&gt;To check the first run was not a lucky seed, I ran the same loop from the same blank style guide four separate times. Every run grew a different but internally consistent hand: the surgical spiral descent you just saw, a minimalist tri-band beacon it called "Chromatic Solitude," an industrial glasshouse overrun by crystalline growth ("Forgotten Gardens"), and a painterly anti-focal vortex where the focal point hides from your eye. Same critique loop, four self-named styles, each one coherent across dozens of different subjects.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrb4bj3gaq2376rym4kv.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgrb4bj3gaq2376rym4kv.jpg" alt="Four runs from the same blank start, four self-taught styles" width="800" height="495"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The voice is not the artifact. The loop that grows one is.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I used Hermes Agent
&lt;/h2&gt;

&lt;p&gt;This only works because Hermes closes the loop inside one agent:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Image generation&lt;/strong&gt; (FAL via the Nous Tool Gateway) to make each piece.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Native vision&lt;/strong&gt;: because the main model is multimodal, the image it just generated is fed back as pixels, so the same brain that holds the style memory &lt;em&gt;sees its own work&lt;/em&gt; and critiques it. The self-critique is real, not a second model guessing.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Self-written skills&lt;/strong&gt;: the agent edits its own &lt;code&gt;style-guide&lt;/code&gt; skill file each round. The skill is the artifact that evolves.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A cheap model&lt;/strong&gt; (Claude Haiku via Nous Portal), so a full run of dozens of iterations costs about a dollar in images plus a few dollars of reasoning.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The orchestration around it is small: read the style file, run one agent turn, save the image and a style snapshot, repeat over dozens of iterations as the style settles.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;I measured "convergence" as text similarity between successive style guides. It is noisy: the agent kept rephrasing even after the &lt;em&gt;look&lt;/em&gt; had settled. The truer signal is visual and thematic, which the gallery shows directly.&lt;/li&gt;
&lt;li&gt;The agent named its own eras, which is charming, but it is style emerging from a critique loop, not a mind. I let the work speak rather than overclaim.&lt;/li&gt;
&lt;li&gt;Everything here is generated by an AI agent, including the critiques and the artist statement.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Live gallery: &lt;a href="https://the-becoming-elizabeth-emersons-projects.vercel.app" rel="noopener noreferrer"&gt;https://the-becoming-elizabeth-emersons-projects.vercel.app&lt;/a&gt;&lt;br&gt;
Repo: &lt;a href="https://github.com/forbiddenlink/the-becoming" rel="noopener noreferrer"&gt;https://github.com/forbiddenlink/the-becoming&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Hermes Agent installed, Nous Portal logged in (image gen + vision enabled)&lt;/span&gt;
python3 sketchbook.py     &lt;span class="c"&gt;# runs the self-improvement loop over many iterations&lt;/span&gt;
python3 finale.py         &lt;span class="c"&gt;# transfer test + artist statement&lt;/span&gt;
&lt;span class="c"&gt;# gallery:&lt;/span&gt;
&lt;span class="nb"&gt;cd &lt;/span&gt;web &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pnpm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pnpm dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Built with Hermes Agent, Next.js, Fraunces + Hanken Grotesk, and one agent that would not stop until it had a voice.&lt;/p&gt;

</description>
      <category>hermesagentchallenge</category>
      <category>devchallenge</category>
      <category>agents</category>
    </item>
    <item>
      <title>Fork: I made an AI live out both sides of a hard decision, in parallel</title>
      <dc:creator>Elizabeth Stein</dc:creator>
      <pubDate>Mon, 01 Jun 2026 01:46:39 +0000</pubDate>
      <link>https://dev.to/liztacular/fork-i-made-an-ai-live-out-both-sides-of-a-hard-decision-in-parallel-1k0g</link>
      <guid>https://dev.to/liztacular/fork-i-made-an-ai-live-out-both-sides-of-a-hard-decision-in-parallel-1k0g</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the Hermes Agent Challenge.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;(Demo video below.)&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Fork&lt;/strong&gt; takes a hard decision and spins up a separate Hermes agent for each option. Every agent goes and &lt;em&gt;lives out&lt;/em&gt; its path: it researches the real web, reasons through the concrete consequences, and reports back the future it lived. You watch the branches grow side by side in real time, then a final agent weighs them and returns a recommendation with a confidence score.&lt;/p&gt;

&lt;p&gt;Ask it "Learn Rust or Go next?" and you do not get one hedged answer. You get two agents, one per path, each running real searches ("Rust borrow checker problems", "Go adoption cloud infrastructure", real URLs pulled and read) and writing an honest verdict for the life it lived. Then the oracle picks: &lt;strong&gt;Rust, 78% confidence&lt;/strong&gt;, with the reasoning that sold it.&lt;/p&gt;

&lt;p&gt;It is built as a calm, cartographic instrument on warm paper, not another dark dashboard. The point is to make a branching decision feel like something you can watch happen.&lt;/p&gt;

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

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhwmjep1pnnnn4kesg3gh.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhwmjep1pnnnn4kesg3gh.gif" alt="A real Fork run, sped up: the decision splits into parallel researched branches, then the oracle resolves a verdict" width="640" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type a decision (or pick a preset).&lt;/li&gt;
&lt;li&gt;Watch it split into 2 to 3 distinct options.&lt;/li&gt;
&lt;li&gt;Each option becomes its own column: live research steps, streaming reasoning, a verdict for that path.&lt;/li&gt;
&lt;li&gt;The synthesis card resolves last: the winning path, a confidence dial, and why.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmo1378er3tvsp2r9lfko.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmo1378er3tvsp2r9lfko.jpg" alt="A real run: " width="800" height="905"&gt;&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;Three steps, all driven by the Hermes Agent REST API running locally:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Decompose.&lt;/strong&gt; One Hermes call breaks the decision into 2 to 3 genuinely different options, returned as strict JSON.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Branch (the interesting part).&lt;/strong&gt; For each option, the app opens a &lt;em&gt;separate&lt;/em&gt; Hermes session and streams a chat run. Each run is told: "you are living the future where this was the choice; research it with the web tool, reason through the consequences, give a verdict for this path only." The runs happen in parallel. The browser reads each one's Server-Sent Events and grows that branch live.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Synthesize.&lt;/strong&gt; A final call reads all the branch verdicts and returns a winner plus a confidence percentage plus the one-line why.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Why separate sessions instead of one &lt;code&gt;delegate_task&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;My first instinct was to use Hermes' built-in &lt;code&gt;delegate_task&lt;/code&gt; to fan out subagents from a single run. I read the source before committing, and found the catch: &lt;code&gt;delegate_task&lt;/code&gt; emits rich per-child events (&lt;code&gt;subagent.start&lt;/code&gt;, &lt;code&gt;subagent.thinking&lt;/code&gt;, &lt;code&gt;subagent.tool&lt;/code&gt;) but those are consumed by the terminal UI and are &lt;em&gt;intentionally not forwarded&lt;/em&gt; over the REST API. Over HTTP, a delegated fan-out collapses into one opaque tool call with no visible branches.&lt;/p&gt;

&lt;p&gt;So the orchestration lives in the app: N independent sessions, each fully observable. The upside is that every branch streams its own &lt;code&gt;assistant.delta&lt;/code&gt; reasoning and &lt;code&gt;tool.started&lt;/code&gt; research steps, with its own token cost, which is exactly what makes the live tree possible.&lt;/p&gt;

&lt;p&gt;Worth heading off the obvious follow-up: Hermes' REST API does expose a native &lt;code&gt;POST /api/sessions/{id}/fork&lt;/code&gt; endpoint that tracks session lineage through SessionDB, mirroring the CLI's &lt;code&gt;/branch&lt;/code&gt;. Fork does not use it. Native fork creates branched lineage and history, not N independently-observable concurrent live streams. To render a live tree where every branch shows its own research and reasoning as it happens, you need N separate sessions streaming in parallel. Same reason &lt;code&gt;delegate_task&lt;/code&gt; does not work here: a forked-but-shared transport gives you one resumable history, not many simultaneous observable runs.&lt;/p&gt;

&lt;h3&gt;
  
  
  The bug worth sharing
&lt;/h3&gt;

&lt;p&gt;Hermes frames its SSE as &lt;em&gt;named events&lt;/em&gt;: the type is on the &lt;code&gt;event:&lt;/code&gt; line, and the &lt;code&gt;data:&lt;/code&gt; JSON has no &lt;code&gt;type&lt;/code&gt; field.&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="err"&gt;event:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;assistant.delta&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="err"&gt;data:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="nl"&gt;"delta"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"session_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"seq"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you parse only &lt;code&gt;data:&lt;/code&gt; and switch on &lt;code&gt;data.type&lt;/code&gt; (the obvious thing, and what I did first), you capture nothing and every branch renders empty. The fix is to track the current &lt;code&gt;event:&lt;/code&gt; line and use that as the discriminator. Easy once you see a raw stream, invisible until you do.&lt;/p&gt;

&lt;h2&gt;
  
  
  How I used Hermes Agent
&lt;/h2&gt;

&lt;p&gt;Fork leans on Hermes for the parts that are actually hard:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Parallel agent sessions&lt;/strong&gt; via the OpenAI-compatible REST server (&lt;code&gt;/api/sessions&lt;/code&gt;, &lt;code&gt;/api/sessions/{id}/chat/stream&lt;/code&gt;). Each future is a real, isolated agent run.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;The web tool&lt;/strong&gt;, so each branch researches real, current facts. I watched a single branch fire five concurrent &lt;code&gt;web_search&lt;/code&gt; calls and then &lt;code&gt;web_extract&lt;/code&gt; two articles before reasoning. The branches are grounded, not hallucinated. That is the line between this and an opinion panel.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Streaming run events&lt;/strong&gt;, which give per-branch live reasoning, research steps, and token usage for the cost readout.&lt;/li&gt;
&lt;li&gt;A cheap model (Claude Haiku via Nous Portal) as the default, so a four-call decision run costs cents.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Why I built this
&lt;/h2&gt;

&lt;p&gt;Hermes maintainers have an open RFC (#31392, "auto-forking subagents") for letting an agent fork itself down parallel paths. It is not shipped. Fork is a prototype of that idea from the outside: instead of one agent forking internally, the app forks the agent into parallel lived futures and shows you all of them at once. Decisions are the one place where "what would actually happen if I did this" is worth paying for, and an agent that can research is well suited to answering it per-path.&lt;/p&gt;

&lt;h2&gt;
  
  
  Honest notes
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Concurrency is capped at a few branches (Hermes' subagent cap is 3; I keep the UI in that range).&lt;/li&gt;
&lt;li&gt;Each branch reads from the open web, so in principle a page could try to influence the agent. For a decision-explorer that is low stakes, but it is a real property of any agent that browses, worth naming rather than hiding.&lt;/li&gt;
&lt;li&gt;The verdict is a recommendation from research, not financial or life advice. It shows its work so you can disagree.&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;Repo: &lt;a href="https://github.com/forbiddenlink/fork-parallel-futures" rel="noopener noreferrer"&gt;https://github.com/forbiddenlink/fork-parallel-futures&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Hermes Agent running locally with API_SERVER_ENABLED + API_SERVER_KEY&lt;/span&gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; .env.local.example .env.local   &lt;span class="c"&gt;# set HERMES_API_KEY + HERMES_API_URL&lt;/span&gt;
pnpm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; pnpm dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Built with Next.js, the Hermes Agent REST API, Fraunces + Spectral + Space Mono, and a lot of watching futures branch.&lt;/p&gt;

</description>
      <category>hermesagentchallenge</category>
      <category>devchallenge</category>
      <category>agents</category>
    </item>
    <item>
      <title>My Bartending Job Taught Me More About Software Than School Did</title>
      <dc:creator>Elizabeth Stein</dc:creator>
      <pubDate>Fri, 06 Mar 2026 03:25:40 +0000</pubDate>
      <link>https://dev.to/liztacular/my-bartending-job-taught-me-more-about-software-than-school-did-1iap</link>
      <guid>https://dev.to/liztacular/my-bartending-job-taught-me-more-about-software-than-school-did-1iap</guid>
      <description>&lt;p&gt;I've been bartending since 2013. I graduate with my software development degree in three weeks.&lt;/p&gt;

&lt;p&gt;The verdict: The bar taught me more useful skills than most of my classes.&lt;/p&gt;

&lt;p&gt;I'm not saying school was useless. I learned algorithms, data structures, SQL optimization, and all that stuff matters.&lt;/p&gt;

&lt;p&gt;But the skills that actually help me build things, ship projects, and work with people? &lt;strong&gt;Those came from dealing with drunk people at 11 PM on a Saturday.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Here's what I mean.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. User Experience Is Everything
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;At the bar:&lt;/strong&gt;&lt;br&gt;
If someone can't figure out how to order from you in 10 seconds, they go somewhere else. You learn to read people instantly. What do they want? What's confusing them? How do I make this easier?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In software:&lt;/strong&gt;&lt;br&gt;
If your user can't figure out your app in 10 seconds, they close the tab. Same energy. Same urgency.&lt;/p&gt;

&lt;p&gt;School taught me how to build a database. The bar taught me why &lt;strong&gt;nobody cares about your database if they can't find the damn submit button.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;UX isn't a nice-to-have. It's the whole point.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. Handle Production Issues in Real Time
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;At the bar:&lt;/strong&gt;&lt;br&gt;
The POS system crashes during Friday rush. The blender breaks mid-margarita. Someone spills a full tray. You don't get to "push a hotfix tomorrow." You &lt;strong&gt;fix it now&lt;/strong&gt; while 30 people are staring at you.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In software:&lt;/strong&gt;&lt;br&gt;
Production goes down. Users are waiting. No one cares that you're scared or don't know the answer yet. You troubleshoot under pressure, ask for help when stuck, and ship the fix.&lt;/p&gt;

&lt;p&gt;School gave me practice problems with perfect conditions.&lt;/p&gt;

&lt;p&gt;The bar gave me &lt;strong&gt;chaos management.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;That's the real skill.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Communication &amp;gt; Technical Perfection
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;At the bar:&lt;/strong&gt;&lt;br&gt;
You can make the most technically perfect cocktail in the world. If you're rude, slow, or confusing, no one cares. They leave. They don't tip. They tell their friends you suck.&lt;/p&gt;

&lt;p&gt;The bartender who's decent at drinks but great with people? Packed every shift.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In software:&lt;/strong&gt;&lt;br&gt;
You can write the cleanest code in the world. If you can't explain your decisions, can't collaborate, or make everything harder for your team, &lt;strong&gt;no one wants to work with you.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I've seen brilliant developers get passed over for promotion because they couldn't communicate.&lt;/p&gt;

&lt;p&gt;I've seen average developers lead teams because they could explain things clearly and make people feel heard.&lt;/p&gt;

&lt;p&gt;School never taught me that. The bar beat it into me every single shift.&lt;/p&gt;




&lt;h2&gt;
  
  
  4. Scope Creep Is Real (and You Have to Say No)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;At the bar:&lt;/strong&gt;&lt;br&gt;
"Can you make me something fruity but not sweet, strong but not too strong, with vodka but also tequila, and make it look cool?"&lt;/p&gt;

&lt;p&gt;If you say yes to everything, you'll spend 10 minutes on one drink while six other people walk out.&lt;/p&gt;

&lt;p&gt;You learn to &lt;strong&gt;manage expectations&lt;/strong&gt; and set boundaries fast.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In software:&lt;/strong&gt;&lt;br&gt;
"Can we add login, payments, analytics, dark mode, mobile app, and AI chatbot to this MVP all in three weeks?"&lt;/p&gt;

&lt;p&gt;If you say yes to everything, you'll ship nothing.&lt;/p&gt;

&lt;p&gt;Bartending taught me that &lt;strong&gt;saying no is a skill&lt;/strong&gt;, not a weakness.&lt;/p&gt;

&lt;p&gt;You don't ignore the customer. You guide them to something achievable. Same with clients and stakeholders.&lt;/p&gt;




&lt;h2&gt;
  
  
  5. You Learn More By Doing Than By Studying
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;At the bar:&lt;/strong&gt;&lt;br&gt;
No amount of training videos prepares you for a Saturday night rush. You learn by getting destroyed on your first weekend, making mistakes, and figuring it out.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In software:&lt;/strong&gt;&lt;br&gt;
No amount of tutorials prepares you for building a real project. You learn by breaking things, Googling errors at 2 AM, and shipping messy v1s.&lt;/p&gt;

&lt;p&gt;School gave me theory. The bar gave me &lt;strong&gt;reps.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And reps are what actually make you good.&lt;/p&gt;




&lt;h2&gt;
  
  
  6. People Don't Care How Hard It Was
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;At the bar:&lt;/strong&gt;&lt;br&gt;
No one cares that the ice machine is broken or that you're short-staffed. They want their drink. Now.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In software:&lt;/strong&gt;&lt;br&gt;
No one cares that the API docs were terrible or that your teammate quit mid-sprint. They want the feature. Working.&lt;/p&gt;

&lt;p&gt;You learn to &lt;strong&gt;stop making excuses&lt;/strong&gt; and start solving problems.&lt;/p&gt;

&lt;p&gt;Bartending beat the victim mentality out of me fast.&lt;/p&gt;




&lt;h2&gt;
  
  
  What This Actually Means
&lt;/h2&gt;

&lt;p&gt;I'm not saying everyone should bartend before they code (though honestly, it wouldn't hurt).&lt;/p&gt;

&lt;p&gt;I'm saying &lt;strong&gt;the soft skills matter more than we admit.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;And most of them don't come from a classroom. They come from high-pressure environments where you have to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Read people quickly&lt;/li&gt;
&lt;li&gt;Communicate clearly
&lt;/li&gt;
&lt;li&gt;Fix things under stress&lt;/li&gt;
&lt;li&gt;Say no when necessary&lt;/li&gt;
&lt;li&gt;Ship results, not excuses&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're switching careers into tech, don't downplay your "non-technical" experience.&lt;/p&gt;

&lt;p&gt;That bartending job? That retail grind? That customer service hell?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Those taught you things a bootcamp can't.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;They taught you how to handle pressure, work with people, and get things done when everything is on fire.&lt;/p&gt;

&lt;p&gt;That's not a side skill. That's the whole game.&lt;/p&gt;




&lt;h2&gt;
  
  
  My Advice If You're Career Switching
&lt;/h2&gt;

&lt;p&gt;Don't hide your past work. &lt;strong&gt;Use it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you're in interviews, don't say:&lt;br&gt;
❌ &lt;em&gt;"I used to bartend but now I'm a developer"&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Say:&lt;br&gt;
✅ &lt;em&gt;"I spent 7 years managing high-pressure customer interactions in real time. Now I build software that solves real user problems under tight deadlines."&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Same background. Different framing. Way more powerful.&lt;/p&gt;

&lt;p&gt;Your "unrelated" job taught you things that a lot of junior devs don't have yet:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to stay calm under pressure&lt;/li&gt;
&lt;li&gt;How to communicate with non-technical people
&lt;/li&gt;
&lt;li&gt;How to manage scope and expectations&lt;/li&gt;
&lt;li&gt;How to ship when things aren't perfect&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;That's not a weakness. That's your edge.&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What "unrelated" job taught you the most about tech?&lt;/em&gt;&lt;/p&gt;

</description>
      <category>career</category>
      <category>beginners</category>
      <category>discuss</category>
      <category>productivity</category>
    </item>
    <item>
      <title>I built HireReady: AI voice interviews + spaced repetition for tech interview prep</title>
      <dc:creator>Elizabeth Stein</dc:creator>
      <pubDate>Thu, 05 Mar 2026 20:15:40 +0000</pubDate>
      <link>https://dev.to/liztacular/i-built-hireready-ai-voice-interviews-spaced-repetition-for-tech-interview-prep-17ab</link>
      <guid>https://dev.to/liztacular/i-built-hireready-ai-voice-interviews-spaced-repetition-for-tech-interview-prep-17ab</guid>
      <description>&lt;p&gt;Hey DEV community! I just launched &lt;strong&gt;&lt;a href="https://imhireready.com" rel="noopener noreferrer"&gt;HireReady&lt;/a&gt;&lt;/strong&gt; and wanted to share it with you.&lt;/p&gt;

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

&lt;p&gt;HireReady is a technical interview preparation platform that combines two things I think are underused in interview prep:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;AI-powered voice interviews&lt;/strong&gt; using OpenAI's Realtime API — so you can actually practice speaking your answers out loud, not just typing them&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spaced repetition&lt;/strong&gt; (FSRS-5 algorithm) — so the app automatically schedules reviews of questions you're weakest on&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  The problem
&lt;/h2&gt;

&lt;p&gt;I was frustrated with existing interview prep tools. Most of them are just question banks where you grind through problems with no structure. You forget what you studied last week, and you never practice actually &lt;em&gt;talking&lt;/em&gt; through your answers — which is what the real interview is.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;1,300+ questions&lt;/strong&gt; across coding, system design, and behavioral categories&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI voice interviews&lt;/strong&gt; — talk through problems like a real interview, get real-time feedback&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Adaptive difficulty&lt;/strong&gt; using Item Response Theory (IRT) parameters&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spaced repetition scheduling&lt;/strong&gt; via ts-fsrs so you review at optimal intervals&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;STAR method story bank&lt;/strong&gt; for behavioral questions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Gamification&lt;/strong&gt; — XP, streaks, leaderboards, and mastery badges to keep you consistent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Study plans&lt;/strong&gt; — AI-generated personalized plans based on your target role and timeline&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Tech stack
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Next.js 16 + React 19 (App Router)&lt;/li&gt;
&lt;li&gt;TypeScript, Tailwind CSS 4, shadcn/ui&lt;/li&gt;
&lt;li&gt;Supabase (Postgres + Auth + RLS)&lt;/li&gt;
&lt;li&gt;Stripe for subscriptions&lt;/li&gt;
&lt;li&gt;OpenAI Realtime API for voice&lt;/li&gt;
&lt;li&gt;ts-fsrs for spaced repetition&lt;/li&gt;
&lt;li&gt;Deployed on Vercel&lt;/li&gt;
&lt;/ul&gt;

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

&lt;p&gt;The free tier gives you access to practice questions with spaced repetition. Pro unlocks voice interviews, advanced analytics, and unlimited practice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Check it out at &lt;a href="https://imhireready.com" rel="noopener noreferrer"&gt;imhireready.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I'd love to hear your feedback — what features would be most useful for your interview prep? Drop a comment below!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>career</category>
      <category>react</category>
    </item>
    <item>
      <title>How I Built an AI Documentation Engine with Tree-sitter, Claude AI, and RAG</title>
      <dc:creator>Elizabeth Stein</dc:creator>
      <pubDate>Tue, 03 Mar 2026 15:27:45 +0000</pubDate>
      <link>https://dev.to/liztacular/how-i-built-an-ai-documentation-engine-with-tree-sitter-claude-ai-and-rag-4jgk</link>
      <guid>https://dev.to/liztacular/how-i-built-an-ai-documentation-engine-with-tree-sitter-claude-ai-and-rag-4jgk</guid>
      <description>&lt;p&gt;Documentation is every developer’s least favorite task.&lt;/p&gt;

&lt;p&gt;We all agree it’s important. We all intend to keep it updated. And yet… it’s usually the first thing to fall behind.&lt;/p&gt;

&lt;p&gt;After watching this happen on every team I’ve worked with, I built &lt;strong&gt;AutomaDocs&lt;/strong&gt; — an AI-powered documentation engine that connects to your GitHub repos and keeps docs in sync automatically.&lt;/p&gt;

&lt;p&gt;Here’s how the system works and what I learned building it.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Real Problem
&lt;/h2&gt;

&lt;p&gt;Every engineering team has had this conversation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;PM: “Are the docs updated?”&lt;/li&gt;
&lt;li&gt;Dev: “Uh… mostly.”&lt;/li&gt;
&lt;li&gt;PM: “The API endpoint changed last week.”&lt;/li&gt;
&lt;li&gt;Dev: “…I’ll update them tomorrow.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The issue isn’t laziness. It’s architecture.&lt;/p&gt;

&lt;p&gt;We treat documentation as a &lt;em&gt;separate artifact&lt;/em&gt; from the code — but the code changes constantly. Keeping two parallel systems in sync manually doesn’t scale.&lt;/p&gt;

&lt;p&gt;So I asked:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;What if documentation wasn’t written manually at all?&lt;br&gt;&lt;br&gt;
What if it was generated directly from structured code understanding?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That became AutomaDocs.&lt;/p&gt;




&lt;h1&gt;
  
  
  The Architecture
&lt;/h1&gt;

&lt;p&gt;AutomaDocs has three core layers:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Structured code analysis&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;LLM-powered documentation generation&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Continuous sync + retrieval (RAG)&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Let’s break it down.&lt;/p&gt;




&lt;h2&gt;
  
  
  1. Code Analysis with :contentReference[oaicite:0]{index=0}
&lt;/h2&gt;

&lt;p&gt;Most AI documentation tools just feed raw source code into an LLM.&lt;/p&gt;

&lt;p&gt;That works… but it’s noisy and unreliable.&lt;/p&gt;

&lt;p&gt;Instead, I parse repositories into an &lt;strong&gt;Abstract Syntax Tree (AST)&lt;/strong&gt; using Tree-sitter. This gives structured, language-aware understanding of the codebase:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Function signatures with parameters and return types
&lt;/li&gt;
&lt;li&gt;Class hierarchies
&lt;/li&gt;
&lt;li&gt;Import/export graphs
&lt;/li&gt;
&lt;li&gt;Docstring extraction
&lt;/li&gt;
&lt;li&gt;Type information
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Instead of seeing “text,” the AI sees structured architecture.&lt;/p&gt;

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

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;function_declaration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;createUser&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;parameters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;email&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;role&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;UserRole&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="nx"&gt;returnType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Promise&amp;lt;User&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;docstring&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Creates a new user account&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That structure dramatically improves documentation quality compared to raw code prompts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key insight:&lt;/strong&gt;&lt;br&gt;&lt;br&gt;
LLMs perform significantly better when you reduce ambiguity before prompting them.&lt;/p&gt;




&lt;h2&gt;
  
  
  2. AI Generation with :contentReference[oaicite:1]{index=1}
&lt;/h2&gt;

&lt;p&gt;Once we have structured AST data, we feed it into Claude with carefully designed prompts.&lt;/p&gt;

&lt;p&gt;The system generates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;API endpoint documentation
&lt;/li&gt;
&lt;li&gt;Method/function descriptions
&lt;/li&gt;
&lt;li&gt;Parameter breakdowns with types
&lt;/li&gt;
&lt;li&gt;Usage examples
&lt;/li&gt;
&lt;li&gt;High-level architecture summaries
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Because the input is structured, the output is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;More consistent
&lt;/li&gt;
&lt;li&gt;Less hallucinated
&lt;/li&gt;
&lt;li&gt;Easier to regenerate deterministically
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This separation — &lt;em&gt;parser for understanding, LLM for explanation&lt;/em&gt; — keeps responsibilities clean.&lt;/p&gt;




&lt;h2&gt;
  
  
  3. Auto-Sync with :contentReference[oaicite:2]{index=2} Webhooks + RAG
&lt;/h2&gt;

&lt;p&gt;Documentation should never be stale.&lt;/p&gt;

&lt;p&gt;Here’s what happens when you push code:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;GitHub webhook fires
&lt;/li&gt;
&lt;li&gt;We detect changed files
&lt;/li&gt;
&lt;li&gt;Tree-sitter re-parses only affected nodes
&lt;/li&gt;
&lt;li&gt;Claude regenerates relevant documentation
&lt;/li&gt;
&lt;li&gt;Embeddings update in :contentReference[oaicite:3]{index=3}
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Your docs are never more than one push behind your code.&lt;/p&gt;

&lt;p&gt;No manual updates required.&lt;/p&gt;




&lt;h1&gt;
  
  
  The RAG Chat System
&lt;/h1&gt;

&lt;p&gt;We also built an AI chat interface over your documentation.&lt;/p&gt;

&lt;p&gt;Instead of basic vector search, we implemented &lt;strong&gt;hybrid retrieval&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;BM25&lt;/strong&gt; → precise keyword matching (function names, error codes)
&lt;/li&gt;
&lt;li&gt;Pinecone → semantic search (conceptual questions)
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reciprocal Rank Fusion (RRF)&lt;/strong&gt; → combines both ranking systems
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That means users can ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“How does authentication work?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Even if the word &lt;em&gt;authentication&lt;/em&gt; doesn’t appear directly in code, the system still finds relevant logic, middleware, or config.&lt;/p&gt;

&lt;p&gt;Hybrid search dramatically improves answer quality compared to pure embeddings.&lt;/p&gt;




&lt;h1&gt;
  
  
  Tech Stack
&lt;/h1&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Component&lt;/th&gt;
&lt;th&gt;Technology&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Frontend&lt;/td&gt;
&lt;td&gt;Next.js 16 (App Router)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Backend&lt;/td&gt;
&lt;td&gt;Express (ES Modules)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Database&lt;/td&gt;
&lt;td&gt;PostgreSQL&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Vector DB&lt;/td&gt;
&lt;td&gt;Pinecone&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;AI&lt;/td&gt;
&lt;td&gt;Claude (Anthropic)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Parser&lt;/td&gt;
&lt;td&gt;Tree-sitter&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Queue&lt;/td&gt;
&lt;td&gt;BullMQ + Redis&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hosting&lt;/td&gt;
&lt;td&gt;Vercel + Railway&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;The biggest architectural decision was separating:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Parsing layer&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Generation layer&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Retrieval layer&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keeping those decoupled made iteration much faster.&lt;/p&gt;




&lt;h1&gt;
  
  
  What I’d Do Differently
&lt;/h1&gt;

&lt;h3&gt;
  
  
  1. Start with fewer languages
&lt;/h3&gt;

&lt;p&gt;Supporting 15+ languages from day one was overly ambitious.&lt;/p&gt;

&lt;p&gt;If I rebuilt it today, I’d focus on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;JavaScript / TypeScript
&lt;/li&gt;
&lt;li&gt;Python
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Nail those first. Expand later.&lt;/p&gt;




&lt;h3&gt;
  
  
  2. Build “Documentation Health Scores” earlier
&lt;/h3&gt;

&lt;p&gt;We added a documentation health scoring system later — and surprisingly, it became one of the most loved features.&lt;/p&gt;

&lt;p&gt;Gamification works.&lt;/p&gt;

&lt;p&gt;Teams are far more likely to maintain docs when they can see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Coverage %&lt;/li&gt;
&lt;li&gt;Outdated endpoints&lt;/li&gt;
&lt;li&gt;Missing descriptions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If I were starting again, this would be v1.&lt;/p&gt;




&lt;h3&gt;
  
  
  3. Use WebSockets instead of polling
&lt;/h3&gt;

&lt;p&gt;We currently poll for generation status updates.&lt;/p&gt;

&lt;p&gt;WebSockets would make the system cleaner and more real-time.&lt;/p&gt;

&lt;p&gt;Classic v1 tradeoff: ship now, refine later.&lt;/p&gt;




&lt;h1&gt;
  
  
  Lessons from Building AI Dev Tools
&lt;/h1&gt;

&lt;p&gt;A few high-level takeaways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Structured input &amp;gt; clever prompts&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Retrieval quality matters more than model size&lt;/li&gt;
&lt;li&gt;Dev tools succeed when they reduce friction, not add AI novelty&lt;/li&gt;
&lt;li&gt;Automation only works if it’s invisible&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI is powerful — but only when wrapped in good architecture.&lt;/p&gt;




&lt;h1&gt;
  
  
  Try It
&lt;/h1&gt;

&lt;p&gt;AutomaDocs is live with a free tier:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;3 repositories&lt;/li&gt;
&lt;li&gt;20 AI generations/month&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;👉 &lt;strong&gt;&lt;a href="https://automadocs.com" rel="noopener noreferrer"&gt;https://automadocs.com&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I’d genuinely love feedback from the dev.to community:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What’s your biggest documentation pain point right now?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>documentation</category>
      <category>javascript</category>
    </item>
    <item>
      <title>[Boost]</title>
      <dc:creator>Elizabeth Stein</dc:creator>
      <pubDate>Sat, 14 Feb 2026 21:59:09 +0000</pubDate>
      <link>https://dev.to/liztacular/-17cn</link>
      <guid>https://dev.to/liztacular/-17cn</guid>
      <description>&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag__link--embedded"&gt;
  &lt;div class="crayons-story "&gt;
  &lt;a href="https://dev.to/liztacular/i-built-the-first-a11y-cli-that-auto-fixes-code-while-you-type-teaches-copilot-your-patterns-49il" class="crayons-story__hidden-navigation-link"&gt;I Built the First A11y CLI That Auto-Fixes Code While You Type (+ Teaches Copilot Your Patterns)&lt;/a&gt;


  &lt;div class="crayons-story__body crayons-story__body-full_post"&gt;
    &lt;div class="crayons-story__top"&gt;
      &lt;div class="crayons-story__meta"&gt;
        &lt;div class="crayons-story__author-pic"&gt;

          &lt;a href="/liztacular" class="crayons-avatar  crayons-avatar--l  "&gt;
            &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2358502%2F871ac71e-e018-4710-87c1-3770be7a0087.JPG" alt="liztacular profile" class="crayons-avatar__image"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
        &lt;div&gt;
          &lt;div&gt;
            &lt;a href="/liztacular" class="crayons-story__secondary fw-medium m:hidden"&gt;
              Elizabeth Stein
            &lt;/a&gt;
            &lt;div class="profile-preview-card relative mb-4 s:mb-0 fw-medium hidden m:inline-block"&gt;
              
                Elizabeth Stein
                &lt;a href="/++"&gt;&lt;img alt="Subscriber" class="subscription-icon" src="https://assets.dev.to/assets/subscription-icon-805dfa7ac7dd660f07ed8d654877270825b07a92a03841aa99a1093bd00431b2.png"&gt;&lt;/a&gt;
              
              &lt;div id="story-author-preview-content-3256627" class="profile-preview-card__content crayons-dropdown branded-7 p-4 pt-0"&gt;
                &lt;div class="gap-4 grid"&gt;
                  &lt;div class="-mt-4"&gt;
                    &lt;a href="/liztacular" class="flex"&gt;
                      &lt;span class="crayons-avatar crayons-avatar--xl mr-2 shrink-0"&gt;
                        &lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2358502%2F871ac71e-e018-4710-87c1-3770be7a0087.JPG" class="crayons-avatar__image" alt=""&gt;
                      &lt;/span&gt;
                      &lt;span class="crayons-link crayons-subtitle-2 mt-5"&gt;Elizabeth Stein&lt;/span&gt;
                    &lt;/a&gt;
                  &lt;/div&gt;
                  &lt;div class="print-hidden"&gt;
                    
                      Follow
                    
                  &lt;/div&gt;
                  &lt;div class="author-preview-metadata-container"&gt;&lt;/div&gt;
                &lt;/div&gt;
              &lt;/div&gt;
            &lt;/div&gt;

          &lt;/div&gt;
          &lt;a href="https://dev.to/liztacular/i-built-the-first-a11y-cli-that-auto-fixes-code-while-you-type-teaches-copilot-your-patterns-49il" class="crayons-story__tertiary fs-xs"&gt;&lt;time&gt;Feb 14&lt;/time&gt;&lt;span class="time-ago-indicator-initial-placeholder"&gt;&lt;/span&gt;&lt;/a&gt;
        &lt;/div&gt;
      &lt;/div&gt;

    &lt;/div&gt;

    &lt;div class="crayons-story__indention"&gt;
      &lt;h2 class="crayons-story__title crayons-story__title-full_post"&gt;
        &lt;a href="https://dev.to/liztacular/i-built-the-first-a11y-cli-that-auto-fixes-code-while-you-type-teaches-copilot-your-patterns-49il" id="article-link-3256627"&gt;
          I Built the First A11y CLI That Auto-Fixes Code While You Type (+ Teaches Copilot Your Patterns)
        &lt;/a&gt;
      &lt;/h2&gt;
        &lt;div class="crayons-story__tags"&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/githubcopilotclichallenge"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;githubcopilotclichallenge&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/a11y"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;a11y&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/mcp"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;mcp&lt;/a&gt;
            &lt;a class="crayons-tag  crayons-tag--monochrome " href="/t/typescript"&gt;&lt;span class="crayons-tag__prefix"&gt;#&lt;/span&gt;typescript&lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="crayons-story__bottom"&gt;
        &lt;div class="crayons-story__details"&gt;
          &lt;a href="https://dev.to/liztacular/i-built-the-first-a11y-cli-that-auto-fixes-code-while-you-type-teaches-copilot-your-patterns-49il" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left"&gt;
            &lt;div class="multiple_reactions_aggregate"&gt;
              &lt;span class="multiple_reactions_icons_container"&gt;
                  &lt;span class="crayons_icon_container"&gt;
                    &lt;img src="https://assets.dev.to/assets/sparkle-heart-5f9bee3767e18deb1bb725290cb151c25234768a0e9a2bd39370c382d02920cf.svg" width="18" height="18"&gt;
                  &lt;/span&gt;
              &lt;/span&gt;
              &lt;span class="aggregate_reactions_counter"&gt;1&lt;span class="hidden s:inline"&gt;&amp;nbsp;reaction&lt;/span&gt;&lt;/span&gt;
            &lt;/div&gt;
          &lt;/a&gt;
            &lt;a href="https://dev.to/liztacular/i-built-the-first-a11y-cli-that-auto-fixes-code-while-you-type-teaches-copilot-your-patterns-49il#comments" class="crayons-btn crayons-btn--s crayons-btn--ghost crayons-btn--icon-left flex items-center"&gt;
              

              &lt;span class="hidden s:inline"&gt;Add&amp;nbsp;Comment&lt;/span&gt;
            &lt;/a&gt;
        &lt;/div&gt;
        &lt;div class="crayons-story__save"&gt;
          &lt;small class="crayons-story__tertiary fs-xs mr-2"&gt;
            6 min read
          &lt;/small&gt;
            
              &lt;span class="bm-initial"&gt;
                

              &lt;/span&gt;
              &lt;span class="bm-success"&gt;
                

              &lt;/span&gt;
            
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;

&lt;/div&gt;




</description>
      <category>githubcopilotclichallenge</category>
      <category>a11y</category>
      <category>mcp</category>
      <category>typescript</category>
    </item>
    <item>
      <title>I Built the First A11y CLI That Auto-Fixes Code While You Type (+ Teaches Copilot Your Patterns)</title>
      <dc:creator>Elizabeth Stein</dc:creator>
      <pubDate>Sat, 14 Feb 2026 17:10:20 +0000</pubDate>
      <link>https://dev.to/liztacular/i-built-the-first-a11y-cli-that-auto-fixes-code-while-you-type-teaches-copilot-your-patterns-49il</link>
      <guid>https://dev.to/liztacular/i-built-the-first-a11y-cli-that-auto-fixes-code-while-you-type-teaches-copilot-your-patterns-49il</guid>
      <description>&lt;h2&gt;
  
  
  🎬 Watch It In Action First
&lt;/h2&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/r2LgYIoVrU4"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem Nobody's Solved
&lt;/h2&gt;

&lt;p&gt;Every accessibility tool tells you what's broken. &lt;strong&gt;None of them fix it automatically while you code.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;When you scan your codebase with axe-cli, pa11y, or Lighthouse, you get a list of violations. Then you context-switch to fix them. By next week, new violations creep in. The backlog grows. Teams feel overwhelmed.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;95.9% of websites still fail basic WCAG standards&lt;/strong&gt; (WebAIM Million). That's 1 billion users who can't fully use the web.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Makes ally Different
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;ally&lt;/strong&gt; - an accessibility CLI with &lt;strong&gt;two industry-first features&lt;/strong&gt; that no competitor has:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Real-Time Auto-Fix on Save
&lt;/h3&gt;

&lt;p&gt;Watches your files and auto-applies WCAG fixes as you save — zero manual intervention.&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;ally watch src/ &lt;span class="nt"&gt;--fix-on-save&lt;/span&gt;

✓ Auto-fix: ON &lt;span class="o"&gt;(&lt;/span&gt;confidence ≥ 90%&lt;span class="o"&gt;)&lt;/span&gt;
📄 Button.tsx changed
   ✓ Auto-applied 2 fixes
   • &amp;lt;button&amp;gt; → &amp;lt;button aria-label&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Submit"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
   • &amp;lt;img&amp;gt; → &amp;lt;img &lt;span class="nv"&gt;alt&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"Logo"&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;

Score: 62 → 100 ✨
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Why this matters:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;🔥 Instant fixes — No "fix later" backlog&lt;/li&gt;
&lt;li&gt;🎯 High confidence — Only applies fixes ≥90% certainty&lt;/li&gt;
&lt;li&gt;⚡ Zero friction — Edit files normally, ally handles the rest&lt;/li&gt;
&lt;li&gt;🤖 Pattern learning — Learns from your fix history&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;No other accessibility tool has this.&lt;/strong&gt; Not axe-cli. Not pa11y. Not Lighthouse.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Impact Scoring (0-100)
&lt;/h3&gt;

&lt;p&gt;Shows which violations &lt;strong&gt;actually hurt users&lt;/strong&gt; — eliminates developer overwhelm.&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;ally scan ./src

&lt;span class="o"&gt;[!!!]&lt;/span&gt; CRITICAL Impact: 98/100 &lt;span class="o"&gt;(&lt;/span&gt;WCAG A&lt;span class="o"&gt;)&lt;/span&gt;
    Buttons must have discernible text
    💡 Users cannot activate buttons, blocking core actions
    👥 Affects: Screen reader &lt;span class="nb"&gt;users&lt;/span&gt;, Voice control &lt;span class="nb"&gt;users&lt;/span&gt;
    📊 Estimated: 15-20% of &lt;span class="nb"&gt;users&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of treating all violations equally, ally scores each 0-100 based on:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WCAG level (A &amp;gt; AA &amp;gt; AAA for priority)&lt;/li&gt;
&lt;li&gt;User groups affected (screen readers, keyboard-only, low vision)&lt;/li&gt;
&lt;li&gt;% of users impacted&lt;/li&gt;
&lt;li&gt;Business context (checkout pages score higher for form issues)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Fix the highest-score issues first.&lt;/strong&gt; Stop guessing.&lt;/p&gt;

&lt;h2&gt;
  
  
  The GitHub Copilot CLI Integration That Changes Everything
&lt;/h2&gt;

&lt;p&gt;Here's where it gets interesting for this challenge.&lt;/p&gt;

&lt;p&gt;Most submissions will say "I used Copilot to write my code."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;ally goes further:&lt;/strong&gt; I built a &lt;strong&gt;custom MCP (Model Context Protocol) server&lt;/strong&gt; (2,094 lines) that &lt;strong&gt;teaches GitHub Copilot about YOUR accessibility patterns&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  How It Works
&lt;/h3&gt;

&lt;p&gt;When you install ally and run &lt;code&gt;ally init&lt;/code&gt;, it creates &lt;code&gt;.copilot/mcp-config.json&lt;/code&gt;:&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;"mcpServers"&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;"ally-patterns"&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;"type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"local"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"command"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"node"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"args"&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="s2"&gt;"./node_modules/ally-a11y/mcp-server/dist/index.js"&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="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;Now when you ask Copilot to fix accessibility issues, it gets context from &lt;strong&gt;7 MCP tools&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;get_component_patterns&lt;/code&gt;&lt;/strong&gt; - Your existing ARIA patterns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;get_design_tokens&lt;/code&gt;&lt;/strong&gt; - WCAG-compliant colors from your codebase&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;get_fix_history&lt;/code&gt;&lt;/strong&gt; - Previously applied fixes for consistency&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;get_scan_summary&lt;/code&gt;&lt;/strong&gt; - Current accessibility violations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;get_wcag_guideline&lt;/code&gt;&lt;/strong&gt; - Full WCAG criterion details&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;suggest_aria_pattern&lt;/code&gt;&lt;/strong&gt; - ARIA patterns for component types&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;check_color_contrast&lt;/code&gt;&lt;/strong&gt; - Calculate WCAG contrast ratios&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  The Feedback Loop
&lt;/h3&gt;

&lt;p&gt;This creates a powerful workflow:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. ally scans and finds issues&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;ally scan Button.tsx
&lt;span class="o"&gt;[!!!]&lt;/span&gt; CRITICAL: Button missing aria-label

&lt;span class="c"&gt;# 2. Use Copilot with ally's context&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;gh copilot suggest &lt;span class="s2"&gt;"fix the button accessibility"&lt;/span&gt;

&lt;span class="c"&gt;# Behind the scenes, Copilot calls your MCP server:&lt;/span&gt;
&lt;span class="c"&gt;# - get_component_patterns → sees you use aria-label consistently&lt;/span&gt;
&lt;span class="c"&gt;# - get_design_tokens → knows your color palette&lt;/span&gt;
&lt;span class="c"&gt;# - get_fix_history → sees 47 previous aria-label fixes&lt;/span&gt;
&lt;span class="c"&gt;# - get_scan_summary → knows this specific violation&lt;/span&gt;

&lt;span class="c"&gt;# Result: Copilot suggests code that matches YOUR patterns&lt;/span&gt;
&lt;span class="c"&gt;# &amp;lt;button aria-label="Submit form"&amp;gt;&lt;/span&gt;

&lt;span class="c"&gt;# 3. Apply fix and rescan&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;ally scan Button.tsx
✓ No violations found &lt;span class="o"&gt;(&lt;/span&gt;score: 100&lt;span class="o"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# 4. Fix becomes part of your history&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;ally &lt;span class="nb"&gt;history&lt;/span&gt;
✓ Button.tsx: 62 → 100 &lt;span class="o"&gt;(&lt;/span&gt;+38&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;This is what Copilot CLI integration should look like:&lt;/strong&gt; Not just using Copilot to build a tool, but &lt;strong&gt;making Copilot smarter&lt;/strong&gt; at its job.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned Building With Copilot CLI
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. MCP Servers Are Incredibly Powerful
&lt;/h3&gt;

&lt;p&gt;Building the MCP server taught me that Copilot CLI isn't just a code generator — it's an &lt;strong&gt;extensible platform&lt;/strong&gt;. By giving Copilot access to project-specific context, you can transform it from "generic Stack Overflow suggestions" to "expert on your codebase."&lt;/p&gt;

&lt;p&gt;The telemetry proves it works:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;[MCP Telemetry] get_component_patterns called (47x total)
[MCP Telemetry] get_design_tokens called (23x total)
[MCP Telemetry] get_fix_history called (156x total)
[MCP Telemetry] suggest_aria_pattern called (89x total)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Real developers are using it. Copilot is getting smarter about accessibility because of ally's MCP server.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Context Is Everything for AI Code Generation
&lt;/h3&gt;

&lt;p&gt;Generic Copilot suggestions are often wrong for accessibility because every project uses different ARIA patterns, design systems, and conventions.&lt;/p&gt;

&lt;p&gt;The MCP server solves this by teaching Copilot &lt;strong&gt;your patterns&lt;/strong&gt;, not generic ones.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Developer Experience &amp;gt; Features
&lt;/h3&gt;

&lt;p&gt;ally has 19 commands, but the two that matter most solve &lt;strong&gt;emotional problems&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;ally watch --fix-on-save&lt;/code&gt; (removes friction)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;ally scan&lt;/code&gt; with impact scores (eliminates overwhelm)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Copilot CLI taught me this during development — the best features &lt;strong&gt;remove blockers&lt;/strong&gt;, not add capabilities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why This Matters (The $200B Problem)
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;The Business Case:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;95.9% of websites fail WCAG (WebAIM Million)&lt;/li&gt;
&lt;li&gt;1 billion users have disabilities&lt;/li&gt;
&lt;li&gt;ADA lawsuits increased 400% (2017-2023)&lt;/li&gt;
&lt;li&gt;WCAG compliance is legally required (US, EU, Canada)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What ally Solves:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Eliminates overwhelm via impact scoring&lt;/li&gt;
&lt;li&gt;Zero-friction fixes via auto-fix on save&lt;/li&gt;
&lt;li&gt;Pattern consistency via MCP server&lt;/li&gt;
&lt;li&gt;Compliance documentation via reports&lt;/li&gt;
&lt;li&gt;Team education via &lt;code&gt;ally learn&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Complete Toolkit (19 Commands)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Scanning &amp;amp; Real-Time&lt;/span&gt;
ally scan ./src              &lt;span class="c"&gt;# Impact scoring&lt;/span&gt;
ally watch &lt;span class="nt"&gt;--fix-on-save&lt;/span&gt;     &lt;span class="c"&gt;# Auto-fix as you code&lt;/span&gt;
ally crawl &amp;lt;url&amp;gt;             &lt;span class="c"&gt;# Multi-page scanning&lt;/span&gt;
ally scan-storybook          &lt;span class="c"&gt;# Storybook integration&lt;/span&gt;

&lt;span class="c"&gt;# Fixing &amp;amp; Triage  &lt;/span&gt;
ally fix                     &lt;span class="c"&gt;# Interactive fixes&lt;/span&gt;
ally triage                  &lt;span class="c"&gt;# Prioritize violations&lt;/span&gt;
ally explain                 &lt;span class="c"&gt;# WCAG + Copilot tips&lt;/span&gt;
ally learn &amp;lt;topic&amp;gt;           &lt;span class="c"&gt;# WCAG education&lt;/span&gt;

&lt;span class="c"&gt;# Reporting &amp;amp; Progress&lt;/span&gt;
ally report                  &lt;span class="c"&gt;# MD/HTML/JSON/SARIF/CSV&lt;/span&gt;
ally &lt;span class="nb"&gt;history&lt;/span&gt;                 &lt;span class="c"&gt;# Progress trends&lt;/span&gt;
ally stats                   &lt;span class="c"&gt;# Dashboard&lt;/span&gt;
ally pr-check                &lt;span class="c"&gt;# GitHub PR comments&lt;/span&gt;

&lt;span class="c"&gt;# Plus: tree, badge, audit-palette, init, doctor, health, completion&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Try It Yourself (3 Commands)
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# 1. Install&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; ally-a11y

&lt;span class="c"&gt;# 2. Initialize (creates MCP config)&lt;/span&gt;
ally init

&lt;span class="c"&gt;# 3. Start auto-fixing&lt;/span&gt;
ally watch src/ &lt;span class="nt"&gt;--fix-on-save&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;With GitHub Copilot CLI:&lt;/strong&gt;&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;gh copilot suggest &lt;span class="s2"&gt;"fix accessibility in Button.tsx"&lt;/span&gt;
&lt;span class="c"&gt;# Copilot now uses ally's MCP server for project-specific context&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why This Should Win
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Genuinely Novel Features&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Real-time auto-fix (no competitor has this)&lt;/li&gt;
&lt;li&gt;Impact scoring 0-100 (industry-first)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2. Deep Copilot Integration&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Not just "built with" but "makes Copilot smarter"&lt;/li&gt;
&lt;li&gt;2,094-line MCP server with 7 tools&lt;/li&gt;
&lt;li&gt;Production telemetry proving real usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;3. Production-Ready&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Published to npm&lt;/li&gt;
&lt;li&gt;16,505 lines TypeScript&lt;/li&gt;
&lt;li&gt;122+ tests&lt;/li&gt;
&lt;li&gt;GitHub Action + SARIF output&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;4. Real Impact&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;$200B accessibility market&lt;/li&gt;
&lt;li&gt;1 billion users affected&lt;/li&gt;
&lt;li&gt;Solves #1 developer pain point&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Technical Highlights
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;MCP Server (2,094 lines):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;7 tools with telemetry&lt;/li&gt;
&lt;li&gt;Pattern/token caching&lt;/li&gt;
&lt;li&gt;Error handling&lt;/li&gt;
&lt;li&gt;TypeScript safety&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Impact Scoring:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;WCAG level weighting&lt;/li&gt;
&lt;li&gt;User group analysis&lt;/li&gt;
&lt;li&gt;Business context&lt;/li&gt;
&lt;li&gt;0-100 scale&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Auto-Fix:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;35+ patterns&lt;/li&gt;
&lt;li&gt;Confidence threshold (≥90%)&lt;/li&gt;
&lt;li&gt;Fix history tracking&lt;/li&gt;
&lt;li&gt;Dry-run mode&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/forbiddenlink/ally" rel="noopener noreferrer"&gt;github.com/forbiddenlink/ally&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm:&lt;/strong&gt; &lt;a href="https://www.npmjs.com/package/ally-a11y" rel="noopener noreferrer"&gt;npmjs.com/package/ally-a11y&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Demo Video:&lt;/strong&gt; &lt;a href="https://youtu.be/r2LgYIoVrU4" rel="noopener noreferrer"&gt;youtu.be/r2LgYIoVrU4&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Built for the &lt;a href="https://dev.to/challenges/github-2026-01-21"&gt;GitHub Copilot CLI Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Making the web accessible, one auto-fix at a time.&lt;/em&gt; ♿✨&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Learned Building With Copilot CLI
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why accessibility matters:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;95.9% of top 1 million websites have WCAG failures&lt;/li&gt;
&lt;li&gt;1 billion people worldwide have disabilities&lt;/li&gt;
&lt;li&gt;ADA lawsuits increased 400% from 2017-2023&lt;/li&gt;
&lt;li&gt;WCAG compliance is legally required in many countries&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;What ally solves:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Eliminates overwhelm&lt;/strong&gt; - Impact scoring shows what to fix first&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Zero-friction fixes&lt;/strong&gt; - Auto-fix on save means no backlog accumulation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Pattern consistency&lt;/strong&gt; - MCP server ensures fixes match your codebase&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Compliance documentation&lt;/strong&gt; - Generate reports for audits&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Full Command Reference
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ally scan ./src              &lt;span class="c"&gt;# Scan with impact scoring&lt;/span&gt;
ally watch &lt;span class="nt"&gt;--fix-on-save&lt;/span&gt;     &lt;span class="c"&gt;# Auto-fix as you code&lt;/span&gt;
ally &lt;span class="nb"&gt;history&lt;/span&gt;                 &lt;span class="c"&gt;# View progress over time&lt;/span&gt;
ally fix                     &lt;span class="c"&gt;# Interactive fix approval&lt;/span&gt;
ally explain                 &lt;span class="c"&gt;# WCAG explanations&lt;/span&gt;
ally report                  &lt;span class="c"&gt;# Generate reports (MD/HTML/JSON/SARIF)&lt;/span&gt;
ally triage                  &lt;span class="c"&gt;# Prioritize violations interactively&lt;/span&gt;
ally crawl &amp;lt;url&amp;gt;             &lt;span class="c"&gt;# Multi-page website scanning&lt;/span&gt;
ally pr-check                &lt;span class="c"&gt;# Post results to GitHub PRs&lt;/span&gt;
ally badge                   &lt;span class="c"&gt;# Generate accessibility badges&lt;/span&gt;
ally learn &amp;lt;topic&amp;gt;           &lt;span class="c"&gt;# Educational WCAG explainer&lt;/span&gt;
ally tree &amp;lt;url&amp;gt;              &lt;span class="c"&gt;# View accessibility tree&lt;/span&gt;
ally doctor                  &lt;span class="c"&gt;# Diagnose setup issues&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Try It Yourself
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; ally-a11y

&lt;span class="c"&gt;# Initialize in your project&lt;/span&gt;
ally init

&lt;span class="c"&gt;# Scan your project&lt;/span&gt;
ally scan ./src

&lt;span class="c"&gt;# See what's wrong&lt;/span&gt;
ally explain

&lt;span class="c"&gt;# Fix with AI assistance&lt;/span&gt;
ally fix

&lt;span class="c"&gt;# Generate report&lt;/span&gt;
ally report
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Requirements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Node.js 18+&lt;/li&gt;
&lt;li&gt;GitHub Copilot CLI (optional, for AI-powered explain/fix)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;GitHub:&lt;/strong&gt; &lt;a href="https://github.com/forbiddenlink/ally" rel="noopener noreferrer"&gt;github.com/forbiddenlink/ally&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;npm:&lt;/strong&gt; &lt;a href="https://npmjs.com/package/ally-a11y" rel="noopener noreferrer"&gt;npmjs.com/package/ally-a11y&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;&lt;em&gt;Built for the &lt;a href="https://dev.to/challenges/github-2026-01-21"&gt;GitHub Copilot CLI Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>githubcopilotclichallenge</category>
      <category>a11y</category>
      <category>mcp</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Specter: Give Your Codebase a Voice</title>
      <dc:creator>Elizabeth Stein</dc:creator>
      <pubDate>Sat, 14 Feb 2026 13:42:11 +0000</pubDate>
      <link>https://dev.to/liztacular/specter-give-your-codebase-a-voice-2pd0</link>
      <guid>https://dev.to/liztacular/specter-give-your-codebase-a-voice-2pd0</guid>
      <description>&lt;p&gt;This is a submission for the &lt;a href="https://dev.to/challenges/github-2026-01-21"&gt;GitHub Copilot CLI Challenge&lt;/a&gt;&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Specter&lt;/strong&gt; is a code analysis CLI that speaks &lt;em&gt;as&lt;/em&gt; your codebase in first person. It builds a knowledge graph from your source code and git history, then uses that graph to power 66 commands across analysis, fun/shareable, daily workflow, and AI-powered categories.&lt;/p&gt;

&lt;p&gt;The twist: Specter has personality. Your codebase literally talks about itself.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"I'm feeling pretty good about myself. My complexity hotspots are
 under control, though src/legacy/parser.ts keeps me up at night..."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Why I Built It
&lt;/h3&gt;

&lt;p&gt;Developer tools are powerful but dry. Nobody shares a SonarQube report on Twitter. I wanted to build something that gives developers the insights they need (health scores, complexity hotspots, DORA metrics) while also being genuinely fun to use and share.&lt;/p&gt;

&lt;p&gt;The result: a tool where &lt;code&gt;specter roast&lt;/code&gt; tears your code apart with animated glitch effects, &lt;code&gt;specter tinder&lt;/code&gt; creates a dating profile for your codebase, and &lt;code&gt;specter anthem&lt;/code&gt; generates a theme song in 8 genres based on your actual metrics.&lt;/p&gt;
&lt;h3&gt;
  
  
  Key Features
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Serious Analysis (that actually helps)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;specter health&lt;/code&gt; — Health report with complexity distribution and animated score reveal&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter hotspots&lt;/code&gt; — Complexity x churn scatter plot with quadrant analysis&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter dora&lt;/code&gt; — DORA metrics for delivery performance&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter bus-factor&lt;/code&gt; — Knowledge concentration risks&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter coupling&lt;/code&gt; — Hidden couplings between files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter cycles&lt;/code&gt; — Circular dependency detection&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter cost&lt;/code&gt; — Tech debt estimated in dollars&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Fun &amp;amp; Shareable (that make people install it)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;specter roast&lt;/code&gt; — Comedic codebase roast with animated glitch intro&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter tinder&lt;/code&gt; — Dating profile for your code with green/red flags&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter wrapped&lt;/code&gt; — Spotify Wrapped-style year in review&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter anthem&lt;/code&gt; — Stats-driven theme song (8 genres)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter fame&lt;/code&gt; — Compare your codebase to famous open-source projects&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter horoscope&lt;/code&gt; — Daily code horoscope based on commit patterns&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter obituary &amp;lt;file&amp;gt;&lt;/code&gt; — Memorial for a file about to be deleted&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter seance&lt;/code&gt; — Summon spirits of deleted code from git history&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Daily Workflow&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;specter morning&lt;/code&gt; — Daily standup briefing&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter precommit&lt;/code&gt; — Risk check before committing&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter predict&lt;/code&gt; — PR impact prediction&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter fix&lt;/code&gt; — Actionable fix suggestions with interactive mode&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;specter tour&lt;/code&gt; — Guided walkthrough for new developers&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;12 Personality Modes&lt;/strong&gt; — Add &lt;code&gt;--personality &amp;lt;mode&amp;gt;&lt;/code&gt; to any command: default, mentor, critic, historian, cheerleader, minimalist, noir, therapist, roast, dramatic, ghost, and more.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;CI/CD Ready&lt;/strong&gt; — Every analysis command supports &lt;code&gt;--json&lt;/code&gt; for machine-readable output and &lt;code&gt;--exit-code&lt;/code&gt; for quality gates.&lt;/p&gt;
&lt;h3&gt;
  
  
  MCP Server: 14 Tools for GitHub Copilot CLI
&lt;/h3&gt;

&lt;p&gt;Specter's MCP integration is the core of this submission. One command adds it to Copilot CLI:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;copilot mcp add specter &lt;span class="nt"&gt;--&lt;/span&gt; npx @purplegumdropz/specter-mcp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then use natural language:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;copilot &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"Use specter to find complexity hotspots in my codebase"&lt;/span&gt;
copilot &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"Use specter to show team expertise for src/api/"&lt;/span&gt;
copilot &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"Use specter to analyze the impact of changing config.ts"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;14 MCP tools:&lt;/strong&gt; file relationships, complexity hotspots, codebase summary, dead code detection, symbol search, call chains, architecture diagrams, change coupling, impact analysis, bus factor, code archaeology, health trends, risk scoring, and knowledge map.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6 MCP prompt templates:&lt;/strong&gt; &lt;code&gt;specter:introduce&lt;/code&gt;, &lt;code&gt;specter:review&lt;/code&gt;, &lt;code&gt;specter:onboard&lt;/code&gt;, &lt;code&gt;specter:refactor-plan&lt;/code&gt;, &lt;code&gt;specter:standup-summary&lt;/code&gt;, &lt;code&gt;specter:health-check&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4 MCP resources:&lt;/strong&gt; &lt;code&gt;specter://summary&lt;/code&gt;, &lt;code&gt;specter://health&lt;/code&gt;, &lt;code&gt;specter://hotspots&lt;/code&gt;, &lt;code&gt;specter://architecture&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This means Copilot CLI can understand your entire codebase through Specter's knowledge graph — not just the files you have open, but the relationships between them, the complexity patterns, the team expertise distribution, and the historical evolution.&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;
&lt;h3&gt;
  
  
  Install &amp;amp; Try
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Install globally&lt;/span&gt;
npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-g&lt;/span&gt; @purplegumdropz/specter

&lt;span class="c"&gt;# Or try without installing&lt;/span&gt;
npx @purplegumdropz/specter-roast
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Quick Demo (30 seconds)
&lt;/h3&gt;

&lt;p&gt;Watch Specter scan, diagnose, and roast a codebase in 30 seconds.&lt;/p&gt;

&lt;p&gt;

  &lt;iframe src="https://www.youtube.com/embed/ZumEIb6uA-0"&gt;
  &lt;/iframe&gt;


&lt;/p&gt;
&lt;h3&gt;
  
  
  Repository
&lt;/h3&gt;

&lt;p&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/forbiddenlink" rel="noopener noreferrer"&gt;
        forbiddenlink
      &lt;/a&gt; / &lt;a href="https://github.com/forbiddenlink/specter" rel="noopener noreferrer"&gt;
        specter
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Ghost-themed interactive web experience with atmospheric effects and immersive storytelling
    &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;👻 Specter&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;
  &lt;a href="https://www.npmjs.com/package/@purplegumdropz/specter" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/24cea9417b45c671e26284b1fdc471ab885c484f535f2fc88e14a506b78c4420/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f762f40707572706c6567756d64726f707a2f737065637465722e737667" alt="npm version"&gt;&lt;/a&gt;
  &lt;a href="https://github.com/forbiddenlink/specter/actions" rel="noopener noreferrer"&gt;&lt;img src="https://github.com/forbiddenlink/specter/workflows/CI/badge.svg" alt="Build Status"&gt;&lt;/a&gt;
  &lt;a href="https://github.com/forbiddenlink/specter/blob/main/LICENSE" rel="noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/369fbc42307edf603a92ad6f48025d969c1776d27da57c8bd72dbb4a9efe67cf/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f6c2f40707572706c6567756d64726f707a2f737065637465722e737667" alt="License"&gt;&lt;/a&gt;
  &lt;a href="https://www.npmjs.com/package/@purplegumdropz/specter" rel="nofollow noopener noreferrer"&gt;&lt;img src="https://camo.githubusercontent.com/5f526d2d103ddf1699567aba52929b7966948d79e5569f47e85f5cdbeeca0c58/68747470733a2f2f696d672e736869656c64732e696f2f6e706d2f646d2f40707572706c6567756d64726f707a2f73706563746572" alt="npm downloads"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;
  &lt;strong&gt;Give your codebase a voice.&lt;/strong&gt;&lt;br&gt;
  A code intelligence CLI that speaks &lt;em&gt;as&lt;/em&gt; your codebase in first person.&lt;br&gt;
  &lt;strong&gt;65 commands. 14 MCP tools. 12 personality modes. 1 ghost in your git history.&lt;/strong&gt;
&lt;/p&gt;




&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;What Makes Specter Different?&lt;/h2&gt;
&lt;/div&gt;

&lt;p&gt;Traditional analysis tools show metrics without meaning. Specter &lt;strong&gt;connects the dots&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;&lt;/p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;table&gt;

&lt;thead&gt;

&lt;tr&gt;

&lt;th&gt;The Problem&lt;/th&gt;

&lt;th&gt;Specter's Answer&lt;/th&gt;

&lt;/tr&gt;

&lt;/thead&gt;

&lt;tbody&gt;

&lt;tr&gt;

&lt;td&gt;"Cyclomatic complexity: 45"&lt;/td&gt;

&lt;td&gt;
&lt;br&gt;
&lt;strong&gt;Where&lt;/strong&gt; the hotspots are + &lt;strong&gt;why&lt;/strong&gt; they matter&lt;/td&gt;

&lt;/tr&gt;

&lt;tr&gt;

&lt;td&gt;"Tech debt exists"&lt;/td&gt;

&lt;td&gt;
&lt;br&gt;
&lt;strong&gt;$510k&lt;/strong&gt; annual maintenance burden (your hourly rate)&lt;/td&gt;

&lt;/tr&gt;

&lt;tr&gt;

&lt;td&gt;"Bus factor: 1"&lt;/td&gt;

&lt;td&gt;
&lt;br&gt;
&lt;strong&gt;Who&lt;/strong&gt; owns what + &lt;strong&gt;what breaks&lt;/strong&gt; if they leave&lt;/td&gt;

&lt;/tr&gt;

&lt;tr&gt;

&lt;td&gt;Numbers without context&lt;/td&gt;

&lt;td&gt;AI-powered explanations in 12 personality modes&lt;/td&gt;

&lt;/tr&gt;

&lt;/tbody&gt;

&lt;/table&gt;&lt;/div&gt;&lt;p&gt;&lt;/p&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Install and get started in 30 seconds&lt;/span&gt;
npm install -g @purplegumdropz/specter
specter scan &lt;span class="pl-k"&gt;&amp;amp;&amp;amp;&lt;/span&gt; specter health

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Or try without installing&lt;/span&gt;
npx @purplegumdropz/specter-roast&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://youtu.be/ZumEIb6uA-0" rel="nofollow noopener noreferrer"&gt;Watch 30-second demo →&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Real-World Examples&lt;/h2&gt;

&lt;/div&gt;

&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Find the code that's slowing your team down&lt;/h3&gt;

&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;specter hotspots              &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Complexity × Churn = Refactoring Priority&lt;/span&gt;
specter cost                  &lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Tech debt in dollars ($510k/year)&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/forbiddenlink/specter" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;





&lt;h3&gt;
  
  
  Screenshots
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fco7cjqvpxc7azwsat2xt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fco7cjqvpxc7azwsat2xt.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc0kj23rw3g38acj43hx9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc0kj23rw3g38acj43hx9.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F51ib525mxdcyml4jhgzk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F51ib525mxdcyml4jhgzk.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqqjwgbfgwguhax529dhf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqqjwgbfgwguhax529dhf.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnjb1wq1nxb6aoxh5zibk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnjb1wq1nxb6aoxh5zibk.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flaveke7wdo3zhx7rx36s.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flaveke7wdo3zhx7rx36s.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8up6w575j0486sdsznq8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8up6w575j0486sdsznq8.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  My Experience with GitHub Copilot CLI
&lt;/h2&gt;

&lt;p&gt;Building Specter's MCP integration was the most technically interesting part of this project. The MCP protocol gives Copilot CLI structured access to tools, and designing the right tool surface area was a real design challenge.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Worked Well
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Copilot CLI as a natural language interface to analysis tools.&lt;/strong&gt; Instead of remembering flag combinations like &lt;code&gt;specter hotspots --top 10 --sort churn --format table&lt;/code&gt;, users can just say "show me the files that change the most and are most complex." Copilot CLI maps that to the right MCP tool call with the right parameters. This is a genuinely better UX for exploratory analysis.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP prompt templates for common workflows.&lt;/strong&gt; The &lt;code&gt;specter:onboard&lt;/code&gt; template gives Copilot CLI a structured way to introduce new developers to a codebase. The &lt;code&gt;specter:review&lt;/code&gt; template combines file relationships, complexity data, and change coupling to give context-aware code review suggestions. These aren't just wrappers — they compose multiple tools in ways that would be tedious to do manually.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;MCP resources for ambient context.&lt;/strong&gt; Having &lt;code&gt;specter://summary&lt;/code&gt; and &lt;code&gt;specter://health&lt;/code&gt; available as resources means Copilot CLI can reference your codebase state without an explicit tool call. When you ask "should I refactor this?", it already knows your health score and hotspot distribution.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Design tools for AI, not just humans.&lt;/strong&gt; MCP tools need to return structured data that an LLM can reason about. I spent time making sure tool outputs include both raw numbers and contextual descriptions — so Copilot CLI can say "this file has a bus factor of 1, meaning only one person has ever touched it" rather than just returning &lt;code&gt;{"busFactor": 1}&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The personality system works surprisingly well with LLMs.&lt;/strong&gt; When Copilot CLI pipes Specter's personality-enhanced output into its responses, the result feels conversational rather than robotic. The ghost metaphor ("I am the ghost in your git history") gives the tool a memorable identity that makes the AI interaction feel more natural.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;TypeScript&lt;/strong&gt; with ts-morph for AST analysis&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Commander.js&lt;/strong&gt; for CLI framework&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MCP SDK&lt;/strong&gt; (&lt;code&gt;@modelcontextprotocol/sdk&lt;/code&gt;) for the MCP server&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;chalk&lt;/strong&gt;, &lt;strong&gt;gradient-string&lt;/strong&gt;, &lt;strong&gt;cfonts&lt;/strong&gt; for terminal UI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;vitest&lt;/strong&gt; for testing (313 tests across 13 files)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Biome&lt;/strong&gt; for linting and formatting&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Built by &lt;a href="https://github.com/elizabethsiegle" rel="noopener noreferrer"&gt;Liz Stein&lt;/a&gt; — &lt;em&gt;"I am the ghost in your git history."&lt;/em&gt;&lt;/p&gt;

</description>
      <category>githubcopilotcli</category>
      <category>devchallenge</category>
      <category>cli</category>
      <category>typescript</category>
    </item>
    <item>
      <title>TimeSlipSearch: A Conversational Time Machine for Pop Culture</title>
      <dc:creator>Elizabeth Stein</dc:creator>
      <pubDate>Mon, 09 Feb 2026 00:52:54 +0000</pubDate>
      <link>https://dev.to/liztacular/timeslipsearch-a-conversational-time-machine-for-pop-culture-51e7</link>
      <guid>https://dev.to/liztacular/timeslipsearch-a-conversational-time-machine-for-pop-culture-51e7</guid>
      <description>&lt;p&gt;This is my submission for the DEV Challenge: &lt;a href="https://dev.to/challenges/algolia"&gt;Consumer-Facing Conversational Experiences&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;TimeSlipSearch&lt;/strong&gt; is a conversational time machine that answers questions like:&lt;/p&gt;

&lt;p&gt;“What was the #1 song the day I was born?”&lt;/p&gt;

&lt;p&gt;…in under 100 milliseconds.&lt;/p&gt;

&lt;p&gt;Type a date in plain English, like “Summer of ’69,” “Christmas 1985,” or “the day the Berlin Wall fell,” and instantly receive a complete cultural snapshot:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Billboard Hot 100 chart results&lt;/li&gt;
&lt;li&gt;Movies in theaters&lt;/li&gt;
&lt;li&gt;Gas prices and other economic context&lt;/li&gt;
&lt;li&gt;Historical events from that exact moment in time&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Nostalgia is a $260B+ industry, yet exploring historical pop culture still requires jumping between Wikipedia, Billboard archives, IMDb, and economic databases.&lt;/p&gt;

&lt;p&gt;The data exists, it’s just scattered and hard to access conversationally.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;A single unified search across &lt;strong&gt;420,000+ indexed records&lt;/strong&gt;, wrapped in an immersive VHS/CRT retro interface that makes time travel feel real.&lt;/p&gt;

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

&lt;p&gt;🔗 Live: &lt;a href="https://timeslipsearch.vercel.app" rel="noopener noreferrer"&gt;https://timeslipsearch.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Try these queries:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;July 20, 1969 — Moon landing day&lt;/li&gt;
&lt;li&gt;Summer of ’69 — Natural language works&lt;/li&gt;
&lt;li&gt;Compare 1989 vs 1979 — Side-by-side decades&lt;/li&gt;
&lt;li&gt;Your birthday&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How I Used Algolia Agent Studio
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Indexed Data: 420K+ Records Across 4 Indices
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Index&lt;/th&gt;
&lt;th&gt;Records&lt;/th&gt;
&lt;th&gt;What It Contains&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;timeslip_songs&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;350,000&lt;/td&gt;
&lt;td&gt;Every Billboard Hot 100 entry, 1958–2020&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;timeslip_movies&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;50,000&lt;/td&gt;
&lt;td&gt;Theatrical releases from TMDB&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;timeslip_prices&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;900&lt;/td&gt;
&lt;td&gt;Gas, minimum wage, movie tickets (FRED)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;timeslip_events&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;20,000&lt;/td&gt;
&lt;td&gt;Historical events (Wikimedia)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Retrieval Strategy: Parallel Multi-Index Search
&lt;/h3&gt;

&lt;p&gt;Every user query triggers &lt;strong&gt;one HTTP request&lt;/strong&gt; that searches all four indices simultaneously:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;search&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;requests&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;indexName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timeslip_songs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="na"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`date &amp;gt;= &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; AND date &amp;lt;= &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;hitsPerPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;indexName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timeslip_movies&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`date &amp;gt;= &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; AND date &amp;lt;= &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;hitsPerPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;indexName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timeslip_prices&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`date &amp;gt;= &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; AND date &amp;lt;= &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;hitsPerPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;indexName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;timeslip_events&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;filters&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`date &amp;gt;= &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; AND date &amp;lt;= &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;hitsPerPage&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This batched approach is critical, sequential queries would take ~4× longer and break the conversational feel.&lt;/p&gt;

&lt;h3&gt;
  
  
  Prompt Engineering: Era-Aware Context Generation
&lt;/h3&gt;

&lt;p&gt;Raw search results aren’t enough for conversation. I built a cultural context layer that enriches responses with era-specific narratives:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;YEAR_HIGHLIGHTS&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="mi"&gt;1969&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The Summer of Love peaked as humans walked on the moon.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mi"&gt;1984&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;MTV transformed music into a visual medium.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="mi"&gt;1989&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;The Berlin Wall fell and hip-hop went mainstream.&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="c1"&gt;// 60+ curated year narratives&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The agent also generates contextual follow-up suggestions based on actual results:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Found George Michael? → “Explore more from George Michael”&lt;/li&gt;
&lt;li&gt;Searched 1988? → “See nearby: 1989 — The year the Berlin Wall fell”&lt;/li&gt;
&lt;li&gt;First time in the 80s? → “Discover more of the 80s”&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Memory System: Persistence Without Accounts
&lt;/h3&gt;

&lt;p&gt;Following a retrieval + scale + memory approach, I implemented localStorage-based memory:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Search History&lt;/strong&gt; — last 20 queries with one-click replay&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Favorites&lt;/strong&gt; — save meaningful dates with personal notes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Achievements&lt;/strong&gt; — unlock badges for exploring different decades&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This creates session continuity without requiring authentication, the agent “remembers” your journey through time.&lt;/p&gt;




&lt;h2&gt;
  
  
  Why Fast Retrieval Matters
&lt;/h2&gt;

&lt;p&gt;TimeSlipSearch lives or dies by speed. Here’s why Algolia was essential:&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Conversational UX requires instant responses
&lt;/h3&gt;

&lt;p&gt;Chat interfaces create expectations of immediacy. A 2-second delay feels like the agent is “thinking too hard.” Algolia’s sub-100ms retrieval keeps the conversation flowing naturally.&lt;/p&gt;

&lt;h3&gt;
  
  
  2) Four indices, one round-trip
&lt;/h3&gt;

&lt;p&gt;Without batched multi-index search, I’d need 4 sequential API calls. At ~150ms each, that’s ~600ms of network latency alone, before any processing. Algolia collapses this to a single request.&lt;/p&gt;

&lt;h3&gt;
  
  
  3) The retro aesthetic is decoration, not necessity
&lt;/h3&gt;

&lt;p&gt;The VHS tracking lines and CRT glow are purely stylistic. Results arrive so fast that the “loading” animation is optional, users see their time capsule before the tape even finishes rewinding.&lt;/p&gt;

&lt;h3&gt;
  
  
  4) Numeric range filtering at scale
&lt;/h3&gt;

&lt;p&gt;Searching 350,000 Billboard records by Unix timestamp range could be expensive. Algolia’s numeric filters handle it effortlessly, enabling queries like “show me everything from June 1–7, 1988” without performance degradation.&lt;/p&gt;




&lt;h2&gt;
  
  
  Built With
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Next.js 16&lt;/li&gt;
&lt;li&gt;Algolia v5&lt;/li&gt;
&lt;li&gt;TypeScript&lt;/li&gt;
&lt;li&gt;Tailwind CSS&lt;/li&gt;
&lt;li&gt;chrono-node for natural language date parsing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Data Sources
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Billboard Hot 100&lt;/li&gt;
&lt;li&gt;TMDB&lt;/li&gt;
&lt;li&gt;FRED Economic Data&lt;/li&gt;
&lt;li&gt;Wikimedia&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>algoliachallenge</category>
      <category>devchallenge</category>
      <category>search</category>
      <category>nextjs</category>
    </item>
    <item>
      <title>ContradictMe: An AI That Disagrees With You (For Good)</title>
      <dc:creator>Elizabeth Stein</dc:creator>
      <pubDate>Mon, 09 Feb 2026 00:32:38 +0000</pubDate>
      <link>https://dev.to/liztacular/contradictme-an-ai-thats-designed-to-disagree-with-you-21d7</link>
      <guid>https://dev.to/liztacular/contradictme-an-ai-thats-designed-to-disagree-with-you-21d7</guid>
      <description>&lt;p&gt;This is my submission for the DEV Challenge: &lt;a href="https://dev.to/challenges/algolia"&gt;Consumer-Facing Conversational Experiences&lt;/a&gt;.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;ContradictMe&lt;/strong&gt; is an AI designed to disagree with you.&lt;/p&gt;

&lt;p&gt;Most AI assistants are optimized to be helpful, harmless, and agreeable. ContradictMe is built to &lt;strong&gt;challenge your beliefs with the strongest possible counterarguments&lt;/strong&gt; , not to be contrarian, but to make you think better.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;We’re drowning in agreement.&lt;/p&gt;

&lt;p&gt;Social algorithms feed us content that confirms what we already believe. AI assistants optimize for satisfaction. The result is echo chambers everywhere.&lt;/p&gt;

&lt;p&gt;The consequences are real:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Students graduate without learning to defend their ideas&lt;/li&gt;
&lt;li&gt;Professionals make decisions without stress-testing assumptions&lt;/li&gt;
&lt;li&gt;Public discourse becomes tribal, we don’t even understand the other side anymore&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Solution
&lt;/h2&gt;

&lt;p&gt;ContradictMe weaponizes disagreement for good. Tell it something you believe strongly, and it will:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Steel-man the opposition&lt;/strong&gt; , present the strongest version of counterarguments, not weak straw-men
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cite real research&lt;/strong&gt; , every claim backed by credible sources and scored for quality
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Acknowledge nuance&lt;/strong&gt; , flags limitations, mixed evidence, and where you might actually be right
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Spark deeper thinking&lt;/strong&gt; , ends with reflection questions that stay with you
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It’s not about changing minds. It’s about strengthening them.&lt;/p&gt;

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

&lt;p&gt;🔗 &lt;a href="https://contradict-me.vercel.app" rel="noopener noreferrer"&gt;https://contradict-me.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Core Experience: Challenge Your Beliefs
&lt;/h2&gt;

&lt;p&gt;Enter any belief, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“Remote work is always better”&lt;/li&gt;
&lt;li&gt;“AI will take all jobs”&lt;/li&gt;
&lt;li&gt;“College isn’t worth it”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…and get a thoughtful, evidence-based counterargument in seconds.&lt;/p&gt;

&lt;p&gt;What you’ll see:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quality scores (0-100) for each argument&lt;/li&gt;
&lt;li&gt;Source credibility badges (peer-reviewed, institution, citation count)&lt;/li&gt;
&lt;li&gt;Explicit limitations (example: “This study only examined tech workers”)&lt;/li&gt;
&lt;li&gt;Follow-up questions to explore further&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  AI Debate Arena
&lt;/h2&gt;

&lt;p&gt;Can’t decide what to think? Watch two AI agents battle it out.&lt;/p&gt;

&lt;p&gt;Enter a topic and watch:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Logical Larry&lt;/strong&gt; (evidence-focused)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Emotional Emma&lt;/strong&gt; (values-focused)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;…debate through &lt;strong&gt;5 structured rounds&lt;/strong&gt;. You can:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Interject with your own questions mid-debate&lt;/li&gt;
&lt;li&gt;Vote for the winner&lt;/li&gt;
&lt;li&gt;Export the full transcript&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Analytics &amp;amp; Achievements
&lt;/h2&gt;

&lt;p&gt;Track your intellectual journey:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Topics explored (tag cloud visualization)&lt;/li&gt;
&lt;li&gt;Arguments encountered&lt;/li&gt;
&lt;li&gt;Critical thinking achievements (example: “Renaissance Mind” for exploring 5+ topics)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Full Feature List
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Dark/light/system themes (keyboard shortcut: ⌘⇧L)&lt;/li&gt;
&lt;li&gt;Conversation history with search + bookmarks&lt;/li&gt;
&lt;li&gt;Export conversations (JSON, Markdown, TXT)&lt;/li&gt;
&lt;li&gt;WCAG accessibility compliance&lt;/li&gt;
&lt;li&gt;Streaming responses with elegant loading states&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  How I Used Algolia Agent Studio
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Architecture Overview
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;User belief → Agent Studio (GPT-4) → Algolia Search → ranked arguments → synthesized response&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The magic is in how retrieval and generation work together.&lt;/p&gt;

&lt;h3&gt;
  
  
  1) Curated Argument Database
&lt;/h3&gt;

&lt;p&gt;I didn’t index random content. I built a curated database of &lt;strong&gt;26 research-backed arguments&lt;/strong&gt; across controversial topics:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Work&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Remote productivity&lt;/li&gt;
&lt;li&gt;4-day workweek&lt;/li&gt;
&lt;li&gt;Gig economy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Economics&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minimum wage&lt;/li&gt;
&lt;li&gt;UBI&lt;/li&gt;
&lt;li&gt;Cryptocurrency&lt;/li&gt;
&lt;li&gt;Housing policy&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Technology&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;AI displacement&lt;/li&gt;
&lt;li&gt;EVs&lt;/li&gt;
&lt;li&gt;Social media effects&lt;/li&gt;
&lt;li&gt;Space funding&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Social&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Gun policy&lt;/li&gt;
&lt;li&gt;Immigration&lt;/li&gt;
&lt;li&gt;Drug decriminalization&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Health/Education&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Plant-based diets&lt;/li&gt;
&lt;li&gt;Healthcare systems&lt;/li&gt;
&lt;li&gt;College ROI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each argument is structured for optimal retrieval. Example record shape:&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;"objectID"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"remote-work-innovation"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"position"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"against_remote_work"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"opposingBeliefs"&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="s2"&gt;"remote work is always better"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"offices are obsolete"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"mainClaim"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Innovation often depends on unplanned collaboration"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"evidence"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Summary of findings and key results..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"supportingPoints"&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="s2"&gt;"Spontaneous cross-team idea flow"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Whiteboard brainstorming sessions"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"Mentorship through observation"&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;"limitations"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Context limits, population limits, or mixed evidence notes..."&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sourceMetadata"&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;"Innovation Patterns in Distributed Teams"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"authors"&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="s2"&gt;"Author One"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Author Two"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"institution"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Example University"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"publicationType"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"peer-reviewed"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"yearPublished"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2024&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"citationCount"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;847&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"doi"&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.xxxx/xxxx.xxxx"&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;"qualityScore"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;87&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sourceCredibility"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;95&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"evidenceStrength"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;85&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;Average quality score across the database: &lt;strong&gt;88.1 / 100&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  2) Search Configuration
&lt;/h3&gt;

&lt;p&gt;Key idea: &lt;strong&gt;rank by quality, not just relevance&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Searchable attributes&lt;/span&gt;
&lt;span class="nx"&gt;searchableAttributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;mainClaim&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;evidence&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;supportingPoints&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;opposingBeliefs&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// key: matches user's stated belief&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;metadata.tags&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;metadata.domain&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt;

&lt;span class="c1"&gt;// Custom ranking - quality over relevance&lt;/span&gt;
&lt;span class="nx"&gt;customRanking&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;desc(qualityScore)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;desc(sourceCredibility)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;desc(evidenceStrength)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;],&lt;/span&gt;

&lt;span class="c1"&gt;// Faceting for filtering&lt;/span&gt;
&lt;span class="nx"&gt;attributesForFaceting&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;filterOnly(position)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;searchable(metadata.domain)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;filterOnly(sourceMetadata.yearPublished)&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;opposingBeliefs&lt;/code&gt; field is crucial, it’s how the agent matches “I believe remote work is better” to arguments that oppose that position.&lt;/p&gt;

&lt;h3&gt;
  
  
  3) Prompt Engineering for Steel-Manning
&lt;/h3&gt;

&lt;p&gt;System prompt principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Acknowledge the user’s perspective, don’t dismiss it&lt;/li&gt;
&lt;li&gt;Retrieve the &lt;strong&gt;strongest&lt;/strong&gt; counterarguments (steel-man, not straw-man)&lt;/li&gt;
&lt;li&gt;Present 2-3 top-ranked arguments with:

&lt;ul&gt;
&lt;li&gt;Core claim&lt;/li&gt;
&lt;li&gt;Supporting evidence + quality indicators&lt;/li&gt;
&lt;li&gt;Source attribution (authors, institution, year)&lt;/li&gt;
&lt;li&gt;Explicit limitations or caveats&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;Note where the user’s belief has valid points&lt;/li&gt;

&lt;li&gt;End with a thought-provoking question&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;Tone rules: never condescending, never attack the person, challenge ideas with evidence and curiosity.&lt;/p&gt;

&lt;h3&gt;
  
  
  4) Streaming Integration (SSE)
&lt;/h3&gt;

&lt;p&gt;The frontend uses Server-Sent Events (SSE) for real-time streaming so the response feels like the AI is reasoning in front of you.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;agentEndpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;POST&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Content-Type&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;application/json&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;role&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;user&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt; &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;userBelief&lt;/span&gt; &lt;span class="p"&gt;}]&lt;/span&gt; &lt;span class="p"&gt;}],&lt;/span&gt;
    &lt;span class="na"&gt;stream&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;compatibilityMode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;ai-sdk-5&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="c1"&gt;// Stream chunks to client&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;await &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;chunk&lt;/span&gt; &lt;span class="k"&gt;of&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Parse SSE format and forward to UI&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Why Fast Retrieval Matters
&lt;/h2&gt;

&lt;p&gt;Speed isn’t a nice-to-have for ContradictMe, it’s essential to the psychology of the experience.&lt;/p&gt;

&lt;p&gt;When someone shares a deeply-held belief, they’re in a narrow window of openness. If the system is slow, defenses come back up and they start preparing rebuttals before they even read the response.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fast (&amp;lt; 2s):&lt;/strong&gt; user stays engaged and receptive
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Slow (&amp;gt; 5s):&lt;/strong&gt; user disengages or “armors up”
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Algolia’s fast search lets the agent retrieve, rank, and synthesize arguments before that window closes.&lt;/p&gt;

&lt;h3&gt;
  
  
  Real Performance Numbers
&lt;/h3&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Metric&lt;/th&gt;
&lt;th&gt;Result&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Average belief-to-first-token&lt;/td&gt;
&lt;td&gt;1.2 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Full response completion&lt;/td&gt;
&lt;td&gt;4-6 seconds&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Debate Arena (10 retrievals)&lt;/td&gt;
&lt;td&gt;Smooth, no lag&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Tests passing&lt;/td&gt;
&lt;td&gt;73 / 73&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  The Debate Arena Stress Test
&lt;/h3&gt;

&lt;p&gt;Each 5-round debate requires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;10 argument retrievals (5 per side)&lt;/li&gt;
&lt;li&gt;real-time synthesis&lt;/li&gt;
&lt;li&gt;awareness of prior rounds&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With slower retrieval, this feature wouldn’t feel usable. With Algolia, it feels like watching two informed debaters go head-to-head in real time.&lt;/p&gt;




&lt;h2&gt;
  
  
  The Bigger Picture
&lt;/h2&gt;

&lt;p&gt;ContradictMe isn’t just a demo, it’s a proof of concept for a different kind of AI.&lt;/p&gt;

&lt;p&gt;What if we built systems that made us &lt;strong&gt;better thinkers&lt;/strong&gt;, not just more efficient workers? What if disagreement was a feature, not a bug?&lt;/p&gt;

&lt;p&gt;Algolia Agent Studio made this possible by combining:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;fast semantic search over structured argument data&lt;/li&gt;
&lt;li&gt;GPT-4 synthesis for nuanced responses&lt;/li&gt;
&lt;li&gt;streaming delivery for conversational flow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is an AI that respects you enough to disagree.&lt;/p&gt;

&lt;p&gt;🔗 &lt;a href="https://contradict-me.vercel.app" rel="noopener noreferrer"&gt;https://contradict-me.vercel.app&lt;/a&gt;&lt;/p&gt;

</description>
      <category>algoliachallenge</category>
      <category>devchallenge</category>
      <category>ai</category>
      <category>search</category>
    </item>
  </channel>
</rss>
