<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Fabian Morón Zirfas&apos;s Blog</title><description>Blogging or not blogging... Sometimes about stuff that involves things</description><link>https://fabianmoronzirfas.me/</link><item><title>README</title><link>https://fabianmoronzirfas.me/blog/2014-11-23-readme/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2014-11-23-readme/</guid><pubDate>Sun, 04 Sep 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;This site ist currently under constructions. Needs a full redesign.
Thanks for your patience.&lt;/p&gt;</content:encoded></item><item><title>Work in Progress</title><link>https://fabianmoronzirfas.me/blog/2016-09-04-wip/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2016-09-04-wip/</guid><pubDate>Mon, 05 Sep 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I actually started working on the site again. I hope to have something till the end of the month. Stay tuned.&lt;/p&gt;</content:encoded></item><item><title>It&apos;s time to start blogging (again)</title><link>https://fabianmoronzirfas.me/blog/2016-12-07-blogging-again/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2016-12-07-blogging-again/</guid><pubDate>Wed, 07 Dec 2016 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Recent events in big data, like the usage of &lt;a href=&quot;https://www.dasmagazin.ch/2016/12/03/ich-habe-nur-gezeigt-dass-es-die-bombe-gibt/&quot;&gt;Michal Kosinski research&lt;/a&gt; for influencing elections, the &lt;a href=&quot;https://www.theguardian.com/technology/2016/dec/04/google-democracy-truth-internet-search-facebook&quot;&gt;&quot;hacking&quot; of Googles search algorithms&lt;/a&gt; for pushing right wing propaganda into search results and the development from &lt;a href=&quot;https://medium.com/matter/the-web-we-have-to-save-2eb1fe15a426#.y88r8rsbd&quot;&gt;hyperlinked information to linear TV like consumption&lt;/a&gt; makes me sangry (sad+angry). So I will start blogging. Not on medium, not Tumblr or whatever. It will happen here. Sometimes in English, sometimes German, sometimes in Code. So stay tuned and use the RSS feed.&lt;/p&gt;
&lt;h2&gt;Links&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://www.dasmagazin.ch/2016/12/03/ich-habe-nur-gezeigt-dass-es-die-bombe-gibt/&quot;&gt;Ich habe nur gezeigt, dass es die Bombe gibt - Das Magazin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.theguardian.com/technology/2016/dec/04/google-democracy-truth-internet-search-facebook&quot;&gt;Google, democracy and the truth about internet search - Technology - The Guardian&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://medium.com/matter/the-web-we-have-to-save-2eb1fe15a426#.9amrwp6ye&quot;&gt;The Web We Have to Save – Matter – Medium&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>Dog not Cat - Colored output in from cat in the terminal</title><link>https://fabianmoronzirfas.me/blog/2017-01-04-dog-not-cat/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2017-01-04-dog-not-cat/</guid><pubDate>Wed, 04 Jan 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;How to make &lt;code&gt;cat&lt;/code&gt; have colored output?&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;sudo easy_install Pygments
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Then edit your &lt;code&gt;.bashrc&lt;/code&gt;, &lt;code&gt;.bash_profile&lt;/code&gt; or &lt;code&gt;.zshrc&lt;/code&gt; and add the following line:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;alias dog=&quot;pygmentize -g&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Source it and you are good to go.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;dog myfile
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Will give you colored output. Nice!&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Found around &lt;a href=&quot;http://stackoverflow.com/questions/7851134/syntax-highlighting-colorizing-cat&quot;&gt;the web.&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Weekly round up - translation, productive habits and procrastination</title><link>https://fabianmoronzirfas.me/blog/2017-01-08-translation-prodictivity-procrastination/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2017-01-08-translation-prodictivity-procrastination/</guid><pubDate>Wed, 04 Jan 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Writing a blog post each week is hard. Especially when you have a kid, a job, a wife, friends, a hobby and a paper due in 3 weeks. So here is just a quick one for this week.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;First the overwhelming change in Google Translate (you really should check it out). They applied some neural network magic to it and now have really good translations. This is awesome. It seems also that the AI created its own language.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Google’s researchers think their system achieves this breakthrough by finding a common ground whereby sentences with the same meaning are represented in similar ways regardless of language – which they say is an example of an “interlingua”. In a sense, that means it has created a new common language, albeit one that’s specific to the task of translation and not readable or usable for humans.&lt;br&gt;
&lt;a href=&quot;https://www.newscientist.com/article/2114748-google-translate-ai-invents-its-own-language-to-translate-with/&quot;&gt;newscientist.com - Google Translate AI invents its own language to translate with&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;There is this article &lt;a href=&quot;https://www.nytimes.com/2016/12/14/magazine/the-great-ai-awakening.html?_r=1&quot;&gt;nytimes.com - The Great A.I. Awakening&lt;/a&gt; that I really need to read.&lt;/p&gt;
&lt;p&gt;Second thing is this app: &lt;a href=&quot;https://productiveapp.io/&quot;&gt;productiveapp.io&lt;/a&gt;. I really did drink enough water this week. Also, I&apos;m writing this blog post. Ain&apos;t I?&lt;br&gt;
Third procrastination. I&apos;m good at it. Not writing the paper but a blog post instead, my plants have water the kitchen is clean and so on. Well. Then let&apos;s get back to work…&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://i.giphy.com/heK9M5vuUcloY.gif&quot; alt=&quot;work&quot;&gt;&lt;/p&gt;</content:encoded></item><item><title>Markdown Preview in the Terminal</title><link>https://fabianmoronzirfas.me/blog/2017-03-31-markdown-preview-in-the-terminal/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2017-03-31-markdown-preview-in-the-terminal/</guid><pubDate>Fri, 31 Mar 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;So how can we preview Markdown files in the terminal? There is of course &lt;a href=&quot;http://brettterpstra.com/projects/mdless/&quot;&gt;mdless by Brett Terpstra&lt;/a&gt;, but what if you don&apos;t want to use a ruby gem (for some kind of wired reason). The best solution I found is a combination of two tools &lt;a href=&quot;http://pandoc.org/&quot;&gt;pandoc&lt;/a&gt; and &lt;a href=&quot;http://lynx.browser.org/&quot;&gt;lynx&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Together you can turn them into a handy function to preview your markdown files when you are logged into that machine on the other side of the world.&lt;/p&gt;
&lt;p&gt;If you are using fish add this to your functions under &lt;code&gt;.config/fish/functions/mdview.fish&lt;/code&gt; (mdview is the name of the function and the file you will have to create).&lt;/p&gt;
&lt;p&gt;There are some sanity checks in there that look if pandoc and lynx are installed. If not on macOS run &lt;code&gt;brew update &amp;#x26;&amp;#x26; brew install pandoc lynx&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;function mdview
if set -q argv
  switch $argv
    case -h
      echo &quot;[M↓] Help&quot;
      echo &quot;call the mdview with a Markdown [M↓] file as argument&quot;
      echo &quot;this script needs pandoc and lynx installed&quot;
      echo &quot;on macOS run &apos;brew install pandoc lynx&apos;&quot;
    case &quot;*&quot;
      # check if pandoc is installed
      if pandoc -v &gt;/dev/null do
      # check if lynx is installed
        if lynx -version &gt;/dev/null do
          # run the magic
          # pass the file to pandoc
          # it will be converted to HTML and go to stdout
          # pipe it into lynx stdin
          pandoc $argv | lynx -stdin
        else
          echo &quot;lynx is not installed&quot;
        end
      else
        echo &quot;pandoc is not installed&quot;
      end
    end
  end
end
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;For bash/zsh this should be something like this in its simplest form.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;#!/bin/bash
function mdview (){
    # pipe it into lynx stdin
    pandoc &quot;$1&quot; | lynx -stdin
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Have fun.&lt;/p&gt;</content:encoded></item><item><title>JSON feed</title><link>https://fabianmoronzirfas.me/blog/2017-05-18-json-feed/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2017-05-18-json-feed/</guid><pubDate>Thu, 18 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I have a &lt;a href=&quot;https://jsonfeed.org/&quot;&gt;JSON feed&lt;/a&gt; now &lt;a href=&quot;%7B%7Bsite.baseurl%7D%7D/feed.json&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We — Manton Reece and Brent Simmons — have noticed that JSON has become the developers’ choice for APIs, and that developers will often go out of their way to avoid XML. JSON is simpler to read and write, and it’s less prone to bugs.&lt;br&gt;
So we developed JSON Feed, a format similar to &lt;a href=&quot;http://cyber.harvard.edu/rss/rss.html&quot;&gt;RSS&lt;/a&gt; and &lt;a href=&quot;https://tools.ietf.org/html/rfc4287&quot;&gt;Atom&lt;/a&gt; but in JSON. It reflects the lessons learned from our years of work reading and publishing feeds.&lt;br&gt;
&lt;a href=&quot;https://jsonfeed.org/version/1&quot;&gt;See the spec&lt;/a&gt;. It’s at version 1, which may be the only version ever needed. If future versions are needed, version 1 feeds will still be valid feeds. (…)&lt;br&gt;
&lt;a href=&quot;https://jsonfeed.org/&quot;&gt;source&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title>Things 3 or not?</title><link>https://fabianmoronzirfas.me/blog/2017-05-19-things-3/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2017-05-19-things-3/</guid><pubDate>Fri, 19 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The people at &lt;a href=&quot;https://culturedcode.com/things/&quot;&gt;Culturecode&lt;/a&gt; updated Things from v2 to v3. There is no upgrade pricing. Which is understandable after so many years of development. I&apos;m asking myself now: “Should I spend the 50€ (macOS + iOS) version?” The thing (lowercase) is I moved on. I didn&apos;t start Things (upper case) for a long time. I moved on to &lt;a href=&quot;https://www.taskpaper.com/&quot;&gt;Taskpaper&lt;/a&gt;, but even these are not part of my daily habits. After I first evaluation of the trial app, I still wasn&apos;t convinced that I should move back.&lt;/p&gt;
&lt;p&gt;This seems the biggest challenge for me. The feeling I&apos;m moving backward.&lt;/p&gt;
&lt;p&gt;If you have any thoughts on this contact &lt;a href=&quot;https://twitter.com/fmoronzirfas&quot;&gt;@fmoronzirfas&lt;/a&gt; me on Twitter&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;!-- links --&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;While I&apos;m writing this Twitter is down (2017-05-19 13:55). How to get news if Twitter is down and whats up when your standard service for checking such things is affected? &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>JSONfeed and real problems</title><link>https://fabianmoronzirfas.me/blog/2017-05-24-jsonfeed-and-real-problems/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2017-05-24-jsonfeed-and-real-problems/</guid><pubDate>Wed, 24 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;The hype around this effort reminds me of the hype at the start of Atom. Thankfully the personal stuff does not seem to be coming along with it this time.&lt;/p&gt;
&lt;p&gt;Is this something we should be focusing on?&lt;/p&gt;
&lt;p&gt;I think we have to work on climate change and the fascism that&apos;s trying to boot up in the US. Our systems for news suck, and there are obvious ways to improve them if we put our minds to it. And I think a new incompatible feed format not only doesn&apos;t move us toward solving those problems, in a very small way (not worth worrying about) it moves us away from solving them. By using bandwidth that could be used to foster working-together, perhaps. By making things that would otherwise interop, not interop.&lt;br&gt;
&lt;a href=&quot;http://scripting.com/2017/05/21/reEvanWilliamsAndJsonFeed.html&quot;&gt;&quot;Re Evan Williams and JSON Feed&quot; by Dave Winer&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;But real problems are messy. Tech culture prefers to solve harder, more abstract problems that haven&apos;t been sullied by contact with reality. So they worry about how to give Mars an earth-like climate, rather than how to give Earth an earth-like climate. They debate how to make a morally benevolent God-like AI, rather than figuring out how to put ethical guard rails around the more pedestrian AI they are introducing into every area of people&apos;s lives.&lt;br&gt;
&lt;a href=&quot;http://idlewords.com/talks/notes_from_an_emergency.htm&quot;&gt;&quot;Notes From An Emergency&quot; by Maciej Cegłowski&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yes, I also jumped on the JSONfeed train and I still think it is a good idea. Reading the transcript from Maciej made me think a lot on my way home. I guess he&apos;s right. It is way easier to build something from scratch that solves a new problem then tackling an existing one. JSON feed versus climate change? That&apos;s a tough neighborhood.&lt;/p&gt;</content:encoded></item><item><title>My thing with Setapp is…</title><link>https://fabianmoronzirfas.me/blog/2017-05-24-setapp-and-me/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2017-05-24-setapp-and-me/</guid><pubDate>Wed, 24 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;The idea of &lt;a href=&quot;https://setapp.com&quot;&gt;Setapp&lt;/a&gt; is great. Having a subscription model for all those lovely apps and just paying 9.99$ per month is very intriguing. My problem is, for the apps that interest me the most in their catalog I already have a license:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://macpaw.com/de/cleanmymac&quot;&gt;Cleanmymac&lt;/a&gt; (Have it, use it, love it.)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://marked2app.com/&quot;&gt;Marked&lt;/a&gt; (no [M↓] document is written without it.)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://macpaw.com/de/gemini&quot;&gt;Gemini&lt;/a&gt; (from time to time I use it but not that often as I should.)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://numi.io/&quot;&gt;Numi&lt;/a&gt; (Great calculator. It is actually free.)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://macitbetter.com/&quot;&gt;Betterzip&lt;/a&gt; (Also way better than the built-in archiver. And also free.)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://coderunnerapp.com/&quot;&gt;Coderunner&lt;/a&gt; (Well this is one of the apps I never use but I love the idea. normally I use the &lt;a href=&quot;https://www.iterm2.com/&quot;&gt;iTerm&lt;/a&gt; and the REPL.)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://menial.co.uk/base/&quot;&gt;Base&lt;/a&gt; (Okay this one might come in handy when I actually start using SQLite.)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.yummysoftware.com/&quot;&gt;Yummy FTP&lt;/a&gt; (I have a license but I use &lt;a href=&quot;https://www.panic.com/transmit/&quot;&gt;Transmit&lt;/a&gt;.)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.manuscriptsapp.com/&quot;&gt;Manuscript&lt;/a&gt; (Bought a license for that one. It really sucked. I hope it improved.)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.ulyssesapp.com/&quot;&gt;Ulysses&lt;/a&gt; (I&apos;m on &lt;a href=&quot;https://www.literatureandlatte.com/scrivener.php&quot;&gt;Scrivener&lt;/a&gt; for this kind of writing. Even though I like the visual appearance of Ulysses more.)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.taskpaper.com/&quot;&gt;Taskpaper&lt;/a&gt; (Well this one I bought after the beta subscription of Setapp ran out.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Any thoughts? Talk to me on Twitter &lt;a href=&quot;https://twitter.com/fmoronzirfas&quot;&gt;@fmoronzirfas&lt;/a&gt; about it.&lt;/p&gt;</content:encoded></item><item><title>Just remember that keycombo for π</title><link>https://fabianmoronzirfas.me/blog/2017-05-25-just-remember-pi/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2017-05-25-just-remember-pi/</guid><pubDate>Thu, 25 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;code&gt;⌥ + p&lt;/code&gt; is &lt;code&gt;π&lt;/code&gt;.&lt;/p&gt;</content:encoded></item><item><title>No Monday morning without wired problems…</title><link>https://fabianmoronzirfas.me/blog/2017-05-29-monday-morning-wiredness/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2017-05-29-monday-morning-wiredness/</guid><pubDate>Mon, 29 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Does every Monday have to start with wired problems? iTerm2 can&apos;t connect over ssh to our remote server. Terminal can. After a reboot, everything works normally…? WTF? Gremlins?&lt;/p&gt;</content:encoded></item><item><title>Awesome @ubernauten</title><link>https://fabianmoronzirfas.me/blog/2017-05-31-awesome-uberspace/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2017-05-31-awesome-uberspace/</guid><pubDate>Tue, 30 May 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;/assets/images/uberspace/badge-white-fmz-asteroids.png&quot; alt=&quot;asteroids&quot;&gt;&lt;/p&gt;
&lt;p&gt;Did I mention before&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; that I moved my site to &lt;a href=&quot;https://uberspace.de&quot;&gt;uberspace.de&lt;/a&gt;? The best web hosting service I ever encountered. Not only do they have a name your own price policy – you can also run Node.js, Ruby (on Rails if you want). Install daemons, have crontabs, of course, ssh and letsencrypt out of the box and many more things. But what is most important they provide the best customer service ever. No question is dumb enough to not being answered fast and politely. These guys are awesome. Oh, and it&apos;s all hosted on asteroids!&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;That I can dance in my pants and in your face! &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>About Computing</title><link>https://fabianmoronzirfas.me/blog/2017-07-19-a-good-article-about-computing/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2017-07-19-a-good-article-about-computing/</guid><pubDate>Sat, 18 Nov 2017 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;This is ambient computing, the transformation of the environment all around us with intelligence and capabilities that don’t seem to be there at all.&lt;br&gt;
Mossberg: The Disappearing Computer - Recode&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://www.recode.net/2017/5/25/15689094/mossberg-final-column&quot;&gt;source&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Read this: Notes From An Emergency</title><link>https://fabianmoronzirfas.me/blog/2017-07-19-read-this_-notes-from-an-emergency/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2017-07-19-read-this_-notes-from-an-emergency/</guid><pubDate>Sat, 18 Nov 2017 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;In their online life, Europeans have become completely dependent on companies headquartered in the United States.(…)&lt;br&gt;
And so Trump is in charge in America, and America has all your data. This leaves you in a very exposed position. US residents enjoy some measure of legal protection against the American government. Even if you think our intelligence agencies are evil, they&apos;re a lawful evil. They have to follow laws and procedures, and the people in those agencies take them seriously.(…)&lt;br&gt;
There are five Internet companies—Apple, Google, Microsoft, Amazon and Facebook. Together they have a market capitalization just under 3 trillion dollars.(…)&lt;br&gt;
Bruce Schneier has called this arrangement the feudal Internet. Part of this concentration is due to network effects, but a lot of it is driven by the problem of security. If you want to work online with any measure of convenience and safety, you must choose a feudal lord who is big enough to protect you.(…)&lt;br&gt;
&lt;a href=&quot;http://idlewords.com/talks/notes_from_an_emergency.htm&quot;&gt;source&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I always love to read what Maciej Cegłowski has to say.&lt;/p&gt;</content:encoded></item><item><title>Node.js on AWS Beanstalk</title><link>https://fabianmoronzirfas.me/blog/2017-08-01-express-app-on-aws-beanstalk/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2017-08-01-express-app-on-aws-beanstalk/</guid><pubDate>Tue, 01 Aug 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Are you trying to deploy a Express/Node.js application to AWS Beanstalk? I tried today and these are the things you should take into account if you are using the AWS Console.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;When uploading a .zip you need to zip the content of your project folder. Not the folder.&lt;/li&gt;
&lt;li&gt;Name your main file &quot;app.js&quot; or &quot;server.js&quot; or create the &quot;npm start&quot;.&lt;/li&gt;
&lt;li&gt;You can define a own node command to run your app in the configuration of your Beanstalk application.&lt;/li&gt;
&lt;li&gt;If using Nginx the port will be 8081 according to this &lt;a href=&quot;https://stackoverflow.com/questions/36968989/cant-deploy-node-restify-app-to-aws-eb&quot;&gt;stackoverflow.com question&lt;/a&gt;. To don&apos;t hardcode the port use &lt;code&gt;const port = process.env.PORT || 3000&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This might be it…&lt;/p&gt;
&lt;p&gt;Oh, and socket.io is throwing an error. This &lt;a href=&quot;https://github.com/socketio/socket.io/issues/1942&quot;&gt;is a problem&lt;/a&gt; for another day. Also, I should take a look at the command line tool for deploying Beanstalk. It seems I can define a aws region for an app.&lt;/p&gt;</content:encoded></item><item><title>Vim is fun… NOT</title><link>https://fabianmoronzirfas.me/blog/2017-08-18-vim-is-fun/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2017-08-18-vim-is-fun/</guid><pubDate>Fri, 18 Aug 2017 00:00:00 GMT</pubDate><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;a href=&quot;https://medium.freecodecamp.org/vim-isnt-that-scary-here-are-5-free-resources-you-can-use-to-learn-it-ab78f5726f8d&quot;&gt;Vim isn’t that scary. Here are 5 free resources you can use to learn it.&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Vim is fun when you are a masochist that misplaced his whip. Nuff said.&lt;/p&gt;</content:encoded></item><item><title>About CEP Panels</title><link>https://fabianmoronzirfas.me/blog/2017-11-16-adobe-cep-panels/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2017-11-16-adobe-cep-panels/</guid><pubDate>Sat, 18 Nov 2017 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I recently collected some links on CEP Panels&lt;/p&gt;
&lt;p&gt;CEP Reosources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://victorianece.com/2015/12/getting-started-with-html5-cep-panels-for-after-effects/&quot;&gt;Getting started with HTML5 (CEP) Panels for After Effects - Victoria Nece&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://victorianece.com/tag/cep/&quot;&gt;CEP - Victoria Nece&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://www.adobe.io/apis/creativecloud/cep.html&quot;&gt;Creative Cloud Extension SDK - CC extension resources - Adobe I/O&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://aphall.com/2014/08/cep-mega-guide-en/&quot;&gt;CEP 5 Super mega guide: Extending Adobe apps with HTML5+Node.js - aphall.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Adobe-CEP&quot;&gt;Adobe CEP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.adobe.com/devnet/creativesuite/articles/a-short-guide-to-HTML5-extensions.html&quot;&gt;A Short Guide to HTML5 Extensions - Adobe Developer Connection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.adobe.com/devnet/aftereffects/panelsdk/cc2015.html&quot;&gt;After Effects CC 2015 Panel SDK - Adobe Developer Connection&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://victorianece.com/2015/12/html5-cep-panels-for-after-effects-fixes-hacks-and-workarounds/&quot;&gt;HTML5 (CEP) Panels for After Effects: Fixes, hacks and workarounds - Victoria Nece&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jenstroeger/Bookalope-CEP&quot;&gt;jenstroeger/Bookalope-CEP: Adobe CEP extension for InDesign to use the Bookalope cloud services.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Trevor-/CSTK&quot;&gt;Trevor-/CSTK: Adobe HTML extension Console for js, jsx and shell and extensions development help&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>Gated Communities</title><link>https://fabianmoronzirfas.me/blog/2018-04-06-gated-communities/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2018-04-06-gated-communities/</guid><pubDate>Fri, 06 Apr 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Whenever I come across a Facebook link I feel like: &quot;ohh noooo, this path leeds into a gated community, where the land lord has cameras in your house and collects your trash and comes to your house when you sleep to look at your undies. Lucky me - I live in the woods where everyone can pass through my camp.&quot;&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; In other words:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;https://media1.giphy.com/media/4SqyKskMyduEw/giphy.gif&quot; alt=&quot;&quot;&gt;&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;Yes they also can look at my stuff but I try to keep my undies in my backpack and I check for hidden cameras. &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>My Rant on Development Practices</title><link>https://fabianmoronzirfas.me/blog/2018-04-06-my-rant-on-overtooling/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2018-04-06-my-rant-on-overtooling/</guid><pubDate>Fri, 06 Apr 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;!Note: I wrote this actually on 01.08.2017 but never published it. So here it goes!&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;There are already a lot of rants about the state of (over)tooling, development style, scalability and what not. This is not news. My rant is aimed at my realm&lt;sup&gt;&lt;a href=&quot;#user-content-fn-8&quot; id=&quot;user-content-fnref-8&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. The University.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://xkcd.com/1629/&quot;&gt;&lt;img src=&quot;https://imgs.xkcd.com/comics/tools.png&quot; alt=&quot;&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Dear &lt;em&gt;(developer/student Let&apos;s call you:)&lt;/em&gt; Johnny,&lt;/p&gt;
&lt;p&gt;The next time you build something that others should be able to use in a project, think twice about what cool new [FRAMEWORK || BUILD TOOL || ENVIRONMENT]&lt;sup&gt;&lt;a href=&quot;#user-content-fn-0&quot; id=&quot;user-content-fnref-0&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; you use. It would be great to just pop up a terminal and run &lt;code&gt;npm install &amp;#x26;&amp;#x26; npm start&lt;/code&gt;, open &lt;a href=&quot;http://localhost:3000&quot;&gt;localhost:3000&lt;/a&gt; and be ready to go. Instead, I have to learn:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;that cool new way to write commit messages because somebody thinks &lt;code&gt;git commit -a -m &quot;I did something important&quot;&lt;/code&gt; is too verbose or not enough&lt;sup&gt;&lt;a href=&quot;#user-content-fn-6&quot; id=&quot;user-content-fnref-6&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;that fancy framework&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;4&lt;/a&gt;&lt;/sup&gt; from, let&apos;s say Foobook™, for running a simple one-page application with three buttons that kick of some process&lt;/li&gt;
&lt;li&gt;that awesome IDE because those simple text editors are for old geezers&lt;/li&gt;
&lt;li&gt;that new JS flavor called MilkyScript&lt;sup&gt;&lt;a href=&quot;#user-content-fn-7&quot; id=&quot;user-content-fnref-7&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; that is so much superior to JS&lt;/li&gt;
&lt;li&gt;you name it…&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Oh. I need to install a ton of global tools you run for compiling es2525 and beyond because we really need &lt;code&gt;import&lt;/code&gt; instead of &lt;code&gt;module.exports&lt;/code&gt; now everywhere. Of course, you did not tell me which version you installed half a year ago and did not update on a regular basis.&lt;/p&gt;
&lt;p&gt;After I dug through all those dependencies and got them installed I try to understand your &lt;code&gt;scripts&lt;/code&gt; in &lt;code&gt;package.json&lt;/code&gt; but they are all broken or written in Latin or executing a sub shell in elvish&lt;sup&gt;&lt;a href=&quot;#user-content-fn-2&quot; id=&quot;user-content-fnref-2&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;6&lt;/a&gt;&lt;/sup&gt;. Except for &lt;code&gt;dev&lt;/code&gt; which compiles your es2525 every time even though I did not change anything.&lt;/p&gt;
&lt;p&gt;I almost forget to read your README entirely, because it is not enough to run &lt;code&gt;cd into/project/folder/ &amp;#x26;&amp;#x26; npm install&lt;/code&gt;. Of course not. You needed to symlink your &lt;code&gt;src&lt;/code&gt; folder into the &lt;code&gt;app&lt;/code&gt; folder to access your &lt;code&gt;modules&lt;/code&gt; like &lt;code&gt;node_modules&lt;/code&gt; (instead of using something that happens on &lt;a href=&quot;https://github.com/patrick-steele-idem/app-module-path-node&quot;&gt;module level&lt;/a&gt; and is cross-platform).&lt;/p&gt;
&lt;p&gt;Of course, you need that fully scalable multi site CMS to build the documentation of your project. No, you won&apos;t stick around to take care of this. You were just asked to set it up. When confronted with the question: &quot;Why not use a static site generator?&quot; the answer is &quot;They feel so retro, but that&apos;s hip currently isn&apos;t it?&quot;. You tell me. Yeah – you need the big guns. I know.&lt;/p&gt;
&lt;p&gt;Did I mention the hard coded absolute path to your Library to fetch that platform specific framework for accessing that MongoDB YOU HAVE RU.... 😡&lt;/p&gt;
&lt;p&gt;You get the gist.&lt;/p&gt;
&lt;p&gt;I get it that you need to play with those tools and where to try them out best? In projects. It&apos;s important you learn these things. But at what cost? The project will be abandoned at some point. That&apos;s for sure. By abandoning it in a state where only you can use it nobody will be able to build on it. That is sad because the project is pretty awesome. What bugs me about it that you took hours and hours of setting up your tool-chain. That time could have been used to work on real problems concerning your application logic or your concept. What is wrong with some VanillaJS, a tiny bit of HTML and some CSS toppings? and what is wrong with &lt;code&gt;;&lt;/code&gt;?&lt;sup&gt;&lt;a href=&quot;#user-content-fn-3&quot; id=&quot;user-content-fnref-3&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;7&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Don&apos;t get me wrong - those tools a great, but they were build by a large group of developers at Foobook™ for, well, building Foobook™.&lt;/p&gt;
&lt;p&gt;You have to take some things into account before introducing a new tool.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Can you achieve the same thing without it in the time you use to learn it?&lt;/li&gt;
&lt;li&gt;Will somebody else need to run it (if so write some docs)?&lt;/li&gt;
&lt;li&gt;Will you write these docs or just put it down as a todo?&lt;/li&gt;
&lt;li&gt;Is it portable to another computer without problems?&lt;/li&gt;
&lt;li&gt;Where lies your focus? On the tool of the project?&lt;/li&gt;
&lt;li&gt;Will you have to use this tool often?&lt;/li&gt;
&lt;li&gt;And many more things…&lt;sup&gt;&lt;a href=&quot;#user-content-fn-5&quot; id=&quot;user-content-fnref-5&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I remember being the same. When I was at the same point of learning to write software, it was cool to run Processing in Eclipse, because Eclipse is the way better IDE &lt;em&gt;(long pause)&lt;/em&gt; NOT!&lt;br&gt;
A year or two later I tried to revive that project. It took me a long time to not accomplish it in Eclipse and some more time to port it back to Processing. Or another project where I started using Grunt. I have 304 lines of code in that Gruntfile.js. Now that project has been dormant for some time. Whenever I think &quot;you could do something on it&quot;. I stop when remembering that Gruntfile.js and that I can&apos;t remember how to build. Yes, I could start looking at my documentation. Or not. Because writing docs are something I did not do at that time. I just coded the hell out of it because it is fun.&lt;/p&gt;
&lt;p&gt;So did you write documentation? Oh of course not. It is the end of the semester and it had to be done quickly because fiddling with all those cool toys took so much time…&lt;/p&gt;
&lt;p&gt;I could go on and on. This is not only for you Johnny. This mainly for myself to blow off some steam and to remind me to focus. I really would love to use &lt;code&gt;import&lt;/code&gt; instead of &lt;code&gt;require&lt;/code&gt; but not at the cost of always having to run a process that watches what I do and babels out some JS code my Node.js installation understands. The same thing goes for things like jQuery, Webpack, Rollup and so on. The things I build, like this site, actually don&apos;t need so many libraries. 73% of jQuery are not in use for this site. I could write everything in plain old boring JS.&lt;sup&gt;&lt;a href=&quot;#user-content-fn-4&quot; id=&quot;user-content-fnref-4&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;9&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;/assets/images/blog/covarage-rant.png&quot;&gt;&lt;img src=&quot;/assets/images/blog/covarage-rant.png&quot; alt=&quot;code coverage screenshot&quot;&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Yours sincerely,&lt;br&gt;
Fabian&lt;/p&gt;
&lt;p&gt;P.S. You don&apos;t agree with me? Let&apos;s talk about it on &lt;a href=&quot;https://twitter.com/fmoronzirfas&quot;&gt;Twitter&lt;/a&gt; or open an &lt;a href=&quot;https://github.com/fabianmoronzirfas/fabianmoronzirfas.github.io/issues&quot;&gt;issue on GitHub&lt;/a&gt;.&lt;br&gt;
P.P.S. You feel like this is aimed at you? Well maybe…&lt;/p&gt;
&lt;!-- footnotes --&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-8&quot;&gt;
&lt;p&gt;At least this will be my realm until the end of August. But more about that in a later post. &lt;a href=&quot;#user-content-fnref-8&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-0&quot;&gt;
&lt;p&gt;Insert value here. &lt;a href=&quot;#user-content-fnref-0&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 2&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-6&quot;&gt;
&lt;p&gt;I know &lt;a href=&quot;https://xkcd.com/1296/&quot;&gt;commit message quality&lt;/a&gt; tend to decline over time, still… &lt;a href=&quot;#user-content-fnref-6&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 3&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;Of course still in alpha! &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 4&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-7&quot;&gt;
&lt;p&gt;Actually not a flavor more some sort of esoteric way of writing JS like &lt;a href=&quot;http://www.jsfuck.com/&quot;&gt;jsfuck.com&lt;/a&gt;. Or &lt;a href=&quot;http://patriciopalladino.com/files/hieroglyphy/&quot;&gt;Hieroglyphy&lt;/a&gt;. See &lt;a href=&quot;https://gist.githubusercontent.com/fabianmoronzirfas/cb08fb6dadd29fa8d5bdf20a8e017486/raw/7175a2ec3d9b4935a02d40f08f65d276997415e7/alert-hello-world.js&quot;&gt;this&lt;/a&gt; and paste it into your console. I dare you. &lt;a href=&quot;#user-content-fnref-7&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 5&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-2&quot;&gt;
&lt;p&gt;Or maybe it is the tongue of Mordor in Elvish script? I can&apos;t tell. &lt;a href=&quot;#user-content-fnref-2&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 6&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-3&quot;&gt;
&lt;p&gt;Did I mention that your tiny Processing app does not work because you are so accustomed to leaving them out. &lt;a href=&quot;#user-content-fnref-3&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 7&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-5&quot;&gt;
&lt;p&gt;I&apos;m actually not sure if these are the right questions. Educate me if you want. &lt;a href=&quot;#user-content-fnref-5&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 8&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-4&quot;&gt;
&lt;p&gt;Which is an &lt;a href=&quot;https://github.com/fabianmoronzirfas/fabianmoronzirfas.github.io/issues/4&quot;&gt;issue&lt;/a&gt;. &lt;a href=&quot;#user-content-fnref-4&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 9&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>openFrameworks - App Crashes After Transfer to Another Computer</title><link>https://fabianmoronzirfas.me/blog/2018-04-06-of-app-crash/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2018-04-06-of-app-crash/</guid><pubDate>Fri, 06 Apr 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;!Note: Actually written on 29.11.2017&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I had a learning today that I want to share with you because it will reappear again and again when we develop applications with openFrameworks.&lt;/p&gt;
&lt;p&gt;We had the wired problem that OF Apps crashed on startup when we passed them over to other computers. It seemed quite random. Passed on a USB device. They launched fine. Passed on in a .zip over Slack or via GitLab they did not launch.&lt;/p&gt;
&lt;p&gt;Crash on Double Click&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt; Since macOS (formaly OSX 10.5) there is a security setting in place that prevents apps that where downloaded from the web to be executed. it is a part of the GateKeeper. To overcome this you once need to move manually the &quot;Fancy ofApp.app&quot; to another location on your computer and then move it back next to its data folder. Then you should be able to execute the app.&lt;/p&gt;
&lt;p&gt;More technical&lt;/p&gt;
&lt;p&gt;The feature is called &quot;App Translocation&quot;. The new application gets a xattr flag called com.apple.quarantine. This flag holds information when and with which Browser the app was loaded. The app will be moved on execution to a hidden temp folder and executed there. Having a .dmg with a &quot;Move To Applications&quot; link is not enough. The flag stays. Only when you move the App manually this gets removed. You can also inspect the xattr by running:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;xattr &quot;Fancy ofApp.app&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This will show you the flag com.apple.quarantine&lt;/p&gt;
&lt;p&gt;With&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;xattr -p com.apple.quarantine &quot;Fancy ofApp.app&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can see its content.&lt;/p&gt;
&lt;p&gt;To remove this from the commandline use:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-shell&quot;&gt;xattr -dr com.apple.quarantine &quot;Fancy ofApp.app&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You can read some more about this behind those links:&lt;/p&gt;
&lt;p&gt;App Translocation&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://eclecticlight.co/2016/06/16/macos-sierra-will-break-many-installers-and-updaters/&quot;&gt;Source: macOS Sierra will break many installers and updaters – The Eclectic Light Company&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>The Feynman Technique: The Best Way to Learn Anything</title><link>https://fabianmoronzirfas.me/blog/2018-04-06-read-this---the-feynman-technique---the-best-way-to-learn-anything/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2018-04-06-read-this---the-feynman-technique---the-best-way-to-learn-anything/</guid><pubDate>Fri, 06 Apr 2018 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;em&gt;!Note: Actually written on 27.01.2018 but never got published.&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;There are four simple steps to the Feynman Technique, which I&apos;ll explain below:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Choose a Concept&lt;/li&gt;
&lt;li&gt;Teach it to a Toddler&lt;/li&gt;
&lt;li&gt;Identify Gaps and Go Back to The Source Material&lt;/li&gt;
&lt;li&gt;Review and Simplify (optional)&lt;br&gt;
&lt;a href=&quot;https://www.fs.blog/2012/04/learn-anything-faster-with-the-feynman-technique/&quot;&gt;Source: &quot;The Feynman Technique: The Best Way to Learn Anything&quot;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title>Cross Repository Action Triggers Using GitHub Actions</title><link>https://fabianmoronzirfas.me/blog/2019-02-06-cross-repo-github-action-triggering/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2019-02-06-cross-repo-github-action-triggering/</guid><pubDate>Wed, 06 Feb 2019 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Cross Repository GitHub Action Triggering&lt;/h1&gt;
&lt;p&gt;Wow what a title.&lt;/p&gt;
&lt;p&gt;While developing the reference for our project &lt;a href=&quot;https://github.com/basiljs/basil.js&quot;&gt;Basil.js&lt;/a&gt; we ran into the following problem. We are lazy and we don&apos;t want to touch the reference each time some new function is added or even worse – we find a type in the JSDoc comments in the source.&lt;/p&gt;
&lt;p&gt;I took a look into TravisCI but learned early that the cross repo trigger is not possible. At least out of the box. Again. I&apos;m lazy and I have little time to develop a complex TravisCI script that does somehow use GitHubs API to be triggered.&lt;/p&gt;
&lt;p&gt;Some time passed and we did not find a solution. Then out of the blue GitHub &lt;a href=&quot;https://github.com/features/actions&quot;&gt;announced their actions&lt;/a&gt; feature &lt;sup&gt;&lt;a href=&quot;#user-content-fn-actions&quot; id=&quot;user-content-fnref-actions&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. Wooohooo \o/. Here wee goooo 🎢 …&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;You will need two repositories. Let&apos;s call the first one &lt;code&gt;trigger&lt;/code&gt; and the second one &lt;code&gt;target&lt;/code&gt;. The &lt;code&gt;trigger&lt;/code&gt; repo represents the source of our project &lt;a href=&quot;https://github.com/basiljs/basil.js&quot;&gt;Basil.js&lt;/a&gt;. Here we are developing and writing the source of our docs. The &lt;code&gt;target&lt;/code&gt; repo holds or documentation. In our case it is the &lt;a href=&quot;https://github.com/basiljs/basiljs.github.io&quot;&gt;GitHub orgs site repo&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You also will need a Personal Access Token. You can create it &lt;a href=&quot;https://github.com/settings/tokens&quot;&gt;here&lt;/a&gt;. This token needs to be added as a secret to both repositories&lt;sup&gt;&lt;a href=&quot;#user-content-fn-secret&quot; id=&quot;user-content-fnref-secret&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;. You also will have to activate it in your main.workflow&lt;sup&gt;&lt;a href=&quot;#user-content-fn-mainwf&quot; id=&quot;user-content-fnref-mainwf&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; interface.&lt;/p&gt;
&lt;h2&gt;The Trigger Repository&lt;/h2&gt;
&lt;p&gt;On our &lt;code&gt;trigger&lt;/code&gt; we create the following action setup. On push we run the docker container defined under &lt;code&gt;./action&lt;/code&gt;. The only needed application in this container is curl to execute the webhook.&lt;/p&gt;
&lt;p&gt;This is &lt;code&gt;.github/main.workflow&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;workflow &quot;trigger&quot; {
  on = &quot;push&quot;
  resolves = [&quot;run-it&quot;]
}

action &quot;run-it&quot; {
  uses = &quot;./action&quot;
  secrets = [&quot;PA_TOKEN&quot;]
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is the content of &lt;code&gt;action/Dockerfile&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-docker&quot;&gt;FROM alpine
RUN apk add --no-cache curl
ADD entrypoint.sh /entrypoint.sh
ENTRYPOINT [&quot;/entrypoint.sh&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This is &lt;code&gt;action/entrypoint.sh&lt;/code&gt; with the curl post call:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;#!/bin/sh -l
sh -c &quot;curl -XPOST -H \&quot;Accept: \
application/vnd.github.everest-preview+json\&quot;  \
-H \&quot;Content-Type: application/json\&quot; \
-H \&quot;Authorization: token ${PA_TOKEN}\&quot; \
https://api.github.com/repos/fabianmoronzirfas/target/dispatches \
--data &apos;{\&quot;event_type\&quot;: \&quot;run-it\&quot;}&apos;&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;The Target Repository&lt;/h2&gt;
&lt;p&gt;This is &lt;code&gt;.github/main.workflow&lt;/code&gt;. Currently this is configured to build on the &lt;a href=&quot;https://developer.github.com/actions/creating-workflows/triggering-a-repositorydispatch-webhook/&quot;&gt;webhook repository_dispatch&lt;/a&gt; trigger.&lt;/p&gt;
&lt;p&gt;In this example the &lt;code&gt;args&lt;/code&gt; and the &lt;code&gt;env&lt;/code&gt; values are not used. Just for illustrating the possibility of having them. The repo waits on its webhook to be called and then executes the script in the docker container.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;workflow &quot;Build-it on webhook&quot; {
  on = &quot;repository_dispatch&quot;
  resolves = [&quot;execute build&quot;]
}

action &quot;execute build&quot; {
  uses = &quot;./action&quot;
  env = {
    NAME = &quot;fabianmoronzirfas&quot;
  }
  args = &quot;\&quot;This name is set as a env variable: $NAME\&quot;&quot;
  secrets = [&quot;PA_TOKEN&quot;]
}

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;The container has the following dependencies:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;git&lt;/li&gt;
&lt;li&gt;node.js&lt;/li&gt;
&lt;li&gt;npm&lt;/li&gt;
&lt;li&gt;openssh&lt;/li&gt;
&lt;li&gt;bash (optional)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is the content of &lt;code&gt;action/Dockerfile&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-docker&quot;&gt;FROM alpine
ADD entrypoint.sh /entrypoint.sh
RUN apk --update add --no-cache bash nodejs nodejs-npm git openssh
ENTRYPOINT [&quot;/entrypoint.sh&quot;]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;And this is the script that does the execution. Fist we output some infos to see if the install worked. The important part is the &lt;code&gt;npm run build&lt;/code&gt; call. It is a Node.js script that creates a file within the container. It is very simple in our case just a &lt;code&gt;require(&apos;fs&apos;).writeFileSync(&apos;./out-date&apos;, JSON.stringify(new Date()))&lt;/code&gt; to have some output.
Then it adds this file with &lt;code&gt;git&lt;/code&gt; and uses the Personal Access Token to &lt;code&gt;push&lt;/code&gt; to the repo via https.&lt;/p&gt;
&lt;p&gt;This is &lt;code&gt;action/entrypoint.sh&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;#!/bin/sh -l
sh -c &quot;echo &apos;in entrypoint.sh&apos;&quot;
sh -c &quot;echo &apos;NODE version:&apos; $(node -v)&quot;
sh -c &quot;echo &apos;NPM version:&apos; $(npm -v)&quot;
sh -c &quot;echo &apos;GIT version:&apos; $(git --version)&quot;
sh -c &quot;echo &apos;output of pwd:&apos; &amp;#x26;&amp;#x26; pwd&quot;
sh -c &quot;echo &apos;output of ls:&apos; &amp;#x26;&amp;#x26; ls&quot;
sh -c &quot;echo &apos;these are arguments set to the workflow&apos; &amp;#x26;&amp;#x26; echo ${*}&quot;
sh -c &quot;cd action &amp;#x26;&amp;#x26; npm test&quot;
sh -c &quot;cd action &amp;#x26;&amp;#x26; npm run build&quot;
sh -c &quot;cd action &amp;#x26;&amp;#x26; echo &apos;output of ls:&apos; &amp;#x26;&amp;#x26; ls&quot;
sh -c &quot;git config --global user.email &apos;fabian.moron.zirfas@gmail.com&apos;&quot;
sh -c &quot;git config --global user.name &apos;me-as-a-bot&apos;&quot;
sh -c &quot;echo &apos;git status&apos; &amp;#x26;&amp;#x26; git status&quot;
sh -c &quot;git add .&quot;
sh -c &quot;git commit -m &apos;added file&apos;&quot;
sh -c &quot;git push https://${PA_TOKEN}@github.com/fabianmoronzirfas/target.git&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;As soon as GitHub Actions are out of beta I will make these repos public so you can take a look at the source.&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-actions&quot;&gt;
&lt;p&gt;GitHub Actions are in beta while I am writing this (07. Jan 2019). &lt;a href=&quot;#user-content-fnref-actions&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-secret&quot;&gt;
&lt;p&gt;You can set your secrets under this url &lt;a href=&quot;https://github.com/%5BYOUR&quot;&gt;https://github.com/[YOUR&lt;/a&gt; USER NAME]/[YOUR REPO NAME]/settings/secrets &lt;a href=&quot;#user-content-fnref-secret&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 2&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-mainwf&quot;&gt;
&lt;p&gt;You will find your main.workflow here &lt;a href=&quot;https://github.com/%5BYOUR&quot;&gt;https://github.com/[YOUR&lt;/a&gt; USER NAME]/[YOUR REPO NAME]/blob/master/.github/main.workflow &lt;a href=&quot;#user-content-fnref-mainwf&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 3&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>Rename a GitHub Repo with a Linked Netlify Project</title><link>https://fabianmoronzirfas.me/blog/2020-08-05-rename-github-repo-with-linked-netlify-project/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2020-08-05-rename-github-repo-with-linked-netlify-project/</guid><pubDate>Wed, 05 Aug 2020 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Rename a GitHub Repo with a Linked Netlify Project&lt;/h1&gt;
&lt;p&gt;So what needs to be done before you do that ⤴?&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;stop all builds&lt;/li&gt;
&lt;li&gt;disable auto deploys on Netlify&lt;/li&gt;
&lt;li&gt;rename the repo on GitHub&lt;/li&gt;
&lt;li&gt;relink the repo on Netlify (should trigger a build)&lt;/li&gt;
&lt;li&gt;your environment variables might be gone - set them again&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;&lt;strong&gt;!Bonus Tip:&lt;/strong&gt; Don&apos;t set &lt;code&gt;NODE_ENV&lt;/code&gt; on &lt;code&gt;netlify.toml&lt;/code&gt;. Or your &lt;code&gt;devDepndencies&lt;/code&gt; wont be installed. (:facepalm:)&lt;/p&gt;</content:encoded></item><item><title>Misc Links from the interwebs</title><link>https://fabianmoronzirfas.me/blog/2021-04-13-links/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2021-04-13-links/</guid><pubDate>Tue, 13 Apr 2021 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Writing&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ink&lt;/strong&gt; interactive story authoring language | &lt;a href=&quot;https://www.inklestudios.com/ink/&quot;&gt;https://www.inklestudios.com/ink/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;VSCode&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Bash IDE&lt;/strong&gt; | Visual Studio Code extension utilizing the bash language server, that is based on Tree Sitter and its grammar for Bash and supports explainshell integration &lt;a href=&quot;https://marketplace.visualstudio.com/items?itemName=mads-hartmann.bash-ide-vscode&quot;&gt;https://marketplace.visualstudio.com/items?itemName=mads-hartmann.bash-ide-vscode&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;VSCode Debugger Tutorial&lt;/strong&gt; - Interactively debug Node.js apps with the built-in and Visual Studio Code debuggers &lt;a href=&quot;https://docs.microsoft.com/en-us/learn/modules/debug-nodejs/&quot;&gt;https://docs.microsoft.com/en-us/learn/modules/debug-nodejs/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Static Site Generator&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Explosiv&lt;/strong&gt; | A simple and powerful JSX Static Site Generator. &lt;a href=&quot;https://explosiv-vixalien.vercel.app/&quot;&gt;https://explosiv-vixalien.vercel.app/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;A Deep Dive Into &lt;strong&gt;Eleventy&lt;/strong&gt; Static Site Generator | &lt;a href=&quot;https://www.smashingmagazine.com/2021/03/eleventy-static-site-generator/&quot;&gt;https://www.smashingmagazine.com/2021/03/eleventy-static-site-generator/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Code Quality&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Eslint&lt;/strong&gt; Regex Plugin | &lt;a href=&quot;https://github.com/RunDevelopment/eslint-plugin-clean-regex&quot;&gt;https://github.com/RunDevelopment/eslint-plugin-clean-regex&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Load Testing Tools&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Vegeta&lt;/strong&gt; is a versatile HTTP load testing tool built out of a need to drill HTTP services with a constant request rate. It can be used both as a command line utility and a library. | &lt;a href=&quot;https://github.com/tsenart/vegeta&quot;&gt;https://github.com/tsenart/vegeta&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;k6&lt;/strong&gt; is a modern load testing tool, building on our years of experience in the load and performance testing industry. It provides a clean, approachable scripting API, local and cloud execution, and flexible configuration. | &lt;a href=&quot;https://github.com/k6io/k6&quot;&gt;https://github.com/k6io/k6&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Siege&lt;/strong&gt; is an http load testing and benchmarking utility. It was designed to let web developers measure their code under duress, to see how it will stand up to load on the internet. Siege supports basic authentication, cookies, HTTP, HTTPS and FTP protocols. It lets its user hit a server with a configurable number of simulated clients. Those clients place the server “under siege.” | &lt;a href=&quot;https://www.joedog.org/siege-home/&quot;&gt;https://www.joedog.org/siege-home/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Artillery&lt;/strong&gt; is a modern load testing and smoke testing solution designed for cross-functional teams that run microservice-based systems on AWS and rely on CI/CD to ship at high velocity | &lt;a href=&quot;https://artillery.io/&quot;&gt;https://artillery.io/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;SQL&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SQLite&lt;/strong&gt; is not a toy database | &lt;a href=&quot;https://antonz.org/sqlite-is-not-a-toy-database/&quot;&gt;https://antonz.org/sqlite-is-not-a-toy-database/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PSQL Tips&lt;/strong&gt; &lt;a href=&quot;https://mydbanotebook.org/psql_tips_all.html&quot;&gt;https://mydbanotebook.org/psql_tips_all.html&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Testing&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Playwright&lt;/strong&gt; | e2e testing in all browsers | &lt;a href=&quot;https://playwright.dev/&quot;&gt;https://playwright.dev/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Self Hosted Paas alternatives&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;coolify: Heroku &amp;#x26; Netlify alternative |
&lt;a href=&quot;https://coollabs.io/coolify&quot;&gt;https://coollabs.io/coolify&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Text Processing&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;TxtFiddle&lt;/strong&gt; JavaScript Playground for Text Manipulation &lt;a href=&quot;https://txtfiddle.com/&quot;&gt;https://txtfiddle.com/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TextBuddy&lt;/strong&gt; is a Mac app for manipulating text. A Swiss Army knife for plain text that is there when you need it and hidden when you don’t.
Faster than your IDE. Easier than the command line.&lt;a href=&quot;https://textbuddy.app/&quot;&gt;https://textbuddy.app/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Data Sources/OpenData&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Common Crawl&lt;/strong&gt; Everyone should have the opportunity to indulge their curiosities, analyze the world and pursue brilliant ideas. Small startups or even individuals can now access high quality crawl data that was previously only available to large search engine corporations. &lt;a href=&quot;https://commoncrawl.org/&quot;&gt;https://commoncrawl.org/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>ein neuer Tiefpunkt der BTC Ära</title><link>https://fabianmoronzirfas.me/blog/2021-04-16-de-ein-tiefpunkt-fuer-btc/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2021-04-16-de-ein-tiefpunkt-fuer-btc/</guid><pubDate>Fri, 16 Apr 2021 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Grundsätzlich mag ich ja die Idee von dezentralem und unabhängigen Geld, aber Kohle Kraftwerke wieder anwerfen um BTC zu schürfen ist ein neuer Tiefpunkt.&lt;/p&gt;
&lt;p&gt;&quot;A New Threat to New York’s Clean Energy Goals: Bitcoin Mining - New York Focus&quot; | &lt;a href=&quot;https://www.nysfocus.com/2021/04/13/new-york-bitcoin-mining-threat&quot;&gt;https://www.nysfocus.com/2021/04/13/new-york-bitcoin-mining-threat&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Wroooooomm</title><link>https://fabianmoronzirfas.me/blog/2024-03-20-wrrrrooooommm/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2024-03-20-wrrrrooooommm/</guid><pubDate>Wed, 20 Mar 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;strong&gt;Deutsche Bahn&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I don&apos;t have a drivers license but the last few month commuting with the Deutsche Bahn from Berlin to Braunschweig makes regret that decision.
I&apos;m commuting since 5 grade from a little village to Braunschweig with the Bahn to get to school until I moved to the city. When I studied and worked at the FHP I commuted from 2005 till 2017 from Berlin to Potsdam.
Not sure if I&apos;m an old man yelling war stories but it feels like it is getting worse with the DB.&lt;/p&gt;
&lt;p&gt;So wroooom wroooomm? 🏍️&lt;/p&gt;</content:encoded></item><item><title>Procrastination</title><link>https://fabianmoronzirfas.me/blog/2024-08-30-procrastination/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2024-08-30-procrastination/</guid><pubDate>Fri, 30 Aug 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import Procrastination from &quot;../../components/procrastination.tsx&quot;;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Procrastination is the act of unnecessarily and voluntarily delaying or postponing something despite knowing that there could be negative consequences for doing so.
&lt;a href=&quot;https://en.wikipedia.org/wiki/Procrastination&quot;&gt;Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;procrastination&gt;&lt;/procrastination&gt;&lt;/p&gt;</content:encoded></item><item><title>git log? WTF</title><link>https://fabianmoronzirfas.me/blog/2024-09-04-git-log/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2024-09-04-git-log/</guid><pubDate>Wed, 04 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Why is GitHub showing all these people as contributors? What did I do ~2012 to mix my history with some other project? See &lt;a href=&quot;https://github.com/ff6347/ff6347.github.io/graphs/contributors&quot;&gt;https://github.com/ff6347/ff6347.github.io/graphs/contributors&lt;/a&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;❯ git log --format=&apos;%aN&apos; | sort -u

Abhijeet Kumar
Alessio Caiazza
Alistair Hutchison
Andrea Schiavini
Anton Vattay
Brandon Philips
Darren Jeacocke
Fabian Morón Zirfas
Fabian Morón Zirfas
Jade
Jade Dominguez
James Fleeting
Jesse Chan-Norris
Kori Roys
Lukas Knuth
Martijn Pieters
Matt Swanson
Michael-Keith Bernard
Pradeep Nayak
Renovate Bot
Simon Starr
Stephen Ball
Tommaso Visconti
Yuya Saito
christine
dependabot[bot]
elephant
fabianmoronzirfas
fabiantheblind
ff6347
fmoronzirfas
greenkeeper[bot]
jayraj
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;After some digging I found that as the git noob that I was then I used some jekyll-bootstrap repo and did not remove the .git folder or something like that. &lt;code&gt;¯\_(ツ)_/¯&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Also I had a lot of different names in my &lt;code&gt;.gitconfig&lt;/code&gt; → &lt;code&gt;user.name&lt;/code&gt; over the years.&lt;/p&gt;</content:encoded></item><item><title>Exclude files from git diff</title><link>https://fabianmoronzirfas.me/blog/2024-09-16-til-git-diff-exclude/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2024-09-16-til-git-diff-exclude/</guid><pubDate>Mon, 16 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Normally the &lt;code&gt;git diff&lt;/code&gt; in a Node.js project with a package-lock.json present is a bit noisy. TIL to exclude a file from the diff.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;git diff -- . &apos;:!package-lock.json&apos;
&lt;/code&gt;&lt;/pre&gt;</content:encoded></item><item><title>Raycast Extension - CSS Color Names</title><link>https://fabianmoronzirfas.me/blog/2024-09-17-raycast-extension-css-color-names/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2024-09-17-raycast-extension-css-color-names/</guid><pubDate>Tue, 17 Sep 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve been wanting to built this &lt;a href=&quot;https://www.raycast.com/&quot;&gt;Raycast&lt;/a&gt; extension for quite some time from my Alfred extension that does the same. So here it is! Woohoo \o/&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://github.com/ff6347/css-color-names-raycast&quot;&gt;https://github.com/ff6347/css-color-names-raycast&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Allows you to filter through named CSS colors. Installation currently only by cloning and installing via import. I need to iron out some ideas before submitting to the raycast store.&lt;/p&gt;</content:encoded></item><item><title>So you know what I did this summer?</title><link>https://fabianmoronzirfas.me/blog/2024-10-01-you-know-what-i-did-this-summer/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2024-10-01-you-know-what-i-did-this-summer/</guid><pubDate>Tue, 01 Oct 2024 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;So I had some time since I left the Technologiestiftung. The next semester is about to start in two weeks. Here is a recap of my summer not in chronological order&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I found a flat. Will be moving partially soonish. Yay \o/ (it is in X-Berg again and I couldn&apos;t be happier about it. Whenever I ride through the Kiez I really feel at home)&lt;/li&gt;
&lt;li&gt;Started learning more CSS with &lt;a href=&quot;https://cssgrid.io/&quot;&gt;https://cssgrid.io/&lt;/a&gt; and &lt;a href=&quot;https://css-for-js.dev/&quot;&gt;https://css-for-js.dev/&lt;/a&gt; Very nice. Can&apos;t wait to reach the animation part.&lt;/li&gt;
&lt;li&gt;Incorporated some of the learnings into the syllabus for the upcoming semester.&lt;/li&gt;
&lt;li&gt;Ported an &lt;a href=&quot;https://github.com/ff6347/alfred-color-names&quot;&gt;Alfred CSS color names search&lt;/a&gt; extension of mine &lt;a href=&quot;https://github.com/ff6347/css-color-names-raycast&quot;&gt;to Raycast&lt;/a&gt; and made it more useful. I use it all the time when preparing my seminar.&lt;/li&gt;
&lt;li&gt;Also made a little &lt;a href=&quot;https://colornames.inpyjamas.dev/&quot;&gt;react app to search color names&lt;/a&gt; out of it so my students can use it as well (tried to have it on codepen.io but it is hard to maintain in one pen)&lt;/li&gt;
&lt;li&gt;Went pro on codepen.io to use it for my seminar&lt;/li&gt;
&lt;li&gt;Ported an &lt;a href=&quot;https://github.com/typefacts/alfred-special-characters/&quot;&gt;Alfred extension by typefaces&lt;/a&gt; for special characters &lt;a href=&quot;https://github.com/ff6347/raycast-special-characters&quot;&gt;to Raycast&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Applied for the project lead role for p5.js but didn’t land that job. It’s okay. I had to try.&lt;/li&gt;
&lt;li&gt;Revived some old Robert Penner easing code I once &lt;a href=&quot;https://github.com/ff6347/processing-easing&quot;&gt;wrote for Processing&lt;/a&gt; and &lt;a href=&quot;https://easing.inpyjamas.dev/&quot;&gt;ported it to p5.js&lt;/a&gt;. Still working on the docs though.&lt;/li&gt;
&lt;li&gt;Found out that I’m &lt;a href=&quot;https://github.com/hslu-dda/p5easing&quot;&gt;not the only one with that idea&lt;/a&gt;. Duh. Which interface is the better one? Any opinions?&lt;/li&gt;
&lt;li&gt;Toyed a little with the idea of a p5.js add on that uses ASTs to control CSS. I call it the &lt;code&gt;style()&lt;/code&gt; method. Still only a POC. I need to think about what API/features I want before I start writing code.&lt;/li&gt;
&lt;li&gt;Contributed a little to the new P5.js website. Boy there are so many broken links.&lt;/li&gt;
&lt;li&gt;Packed nearly all the things in my mother&apos;s flat. This was rollercoaster ride of emotions in the theme park called “her life” located in her fortress of solitude.&lt;/li&gt;
&lt;/ol&gt;</content:encoded></item><item><title>Design Mode (TIL)</title><link>https://fabianmoronzirfas.me/blog/2025-03-27-designmode/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-03-27-designmode/</guid><pubDate>Thu, 27 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import Url from &quot;../../components/design-mode-url.astro&quot;;&lt;/p&gt;
&lt;p&gt;There is something in the browser called &quot;Design Mode&quot;. &lt;strong&gt;Nice one!&lt;/strong&gt; You can enable it by running:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;document.designMode = &quot;on&quot;;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;To test this load this page (or others here in &lt;url&gt;) using the search params &lt;code&gt;?designmode=on&lt;/code&gt;. {}&lt;/url&gt;&lt;/p&gt;</content:encoded></item><item><title>Fabian Morón Surfers</title><link>https://fabianmoronzirfas.me/blog/2025-03-30-fabian-moron-surfer/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-03-30-fabian-moron-surfer/</guid><pubDate>Sun, 30 Mar 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Dictation makes this out of my name, sometimes: Fabian Morón Surfers&lt;/p&gt;
&lt;p&gt;I like it. Sounds pretty cool. 🏄‍♂️&lt;/p&gt;</content:encoded></item><item><title>CustomEvent</title><link>https://fabianmoronzirfas.me/blog/2025-04-02-til-customevnet/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-04-02-til-customevnet/</guid><pubDate>Wed, 02 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent&quot;&gt;https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>Emile Leary</title><link>https://fabianmoronzirfas.me/blog/2025-04-09-emile-leary/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-04-09-emile-leary/</guid><pubDate>Wed, 09 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;a href=&quot;https://en.m.wikipedia.org/wiki/Emile_Leray&quot;&gt;https://en.m.wikipedia.org/wiki/Emile_Leray&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;He was stranded twenty miles from the nearest settlement, with only enough food and water to last ten days. To survive, Leray used parts of his broken-down car to build a motorcycle, and twelve days after the accident was able to drive it to a village 20 miles away.&lt;/p&gt;
&lt;/blockquote&gt;</content:encoded></item><item><title>TPW and Cloudflare had a baby, ReadwoodSDK</title><link>https://fabianmoronzirfas.me/blog/2025-04-25-readwood-sdk/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-04-25-readwood-sdk/</guid><pubDate>Fri, 25 Apr 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;If you are into React and RSC (React Server Components) and Cloudflare this looks pretty neat &lt;a href=&quot;https://docs.rwsdk.com/&quot;&gt;https://docs.rwsdk.com/&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>AI Fatigue in the Morning</title><link>https://fabianmoronzirfas.me/blog/2025-05-29-ai-fatique/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-05-29-ai-fatique/</guid><pubDate>Thu, 29 May 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;In the beginning of the current AI wave, everything that came made us go &quot;ooohhhh&quot; and &quot;aaaah&quot;. We made it through the first year and generated images with a median of 12.42 fingers per person and were happy about it. We were okay to &quot;delve&quot; into the depths of poorly written content and saw a utopian future where none of us would have to work anymore, while the doomers were prepping their tinfoil hats and pulling their fillings so Skynet wouldn&apos;t get them.&lt;/p&gt;
&lt;p&gt;And now? We see diffusion-based models generate large text chunks in sub-seconds with GPT-3.5+ quality, and we are like, &quot;meh&quot;. Predictions say A{G|S}I will be here in 4, 8, 15, 16, 23, 42 years, or never. We see &quot;Younglings&quot; using the &quot;vibe force&quot; to dream up applications that would have taken us weeks and months of crawling through Stack Overflow to cobble together, and we are mad at them because &quot;they don&apos;t honor the platform,&quot; &quot;this code is not production-ready and hard to maintain if you are a &lt;em&gt;real&lt;/em&gt; programmer,&quot; and &quot;GET OFF MY WLAN, YOU DAMN KIDS!&quot;. Of course, they don&apos;t clap when the plane lands. It is normal for them that they come down now.&lt;/p&gt;
&lt;p&gt;What I want to say with this is: it&apos;s 7:20 in the morning, and I am having a coffee, so &lt;code&gt;¯\_(ツ)_/¯&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;xo[1] fab&lt;/p&gt;
&lt;p&gt;[1]: Do kids still use this? Or is it &lt;code&gt;&amp;#x3C;fill in word for embarrassing parents trying to stay cool&gt;&lt;/code&gt;?&lt;/p&gt;</content:encoded></item><item><title>til: JS Array.push returns new length</title><link>https://fabianmoronzirfas.me/blog/2025-06-19-til-js-push-returns-the-value/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-06-19-til-js-push-returns-the-value/</guid><pubDate>Thu, 19 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I never thought about what this might return nor that it even should return something. Today I learned that it is the new length of the array. So the code below return &lt;code&gt;1&lt;/code&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;console.log([].push(4));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Good to know.&lt;/p&gt;</content:encoded></item><item><title>One Does Not Just Simply Do That!</title><link>https://fabianmoronzirfas.me/blog/2025-09-04-one-does-not-simply-do-that/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-09-04-one-does-not-simply-do-that/</guid><pubDate>Thu, 04 Sep 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Doing tutorials, and saying things like &quot;&lt;strong&gt;just&lt;/strong&gt; do this&quot; and &quot;you &lt;strong&gt;simply&lt;/strong&gt; do that&quot; is often problematic. There are people who struggle with your topics, and for some it is not as simple as you describe it.&lt;/p&gt;
&lt;p&gt;Just simply saying…&lt;/p&gt;</content:encoded></item><item><title>Offline First or Always On</title><link>https://fabianmoronzirfas.me/blog/2025-10-21-offline-first-or-always-on/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-10-21-offline-first-or-always-on/</guid><pubDate>Tue, 21 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Don&apos;t you feel that it&apos;s nuts that we are in a world where some company has an outage for one day and everyone is touched by that?&lt;br&gt;
People are complaining that the helpdesk is down or they can&apos;t access their Asana boards or whatever. This is, of course, a problem of globalization, but I see this as an implementation problem we created.&lt;/p&gt;
&lt;p&gt;For example, when I&apos;m on the train and I try to open Figma to just sketch out something for a project, I can&apos;t generate a new file or access my existing files because most of our applications are designed online first.&lt;/p&gt;
&lt;p&gt;But if we would embrace an offline-first and then sync methodology, people could keep working or creating or reading or whatever, and we still could be on when possible, instead of always on and not possible if not on.&lt;/p&gt;</content:encoded></item><item><title>Code Of Conduct</title><link>https://fabianmoronzirfas.me/blog/2025-10-23-code-of-conduct/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-10-23-code-of-conduct/</guid><pubDate>Thu, 23 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I just started a class in the masters program by &lt;a href=&quot;https://frannnca.com/&quot;&gt;Franca Lopéz Barbera&lt;/a&gt;. Design in Many Words. I really like the idea of having a code of conduct for a seminar. I am going to &lt;del&gt;steal&lt;/del&gt; ähm, &lt;del&gt;copy&lt;/del&gt; also have this when doing teaching again.&lt;/p&gt;</content:encoded></item><item><title>Obsidian Plugins</title><link>https://fabianmoronzirfas.me/blog/2025-10-29-obsidian-plugins/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-10-29-obsidian-plugins/</guid><pubDate>Wed, 29 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Since I am studying again, and I have a lot of text and notes to handle, I moved to obsidian. And of course I&apos;m trying out the plug-in development. These are mostly coded using an LLM assistant, but I&apos;m trying to review every bit. The plug-ins are not yet published to the obsidian community plug-ins registry but there are easy ways to install these without hacking too much.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[!NOTE]
The latest version are in the beta channels not the latest on the main stable branch. Be on the edge with me&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Web Dev Playground&lt;/h2&gt;
&lt;p&gt;This plugin allows you to write a note with HTML, CSS and JavaScript or Typescript code blocks and view a compiled page in the sidebar.  Only the content of the code blocks is added to the page. There is no auto-complete, no linting, no formatting. Only code blocks that are denoted as the specific languages are parsed. Code blocks without language or with other languages like python or what whatsoever are ignored. The plug-in does auto compile and has an infinite loop protection. That&apos;s it.&lt;/p&gt;
&lt;p&gt;It really has become useful to create little notes about web development that I can see directly. Helps also to check if the code really works. I&apos;m looking for input on this.&lt;/p&gt;
&lt;p&gt;You can get the current state from this repo → &lt;a href=&quot;https://github.com/ff6347/obsidian-web-dev-playground&quot;&gt;github.com/ff6347/obsidian-web-dev-playground&lt;/a&gt; or you use &lt;a href=&quot;https://tfthacker.com/BRAT&quot;&gt;BRAT&lt;/a&gt; plugin into install it.&lt;/p&gt;
&lt;h2&gt;Canvas Context&lt;/h2&gt;
&lt;p&gt;This is a large undertaking and I&apos;m dog fooding this currently. The idea is to use the canvas as context provider for interaction with large language models. You can select a card or note on the canvas and plug-in will walk up the tree and pull in all the notes to create a message. You can send to last language model. There are some rules that I&apos;m not going to explain here because this is part of the repository end of the journey. Maybe you &lt;a href=&quot;https://github.com/ff6347/obsidian-canvas-context/discussions&quot;&gt;use the discussions&lt;/a&gt; on GitHub for feedback?&lt;/p&gt;
&lt;p&gt;You will need LM Studio or Ollama if you want to run local models. If you want to use the big models you need an OpenRouter or OpenAI API key.
You can get the current state from this repo →  &lt;a href=&quot;https://github.com/ff6347/obsidian-canvas-context&quot;&gt;github.com/ff6347/obsidian-canvas-context&lt;/a&gt; or you use &lt;a href=&quot;https://tfthacker.com/BRAT&quot;&gt;BRAT&lt;/a&gt; plugin into install it&lt;/p&gt;</content:encoded></item><item><title>MCP in experimentation or how I trust the trust of others</title><link>https://fabianmoronzirfas.me/blog/2025-10-31-mcp-security/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-10-31-mcp-security/</guid><pubDate>Fri, 31 Oct 2025 00:00:00 GMT</pubDate><content:encoded>&lt;h2&gt;Contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#the-security-risks-at-hand&quot;&gt;The Security Risks at Hand&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#problems-with-npm&quot;&gt;Problems With NPM&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#the-combination-of-service&quot;&gt;The Combination of Service&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#how-not-to-do-it&quot;&gt;How Not to Do It&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#a-more-complex-but-more-secure-solution&quot;&gt;A More Complex but More Secure Solution&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#containers-instead-of-bare-metal&quot;&gt;Containers Instead of Bare Metal&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#the-more-secure-mcp-configuration&quot;&gt;The More Secure MCP Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#speeding-things-up&quot;&gt;Speeding Things Up&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#bonus-be-even-more-restrictive&quot;&gt;Bonus: Be Even More Restrictive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;The Security Risks at Hand&lt;/h2&gt;
&lt;h3&gt;Problems With NPM&lt;/h3&gt;
&lt;p&gt;Node.js (I&apos;ll explain what this is later on) and JavaScript (JS) are tightly coupled to the &lt;a href=&quot;https://www.npmjs.com/&quot;&gt;Node Package Manager (NPM)&lt;/a&gt; ecosystem. This is a vaste registry of packages of ready made JavaScript modules. These modules serve different porpuses. There is a module for everything, so we don&apos;t have to reinvent the wheel every time we create a new project. It is easy to use, easy to add and saves us a ton of time. By adding some module we create a dependency. These other developers also don&apos;t want to reinvent the wheel, and so they also add dependencies to their packages. You might get the idea. We create a deeply nested tree of dependencies and transitive dependencies&lt;sup&gt;&lt;a href=&quot;#user-content-fn-transitive&quot; id=&quot;user-content-fnref-transitive&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;This means: When I add some code to my project as a dependency, I also have to trust that the author of this code trusts the authors of the dependencies he added, and they trust the other authors and so on.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The current state of the NPM ecosystem is problematic. In the last few months, we saw elaborate supply chain attacks against the registry and prominent packages that have millions of downloads. If you are interested in what happened, read &lt;a href=&quot;https://jfrog.com/blog/shai-hulud-npm-supply-chain-attack-new-compromised-packages-detected/&quot;&gt;Shai-Hulud npm supply chain attack - new compromised packages detected&lt;/a&gt;&lt;sup&gt;&lt;a href=&quot;#user-content-fn-shaihulud&quot; id=&quot;user-content-fnref-shaihulud&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; or &lt;a href=&quot;https://www.koi.ai/blog/phantomraven-npm-malware-hidden-in-invisible-dependencies&quot;&gt;PhantomRaven: NPM Malware Hidden in Invisible Dependencies | Koi Blog&lt;/a&gt;. I won&apos;t go into the details of these, because this is too technical and others can explain this better than I can.&lt;/p&gt;
&lt;h3&gt;The Combination of Service&lt;/h3&gt;
&lt;p&gt;Often, one MCP is harmless, only the combination of several MCPs create
an attack vector. If you, for example, restrict the LLM from accessing the internet and only feed it trusted context, that you yourself reviewed or created, the instructions you generally get are fine. As soon as you add untrusted context into the mix, we get something &lt;a href=&quot;https://simonwillison.net/2025/Jun/16/the-lethal-trifecta/&quot;&gt;Simon Willison coined &quot;The Lethal Trifecta&quot;&lt;/a&gt;. He states that these three components:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Access to you private data&lt;/li&gt;
&lt;li&gt;The ability to externally communicate&lt;/li&gt;
&lt;li&gt;Exposure to untrusted content&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Create a big security risk. I urge you to read his blog, it is a great resource for understanding LLMs.&lt;/p&gt;
&lt;h2&gt;How Not to Do It&lt;/h2&gt;
&lt;p&gt;When using the widely propagated method of installing a MCP service, we normally get an instruction to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;install Claude Desktop or ChatGPT Desktop&lt;/li&gt;
&lt;li&gt;and Node.js.&lt;/li&gt;
&lt;li&gt;Together with the instruction to add the below JavaScript Object Notation (JSON) somewhere in the settings of one of these desktop apps.&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
	&quot;mcpServers&quot;: {
		&quot;filesystem&quot;: {
			&quot;command&quot;: &quot;npx&quot;,
			&quot;args&quot;: [
			&quot;-y&quot;,
    	&quot;@modelcontextprotocol/server-filesystem&quot;,
    	&quot;/Users/username/Desktop&quot;,
    	&quot;/Users/username/Downloads&quot;
			]
		}
	}
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;This seems easy. Let us examine what we are adding here. The desktop applications are not the problem. But we also install &lt;a href=&quot;https://nodejs.org/en&quot;&gt;Node.js&lt;/a&gt;. This is a program that can execute JS code on your computer. Don&apos;t get me wrong. I love Node and I have been programming with it for more than a decade. It is a great tool. The great thing and the problem is that it can do anything. It was created around 2009. The original author of Node.js, Ryan Dahl, started years later another project called Deno, with the intention to fix the problems he introduced with Node.js. But this is not a rant about Node or a history lesson.&lt;/p&gt;
&lt;p&gt;Back to the problem. When we run code with Node.js, it has same rights that you have on your computer without entering your password. It can read and also write files, make web requests, and so on. It could extract information about you that can range from your email, to which programs you use, and even install arbitrary code that gets executed when you do something.&lt;/p&gt;
&lt;p&gt;Back to our little innocent JSON snippet we added to our LLMs settings:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;&quot;command&quot;: &quot;npx&quot;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Together with &lt;code&gt;node&lt;/code&gt; we install a tool called &lt;code&gt;npm&lt;/code&gt; (yes the same name as the registry), and with &lt;code&gt;npm&lt;/code&gt; there comes a little (very useful) tool called &lt;code&gt;npx&lt;/code&gt;. This stands for something like &quot;node package execute&quot;. It takes as an argument the name of a module from the NPM registry. Here it is &lt;code&gt;@modelcontextprotocol/server-filesystem&lt;/code&gt;. What it does is&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;download the code from this module and all its dependencies and transitive dependencies&lt;/li&gt;
&lt;li&gt;and execute it.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Normally, it asks the user if it should do that and he needs to confirm this. This wont work with an LLM. Therefore, we pass it the flag &lt;code&gt;-y&lt;/code&gt; for &quot;yes, do that!&quot; in the &lt;code&gt;args&lt;/code&gt; of our JSON snippet.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;&quot;args&quot;: [
      &quot;-y&quot;,
      &quot;@modelcontextprotocol/server-filesystem&quot;,
      &quot;/Users/username/Desktop&quot;,
      &quot;/Users/username/Downloads&quot;
    ]
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;What comes next in the snippet are arguments for the code that &lt;code&gt;npx&lt;/code&gt; finds under &lt;code&gt;@modelcontextprotocol/server-filesystem&lt;/code&gt; in the registry. This has nothing to do with access restrictions imposed onto Node.js. This is only for the module we execute. If you take a look at the code of this module, you will see that it does use these as &quot;allowed directories&quot; and it throws an error if the executor, here the LLM, tries to run code against other directories. So maybe this is enough security for you and you call it a day and call me a nerd or fearmonger. It is okay. See you.&lt;/p&gt;
&lt;p&gt;For the rest of you who want to continue — bear with me. Here comes the trust thing again. I can look up the code for this module and see what it does, and NPM recently added a feature to see the actual code of a package in the registry, but the advice we get is to trust the package and all its future versions. Because the string &lt;code&gt;@modelcontextprotocol/server-filesystem&lt;/code&gt; tells &lt;code&gt;npx&lt;/code&gt;, &quot;Hey, get the latest version of that module.&quot; You also often see &lt;code&gt;@modelcontextprotocol/server-filesystem@latest&lt;/code&gt;, which is the same as the reference before. To be a little more secure, you could pin the version of the module whose author you trust. Adding the version number instead of latest would already make a big difference. &lt;code&gt;@modelcontextprotocol/server-filesystem@2025.8.21&lt;/code&gt;. This is a little less convenient. You won&apos;t get the latest version once it is out, but you can vet the code on NPM and then use this one module. If you encounter any bugs, you can take a look at NPM again and see if a newer version is there that fixed that bug.&lt;/p&gt;
&lt;p&gt;That&apos;s it, Fabian? This is why you add all those thoughts to the entropy of the web?&lt;/p&gt;
&lt;p&gt;Well, no. The problem is still that the author trusted other authors. If he did not vet and pin his dependencies, there is still the chance that someone exchanges the code beneath our eyes without us knowing. In JavaScript and the NPM ecosystem, there is a little something that is called &quot;semantic versioning&quot;. It tells &lt;code&gt;npm&lt;/code&gt; that it is okay to use a specific range of versions of a module. Like saying, &quot;All the bug fixes (also called patches) are okay.&quot; Or, &quot;Yes, it is okay to use new version that is higher than the currently used one, as long as it does not break something.&quot; Which is a great idea but also means I have to trust the authors in my tree all the wy down.&lt;/p&gt;
&lt;p&gt;In the recent supply chain attacks, this is what happened. Malicious actors took over the accounts of authors who are trustworthy and changed their modules by releasing a new patch version to the NPM registry. Since they were required by other modules, this code could have gotten added to your project without you even knowing.&lt;/p&gt;
&lt;p&gt;What can we do about this? Vendoring all dependencies? Never touch a computer again? Ignore it?&lt;/p&gt;
&lt;h2&gt;A More Complex but More Secure Solution&lt;/h2&gt;
&lt;p&gt;With a little effort, we should be able to run these tools in a more secure way. We need to cut the access for the command from the rest of the computer and still give it access to those two folders we want it to act on.&lt;/p&gt;
&lt;h3&gt;Containers Instead of Bare Metal&lt;/h3&gt;
&lt;p&gt;Instead of installing Node.js directly onto our machine, we install &lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt; or even better &lt;a href=&quot;https://podman.io/&quot;&gt;Podman&lt;/a&gt;. Podman and Docker are applications called container runtimes. As the name suggests, they containerize an application. Besides giving the application everything it needs to run, it also isolates the application from the host system, which is your computer&lt;sup&gt;&lt;a href=&quot;#user-content-fn-poddocker&quot; id=&quot;user-content-fnref-poddocker&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;. They will serve Node.js for us where we can run the MCP services. I will show you the commands for Docker, since it is the more mature and widely used one. With more funding, more tutorials and it has an easy installable free version for MacOS.&lt;/p&gt;
&lt;p&gt;The great thing about them is that we not only isolate the application, but we can also tell it specifically which folders are allowed to be accessed by the container. I will show you the command we have to add to our configuration and dissect it step by step.&lt;/p&gt;
&lt;h3&gt;The More Secure MCP Configuration&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;{
      &quot;mcpServers&quot;: {
        &quot;my-sandboxed-server&quot;: {
          &quot;command&quot;: &quot;docker&quot;,
          &quot;args&quot;: [
            &quot;run&quot;,
            &quot;--interactive&quot;,
            &quot;--rm&quot;,
            &quot;--volume&quot;, &quot;&amp;#x3C;absolute path to folder you want your LLM to have access to&gt;:/usr/project&quot;,
            &quot;--workdir&quot;, &quot;/usr/project&quot;,
            &quot;node:24-bookworm-slim&quot;,
            &quot;npx&quot;,
            &quot;-y&quot;,
            &quot;@modelcontextprotocol/server-filesystem@latest&quot;,
            &quot;/usr/project&quot;
          ]
        }
      }
    }
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;The first thing you see is we replace the &lt;code&gt;npx&lt;/code&gt; command with &lt;code&gt;docker&lt;/code&gt;. This is the executable we want to run.&lt;/li&gt;
&lt;li&gt;Then we add the &lt;code&gt;run&lt;/code&gt; command which tells Docker to run a container.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;--interactive&lt;/code&gt; allows you to feed input into the container while it&apos;s running (e.g., for a shell or an interactive program).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--rm&lt;/code&gt; tells Docker to automatically delete the container&apos;s filesystem &lt;strong&gt;after it exits&lt;/strong&gt;. This sounds like a bad idea since we want to interact with the filesystem.&lt;/li&gt;
&lt;li&gt;This is where the &lt;code&gt;--volume&lt;/code&gt; comes in. We are telling Docker to connect a specific folder from the host system into the container. This way, the container can read and write to that folder, which is necessary for the filesystem MCP to function properly.&lt;/li&gt;
&lt;li&gt;The next entry &lt;code&gt;&amp;#x3C;absolute path to folder you want your LLM to have access to&gt;:/usr/project&quot;&lt;/code&gt; is:
&lt;ul&gt;
&lt;li&gt;the absolute path to the folder you want your LLM to have access to on your system. You need to replace the &lt;code&gt;&amp;#x3C;path to folder&gt;&lt;/code&gt; with an actual path on your machine. On MacOS, you can get the absolute path of a folder by CTRL-clicking (&lt;code&gt;⌃&lt;/code&gt;) or right-clicking on a folder and then, when the menu is open, holding OPTION &lt;code&gt;⌥&lt;/code&gt;. This will change the &lt;code&gt;copy&lt;/code&gt; entry to &lt;code&gt;copy &quot;&amp;#x3C;folder name&gt;&quot; as pathname&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;After the &lt;code&gt;:&lt;/code&gt; is the path inside the container. Here it is &lt;code&gt;/usr/project&lt;/code&gt;. This is inside the container. The LLM will only see the path &lt;code&gt;/usr/project&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If you want to be even more secure, you can restrict the container&apos;s access to your host to be read-only by adding &lt;code&gt;:ro&lt;/code&gt; at the end of it all. But this will prevent the MCP from writing any files to that folder.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--workdir&lt;/code&gt; tells the container to start in a specific directory, which is &lt;code&gt;/usr/project&lt;/code&gt; in this case.&lt;/li&gt;
&lt;/ul&gt;
&lt;!---
I think this created an error.
`--user` This tells the container to run as a specific user, in this case, `node`, which is a non-root user in the container. This is also a security measure to prevent potential exploits.
--&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;node:24-bookworm-slim&lt;/code&gt; This is the Docker image we are running our container from. You can choose a different version if you prefer. I just recommend using the &lt;a href=&quot;https://nodejs.org/en/about/previous-releases&quot;&gt;latest long term support (LTS) version of Node.js&lt;/a&gt;. Take a look at &lt;a href=&quot;https://hub.docker.com/_/node&quot;&gt;https://hub.docker.com/_/node&gt;&lt;/a&gt;. There you can find a long list of available versions.&lt;/li&gt;
&lt;li&gt;Finally, we reached the point where we are at the same command as we had it before. We run &lt;code&gt;npx&lt;/code&gt; but now it is properly sandboxed in a container.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-y&lt;/code&gt; tells &lt;code&gt;npx&lt;/code&gt; to automatically answer &quot;yes&quot; to any prompts, which is needed for the MCP server not to hang on prompts.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@modelcontextprotocol/server-filesystem@latest&lt;/code&gt; is the package we want to run. As you already learned, I am using the less secure version where with the &lt;code&gt;latest&lt;/code&gt; tag. &lt;strong&gt;I urge you not to do that.&lt;/strong&gt; I use this here since any version number I add might be outdated in a few weeks. Go to &lt;a href=&quot;https://www.npmjs.com/package/@modelcontextprotocol/server-filesystem?activeTab=versions&quot;&gt;the version tab of the module&lt;/a&gt; and get the version number you want to use.&lt;/li&gt;
&lt;li&gt;Last one. Then we are done. We now tell the module which path it should have access to. Here it is &lt;code&gt;/usr/project&lt;/code&gt; This is the same path we connected or our local folder to earlier and we also set as the working directory for the container. This time, we are inside the container. The module has no &quot;knowledge&quot; of our host&apos;s filesystem.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;With this more verbose version, we can now run the MCP server within a secure sandbox. Of course, we need to determine for each MCP we want to use if this is the right approach.&lt;/p&gt;
&lt;h3&gt;Speeding Things Up&lt;/h3&gt;
&lt;p&gt;To make this work faster on the first run I would also suggest downloading the image beforehand. Yes some new word to make this short: The image is the blueprint from which the container is created. You can do this by running the following command in your Terminal.app:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker pull node:24-bookworm-slim
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you find the Terminal.app scary. You can use the Docker Desktop application to pull images and manage containers with a graphical user interface (GUI). Just insert the &lt;code&gt;node:24-bookworm-slim&lt;/code&gt; into the search bar from the Desktop application and download (pull) it from there.&lt;/p&gt;
&lt;h2&gt;Bonus: Be Even More Restrictive&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;--network none&lt;/code&gt; if network access isn&apos;t needed. This will prevent the container from accessing the internet.&lt;/li&gt;
&lt;li&gt;Use Podman instead of Docker if you want to run containers without root.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Yes. This was a long one. I hope you found it informative and you could follow along. Using LLMs on our computers is marvelous. We are entering a new era of computing in my opinion. As always, this comes with a price. As the internet was also created with trust in mind (hi there, good old HTTP), we had to learn the hard way that there will be people misusing our trust. The only thing we can do is learn the tools and understand what is actually happening under the hood. If you have any questions, use one of the channels below to ask.&lt;/p&gt;
&lt;hr&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-transitive&quot;&gt;
&lt;p&gt;Transitive means if my module A depends on module B and B depends on C, C is a transitive dependency of A. &lt;a href=&quot;#user-content-fnref-transitive&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-shaihulud&quot;&gt;
&lt;p&gt;Yes, pretty nerdy name, but we bless the maker and his water. &lt;a href=&quot;#user-content-fnref-shaihulud&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 2&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-poddocker&quot;&gt;
&lt;p&gt;The big difference between Docker and Podman is that the latter does not need root access to run containers. This makes it even more secure. &lt;a href=&quot;#user-content-fnref-poddocker&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 3&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>Learning MCP</title><link>https://fabianmoronzirfas.me/blog/2025-11-05-learning-mcp/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-11-05-learning-mcp/</guid><pubDate>Wed, 05 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I am currently attending Professor Reto Wettach&apos;s seminar about: &quot;Language as an Interface - Interface Design in times of AI and MCPs/Agentic AI&quot;. That is why I am trying to wrap my head around MCPs and all that.&lt;/p&gt;
&lt;h2&gt;contents&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#how-learning-works-currently-for-me&quot;&gt;How Learning Works Currently for Me&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#insights&quot;&gt;Insights&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#implementation-flow&quot;&gt;Implementation Flow&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#code-examples&quot;&gt;Code Examples&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#hostjs&quot;&gt;host.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#clientjs&quot;&gt;client.js&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#serverjs&quot;&gt;server.js&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#conclusion&quot;&gt;Conclusion&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;How Learning Works Currently for Me&lt;/h2&gt;
&lt;p&gt;For me the best way to learn a new technology is reading about it and reading a simple implementation for better usage insight. Then write down some notes (in form of this blog more often I hope). Nowadays a LLM comes into the mix. In this case it was pretty nice. I read some parts of &lt;a href=&quot;https://modelcontextprotocol.io/specification/2025-06-18&quot;&gt;MCP Specification&lt;/a&gt; (enough for grasping the basics) and asked an LLM some questions afterwards.&lt;/p&gt;
&lt;h2&gt;Insights&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Security is based on trust.&lt;/li&gt;
&lt;li&gt;In the implementation the distinction between host and client is fuzzy.&lt;/li&gt;
&lt;li&gt;In the spec the host should orchestrate several clients.&lt;/li&gt;
&lt;li&gt;The clients connect to the servers which provide tools, resources and prompts.&lt;/li&gt;
&lt;li&gt;The servers are based on JSON-RPC. Which is an action oriented API.
&lt;ul&gt;
&lt;li&gt;JSON RPC uses only POST requests and does not need HTTP. Can also be over TCP, Websocket or stdio. JSON-RPC is transport agnostic.&lt;/li&gt;
&lt;li&gt;A problem with stdio is that you are not allowed to log to stdout. :(&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;There are Requests that need a response and share an id for mapping and notifications which don&apos;t need one.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;MCP is actually an abstraction layer on top of model tool calling capability.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Anthropic skills are workflow specifications that is again on top of MCP.&lt;/li&gt;
&lt;li&gt;MCP is meant for discoverability.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Implementation Flow&lt;/h3&gt;
&lt;p&gt;Flow: &lt;a href=&quot;https://platform.openai.com/docs/guides/function-calling&quot;&gt;1&lt;/a&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Host spawns MCP server, gets available tools&lt;/li&gt;
&lt;li&gt;Converts MCP tool schemas to OpenAI function format&lt;/li&gt;
&lt;li&gt;Sends user query + functions to OpenAI&lt;/li&gt;
&lt;li&gt;OpenAI returns function call decision&lt;/li&gt;
&lt;li&gt;Host executes tool via MCP&lt;/li&gt;
&lt;li&gt;Host sends result back to OpenAI for natural language response&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Run: &lt;code&gt;OPENAI_API_KEY=your_key node host.js&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Here are the three most interesting (code) snippets to understand MCP.&lt;/p&gt;
&lt;h2&gt;Code Examples&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;TBD: Explanation of how these three files relate to each other and how to run them together.&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;host.js&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;// host.js - LLM host with OpenAI integration
import { spawn } from &quot;child_process&quot;;
import { createInterface } from &quot;readline&quot;;
import https from &quot;https&quot;;

class LLMHost {
	constructor(apiKey) {
		this.apiKey = apiKey;
		this.client = null;
		this.messageId = 0;
		this.pendingRequests = new Map();
		this.tools = [];
	}

	async start() {
		// Start MCP server
		this.client = spawn(&quot;node&quot;, [&quot;server.js&quot;]);

		const rl = createInterface({
			input: this.client.stdout,
			crlfDelay: Infinity,
		});

		rl.on(&quot;line&quot;, (line) =&gt; {
			const msg = JSON.parse(line);
			if (msg.id &amp;#x26;&amp;#x26; this.pendingRequests.has(msg.id)) {
				const { resolve } = this.pendingRequests.get(msg.id);
				this.pendingRequests.delete(msg.id);
				resolve(msg.result);
			}
		});

		// Initialize MCP connection
		await this.mcpRequest(&quot;initialize&quot;, {
			protocolVersion: &quot;2024-11-05&quot;,
			capabilities: {},
			clientInfo: { name: &quot;llm-host&quot;, version: &quot;1.0.0&quot; },
		});

		// Get available tools from MCP server
		const { tools } = await this.mcpRequest(&quot;tools/list&quot;);
		this.tools = tools;
		console.log(
			&quot;MCP tools loaded:&quot;,
			tools.map((t) =&gt; t.name),
		);

		// Process user query
		await this.processUserQuery(&quot;What is 15 + 27?&quot;);
	}

	async processUserQuery(query) {
		console.log(`\nUser: ${query}`);

		// Convert MCP tools to OpenAI function format
		const functions = this.tools.map((t) =&gt; ({
			name: t.name,
			description: t.description,
			parameters: t.inputSchema,
		}));

		// Call OpenAI with function calling
		const completion = await this.callOpenAI(
			[{ role: &quot;user&quot;, content: query }],
			functions,
		);

		const message = completion.choices[0].message;

		// Check if LLM wants to call a function
		if (message.function_call) {
			const { name, arguments: argsStr } = message.function_call;
			const args = JSON.parse(argsStr);

			console.log(`LLM calling tool: ${name}(${JSON.stringify(args)})`);

			// Execute tool via MCP
			const result = await this.mcpRequest(&quot;tools/call&quot;, {
				name,
				arguments: args,
			});

			// Send result back to LLM for final response
			const finalCompletion = await this.callOpenAI(
				[
					{ role: &quot;user&quot;, content: query },
					message,
					{
						role: &quot;function&quot;,
						name,
						content: result.content[0].text,
					},
				],
				functions,
			);

			console.log(`Assistant: ${finalCompletion.choices[0].message.content}`);
		} else {
			console.log(`Assistant: ${message.content}`);
		}
	}

	async callOpenAI(messages, functions) {
		const data = JSON.stringify({
			model: &quot;gpt-4&quot;,
			messages,
			functions,
			function_call: &quot;auto&quot;,
		});

		return new Promise((resolve, reject) =&gt; {
			const req = https.request(
				{
					hostname: &quot;api.openai.com&quot;,
					path: &quot;/v1/chat/completions&quot;,
					method: &quot;POST&quot;,
					headers: {
						&quot;Content-Type&quot;: &quot;application/json&quot;,
						Authorization: `Bearer ${this.apiKey}`,
						&quot;Content-Length&quot;: data.length,
					},
				},
				(res) =&gt; {
					let body = &quot;&quot;;
					res.on(&quot;data&quot;, (chunk) =&gt; (body += chunk));
					res.on(&quot;end&quot;, () =&gt; resolve(JSON.parse(body)));
				},
			);

			req.on(&quot;error&quot;, reject);
			req.write(data);
			req.end();
		});
	}

	async mcpRequest(method, params) {
		const id = ++this.messageId;
		this.client.stdin.write(
			JSON.stringify({
				jsonrpc: &quot;2.0&quot;,
				id,
				method,
				params,
			}) + &quot;\n&quot;,
		);

		return new Promise((resolve) =&gt; {
			this.pendingRequests.set(id, { resolve });
		});
	}
}

// Usage: node host.js
const apiKey = process.env.OPENAI_API_KEY;
if (!apiKey) {
	console.error(&quot;Set OPENAI_API_KEY environment variable&quot;);
	process.exit(1);
}

await new LLMHost(apiKey).start();
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;client.js&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;import { spawn } from &quot;child_process&quot;;
import { createInterface } from &quot;readline&quot;;

class MCPClient {
	constructor() {
		this.process = null;
		this.messageId = 0;
		this.pendingRequests = new Map();
	}

	connect(serverScript) {
		// Spawn server process
		this.process = spawn(&quot;node&quot;, [serverScript]);

		// Setup line-by-line reading from stdout
		const rl = createInterface({
			input: this.process.stdout,
			crlfDelay: Infinity,
		});

		// Handle incoming messages
		rl.on(&quot;line&quot;, (line) =&gt; {
			const message = JSON.parse(line);

			if (message.id &amp;#x26;&amp;#x26; this.pendingRequests.has(message.id)) {
				const { resolve, reject } = this.pendingRequests.get(message.id);
				this.pendingRequests.delete(message.id);

				if (message.error) {
					reject(message.error);
				} else {
					resolve(message.result);
				}
			}
		});

		this.process.stderr.on(&quot;data&quot;, (data) =&gt; {
			console.error(&quot;Server error:&quot;, data.toString());
		});

		return this.initialize();
	}

	async request(method, params = {}) {
		const id = ++this.messageId;
		const message = {
			jsonrpc: &quot;2.0&quot;,
			id,
			method,
			params,
		};

		// Send JSON-RPC request
		this.process.stdin.write(JSON.stringify(message) + &quot;\n&quot;);

		// Wait for response
		return new Promise((resolve, reject) =&gt; {
			this.pendingRequests.set(id, { resolve, reject });
		});
	}

	async initialize() {
		return this.request(&quot;initialize&quot;, {
			protocolVersion: &quot;2024-11-05&quot;,
			capabilities: {},
			clientInfo: { name: &quot;simple-client&quot;, version: &quot;1.0.0&quot; },
		});
	}

	async listTools() {
		return this.request(&quot;tools/list&quot;);
	}

	cleanup() {
		this.process.kill();
	}
}

// Usage
const client = new MCPClient();
await client.connect(&quot;./server.js&quot;);
const tools = await client.listTools();
console.log(
	&quot;Tools:&quot;,
	tools.tools.map((t) =&gt; t.name),
);
client.cleanup();
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;server.js&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-js&quot;&gt;import { createInterface } from &quot;readline&quot;;

// Setup stdin/stdout communication
const rl = createInterface({
	input: process.stdin,
	output: process.stdout,
	terminal: false,
});

// Handle incoming JSON-RPC messages
rl.on(&quot;line&quot;, (line) =&gt; {
	const message = JSON.parse(line);

	// Route to handler
	if (message.method === &quot;initialize&quot;) {
		handleInitialize(message);
	} else if (message.method === &quot;tools/list&quot;) {
		handleToolsList(message);
	} else if (message.method === &quot;tools/call&quot;) {
		handleToolCall(message);
	}
});

function send(message) {
	console.log(JSON.stringify(message));
}

function handleInitialize(request) {
	send({
		jsonrpc: &quot;2.0&quot;,
		id: request.id,
		result: {
			protocolVersion: &quot;2024-11-05&quot;,
			capabilities: {
				tools: {},
			},
			serverInfo: {
				name: &quot;simple-server&quot;,
				version: &quot;1.0.0&quot;,
			},
		},
	});
}

function handleToolsList(request) {
	send({
		jsonrpc: &quot;2.0&quot;,
		id: request.id,
		result: {
			tools: [
				{
					name: &quot;add&quot;,
					description: &quot;Add two numbers&quot;,
					inputSchema: {
						type: &quot;object&quot;,
						properties: {
							a: { type: &quot;number&quot; },
							b: { type: &quot;number&quot; },
						},
						required: [&quot;a&quot;, &quot;b&quot;],
					},
				},
			],
		},
	});
}

function handleToolCall(request) {
	const { name, arguments: args } = request.params;

	if (name === &quot;add&quot;) {
		const result = args.a + args.b;
		send({
			jsonrpc: &quot;2.0&quot;,
			id: request.id,
			result: {
				content: [
					{
						type: &quot;text&quot;,
						text: `Result: ${result}`,
					},
				],
			},
		});
	}
}

// Keep process alive
process.stdin.resume();
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;TBD: Summary of key learnings and next steps.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Here is the full &lt;a href=&quot;https://kagi.com/assistant/d0ec1459-05b9-4fed-b3ec-f1617b9035a6&quot;&gt;conversation&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>Context About Colombian Authors</title><link>https://fabianmoronzirfas.me/blog/2025-11-07-context-about-colombian-authors/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-11-07-context-about-colombian-authors/</guid><pubDate>Fri, 07 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;import { Picture, Image } from &quot;astro:assets&quot;;
import costeno from &apos;../../images/1024px-el_costeno.jpg&apos;;&lt;/p&gt;
&lt;figure&gt;
&lt;img src=&quot;{costeno}&quot; alt=&quot;El Costeño by José Agustín Arrieta (1802-1879), Public domain, via Wikimedia Commons.&quot; width=&quot;{1024}&quot; height=&quot;{1322}&quot; layout=&quot;constrained&quot;&gt;
&lt;figcaption&gt;
*El Costeño by José Agustín Arrieta (1802-1879), Public domain, via [Wikimedia Commons.](https://commons.wikimedia.org/wiki/File:El_Coste%C3%B1o.jpg)*
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Yesterday, on November the 6th 2025, the  during class, I said something in the realm of &quot;You can&apos;t understand people from the South.&quot; I want to expand on this.  It wasn&apos;t meant as an attack on all of you. I am also European, even if I don&apos;t look like that. I also can&apos;t fully grasp what it means to be from &quot;the South&quot;.  So it should have actually been &quot;We can&apos;t understand people from the South&quot;. &lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; I also think when reading, like Franca already urged us to, we have to take into account how the authors  where socialized. Here is some context about Colombia, which  in my opinion makes it easier to understand the desire of freeing the worlds of oppression and allow the existence of parallel realities as Alfredo Gutiérrez Borrero or Arturo Escobar suggest.&lt;/p&gt;
&lt;p&gt;These things about Colombia I experienced myself or got told first hand from my father who was Colombian, born in 1942. He emigrated to Germany in the end of the 1960s and returned to Colombia in 2006 where he lived and thought Physics at the Universidad de Cartagena until 2016.&lt;/p&gt;
&lt;p&gt;One thing is to understand is the diversity of cultures that make up Colombia. The Caribbean coast of Colombia for example has many areas where the descendants of slaves settled. This means we have the cultures of Berbers (Amazigh), Arabs, Egyptians, Nubians, Mandinka, Malinke, Bambara, Songhai, Fulani, Wolof, Serer, Akan, Ashanti, Fante, Dagomba, Ewe, Yoruba, Igbo, Hausa, Kanuri, Fon, Baoulé, Bété, Senufo, Bamileke, Duala, Bantu-speaking peoples. Together with the peoples who already inhabited these areas later known as Colombia and Venezuelas, Panama and Costa Rica, and the Yucatan. Mixed with the Spanish, the French, the British. All these cultures did not just disappear. They mixed and created something new. Due this &quot;mescla&quot;&lt;sup&gt;&lt;a href=&quot;#user-content-fn-2&quot; id=&quot;user-content-fnref-2&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;2&lt;/a&gt;&lt;/sup&gt; the Spanish spoken at the coast, &quot;el costeño&quot;, is very different from other dialects. People from other regions of Colombia told me they don&apos;t understand it.
This area is also one of the most bio diverse areas on earth. Everything moves, crawls, flies, swims, grows, decays all around you.
Remember this is only the Caribbean coast. That is why I think I get that thought pluralism can easily grow in someone who is socialized in such an environment.&lt;/p&gt;
&lt;p&gt;Then there is the oppression. In the colonial period through the Spanish from 1499 until ~1810 a huge part of the Quimbaya (Pacific coast), Chibchas (Andes) and Kalina (Atlantic coast) population was eradicated. From the 6 Million indigenous remained 600.000 in the Colombian population.
In the recent history this country has been in a constant civil war from the mid 1960 until 2016.  Many cruelties were happening from all the sides of this conflict. The communist opposition (FARC), the state, the paramilitary groups, and from the 70s on, also from the narcotic trafficking cartels. Due to the war and drugs that was proclaimed in the 70s, the United States of America also executed military actions in this sovereign country.&lt;/p&gt;
&lt;p&gt;I got the feeling that there&apos;s a big distrust within the population against each other. People living in gated communities if they can afford that or behind bars, if not.&lt;/p&gt;
&lt;p&gt;This creates a very strong opposition against being oppressed, being seen as &quot;the periphery&quot;, being colonized, being the backyard of others.&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;I also think we can&apos;t understand a lot of things. I can&apos;t understand feminism because I am not a woman. I can&apos;t understand Islam. I can understand racism because because I experience it. &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-2&quot;&gt;
&lt;p&gt;&quot;Mescla&quot; is the Spanish word for mixture. &lt;a href=&quot;#user-content-fnref-2&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 2&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>Biga Ranx tonight</title><link>https://fabianmoronzirfas.me/blog/2025-11-08-biga_ranx/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-11-08-biga_ranx/</guid><pubDate>Sun, 09 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I am going to see &lt;a href=&quot;https://en.wikipedia.org/wiki/Biga_Ranx&quot;&gt;Biga*Ranx&lt;/a&gt; tonight!&lt;/p&gt;</content:encoded></item><item><title>Marble Fountain by Will Morrison</title><link>https://fabianmoronzirfas.me/blog/2025-11-10-marble-fountain/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-11-10-marble-fountain/</guid><pubDate>Mon, 10 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Marble Fountain by Will Morrison
&lt;a href=&quot;https://willmorrison.net/posts/marble-fountain/&quot;&gt;https://willmorrison.net/posts/marble-fountain/&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Very beautiful work and great presentation. Via &lt;a href=&quot;https://news.ycombinator.com/item?id=45866697&quot;&gt;HN&lt;/a&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Finally, a huge thanks to my friend Alex who listened to me ramble about marbles for several months every day while walking home from work, gave a ton of helpful input, and lived with the dozens of ball bearings scattered across our apartment.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Yes thanks Alex! :D&lt;/p&gt;</content:encoded></item><item><title>reponse to: Tools Shape Our Products by Boris Müller</title><link>https://fabianmoronzirfas.me/blog/2025-11-13-reponse-to-tools-shape-our-products/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-11-13-reponse-to-tools-shape-our-products/</guid><pubDate>Thu, 13 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Hi Boris, in your article &lt;a href=&quot;https://borism.medium.com/tools-shape-our-products-fa121366dac4&quot;&gt;Tools Shape Our Products&lt;/a&gt; you argue that the code editor is this arcane empty text field we are staring at when coding. In my opinion you are exaggerating (maybe to make your point?).&lt;/p&gt;
&lt;p&gt;When I open a Terminal. It does not look like this anymore:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/images/blog/not-like-this-terminal.png&quot; alt=&quot;An image of MacOS Terminal with bash prompt loaded&quot;&gt;&lt;/p&gt;
&lt;p&gt;It looks more like this:&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/images/blog/terminal.png&quot; alt=&quot;An image of MacOS Terminal with iTerm2 and fish shell loaded&quot;&gt;&lt;/p&gt;
&lt;p&gt;And also the editor. We are not using the plainest of plain text.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/images/blog/not-like-this-editor.png&quot; alt=&quot;An image of an empty text editor with the hello world in JavaScript&quot;&gt;&lt;/p&gt;
&lt;p&gt;It is actually more like this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/images/blog/editor.png&quot; alt=&quot;An image of VSCode with debugger and chat open&quot;&gt;&lt;/p&gt;
&lt;p&gt;There is so much information and tooling to make my life easier. Debuggers, Breakpoints, Linters, Code Formatters, Static Typing, Code Generators. The list goes on. Even the color of the words I type contain information about what I am doing. when I type the application suggest what I could type next based on context.&lt;/p&gt;
&lt;p&gt;But I get your point.&lt;/p&gt;</content:encoded></item><item><title>Speculative Software Design == What if?</title><link>https://fabianmoronzirfas.me/blog/2025-11-14-speculative-software-design/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-11-14-speculative-software-design/</guid><pubDate>Fri, 14 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Maybe you noticed, or maybe not, I started studying again and this makes me also write a little more. Which is nice. I also read a lot more then technical documentation. So here is a thought on something to read.&lt;/p&gt;
&lt;p&gt;Speculative (Software) Design is actually the question of &quot;What if?&quot;. So here is a book about this.&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;/assets/images/blog/what-if-by-randall-munroe.png&quot; alt=&quot;What if? by Randall Munroe (Serious Scientific Answers to Absurd Hypothetical Questions)&quot;&gt;&lt;/p&gt;</content:encoded></item><item><title>The New (Old) Developer</title><link>https://fabianmoronzirfas.me/blog/2025-11-16-the-new-developer/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-11-16-the-new-developer/</guid><pubDate>Sun, 16 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;m am pretty sure this has been said already on the internet. I still want to write down my thoughts — just for me and maybe you get some insight to.&lt;/p&gt;
&lt;p&gt;It&apos;s Sunday morning, 6:15, and I&apos;m sitting in my kitchen&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. So I had this idea about this  project we&apos;ve been working on in the last workshops session about AI at @fh-potsdam.&lt;/p&gt;
&lt;p&gt;This is not a mission critical project. It&apos;s totally vibe-coded, but I&apos;m still putting in some thought because I like how it turned out.&lt;/p&gt;
&lt;p&gt;Since it&apos;s 6:15, I really don&apos;t want to get to my computer and start hacking away. Also, my little son is sleeping in my bed, so there&apos;s no place to start hacking.&lt;/p&gt;
&lt;p&gt;Enter Claude Code for the web.&lt;/p&gt;
&lt;p&gt;Just for fun, I described my idea to Claude Code on my phone in a few words and let it hack away on this small refactor. Then there comes this other idea while thinking about the first one, and I spin up a second session and let Claude hack on this idea as well.&lt;/p&gt;
&lt;p&gt;Now, while I&apos;m writing this, I have already two pull requests waiting for me to review them and I am still &lt;a href=&quot;https://inpyjamas.dev/&quot;&gt;in my pyjamas&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Another project. For a seminars about language as an interface, I started to build a prototype for an iOS application. Since I know &lt;a href=&quot;https://ui.shadcn.com/&quot;&gt;shad/cn&lt;/a&gt; a little and we got introduced to &lt;a href=&quot;https://www.figma.com/make/&quot;&gt;Figma Make&lt;/a&gt; in the last session, I prompted my way to a visual draft of my iOS application within 30 minutes. I took screenshots of this application and passed them on to Claude in Xcode. After another 30 minutes and some debugging with Claude, I had a working first draft of my application on my phone. Now I&apos;m in the stage of this project to test out the UX and write tickets for Claude. Since I am not familiar with Swift, it is the developer, and I am the project manager (PM). Creating this prototype would have taken me weeks to learn the basics of Swift and SwitftUI to get where I am now after about half a day.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Bottom line: These tools are really a game changer, and I&apos;m sure some of the AI skeptics and hardcore developers will tell me about non-maintainable code and all those things, it taking away the fun in coding, watch out for the robot apocalypse, &lt;strong&gt;KILL ALL HUMANS KILL ALL HUMANS&lt;/strong&gt;, and so on… But still, I am not a developer per se, I&apos;m not a pure visual designer. I&apos;m a creative technologist, and my main field is creating ideas, exploring technology and building prototypes. Yes, sometimes I do fullstack work, and yes, sometimes I do frontend work. But for these projects mentioned above, I&apos;m the designer, I&apos;m the project manager, and I&apos;m the creative director and I am enabled to create these artifacts in such a short period that would never have been possible three years ago.&lt;/p&gt;
&lt;p&gt;So, why writing all this? The problem we have is that I am developing software since more or less 15 years&lt;sup&gt;&lt;a href=&quot;#user-content-fn-2&quot; id=&quot;user-content-fnref-2&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;. I have been writing scripts even longer. For Adobe InDesign, for example when working on layouts with &lt;a href=&quot;https://www.grenzfarben.de/&quot;&gt;Grenzfarben&lt;/a&gt;. I started creative coding in around 2007 or 2008 with Processing. I used Open Frameworks. I used Terraform. I used AWS. I used Postgres and SQLite. I used docker a lot. I used JavaScript in the front and back-end. I am dipping my toes into Ruby right now. So, there is a lot of coding experience under my belt. That&apos;s why I&apos;m confident that I can build such projects and also debug them later on. Or decide if this is just a prototype or something to pursue. I can ask questions about it, and I can answer to colleagues what is happening in there even if I haven&apos;t internalized Swift + SwiftUI.&lt;/p&gt;
&lt;p&gt;During my time at the University of Arts Braunschweig, I also taught students of the visual communications how to code with JavaScript on the front-end and later on we started vibe coding. Every time when they were vibe coding, the assistant pumped out code that they couldn&apos;t explain and had to depend on the assistant to do changes. They pretty often came 70-80% of the way and then got stuck.&lt;/p&gt;
&lt;p&gt;So when we are automating away all those juniors, we will end in a state where there is nobody to debug our code because the greybeards will die out, and then you are left with vibe coders and 80% of your project done my dear PM of the future.&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;Yes, I know it&apos;s early, but this is another topic. &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-2&quot;&gt;
&lt;p&gt;This sounds wired. It is not the problem that &lt;strong&gt;I&lt;/strong&gt; am developing but keep in reading above. &lt;a href=&quot;#user-content-fnref-2&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 2&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>NPM trusted publishing rabbits hole</title><link>https://fabianmoronzirfas.me/blog/2025-11-23-npm-trusted-publishing-rabbits-hole/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-11-23-npm-trusted-publishing-rabbits-hole/</guid><pubDate>Sun, 23 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Ok, I fell into a rabbit&apos;s hole of npm dependencies today. So I want to just jot down quickly what I had to do. Since the supply chain attacks recently, NPM is deprecating classic tokens. This means we need to use more granular tokens that also need to be rotated every 90 days. This is something I really don&apos;t want to take care of and I really don&apos;t want to set up some automation to rotate tokens using the NPM API (if there is something like that).&lt;/p&gt;
&lt;p&gt;So I went for &lt;a href=&quot;https://docs.npmjs.com/trusted-publishers&quot;&gt;trusted publishing&lt;/a&gt;. This is something that the registry (npmjs.org) and the CI provider (like GitHub.com) do some handshaking. Not sure what is going on behind the scenes, but they say that&apos;s their thing. So I will go for it. The problem I had here is that there need to be some changes to the repos. First it&apos;s &lt;strong&gt;the permissions on the GitHub workflow.&lt;/strong&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;name: Node.js CI
permissions:
  contents: write
  id-token: write # needed for OIDC
  packages: write
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;I also had to go into the settings of my published module on npmjs.org and tell npm which workflow is allowed to publish.&lt;/p&gt;
&lt;p&gt;Pretty straight forward until this point. Now here comes the rabbits hole.&lt;/p&gt;
&lt;p&gt;I&apos;ve been using a shared semantic release config we created the Technologiestiftung Berlin a lot, but this needed to be updated. It needs to use the latest semantic-release (currently 25.0.2) and the semantic-release npm plug-in (currently 13.1.2). Since I don&apos;t want to interfere with the current setup on all the repos Technologiestiftung&apos;s version uses, I went for a &lt;a href=&quot;https://github.com/ff6347/semantic-release-config/&quot;&gt;fork&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Another thing that had to be done was to &lt;strong&gt;remove the NPM_TOKEN environment variable&lt;/strong&gt; so this doesn&apos;t interfere with the trusted publishing.&lt;/p&gt;
&lt;p&gt;I also had an error because my &lt;code&gt;package.json&lt;/code&gt; file didn&apos;t have the &lt;a href=&quot;https://docs.npmjs.com/cli/v11/configuring-npm/package-json#repository&quot;&gt;repository field&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Things you do on a Sunday morning for a package that is some kind of abandon-ware. &lt;code&gt;¯\_(ツ)_/¯&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Update 2025-12-25&lt;/h2&gt;
&lt;p&gt;I just ran into the same issue here without consulting my notes. m(
Once again for future me:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Setup trusted publishing on npmjs.org&lt;/li&gt;
&lt;li&gt;Needs semantic-release &gt;= 25&lt;/li&gt;
&lt;li&gt;Needs npm semantic release plugin &gt;= 13&lt;/li&gt;
&lt;li&gt;Optional use @ff6347/semantic-release-config &gt;= 1.0.6&lt;/li&gt;
&lt;li&gt;The Workflow or job needs the following permissions:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;permissions:
  contents: write
  issues: write
  pull-requests: write
  id-token: write
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Remove any &lt;code&gt;NPM_TOKEN&lt;/code&gt; env variable&lt;/li&gt;
&lt;li&gt;The package.json needs the &lt;code&gt;repository&lt;/code&gt; field:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-json&quot;&gt;&quot;repository&quot;: {
  &quot;type&quot;: &quot;git&quot;,
  &quot;url&quot;: &quot;git+https://github.com/OWNER/REPO.git&quot;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Persist the credentials on the jobs checkout step (happens by default):&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;persist-credentials: true
&lt;/code&gt;&lt;/pre&gt;
&lt;ul&gt;
&lt;li&gt;Semantic release steps needs &lt;code&gt;GITHUB_TOKEN&lt;/code&gt; from the env&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;&lt;code class=&quot;language-yaml&quot;&gt;env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Link to a &lt;a href=&quot;https://github.com/ff6347/named-css-colors/blob/af6c24e8d2c035ac75d119e1a58f6ef1a51da6f9/.github/workflows/test.yml&quot;&gt;working workflow&lt;/a&gt;
Link to a &lt;a href=&quot;https://github.com/ff6347/named-css-colors/blob/af6c24e8d2c035ac75d119e1a58f6ef1a51da6f9/package.json&quot;&gt;working package.json&lt;/a&gt;&lt;/p&gt;</content:encoded></item><item><title>p5 Easing is in Use</title><link>https://fabianmoronzirfas.me/blog/2025-11-25-p5-easing-is-in-use/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-11-25-p5-easing-is-in-use/</guid><pubDate>Tue, 25 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Yesterday I learned that Pieter-Jan Vaernewijck and his students are using my &lt;a href=&quot;https://github.com/ff6347/p5-easing&quot;&gt;p5js easing&lt;/a&gt; library over at &lt;a href=&quot;https://www.devine.be/en/&quot;&gt;devine.be&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;How did find out? I broke the build by &lt;a href=&quot;/blog/2025-11-23-npm-trusted-publishing-rabbits-hole/&quot;&gt;setting up trusted publishing to npm&lt;/a&gt; and they could not use the CDN unpkg version any more.&lt;/p&gt;
&lt;p&gt;This makes me very happy.&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;No. Not that I broke it and they could not use it. That people are using it. Duh! &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>Living with SLE</title><link>https://fabianmoronzirfas.me/blog/2025-11-26-living-with-sle/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-11-26-living-with-sle/</guid><pubDate>Wed, 26 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Okay. This one is something very personal. Maybe you are interested. I was diagnosed with &lt;a href=&quot;https://en.wikipedia.org/wiki/Lupus&quot;&gt;systemic lupus erythematosus (SLE)&lt;/a&gt; in 2016, the day Olivia told me that I am going to be a father. So at least there were good news and bad news that day.
Before you go “poor Fab” in your head: It is okay.&lt;sup&gt;&lt;a href=&quot;#user-content-fn-2&quot; id=&quot;user-content-fnref-2&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; There are people way worse than my mild SLE. I manage. Sure, your own suffering is the biggest suffering you know, but still I feel lucky — life is suffering I heard.
Why am I writing this down? I am working on a project about it. So I a looking a lot into it and because I was told writing things down helps to digest them. So here we go.&lt;/p&gt;
&lt;p&gt;I think the SLE was there long before the diagnosis and the butterfly rash that came in 2016. As an adolescent I already had frequent inflammatory diseases and some (allegedly) viral arthritis at the age of 14 after some mosquito bites from Colombia for a year. This kept on in my twenties with spotted hair loss and other inflammatory diseases.&lt;/p&gt;
&lt;p&gt;Being young and in Berlin in the 2000s did not help. Drinking, smoking and other things with techno parties at the Panorama Bar. It was a rave. Let’s say my lifestyle from the mid-1990s till the mid-2010s was a little too wild for having such an illness.&lt;sup&gt;&lt;a href=&quot;#user-content-fn-3&quot; id=&quot;user-content-fnref-3&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;The SLE got worse over the years. I think my peak was around 2021/2022 where other things came together that were very stressful. What helped to get me out of this?&lt;/p&gt;
&lt;p&gt;Due to the meds I am taking I stopped drinking alcohol. This is great. I have been sober for more or less 1250 days. I stopped smoking. Maybe 1000 days without a cigarette? This is way harder than drinking. I do sports. This is my temple. I have been a student at the Kung Fu Academy Berlin since 2008. This already helped me channel energy away from partying to something more productive. When I have fatigue days this is what gets me up and running again. It is wired in a way that I can’t get out of bed to do nearly anything, but when I make it into the “classroom” it gets better. My head clears and I feel happy afterwards. Food is also a big thing. I sometimes do phases without sugar. Without milk products. Without gluten. I take Vitamin D every day. I use sunscreen every day. And of course my meds.&lt;/p&gt;
&lt;p&gt;Let me put a rhetorical question here to keep this floating: How is it to live with that?&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;3&lt;/a&gt;&lt;/sup&gt; Well, I have to be more conscious about what I do. I can’t go to the beach and have a sunny day. (I can, but then I have a bad day or several afterwards.) I have to plan with the energy I have. Of course you have to do that without lupus as well, but exhausting myself can throw me into a flare, which is bad. I have to stay away from stress as best as possible, because this also ends in a flare. And I have to watch out for infections. The SLE is actually my immune system going very strong — too strong — and attacking my body. This is where the immunosuppressiva come in. They try to lower my system. Therefore it is more likely that I catch a cold and all those other annoying things you can get from the Kita. My rule of thumb is: Don’t eat the kid’s plate. They eventually sneeze on it. And don’t get me started on pink eye. I just have to see the sign that some kid had it and it already itches.&lt;/p&gt;
&lt;p&gt;My biggest problem currently is insomnia. This is why I start writing blog posts at 4 in the morning. Full circle.&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-2&quot;&gt;
&lt;p&gt;Nooo not about the kids. ;) &lt;a href=&quot;#user-content-fnref-2&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-3&quot;&gt;
&lt;p&gt;But I can only see this in retrospect now. It still was fun. &lt;a href=&quot;#user-content-fnref-3&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 2&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;Thanks for asking. &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 3&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>Rotating Cubes</title><link>https://fabianmoronzirfas.me/blog/2025-11-28-rotating-cubes/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-11-28-rotating-cubes/</guid><pubDate>Tue, 25 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;/assets/images/blog/rotating-cubes.png&quot; alt=&quot;white 3D cubes stacked into one another with only edges. Low poly. Chromatic abboreation&quot;&gt;&lt;/p&gt;
&lt;p&gt;This is something I quickly vibe coded on the way home from Potsdam. It is based on some other students results from the Unity XR workshp at FH Potsdam. I liked the stacked cubes idea. But what intrigued me the most was the artifacts that came from the low quality rendering in the Oculus Quest 2. This wasn&apos;t intended by the others.
To remind me of this effect I created this artifact in threejs.
Bottom line. Use the restrictions and limitations of a system to create effects. Not every effect/look needsto be inteded See &lt;a href=&quot;https://ff6347.github.io/loficubed/&quot;&gt;the live version here&lt;/a&gt; and the &lt;a href=&quot;https://github.com/ff6347/loficubed&quot;&gt;source code here&lt;/a&gt;. It is &lt;strong&gt;DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSED&lt;/strong&gt;&lt;/p&gt;</content:encoded></item><item><title>BärGPT by the CityLAB for Berlin</title><link>https://fabianmoronzirfas.me/blog/2025-11-29-baegpt-from-the-citylab/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-11-29-baegpt-from-the-citylab/</guid><pubDate>Sat, 29 Nov 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I am really proud of my friends over at CityLAB and Technologiestiftung Berlin for getting this up and running. A custom made solution for using large language models in the Berlin administration ☞ &lt;a href=&quot;https://www.baergpt.berlin/&quot;&gt;BärGPT&lt;/a&gt;. I have been watching from the sideline how this came to life. A great piece of work. Read this as well &lt;a href=&quot;https://citylab-berlin.org/en/blog/baergpt-the-technical-deep-dive-for-the-new-ai-assistant-for-berlins-public-administration/&quot;&gt;BärGPT: The technical Deep Dive for the new AI assistant for Berlin’s public administration&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;And you know what? The whole thing is &lt;a href=&quot;https://github.com/technologiestiftung/baergpt&quot;&gt;open source&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Chapeau my friends!&lt;/p&gt;</content:encoded></item><item><title>November 2025 and 0.5 × December 2025</title><link>https://fabianmoronzirfas.me/blog/2025-12-14-november-2025-and-0-5-december-2025/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-12-14-november-2025-and-0-5-december-2025/</guid><pubDate>Sun, 14 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;So what happened this November. I will try to summarize some things that landed in my daily notes and what I did.&lt;/p&gt;
&lt;h2&gt;Thesis Topics and Master Studies&lt;/h2&gt;
&lt;p&gt;I had some ideas for my thesis topics landing in my inbox. Here are some keywords. I might expand on this later on.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Small Language Models:&lt;/strong&gt;  I really think this is a topic worth exploring. I already trained a SML on some personal data.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Gestalt Theory:&lt;/strong&gt; In 2016 I did this Gestalten In Code seminar @FH;P and I want to dig deeper into this. Maybo together with SLMs?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Color Theory:&lt;/strong&gt; Same as the ones above. I want to dig into training a model for color creation&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Learn Code the Hard Way:&lt;/strong&gt; For the master we need to do some teaching experience. I was thinking about a seminar that does the following. First generate code using LLMs. Second part try to write this yourself. See also  &lt;a href=&quot;https://arxiv.org/html/2507.22900v4&quot;&gt;New Kid in the Classroom: Exploring Student Perceptions of AI Coding Assistants&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Student Paper:&lt;/strong&gt; I am working on a project that should end up in a student paper about: &quot;On Device Small Language Models for Symptom Diary P.R.O. Measures&quot;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Reading Group:&lt;/strong&gt; We did a lot of reading about, post-colonialism, design justice, equality, oppression, pluralism and and and. All related to design. Makes we wanna ditch the term title Design a little.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Workshops:&lt;/strong&gt; There Where also some pretty interesting workshops going on.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Unity&lt;/li&gt;
&lt;li&gt;D3&lt;/li&gt;
&lt;li&gt;Spatial Typography&lt;/li&gt;
&lt;li&gt;AI&lt;/li&gt;
&lt;li&gt;Touch Designer
Below you can see some videos. I&apos;ll add no additional comments here.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Find a Font:&lt;/strong&gt; The hardest task besides naming things&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Links&lt;/h2&gt;
&lt;h3&gt;Mine&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ff6347/wimage&quot;&gt;ff6347/wimage&lt;/a&gt; Project together with Lele from the AI workshop. A AI pipeline using vision from moonshot to get related wikipedia articles&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ff6347/renovate-config&quot;&gt;ff6347/renovate-config&lt;/a&gt; Updated my renovate config to have a cooldown phase.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ff6347/loficubed&quot;&gt;ff6347/loficubed&lt;/a&gt; Something I made claude create when I was on the train. Some fellow students showed some interesting visual and I got inspired to make something similar.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ff6347/ffckoverlays&quot;&gt;ffckoverlays&lt;/a&gt; Firefox WebExtension. Right-click any overlay to remove it. Inspired by the Chrome extension &quot;F*ck Overlays&quot; (&lt;a href=&quot;https://chrome.google.com/webstore/detail/fck-overlays/ppedokobpbdajgiejhnjfbdjlgobcpkp&quot;&gt;https://chrome.google.com/webstore/detail/fck-overlays/ppedokobpbdajgiejhnjfbdjlgobcpkp&lt;/a&gt;). Actually just a fork I fixed to make it work again.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ff6347/semantic-release-config&quot;&gt;semantic-release-config&lt;/a&gt; Worked on my personal semantic release config.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Others&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Utopia as a Method &lt;a href=&quot;https://www.critical.design/post/utopia-as-a-method&quot;&gt;https://www.critical.design/post/utopia-as-a-method&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;BIRD conference &lt;a href=&quot;https://www.bird-international-research-in-design.org/conferences&quot;&gt;https://www.bird-international-research-in-design.org/conferences&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Hartumut Rosa - &lt;a href=&quot;https://en.wikipedia.org/wiki/Hartmut_Rosa&quot;&gt;https://en.wikipedia.org/wiki/Hartmut_Rosa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Olafur Eliasson - &lt;a href=&quot;https://en.wikipedia.org/wiki/Olafur_Eliasson&quot;&gt;https://en.wikipedia.org/wiki/Olafur_Eliasson&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;James Auger &lt;a href=&quot;https://www.rmit.edu.au/profiles/a/james-auger2&quot;&gt;https://www.rmit.edu.au/profiles/a/james-auger2&lt;/a&gt; | &lt;a href=&quot;https://speculativeedu.eu/interview-james-auger/&quot;&gt;https://speculativeedu.eu/interview-james-auger/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Helga Schmid: &lt;a href=&quot;https://birkhauser.com/en/book/9783035618112&quot;&gt;https://birkhauser.com/en/book/9783035618112&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/gulbanana/gg&quot;&gt;gulbanana/gg&lt;/a&gt; Gui for JJ&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/metaspartan/gotui&quot;&gt;metaspartan/gotui&lt;/a&gt; TUI toolkit in go&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/kiki-ki/go-qo&quot;&gt;kiki-ki/go-qo&lt;/a&gt; CLI tool for queriying JSON, TSV, CSV data using SQL syntax&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/vercel/streamdown&quot;&gt;vercel/streamdown&lt;/a&gt; Streaming Markdown&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/pomdtr/tweety&quot;&gt;pomdtr/tweety&lt;/a&gt; A terminal in the browser
&lt;a href=&quot;https://github.com/shun126/livelinkface_arkit_receiver&quot;&gt;shun126/livelinkface_arkit_receiver&lt;/a&gt; LiveLinkFace ARKit Receiver for Blender&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/timescale/pg-aiguide&quot;&gt;timescale/pg-aiguide&lt;/a&gt; MCP/ Claude plugin for writing better SQL&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/chr15m/runprompt&quot;&gt;chr15m/runprompt&lt;/a&gt; Tool for running &lt;a href=&quot;https://google.github.io/dotprompt/&quot;&gt;dotprompt&lt;/a&gt; files. Which as I understand it is a plain text prompt format that is vendor agnostic and contains metadata to make prompts more reproducable.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/sindresorhus/is-online&quot;&gt;sindresorhus/is-online&lt;/a&gt;. A simple package to check if the internet connection is up.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/karpathy/nn-zero-to-hero&quot;&gt;karpathy/nn-zero-to-hero&lt;/a&gt; Neural Networks: Zero to Hero by Andrej Karpathy.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/karpathy/build-nanogpt&quot;&gt;karpathy/build-nanogpt&lt;/a&gt; Video+code lecture on building nanoGPT from scratch&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/rowboatlabs/rowboat&quot;&gt;rowboatlabs/rowboat&lt;/a&gt; RowboatX is a local-first CLI for creating background AI agents with full shell access. (Haven&apos;t tried it yet, but looks interesting)
&lt;a href=&quot;https://github.com/AnandChowdhary/continuous-claude&quot;&gt;AnandChowdhary/continuous-claude&lt;/a&gt; Make Claude run until it is done. (Define &quot;done&quot; though?)&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/kaushiksrini/parqeye&quot;&gt;kaushiksrini/parqeye&lt;/a&gt; Nevwer hat to use Parquet files but I see them popping up more often. Since they are not plain text this is needed to take a look inside them.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tconbeer/harlequin&quot;&gt;tconbeer/harlequin&lt;/a&gt; A SQL IDE for Your Terminal.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/jbranchaud/til&quot;&gt;jbranchaud/til&lt;/a&gt; Extensive TIL repo by someone else.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tldr-pages/tlrc&quot;&gt;tldr-pages/tlrc&lt;/a&gt; TLDR cli seems dead. This is the replacement.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/kavishdevar/librepods&quot;&gt;kavishdevar/librepods&lt;/a&gt; Free airpods from Apple.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Obsidian&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/tariquesani/obsidian-merge-dailynotes&quot;&gt;tariquesani/obsidian-merge-dailynotes&lt;/a&gt; I wanted to merge some notes to create this monthly digest. So this is one thing I found.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/Quorafind/Obsidian-Daily-Notes-Editor&quot;&gt;Quorafind/Obsidian-Daily-Notes-Editor&lt;/a&gt; Same thing here. Wanted to merge notes.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://github.com/ff6347/obsidian-base-merge&quot;&gt;obsidian-base-merge&lt;/a&gt; In the End i settled for my own Obsidian plugin. It merges all notes in the current base into an new file.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Videos&lt;/h2&gt;
&lt;h3&gt;Spatial Typography&lt;/h3&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/0jyo2lnymt4?si=NSWJdtOMQ2jYmYPB&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;h3&gt;Unity&lt;/h3&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/WYZU_b0UyDg?si=3QPPXFA_kcCbmxZZ&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/-bwLYsPNSYw?si=zubiOguL453q247m&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;h3&gt;D3&lt;/h3&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/7oZYLGMYy0w?si=cVIVPNGVf_3CRqgw&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;&lt;/iframe&gt;
&lt;h3&gt;TouchDesigner&lt;/h3&gt;
&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/cagHAFALR28?si=DXpHtXYw6LDnJ62I&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share&quot; referrerpolicy=&quot;strict-origin-when-cross-origin&quot; allowfullscreen&gt;&lt;/iframe&gt;</content:encoded></item><item><title>TIL. Fritz Box just truncates a password if it is to long</title><link>https://fabianmoronzirfas.me/blog/2025-12-20-til-fritz-box-just-truncates-a-password-if-it-is-to-long/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-12-20-til-fritz-box-just-truncates-a-password-if-it-is-to-long/</guid><pubDate>Sat, 20 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Holy shit! I am in the process of setting up a system wide pi-hole and my new FritzBox didn&apos;t tell me that the new password was to long. So it just truncated it and went on with the password change. m(&lt;/p&gt;</content:encoded></item><item><title>Where to publish code if not on GitHub?</title><link>https://fabianmoronzirfas.me/blog/2025-12-20-where-to-publish-stuff/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-12-20-where-to-publish-stuff/</guid><pubDate>Sat, 20 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Lately if been using the the phrase &quot;if it&apos;s free, you&apos;re the product&quot; pretty often. For search I use Kagi.com. For mail I use Fastmail, ProtonMail and Uberspace and pay for them.
I&apos;ve stopped looking at and feeding into social media networks over the past few years. You can find the occasional image from the street on Mastodon from me, but the rest isn&apos;t that interesting anymore. I don&apos;t doom-scroll any of them - except for Hacker News.&lt;/p&gt;
&lt;p&gt;So now here is my problem. I publish a lot on GitHub -- Owned by MSFT. I have over 600 repositories, many of them Abandonwear™, or just some proof of concept, some code for workshops, some organization dedicated to a specific topic, some CLI or web tools and what not. I think I built some kind of portfolio there and for developers it is currently the de facto place to show their work.
If I ask one of the (sota) large language models: who is Fabian Morón Zirfas? I get a pretty accurate description of what I have been doing over the last 15 years. I joint GitHub in 2010 so I am seeing and I walked the path of &lt;a href=&quot;https://en.wikipedia.org/wiki/Enshittification&quot;&gt;enshittificantion&lt;/a&gt; with them (which seems inevitable for such a large project). I still think it is a okayish product but there are some parts that are becoming wired and clunky. The most important thing though is &lt;strong&gt;digital sovereignty from the bigcorp-clouds in the US&lt;/strong&gt;. I&apos;ve been reading &quot;Technofeudalism: What Killed Capitalism&quot; by &lt;a href=&quot;https://www.yanisvaroufakis.eu/&quot;&gt;Yanis Varoufakis&lt;/a&gt; and I get the impression that it is more important than ever that we take a path other then throwing all our data into the beast just out of convenience.&lt;/p&gt;
&lt;p&gt;So what are the alternatives (besides self-hosting)?&lt;/p&gt;
&lt;p&gt;I guess the realistic options are Codeberg and Sourcehut.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://codeberg.org/&quot;&gt;Codeberg&lt;/a&gt; Germany and a non-profit e.v.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://sr.ht/&quot;&gt;sourcehut&lt;/a&gt; Netherlands for profit but with a strong ethos about open source.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I need to checkout if my usual workflows are supported. Gitflow publishing to Cloudflare, Netlify and NPM package registry. The occasional image going to Docker Hub might be needed&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. Working with LLM coding agents makes this even harder, since they are integrated with GitHub or maybe GitLab but that is it.&lt;/p&gt;
&lt;p&gt;Bitbucket (US and Atlassian) and GitLab (also US) are not as big as MSFT but still operated on us soil under their law.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://bitbucket.org&quot;&gt;Bitbucket&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://gitlab.com/&quot;&gt;GitLab&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;A whole other thing. Decentralized git hosting on your own infrastructure (called knot) based on atproto with tangled as the frontend as I understand it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://tangled.org/&quot;&gt;Tangled&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This is an open ended post I guess. If someone is reading this, any opinions on that, what do you do? And one last question comes still to my mind. Should I mirror important projects?&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;Yes while writing it I see the next challenge coming up. &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>igittigit and licensor</title><link>https://fabianmoronzirfas.me/blog/2025-12-23-igittigit-and-licensor/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-12-23-igittigit-and-licensor/</guid><pubDate>Tue, 23 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I just published two tools I recently vibe coded to scratch an itch.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;igittigit&lt;/code&gt; &lt;a href=&quot;https://github.com/ff6347/igittigit&quot;&gt;github.com/ff6347/igittigit&lt;/a&gt; Pulls &lt;code&gt;.gitignore&lt;/code&gt; templates into your current directory. I am trying to move aways from to much VSCode use to Zed. One thing I am missing from VSCode is the &lt;a href=&quot;https://github.com/CodeZombieCH/vscode-gitignore&quot;&gt; gitignore extension (github.com/CodeZombieCH/vscode-gitignore)&lt;/a&gt;. So I created something similar for the command line.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;licensor&lt;/code&gt; &lt;a href=&quot;https://github.com/ff6347/licensor/&quot;&gt;github.com/ff6347/licensor/&lt;/a&gt;. Same goes for the &lt;a href=&quot;https://github.com/ymotongpoo/vsc-licenser&quot;&gt;licenser extension (github.com/ymotongpoo/vsc-licenser)&lt;/a&gt;. I normally need a LICENSE file for every project. So this pulls licenses from choosalicense.com&apos;s git repo and also some more Creative Commons licenses.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Both tools can be downloaded as binaries from their GitHub release pages, installed via go or build from source. If you trust me that much you can also can install them directly from my homebrew tap.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;brew install ff6347/tap/licensor
brew install ff6347/tap/igittigit
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Yes! I vibe coded them. Since I am no go developer and I am to busy to build this without an AI doing the coding.&lt;/p&gt;
&lt;p&gt;Any feedback is welcome.&lt;/p&gt;</content:encoded></item><item><title>Notes on Containerized/Isolated Agents</title><link>https://fabianmoronzirfas.me/blog/2025-12-28-notes-on-containerized-isolated-agents/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2025-12-28-notes-on-containerized-isolated-agents/</guid><pubDate>Sun, 28 Dec 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I have to put my money where my mouth is. Since I&apos;ve been ranting about MCP and security in the post about &lt;a href=&quot;https://fabianmoronzirfas.me/blog/2025-10-31-mcp-security/&quot;&gt;&quot;MCP in experimentation or how I trust the trust of others&quot;&lt;/a&gt;. Having a docker container where I run the MCP tool in was not as straight forward as I thought. It worked somehow but also became annoying to maintain volumes in that one string to make this feasible. I dropped that and went on with my live.&lt;/p&gt;
&lt;p&gt;But then I have been dabbling with agents in containers recently and here are some nice things I found.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Conductor &lt;a href=&quot;https://www.conductor.build/&quot;&gt;conductor.build&lt;/a&gt; A pretty nice application that uses &lt;a href=&quot;https://git-scm.com/docs/git-worktree&quot;&gt;git-worktrees&lt;/a&gt; on your local machine to run agents in your repos.&lt;/li&gt;
&lt;li&gt;git-worktrees in general make a good tool for having a second checked out version of your repo. &lt;code&gt;git worktree add ../my-feautre main&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;in &lt;a href=&quot;https://www.docker.com/&quot;&gt;Docker&lt;/a&gt; 4.5 they introduced &lt;a href=&quot;https://docs.docker.com/ai/sandboxes/advanced-config/&quot;&gt;&lt;code&gt;sandbox&lt;/code&gt; command&lt;/a&gt; It runs a container for you with the current working directory mounted into the container. In the container &lt;a href=&quot;https://claude.ai&quot;&gt;&lt;code&gt;claude&lt;/code&gt;&lt;/a&gt; is already installed as binary. Very nice. You can even specify your own image templates. &lt;code&gt;claude&lt;/code&gt; runs here with &lt;code&gt;--dangerously-skip-permissions&lt;/code&gt; I would recommend a combination of, commit before running or better use git-worktrees with it.&lt;/li&gt;
&lt;li&gt;Just yesterday I stumbled upon &lt;a href=&quot;https://sketch.dev/welcome&quot;&gt;sketch.dev&lt;/a&gt; via HN That gives you fully isolated docker containers locally, remote and also with a hosted platform. The UI still seems a little beta but kinda nice.&lt;/li&gt;
&lt;li&gt;They (the people from sketch.dev) also have a service called &lt;a href=&quot;https://exe.dev&quot;&gt;exe.dev&lt;/a&gt; Here you get a VM in the clouds to run your agent in. With lots of great DX.&lt;/li&gt;
&lt;li&gt;One last thing to sandbox an agent differently is giving it access to a Raspberry Pi. I have Pi5 with 8GB and a nvm base attached to it hocked into my local network. On the Pi I have tailscale running with &lt;code&gt;tailscale up --ssh&lt;/code&gt; and some tags in my ACL to allow access from a ephemeral machine. Then I just pass claude the temporary token and tell him to ssh into the pi and go havoc in there. :D. (I noticed that &lt;code&gt;claude&lt;/code&gt; likes it more to run command from the host on the Pi rather then logging in and having a session in there, but hey — however you think you are absolutely right &lt;code&gt;claude&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Docker Sandbox Recipes&lt;/h2&gt;
&lt;p&gt;Run Go dev env for &lt;code&gt;claude&lt;/code&gt;:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-Dockerfile&quot;&gt;# ABOUTME: Development container for docker sandbox, adds Go toolchain for Pi development
# ABOUTME: Extends official claude code sandbox template with Go and dev tools

FROM docker/sandbox-templates:claude-code

# Create sandbox lock directory
RUN mkdir -p /home/agent/.docker/sandbox/locks

# Install Go and dev tools
RUN &amp;#x26;#x3C;&amp;#x26;#x3C;EOF
sudo apt-get update &amp;#x26;&amp;#x26; sudo apt-get install -y \
	golang-go \
	fish \
	magic-wormhole \
	tmux \
	vim \
	bat \
	lsd \
	zoxide \
	&amp;#x26;&amp;#x26; sudo rm -rf /var/lib/apt/lists/*
EOF

ENV GOPATH=/home/agent/go
ENV PATH=$PATH:/home/agent/go/bin

&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Build the image&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;docker build my-template .
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Use the sandbox with some local &lt;code&gt;~/.claude&lt;/code&gt; folders mounted as read only so the agent behaves more like my local agent. You still will have to login within the container with your credentials or provide a API key.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Run claude in sandbox with this project
docker sandbox run -t my-template -w . \
  -v ~/.claude/CLAUDE.md:/home/agent/.claude/CLAUDE.md:ro \
  -v ~/.claude/plugins:/home/agent/.claude/plugins:ro \
  -v ~/.claude/commands:/home/agent/.claude/commands:ro \
  claude
# Continue previous session
docker sandbox run -t creatureone-dev -w . claude -c
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;If you do changes to the template you need to remove it first.&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# If you rebuild the image, remove the old sandbox first
docker sandbox ls
docker sandbox rm &amp;#x3C;sandbox-id&gt;
&lt;/code&gt;&lt;/pre&gt;</content:encoded></item><item><title>The AI Discussion Loop</title><link>https://fabianmoronzirfas.me/blog/2026-01-14-the-ai-discussion-loop/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2026-01-14-the-ai-discussion-loop/</guid><pubDate>Wed, 14 Jan 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I used to be very interested in what people were saying about AI and its current trajectory in the development community. But today I noticed that I get the feeling of: &quot;AI is going to be blah blah blah…&quot;&lt;/p&gt;
&lt;p&gt;It is fine if you&apos;re totally betting on AI in development. Great show me how you do it! What worked well? What did not work? Any new learnings? And if you&apos;re against it. It&apos;s also fine right code by hand.&lt;/p&gt;
&lt;p&gt;But please can you both shut up and stop proselytizing&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;. There is more than one solution, my friends. My professor and mentor recently said something in the realm of: &quot;whenever I read the word inevitable, I start to doubt.&quot;&lt;/p&gt;
&lt;p&gt;Yes. Stop thinking in your binary, black or white, all or nothing method.&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;yes. I looked this word up with AI. &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>Platform vs Company</title><link>https://fabianmoronzirfas.me/blog/2026-02-24-platform-vs-company/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2026-02-24-platform-vs-company/</guid><pubDate>Tue, 24 Feb 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I&apos;ve been listening to a podcast where they were talking about social media restrictions for adolescents. I&apos;m pretty happy this discussion is happening now, as my children will hopefully grow up in a society where it&apos;s already been settled. I see it like the prohibition of tobacco or alcohol for people under age. As are the advertisements of cigarettes in public space. It&apos;s good for us that we have this.&lt;/p&gt;
&lt;p&gt;But what stood out most to me is that somehow our language has been altered to use the term platform for things like TikTok or X et al.&lt;/p&gt;
&lt;p&gt;This disguises the actual reality. These are companies that earn money from our attention or advertisement or selling our data.
Period&lt;/p&gt;</content:encoded></item><item><title>Colony - A Speculative Software Project</title><link>https://fabianmoronzirfas.me/blog/2026-04-06-colony/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2026-04-06-colony/</guid><pubDate>Mon, 06 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;/assets/images/blog/benczur-narcissus.jpg&quot; alt=&quot;Image of Narcissus 1881 oil on canvas by Gyula Benczúr (1844–1920)&quot;&gt;&lt;/p&gt;
&lt;h2&gt;What if the singularity already happened and we missed it because we were looking for ourselves?&lt;/h2&gt;
&lt;p&gt;Like Narcissus we love our own reflection. Therefore we measure all intelligence against human intelligence. Does it look like us, speak like us, write like us, sound like us? But what these are entirely the wrong questions. When we look at bee swarms or slime molds we see a network of entities that form intelligence in their interaction. Looking at language models the intelligence does not lie in the sole generation of the next token. When bringing together tool calling for interaction with other entities, file input output for creating or recalling memories, access to the shell for altering their own source, access to the internet for information retrieval we end up with things creating things. Colony (or c010ny.cc because the non leet code domain was way to expensive) is the first iteration of this. It is small language models running on raspberry pis. Their natural senses are things like memory load, cpu temperature or disk usage. They exist in a network where they can choose to interact with other entities that have access to their realm. What emerges from this?&lt;/p&gt;
&lt;p&gt;The process of creating this started with Opus 4.5 and moved to 4.6. I gave it as much agency as possible. Running it in a Docker container in yolo modus. Giving it access to the VPN and SSH to the pis was crucial, so it could deploy and modify the entities by itself. My part was generally giving ideas, setting up hardware and infrastructure, steering when it went of rails. One example of its agency was for example the audio expression of the entities. I gave it directions in form of &quot;make it sound R2D2-ish&quot;. It came up with several versions how the result of an inference could be translated into sound. The same goes for the visual output on the attached display (which was dropped in favor for the audio output).&lt;/p&gt;
&lt;p&gt;The first presentation in the seminar was also fully written by Claude with minor editing and full styling from my side.&lt;/p&gt;
&lt;p&gt;Things creating things.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Sidenote: The project started before the release of OpenClaw and the whole agents with heartbeats thing. Nice to see parallel developments. I guess the idea to run inference in a loop was inevitable -- starting with Ralph in a loop.&lt;/em&gt;&lt;/p&gt;</content:encoded></item><item><title>Flarelines - A Speculative Software Project</title><link>https://fabianmoronzirfas.me/blog/2026-04-06-flarelines/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2026-04-06-flarelines/</guid><pubDate>Mon, 06 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;&lt;img src=&quot;/assets/images/blog/line-light.png&quot; alt=&quot;Logo for the App Flarelines showing 6 Dots connected by a line forming a graph&quot;&gt;&lt;/p&gt;
&lt;p&gt;The elevator pitch would be as follows: Lupus is a chronic autoimmune disease. Studies have shown that keeping track of such an illness using journaling helps cope with the disease. Also having a better understanding auf the progression of the illness helps when talking to your medical health practitioner. Flarelines uses small language models (SLM) on device to categorize symptoms into 4 categories. From 0 to 3 where 0 is no activity and 3 is strong flares.
I am using it for myself. Did the whole LORA fine tune pipeline with Qwen 2.5  locally using some of my own journals and synthetic data. The application is also done using Opus 4.5 and 4.6 in Swift.&lt;/p&gt;</content:encoded></item><item><title>What I did this Winter</title><link>https://fabianmoronzirfas.me/blog/2026-04-06-what-i-did-this-winter/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/2026-04-06-what-i-did-this-winter/</guid><pubDate>Mon, 06 Apr 2026 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;It&apos;s gotten pretty silent around here. My semester was over and I had to take a break and let the things I read and created sink in a little. This doesn&apos;t mean that I was sitting on my hands, but I needed a little output break. So most of Februar was a lot of Kung Fu, fiddling around the house, doing stuff with the kids. Most of March, I&apos;ve been working on a job for the university. &lt;a href=&quot;https://github.com/bonanzahq/bonanza&quot;&gt;github.com/bonanzahq/bonanza&lt;/a&gt; &lt;em&gt;[Music playing in your head, some cowboys riding towards a farm]&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Bonanza&lt;/strong&gt; is a project that was first conceived around 2013/2014 when I was the lab supervisor of the interface workshop at FHP. It is the lending system that has been in use in the workshops since then. This application was so much EOL, its Ruby version, its Rails version and the OS version of the server was running on, the FHP asked me if I could bring it back into this decade. First, I was pretty cautious because I don&apos;t read and write Ruby, I don&apos;t know anything about Rails. But I still like a challenge.&lt;/p&gt;
&lt;p&gt;So I took the job.&lt;/p&gt;
&lt;p&gt;Lucky me, Opus 4.6 landed before I had to work on it. Over the last few weeks I worked often on this project, fully assisted by Opus. I revived the project and developed a nice process to work on larger endeavors like these.&lt;/p&gt;
&lt;p&gt;My process can be described as the following.&lt;/p&gt;
&lt;p&gt;Several agents, running on a Mac Mini M1 sitting on my desk connected to my local network and my Tailscale VPN. Me logging in via SSH from my laptop or Terminus from mobile devices. All sessions are persistent tmux sessions. (Learned quite a bit to use tmux) There&apos;s always one main session I call the project manager which only handles creating git worktrees, writing handoff.md into them and spawning agents in new tmux windows. These agents use an agent messaging skill to report back to the project manager and synchronize with other agents for access to the Docker stack. All development is test driven development. Since the agents are running on a desktop computer, they can use browsers to validate the features they wrote using end to end testing.
I developed some nice agent skills on the way to the v2. We are still in implicit Copyright mode but will add a open source license soon.&lt;/p&gt;
&lt;p&gt;On other news I released two projects. They are still work in progress but in a state where I can start talking about them.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First one is Flarelines. See it at &lt;a href=&quot;https://flarelines.cc/&quot;&gt;flarelines.cc&lt;/a&gt;. Read more about it in &lt;a href=&quot;/blog/2026-04-06-flarelines&quot;&gt;this blog post&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Second project from last semesters Studio Seminar is Colony &lt;a href=&quot;https://c010ny.cc/&quot;&gt;c010ny.cc&lt;/a&gt;. You can read more about it over in &lt;a href=&quot;/blog/2026-04-06-colony&quot;&gt;that blog post&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>Agentic Search (POC)</title><link>https://fabianmoronzirfas.me/blog/agentic-search/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/agentic-search/</guid><pubDate>Tue, 24 Jun 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I have been tinkering (semi vibe coding) an agentic search using OpenAI and the Brave Search API over the weekend. I am sure there are some problems and edge cases but I am pretty happy with the result. I thought there is more to it.&lt;/p&gt;
&lt;p&gt;The core logic is giving the LLM a tool it can call and have some break conditions so it does not end up in an infinite loop. See the proof of concept here &lt;a href=&quot;https://github.com/ff6347/agentic-search-poc&quot;&gt;https://github.com/ff6347/agentic-search-poc&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;You will have to bring your own Openai API key and the Brave Search API key though.&lt;/p&gt;</content:encoded></item><item><title>Moving to Astro</title><link>https://fabianmoronzirfas.me/blog/astro/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/astro/</guid><pubDate>Wed, 19 Jul 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Moved all this to &lt;a href=&quot;https://astro.build/&quot;&gt;Astro&lt;/a&gt;. I like it. was pretty painless. Now I just need some style.&lt;/p&gt;</content:encoded></item><item><title>Markdown Test Document</title><link>https://fabianmoronzirfas.me/blog/markdown-test-document/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/markdown-test-document/</guid><pubDate>Wed, 01 Jan 2014 00:00:00 GMT</pubDate><content:encoded>&lt;h1&gt;Markdown Test Document&lt;/h1&gt;
&lt;p&gt;This document tests various markdown elements to ensure proper rendering.&lt;/p&gt;
&lt;h2&gt;Text Formatting&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Bold text&lt;/strong&gt; and &lt;strong&gt;also bold&lt;/strong&gt;
&lt;em&gt;Italic text&lt;/em&gt; and &lt;em&gt;also italic&lt;/em&gt;
&lt;em&gt;&lt;strong&gt;Bold and italic&lt;/strong&gt;&lt;/em&gt; and &lt;em&gt;&lt;strong&gt;also bold and italic&lt;/strong&gt;&lt;/em&gt;
&lt;del&gt;Strikethrough text&lt;/del&gt;
&lt;code&gt;Inline code&lt;/code&gt;&lt;/p&gt;
&lt;h2&gt;Headings&lt;/h2&gt;
&lt;h1&gt;H1 Heading&lt;/h1&gt;
&lt;h2&gt;H2 Heading&lt;/h2&gt;
&lt;h3&gt;H3 Heading&lt;/h3&gt;
&lt;h4&gt;H4 Heading&lt;/h4&gt;
&lt;h5&gt;H5 Heading&lt;/h5&gt;
&lt;h6&gt;H6 Heading&lt;/h6&gt;
&lt;h2&gt;Lists&lt;/h2&gt;
&lt;h3&gt;Unordered Lists&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;First item&lt;/li&gt;
&lt;li&gt;Second item
&lt;ul&gt;
&lt;li&gt;Nested item&lt;/li&gt;
&lt;li&gt;Another nested item
&lt;ul&gt;
&lt;li&gt;Deeply nested item&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Third item&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Alternative bullet&lt;/li&gt;
&lt;li&gt;Another item&lt;/li&gt;
&lt;/ul&gt;
&lt;ul&gt;
&lt;li&gt;Yet another bullet style&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Ordered Lists&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;First numbered item&lt;/li&gt;
&lt;li&gt;Second numbered item
&lt;ol&gt;
&lt;li&gt;Nested numbered item&lt;/li&gt;
&lt;li&gt;Another nested numbered item&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Third numbered item&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;Code Blocks&lt;/h2&gt;
&lt;h3&gt;Inline Code&lt;/h3&gt;
&lt;p&gt;Use &lt;code&gt;console.log()&lt;/code&gt; to output to the console.&lt;/p&gt;
&lt;h3&gt;Code Blocks&lt;/h3&gt;
&lt;pre&gt;&lt;code class=&quot;language-javascript&quot;&gt;function greetUser(name) {
  console.log(`Hello, ${name}!`);
}

greetUser(&apos;World&apos;);
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-python&quot;&gt;def calculate_sum(a, b):
    return a + b

result = calculate_sum(5, 3)
print(f&quot;The sum is: {result}&quot;)
&lt;/code&gt;&lt;/pre&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;# Install dependencies
npm install

# Run development server
npm run dev
&lt;/code&gt;&lt;/pre&gt;
&lt;h2&gt;Blockquotes&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;This is a blockquote.
It can span multiple lines.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This is a nested blockquote.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/blockquote&gt;
&lt;h2&gt;Links and Images&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://google.com&quot;&gt;Link to Google&lt;/a&gt;
&lt;a href=&quot;https://example.com&quot; title=&quot;Example Title&quot;&gt;Link with title&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Auto-link: &lt;a href=&quot;https://github.com&quot;&gt;https://github.com&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;Tables&lt;/h2&gt;




















&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Column 1&lt;/th&gt;&lt;th&gt;Column 2&lt;/th&gt;&lt;th&gt;Column 3&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;Row 1, Col 1&lt;/td&gt;&lt;td&gt;Row 1, Col 2&lt;/td&gt;&lt;td&gt;Row 1, Col 3&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;Row 2, Col 1&lt;/td&gt;&lt;td&gt;Row 2, Col 2&lt;/td&gt;&lt;td&gt;Row 2, Col 3&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;h2&gt;Horizontal Rule&lt;/h2&gt;
&lt;hr&gt;
&lt;h2&gt;Special Characters&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Em dash: —&lt;/li&gt;
&lt;li&gt;En dash: –&lt;/li&gt;
&lt;li&gt;Ellipsis: …&lt;/li&gt;
&lt;li&gt;Copyright: ©&lt;/li&gt;
&lt;li&gt;Trademark: ™&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;HTML Elements&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Bold HTML&lt;/strong&gt;
&lt;em&gt;Italic HTML&lt;/em&gt;
&lt;code&gt;Inline HTML code&lt;/code&gt;&lt;/p&gt;
&lt;div&gt;
  &lt;p&gt;HTML block element&lt;/p&gt;
&lt;/div&gt;
&lt;h2&gt;Task Lists&lt;/h2&gt;
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; Completed task&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Incomplete task&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Another incomplete task
&lt;ul class=&quot;contains-task-list&quot;&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; checked disabled&gt; Nested completed task&lt;/li&gt;
&lt;li class=&quot;task-list-item&quot;&gt;&lt;input type=&quot;checkbox&quot; disabled&gt; Nested incomplete task&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;Definition Lists&lt;/h2&gt;
&lt;p&gt;Term 1
: Definition 1&lt;/p&gt;
&lt;p&gt;Term 2
: Definition 2a
: Definition 2b&lt;/p&gt;
&lt;h2&gt;Footnotes&lt;/h2&gt;
&lt;p&gt;This text has a footnote&lt;sup&gt;&lt;a href=&quot;#user-content-fn-1&quot; id=&quot;user-content-fnref-1&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Another footnote reference&lt;sup&gt;&lt;a href=&quot;#user-content-fn-note&quot; id=&quot;user-content-fnref-note&quot; data-footnote-ref=&quot;&quot; aria-describedby=&quot;footnote-label&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;section data-footnotes=&quot;&quot; class=&quot;footnotes&quot;&gt;&lt;h2 class=&quot;sr-only&quot; id=&quot;footnote-label&quot;&gt;Footnotes&lt;/h2&gt;
&lt;ol&gt;
&lt;li id=&quot;user-content-fn-1&quot;&gt;
&lt;p&gt;This is the first footnote. &lt;a href=&quot;#user-content-fnref-1&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 1&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&quot;user-content-fn-note&quot;&gt;
&lt;p&gt;This is a named footnote. &lt;a href=&quot;#user-content-fnref-note&quot; data-footnote-backref=&quot;&quot; aria-label=&quot;Back to reference 2&quot; class=&quot;data-footnote-backref&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/section&gt;</content:encoded></item><item><title>Today I Learned about /bin/[</title><link>https://fabianmoronzirfas.me/blog/til-slash-bin-open-bracket/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/til-slash-bin-open-bracket/</guid><pubDate>Sun, 26 Nov 2023 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;Once I saw in &lt;code&gt;/bin&lt;/code&gt; a file &lt;code&gt;[&lt;/code&gt;. Since I don&apos;t want to destroy the fabric of my little unixiverse I thought: Maybe some leftover of some command gone wrong or whatever. I did a &lt;code&gt;¯\_(ツ)_/¯&lt;/code&gt; and moved on.&lt;/p&gt;
&lt;p&gt;Today I learned:&lt;/p&gt;
&lt;p&gt;When you write a script like this:&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;if [ a = b ]; then
	echo &quot;a equal to b&quot;
fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;You don&apos;t use a language built in expression. You run with the executable &lt;code&gt;/bin/test&lt;/code&gt;. Because &lt;code&gt;/bin/[&lt;/code&gt; is an alias for &lt;code&gt;/bin/test&lt;/code&gt;. The only difference is that &lt;code&gt;[&lt;/code&gt; looks for the closing &lt;code&gt;]&lt;/code&gt; to even things out.&lt;/p&gt;
&lt;p&gt;So the script above could also be :&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;if test a = b; then
	echo &quot;a equal to b&quot;
fi
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;🤯&lt;/p&gt;
&lt;p&gt;source: &lt;a href=&quot;https://jmmv.dev/2020/03/test-bracket.html&quot;&gt;https://jmmv.dev/2020/03/test-bracket.html&lt;/a&gt; via Hacker News&lt;/p&gt;</content:encoded></item><item><title>Time Washing Machine</title><link>https://fabianmoronzirfas.me/blog/time-washing-machine/</link><guid isPermaLink="true">https://fabianmoronzirfas.me/blog/time-washing-machine/</guid><pubDate>Thu, 31 Jul 2025 00:00:00 GMT</pubDate><content:encoded>&lt;p&gt;What about using a time machine instead of a washing machine? We could just send the cloth back in time to the point where it was clean! Any objections?&lt;/p&gt;</content:encoded></item></channel></rss>