<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>4sh.dev</title>
    <link>https://4sh.dev/</link>
    <description>Recent content on 4sh.dev</description>
    <image>
      <title>4sh.dev</title>
      <url>https://4sh.dev/images/Ash-Drawing.jpg</url>
      <link>https://4sh.dev/images/Ash-Drawing.jpg</link>
    </image>
    <generator>Hugo -- 0.147.9</generator>
    <language>en-us</language>
    <lastBuildDate>Thu, 07 May 2026 00:00:00 +0000</lastBuildDate>
    <atom:link href="https://4sh.dev/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Codex, Three Months In</title>
      <link>https://4sh.dev/posts/2026/codex-three-months-in/</link>
      <pubDate>Thu, 07 May 2026 00:00:00 +0000</pubDate>
      <guid>https://4sh.dev/posts/2026/codex-three-months-in/</guid>
      <description>Three months of daily-driving Codex: release tracking, a maturing plugin system, and the unglamorous polish that makes a side project feel lived-in.</description>
    </item>
    <item>
      <title>Building HiveLabs: Taking the AI Agent Team Concept to Production</title>
      <link>https://4sh.dev/posts/2026/building-hivelabs/</link>
      <pubDate>Fri, 13 Mar 2026 00:00:00 +0000</pubDate>
      <guid>https://4sh.dev/posts/2026/building-hivelabs/</guid>
      <description>&lt;p&gt;A couple of weeks ago I wrote about &lt;a href=&#34;https://4sh.dev/posts/2026/building-4shclaw/&#34;&gt;4shClaw&lt;/a&gt;, a personal multi-agent AI assistant running with Docker. It works. Agents spin up in containers, coordinate through a shared ledger, and build a game called &lt;a href=&#34;https://github.com/AshDevFr/GLORP&#34;&gt;GLORP&lt;/a&gt; autonomously. The architecture proved out the core ideas: container isolation, declarative capabilities, ephemeral agents, lead-agent orchestration.&lt;/p&gt;
&lt;p&gt;But 4shClaw is a personal tool. Single user, SQLite, filesystem IPC, Node.js host. That&amp;rsquo;s fine for me. It&amp;rsquo;s not fine for a team of five engineers at a fintech company who want the same thing on their infrastructure, with audit trails their compliance team will accept.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Building 4shClaw: A Multi-Agent AI Assistant That Runs Your Life (and Builds Its Own Demo)</title>
      <link>https://4sh.dev/posts/2026/building-4shclaw/</link>
      <pubDate>Sat, 28 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://4sh.dev/posts/2026/building-4shclaw/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been trying to build personal AI assistants on and off for a while. Bots backed by LLM APIs, cron jobs that would run some automated task. None of them stuck really.&lt;/p&gt;
&lt;p&gt;Then &lt;a href=&#34;https://github.com/open-claw/open-claw&#34;&gt;OpenClaw&lt;/a&gt; came along and kicked off the personal AI assistant movement. It looked like what I wanted, until I looked under the hood. The thing wants access to &lt;em&gt;everything&lt;/em&gt;: your email, your calendar, your GitHub, your files, all funneled through a single Node.js process with shared memory and no real isolation. One bad prompt injection through an email summary could, in theory, access your GitHub token, your calendar credentials, and every other secret the system knows about. That&amp;rsquo;s not a hypothetical either: multiple critical CVEs in 2026 alone, all stemming from the same architecture.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Why I&#39;m Building Codex: A Digital Library Server in Rust</title>
      <link>https://4sh.dev/posts/2026/building-codex/</link>
      <pubDate>Thu, 05 Feb 2026 00:00:00 +0000</pubDate>
      <guid>https://4sh.dev/posts/2026/building-codex/</guid>
      <description>&lt;p&gt;I love &lt;a href=&#34;https://komga.org/&#34;&gt;Komga&lt;/a&gt;. It&amp;rsquo;s been my go-to for managing comics, manga, and ebooks for years, and it genuinely does the job well. The UI is clean, the feature set is rich, and the community around it is great. If you self-host a digital reading collection and haven&amp;rsquo;t tried it, you should.&lt;/p&gt;
&lt;p&gt;But after years of daily use, I kept bumping into a few limitations that I couldn&amp;rsquo;t work around. And eventually, the itch to build something of my own became too strong to ignore.&lt;/p&gt;</description>
    </item>
    <item>
      <title>On-Demand Workloads with Sablier - Scale to Zero for Homelab Efficiency</title>
      <link>https://4sh.dev/articles/homelab/sablier/</link>
      <pubDate>Sun, 12 Oct 2025 00:00:00 +0000</pubDate>
      <guid>https://4sh.dev/articles/homelab/sablier/</guid>
      <description>Save homelab resources by scaling unused services to zero with Sablier and Traefik integration for automatic service wake-up on demand.</description>
    </item>
    <item>
      <title>Bee AI n8n Workflows</title>
      <link>https://4sh.dev/posts/2025/n8n-nodes-bee-ai-workflows/</link>
      <pubDate>Thu, 03 Jul 2025 00:00:00 +0000</pubDate>
      <guid>https://4sh.dev/posts/2025/n8n-nodes-bee-ai-workflows/</guid>
      <description>&lt;h2 id=&#34;the-n8n-nodes-bee-ai-package&#34;&gt;The n8n-nodes-bee-ai Package&lt;/h2&gt;
&lt;p&gt;Blog Post: &lt;a href=&#34;../n8n-nodes-bee-ai&#34;&gt;Bee AI n8n node&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Github Repo: &lt;a href=&#34;https://github.com/AshDevFr/n8n-nodes-bee-ai&#34;&gt;AshDevFr/n8n-nodes-bee-ai&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;sub-workflows-to-fetch-them-all&#34;&gt;Sub Workflows to fetch them all&lt;/h2&gt;







  




  &lt;h3 id=&#34;bee-ai---fetch-all-conversations&#34;&gt;Bee AI - Fetch all Conversations&lt;/h3&gt;
&lt;p&gt;Note: the Conversation model is a nested object, so because of that, I added a code node to flatten the results.&lt;/p&gt;
&lt;p&gt;Conversation (GET /v1/{userId}/conversations/{id} response):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; class=&#34;chroma&#34;&gt;&lt;code class=&#34;language-json&#34; data-lang=&#34;json&#34;&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;nt&#34;&gt;&amp;#34;conversation&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;p&#34;&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;id&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;mi&#34;&gt;3456789&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;nt&#34;&gt;&amp;#34;summary&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;:&lt;/span&gt; &lt;span class=&#34;s2&#34;&gt;&amp;#34;...&amp;#34;&lt;/span&gt;&lt;span class=&#34;p&#34;&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;        &lt;span class=&#34;err&#34;&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;    &lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class=&#34;line&#34;&gt;&lt;span class=&#34;cl&#34;&gt;&lt;span class=&#34;p&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;n8n-demo workflow=&#39;{
  &amp;#34;nodes&amp;#34;: [
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;pagination&amp;#34;: {
          &amp;#34;page&amp;#34;: &amp;#34;={{ $json.page }}&amp;#34;,
          &amp;#34;limit&amp;#34;: 200
        },
        &amp;#34;requestOptions&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-bee-ai.beeai&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 1,
      &amp;#34;position&amp;#34;: [
        240,
        220
      ],
      &amp;#34;id&amp;#34;: &amp;#34;47739e54-dd38-4e34-ba87-e22fd999500f&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;List all conversations&amp;#34;,
      &amp;#34;credentials&amp;#34;: {
        &amp;#34;beeAIApi&amp;#34;: {
          &amp;#34;id&amp;#34;: &amp;#34;mOMKfymUx3xKGCvr&amp;#34;,
          &amp;#34;name&amp;#34;: &amp;#34;BeeAI account&amp;#34;
        }
      }
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;jsCode&amp;#34;: &amp;#34;// Loop over input items and add a new field called &amp;#39;myNewField&amp;#39; to the JSON of each one\nconst workflowStaticData = $getWorkflowStaticData(&amp;#39;global&amp;#39;);\n\nconst conversations = workflowStaticData.conversations || [];\n\nconversations.push(...$input.first().json.conversations);\n\nworkflowStaticData.conversations = conversations;\n\nreturn {conversations};&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.code&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2,
      &amp;#34;position&amp;#34;: [
        400,
        140
      ],
      &amp;#34;id&amp;#34;: &amp;#34;3c97a488-fd93-4aff-9e0d-801d9f35f7a2&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Merge Conversations&amp;#34;,
      &amp;#34;executeOnce&amp;#34;: true
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;jsCode&amp;#34;: &amp;#34;const workflowStaticData = $getWorkflowStaticData(&amp;#39;global&amp;#39;);\n\nreturn workflowStaticData.conversations;&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.code&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2,
      &amp;#34;position&amp;#34;: [
        720,
        40
      ],
      &amp;#34;id&amp;#34;: &amp;#34;dd321b6a-6476-45b0-861c-342417a7fb31&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Return All Conversations&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;content&amp;#34;: &amp;#34;## Conversations\nUsing a loop to go through paginated results&amp;#34;,
        &amp;#34;height&amp;#34;: 440,
        &amp;#34;width&amp;#34;: 1080,
        &amp;#34;color&amp;#34;: 4
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.stickyNote&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 1,
      &amp;#34;position&amp;#34;: [
        0,
        0
      ],
      &amp;#34;id&amp;#34;: &amp;#34;72c465e9-7f9a-4925-b301-8a52a6a5dbee&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Sticky Note&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;conditions&amp;#34;: {
          &amp;#34;options&amp;#34;: {
            &amp;#34;caseSensitive&amp;#34;: true,
            &amp;#34;leftValue&amp;#34;: &amp;#34;&amp;#34;,
            &amp;#34;typeValidation&amp;#34;: &amp;#34;strict&amp;#34;,
            &amp;#34;version&amp;#34;: 2
          },
          &amp;#34;conditions&amp;#34;: [
            {
              &amp;#34;id&amp;#34;: &amp;#34;7336889b-7509-459f-a81c-d5293a043e94&amp;#34;,
              &amp;#34;leftValue&amp;#34;: &amp;#34;={{ $(&amp;#39;List all conversations&amp;#39;).item.json.currentPage }}&amp;#34;,
              &amp;#34;rightValue&amp;#34;: &amp;#34;={{ $(&amp;#39;List all conversations&amp;#39;).item.json.totalPages }}&amp;#34;,
              &amp;#34;operator&amp;#34;: {
                &amp;#34;type&amp;#34;: &amp;#34;number&amp;#34;,
                &amp;#34;operation&amp;#34;: &amp;#34;equals&amp;#34;
              }
            }
          ],
          &amp;#34;combinator&amp;#34;: &amp;#34;and&amp;#34;
        },
        &amp;#34;options&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.if&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2.2,
      &amp;#34;position&amp;#34;: [
        560,
        140
      ],
      &amp;#34;id&amp;#34;: &amp;#34;f27df6bd-4963-43ef-9e92-b1e6cacf4978&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;If Final Conversations Page&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;assignments&amp;#34;: {
          &amp;#34;assignments&amp;#34;: [
            {
              &amp;#34;id&amp;#34;: &amp;#34;6dfc0e3c-8ae4-4fb7-921a-3ccd9aefa57a&amp;#34;,
              &amp;#34;name&amp;#34;: &amp;#34;page&amp;#34;,
              &amp;#34;value&amp;#34;: &amp;#34;1&amp;#34;,
              &amp;#34;type&amp;#34;: &amp;#34;string&amp;#34;
            }
          ]
        },
        &amp;#34;options&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.set&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 3.4,
      &amp;#34;position&amp;#34;: [
        60,
        220
      ],
      &amp;#34;id&amp;#34;: &amp;#34;90a38005-71b3-4af9-9d5c-dc33d955a7b1&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Set Page Conversations Number&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;assignments&amp;#34;: {
          &amp;#34;assignments&amp;#34;: [
            {
              &amp;#34;id&amp;#34;: &amp;#34;6dfc0e3c-8ae4-4fb7-921a-3ccd9aefa57a&amp;#34;,
              &amp;#34;name&amp;#34;: &amp;#34;page&amp;#34;,
              &amp;#34;value&amp;#34;: &amp;#34;={{ $(&amp;#39;List all conversations&amp;#39;).item.json.currentPage &amp;#43; 1 }}&amp;#34;,
              &amp;#34;type&amp;#34;: &amp;#34;number&amp;#34;
            }
          ]
        },
        &amp;#34;options&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.set&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 3.4,
      &amp;#34;position&amp;#34;: [
        720,
        220
      ],
      &amp;#34;id&amp;#34;: &amp;#34;6aca719c-72f6-45c5-939b-b7cfd61ac610&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Increase Conversations Page Number&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;operation&amp;#34;: &amp;#34;get&amp;#34;,
        &amp;#34;id&amp;#34;: &amp;#34;={{ $json.id }}&amp;#34;,
        &amp;#34;requestOptions&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-bee-ai.beeai&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 1,
      &amp;#34;position&amp;#34;: [
        920,
        40
      ],
      &amp;#34;id&amp;#34;: &amp;#34;0244adf9-9fdd-48b5-8180-3c562d5374e1&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Get a conversation by ID&amp;#34;,
      &amp;#34;credentials&amp;#34;: {
        &amp;#34;beeAIApi&amp;#34;: {
          &amp;#34;id&amp;#34;: &amp;#34;mOMKfymUx3xKGCvr&amp;#34;,
          &amp;#34;name&amp;#34;: &amp;#34;BeeAI account&amp;#34;
        }
      }
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;jsCode&amp;#34;: &amp;#34;// Loop over input items and add a new field called &amp;#39;myNewField&amp;#39; to the JSON of each one\nfor (const item of $input.all()) {\n  item.json.myNewField = 1;\n}\n\nreturn $input.all().map(item =&amp;gt; item.json.conversation);&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.code&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2,
      &amp;#34;position&amp;#34;: [
        920,
        240
      ],
      &amp;#34;id&amp;#34;: &amp;#34;4cad4929-ed10-4e94-a882-dcb32bbc6b89&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Flatten Conversations&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;inputSource&amp;#34;: &amp;#34;passthrough&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.executeWorkflowTrigger&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 1.1,
      &amp;#34;position&amp;#34;: [
        -320,
        220
      ],
      &amp;#34;id&amp;#34;: &amp;#34;ff4a0ae5-8983-41be-8d6c-981e1231f58e&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;When Executed by Another Workflow&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;jsCode&amp;#34;: &amp;#34;const workflowStaticData = $getWorkflowStaticData(&amp;#39;global&amp;#39;);\nworkflowStaticData.conversations = [];\nreturn $input.all();&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.code&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2,
      &amp;#34;position&amp;#34;: [
        -140,
        220
      ],
      &amp;#34;id&amp;#34;: &amp;#34;5c1753cd-e3b2-44e2-b672-6b5de6db8eca&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Reset Global variable&amp;#34;
    }
  ],
  &amp;#34;connections&amp;#34;: {
    &amp;#34;List all conversations&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Merge Conversations&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Merge Conversations&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;If Final Conversations Page&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Return All Conversations&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Get a conversation by ID&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;If Final Conversations Page&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Return All Conversations&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ],
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Increase Conversations Page Number&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Set Page Conversations Number&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;List all conversations&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Increase Conversations Page Number&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;List all conversations&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Get a conversation by ID&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Flatten Conversations&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;When Executed by Another Workflow&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Reset Global variable&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Reset Global variable&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Set Page Conversations Number&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    }
  },
  &amp;#34;pinData&amp;#34;: {},
  &amp;#34;meta&amp;#34;: {
    &amp;#34;instanceId&amp;#34;: &amp;#34;8bc1c2d2c1dce278cdfe696155aa34f0a2de517c041fd1624c10504d76351bb8&amp;#34;
  }
}&#39; frame=true&gt;&lt;/n8n-demo&gt;












  




  &lt;h3 id=&#34;bee-ai---fetch-all-facts&#34;&gt;Bee AI - Fetch all Facts&lt;/h3&gt;
&lt;n8n-demo workflow=&#39;{
  &amp;#34;nodes&amp;#34;: [
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;inputSource&amp;#34;: &amp;#34;passthrough&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.executeWorkflowTrigger&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 1.1,
      &amp;#34;position&amp;#34;: [
        -320,
        220
      ],
      &amp;#34;id&amp;#34;: &amp;#34;9e3c34c7-d0c1-4a0f-9449-33239fed6b6a&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;When Executed by Another Workflow&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;jsCode&amp;#34;: &amp;#34;const workflowStaticData = $getWorkflowStaticData(&amp;#39;global&amp;#39;);\nworkflowStaticData.facts = [];\nreturn $input.all();&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.code&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2,
      &amp;#34;position&amp;#34;: [
        -140,
        220
      ],
      &amp;#34;id&amp;#34;: &amp;#34;e9d0b680-0785-4806-8966-cd8ad97d8406&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Reset Global variable&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;content&amp;#34;: &amp;#34;## Facts\nUsing a loop to go through paginated results&amp;#34;,
        &amp;#34;height&amp;#34;: 440,
        &amp;#34;width&amp;#34;: 1040,
        &amp;#34;color&amp;#34;: 5
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.stickyNote&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 1,
      &amp;#34;position&amp;#34;: [
        0,
        0
      ],
      &amp;#34;id&amp;#34;: &amp;#34;becddbbc-c028-495e-9d65-dabb35fb6cce&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Sticky Note1&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;jsCode&amp;#34;: &amp;#34;// Loop over input items and add a new field called &amp;#39;myNewField&amp;#39; to the JSON of each one\nconst workflowStaticData = $getWorkflowStaticData(&amp;#39;global&amp;#39;);\n\nconst facts = workflowStaticData.facts || [];\n\nfacts.push(...$input.first().json.facts);\n\nworkflowStaticData.facts = facts;\n\nreturn {facts};&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.code&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2,
      &amp;#34;position&amp;#34;: [
        420,
        140
      ],
      &amp;#34;id&amp;#34;: &amp;#34;456715c8-93f0-41bc-80a0-4a24694bc7ef&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Merge Facts&amp;#34;,
      &amp;#34;executeOnce&amp;#34;: true
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;assignments&amp;#34;: {
          &amp;#34;assignments&amp;#34;: [
            {
              &amp;#34;id&amp;#34;: &amp;#34;6dfc0e3c-8ae4-4fb7-921a-3ccd9aefa57a&amp;#34;,
              &amp;#34;name&amp;#34;: &amp;#34;page&amp;#34;,
              &amp;#34;value&amp;#34;: &amp;#34;={{ $(&amp;#39;List all facts&amp;#39;).item.json.currentPage &amp;#43; 1 }}&amp;#34;,
              &amp;#34;type&amp;#34;: &amp;#34;number&amp;#34;
            }
          ]
        },
        &amp;#34;options&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.set&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 3.4,
      &amp;#34;position&amp;#34;: [
        740,
        220
      ],
      &amp;#34;id&amp;#34;: &amp;#34;f89c1d43-0beb-404f-a3c2-aaa32b8336d1&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Increase Facts Page Number&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;assignments&amp;#34;: {
          &amp;#34;assignments&amp;#34;: [
            {
              &amp;#34;id&amp;#34;: &amp;#34;6dfc0e3c-8ae4-4fb7-921a-3ccd9aefa57a&amp;#34;,
              &amp;#34;name&amp;#34;: &amp;#34;page&amp;#34;,
              &amp;#34;value&amp;#34;: &amp;#34;1&amp;#34;,
              &amp;#34;type&amp;#34;: &amp;#34;string&amp;#34;
            }
          ]
        },
        &amp;#34;options&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.set&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 3.4,
      &amp;#34;position&amp;#34;: [
        60,
        220
      ],
      &amp;#34;id&amp;#34;: &amp;#34;6206b67a-a039-4513-a87c-942e70928d69&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Set Facts Page Number&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;jsCode&amp;#34;: &amp;#34;const workflowStaticData = $getWorkflowStaticData(&amp;#39;global&amp;#39;);\n\nreturn workflowStaticData.facts;&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.code&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2,
      &amp;#34;position&amp;#34;: [
        740,
        40
      ],
      &amp;#34;id&amp;#34;: &amp;#34;d66ad9db-c701-4cca-ab82-665549877541&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Return All Facts&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;conditions&amp;#34;: {
          &amp;#34;options&amp;#34;: {
            &amp;#34;caseSensitive&amp;#34;: true,
            &amp;#34;leftValue&amp;#34;: &amp;#34;&amp;#34;,
            &amp;#34;typeValidation&amp;#34;: &amp;#34;strict&amp;#34;,
            &amp;#34;version&amp;#34;: 2
          },
          &amp;#34;conditions&amp;#34;: [
            {
              &amp;#34;id&amp;#34;: &amp;#34;7336889b-7509-459f-a81c-d5293a043e94&amp;#34;,
              &amp;#34;leftValue&amp;#34;: &amp;#34;={{ $(&amp;#39;List all facts&amp;#39;).item.json.currentPage }}&amp;#34;,
              &amp;#34;rightValue&amp;#34;: &amp;#34;={{ $(&amp;#39;List all facts&amp;#39;).item.json.totalPages }}&amp;#34;,
              &amp;#34;operator&amp;#34;: {
                &amp;#34;type&amp;#34;: &amp;#34;number&amp;#34;,
                &amp;#34;operation&amp;#34;: &amp;#34;equals&amp;#34;
              }
            }
          ],
          &amp;#34;combinator&amp;#34;: &amp;#34;and&amp;#34;
        },
        &amp;#34;options&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.if&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2.2,
      &amp;#34;position&amp;#34;: [
        580,
        140
      ],
      &amp;#34;id&amp;#34;: &amp;#34;f7d4acf9-8989-4879-b82b-3a44a141fa6c&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;If Final Facts Page&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;resource&amp;#34;: &amp;#34;facts&amp;#34;,
        &amp;#34;filter&amp;#34;: {},
        &amp;#34;pagination&amp;#34;: {
          &amp;#34;page&amp;#34;: &amp;#34;={{ $json.page }}&amp;#34;,
          &amp;#34;limit&amp;#34;: 200
        },
        &amp;#34;requestOptions&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-bee-ai.beeai&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 1,
      &amp;#34;position&amp;#34;: [
        240,
        220
      ],
      &amp;#34;id&amp;#34;: &amp;#34;bbb7ed8b-5c25-41a1-914f-2bca85c4dc52&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;List all facts&amp;#34;,
      &amp;#34;credentials&amp;#34;: {
        &amp;#34;beeAIApi&amp;#34;: {
          &amp;#34;id&amp;#34;: &amp;#34;mOMKfymUx3xKGCvr&amp;#34;,
          &amp;#34;name&amp;#34;: &amp;#34;BeeAI account&amp;#34;
        }
      }
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;resource&amp;#34;: &amp;#34;facts&amp;#34;,
        &amp;#34;operation&amp;#34;: &amp;#34;get&amp;#34;,
        &amp;#34;id&amp;#34;: &amp;#34;={{ $json.id }}&amp;#34;,
        &amp;#34;requestOptions&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-bee-ai.beeai&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 1,
      &amp;#34;position&amp;#34;: [
        900,
        40
      ],
      &amp;#34;id&amp;#34;: &amp;#34;98ee9df1-f68b-4edf-bd17-1d92fa3c5d65&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Get a fact by ID&amp;#34;,
      &amp;#34;credentials&amp;#34;: {
        &amp;#34;beeAIApi&amp;#34;: {
          &amp;#34;id&amp;#34;: &amp;#34;mOMKfymUx3xKGCvr&amp;#34;,
          &amp;#34;name&amp;#34;: &amp;#34;BeeAI account&amp;#34;
        }
      }
    }
  ],
  &amp;#34;connections&amp;#34;: {
    &amp;#34;When Executed by Another Workflow&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Reset Global variable&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Reset Global variable&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Set Facts Page Number&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Merge Facts&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;If Final Facts Page&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Increase Facts Page Number&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;List all facts&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Set Facts Page Number&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;List all facts&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Return All Facts&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Get a fact by ID&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;If Final Facts Page&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Return All Facts&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ],
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Increase Facts Page Number&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;List all facts&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Merge Facts&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    }
  },
  &amp;#34;pinData&amp;#34;: {},
  &amp;#34;meta&amp;#34;: {
    &amp;#34;instanceId&amp;#34;: &amp;#34;8bc1c2d2c1dce278cdfe696155aa34f0a2de517c041fd1624c10504d76351bb8&amp;#34;
  }
}&#39; frame=true&gt;&lt;/n8n-demo&gt;












  




  &lt;h3 id=&#34;bee-ai---fetch-all-todos&#34;&gt;Bee AI - Fetch all Todos&lt;/h3&gt;
&lt;n8n-demo workflow=&#39;{
  &amp;#34;nodes&amp;#34;: [
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;inputSource&amp;#34;: &amp;#34;passthrough&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.executeWorkflowTrigger&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 1.1,
      &amp;#34;position&amp;#34;: [
        -320,
        240
      ],
      &amp;#34;id&amp;#34;: &amp;#34;83398aa6-5779-4182-8be0-a4822e9b8724&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;When Executed by Another Workflow&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;jsCode&amp;#34;: &amp;#34;const workflowStaticData = $getWorkflowStaticData(&amp;#39;global&amp;#39;);\nworkflowStaticData.todos = [];\nreturn $input.all();&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.code&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2,
      &amp;#34;position&amp;#34;: [
        -140,
        240
      ],
      &amp;#34;id&amp;#34;: &amp;#34;8b654d4c-d6b0-4535-a295-ae2c662653df&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Reset Global variable&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;content&amp;#34;: &amp;#34;## Todos\nUsing a loop to go through paginated results&amp;#34;,
        &amp;#34;height&amp;#34;: 440,
        &amp;#34;width&amp;#34;: 1020,
        &amp;#34;color&amp;#34;: 6
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.stickyNote&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 1,
      &amp;#34;position&amp;#34;: [
        20,
        20
      ],
      &amp;#34;id&amp;#34;: &amp;#34;27500599-de26-4d1e-bd1e-6447c9f2822e&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Sticky Note2&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;assignments&amp;#34;: {
          &amp;#34;assignments&amp;#34;: [
            {
              &amp;#34;id&amp;#34;: &amp;#34;6dfc0e3c-8ae4-4fb7-921a-3ccd9aefa57a&amp;#34;,
              &amp;#34;name&amp;#34;: &amp;#34;page&amp;#34;,
              &amp;#34;value&amp;#34;: &amp;#34;1&amp;#34;,
              &amp;#34;type&amp;#34;: &amp;#34;string&amp;#34;
            }
          ]
        },
        &amp;#34;options&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.set&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 3.4,
      &amp;#34;position&amp;#34;: [
        60,
        240
      ],
      &amp;#34;id&amp;#34;: &amp;#34;d5e189ef-5eba-4a77-8386-26335a9c714f&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Set Page Todos Number&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;resource&amp;#34;: &amp;#34;todos&amp;#34;,
        &amp;#34;pagination&amp;#34;: {
          &amp;#34;page&amp;#34;: &amp;#34;={{ $json.page }}&amp;#34;,
          &amp;#34;limit&amp;#34;: 200
        },
        &amp;#34;requestOptions&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-bee-ai.beeai&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 1,
      &amp;#34;position&amp;#34;: [
        240,
        240
      ],
      &amp;#34;id&amp;#34;: &amp;#34;467b3712-357f-4f39-bca1-0ca51be70062&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;List all todos&amp;#34;,
      &amp;#34;credentials&amp;#34;: {
        &amp;#34;beeAIApi&amp;#34;: {
          &amp;#34;id&amp;#34;: &amp;#34;mOMKfymUx3xKGCvr&amp;#34;,
          &amp;#34;name&amp;#34;: &amp;#34;BeeAI account&amp;#34;
        }
      }
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;jsCode&amp;#34;: &amp;#34;// Loop over input items and add a new field called &amp;#39;myNewField&amp;#39; to the JSON of each one\nconst workflowStaticData = $getWorkflowStaticData(&amp;#39;global&amp;#39;);\n\nconst todos = workflowStaticData.todos || [];\n\ntodos.push(...$input.first().json.todos);\n\nworkflowStaticData.todos = todos;\n\nreturn {todos};&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.code&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2,
      &amp;#34;position&amp;#34;: [
        420,
        160
      ],
      &amp;#34;id&amp;#34;: &amp;#34;fc42852f-fc1d-4a43-afdb-b2d917959f33&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Merge Todos&amp;#34;,
      &amp;#34;executeOnce&amp;#34;: true
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;conditions&amp;#34;: {
          &amp;#34;options&amp;#34;: {
            &amp;#34;caseSensitive&amp;#34;: true,
            &amp;#34;leftValue&amp;#34;: &amp;#34;&amp;#34;,
            &amp;#34;typeValidation&amp;#34;: &amp;#34;strict&amp;#34;,
            &amp;#34;version&amp;#34;: 2
          },
          &amp;#34;conditions&amp;#34;: [
            {
              &amp;#34;id&amp;#34;: &amp;#34;7336889b-7509-459f-a81c-d5293a043e94&amp;#34;,
              &amp;#34;leftValue&amp;#34;: &amp;#34;={{ $(&amp;#39;List all todos&amp;#39;).item.json.currentPage }}&amp;#34;,
              &amp;#34;rightValue&amp;#34;: &amp;#34;={{ $(&amp;#39;List all todos&amp;#39;).item.json.totalPages }}&amp;#34;,
              &amp;#34;operator&amp;#34;: {
                &amp;#34;type&amp;#34;: &amp;#34;number&amp;#34;,
                &amp;#34;operation&amp;#34;: &amp;#34;equals&amp;#34;
              }
            }
          ],
          &amp;#34;combinator&amp;#34;: &amp;#34;and&amp;#34;
        },
        &amp;#34;options&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.if&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2.2,
      &amp;#34;position&amp;#34;: [
        580,
        160
      ],
      &amp;#34;id&amp;#34;: &amp;#34;5c053d74-4685-4c96-9321-c37876a72026&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;If Final Todos Page&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;assignments&amp;#34;: {
          &amp;#34;assignments&amp;#34;: [
            {
              &amp;#34;id&amp;#34;: &amp;#34;6dfc0e3c-8ae4-4fb7-921a-3ccd9aefa57a&amp;#34;,
              &amp;#34;name&amp;#34;: &amp;#34;page&amp;#34;,
              &amp;#34;value&amp;#34;: &amp;#34;={{ $(&amp;#39;List all todos&amp;#39;).item.json.currentPage &amp;#43; 1 }}&amp;#34;,
              &amp;#34;type&amp;#34;: &amp;#34;number&amp;#34;
            }
          ]
        },
        &amp;#34;options&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.set&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 3.4,
      &amp;#34;position&amp;#34;: [
        740,
        240
      ],
      &amp;#34;id&amp;#34;: &amp;#34;da3ce2cc-5a53-4671-ad5b-78d916ad2c1b&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Increase Todos Page Number&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;jsCode&amp;#34;: &amp;#34;const workflowStaticData = $getWorkflowStaticData(&amp;#39;global&amp;#39;);\n\nreturn workflowStaticData.todos;&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.code&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2,
      &amp;#34;position&amp;#34;: [
        740,
        60
      ],
      &amp;#34;id&amp;#34;: &amp;#34;a25dab1f-2c14-45d5-a607-019c3bf26ee9&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Return All Todos&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;resource&amp;#34;: &amp;#34;todos&amp;#34;,
        &amp;#34;operation&amp;#34;: &amp;#34;get&amp;#34;,
        &amp;#34;id&amp;#34;: &amp;#34;={{ $json.id }}&amp;#34;,
        &amp;#34;requestOptions&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-bee-ai.beeai&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 1,
      &amp;#34;position&amp;#34;: [
        900,
        60
      ],
      &amp;#34;id&amp;#34;: &amp;#34;787ff6ce-6bf3-4ee3-a575-49a4940ceb4f&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Get a todo by ID&amp;#34;,
      &amp;#34;credentials&amp;#34;: {
        &amp;#34;beeAIApi&amp;#34;: {
          &amp;#34;id&amp;#34;: &amp;#34;mOMKfymUx3xKGCvr&amp;#34;,
          &amp;#34;name&amp;#34;: &amp;#34;BeeAI account&amp;#34;
        }
      }
    }
  ],
  &amp;#34;connections&amp;#34;: {
    &amp;#34;When Executed by Another Workflow&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Reset Global variable&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Reset Global variable&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Set Page Todos Number&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Set Page Todos Number&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;List all todos&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;List all todos&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Merge Todos&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Merge Todos&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;If Final Todos Page&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;If Final Todos Page&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Return All Todos&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ],
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Increase Todos Page Number&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Increase Todos Page Number&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;List all todos&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Return All Todos&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Get a todo by ID&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    }
  },
  &amp;#34;pinData&amp;#34;: {},
  &amp;#34;meta&amp;#34;: {
    &amp;#34;instanceId&amp;#34;: &amp;#34;8bc1c2d2c1dce278cdfe696155aa34f0a2de517c041fd1624c10504d76351bb8&amp;#34;
  }
}&#39; frame=true&gt;&lt;/n8n-demo&gt;












  




  &lt;h3 id=&#34;bee-ai---fetch-all-locations&#34;&gt;Bee AI - Fetch all Locations&lt;/h3&gt;
&lt;n8n-demo workflow=&#39;{
  &amp;#34;nodes&amp;#34;: [
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;inputSource&amp;#34;: &amp;#34;passthrough&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.executeWorkflowTrigger&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 1.1,
      &amp;#34;position&amp;#34;: [
        -320,
        220
      ],
      &amp;#34;id&amp;#34;: &amp;#34;d57099c7-8b5a-4a72-b2f4-cd91b3462e3a&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;When Executed by Another Workflow&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;jsCode&amp;#34;: &amp;#34;const workflowStaticData = $getWorkflowStaticData(&amp;#39;global&amp;#39;);\nworkflowStaticData.locations = [];\nreturn $input.all();&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.code&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2,
      &amp;#34;position&amp;#34;: [
        -140,
        220
      ],
      &amp;#34;id&amp;#34;: &amp;#34;dd312c94-2649-4616-9326-24276d1cbd50&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Reset Global variable&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;content&amp;#34;: &amp;#34;## Locations\nUsing a loop to go through paginated results&amp;#34;,
        &amp;#34;height&amp;#34;: 440,
        &amp;#34;width&amp;#34;: 900,
        &amp;#34;color&amp;#34;: 5
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.stickyNote&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 1,
      &amp;#34;position&amp;#34;: [
        0,
        0
      ],
      &amp;#34;id&amp;#34;: &amp;#34;bb9c651c-d2b3-4f37-8999-c538fc9bf346&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Sticky Note3&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;assignments&amp;#34;: {
          &amp;#34;assignments&amp;#34;: [
            {
              &amp;#34;id&amp;#34;: &amp;#34;6dfc0e3c-8ae4-4fb7-921a-3ccd9aefa57a&amp;#34;,
              &amp;#34;name&amp;#34;: &amp;#34;page&amp;#34;,
              &amp;#34;value&amp;#34;: &amp;#34;1&amp;#34;,
              &amp;#34;type&amp;#34;: &amp;#34;string&amp;#34;
            }
          ]
        },
        &amp;#34;options&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.set&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 3.4,
      &amp;#34;position&amp;#34;: [
        60,
        220
      ],
      &amp;#34;id&amp;#34;: &amp;#34;966893ee-5f58-4ee7-8595-f3e9fee1d5eb&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Set Locations Page Number&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;resource&amp;#34;: &amp;#34;locations&amp;#34;,
        &amp;#34;pagination&amp;#34;: {
          &amp;#34;page&amp;#34;: &amp;#34;={{ $json.page }}&amp;#34;,
          &amp;#34;limit&amp;#34;: 200
        },
        &amp;#34;requestOptions&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-bee-ai.beeai&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 1,
      &amp;#34;position&amp;#34;: [
        240,
        220
      ],
      &amp;#34;id&amp;#34;: &amp;#34;48749a52-7ce0-4879-9e44-93f43dc5ceb9&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;List all locations&amp;#34;,
      &amp;#34;credentials&amp;#34;: {
        &amp;#34;beeAIApi&amp;#34;: {
          &amp;#34;id&amp;#34;: &amp;#34;mOMKfymUx3xKGCvr&amp;#34;,
          &amp;#34;name&amp;#34;: &amp;#34;BeeAI account&amp;#34;
        }
      }
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;jsCode&amp;#34;: &amp;#34;// Loop over input items and add a new field called &amp;#39;myNewField&amp;#39; to the JSON of each one\nconst workflowStaticData = $getWorkflowStaticData(&amp;#39;global&amp;#39;);\n\nconst locations = workflowStaticData.locations || [];\n\nlocations.push(...$input.first().json.locations);\n\nworkflowStaticData.locations = locations;\n\nreturn {locations};&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.code&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2,
      &amp;#34;position&amp;#34;: [
        420,
        140
      ],
      &amp;#34;id&amp;#34;: &amp;#34;e91664cc-b477-4140-807b-dbfe11beb6bc&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Merge Locations&amp;#34;,
      &amp;#34;executeOnce&amp;#34;: true
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;conditions&amp;#34;: {
          &amp;#34;options&amp;#34;: {
            &amp;#34;caseSensitive&amp;#34;: true,
            &amp;#34;leftValue&amp;#34;: &amp;#34;&amp;#34;,
            &amp;#34;typeValidation&amp;#34;: &amp;#34;strict&amp;#34;,
            &amp;#34;version&amp;#34;: 2
          },
          &amp;#34;conditions&amp;#34;: [
            {
              &amp;#34;id&amp;#34;: &amp;#34;7336889b-7509-459f-a81c-d5293a043e94&amp;#34;,
              &amp;#34;leftValue&amp;#34;: &amp;#34;={{ $(&amp;#39;List all locations&amp;#39;).item.json.currentPage }}&amp;#34;,
              &amp;#34;rightValue&amp;#34;: &amp;#34;={{ $(&amp;#39;List all locations&amp;#39;).item.json.totalPages }}&amp;#34;,
              &amp;#34;operator&amp;#34;: {
                &amp;#34;type&amp;#34;: &amp;#34;number&amp;#34;,
                &amp;#34;operation&amp;#34;: &amp;#34;equals&amp;#34;
              }
            }
          ],
          &amp;#34;combinator&amp;#34;: &amp;#34;and&amp;#34;
        },
        &amp;#34;options&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.if&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2.2,
      &amp;#34;position&amp;#34;: [
        580,
        140
      ],
      &amp;#34;id&amp;#34;: &amp;#34;81fe06dc-4ca0-4453-a5e2-a64610625473&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;If Final Locations Page&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;assignments&amp;#34;: {
          &amp;#34;assignments&amp;#34;: [
            {
              &amp;#34;id&amp;#34;: &amp;#34;6dfc0e3c-8ae4-4fb7-921a-3ccd9aefa57a&amp;#34;,
              &amp;#34;name&amp;#34;: &amp;#34;page&amp;#34;,
              &amp;#34;value&amp;#34;: &amp;#34;={{ $(&amp;#39;List all locations&amp;#39;).item.json.currentPage &amp;#43; 1 }}&amp;#34;,
              &amp;#34;type&amp;#34;: &amp;#34;number&amp;#34;
            }
          ]
        },
        &amp;#34;options&amp;#34;: {}
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.set&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 3.4,
      &amp;#34;position&amp;#34;: [
        740,
        220
      ],
      &amp;#34;id&amp;#34;: &amp;#34;6373f5ae-2c58-47c3-98aa-d46abcc6566f&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Increase Locations Page Number&amp;#34;
    },
    {
      &amp;#34;parameters&amp;#34;: {
        &amp;#34;jsCode&amp;#34;: &amp;#34;const workflowStaticData = $getWorkflowStaticData(&amp;#39;global&amp;#39;);\n\nreturn workflowStaticData.locations;&amp;#34;
      },
      &amp;#34;type&amp;#34;: &amp;#34;n8n-nodes-base.code&amp;#34;,
      &amp;#34;typeVersion&amp;#34;: 2,
      &amp;#34;position&amp;#34;: [
        740,
        40
      ],
      &amp;#34;id&amp;#34;: &amp;#34;888ec972-a94b-4d9f-8332-7fc535d04932&amp;#34;,
      &amp;#34;name&amp;#34;: &amp;#34;Return All Locations&amp;#34;
    }
  ],
  &amp;#34;connections&amp;#34;: {
    &amp;#34;When Executed by Another Workflow&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Reset Global variable&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Reset Global variable&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Set Locations Page Number&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Set Locations Page Number&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;List all locations&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;List all locations&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Merge Locations&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Merge Locations&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;If Final Locations Page&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;If Final Locations Page&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Return All Locations&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ],
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;Increase Locations Page Number&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    },
    &amp;#34;Increase Locations Page Number&amp;#34;: {
      &amp;#34;main&amp;#34;: [
        [
          {
            &amp;#34;node&amp;#34;: &amp;#34;List all locations&amp;#34;,
            &amp;#34;type&amp;#34;: &amp;#34;main&amp;#34;,
            &amp;#34;index&amp;#34;: 0
          }
        ]
      ]
    }
  },
  &amp;#34;pinData&amp;#34;: {},
  &amp;#34;meta&amp;#34;: {
    &amp;#34;templateCredsSetupCompleted&amp;#34;: true,
    &amp;#34;instanceId&amp;#34;: &amp;#34;8bc1c2d2c1dce278cdfe696155aa34f0a2de517c041fd1624c10504d76351bb8&amp;#34;
  }
}&#39; frame=true&gt;&lt;/n8n-demo&gt;





&lt;h2 id=&#34;workflows&#34;&gt;Workflows&lt;/h2&gt;







  




  &lt;h3 id=&#34;bee-ai---backup-v2&#34;&gt;Bee AI - Backup v2&lt;/h3&gt;
&lt;p&gt;Uses the &lt;code&gt;Fetch all x&lt;/code&gt; workflows to get all the data, then insert it into a MongoDB database anf a json file in Google Drive.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Bee AI n8n nodes</title>
      <link>https://4sh.dev/posts/2025/n8n-nodes-bee-ai/</link>
      <pubDate>Wed, 25 Jun 2025 00:00:00 +0000</pubDate>
      <guid>https://4sh.dev/posts/2025/n8n-nodes-bee-ai/</guid>
      <description>&lt;p&gt;I recently developed a custom n8n node package that connects Bee AI with the n8n workflow automation platform, opening up new possibilities for automating personal AI data.&lt;/p&gt;
&lt;h2 id=&#34;what-is-bee-ai&#34;&gt;What is Bee AI?&lt;/h2&gt;
&lt;p&gt;Bee AI is a wearable personal AI device that sits quietly in the background, capturing and processing your daily interactions. Unlike traditional smart assistants that require explicit activation, Bee continuously learns from your conversations, tasks, and locations, transforming these moments into actionable insights, summaries, and reminders.&lt;/p&gt;</description>
    </item>
    <item>
      <title>RAG Agents with LangChain and LangGraph</title>
      <link>https://4sh.dev/posts/2024/an-opinionated-rag-agent/</link>
      <pubDate>Mon, 28 Oct 2024 00:00:00 +0000</pubDate>
      <guid>https://4sh.dev/posts/2024/an-opinionated-rag-agent/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://arxiv.org/abs/2310.11511&#34;&gt;Self-RAG&lt;/a&gt; (Self-Reflective Retrieval-Augmented Generation) is a framework that
combines the benefits of
retrieval-augmented generation (RAG) with self-reflection, allowing large language models (LLMs) to adaptively retrieve
passages on-demand and generate more accurate responses.&lt;/p&gt;
&lt;p&gt;Langgraph recently published
a &lt;a href=&#34;https://langchain-ai.github.io/langgraph/tutorials/rag/langgraph_self_rag_local/&#34;&gt;blog post&lt;/a&gt; on &lt;em&gt;Self-RAG&lt;/em&gt; with their
own implementation.&lt;/p&gt;
&lt;p&gt;I really like the idea of validating the retrieved information. In that past I have noticed that, while vector databases
will return documents that usually match the input query string, some may contain irrelevant content.
Having the ability to validate and correct this is a great feature for any RAG setup.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Adventures in Greenhaven</title>
      <link>https://4sh.dev/posts/2024/adventures-in-greenhaven/</link>
      <pubDate>Wed, 23 Oct 2024 00:00:00 +0000</pubDate>
      <guid>https://4sh.dev/posts/2024/adventures-in-greenhaven/</guid>
      <description>&lt;p&gt;I recently published my first tabletop role-playing game (TTRPG) designed specifically for young hearts, Adventures in
Greenhaven.&lt;/p&gt;
&lt;p&gt;This project matters to me because I want to make tabletop gaming accessible and enjoyable for kids.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve always been passionate about sharing the magic of D&amp;amp;D with others, but as my children grew older, I realized that
traditional D&amp;amp;D wasn&amp;rsquo;t quite suitable for them yet. So, I decided to create a game that captures the essence of D&amp;amp;D, but
with simpler rules, more accessible storytelling, and a focus on fun and adventure.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Game Dev - Unity</title>
      <link>https://4sh.dev/posts/_old-blog/game-dev-unity/</link>
      <pubDate>Thu, 02 Sep 2021 05:47:35 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/game-dev-unity/</guid>
      <description>&lt;p&gt;After spending years trying to build mini D&amp;amp;D games using JS, Elm, Elixir, etc&amp;hellip; I decided to give a shot to Unity.&lt;/p&gt;
&lt;h2 id=&#34;dungeon-generator&#34;&gt;Dungeon generator&lt;/h2&gt;
&lt;p&gt;I decided to jump right away into Unity and build a procedural dungeon generator from scratch.&lt;/p&gt;
&lt;p&gt;&lt;img loading=&#34;lazy&#34; src=&#34;https://4sh.dev/posts/_old-blog/game-dev-unity/Screen-Shot-2021-09-01-at-11.16.32-PM.png&#34;&gt;
&lt;img loading=&#34;lazy&#34; src=&#34;https://4sh.dev/posts/_old-blog/game-dev-unity/Screen-Shot-2021-09-01-at-11.16.41-PM.png&#34;&gt;
&lt;img loading=&#34;lazy&#34; src=&#34;https://4sh.dev/posts/_old-blog/game-dev-unity/Screen-Shot-2021-09-01-at-11.17.33-PM.png&#34;&gt;&lt;/p&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
    &lt;a class=&#34;shortcode-youtube&#34; href=&#34;https://www.youtube.com/watch?v=k6xC7YY7mHE&#34; title=&#34;Play Youtube video&#34; target=&#34;_blank&#34;&gt;
        &lt;img
            width=&#34;600&#34;
            height=&#34;339&#34;
            src=&#34;https://i.ytimg.com/vi/k6xC7YY7mHE/hqdefault.jpg&#34;
            alt=&#34;Youtube video k6xC7YY7mHE&#34;
        /&gt;
&lt;/a&gt;
&lt;/div&gt;

&lt;style&gt;
    .shortcode-youtube {
        position: relative; display: inline-block;
    }
    .shortcode-youtube::before, .shortcode-youtube::after {
        content: &#34;&#34;;
        width: 100%;
        height: 100%;
        position: absolute;
        top: 0;
        left: 0;
    }
    .shortcode-youtube::before {
        background: url(&#34;/images/youtube_button.svg&#34;) center center / auto 4rem no-repeat;
    }
    .shortcode-youtube:hover::before {
        background: url(&#34;/images/youtube_button_hover.svg&#34;) center center / auto 4rem no-repeat;
    }
    .shortcode-youtube::after {
        background: url(&#34;/images/youtube.svg&#34;) calc(100% - 1rem) calc(100% - 1rem) / auto 2rem no-repeat;
    }
    .shortcode-youtube img {
        display: block;
    }
&lt;/style&gt;

&lt;p&gt;As expected the result was not great (pretty ugly let&amp;rsquo;s be honest). It&amp;rsquo;s not that C# is difficult, but you have to learn a new tool (Unity) which comes with a lot of new concepts and options that if you don&amp;rsquo;t know makes your task more complex.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Encounters v0.3.0 (Alpha) - Dynamic lightning is coming</title>
      <link>https://4sh.dev/posts/_old-blog/encounters-v0-3-0-alpha-dynamic-lightning-is-coming/</link>
      <pubDate>Sat, 16 May 2020 22:43:29 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/encounters-v0-3-0-alpha-dynamic-lightning-is-coming/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s been few weeks since my last update. I have been quite busy working on a lot of interesting stuff. Some related to this project, some a bit less.&lt;/p&gt;
&lt;p&gt;Here is a preview of the Dynamic lightning I have been working on. It&amp;rsquo;s not live for now since it needs a lot of small adjustments before being 100% usable.&lt;/p&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
    &lt;a class=&#34;shortcode-youtube&#34; href=&#34;https://www.youtube.com/watch?v=b2GbM7xtfUI&#34; title=&#34;Play Youtube video&#34; target=&#34;_blank&#34;&gt;
        &lt;img
            width=&#34;560&#34;
            height=&#34;315&#34;
            src=&#34;https://i.ytimg.com/vi/b2GbM7xtfUI/hqdefault.jpg&#34;
            alt=&#34;Youtube video b2GbM7xtfUI&#34;
        /&gt;
&lt;/a&gt;
&lt;/div&gt;

&lt;style&gt;
    .shortcode-youtube {
        position: relative; display: inline-block;
    }
    .shortcode-youtube::before, .shortcode-youtube::after {
        content: &#34;&#34;;
        width: 100%;
        height: 100%;
        position: absolute;
        top: 0;
        left: 0;
    }
    .shortcode-youtube::before {
        background: url(&#34;/images/youtube_button.svg&#34;) center center / auto 4rem no-repeat;
    }
    .shortcode-youtube:hover::before {
        background: url(&#34;/images/youtube_button_hover.svg&#34;) center center / auto 4rem no-repeat;
    }
    .shortcode-youtube::after {
        background: url(&#34;/images/youtube.svg&#34;) calc(100% - 1rem) calc(100% - 1rem) / auto 2rem no-repeat;
    }
    .shortcode-youtube img {
        display: block;
    }
&lt;/style&gt;</description>
    </item>
    <item>
      <title>From Kubernetes to Gitlab-ci in less than 10min</title>
      <link>https://4sh.dev/posts/_old-blog/from-kubernetes-to-gitlab-ci-in-less-than-10min/</link>
      <pubDate>Sat, 16 May 2020 22:32:04 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/from-kubernetes-to-gitlab-ci-in-less-than-10min/</guid>
      <description>&lt;p&gt;I have been playing a lot with Kubernetes lately, from creating a cluster from scratch on bare metal, setting up a ELK stack, Prometheus metrics to setting up a CI/CD using Gitlab CI.&lt;/p&gt;
&lt;p&gt;I found the last one so easy that I made a video for it.&lt;/p&gt;
&lt;p&gt;I have been using a DigitalOcean Kubernetes cluster for this video, it was super easy and I got $100 to play with it for 60 days.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Encounters v0.2.0 (Alpha)</title>
      <link>https://4sh.dev/posts/_old-blog/encounters-v0-2-0-alpha/</link>
      <pubDate>Sun, 26 Apr 2020 05:43:33 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/encounters-v0-2-0-alpha/</guid>
      <description>&lt;p&gt;Ok now it&amp;rsquo;s getting a bit more serious.&lt;/p&gt;
&lt;p&gt;We can now create, save and restore maps in the editor:&lt;/p&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
    &lt;a class=&#34;shortcode-youtube&#34; href=&#34;https://www.youtube.com/watch?v=4CicbnaluQY&#34; title=&#34;Play Youtube video&#34; target=&#34;_blank&#34;&gt;
        &lt;img
            width=&#34;560&#34;
            height=&#34;315&#34;
            src=&#34;https://i.ytimg.com/vi/4CicbnaluQY/hqdefault.jpg&#34;
            alt=&#34;Youtube video 4CicbnaluQY&#34;
        /&gt;
&lt;/a&gt;
&lt;/div&gt;

&lt;style&gt;
    .shortcode-youtube {
        position: relative; display: inline-block;
    }
    .shortcode-youtube::before, .shortcode-youtube::after {
        content: &#34;&#34;;
        width: 100%;
        height: 100%;
        position: absolute;
        top: 0;
        left: 0;
    }
    .shortcode-youtube::before {
        background: url(&#34;/images/youtube_button.svg&#34;) center center / auto 4rem no-repeat;
    }
    .shortcode-youtube:hover::before {
        background: url(&#34;/images/youtube_button_hover.svg&#34;) center center / auto 4rem no-repeat;
    }
    .shortcode-youtube::after {
        background: url(&#34;/images/youtube.svg&#34;) calc(100% - 1rem) calc(100% - 1rem) / auto 2rem no-repeat;
    }
    .shortcode-youtube img {
        display: block;
    }
&lt;/style&gt;

&lt;p&gt;This tool is available here: &lt;a href=&#34;https://encounters.4sh.dev/&#34;&gt;https://encounters.4sh.dev&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Encounters v0.1.1 (Alpha)</title>
      <link>https://4sh.dev/posts/_old-blog/encounters-v0-1-1-alpha/</link>
      <pubDate>Thu, 23 Apr 2020 22:48:17 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/encounters-v0-1-1-alpha/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m still playing with canvas and I plugged the dungeon generator I worked on a year ago.&lt;/p&gt;
&lt;p&gt;This is the result:&lt;/p&gt;
&lt;div style=&#34;text-align: center;&#34;&gt;
    &lt;a class=&#34;shortcode-youtube&#34; href=&#34;https://www.youtube.com/watch?v=OjLxWfAJFRI&#34; title=&#34;Play Youtube video&#34; target=&#34;_blank&#34;&gt;
        &lt;img
            width=&#34;560&#34;
            height=&#34;315&#34;
            src=&#34;https://i.ytimg.com/vi/OjLxWfAJFRI/hqdefault.jpg&#34;
            alt=&#34;Youtube video OjLxWfAJFRI&#34;
        /&gt;
&lt;/a&gt;
&lt;/div&gt;

&lt;style&gt;
    .shortcode-youtube {
        position: relative; display: inline-block;
    }
    .shortcode-youtube::before, .shortcode-youtube::after {
        content: &#34;&#34;;
        width: 100%;
        height: 100%;
        position: absolute;
        top: 0;
        left: 0;
    }
    .shortcode-youtube::before {
        background: url(&#34;/images/youtube_button.svg&#34;) center center / auto 4rem no-repeat;
    }
    .shortcode-youtube:hover::before {
        background: url(&#34;/images/youtube_button_hover.svg&#34;) center center / auto 4rem no-repeat;
    }
    .shortcode-youtube::after {
        background: url(&#34;/images/youtube.svg&#34;) calc(100% - 1rem) calc(100% - 1rem) / auto 2rem no-repeat;
    }
    .shortcode-youtube img {
        display: block;
    }
&lt;/style&gt;

&lt;p&gt;This tool is available here: &lt;a href=&#34;https://encounters.4sh.dev/&#34;&gt;https://encounters.4sh.dev&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Docker: Multi-stage &amp; Caching</title>
      <link>https://4sh.dev/posts/_old-blog/docker-multi-stage-caching/</link>
      <pubDate>Tue, 21 Apr 2020 05:00:50 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/docker-multi-stage-caching/</guid>
      <description>&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;whale_0-1.png&#34;/&gt; 
&lt;/figure&gt;

&lt;h1 id=&#34;multi-stage&#34;&gt;Multi-stage&lt;/h1&gt;
&lt;h2 id=&#34;in-the-beginning&#34;&gt;In the beginning&lt;/h2&gt;
&lt;p&gt;When we first started to build docker images, long before the multi-stage syntax, our projects would look something like this:&lt;/p&gt;
&lt;script src=&#34;https://gist.github.com/AshDevFr/4342185f3d4bfe67961fff7f0f2a99a4.js&#34;&gt;&lt;/script&gt;

&lt;p&gt;We would have a base docker image containing the dependencies shared by the &lt;code&gt;development&lt;/code&gt; and the &lt;code&gt;production&lt;/code&gt; image, then one file for each final image.&lt;/p&gt;
&lt;p&gt;The script &lt;code&gt;build.sh&lt;/code&gt; shows that we first build the base image tagging it as &lt;code&gt;base_image&lt;/code&gt;, then depending of the argument passed to the script we would build the final image.&lt;/p&gt;</description>
    </item>
    <item>
      <title>D&amp;D Toolbox</title>
      <link>https://4sh.dev/posts/_old-blog/d-d-toolbox/</link>
      <pubDate>Mon, 20 Apr 2020 04:34:16 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/d-d-toolbox/</guid>
      <description>&lt;h2 id=&#34;the-context&#34;&gt;The context&lt;/h2&gt;
&lt;p&gt;With the COVID-19 and the shelter in place, there is not much opportunities to play D&amp;amp;D face to face with friends.&lt;/p&gt;
&lt;p&gt;Some groups decided to go to platforms like Roll20 or Fantasy Ground. While I love those apps they are lacking something in my opinion: an integration with DnD Beyond.&lt;/p&gt;
&lt;p&gt;I personally have a LOT of digital content on DnD Beyond and the idea of buying it again on another platform is not something I am considering.&lt;/p&gt;</description>
    </item>
    <item>
      <title>D&amp;D Beyond DM Screen</title>
      <link>https://4sh.dev/posts/_old-blog/d-d-dm-screen/</link>
      <pubDate>Mon, 20 Apr 2020 03:40:00 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/d-d-dm-screen/</guid>
      <description>&lt;p&gt;Few months ago, I worked on a Chrome extension to make my life easier when DMing D&amp;amp;D using DnD Beyond characters.&lt;/p&gt;
&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;https://user-images.githubusercontent.com/7372540/70300109-84052e80-17ab-11ea-97c1-c250e4ad8d29.png&#34;/&gt; &lt;figcaption&gt;
            DM Screen Extension Screenshot
        &lt;/figcaption&gt;
&lt;/figure&gt;

&lt;p&gt;&lt;a href=&#34;https://chrome.google.com/webstore/detail/dd-beyond-campaign-dm-scr/oiajbaepngjfcgimlkaedfkdjkklkfhh&#34;&gt;D&amp;amp;D Beyond Campaign DM Screen&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The extension has a simple goal: providing the characters&amp;rsquo;s stats in a useful way and refreshing the data when the character&amp;rsquo;s sheets are updated.&lt;/p&gt;
&lt;h2 id=&#34;without-the-extension&#34;&gt;Without the extension&lt;/h2&gt;
&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;image.png&#34;/&gt; 
&lt;/figure&gt;

&lt;h2 id=&#34;with-the-extension&#34;&gt;With the extension&lt;/h2&gt;
&lt;p&gt;When using the embedded version of the DM screen:&lt;/p&gt;
&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;image-1.png&#34;/&gt; 
&lt;/figure&gt;

&lt;p&gt;When using the popup version:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Minecraft  1.15 power by docker</title>
      <link>https://4sh.dev/posts/_old-blog/minecraft-on-docker/</link>
      <pubDate>Wed, 15 Apr 2020 06:05:40 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/minecraft-on-docker/</guid>
      <description>&lt;figure&gt;
    &lt;img loading=&#34;lazy&#34; src=&#34;800px-Nether_Update.png&#34;/&gt; 
&lt;/figure&gt;

&lt;p&gt;Few years ago I created a docker image for me to play on Minecraft with friends.&lt;/p&gt;
&lt;p&gt;I have been updating this image from time to time but basically it&amp;rsquo;s almost always compatible with the new version since it&amp;rsquo;s building the game server from the sources.&lt;/p&gt;
&lt;p&gt;The project can be found here: &lt;a href=&#34;https://github.com/AshDevFr/docker-spigot&#34;&gt;https://github.com/AshDevFr/docker-spigot&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The docker image can be found here: &lt;a href=&#34;https://hub.docker.com/r/ashdev/minecraft-spigot&#34;&gt;https://hub.docker.com/r/ashdev/minecraft-spigot&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I provide the image with an ubuntu base or an alpine base which is much smaller.&lt;/p&gt;</description>
    </item>
    <item>
      <title>One step in the Progressives Web Apps</title>
      <link>https://4sh.dev/posts/_old-blog/one-step-in-the-progressives-web-apps/</link>
      <pubDate>Fri, 15 Apr 2016 11:46:41 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/one-step-in-the-progressives-web-apps/</guid>
      <description>&lt;p&gt;Few months ago, a friend of mine &lt;a href=&#34;https://twitter.com/florpeliere&#34;&gt;@florpeliere&lt;/a&gt; started to work on progressives web apps.
First, I was intrigued, but not that much.
Then he gave us a talk about them, and I started to realise the potential of this concept.
Well, it is not a huge change, it is something which is used for a while; but now, there is a name on it and an official specification.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A web app on my phone, with offline data, ok but what kind of app ?&lt;/p&gt;</description>
    </item>
    <item>
      <title>Docker&#39;s 3rd birthday celebration</title>
      <link>https://4sh.dev/posts/_old-blog/dockers-3rd-birthday-celebration/</link>
      <pubDate>Wed, 23 Mar 2016 22:27:24 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/dockers-3rd-birthday-celebration/</guid>
      <description>&lt;h2 id=&#34;the-event&#34;&gt;The event&lt;/h2&gt;
&lt;p&gt;This week is the Docker&amp;rsquo;s 3rd birthday.
Around the world, a lot of meetups were organized with the same program.&lt;/p&gt;
&lt;p&gt;For this event the Docker team has created a specific presentation with a fun training on how to build, ship and run a distributed application with ease.&lt;/p&gt;
&lt;p&gt;The slides of the presentation :&lt;/p&gt;
&lt;!-- raw HTML omitted --&gt;
&lt;p&gt;The training was in two parts:&lt;/p&gt;
&lt;p&gt;First, a self-paced beginners’ tutorial for attendees to learn Docker.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hands-on Docker in Paris the 22nd of March (Docker&#39;s 3rd birthday)</title>
      <link>https://4sh.dev/posts/_old-blog/hands-on-docker/</link>
      <pubDate>Tue, 23 Feb 2016 12:51:00 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/hands-on-docker/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Edit:&lt;/strong&gt; Due to the Docker Meetup in Paris, the Hands-on Docker is rescheduled to the 22nd of March instead of the 24th of March.&lt;/p&gt;&lt;/blockquote&gt;
&lt;p&gt;Hi!&lt;/p&gt;
&lt;p&gt;Few months ago, I gave a talk about Docker (&lt;a href=&#34;http://blog.sylvaincau.com/talk-about-docker&#34;&gt;the article&lt;/a&gt;). During this talk I saw that a lot of people are really interested by Docker but did not know where to start.&lt;/p&gt;
&lt;p&gt;So, I decided to create a Hands-on Docker to help them understand how to use it. As front end developer, the hands-on will be nodeJS/mongoDB oriented. The same principle could be applied to anything (Java, php, &amp;hellip;).&lt;/p&gt;</description>
    </item>
    <item>
      <title>Blogular</title>
      <link>https://4sh.dev/posts/_old-blog/blogular/</link>
      <pubDate>Wed, 10 Feb 2016 18:55:53 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/blogular/</guid>
      <description>&lt;p&gt;During the last past year, I trained a lot of people on AngularJS in my company. Lately, I was thinking that our repository was old and not really good looking.&lt;/p&gt;
&lt;p&gt;Then, I had an idea, what if I wanted to train people outside of my company, like in university for example. So with this idea I decided to create a new set of exercises to learn how to develop a web application using AngularJS. That is exactly what Blogular is.&lt;/p&gt;</description>
    </item>
    <item>
      <title>EmberJS</title>
      <link>https://4sh.dev/posts/_old-blog/emberjs/</link>
      <pubDate>Tue, 09 Feb 2016 19:48:28 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/emberjs/</guid>
      <description>&lt;p&gt;Last week, I gave a talk about EmberJS.&lt;/p&gt;
&lt;p&gt;As a long time user of AngularJS 1.x some people were expecting a comparaison between these two frameworks. My point was more about what is Ember, what is the good and the bad with this framework.&lt;/p&gt;
&lt;p&gt;I was hoping to give to people the envy of trying it. And after the talk some of them told me that they will try.&lt;/p&gt;
&lt;p&gt;I am currently working on a simple hands-on training on EmberJS. I will probably provide it in few weeks in Paris. Let me know in the comments if you are interested.&lt;/p&gt;</description>
    </item>
    <item>
      <title>ngMockStorage</title>
      <link>https://4sh.dev/posts/_old-blog/ngmockstorage/</link>
      <pubDate>Mon, 21 Dec 2015 19:49:00 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/ngmockstorage/</guid>
      <description>&lt;p&gt;Hi guys,
I just released a first version of a new library for AngularJS.&lt;/p&gt;
&lt;p&gt;The idea is to have a mock in your AngularJS application, but not deployed on the back side.
With this kind of mock you are able to deploy an offline sandbox version of your website.&lt;/p&gt;
&lt;p&gt;The library decorates the $http service and uses the localStorage or sessionStorage to store your data.&lt;/p&gt;
&lt;p&gt;You will find the library there : &lt;a href=&#34;https://github.com/AshDevFr/ngMockStorage&#34;&gt;github&lt;/a&gt; / &lt;a href=&#34;https://www.npmjs.com/package/ngmockstorage&#34;&gt;npm&lt;/a&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Talk about Docker</title>
      <link>https://4sh.dev/posts/_old-blog/talk-about-docker/</link>
      <pubDate>Fri, 06 Nov 2015 13:13:01 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/talk-about-docker/</guid>
      <description>&lt;p&gt;Few weeks ago, as every month, my company has organised their Tech evening.
This time, it was about Docker. &lt;!-- raw HTML omitted --&gt;&lt;!-- raw HTML omitted --&gt;&lt;/p&gt;
&lt;p&gt;As a long time user of virtualization and for the past year of Docker, I offered to talk about how to integrate docker in our everyday work.&lt;/p&gt;
&lt;p&gt;As a front end developper, I use very often Gulp, Grunt and/or Node.js in my projects. These tools are pretty awesome but when I deal with external libs I have to be really careful of what I put in my dependencies file.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Hi!</title>
      <link>https://4sh.dev/posts/_old-blog/hi/</link>
      <pubDate>Thu, 05 Nov 2015 12:37:20 +0000</pubDate>
      <guid>https://4sh.dev/posts/_old-blog/hi/</guid>
      <description>&lt;p&gt;I have been pondering for a long time on the idea of creating a blog, but I was not quite sure on the subject to write
on.&lt;/p&gt;
&lt;p&gt;For the past 6 months I started to do a lot, from talks about Docker to creating AngularJS training.&lt;/p&gt;
&lt;p&gt;Some of these were for my own purpose and other for my company. But it gave me the idea to share my experience of what I
do, what I have done, my issues, etc. Maybe my little contribution will help some of you.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Projects</title>
      <link>https://4sh.dev/projects/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://4sh.dev/projects/</guid>
      <description>projects</description>
    </item>
  </channel>
</rss>
