<?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: Mongoo (Mungunshagai Tum)</title>
    <description>The latest articles on DEV Community by Mongoo (Mungunshagai Tum) (@_6bb3445a3dec).</description>
    <link>https://dev.to/_6bb3445a3dec</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.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2750954%2F7906225d-868f-42c4-8748-3061f3fb1635.png</url>
      <title>DEV Community: Mongoo (Mungunshagai Tum)</title>
      <link>https://dev.to/_6bb3445a3dec</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/_6bb3445a3dec"/>
    <language>en</language>
    <item>
      <title>Amibuddy Live homework agent app - Gemini Live agent hackathon</title>
      <dc:creator>Mongoo (Mungunshagai Tum)</dc:creator>
      <pubDate>Mon, 16 Mar 2026 22:56:57 +0000</pubDate>
      <link>https://dev.to/_6bb3445a3dec/amibuddy-live-homework-agent-app-gemini-live-agent-hackathon-2mp3</link>
      <guid>https://dev.to/_6bb3445a3dec/amibuddy-live-homework-agent-app-gemini-live-agent-hackathon-2mp3</guid>
      <description>&lt;h1&gt;
  
  
  My Daughter's Doodles Came to Life: Building an AI Tutor with Gemini &amp;amp; SAM 2
&lt;/h1&gt;

&lt;h1&gt;
  
  
  GeminiLiveAgentChallenge.
&lt;/h1&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%2Fw29hcdh3ze3sio62gm3f.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%2Fw29hcdh3ze3sio62gm3f.png" alt=" "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;By a Mom Developer&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Spark: First Grade Jitters
&lt;/h2&gt;

&lt;p&gt;My daughter just started first grade here in Japan. It’s a huge milestone—the shiny new &lt;em&gt;randoseru&lt;/em&gt; (backpack), the excitement of new friends, but also the daunting reality of homework.&lt;/p&gt;

&lt;p&gt;Watching her sit at her desk, I noticed two things: she loved drawing, but she found studying to be a chore. She would doodle monsters and princesses on the corners of her math worksheets instead of solving the problems.&lt;/p&gt;

&lt;p&gt;That’s when it hit me. &lt;strong&gt;What if those doodles could help her study?&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;As a developer (and a mom), I decided to build a solution. I wanted to bridge the gap between her creativity and her education. I wanted to bring her drawings to life, not just as animations, but as intelligent, interactive study partners.&lt;/p&gt;

&lt;h2&gt;
  
  
  Introducing AmiBuddy
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AmiBuddy&lt;/strong&gt; is the result of that late-night "mom coding." It’s an AI-powered application that transforms static children's drawings into "Living AI Agents."&lt;/p&gt;

&lt;h3&gt;
  
  
  Demo &amp;amp; Links
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;📺 Watch the Demo:&lt;/strong&gt; &lt;/li&gt;
&lt;/ul&gt;

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

&lt;ul&gt;
&lt;li&gt;  &lt;strong&gt;🚀 Try the App:&lt;/strong&gt; &lt;a href="https://amibuddy-frontend-535548706733.asia-northeast1.run.app/" rel="noopener noreferrer"&gt;AmiBuddy Live Site&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Architecture Overview
&lt;/h2&gt;

&lt;p&gt;I built AmiBuddy using a hybrid architecture: a &lt;strong&gt;React Native (Expo)&lt;/strong&gt; frontend for the best mobile experience, and a &lt;strong&gt;Python (FastAPI)&lt;/strong&gt; backend on &lt;strong&gt;Cloud Run&lt;/strong&gt; for heavy AI processing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;graph LR
    subgraph Frontend ["Frontend Layer (React Native / Expo)"]
        direction TB
        MobileClient["📱 Mobile App"]
        WebClient["💻 Web App"]
    end

    subgraph External_AI ["External AI Services"]
        direction TB
        Gemini["✨ Gemini 2.5 Flash (Vision/Reasoning)"]
        ElevenLabs["🗣️ ElevenLabs (TTS)"]
    end

    subgraph Cloud_Run ["Backend (Cloud Run)"]
        direction TB
        OrchestratorAPI["🚀 Orchestrator API"]
        SAM2["🧩 SAM 2"]
        RiggingAgent["🦴 Rigging Agent"]
    end

    Frontend -.-&amp;gt;|Direct API Call| Gemini
    Frontend -.-&amp;gt;|Direct API Call| ElevenLabs
    Frontend ==&amp;gt;|Upload Image| OrchestratorAPI

    OrchestratorAPI --&amp;gt; SAM2
    OrchestratorAPI --&amp;gt; RiggingAgent
    RiggingAgent -.-&amp;gt;|Query Structure| Gemini
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Technical Deep Dive: The "Living Agent" Pipeline
&lt;/h2&gt;

&lt;p&gt;The core magic happens in the backend, where we turn a static image into a rigged character.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 1: Structural Understanding (Rigging Agent)
&lt;/h3&gt;

&lt;p&gt;Before we can animate a drawing, we need to understand &lt;em&gt;what&lt;/em&gt; it is. Where is the head? Where are the hands?&lt;/p&gt;

&lt;p&gt;I used &lt;strong&gt;Google Gemini 2.5 Flash&lt;/strong&gt; for this. Unlike traditional object detection models that need training, Gemini has incredible "zero-shot" understanding. I simply prompt it to find the joints and body parts.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Highlight: The Rigging Prompt (&lt;code&gt;agents/rigging.py&lt;/code&gt;)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I specifically ask Gemini to be "generous" with bounding boxes to ensure we don't crop off limbs.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;        &lt;span class="n"&gt;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;
        Analyze this character drawing for skeletal animation.
        Provide a JSON object with the following structure:
        {
            &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;joints&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: {
                &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;neck&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: [x, y],
                &lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;left_shoulder&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;: [x, y],
&lt;/span&gt;&lt;span class="gp"&gt;                ...&lt;/span&gt;
            &lt;span class="p"&gt;},&lt;/span&gt;
            &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;parts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;head&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ymin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xmin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ymax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xmax&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;left_arm&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;ymin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xmin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ymax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xmax&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
                &lt;span class="bp"&gt;...&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="n"&gt;IMPORTANT&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;For&lt;/span&gt; &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;parts&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ensure&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;bounding&lt;/span&gt; &lt;span class="n"&gt;boxes&lt;/span&gt; &lt;span class="n"&gt;are&lt;/span&gt; &lt;span class="n"&gt;GENEROUS&lt;/span&gt; &lt;span class="ow"&gt;and&lt;/span&gt; &lt;span class="n"&gt;INCLUSIVE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; 
        &lt;span class="n"&gt;Include&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;ENTIRE&lt;/span&gt; &lt;span class="n"&gt;limb&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;even&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="n"&gt;overlaps&lt;/span&gt; &lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;body&lt;/span&gt; &lt;span class="n"&gt;slightly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; 
        &lt;span class="n"&gt;Do&lt;/span&gt; &lt;span class="ow"&gt;not&lt;/span&gt; &lt;span class="n"&gt;crop&lt;/span&gt; &lt;span class="n"&gt;off&lt;/span&gt; &lt;span class="n"&gt;hands&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;feet&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ow"&gt;or&lt;/span&gt; &lt;span class="n"&gt;joints&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
        &lt;span class="n"&gt;RETURN&lt;/span&gt; &lt;span class="n"&gt;ONLY&lt;/span&gt; &lt;span class="n"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
        &lt;span class="sh"&gt;"""&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Phase 2: Surgical Extraction (Segmentation Agent)
&lt;/h3&gt;

&lt;p&gt;Once Gemini tells us &lt;em&gt;where&lt;/em&gt; the parts are (roughly), we need to cut them out with pixel-perfect precision.&lt;/p&gt;

&lt;p&gt;For this, I used &lt;strong&gt;Meta SAM 2 (Segment Anything Model 2)&lt;/strong&gt;. The magic here is the hand-off: we use the bounding boxes from Gemini as the "prompt" for SAM 2.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Highlight: From Gemini Box to SAM 2 Mask (&lt;code&gt;agents/segmentation.py&lt;/code&gt;)&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;        &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;part_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;parts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;items&lt;/span&gt;&lt;span class="p"&gt;():&lt;/span&gt;
            &lt;span class="c1"&gt;# Convert normalized coordinates from Gemini to pixels
&lt;/span&gt;            &lt;span class="n"&gt;ymin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xmin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ymax&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xmax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;box&lt;/span&gt;
            &lt;span class="n"&gt;input_box&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;np&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;array&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="n"&gt;xmin&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ymin&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;xmax&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;width&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ymax&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;height&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

            &lt;span class="c1"&gt;# Add padding to ensure SAM 2 gets the whole context
&lt;/span&gt;            &lt;span class="n"&gt;padding&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; 
            &lt;span class="n"&gt;input_box&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;max&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;input_box&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
            &lt;span class="bp"&gt;...&lt;/span&gt;

            &lt;span class="c1"&gt;# Ask SAM 2 to predict the mask for this box
&lt;/span&gt;            &lt;span class="n"&gt;masks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;scores&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;_&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;predictor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;predict&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="n"&gt;point_coords&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;point_labels&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="n"&gt;box&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;input_box&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;:],&lt;/span&gt;
                &lt;span class="n"&gt;multimask_output&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;False&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="p"&gt;)&lt;/span&gt;

            &lt;span class="c1"&gt;# The result is a perfect alpha mask for that body part!
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Phase 3: Life &amp;amp; Voice
&lt;/h3&gt;

&lt;p&gt;Finally, the frontend (&lt;code&gt;LiveBuddy&lt;/code&gt; component) takes these cut-out parts and animates them using simple sine waves (math-based animation) to simulate breathing and floating.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Study Buddy Agents
&lt;/h2&gt;

&lt;p&gt;Once the character is "alive," it needs to be "smart." I implemented two more agents on the Frontend side.&lt;/p&gt;

&lt;h3&gt;
  
  
  Phase 4: Homework Analysis (Gemini Vision Agent)
&lt;/h3&gt;

&lt;p&gt;When the child uploads a homework sheet, it’s not enough to just OCR the text. The AI needs to understand the &lt;em&gt;intent&lt;/em&gt; and &lt;em&gt;difficulty&lt;/em&gt; to explain it to a child.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Highlight: Homework Analysis (&lt;code&gt;src/services/geminiService.ts&lt;/code&gt;)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I use a structured JSON prompt with Gemini Vision to extract metadata about the homework. Note how I switch the prompt language based on the user's locale!&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;prompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`Analyze this homework image for a young student.
         Provide a JSON response with:
         - description: A short, encouraging summary of what the homework is about (in simple English).
         - topics: A list of key topics found (e.g., "Addition", "Kanji").
         - difficulty: estimated difficulty ("Easy", "Medium", "Hard").
         Keep the tone friendly and encouraging.
         Return ONLY valid JSON.`&lt;/span&gt;
      &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`この宿題の画像を子供向けに分析してください。
         以下のJSON形式で返してください：
         - description: 宿題の内容についての短く励ますような説明（やさしい日本語で）。
         - topics: 見つかった主要なトピックのリスト（例：「たしざん」、「かんじ」）。
         ...`&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;result&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;model&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;generateContent&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
      &lt;span class="nx"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;inlineData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;mimeType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;base64&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="c1"&gt;// Multimodal Input&lt;/span&gt;
    &lt;span class="p"&gt;]);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Phase 5: Voice Conversation (Speech-to-Text &amp;amp; TTS)
&lt;/h3&gt;

&lt;p&gt;For a 6-year-old, typing is a barrier. AmiBuddy is voice-first.&lt;br&gt;
I used &lt;strong&gt;Gemini 2.5 Flash&lt;/strong&gt; again for Speech-to-Text (transcription) because it handles mixed languages (Japanese/English) better than traditional STT engines, and &lt;strong&gt;ElevenLabs&lt;/strong&gt; for the character's voice.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Code Highlight: Context-Aware Chat (&lt;code&gt;src/services/voiceConversationService.ts&lt;/code&gt;)&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The AI needs to know &lt;em&gt;what homework&lt;/em&gt; we are looking at to answer questions correctly.&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="c1"&gt;// Build conversation context&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;contextPrompt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;locale&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;en&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
      &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="s2"&gt;`You are a friendly teacher helping a child with homework.
         Homework context: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;homeworkContext&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;

         Answer the child's question simply and kindly.
         Keep answers short (2-3 sentences).`&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="nx"&gt;homeworkContext&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;

         子供の質問に対して、わかりやすく、優しく答えてください。
         答えは2-3文で簡潔にしてください。`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Workflow Summary
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sequenceDiagram
    participant User as 👤 User
    participant API as 🚀 Backend
    participant Gemini as ✨ Gemini
    participant SAM2 as 🧩 SAM 2
    participant Storage as ☁️ Firebase
    participant Eleven as 🗣️ ElevenLabs

    Note over User, Storage: 1. Character Creation
    User-&amp;gt;&amp;gt;API: Upload Drawing
    API-&amp;gt;&amp;gt;Gemini: "Rig this character"
    Gemini--&amp;gt;&amp;gt;API: Skeleton Data
    loop Each Part
        API-&amp;gt;&amp;gt;SAM2: "Segment this part"
        SAM2--&amp;gt;&amp;gt;API: Part Mask
    end
    API--&amp;gt;&amp;gt;User: Living Character!

    Note over User, Eleven: 2. Study Session
    User-&amp;gt;&amp;gt;Gemini: Upload Homework Image
    Gemini--&amp;gt;&amp;gt;User: "This looks like Math!"
    User-&amp;gt;&amp;gt;User: Ask by Voice: "How do I do this?"
    User-&amp;gt;&amp;gt;Gemini: Transcribe Voice -&amp;gt; LLM Answer
    Gemini--&amp;gt;&amp;gt;User: "Try counting backwards!"
    User-&amp;gt;&amp;gt;Eleven: Speak Response
    Eleven--&amp;gt;&amp;gt;User: Character speaks!
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why This Matters
&lt;/h2&gt;

&lt;p&gt;For my daughter, AmiBuddy turned homework from a struggle into play. She’s excited to show her "buddy" what she learned today.&lt;/p&gt;

&lt;p&gt;For me, it’s a testament to how AI can be personal. We often talk about AI in terms of productivity or business, but its potential to connect with us emotionally—to nurture a child's curiosity—is what excites me the most.&lt;/p&gt;

&lt;p&gt;I’m open-sourcing parts of this journey to help other parents and developers build their own magic. Because sometimes, the best way to predict the future is to invent it for your kids.&lt;/p&gt;

</description>
      <category>agents</category>
      <category>devchallenge</category>
      <category>gemini</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Building Frankenstein Laboratory: Automating Legacy PHP Migration with Kiro IDE</title>
      <dc:creator>Mongoo (Mungunshagai Tum)</dc:creator>
      <pubDate>Fri, 05 Dec 2025 20:32:32 +0000</pubDate>
      <link>https://dev.to/_6bb3445a3dec/building-frankenstein-laboratory-automating-legacy-php-migration-with-kiro-ide-40m2</link>
      <guid>https://dev.to/_6bb3445a3dec/building-frankenstein-laboratory-automating-legacy-php-migration-with-kiro-ide-40m2</guid>
      <description>&lt;h2&gt;
  
  
  The Problem That Haunts Japanese Companies
&lt;/h2&gt;

&lt;p&gt;After two years working at a traditional Japanese company, I've witnessed a crisis that affects countless organizations across Japan: &lt;strong&gt;legacy PHP projects that refuse to die&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Every year, teams struggle with migration projects. Some critical systems still run on PHP 5 - a version that reached end-of-life in 2018. Developers spend months manually rewriting code, risking bugs with every line. Business stakeholders grow frustrated as new features take a backseat to maintenance. Technical debt compounds year after year.&lt;/p&gt;

&lt;p&gt;This isn't just my company's problem - it's an industry-wide crisis. Japanese companies, known for their stability and long-term thinking, often maintain systems for decades. But that stability becomes a prison when the technology underneath becomes obsolete.&lt;/p&gt;

&lt;p&gt;During the Kiro Halloween Hackathon, I decided to tackle this head-on. The result? &lt;strong&gt;Frankenstein Laboratory&lt;/strong&gt; - a tool that brings dead PHP code back to life by automating migration to modern Python.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built: Two Projects in One
&lt;/h2&gt;

&lt;p&gt;The solution has two components:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. PHP Migration Tool
&lt;/h3&gt;

&lt;p&gt;A web application that automates PHP-to-Python migration:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Clone any GitHub repository&lt;/li&gt;
&lt;li&gt;Analyze PHP code structure automatically&lt;/li&gt;
&lt;li&gt;Generate production-ready Python/FastAPI code&lt;/li&gt;
&lt;li&gt;Create OpenAPI specifications&lt;/li&gt;
&lt;li&gt;Generate property-based tests&lt;/li&gt;
&lt;li&gt;Download everything as a deployable package&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  2. Strangler Studio Demo
&lt;/h3&gt;

&lt;p&gt;A working reference implementation of the Strangler Fig pattern:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Legacy PHP application (student request system)&lt;/li&gt;
&lt;li&gt;Modern Python API (FastAPI equivalent)&lt;/li&gt;
&lt;li&gt;Nginx gateway for intelligent routing&lt;/li&gt;
&lt;li&gt;Zero-downtime incremental migration&lt;/li&gt;
&lt;li&gt;Comprehensive test suite&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The Technical Architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Migration Tool Stack
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Frontend (React + Vite):&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;// Four-stage wizard interface&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stages&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Source&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;    &lt;span class="c1"&gt;// GitHub URL or ZIP upload&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Analyze&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;   &lt;span class="c1"&gt;// PHP code analysis&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Transform&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// Python code generation&lt;/span&gt;
  &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Extract&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;    &lt;span class="c1"&gt;// Download generated code&lt;/span&gt;
&lt;span class="p"&gt;];&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The UI features a Frankenstein laboratory theme with animated logo, electric effects, and cinematic design. Six simultaneous CSS animations create a living, breathing interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.frankenstein-logo&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;animation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; 
    &lt;span class="n"&gt;float-logo&lt;/span&gt; &lt;span class="m"&gt;6s&lt;/span&gt; &lt;span class="n"&gt;ease-in-out&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;glow-pulse-logo&lt;/span&gt; &lt;span class="m"&gt;3s&lt;/span&gt; &lt;span class="n"&gt;ease-in-out&lt;/span&gt; &lt;span class="n"&gt;infinite&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;electric-spark&lt;/span&gt; &lt;span class="m"&gt;8s&lt;/span&gt; &lt;span class="n"&gt;ease-in-out&lt;/span&gt; &lt;span class="n"&gt;infinite&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;&lt;strong&gt;Backend (FastAPI + Python):&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The backend handles the heavy lifting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="nd"&gt;@app.post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/api/clone-github&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;clone_github_repo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;GitHubRepoRequest&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;Clone and analyze GitHub repository&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="c1"&gt;# Shallow clone for performance
&lt;/span&gt;    &lt;span class="n"&gt;git&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Repo&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;clone_from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
        &lt;span class="n"&gt;repo_url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;extract_dir&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;branch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;branch&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;depth&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;  &lt;span class="c1"&gt;# Only latest commit
&lt;/span&gt;        &lt;span class="n"&gt;single_branch&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="bp"&gt;True&lt;/span&gt;
    &lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="c1"&gt;# Analyze PHP code
&lt;/span&gt;    &lt;span class="n"&gt;analyzer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;PHPAnalyzer&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="n"&gt;analysis&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;analyzer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;analyze_directory&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;extract_dir&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;routes&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;analysis&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;routes&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;models&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;analysis&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;models&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
        &lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;dependencies&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;analysis&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="s"&gt;dependencies&lt;/span&gt;&lt;span class="sh"&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;The analyzer uses AST parsing to understand PHP code structure, identifying:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Routes and controllers&lt;/li&gt;
&lt;li&gt;Data models and relationships&lt;/li&gt;
&lt;li&gt;Database queries&lt;/li&gt;
&lt;li&gt;Dependencies and imports&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Then it generates Python code with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;FastAPI endpoints with proper type hints&lt;/li&gt;
&lt;li&gt;Pydantic models for data validation&lt;/li&gt;
&lt;li&gt;OpenAPI specifications&lt;/li&gt;
&lt;li&gt;Property-based tests using Hypothesis&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Strangler Pattern Implementation
&lt;/h3&gt;

&lt;p&gt;The demo showcases safe, incremental migration:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Docker Compose Orchestration:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;gateway&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;nginx:alpine&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8888:80"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
    &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;legacy-php&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;new-api&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

  &lt;span class="na"&gt;legacy-php&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./legacy-php&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8080:80"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;

  &lt;span class="na"&gt;new-api&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./new-api&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;8000:8000"&lt;/span&gt;&lt;span class="pi"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Nginx Gateway Routing:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Route /api/* to new Python API&lt;/span&gt;
&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/api/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://new-api:8000&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Route everything else to legacy PHP&lt;/span&gt;
&lt;span class="k"&gt;location&lt;/span&gt; &lt;span class="n"&gt;/&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;proxy_pass&lt;/span&gt; &lt;span class="s"&gt;http://legacy-php:80&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 allows incremental migration - move one endpoint at a time from PHP to Python while both systems run simultaneously.&lt;/p&gt;

&lt;h2&gt;
  
  
  Property-Based Testing: The Secret Weapon
&lt;/h2&gt;

&lt;p&gt;Traditional unit tests check specific examples. Property-based tests verify universal properties across ALL inputs.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Example: Gateway Routing Correctness&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="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Property 1: Gateway routes requests to correct backend&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;1..100&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c"&gt;# Generate random path&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="k"&gt;$((&lt;/span&gt;RANDOM &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/api/requests"&lt;/span&gt;
        &lt;span class="nv"&gt;EXPECTED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"new-api"&lt;/span&gt;
    &lt;span class="k"&gt;else
        &lt;/span&gt;&lt;span class="nv"&gt;PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/requests"&lt;/span&gt;
        &lt;span class="nv"&gt;EXPECTED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"legacy-php"&lt;/span&gt;
    &lt;span class="k"&gt;fi&lt;/span&gt;

    &lt;span class="c"&gt;# Test routing&lt;/span&gt;
    curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"http://localhost:8888&lt;/span&gt;&lt;span class="nv"&gt;$PATH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="c"&gt;# Verify correct backend handled request&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Python Property Test with Hypothesis:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="n"&gt;hypothesis&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;given&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;strategies&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;st&lt;/span&gt;

&lt;span class="nd"&gt;@given&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;st&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;integers&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;min_value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_api_returns_matching_id&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;request_id&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="sh"&gt;"""&lt;/span&gt;&lt;span class="s"&gt;For ANY valid ID, returned object should have matching ID&lt;/span&gt;&lt;span class="sh"&gt;"""&lt;/span&gt;
    &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sa"&gt;f&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;/requests/&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="n"&gt;request_id&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status_code&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;200&lt;/span&gt;
    &lt;span class="k"&gt;assert&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;json&lt;/span&gt;&lt;span class="p"&gt;()[&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="s"&gt;id&lt;/span&gt;&lt;span class="sh"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;request_id&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This runs 100+ iterations with random inputs, catching edge cases you'd never think to test manually.&lt;/p&gt;

&lt;h2&gt;
  
  
  Working with Kiro: The Development Process
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Spec-Driven Development
&lt;/h3&gt;

&lt;p&gt;For the Strangler Studio demo, I used Kiro's spec-driven approach:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Requirements (EARS format):&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;WHEN a request is made to /api/requests 
THEN the Gateway SHALL route it to the new Python API

WHEN a request is made to /requests 
THEN the Gateway SHALL route it to the legacy PHP application
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;2. Design with Correctness Properties:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;Property 1: Gateway routing correctness
For any request path, the gateway routes to the correct 
backend based on the path prefix.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;3. Task Breakdown:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt; [ ] 1. Set up Docker Compose with three services
&lt;span class="p"&gt;-&lt;/span&gt; [ ] 2. Implement Nginx gateway routing
&lt;span class="p"&gt;-&lt;/span&gt; [ ] 3. Create legacy PHP application
&lt;span class="p"&gt;-&lt;/span&gt; [ ] 4. Create new Python API
&lt;span class="p"&gt;-&lt;/span&gt; [ ] 5. Write property-based tests
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Kiro executed tasks one by one, automatically referencing requirements and implementing correctness properties as tests.&lt;/p&gt;

&lt;h3&gt;
  
  
  Vibe Coding for Rapid Prototyping
&lt;/h3&gt;

&lt;p&gt;For the migration tool UI, I used conversational iteration:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Me:&lt;/strong&gt; "Create a Frankenstein laboratory theme with electric blue and toxic green. Add animations: floating logo, electric glow pulse, and lightning sparks."&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Kiro:&lt;/strong&gt; &lt;em&gt;Generates 200+ lines of CSS with six simultaneous animations, GPU-accelerated properties, and hover effects&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;This flexibility was perfect for UI polish and rapid feature additions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Steering Documents: Project-Specific Intelligence
&lt;/h3&gt;

&lt;p&gt;I created four steering files in &lt;code&gt;.kiro/steering/&lt;/code&gt; that were automatically included in every conversation:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;testing-standards.md:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt; Use Hypothesis for property-based testing
&lt;span class="p"&gt;-&lt;/span&gt; Minimum 100 iterations per test
&lt;span class="p"&gt;-&lt;/span&gt; Tag format: # Feature: {name}, Property {n}: {description}
&lt;span class="p"&gt;-&lt;/span&gt; Test patterns: invariants, round-trips, idempotence
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;halloween-theme.md:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;&lt;span class="p"&gt;-&lt;/span&gt; Electric Blue: #00d4ff
&lt;span class="p"&gt;-&lt;/span&gt; Toxic Green: #76ff03
&lt;span class="p"&gt;-&lt;/span&gt; Font: Cinzel (headings), Inter (body)
&lt;span class="p"&gt;-&lt;/span&gt; No cheap emojis or generic Halloween clichés
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This transformed Kiro from a general assistant into a domain expert for my project. Every response was consistent with project conventions without me repeating myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Technical Challenges and Solutions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Challenge 1: Docker Port Conflicts
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Port 80 already allocated on host system.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Changed gateway to port 8888, updated all documentation. Created PORT_CHANGES_SUMMARY.md to track the change.&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge 2: Git Not Found in Docker
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Backend container couldn't clone GitHub repositories.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Updated Dockerfile to install git:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight docker"&gt;&lt;code&gt;&lt;span class="k"&gt;RUN &lt;/span&gt;apt-get update &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; apt-get &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-y&lt;/span&gt; git
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; GIT_PYTHON_REFRESH=quiet&lt;/span&gt;
&lt;span class="k"&gt;ENV&lt;/span&gt;&lt;span class="s"&gt; GIT_PYTHON_GIT_EXECUTABLE=/usr/bin/git&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Challenge 3: Vercel Serverless Limitations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; 10-second timeout on free tier fails for large repos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Implemented shallow cloning (depth=1), optimized analysis, documented upgrade path to Pro tier ($20/month for 60-second timeout).&lt;/p&gt;

&lt;h3&gt;
  
  
  Challenge 4: Logo Not Showing After Deployment
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Added logo after Docker build, so it wasn't in the container.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt; Created rebuild scripts and documentation explaining Docker's immutable nature. Containers capture files at build time - changes require rebuilds.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Results
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What I Accomplished:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Complete end-to-end migration tool&lt;/li&gt;
&lt;li&gt;Working Strangler pattern demo&lt;/li&gt;
&lt;li&gt;Property-based test suite&lt;/li&gt;
&lt;li&gt;15+ documentation files&lt;/li&gt;
&lt;li&gt;Production-ready code quality&lt;/li&gt;
&lt;li&gt;Deployed to Vercel in 15 minutes&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Code Quality Metrics:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type safety throughout (Pydantic models, TypeScript)&lt;/li&gt;
&lt;li&gt;Comprehensive error handling&lt;/li&gt;
&lt;li&gt;Security headers and CORS configuration&lt;/li&gt;
&lt;li&gt;100+ property-based test iterations&lt;/li&gt;
&lt;li&gt;OpenAPI contract validation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Development Speed:&lt;/strong&gt;&lt;br&gt;
What would normally take weeks took days, thanks to Kiro's assistance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Key Learnings
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Property-Based Testing is Powerful
&lt;/h3&gt;

&lt;p&gt;Hypothesis finds edge cases you'd never think to test. It requires different thinking (properties vs examples) but catches more bugs.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Spec-Driven Development Ensures Quality
&lt;/h3&gt;

&lt;p&gt;Clear requirements prevent misunderstandings. Correctness properties ensure quality. Task-by-task execution is systematic.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Steering Documents are Game-Changers
&lt;/h3&gt;

&lt;p&gt;They transform Kiro from a general assistant into a domain expert. Every response follows project conventions automatically.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. The Strangler Pattern Works
&lt;/h3&gt;

&lt;p&gt;Incremental migration is safer than big-bang rewrites. The gateway pattern allows gradual transition with zero downtime.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Documentation is a Feature
&lt;/h3&gt;

&lt;p&gt;Good docs are as important as good code. Users need multiple entry points: quick start, detailed guide, troubleshooting, reference.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real-World Impact
&lt;/h2&gt;

&lt;p&gt;This solves a real problem for Japanese companies (and companies worldwide) trapped by legacy PHP. The tool provides:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Automated analysis&lt;/strong&gt; - No more manual code review&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intelligent generation&lt;/strong&gt; - Production-ready Python code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Safe migration&lt;/strong&gt; - Strangler pattern with zero downtime&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Comprehensive testing&lt;/strong&gt; - Property-based tests ensure correctness&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Companies can now modernize without fear. No more months-long rewrite projects. No more choosing between maintenance and innovation.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;Immediate improvements:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Support for Laravel, Symfony, WordPress frameworks&lt;/li&gt;
&lt;li&gt;Database schema extraction and migration&lt;/li&gt;
&lt;li&gt;AI-powered code optimization&lt;/li&gt;
&lt;li&gt;Multi-language support (Ruby, Java, Node.js to Python)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Long-term vision:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Japanese language UI and documentation&lt;/li&gt;
&lt;li&gt;Integration with Japanese cloud providers&lt;/li&gt;
&lt;li&gt;Enterprise features (SSO, audit logging)&lt;/li&gt;
&lt;li&gt;Open-source core with plugin ecosystem&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;The ultimate goal:&lt;/strong&gt; Make legacy PHP migration so easy that Japanese companies can modernize without fear.&lt;/p&gt;

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

&lt;p&gt;&lt;strong&gt;GitHub Repository:&lt;/strong&gt; &lt;a href="https://github.com/mongonsh/Strangler-Studio-with-PHP-Migration-Tool" rel="noopener noreferrer"&gt;https://github.com/mongonsh/Strangler-Studio-with-PHP-Migration-Tool&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Deploy to Vercel:&lt;/strong&gt; Follow the guides in the repo - you can have it running in 15 minutes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tech Stack:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Frontend: React, Vite, TailwindCSS&lt;/li&gt;
&lt;li&gt;Backend: FastAPI, Pydantic, GitPython, Hypothesis&lt;/li&gt;
&lt;li&gt;Demo: PHP 8, FastAPI, Nginx, Docker&lt;/li&gt;
&lt;li&gt;Testing: Pytest, Hypothesis, Bash scripts&lt;/li&gt;
&lt;li&gt;Deployment: Vercel (serverless)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This hackathon taught me that the future of software development isn't human OR AI - it's human AND AI working together.&lt;/p&gt;

&lt;p&gt;I provided the vision: solve the legacy PHP problem plaguing Japanese companies.&lt;/p&gt;

&lt;p&gt;Kiro provided the execution: production-ready code, comprehensive tests, beautiful UI, thorough documentation.&lt;/p&gt;

&lt;p&gt;Together, we built something that would have taken weeks in just days.&lt;/p&gt;

&lt;p&gt;Legacy PHP doesn't have to be a death sentence. With the right tools, even the oldest code can be reborn.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;"It's alive!"&lt;/strong&gt; ⚡&lt;/p&gt;




&lt;p&gt;*Built with Kiro IDE during Kiroween *&lt;/p&gt;




&lt;p&gt;#kiro #hackathon #php #python #fastapi #migration #legacy #strangler-pattern #property-based-testing #ai-assisted-development&lt;/p&gt;




&lt;p&gt;What do you think? Would you use a tool like this for your legacy projects? Drop a comment below!&lt;/p&gt;

</description>
      <category>kiroween</category>
      <category>kiro</category>
      <category>hackathon</category>
      <category>legacyprojectmigrationtool</category>
    </item>
  </channel>
</rss>
