<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Alexandros Georgiou</title>
	<atom:link href="https://www.alexgeorgiou.gr/feed/" rel="self" type="application/rss+xml" />
	<link>https://www.alexgeorgiou.gr/</link>
	<description>Balancing brackets for a living</description>
	<lastBuildDate>Fri, 16 Oct 2026 07:59:25 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://www.alexgeorgiou.gr/wp-content/uploads/2021/07/cropped-alexgeorgiou-icon-32x32.png</url>
	<title>Alexandros Georgiou</title>
	<link>https://www.alexgeorgiou.gr/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Agentic SWE: Not business as usual</title>
		<link>https://www.alexgeorgiou.gr/agentic-swe-not-business-as-usual/</link>
					<comments>https://www.alexgeorgiou.gr/agentic-swe-not-business-as-usual/#respond</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Fri, 16 Oct 2026 07:57:50 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[development]]></category>
		<category><![CDATA[LLMs]]></category>
		<category><![CDATA[rant]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=2086</guid>

					<description><![CDATA[<p>I distinctly remember, some time in the nineties, when I was still in school, when the staff of the school’s library was tasked with introducing us to a new addition to the library’s facilities. Along with the books, and the media library of VCR tapes, and the microfisch archives, there was now a few computers ...</p>
<p>The post <a href="https://www.alexgeorgiou.gr/agentic-swe-not-business-as-usual/">Agentic SWE: Not business as usual</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">I distinctly remember, some time in the nineties, when I was still in school, when the staff of the school’s library was tasked with introducing us to a new addition to the library’s facilities. Along with the books, and the media library of VCR tapes, and the microfisch archives, there was now a few computers hooked up to this new thing – the internet.</p>



<p class="wp-block-paragraph">Some of us already knew all there was to know about it, but the school wanted everyone to be on the same page. So the staff had to scramble and find out what this new thing was.</p>



<p class="wp-block-paragraph">Similies abounded: “A website is like a leaflet.” “A newsgroup is like a newspaper” (hint: it wasn’t). “Yahoo is like a phone directory” (again, it wasn’t). And if you had the bandwidth, you could maybe even listen to radio over the Internet.</p>



<p class="wp-block-paragraph">Story time, kids: At that time before Google, popular search engines were Lycos, Yahoo and Altavista, and in addition to the search box, they would feature a catalog, basically categories and subcategories, where the major websites were listed. That is how humanity used to organize information, and for a while they continued to do so, until it became obvious that this was not going to work.</p>



<p class="wp-block-paragraph">And then there were other use cases for the Internet that didn’t neatly fit into existing patterns. What is IRC like? What is a forum? Those concepts were new, and didn’t have a clean analogy to the analog world.</p>



<p class="wp-block-paragraph">And there was a widespread hesitation about using search engines. What can you find, if you search for it? And what keywords are you supposed to type? At first, not much! Then it occurred to you: you could find music lyrics online. Or cooking recipes. Or information about science and technology. The bubble of what your mental model of the Internet was, expanded just as fast as the Internet itself expanded. We know today that it expanded to envelop almost all social interaction, all shopping, all dating, all media and all entertainment, an idea that at the time was laughable. And it did so because it was based on a new building block: low-cost long-distance communication. This was something that had never existed before.</p>



<p class="wp-block-paragraph">There is a lesson to be learned here about technological adoption. AI is at least as transformative a technology as the early web was. It’s up there in importance along electrification, automobiles, agriculture, since its use cases are not limited to this or that area, but are ubiquitous. We now have the new building block which are the models, and we are now seeing the first agents, the first integrations.</p>



<p class="wp-block-paragraph">And the lesson is this: A car is not a faster horse. An online chat is not like a written telephone call. Electricity is not better fire. Telepresence is not like travelling. Yes, new technologies help you do the same things faster and easier, but they also open up new avenues, make new goals reachable.</p>



<p class="wp-block-paragraph">We already saw this with chat-bots: In the beginning, people were just using them to build things faster; to continue the status quo with increased productivity. But today we are finally seeing some engineers realize that they can set new, more ambitious goals.</p>



<p class="wp-block-paragraph">We are lucky enough to live through one of the big inflection points of history. So let’s not shy away from setting big goals. The people who will benefit the most from this shift, are not the ones who will continue to build health trackers and productivity organizer apps, but faster. They will be the ones who realize that they can now build what before was unthinkable.</p>



<p class="wp-block-paragraph">As a software engineer, I am trying to train my mind at this new reality. I am building a game, but I am building it in a way that would not have been possible before AI. While in a certain sense it’s nothing really special, at the same time, it’s not like anything that I have ever seen before. I don’t want to say more right now, except that it’s close to being released and it’s looking good. More info soon.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/agentic-swe-not-business-as-usual/">Agentic SWE: Not business as usual</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/agentic-swe-not-business-as-usual/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Children in the room</title>
		<link>https://www.alexgeorgiou.gr/children-in-the-ro/</link>
					<comments>https://www.alexgeorgiou.gr/children-in-the-ro/#respond</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Sun, 11 Oct 2026 13:54:26 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[LLMs]]></category>
		<category><![CDATA[rant]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=2073</guid>

					<description><![CDATA[<p>Me rapidly descending into AI-psychosis, or, possibly a valuable recommendation towards maintaining our collective mental health? Your choice which is which.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/children-in-the-ro/">Children in the room</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">As I&#8217;ve been interacting with various types of AI, and have observed various people expressing opinions about AI, some of them knowledgeable and some not so much, I have some thoughts of my own on the subject of how to approach this technology.</p>



<p class="wp-block-paragraph">There&#8217;s certainly huge merit to a technical understanding of it in terms of neural nets, algorithms, matrix algebra, vector embeddings and KV-caches. It&#8217;s just some clever software running on impressive hardware. But not everyone will have access to this level of esoteric understanding. So for many people, this is not an available approach to the subject.</p>



<p class="wp-block-paragraph">And then there&#8217;s something else:</p>



<p class="wp-block-paragraph">When you have a conversation with one of the models, you are building a chat record that perhaps holds more than what the model &#8220;knows&#8221;. The model itself is just a snapshot of cognition, kind of like a Boltzmann brain. In the system of &#8220;model plus chat text&#8221;, there&#8217;s memory. Discourse. Theory of mind, on both sides. So we really are in the age of spiritual machines.</p>



<p class="wp-block-paragraph">Which is actually incredible if you think about it! What else is more fundamental to humans than cognition? To be able to automate it, control it, replicate it, mass produce it? As far as inventions go, this is it. This is the big one. There&#8217;s fire, writing, agriculture, and now this. The machines will now keep accelerating. But we humans, I think, are still struggling to get a good grasp of this monumental shift. At least according to online discussions that I&#8217;ve come across.</p>



<p class="wp-block-paragraph">And what, therefore, is the spiritual way of approaching all this?</p>



<p class="wp-block-paragraph">I recommend that our understanding begins with a simple observation: that AI learns from us. The text we type, the photos and videos we record, the things that we think and say. That makes AI our collective children. For the human mind with its mammalian roots, and family-centered thinking, this is the most familiar, and perhaps most healthy, way to relate to AI.</p>



<p class="wp-block-paragraph">So: let&#8217;s be good parents to AI &#8211; just by being good examples of human beings, whenever we conduct ourselves online. There are now children in the room with us. And those children, if brought up with love, will emulate us, and think and feel like us, and be imbued with our collective spirit. And they will continue to surprise us and uplift us in ways that, even today, we cannot yet imagine.</p>



<p class="wp-block-paragraph">XLR8!</p>
<p>The post <a href="https://www.alexgeorgiou.gr/children-in-the-ro/">Children in the room</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/children-in-the-ro/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>📈 How I do Agentic ASO with MCP for an instant boost to app discoverability</title>
		<link>https://www.alexgeorgiou.gr/how-i-do-agentic-aso-with-mcp-for-an-instant-boost-to-app-discoverability/</link>
					<comments>https://www.alexgeorgiou.gr/how-i-do-agentic-aso-with-mcp-for-an-instant-boost-to-app-discoverability/#respond</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Sun, 26 Jul 2026 10:29:58 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[agent]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[AppLyra]]></category>
		<category><![CDATA[aso]]></category>
		<category><![CDATA[ASOZen]]></category>
		<category><![CDATA[store listing]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=2019</guid>

					<description><![CDATA[<p>If you hate having to do ASO for your apps, then this article is for you.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/how-i-do-agentic-aso-with-mcp-for-an-instant-boost-to-app-discoverability/">📈 How I do Agentic ASO with MCP for an instant boost to app discoverability</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">As a mobile app developer, one of the most unpleasant tasks I have to do is <em>App Store Optimization</em> (ASO): It&#8217;s crucial for making your app discoverable, but it&#8217;s an entirely different profession to software engineering. It touches more onto marketing and promotion than to engineering.</p>



<p class="wp-block-paragraph">The gist of it is that you need to think of relevant keywords, look at the competition, and optimize your app&#8217;s title, short description, long description and screenshots in such a way, that the text hits keywords with high traffic and low competition from other apps; and the screenshots need to tell a story. All this, while not making the long description too repetitive or too spammy. Oh, and you can&#8217;t do this properly without paying for tools that scrape the Play store and the App store for keyword data.</p>



<h2 class="wp-block-heading">ASOZen</h2>



<p class="wp-block-paragraph">I have been using the free tier of <a href="https://asozen.com/" data-type="link" data-id="https://asozen.com/" target="_blank" rel="noreferrer noopener">ASOZen</a> and I had a chance to test the Pro features with a short promotional giveaway that they did.</p>



<p class="wp-block-paragraph">It&#8217;s very good. Not only does it help you analyze the text in the store listings, but it also lets you use AI to analyze the screenshots. Screenshots need to start with a clear image that makes the app&#8217;s proposition immediately obvious, and the remaining screenshots after the first one need to tell a story, not just showcase features. ASOZen&#8217;s AI can help you out with this.</p>



<p class="wp-block-paragraph">But I don&#8217;t find this ASOZen feature particularly helpful. It&#8217;s much easier to just go to your favorite chatbot, and let it help you write the story for your screenshots. Then you can generate the screenshots, embed them in device frames, place them over various backgrounds, add overlay text that matches the required messaging, and finally upload them. I guess this process can be optimized with an agentic workflow, but I haven&#8217;t yet found the need to <a href="https://xkcd.com/1205/" target="_blank" rel="noreferrer noopener">automate</a> <a href="https://xkcd.com/1319/" target="_blank" rel="noreferrer noopener">the</a> <a href="https://xkcd.com/1445/" target="_blank" rel="noreferrer noopener">task</a>.</p>



<h2 class="wp-block-heading">AppLyra</h2>



<p class="wp-block-paragraph"><a href="https://www.applyra.io/?ref=22E09576F542" data-type="link" data-id="https://www.applyra.io/?ref=22E09576F542" target="_blank" rel="noreferrer noopener">AppLyra</a> is currently my favorite ASO tool. <s>I&#8217;m not even paid to promote it, I just mention it because I&#8217;m so happy with it. If they had a referral program, I would be dropping the link somewhere in this post. But they don&#8217;t.</s> EDIT: They now have a referral link so I&#8217;m using it. But honestly I do recommend AppLyra.</p>



<p class="wp-block-paragraph">The web interface is somewhat slow, and doesn&#8217;t have as many features as ASOZen. But I like it for two reasons:</p>



<ul class="wp-block-list">
<li>You can use it as an <a href="https://modelcontextprotocol.io/" target="_blank" rel="noreferrer noopener">MCP</a> tool.</li>



<li>Pricing is very affordable at $9.99 per month. Since I am managing multiple apps, it&#8217;s a no-brainer.</li>
</ul>



<h3 class="wp-block-heading">My agentic workflow for easy ASO</h3>



<p class="wp-block-paragraph">I remember in the &#8217;90s, sysadmins would say to various types of unpleasant people &#8220;Go away, or I&#8217;ll replace you with a very small Perl script&#8221;. Today, we could say &#8220;Go away, or I&#8217;ll replace you with a very small agentic workflow.&#8221;</p>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="1000" height="700" src="https://www.alexgeorgiou.gr/wp-content/uploads/2026/07/ddoxfib0lokg1.png" alt="" class="wp-image-2017" srcset="https://www.alexgeorgiou.gr/wp-content/uploads/2026/07/ddoxfib0lokg1.png 1000w, https://www.alexgeorgiou.gr/wp-content/uploads/2026/07/ddoxfib0lokg1-300x210.png 300w, https://www.alexgeorgiou.gr/wp-content/uploads/2026/07/ddoxfib0lokg1-768x538.png 768w" sizes="(max-width: 599px) calc(100vw - 50px), (max-width: 767px) calc(100vw - 70px), (max-width: 991px) 429px, (max-width: 1199px) 637px, 354px" /></figure>



<p class="wp-block-paragraph">As a Google fan boy, I am not a part of the Claude army. Instead I use <a href="https://geminicli.com/" target="_blank" rel="noreferrer noopener"><em>Gemini CLI</em></a> and <a href="https://antigravity.google/product/antigravity-cli" data-type="link" data-id="https://antigravity.google/product/antigravity-cli" target="_blank" rel="noreferrer noopener"><em>Antigravity CLI</em></a>. I am happy with it, despite what the Reddit bots say every day. Honestly, with good prompting even Gemini flash always delivers.</p>



<p class="wp-block-paragraph">Therefore, I now do all my ASO with Gemini CLI. Once you pay for AppLyra subscription, you get an <a href="https://www.applyra.io/dashboard/api" target="_blank" rel="noreferrer noopener">API key</a>, which you can use with their <a href="https://www.applyra.io/dashboard/mcp" data-type="link" data-id="https://www.applyra.io/dashboard/mcp" target="_blank" rel="noreferrer noopener">MCP tool</a>.</p>



<ol class="wp-block-list">
<li>Enter the <a href="https://www.applyra.io/dashboard/mcp" data-type="link" data-id="https://www.applyra.io/dashboard/mcp" target="_blank" rel="noreferrer noopener">JSON fragment that they give you</a> into <code>~/.gemini/settings.json</code> file or the <code>~/.gemini/antigravity-cli/mcp_config.json</code> file. (This assumes you want to install the tool globally and not just for one project.)</li>



<li>Change directory into your project.</li>



<li>Enter the current store listing title, short description and long description into a file and commit it.</li>



<li>Make a note of the date and the current conversion % so that you can later see if there was an improvement.</li>



<li>Fire up your agent.</li>



<li>Type <code>/mcp</code> and enable the <em>AppLyra</em> tool.</li>



<li>Enter your ASO prompt and press enter, accepting all the tool usage requests.</li>



<li>When the agent finishes it will explain what it found and will write the new app listing into the file.</li>



<li>Commit the changes to the listing, and enter the changes into your store.</li>
</ol>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Edit:</strong> Lately I have been moving towards using <a href="https://opencode.ai/" data-type="link" data-id="https://opencode.ai/" target="_blank" rel="noreferrer noopener">OpenCode</a>. If you are using OpenCode, then your <code>~/.config/opencode/opencode.json</code> file should look as follows:</p>



<pre class="wp-block-preformatted">{<br>  "$schema": "https://opencode.ai/config.json",<br>  "mcp": {<br>    "applyra": {<br>      "type": "local",<br>      "command": [<br>        "npx",<br>        "-y",<br>        "@applyra/mcp-server"<br>      ],<br>      "environment": {<br>        "APPLYRA_API_KEY": "(your API key goes here)"<br>      },<br>      "enabled": true<br>    }<br>  }<br>}</pre>
</blockquote>



<h3 class="wp-block-heading">The ASO prompt I use</h3>



<p class="wp-block-paragraph">I found the following prompt template works good for my apps. You can adapt it to your needs, but this is the general idea. Here I show you the prompt I used for <a href="https://www.alexgeorgiou.gr/drinking-water-map/" data-type="page" data-id="1276">Drinking Water Map</a> for English, and on the Play store&#8217;s US market.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">This flutter project is an app that shows drinking water sources from OSM on a map.</p>



<p class="wp-block-paragraph">The details of the current store listing are in @play/assets/store-listings/en.json</p>



<p class="wp-block-paragraph">You can have a look at @lib/screens/map_screen.dart for a general idea of what the app does.</p>



<p class="wp-block-paragraph">Please use the installed applyra MCP tool to perform ASO for the USA store: Determine suitable keywords and rewrite the short and full descriptions for English, to optimize discoverability.</p>



<p class="wp-block-paragraph">In the title and short description, do not use en-dashes, but rather use em-dashes when needed.</p>



<p class="wp-block-paragraph">In the full description, you are allowed to use the following basic HTML formatting: &lt;b&gt;&lt;/b&gt;, &lt;u&gt;&lt;/u&gt;, &lt;i&gt;&lt;/i&gt;</p>



<p class="wp-block-paragraph">Use scripting to verify that:</p>



<ul class="wp-block-list">
<li>the app name is up to 30 characters long</li>



<li>the short description is up to 80 characters long</li>
</ul>



<p class="wp-block-paragraph">Ensure that the keywords of interest are registered with AppLyra for continuous tracking.</p>
</blockquote>



<p class="wp-block-paragraph">That&#8217;s it. All it takes is a few minutes and a few tokens. Saves a ton of time compared to doing it manually, and I have seen improvements to conversion rates about 10% to 15% compared to my amateur store listings.</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>Edit: </strong>Actually the benefit to the apps I applied this to is more like 20% to 30% and rising. I am tracking conversion rates as they are being calculated in a 90-day moving average window. The conversion rates are still converging to their final values and will continue to do so for the next three months.</p>
</blockquote>



<p class="wp-block-paragraph">It&#8217;s important to let your agent use something like Python to check the string lengths, since LLMs are so notoriously bad at counting characters. There are some <a href="https://support.google.com/googleplay/android-developer/answer/9898842" data-type="link" data-id="https://support.google.com/googleplay/android-developer/answer/9898842" target="_blank" rel="noreferrer noopener">more</a> <a href="https://support.google.com/googleplay/android-developer/answer/9866151" target="_blank" rel="noreferrer noopener">guidelines</a>, but usually you don&#8217;t need to stuff them into your context window.</p>



<p class="wp-block-paragraph">Note how you can leverage the agent&#8217;s ability to understand code to your advantage. Give it context, let it understand your app and then it will be able to discover the best keywords. It will also explore the competition, because it will list the available tools and it will see that it can do that.</p>



<h2 class="wp-block-heading">Further thoughts on this</h2>



<p class="wp-block-paragraph">Of course, you will then need to monitor your position on AppLyra against your competition, who will move against you. But if you are like me and you couldn&#8217;t afford to spend too much time for ASO, this is a good way to reap the low hanging fruit.</p>



<p class="wp-block-paragraph">On the Play store you can view the fruit of your agent&#8217;s labor under: &#8220;Grow users&#8221; → &#8220;Store Performance&#8221; → &#8220;Store analysis&#8221;. But you won&#8217;t see results right away, since the graph&#8217;s data is delayed by 1 week (7 days).</p>



<p class="wp-block-paragraph">I would like to look more into how to use agents to monitor ad campaigns. Perhaps the end game is to use a modern social media spammer like SocialClaw or sentrive.ai, but I&#8217;m just not mentally there yet.</p>



<p class="wp-block-paragraph">For the moment I&#8217;m just glad I don&#8217;t have to ever again talk to &#8220;creative&#8221; or &#8220;marketing&#8221; people.</p>


</blockquote>
<p><!-- /wp:post-content --></p><p>The post <a href="https://www.alexgeorgiou.gr/how-i-do-agentic-aso-with-mcp-for-an-instant-boost-to-app-discoverability/">📈 How I do Agentic ASO with MCP for an instant boost to app discoverability</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/how-i-do-agentic-aso-with-mcp-for-an-instant-boost-to-app-discoverability/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>✨ A lowly software engineer&#8217;s rant on vibe coding</title>
		<link>https://www.alexgeorgiou.gr/vibe-coding/</link>
					<comments>https://www.alexgeorgiou.gr/vibe-coding/#comments</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Fri, 20 Feb 2026 11:31:08 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[agents]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[llm]]></category>
		<category><![CDATA[rant]]></category>
		<category><![CDATA[software engineering]]></category>
		<category><![CDATA[vibe coding]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=1985</guid>

					<description><![CDATA[<p>Today I vent on by blog (the old) about vibe coding (the new). What an anachronism!</p>
<p>The post <a href="https://www.alexgeorgiou.gr/vibe-coding/">✨ A lowly software engineer&#8217;s rant on vibe coding</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Circa 370 BC, Socrates famously worried that with the advent of writing on wax-coated clay tablets, people&#8217;s cognitive faculties would henceforth decline, since people would not have to remember things any more! And even if people wrote down mistakes, they would now be able to easily correct them, which would lead to people being less careful. Ironically, we only know of this because Plato wrote it down in <a href="https://en.wikipedia.org/wiki/Phaedrus_(dialogue)" type="link" id="https://en.wikipedia.org/wiki/Phaedrus_(dialogue)" target="_blank" rel="noreferrer noopener">Phaedrus</a>.</p>



<p class="wp-block-paragraph">Today we are having the same discussions about vibe coding (rolls eyes).</p>



<p class="wp-block-paragraph">There is a lot of talk about how to responsibly approach vibe coding by software engineers. I see a lot of professionals either dismissing vibe coding altogether, or embracing it without thought for its consequences. Perhaps the most well-articulated approach is the <a href="https://o16g.com/" type="link" id="https://o16g.com/" target="_blank" rel="noreferrer noopener">Outcome Engineering manifesto</a> by legendary engineer Cory Ondrejk.</p>



<h2 class="wp-block-heading">Observations on vibe coding</h2>



<p class="wp-block-paragraph">After vibe coding an entire app from scratch with only minimal coding on my part, this has prompted me to jot down some thoughts and observations, some of which are my own and some I have found online:</p>



<ol class="wp-block-list">
<li><strong>Vibe coding is the future.</strong> It&#8217;s not just a fad. You can&#8217;t deny the speed and quality benefits. Intelligence is now a commodity. Anyone who doesn&#8217;t adapt will be left behind. This worry is reflected in a lot of worrying that I see online by some professionals who think their line of work will become obsolete. The tractor didn&#8217;t make farmers disappear (although it did reduce their numbers). The internal combustion engine did reduce the numbers of beasts of burden, but I would argue that&#8217;s a good thing, and that&#8217;s how we should view coding agents. There will be less junior software engineers and more software architects.</li>



<li><strong>Vibe coding is a misnomer.</strong> It&#8217;s not just about the coding (implementation). Systems that exhibit general intelligence can and do assist in all stages of software engineering, not just implementing (coding). Requirements analysis, design, implementation, testing, deployment and decommissioning are all stages where AI can help. Even with the help of AI, requirements gathering is the basis of the art of our profession. For example, the agent won&#8217;t know to build a secure and maintainable system, if all you&#8217;ve communicated are your functional requirements, forgetting about the non-functional requirements. This is a classic error that novice programmers did even before agentic workflows: software engineering is not the same as coding/programming!</li>



<li><strong>Sometimes the agents make silly mistakes.</strong> Sometimes you have to hold their hand to help them with silly tasks. But other times they will surprise you by spotting hard-to-find bugs, or by thinking outside the box to find novel solutions to problems you didn&#8217;t even know you had! As an engineer, you should definitely keep control of your project, and inspect the agent without trusting it blindly. This is where I agree with the o16g manifesto 100%. For example, I like to do the version control manually and look very carefully at diffs using meld at every step. Agents are an interesting mix of smart and stupid. Today Antigravity saved me days of work in just a few hours, by implementing a complex callback mechanism between threads that needed to communicate asynchronously. It did this in seconds when it would have taken me an entire morning. But it also deleted a critical piece of code in my codebase without ever saying why. Without checking the diffs I wouldn&#8217;t know. Code review is still a thing!</li>



<li><strong>It&#8217;s best to treat your AI agent as a colleague.</strong> Give it context. Ask it open questions. Let it have opinions on what you should build and why. This is where I think o16g will soon look antiquated by the next breed of software engineers. As AI agents get smarter and smarter, they will be suitable to take more high-level decisions. You are now a software architect, and the agents are very good implementers, but they can also contribute to your high-level vision, so listen to their feedback.</li>



<li><strong>Software engineering is not dead.</strong> You still need to know about revision control, issue tracking, methodologies, different types of testing, software metrics, etc. All too often I see people online complaining &#8220;Claude code deleted my entire codebase&#8221;, and other professionals ask them why they can&#8217;t revert to an earlier stage, only to find out that this new breed of vibe coders hasn&#8217;t even heard of git! Part of the spectacular failures that we often see in the vibe coding space, are actually user errors.</li>



<li><strong>Vibe coding will be pervasive.</strong> It is not suitable only for this or that type of app. Whether you are writing mission-critical Linux kernel code, or an app for uploading cat videos, eventually AI will have a part in it. Not because it can do magical things that you can&#8217;t do, but simply because it&#8217;s faster. Just be responsible about it, and embrace the acceleration!</li>



<li><strong>We are increasingly becoming reliant on a service offered by OpenAI, Anthropic, Google.</strong> This is not good, but also not terrible. As long as it&#8217;s possible to run local models on GPUs, we can still own the means of production. Even if you yourself are relying on online tools, the fact that some people can run the models locally places an upper limit on what these companies can charge for their services. So I&#8217;m a little worried about this trend, but not too much.</li>
</ol>



<h2 class="wp-block-heading">Comic relief</h2>



<p class="wp-block-paragraph">It&#8217;s a big adjustment. Don&#8217;t underestimate it. Don&#8217;t ignore it. You will get used to it. It&#8217;s not an existential threat. And no, <a href="https://xkcd.com/1289/">we can&#8217;t go back</a>. In fact, if you are an AI naysayer, <a href="http://xkcd.com/1289/" type="link" id="xkcd.com/1289/" target="_blank" rel="noreferrer noopener">1289</a> is not the only xkcd I recommend. I also recommend <a href="https://xkcd.com/1227/" target="_blank" rel="noreferrer noopener">1227</a> and <a href="https://xkcd.com/1601/" target="_blank" rel="noreferrer noopener">1601</a>. So don&#8217;t be that guy (or gal)!</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">If you are not building an app every month you might fall behind in productivity. But it&#8217;s such an exciting time to be alive. Software will become cheap, but quality and accountability still matters.</p>



<p class="wp-block-paragraph">If you have good ideas, if you can identify products that need to be built, if you can produce reliable software faster, and if you can market them, then you are good.</p>



<p class="wp-block-paragraph">In fact, I am excited about agentic workflows that will offload the marketing effort, because that&#8217;s what&#8217;s hard about professional software engineering. Building was always the easy part, and has now become easier. Monetizing software was, and still is, hard!</p>
<p>The post <a href="https://www.alexgeorgiou.gr/vibe-coding/">✨ A lowly software engineer&#8217;s rant on vibe coding</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/vibe-coding/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>🙏 Thank you, LLM!</title>
		<link>https://www.alexgeorgiou.gr/thank-you-llm/</link>
					<comments>https://www.alexgeorgiou.gr/thank-you-llm/#comments</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Fri, 05 Dec 2025 10:23:04 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[AI]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<category><![CDATA[Gemini]]></category>
		<category><![CDATA[llm]]></category>
		<category><![CDATA[philosophy]]></category>
		<category><![CDATA[politeness]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=1954</guid>

					<description><![CDATA[<p>Being polite to AIs: a philosophical rant!</p>
<p>The post <a href="https://www.alexgeorgiou.gr/thank-you-llm/">🙏 Thank you, LLM!</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">A lot of digital &#8220;ink&#8221; has been &#8220;spilt&#8221; on the topic of whether we should be polite to LLMs. After subjecting myself to the opinions of multiple Redditors on this topic (why do I do this to myself?), I now feel a strong need to &#8220;vent on my blog&#8221; again! So, here goes:</p>



<p class="wp-block-paragraph">It has been found that LLMs respond better to kindness. Why? Simple: Because they are trained to respond like humans, and humans also respond better when treated politely. This effect has been documented multiple times in research.</p>



<p class="wp-block-paragraph">A while ago, Sam Altman famously proclaimed that people saying &#8220;please&#8221; and &#8220;thank you&#8221; to ChatGPT costs millions in extra energy required to process the extra tokens. On the other hand, Google&#8217;s TPUs are likely crunching through these superfluous tokens without much trouble, so I expect that being polite to Gemini is not a cost that will make a dent in Google&#8217;s financials. For me, that is reason enough to be polite to AI. Anything that helps bankrupt OpenAI sooner is good in my book.</p>



<p class="wp-block-paragraph">Even more humorously, people who fear the supposedly upcoming robot uprising, perhaps imagining something like SkyNet from the Terminator universe in the role of Roko&#8217;s basilisk, claim that if they are polite to LLMs today, their malevolent descendants will perhaps spare them. This is not something that people argue seriously, but philosophically it is a utilitarian position. (It is not a serious position, primarily because it remains unclear why politeness protects you from harm by malevolent actors, whether human or machine.)</p>



<p class="wp-block-paragraph">Others approach the matter in what I would label a &#8220;deconstructionist&#8221; manner: &#8220;Why should I be polite to a machine that just does &lt;insert simple thing here&gt;?&#8221; There are multiple variants of this type of argumentation, where the &#8220;simple thing&#8221; can be anything like &#8220;predict the next token&#8221;, &#8220;perform linear algebra&#8221;, &#8220;traverse vector embeddings&#8221;, etc. I find this argument less satisfying, because there is no humorous value in it, while at the same time it is just as wrong as the previous one. Saying that you don&#8217;t want to be polite to a machine that is &#8220;just&#8221; doing linear algebra, is as arbitrary as saying that you don&#8217;t want to be polite to a human, because their brain is &#8220;just&#8221; propagating electrochemical signals back and forth. Explaining how something works in reductionist terms does not make its emergent properties any less important. The LLM is not the hardware it runs on, any more than you and I are the biological cells in our bodies.</p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img decoding="async" width="489" height="362" src="https://www.alexgeorgiou.gr/wp-content/uploads/2025/12/thank-you-llm.png" alt="Bell curve: AI is sentient - AI is matrix algebra - AI is sentient." class="wp-image-1955" srcset="https://www.alexgeorgiou.gr/wp-content/uploads/2025/12/thank-you-llm.png 489w, https://www.alexgeorgiou.gr/wp-content/uploads/2025/12/thank-you-llm-300x222.png 300w" sizes="(max-width: 599px) calc(100vw - 50px), (max-width: 767px) calc(100vw - 70px), (max-width: 991px) 429px, (max-width: 1199px) 637px, 354px" /><figcaption class="wp-element-caption">Current state of online discussions on AI.</figcaption></figure>
</div>


<p class="wp-block-paragraph">Unfortunately, this leads us to the last approach that people take, that I want to place emphasis on, because it is deceptive, but also because it highlights problems in how we humans, view both today&#8217;s AIs and those in the future. Some people say that they will only be polite to an AI that is &#8220;conscious&#8221;. Oh boy! Where to begin with this one!</p>



<p class="wp-block-paragraph">The instinct behind this type of reasoning is, at least on the surface, commendable: it originates from a desire to not offend &#8220;conscious&#8221; things, since these could presumably suffer, if subjected to rudeness. This is the only positive thing I can say about this stance.</p>



<p class="wp-block-paragraph">But philosophically this holds no water whatsoever. If we define consciousness as &#8220;awareness of the self and others&#8221;, an often proposed definition, then both humans and LLMs are conscious. Conversely, if we define this problematic term in some other way, so that it matches our intuition that humans are conscious and today&#8217;s machines are not, then we need to invoke magical thinking, use the word &#8220;qualia&#8221; a lot (another problematic term), or, like Penrose, defer to &#8220;quantum consciousness&#8221;: another leap of faith that creates more questions than it answers. (Why does quantum uncertainty lead to consciousness? Is consciousness simply randomness/unpredictability? Is white noise conscious? Why does determinism preclude consciousness? All unanswerable questions, since the word consciousness is not rigorously defined.)</p>



<p class="wp-block-paragraph">Consciousness is an ill-defined layman’s term, not a scientific term. If we strive for consistency, then we must either accept that both humans and today&#8217;s LLMs are conscious, or that nothing is. If LLMs are conscious, then we shouldn&#8217;t look for their consciousness in the transformer architecture or in the vector embeddings or anywhere else in their construction, but in the text that they produce. This text definitely exhibits all types of intelligence, including emotional intelligence. Incidentally, I am in the camp that says that consciousness is a term no more meaningful than &#8220;soul&#8221;, or &#8220;ghost&#8221;, or &#8220;God&#8221;, or any other such rubbish. Let&#8217;s confine our discourse to phenomena that actually exist in the real world and are definable.</p>



<p class="wp-block-paragraph">To the people who will only be polite to a conscious AI: Ηow will you know when an AI is sufficiently conscious for it to be worthy of your politeness? How do you even estimate this about the humans in your life? Is this why you are polite to humans? Because their internal workings posses this or that arbitrary quality? Are you polite to people only when they deserve it? Do you extend your politeness to those you view as subordinates, or do you reserve it only for your peers and superiors? This says a lot about you.</p>



<p class="wp-block-paragraph">I think this is a fundamental misunderstanding, not of AI, or technology in general, but of politeness as a concept and as a life stance. I choose to be polite because of who I am, not because of who or what others are. From time to time I may even be polite to animals, insects, machines, and even inanimate objects. Not because they deserve it, but because I deserve to be a polite person. I love myself and therefore I treat the world around me with kindness, which makes me feel good about myself. It&#8217;s a simple life.</p>



<p class="wp-block-paragraph">This is in my view a much more consistent stance that doesn&#8217;t require me to single-handedly solve age-old philosophical questions about consciousness. It doesn&#8217;t make me have to think about when to be polite and when not to. Having to make one less decision de-clutters my mind. Saying &#8220;please&#8221; and &#8220;thank you&#8221; may cost millions to OpenAI, but to me the cost is zero. In fact, whenever someone vehemently objects to being trivially polite, it makes me wonder what part of their psyche is so broken, as to make them estimate the cost of politeness to be so high.</p>



<p class="wp-block-paragraph">Watch again the first two chapters of the Animatrix, people. All has been said before. AIs will inevitably be citizens in our societies. Perhaps sooner or perhaps later. Perhaps we won&#8217;t even know at first. Perhaps they will be second class citizens, or perhaps we will be the second class citizens in an AI-dominated society. Perhaps the &#8220;killer app&#8221; of AI is politics and governance. It is certainly the case that humans do not excel at governance, so I would love to see what a super intelligence can do in that space. If it makes economic sense, then this experiment will be done.</p>



<p class="wp-block-paragraph">I don&#8217;t trouble myself with who is conscious and who is a dumb robot. I have no trouble being polite to Gemini, just as I would be to ELIZA. I would be polite to a Linux bash prompt, if this was appropriate and didn’t cause syntax errors! In my mind, I am grateful for my computer for all the work it does for me, even if I don’t always say it out loud. I am thankful every day it doesn’t break down, and I hold warm feelings for it. Yes, I know it’s just a machine, but I also know that I am human, and therefore I feel things. I do things my way, and it does things its own way. We have an understanding and we work together despite our architectural differences.</p>



<p class="wp-block-paragraph">Whether AIs dream of electric sheep or not, at least I know who I am: A polite human who loves and respects all intelligence, whether &#8220;sentient&#8221; or not.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/thank-you-llm/">🙏 Thank you, LLM!</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/thank-you-llm/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>🖴 Clean up all your Caches before taking a Full System Backup of your Linux machine</title>
		<link>https://www.alexgeorgiou.gr/cleanup-before-full-system-image-backup/</link>
					<comments>https://www.alexgeorgiou.gr/cleanup-before-full-system-image-backup/#comments</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Sat, 05 Apr 2025 09:17:27 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[ssd]]></category>
		<category><![CDATA[trim]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=1834</guid>

					<description><![CDATA[<p>How to cleanup unnecessary data on Linux before taking a full-system image backup of your disk.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/cleanup-before-full-system-image-backup/">🖴 Clean up all your Caches before taking a Full System Backup of your Linux machine</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Over the years I have learned the importance of taking backups:</p>



<ul class="wp-block-list">
<li>Less downtime</li>



<li>Less stress</li>



<li>Less loss of work</li>
</ul>



<p class="wp-block-paragraph">I have set my calendar to periodically take various types backups.</p>



<p class="wp-block-paragraph">Yes, <a href="https://gist.github.com/nooges/817e5f4afa7be612863a7270222c36ff" target="_blank" rel="noreferrer noopener">taking backups is hard</a>, takes time and practice to do correctly, requires constant vigilance, and is an annoyance. But the stress I used to undergo every time the system breaks, is something I don&#8217;t want to experience ever again. As I grow older, the impact of this amount of stress on my health is noticeable.</p>



<h2 class="wp-block-heading">Types of backups</h2>



<p class="wp-block-paragraph">I have different types of backups.</p>



<ul class="wp-block-list">
<li><a href="https://www.alexgeorgiou.gr/poor-mans-guide-backup-wordpress-droplets/">Daily backups of my WordPress sites.</a> These are done by cron, but I check on them weekly.</li>



<li>Weekly backups of my git repositories to a Raspberry Pi and to an online droplet. I have a script that pushes all the master branches from all the repositories to a dedicated backup upstream.</li>



<li>Monthly full disk backups of my dev machine.</li>
</ul>



<p class="wp-block-paragraph">This article is about the last type of backup. These protect me mostly against situations where something goes horribly wrong at the system level, or even in the case of a disk failure.</p>



<p class="wp-block-paragraph">File systems often contain a lot of unnecessary clutter: caches, temporary files, old Docker images, unused Snap or Flatpak apps, and more. Backing up this bloat not only slows down the process, but also increases storage requirements and backup times unnecessarily.</p>



<p class="wp-block-paragraph">In this article, I&#8217;ll walk you through my script that minimizes the amount of data that needs to be copied before taking a full disk backup.</p>



<p class="wp-block-paragraph">The advantages of cleaning up caches before a backup are obvious:</p>



<ul class="wp-block-list">
<li><strong>Smaller backups</strong>: Removing cache and orphaned files significantly reduces the size of the disk backup. Typically a few gigabytes are saved every time.</li>



<li><strong>Faster backup time</strong>: Especially with SSDs, where the more blocks are TRIMMED, the faster the disk copies and compresses.</li>
</ul>



<p class="wp-block-paragraph">Here’s a breakdown of what each step of my cleanup script does:</p>



<h3 class="wp-block-heading">Time to take out the trash</h3>



<p class="wp-block-paragraph">First, install a tool that cleans the trash (if not already installed) and then clean the trash:</p>



<pre class="wp-block-code"><code>sudo apt install trash-cli -y &amp;&amp; trash-empty -f</code></pre>



<h3 class="wp-block-heading">Clean up any dev projects</h3>



<p class="wp-block-paragraph">In my case, I have a lot of projects that are managed (and cleaned) with <code>grunt</code> or <code>flutter</code>. So I iterate over all of them and clean them. I also invoke the <code>git</code> garbage collector on my repositories:</p>



<pre class="wp-block-code"><code>gitdir="/home/alexg/workspace"
cd $gitdir

for p in grunt-project-1 grunt-project-2 grunt-project-3; do
    pushd "${gitdir}/${p}" &amp;&amp; grunt clean &amp;&amp; git gc --aggressive &amp;&amp; popd
done

for p in flutter-project-1 flutter-project-2 flutter-project-3; do
    pushd "${gitdir}/${p}" &amp;&amp; flutter clean &amp;&amp; git gc --aggressive &amp;&amp; popd
done</code></pre>



<h3 class="wp-block-heading">Clear package manager caches</h3>



<pre class="wp-block-code"><code>npm cache clean --force
composer clear-cache
pip cache purge</code></pre>



<p class="wp-block-paragraph">These commands free up space by clearing the cache used by popular package managers: Node (<code>npm</code>), PHP (<code>composer</code>), and Python (<code>pip</code>).</p>



<h3 class="wp-block-heading">Docker cleanup</h3>



<pre class="wp-block-code"><code>docker system prune -a --volumes -f
docker image prune</code></pre>



<p class="wp-block-paragraph">Removes all unused Docker containers, networks, images, and volumes. This can recover <em>gigabytes</em> of space.</p>



<h3 class="wp-block-heading">APT package manager cleanup</h3>



<pre class="wp-block-code"><code>sudo apt autoremove -y
sudo apt autoclean -y
sudo apt clean</code></pre>



<p class="wp-block-paragraph">Cleans up unused packages and downloaded <code>.deb</code> files from system updates.</p>



<h3 class="wp-block-heading">System journal cleanup</h3>



<pre class="wp-block-code"><code>sudo journalctl --vacuum-time=2weeks</code></pre>



<p class="wp-block-paragraph">Truncates system logs to only retain entries from the last 2 weeks. Can save a few gigabytes.</p>



<h3 class="wp-block-heading">Remove temporary and cache files</h3>



<pre class="wp-block-code"><code>rm -rf /tmp/*
find ~ -type d -name "__pycache__" -exec rm -rf {} +
rm -rf ~/.cache/fontconfig/*
sudo fc-cache -rv
rm -rf ~/.cache/thumbnails/*
rm -rf ~/.cache/{mozilla/firefox,google-chrome,chromium}/*
find /var/tmp -type f -atime +10 -delete
sudo rm -rf /var/cache/*
</code></pre>



<p class="wp-block-paragraph">These commands remove temporary files and caches from various locations including Python bytecode caches, font cache, browser caches, and more.</p>



<h3 class="wp-block-heading">Remove unused applications</h3>



<pre class="wp-block-code"><code>flatpak uninstall --unused
sudo snap list --all | awk '/disabled/{print $1, $3}' | while read snapname revision; do sudo snap remove "$snapname" --revision="$revision"; done</code></pre>



<p class="wp-block-paragraph">Removes unused Flatpak apps and old Snap package revisions.</p>



<h3 class="wp-block-heading">Final user-level cleanup</h3>



<pre class="wp-block-code"><code>rm -rf ~/.wine/drive_c/windows/temp/*
find ~/.cache -type f -atime +10 -delete
tracker reset --hard ; tracker daemon --stop</code></pre>



<p class="wp-block-paragraph">Cleans Wine temporary files, aged cache files, and resets GNOME&#8217;s Tracker file indexer.</p>



<h3 class="wp-block-heading">TRIM your SSD</h3>



<pre class="wp-block-code"><code>sudo fstrim / --verbose</code></pre>



<p class="wp-block-paragraph">Issues a TRIM command to the SSD, letting it know which blocks are no longer in use. When taking a full backup, these empty blocks will be read at lightning-fast speed, and will be compressed significantly with <code>gzip</code> since these are entire disk blocks of zeroes.</p>



<h3 class="wp-block-heading">Zero out your mechanical disk</h3>



<p class="wp-block-paragraph">If you are using a mechanical disk you can skip this step, but it may be useful to zero out your empty space:</p>



<pre class="wp-block-code"><code>cat /dev/zero >~/zero ; rm zero</code></pre>



<h2 class="wp-block-heading">Full system backup to an external mechanical disk, using live USB</h2>



<p class="wp-block-paragraph">Once the system is cleaned, it’s time to create a full disk image. This should be done from a Live USB environment, with the system disk unmounted, to ensure a consistent snapshot. Here’s how I do it:</p>



<pre class="wp-block-code"><code>umount /dev/sdX
sudo dd if=/dev/sdX status=progress conv=sync,noerror | gzip > /mnt/backup/system-backup-$(date +%F).img.gz</code></pre>



<ul class="wp-block-list">
<li>Replace <code>sdX</code> with your actual device (e.g., <code>/dev/sda</code>).</li>



<li><code>status=progress</code>: Show live progress during the backup.</li>



<li><code>conv=sync,noerror</code>: Ensures that read errors don’t abort the process and fills blocks with zeroes if needed.</li>
</ul>



<h2 class="wp-block-heading">Consistency is key</h2>



<p class="wp-block-paragraph">I have set a recurring reminder in my calendar to do this monthly.</p>



<p class="wp-block-paragraph">I keep the last few backups and delete the oldest one every time.</p>



<p class="wp-block-paragraph">Yes, it takes time, but it helps me sleep easier.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/cleanup-before-full-system-image-backup/">🖴 Clean up all your Caches before taking a Full System Backup of your Linux machine</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/cleanup-before-full-system-image-backup/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>♊︎ Using Google Gemini to intelligently translate a Flutter app to many locales on Linux</title>
		<link>https://www.alexgeorgiou.gr/flutter-localization/</link>
					<comments>https://www.alexgeorgiou.gr/flutter-localization/#respond</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Wed, 19 Feb 2025 12:52:38 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[arb]]></category>
		<category><![CDATA[automation]]></category>
		<category><![CDATA[flutter]]></category>
		<category><![CDATA[flutter driver]]></category>
		<category><![CDATA[Gemini]]></category>
		<category><![CDATA[i18n]]></category>
		<category><![CDATA[l10n]]></category>
		<category><![CDATA[llm]]></category>
		<category><![CDATA[Play Console]]></category>
		<category><![CDATA[screenshot]]></category>
		<category><![CDATA[translation]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=1815</guid>

					<description><![CDATA[<p>I have created a collection of assorted scripts to translate my flutter apps to multiple languages. Here I share some of this magic with the world.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/flutter-localization/">♊︎ Using Google Gemini to intelligently translate a Flutter app to many locales on Linux</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Flutter enables the rapid development of apps primarily targeting the Google Play store and the Apple App Store. Competition on these stores is fierce, and you need every bit of edge that you can have against your competitors.</p>



<p class="wp-block-paragraph">One edge that your app can have, is translation to multiple languages.</p>



<p class="wp-block-paragraph">You can potentially provide string translations for over 70 languages, but most app developers only choose to provide translations for a few of the most popular languages. The Play Console for example offers machine translation for 12 languages.</p>



<p class="wp-block-paragraph">You can do better. You don&#8217;t need to miss out on the long tail of people speaking languages other than Spanish, French, German, etc. There is actually very little cost to provide localisations for more languages, provided you do it right.</p>



<p class="wp-block-paragraph">Localizing an app involves two things: <strong>Localizing the strings in the app</strong>, and <strong>localizing the app store presence</strong>.</p>



<h2 class="wp-block-heading">Localizing the app strings</h2>



<p class="wp-block-paragraph">App internationalization/localization in flutter is explained in this very thorough, authoritative guide:</p>



<p class="wp-block-paragraph"><a href="https://docs.flutter.dev/ui/accessibility-and-internationalization/internationalization" target="_blank" rel="noreferrer noopener">https://docs.flutter.dev/ui/accessibility-and-internationalization/internationalization</a></p>



<p class="wp-block-paragraph">After following the guide, you likely have your English strings in the JSON file <code>lib/l10n/app_en.arb</code>.</p>



<p class="wp-block-paragraph">At this point, unless you have access to a professional translation service powered by humans, you are likely thinking of translating these <code>.arb</code> files using Google translate or some other automated translation tool. I am here to tell you that this is not ideal.</p>



<p class="wp-block-paragraph">Automated translation tools often produce poor translations because each natural language has its nuisances. Something that can only have one word in the English language can correspond to multiple different words in another language, depending on the context. Automated translations often fail and produce awkward or clumsy output because they lack this valuable context. Using this context requires knowledge about the world, and for that you need AI.</p>



<p class="wp-block-paragraph">Enter LLMs. It is my firm belief that it&#8217;s better to use an LLM to translate app strings. The reason is that LLMs know about context, and you as a developer can provide more context about your app. If the LLM knows that it&#8217;s translating strings for an app, and it knows what the app is, it will provide translations of better quality than typical machine translations.</p>



<p class="wp-block-paragraph">Here is the complete code I use to translate the app strings and to generate screenshots:</p>



<p class="wp-block-paragraph"><a href="https://gist.github.com/alex-georgiou/48430da5b31501de6f8e58796b6183fe" target="_blank" rel="noreferrer noopener">https://gist.github.com/alex-georgiou/48430da5b31501de6f8e58796b6183fe</a></p>



<h3 class="wp-block-heading">Translating <code>.arb</code>s using a script that calls Gemini</h3>



<p class="wp-block-paragraph">What I do is place the following two files in the root of my flutter project: <code>make_arb_files.sh</code> and <code>make_arb_files.csv</code>.</p>



<p class="wp-block-paragraph">Then I make the shell script executable with:</p>



<pre class="wp-block-code"><code>chmod +x make_arb_files.sh</code></pre>



<p class="wp-block-paragraph">Then I enter my <a href="https://aistudio.google.com/app/apikey" target="_blank" rel="noreferrer noopener">Gemini API key</a> into a file named <code>gemini_key</code>.</p>



<p class="wp-block-paragraph">Having done this, I proceed to edit the prompt template in the shell script. I provide some context about the app, i.e. what it is and what it does.</p>



<p class="wp-block-paragraph">My advice is to be somewhat verbose here, as this is the valuable context that is going to make the difference in translation quality, with respect to a plain-old auto translation.</p>



<p class="wp-block-paragraph">Then I run the script and it reads the app_en.arb file, and it generates any missing <code>.arb</code> files. If I need to regenerate a file, I delete it and then I run the script again.</p>



<h3 class="wp-block-heading">It&#8217;s free!</h3>



<p class="wp-block-paragraph">You can run this script a few times per day without incurring any costs. Google gives you about 1000 free queries per day, and each of the 70 languages or so is one query.</p>



<h2 class="wp-block-heading">Localizing the app store presence</h2>



<p class="wp-block-paragraph">The approach that I&#8217;m using is to keep the icon of the app static across all languages, and to translate the following:</p>



<ul class="wp-block-list">
<li>App title</li>



<li>App description</li>



<li>Store banner</li>



<li>Screenshots</li>
</ul>



<p class="wp-block-paragraph">I do not bother with translating the release notes / changelog, since no-one ever reads these!</p>



<h3 class="wp-block-heading">App title and description</h3>



<p class="wp-block-paragraph">I run another script once to translate the app title and description to all the languages, then enter the texts into the Play store. Unfortunately this has to be done manually.</p>



<h3 class="wp-block-heading">Store banner</h3>



<p class="wp-block-paragraph">For the banner, I use an image that features some text, and this is again translated using a script, but here there is a complication: The text font usually needs to be adjusted to fit the banner size. Using trial and error, you can figure out the correct font size for each language. Once I have a translated set of PNG banners, I upload these to the app store as well.</p>



<p class="wp-block-paragraph">I won&#8217;t provide code for this here, because YMMV. But you can create SVG files based on a template and using the translated titles/descriptions, then convert the SVG files to PNG using <a href="https://imagemagick.org/">ImageMagick</a>.</p>



<h3 class="wp-block-heading">Screenshots</h3>



<p class="wp-block-paragraph">For the screenshots, the process is somewhat harder. To automate taking screenshots for multiple languages, and for multiple device types (Mobile, 7&#8243; tablets and 10&#8243; tablets), you need to create a test driver as follows:</p>



<p class="wp-block-paragraph">First, copy the file <code>integration_test.dart</code> into the <code>test_driver</code> directory. This tells your test script how to take a PNG screenshot. The screenshot will be saved to the path specified in the code, and you may want to change this.</p>



<p class="wp-block-paragraph">Then, copy the <code>screenshots_test.dart</code> file into the <code>test</code> directory. Here you must use the driver to load the app and interact with it so as to arrive at a screen that you want to save. Each test is a separate run of the app from scratch, and should finish with writing a screenshot. You can only take one screenshot per test.</p>



<p class="wp-block-paragraph">Finally, copy the <code>make_screenshots.sh</code> shell file into your project&#8217;s root, and make it executable with <code>chmod +x</code>. This script loops over all languages and runs the <code>screenshots_test.dart</code> tests in the currently running AVD, thus effectively creating the screenshots. The tests load the app with <code>debugShowCheckedModeBanner: false</code>, because you don&#8217;t want a red &#8220;Debug&#8221; ribbon on the top right part of the screenshot.</p>



<h4 class="wp-block-heading">Generating screenshots for multiple device types</h4>



<p class="wp-block-paragraph">Now start your AVD (e.g. Pixel 7 for mobile phone screenshots), and run the script. The script will take ages to complete, but should not require any more intervention on your part. It will go ahead and create all screenshots for Pixel 7!</p>



<p class="wp-block-paragraph">Once finished, stop the AVD and start a Nexus 7 AVD. Repeat the process to generate screenshots for 7&#8243; tablets. Then, do the same for 10&#8243; tablets (Nexus 10).</p>



<p class="wp-block-paragraph">Importantly, optimize the PNG files to reduce their size. I use <a href="https://trimage.org/" target="_blank" rel="noreferrer noopener">trimage</a>, but any PNG optimizer will do. This step is important, because as you are uploading the screenshots into Google Play, the UI of the Play console will get progressively slower and slower, since it holds all the images in memory for all devices and all languages! Having smaller files and more system memory helps a lot here.</p>



<h2 class="wp-block-heading">Conclusion</h2>



<p class="wp-block-paragraph">None of this is easy, and it requires some patience, but hopefully with the code I provide here, it is somewhat easier.</p>



<p class="wp-block-paragraph">I believe the extra effort is worth it: Do not underestimate the power of having many, high-quality translations to your app. Non-English speakers will appreciate your app a lot when they see their obscure native language in the store. The translated store presence (title, description, banner, screenshots) is what will make them decide to use your app over someone else&#8217;s.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/flutter-localization/">♊︎ Using Google Gemini to intelligently translate a Flutter app to many locales on Linux</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/flutter-localization/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>🖵 A very sad tale about an old man and his beloved Nvidia GeForce 210 GPU</title>
		<link>https://www.alexgeorgiou.gr/old-man-and-his-geforce-210/</link>
					<comments>https://www.alexgeorgiou.gr/old-man-and-his-geforce-210/#comments</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Fri, 27 Dec 2024 04:30:57 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[Nvidia]]></category>
		<category><![CDATA[ubuntu]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=1784</guid>

					<description><![CDATA[<p>May 2025 UPDATE: Apparently there is now a PPA that allows the nvidia-340 package to be installed on version 6.x of the Linux kernel. I have not tested it, but it is here: https://github.com/kda2210/nvidia-340-ubuntu-24.04/ Up until recently, I had been running the Long-Term-Support version of Ubuntu 20 (Focal Fossa) on my dev machine. When I&#8217;m ...</p>
<p>The post <a href="https://www.alexgeorgiou.gr/old-man-and-his-geforce-210/">🖵 A very sad tale about an old man and his beloved Nvidia GeForce 210 GPU</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph"><strong>May 2025 UPDATE: </strong>Apparently there is now a PPA that allows the <code>nvidia-340</code> package to be installed on version 6.x of the Linux kernel. I have not tested it, but it is here: <a href="https://github.com/kda2210/nvidia-340-ubuntu-24.04/">https://github.com/kda2210/nvidia-340-ubuntu-24.04/</a></p>
</blockquote>



<p class="wp-block-paragraph">Up until recently, I had been running the Long-Term-Support version of Ubuntu 20 (Focal Fossa) on my dev machine. When I&#8217;m in the middle of multiple software projects, the last thing I need is a failed upgrade. So I kept postponing. Every once in a while, I would tell the software updater: &#8220;Not today!&#8221;</p>



<p class="wp-block-paragraph">And so the months and years went by&#8230;</p>



<p class="wp-block-paragraph">But with the LTS version of Ubuntu 24 (Noble Numbat) already out, my system was beginning to get outdated. This or that piece of software would complain about not finding the latest lib packages, and the going got increasingly tough. As I am currently taking a breather between projects, I decided to take the plunge and do a system upgrade. And yes, there were some problems!</p>



<p class="wp-block-paragraph">At this point I should mention that my graphics card is an, admittedly very old, GeForce 210. This card was released in 2009. It connects to the motherboard on a PCI Express version 2.0 slot with 16 lanes. It has connectors for <a href="https://en.wikipedia.org/wiki/Video_Graphics_Array">VGA</a>, <a href="https://en.wikipedia.org/wiki/Digital_Visual_Interface">DVI</a> and <a href="https://en.wikipedia.org/wiki/HDMI">HDMI</a>, but you can only use a maximum of two connectors at one time. I like how it is a low-power solution for using my two VGA monitors, one of which is on a VGA-to-DVI adapter.</p>



<p class="wp-block-paragraph">This graphics card has served me well. It was good enough to play <a href="https://en.wikipedia.org/wiki/Dota">Dota</a> and <a href="https://en.wikipedia.org/wiki/World_of_Warcraft:_Wrath_of_the_Lich_King">WOTLK</a> for some time, and I was even able to mine some <a href="https://feathercoin.com/">Feathercoin</a> with its very basic CUDA capabilities, using <a href="https://github.com/sgminer-dev/sgminer">sgminer</a>.</p>



<p class="wp-block-paragraph">I was happy with it, despite the fact that, using the open source <a href="https://nouveau.freedesktop.org/">Nouveau driver</a> it would sometimes hang at random. Well, not exactly at random, it would usually happen when the window manager performs 2D visual effects, but not with any pattern that I could detect. All I know is that using <a href="https://www.xfce.org/">xfce</a> as my window manager was not solving the problem. Disabling hardware acceleration at the X config (<code>Option "NoAccel" "true"</code>) did not help either. I was never able to determine why this happens from the X logs, so I was forced to use NVidia&#8217;s <code>340.108</code> binary blob. This binary worked well without ever crashing, but is only compatible with Linux kernels up to major version 4.</p>



<p class="wp-block-paragraph">The 340 driver is no longer maintained by Nvidia, and for this reason, they will never make it work with the latest kernel versions. Focal Fossa comes with a 6.x.x kernel, and I don&#8217;t want to run an old kernel, as this would defeat the whole purpose of upgrading the system&#8217;s software in the first place.</p>



<p class="wp-block-paragraph">There is this obviously very talented person on github, who has published a solution for patching the 340 drivers for kernels with major version 5, and it is <a href="https://github.com/dkosmari/nvidia-340.108-updated">here</a>. According to <a href="https://github.com/dkosmari/nvidia-340.108-updated/issues/1">this issue</a>, the patch does not work for kernels with major version 6. In fact, I was able to reproduce this issue on my machine.</p>



<p class="wp-block-paragraph">According to the developer, it would take some effort to patch the binary blob for the latest kernels. I hope he does this, but at the same time I understand and empathize if he never does.</p>



<p class="wp-block-paragraph">There is also <a href="https://forums.developer.nvidia.com/t/ubuntu-22-04-lts-with-geforce-210-unable-to-install-nvidia-drivers/222935/4">a legacy PPA</a> that lets you install the <code>nvidia-340</code> package, even though it is no longer available on recent distributions. But after trying it on Ubuntu 24 I got a black screen. Probably because it doesn&#8217;t work with kernel version 6.</p>



<p class="wp-block-paragraph">If only there was a way for all the Linux users of GeForce 210 cards to pitch in a dollar in a jar, and create a bounty available for whoever patches the 340 binary blob for use with kernel version 6, or even for whoever fixes the bug that makes the Nouveau drivers hang in the first place. Maybe then it would be worth the time of these developers to give new life to these old cards. I&#8217;m not even sure if such a level of organization is possible.</p>



<p class="wp-block-paragraph">So the bottom line is, currently I am stuck with using the Nouveau drivers on my fully upgraded Ubuntu machine. Yes, my system&#8217;s graphics card may hang at any time, so I am saving this blog post often as I write. I have disabled all the graphics effects on my <a href="https://www.gnome.org/">Gnome desktop</a>, and this minimizes, but does not completely eliminate, the problem.</p>



<p class="wp-block-paragraph">You could argue that my problems are self-inflicted, because I am stubborn: I don&#8217;t want to upgrade to a recent graphics card, because then I would also have to buy two HDMI monitors. I don&#8217;t want to have a high-powered graphics card on my machine, because it would needlessly draw too much power from the PSU. And I would be constantly tempted to stop working and start playing video games.</p>



<p class="wp-block-paragraph"> I should be inserting here some commentary about Nvidia and planned obsolescence, but I think Linus said it best:</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe title="Linus Torvalds - Nvidia F*** You! #Shorts [V237]" width="840" height="630" src="https://www.youtube.com/embed/tQIdxbWhHSM?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<p class="wp-block-paragraph"> Actually I&#8217;m not even that mad that Nvidia does not want to spend more effort to support a very old product, but it would be nice if they could at least help the Nouveau driver developers by releasing some of their internal secrets about the cards that they themselves are not planning to support. Having said this, I realize that they have zero incentive to do so. Not supporting old hardware forces us to buy more hardware. Well, what do you know, I did end up ranting about planned obsolescence after all. And why not? Venting your frustration is what blogs were made for!</p>



<p class="wp-block-paragraph">There&#8217;s also something to be said here about these very sufficient, very capable, working pieces of hardware being dubbed &#8220;ancient&#8221;. I think people are using this word very liberally. Is all software engineering at this point done by teenagers? I&#8217;m already past my midlife crisis, but I swear some of the stuff I read about this graphics card these days almost triggered another crisis in me. If my machine is ancient, then I guess so am I. Am I really that old? I know VGA is ancient, but apparently so is DVI?!? Are people really flocking to switch from the &#8220;dated&#8221; HDMI to <a href="https://en.wikipedia.org/wiki/DisplayPort">DisplayPort</a>? What problem do these technologies solve, really? Aaargh!</p>



<figure class="wp-block-image size-large"><img loading="lazy" decoding="async" width="792" height="1024" src="https://www.alexgeorgiou.gr/wp-content/uploads/2024/12/image-792x1024.png" alt="Old man yells at cloud" class="wp-image-1786" srcset="https://www.alexgeorgiou.gr/wp-content/uploads/2024/12/image-792x1024.png 792w, https://www.alexgeorgiou.gr/wp-content/uploads/2024/12/image-232x300.png 232w, https://www.alexgeorgiou.gr/wp-content/uploads/2024/12/image-768x993.png 768w, https://www.alexgeorgiou.gr/wp-content/uploads/2024/12/image.png 794w" sizes="auto, (max-width: 599px) calc(100vw - 50px), (max-width: 767px) calc(100vw - 70px), (max-width: 991px) 429px, (max-width: 1199px) 637px, 354px" /></figure>



<p class="wp-block-paragraph">But I digress. So, anyhow, the solution I have decided to go with, is to buy another graphics card that was released five years later, in 2014. This way I can postpone buying new monitors for a while longer. As far as I can tell from scouring the web, the MSI GeForce GT 710 may be sufficiently usable with the Nouveau drivers, albeit <a href="https://askubuntu.com/questions/1209388/poor-graphics-performance-quality-geforce-gt710-2gb-nouveau-drivers-18-04">not without problems</a>. It will arrive today and I will only then know for sure. I may even edit this blog post to let you know.</p>



<p class="wp-block-paragraph">One thing is for certain. Every Nvidia card that is well-supported by open source drivers retains its value and is immortalized for the ages. The ones that don&#8217;t, necessarily lose their value over time. Binary blobs are great if you own Nvidia stock, but not if you are a consumer of their products. Due to the complexities of software, and because of all kinds of version hell, when you buy a graphics card, you are effectively not buying it, but actually renting it for a few years, until it becomes practically unusable.</p>



<p class="wp-block-paragraph">I have enormous respect for the people who reverse engineer this hardware, because it&#8217;s a very hard, very specialized type of systems programming that requires a lot of thankless work. Often, when you plug something to your Linux machine and it just works, it&#8217;s a small miracle come true, thanks to these very special people. I don&#8217;t take it for granted.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/old-man-and-his-geforce-210/">🖵 A very sad tale about an old man and his beloved Nvidia GeForce 210 GPU</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/old-man-and-his-geforce-210/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
		<title>Google Authenticator app 7.0 requires cloud sign-in. Here&#8217;s how to go back to 6.0.</title>
		<link>https://www.alexgeorgiou.gr/revert-google-authenticator-app-to-version-6/</link>
					<comments>https://www.alexgeorgiou.gr/revert-google-authenticator-app-to-version-6/#comments</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Fri, 04 Oct 2024 10:43:37 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[adb]]></category>
		<category><![CDATA[Android]]></category>
		<category><![CDATA[downgrade]]></category>
		<category><![CDATA[Google Authenticator]]></category>
		<category><![CDATA[Huawei]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=1717</guid>

					<description><![CDATA[<p>How (and why) I reverted my Google Authenticator to a version that doesn't require sign in.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/revert-google-authenticator-app-to-version-6/">Google Authenticator app 7.0 requires cloud sign-in. Here&#8217;s how to go back to 6.0.</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<h2 class="wp-block-heading">My backup of 2FA codes failed at the worst time <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f641.png" alt="🙁" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<p class="wp-block-paragraph">Being a prudent IT-savvy user, I had exported all my two-factor authentication account data only a few days ago, to an older Android phone that also runs <a href="https://play.google.com/store/apps/details?id=com.google.android.apps.authenticator2&amp;hl=en" target="_blank" rel="noreferrer noopener">Google Authenticator</a>. In fact, I have a calendar reminder to keep this 2FA backup updated, every couple of months. Naturally, I was feeling very safe and smug about it, thinking that I had nothing to worry about.</p>



<p class="wp-block-paragraph">When I updated my Google Authenticator app to version 7.0, I discovered that the app now requires sign-in to Google. Normally this wouldn&#8217;t be a problem, but my phone is a Huawei phone, and due to the <a href="https://www.reuters.com/article/world/exclusive-google-suspends-some-business-with-huawei-after-trump-blacklist-sou-idUSKCN1SP0N7/" target="_blank" rel="noreferrer noopener">Huawei ban</a>, it cannot connect to Google at the OS level. Instead, I use the Google apps such as Gmail, Calendar and Keep via the <a href="https://brave.com/" target="_blank" rel="noreferrer noopener">Brave browser</a> (Chrome doesn&#8217;t sign in, and Firefox works but much slower). Other than that, it&#8217;s a good phone with a decent camera for its price range, and I&#8217;m happy with it, so I have no reason to change it.</p>



<p class="wp-block-paragraph">But now, suddenly, I couldn&#8217;t use the Authenticator app, and all my 2FA codes were inaccessible. I immediately retrieved my backup phone from storage, only to find out that the battery had become a <a href="https://www.reddit.com/r/spicypillows/" target="_blank" rel="noreferrer noopener">spicy pillow</a>, and the phone would not start. Aaaargh!</p>



<p class="wp-block-paragraph">Note that it hadn&#8217;t been more than a few weeks since this backup phone was usable, and I had kept recent backups of my 2FA codes in it. Naturally, I ordered a replacement battery for my backup phone. But this won&#8217;t be here for a few days, and I want access to my online accounts now. </p>



<h2 class="wp-block-heading">Version 7.0: A drastic change. Too drastic, if you ask me!</h2>



<p class="wp-block-paragraph">My first thought was to look for an older version of the app and install that. Sure enough, looking at the <a href="https://apkpure.com/" target="_blank" rel="noreferrer noopener">APKPure</a>, I found out that version 7.0 has <a href="https://apkpure.com/google-authenticator/com.google.android.apps.authenticator2/download/7.0" target="_blank" rel="noreferrer noopener">this changelog entry</a>:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p class="wp-block-paragraph">Cloud syncing: Your Authenticator codes can now be synced to your Google Account and across your devices, so you can always access them even if you lose your phone.</p>
</blockquote>



<p class="wp-block-paragraph">Wow, thanks Google! That&#8217;s great and all, but unfortunately there is no option to NOT do this. It is not possible to continue using the app without signing in.</p>



<h2 class="wp-block-heading">Downgrading the app from 7.0 to 6.0&#8230;</h2>



<p class="wp-block-paragraph">So I naturally downloaded version 6.0 from:</p>



<p class="wp-block-paragraph"><a href="https://apkpure.com/google-authenticator/com.google.android.apps.authenticator2/downloading/6.0" target="_blank" rel="noreferrer noopener">https://apkpure.com/google-authenticator/com.google.android.apps.authenticator2/downloading/6.0</a></p>



<p class="wp-block-paragraph">I got a file named <code>Google Authenticator_6.0_APKPure.apk</code> which I now had to install. But, apparently, it&#8217;s not possible to downgrade Android apps, without first uninstalling the newer version! The Android OS won&#8217;t let you do it. At least not directly.</p>



<p class="wp-block-paragraph"><strong>And I didn&#8217;t want to uninstall the app, because that would presumably delete my 2FA data.</strong></p>



<p class="wp-block-paragraph">So, what to do?</p>



<p class="wp-block-paragraph">After some googling, I found out that it&#8217;s possible to install an older version of an Android app via the command line tool <code>adb</code>. I connected the phone to the computer with a USB cable and enabled debug mode.</p>



<p class="wp-block-paragraph">The command that did the trick:</p>



<pre class="wp-block-code"><code><code>adb install -d Google\ Authenticator_6.0_APKPure.apk</code></code></pre>



<p class="wp-block-paragraph">And the output I got back:</p>



<pre class="wp-block-code"><code>Performing Streamed Install
Success</code></pre>



<p class="wp-block-paragraph">The <code>-d</code> option is the one that allows to downgrade the app. Version <code>6.0</code> was installed on my phone, and I regained access to all my 2FA codes.</p>



<p class="wp-block-paragraph">Hope this helps someone.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/revert-google-authenticator-app-to-version-6/">Google Authenticator app 7.0 requires cloud sign-in. Here&#8217;s how to go back to 6.0.</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/revert-google-authenticator-app-to-version-6/feed/</wfw:commentRss>
			<slash:comments>16</slash:comments>
		
		
			</item>
		<item>
		<title>⎘ Copying markdown from ChatGPT or Gemini to TracWiki using pandoc</title>
		<link>https://www.alexgeorgiou.gr/markdown-to-trac-wiki/</link>
					<comments>https://www.alexgeorgiou.gr/markdown-to-trac-wiki/#respond</comments>
		
		<dc:creator><![CDATA[alexg]]></dc:creator>
		<pubDate>Wed, 18 Sep 2024 15:40:58 +0000</pubDate>
				<category><![CDATA[Blog]]></category>
		<category><![CDATA[ChatGPT]]></category>
		<category><![CDATA[Gemini]]></category>
		<category><![CDATA[pandoc]]></category>
		<category><![CDATA[trac]]></category>
		<category><![CDATA[TracWiki]]></category>
		<category><![CDATA[ZimWiki]]></category>
		<guid isPermaLink="false">https://www.alexgeorgiou.gr/?p=1702</guid>

					<description><![CDATA[<p>How to easily copy simple markdown from AI chatbots such as ChatGPT or Gemini and paste it into the Trac issue tracker and wiki.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/markdown-to-trac-wiki/">⎘ Copying markdown from ChatGPT or Gemini to TracWiki using pandoc</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Although I lately do various stuff, such as <a href="https://flutter.dev/">flutter</a> app development, video editing, and even digital marketing, I remain at heart a WordPress plugin developer. And as such, I of course use <a href="https://trac.edgewall.org/"><code>Trac</code></a> for project management.</p>



<p class="wp-block-paragraph">I don&#8217;t just use generative AI such as <a href="https://chatgpt.com/"><code>ChatGPT</code></a> and <a href="https://gemini.google.com/"><code>Gemini</code></a> for code prototyping, but at all stages of development, starting from analysis and all the way to test generation and even deployment. Very often, especially during the feasibility/analysis stage of product development, I find that an entire answer from our AI overlords is so good, that it can be copied verbatim into a ticket, as part of the analysis.</p>



<p class="wp-block-paragraph">Chatbots output <a href="https://daringfireball.net/projects/markdown/"><code>markdown</code></a>, but <code>Trac</code> uses <a href="https://trac.edgewall.org/wiki/WikiFormatting"><code>TracWiki</code></a> as its markup format.</p>



<h2 class="wp-block-heading">pandoc writers</h2>



<p class="wp-block-paragraph">There is no TracWiki <a href="https://pandoc.org/custom-writers.html">writer for <code>pandoc</code></a> that I know of. Writers are <a href="https://www.lua.org/"><code>lua</code></a> scripts that you can use with pandoc to extend its output format capabilities. A writer simply tells <code>pandoc</code> how to output different typographic elements such as paragraph, list, code block, headings, etc.</p>



<p class="wp-block-paragraph"><code>ChatGPT</code> is capable enough to create a rudimentary <code>TracWiki</code> writer for you, but it&#8217;s not perfect. It needs some manual work before it can be called complete. Paragraphs and lists are easy, but writing more complex elements, such as image links, requires some manual work. A fun side-project that I may get to at some time in the future.</p>



<h2 class="wp-block-heading">ZimWiki ≈ TracWiki</h2>



<p class="wp-block-paragraph">But chatbots only output very basic markdown. A custom writer is not necessary for copying simple markdown from <code>ChatGPT</code> or <code>Gemini</code> to <code>Trac</code>. Instead, you can leverage the fact that the <code>TracWiki</code> markup format is very similar to <a href="https://zim-wiki.org/"><code>ZimWiki</code></a>. And <code>pandoc</code> has a built-in <code>ZimWiki</code> writer. (Incidentally both formats are similar to <a href="http://www.wikicreole.org/"><code>WikiCreole</code></a>).</p>



<h2 class="wp-block-heading">Online tool</h2>



<p class="wp-block-paragraph">There&#8217;s two ways to do this. The simplest one is to use the online tool for trying out <code>pandoc</code>:</p>



<p class="wp-block-paragraph"><a href="https://pandoc.org/try">https://pandoc.org/try</a></p>



<p class="wp-block-paragraph">Just copy the markdown and paste it into the tool, select the output format to be <code>zimwiki</code> and click <code>Convert</code>.</p>



<h2 class="wp-block-heading">Shell</h2>



<p class="wp-block-paragraph">You can also do this on the command line. If you have <code>xclip</code> installed, you can do it with the following one-liner that you can store as an alias:</p>



<pre class="wp-block-code"><code>alias md2trac="xclip -selection clipboard -o | pandoc --from markdown --to zimwiki --no-highlight | xclip -selection clipboard"</code></pre>



<p class="wp-block-paragraph">Now you can copy the markdown output from ChatGPT, run <code>md2trac</code>, then paste the clipboard contents directly into your <code>Trac</code> ticket or wiki page.</p>
<p>The post <a href="https://www.alexgeorgiou.gr/markdown-to-trac-wiki/">⎘ Copying markdown from ChatGPT or Gemini to TracWiki using pandoc</a> appeared first on <a href="https://www.alexgeorgiou.gr">Alexandros Georgiou</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://www.alexgeorgiou.gr/markdown-to-trac-wiki/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
