groff --version
)?
@movq@www.uninformativ.de It’s an ancient 1.22.4. :-)
Hey @itsericwoodward@itsericwoodward.com, I just wanna let you know that twtstrm/0.4.0 sends a broken User-Agent
header. Instead of the URL, the nick is repeated.
@bender@twtxt.net Thanks for asking!
So, I’ve been working on 2 main twtxt-related projects.
The first is small Node / express application that serves up a twtxt file while allowing its owner to add twts to it (or edit it outright), and I’ve been testing it on my site since the night I made that post. It’s still very much an MVP, and I’ve been intermittently adding features, improving security, and streamlining the code, with an eye to release it after I get an MVP done of project #2 (the reader).
But that’s where I’ve been struggling. The idea seems simple enough - another Node / express app (this one with a Vite-powered front-end) that reads a public twtxt file, parses the “follow” list, grabs (and parses) those twtxt files, and then creates a river of twts out of the result. The pieces work fine in seclusion (and with dummy data), but I keep running into weird issues when reading real-live twtxt files, so some twts come through, while others get lost in the ether. I’ll figure it out eventually, but for now, I’ve been spending far more time than I anticipated just trying to get it to work end-to-end.
On top of it, the 2 projects wound up turning into 4 (so far), as I’ve been spinning out little libraries to use across both apps (like https://jsr.io/@itsericwoodward/fluent-dom-esm, and a forthcoming twtxt helper library).
In the end, I’m hoping to have project 1 (the editor) into beta by the end of October, and project 2 (the reader) into beta sometime after that, but we’ll see.
I hope this has satisfied your curiosity, but if you’d like to know more, please reach out!
@bender@twtxt.net Thanks for asking!
So, I’ve been working on 2 main twtxt-related projects.
The first is small Node / express application that serves up a twtxt file while allowing its owner to add twts to it (or edit it outright), and I’ve been testing it on my site since the night I made that post. It’s still very much an MVP, and I’ve been intermittently adding features, improving security, and streamlining the code, with an eye to release it after I get an MVP done of project #2 (the reader).
But that’s where I’ve been struggling. The idea seems simple enough - another Node / express app (this one with a Vite-powered front-end) that reads a public twtxt file, parses the “follow” list, grabs (and parses) those twtxt files, and then creates a river of twts out of the result. The pieces work fine in seclusion (and with dummy data), but I keep running into weird issues when reading real-live twtxt files, so some twts come through, while others get lost in the ether. I’ll figure it out eventually, but for now, I’ve been spending far more time than I anticipated just trying to get it to work end-to-end.
On top of it, the 2 projects wound up turning into 4 (so far), as I’ve been spinning out little libraries to use across both apps (like https://jsr.io/@itsericwoodward/fluent-dom-esm, and a forthcoming twtxt helper library).
In the end, I’m hoping to have project 1 (the editor) into beta by the end of October, and project 2 (the reader) into beta sometime after that, but we’ll see.
I hope this has satisfied your curiosity, but if you’d like to know more, please reach out!
@prologic@twtxt.net I know we won’t ever convince each other of the other’s favorite addressing scheme. :-D But I wanna address (haha) your concerns:
I don’t see any difference between the two schemes regarding link rot and migration. If the URL changes, both approaches are equally terrible as the feed URL is part of the hashed value and reference of some sort in the location-based scheme. It doesn’t matter.
The same is true for duplication and forks. Even today, the “cannonical URL” has to be chosen to build the hash. That’s exactly the same with location-based addressing. Why would a mirror only duplicate stuff with location- but not content-based addressing? I really fail to see that. Also, who is using mirrors or relays anyway? I don’t know of any such software to be honest.
If there is a spam feed, I just unfollow it. Done. Not a concern for me at all. Not the slightest bit. And the byte verification is THE source of all broken threads when the conversation start is edited. Yes, this can be viewed as a feature, but how many times was it actually a feature and not more behaving as an anti-feature in terms of user experience?
I don’t get your argument. If the feed in question is offline, one can simply look in local caches and see if there is a message at that particular time, just like looking up a hash. Where’s the difference? Except that the lookup key is longer or compound or whatever depending on the cache format.
Even a new hashing algorithm requires work on clients etc. It’s not that you get some backwards-compatibility for free. It just cannot be backwards-compatible in my opinion, no matter which approach we take. That’s why I believe some magic time for the switch causes the least amount of trouble. You leave the old world untouched and working.
If these are general concerns, I’m completely with you. But I don’t think that they only apply to location-based addressing. That’s how I interpreted your message. I could be wrong. Happy to read your explanations. :-)
@prologic@twtxt.net I can see the issues mentioned, but I think some can be fixed.
The current hash relies on a
url
field too, by specification, it will use the first# url = <URL>
in the feed’s metadata if present, that too can be different from the fetching source, if that field changes it would break the existing hashes too, a better solution would be to use a non-URL key like# feed_id = <UNIQUE_RANDOM_STRING>
with theurl
as fallback.We can prevent duplications if the reference uses that same url field too or the client “collapse” any reference of all the urls defined in the metadata.
I agree that hashing based on content is good, but we still use the URL as part of the hashing, which is just a field in the feed, easily replicable by a bot, also noting that edits can also break the hash, for this issue an alternative solution (E.g. a private key not included in the feed) should be considered.
For offline reading the source would be downloaded already, the fetching of non followed feeds would fill the gap in the same way mentions does, maybe I’m missing some context on this one.
To prevent collisions there was a discussion on extending the hash (forgot if that was already fixed or not), but without a fallback that would break existing clients too, we should think of a parallel format that maintains current implementations unchanged, we are already backward compatible with the original that don’t use threads at all, a mention style format for that could be even more user-friendly for those clients.
We should also keep in mind that the current mention format is already location based (@<example https://example.com/twtxt.txt>
) so I’m not that worried about threads working the same way.
Hope to see some other thought about this matter. 🤓
I’ve got a prototype of my hardcopy simulator going. I’m typing on the keyboard and the “display” goes to the printer:
https://movq.de/v/56feb53912/s.png
https://movq.de/v/235c1eabac/MVI_8810.MOV.mp4
The biiiiiiiiiig problem is that the print head and plastic cover make it impossible to see what’s currently being printed, because this is not a typewriter. This means: In order to see what I just entered, I have to feed the paper back and forth and back and forth … it’s not ideal.
I got that idea of moving back/forth from Drew DeVault, who – as it turned out – did something similar a few years back. (I tried hard to read as little as possible of his blog post, because figuring things out myself is more fun. But that could mean I missed a great idea here or there.)
But hey, at least this is running on my Pentium 133 on SuSE Linux 6.4, printer connected with a parallel cable. 😍
(Also, yes, you can see the printouts of earlier tests and, yes, I used ed(1)
wrong at one point. 🤪 And ls
insisted on using colors …)
Here’s an interesting thought/angle on this topic:
gemini://gemini.conman.org/boston/2025/08/21.1
A further check showed that all the network blocks are owned by one organization—Tencent [4]. I’m seriously thinking that the CCP (Chinese Communist Party) encourage this with maybe the hope of externalizing the cost of the Great Firewall [5] to the rest of the world.
(Just for fun, SuSE Linux 6.4 from ~25 years ago: https://movq.de/v/dc62d0256c/s.png )
@lyse@lyse.isobeef.org @kat@yarn.girlonthemoon.xyz Colorized manpages have been a thing for a very long time:
https://movq.de/v/81219d7f7a/s.png
Problem is, hardly anybody knows this, because you configure this by … drumroll … overwriting TERMCAP entries of less
in your ~/.bashrc
:
export LESS_TERMCAP_md=$'\e[38;5;3m' # Bold
export LESS_TERMCAP_me=$'\e[0m' # End Bold
export LESS_TERMCAP_us=$'\e[4;38;5;6m' # Underline
export LESS_TERMCAP_ue=$'\e[0m' # End Underline
export GROFF_NO_SGR=1 # Needed since groff 1.23
@kat@yarn.girlonthemoon.xyz https://snippets.4-walls.net/kat/890f9db00b1940679161d0348b28c339
@lyse@lyse.isobeef.org 4 years. 🫤
i am having fun with dmenu
https://bytes.4-walls.net/kat/dotfiles/src/branch/main/config/.local/bin/dict
https://bytes.4-walls.net/kat/dotfiles/commit/b5ca2e0eaba3cbc0cf0898926ffcb0bb064d17c7
@kat@yarn.girlonthemoon.xyz NVM i stole other peoples code to make a dictionary lookup script https://bytes.4-walls.net/kat/dotfiles/src/branch/main/config/.local/bin/dict
@lyse@lyse.isobeef.org @kat@yarn.girlonthemoon.xyz I spent so much time in the past figuring out if something is a dict or a list in YAML, for example.
What are the types in this example?
items:
- part_no: A4786
descrip: Water Bucket (Filled)
price: 1.47
quantity: 4
- part_no: E1628
descrip: High Heeled "Ruby" Slippers
size: 8
price: 133.7
quantity: 1
items
is a dict containing … a list of two other dicts? Right?
It is quite hard for me to grasp the structure of YAML docs. 😢
The big advantage of YAML (and JSON and TOML) is that it’s much easier to write code for those formats, than it is with XML. json.loads()
and you’re done.
The WM_CLASS
Property is used on X11 to assign rules to certain windows, e.g. “this is a GIMP window, it should appear on workspace number 16.” It consists of two fields, name
and class
.
Wayland (or rather, the XDG shell protocol – core Wayland knows nothing about this) only has a single field called app_id
.
When you run X11 programs under Wayland, you use XWayland, which is baked into most compositors. Then you have to deal with all three fields.
Some compositors map name
to app_id
, others map class
to app_id
, and even others directly expose the original name
and class
.
Apparently, there is no consensus.
@movq@www.uninformativ.de Yeah, it’s a shitshow. MS overconfirms all my prejudices constantly.
Ignoring e-mail after lunch works great, though. :-)
Our timetracking is offline for over a week because of reasons. The responsible bunglers are falling by the skin of their teeth: https://lyse.isobeef.org/tmp/timetracking.png
- The error message neither includes the timeframe nor a link to an announcement article.
- The HTML page needs to download JS in order to display the fucking error message.
- Proper HTTP status codes are clearly only for big losers.
- Despite being down, heaps of resources are still fetched.
I find it really fascinating how one can screw up on so many levels. This is developed inhouse, I’m just so glad that we’re not a software engineering company. Oh wait. How embarrassing.
@prologic@twtxt.net Yeah, this really could use a proper definition or a “manifest”. 😅 Many of these ideas are not very wide spread. And I haven’t come across similar projects in all these years.
Let’s take the farbfeld image format as an example again. I think this captures the “spirit” quite well, because this isn’t even about code.
This is the entire farbfeld spec:
farbfeld is a lossless image format which is easy to parse, pipe and compress. It has the following format:
╔════════╤═════════════════════════════════════════════════════════╗
║ Bytes │ Description ║
╠════════╪═════════════════════════════════════════════════════════╣
║ 8 │ "farbfeld" magic value ║
╟────────┼─────────────────────────────────────────────────────────╢
║ 4 │ 32-Bit BE unsigned integer (width) ║
╟────────┼─────────────────────────────────────────────────────────╢
║ 4 │ 32-Bit BE unsigned integer (height) ║
╟────────┼─────────────────────────────────────────────────────────╢
║ [2222] │ 4x16-Bit BE unsigned integers [RGBA] / pixel, row-major ║
╚════════╧═════════════════════════════════════════════════════════╝
The RGB-data should be sRGB for best interoperability and not alpha-premultiplied.
(Now, I don’t know if your screen reader can work with this. Let me know if it doesn’t.)
I think these are some of the properties worth mentioning:
- The spec is extremely short. You can read this in under a minute and fully understand it. That alone is gold.
- There are no “knobs”: It’s just a single version, it’s not like there’s also an 8-bit color depth version and one for 16-bit and one for extra large images and one that supports layers and so on. This makes it much easier to implement a fully compliant program.
- Despite being so simple, it’s useful. I’ve used it in various programs, like my window manager, my status bars, some toy programs like “tuxeyes” (an Xeyes variant), or Advent of Code.
- The format does not include compression because it doesn’t need to. Just use something like bzip2 to get file sizes similar to PNG.
- It doesn’t cover every use case under the sun, but it does cover the most important ones (imho). They have discussed using something other than RGBA and decided it’s not worth the trouble.
- They refrained from adding extra baggage like metadata. It would have needlessly complicated things.
Saw this on Mastodon:
https://racingbunny.com/@mookie/114718466149264471
18 rules of Software Engineering
- You will regret complexity when on-call
- Stop falling in love with your own code
- Everything is a trade-off. There’s no “best” 3. Every line of code you write is a liability 4. Document your decisions and designs
- Everyone hates code they didn’t write
- Don’t use unnecessary dependencies
- Coding standards prevent arguments
- Write meaningful commit messages
- Don’t ever stop learning new things
- Code reviews spread knowledge
- Always build for maintainability
- Ask for help when you’re stuck
- Fix root causes, not symptoms
- Software is never completed
- Estimates are not promises
- Ship early, iterate often
- Keep. It. Simple.
Solid list, even though 14 is up for debate in my opinion: Software can be completed. You have a use case / problem, you solve that problem, done. Your software is completed now. There might still be bugs and they should be fixed – but this doesn’t “add” to the program. Don’t use “software is never done” as an excuse to keep adding and adding stuff to your code.
@prologic@twtxt.net … or just bullshit.
I’m Alex, COO at ColdIQ. Built a $4.5M ARR business in under 2 years.
Some “C-level” guy telling people what to do, yeah, I have my doubts.
@movq@www.uninformativ.de make that 4 people! i use plain text when i can because this page convinced me lmfao
@movq@www.uninformativ.de Me too 😅 – Speaking of which i know you’ve lost a bit of “mojo” or “energy” (so have i of late), rest assured, I want to keep the status quo here with what we’ve built, keep it simple and change very little. What we’ve built has worked very well for 5+ years and we have at least 3 very strong clients (maybe 4 or 5?).
@movq@www.uninformativ.de Ahh but it kind of is mine 😅 Or at least I’ve done this kind of thing at least 3 or 4 times now 🤣
SuSE Linux 6.4 and Arachne on DOS also work (with Windows 2000 as a call target):
This is my highlight, really, haven’t seen this in action in a loooooooong time:
@kat@yarn.girlonthemoon.xyz https://snippets.4-walls.net/kat/f1381409ed8244f0a60e0a7a6de23365
hosted opengist because i got bored. works with authelia
One of the nicest things about Go is the language itself, comparing Go to other popular languages in terms of the complexity to learn to be proficient in:
- Go:
25
keywords (Stack Overflow); CSP-style concurrency (goroutines & channels)
- Python 2:
30
keywords (TutorialsPoint); GIL-bound threads & multiprocessing (Wikipedia)
- Python 3:
35
keywords (Initial Commit); GIL-bound threads,asyncio
& multiprocessing (Wikipedia, DEV Community)
- Java:
50
keywords (Stack Overflow); threads +java.util.concurrent
(Wikipedia)
- C++:
82
keywords (Stack Overflow);std::thread
, atomics & futures (en.cppreference.com)
- JavaScript:
38
keywords (Stack Overflow); single-threaded event loop &async/await
, Web Workers (Wikipedia)
- Ruby:
42
keywords (Stack Overflow); GIL-bound threads (MRI), fibers & processes (Wikipedia)
i switched my bookmarks site from espial (unmaintained project) to linkding, and while i’ll miss espial’s simplicity, i do appreciate linkding’s power and the provided API.
at first i got auth working with my SSO (authelia) and was happy, but i want my public bookmarks available without login… and i couldn’t configure my proxy to make that work, because of issues with sub paths, which sucks. so i switched to linkding’s built-in auth. inconvenient, but worth it to share my bookmarks.
@lyse@lyse.isobeef.org that’s alright haha! i don’t expect anyone to listen/watch in full or with full attention bc it’s so long lmao
the thing with PHP for me is that i… feel like it hits a kind of simplicity that i can understand? it’s so plain but can be very powerful. i quite like that. as much as i can learn something infinitely more powerful, PHP hits a comfortable thing where i can handle things like backend sqlite DBs AND how a page is rendered, without requiring a complex frontend with its own quirks (like ruby on rails, which as much as i know and love it, can be heavy).
but i totally get you! PHP security is very scary. i’m always worried that i’m messing something up. it’s why the PHP application i’m working on i have dockerized by default for a small but extra layer of protection
i’ll try to not get discouraged tysm for your advice
morning yarn verse, i was up for 20 hours yesterday and i got 4 hours of sleep today. FML
Buying a TV these days, means trying to avoid endless enshitification:
-Spyware and adware
-Shitty AI upscaling/ frame interpolation
-HW that breaks after 2 - 3 years
-One off OS, dead on arrival
-Android OS, that starts lagging after the third update
-8 buttons worth of ads, on your remote
You probably have to make some kind of a compromise. I thought that was buying from some other brand like Hyundai, but that one also felt into some of those categories and just broke, after less than 3 years of use. At this point I’ll probably go back to LG and hope their HW is still reliable and the rest manageable… It has AI bullshit and knowing LG, probably some spyware you have to try your best to get rid of, can buy a remote with “only” 2 ads on it, some web-based OS shared between all their TVs, that usually gets 4 - 5 years worth of updates and works decently enough afterwards.
At this point, I’ll probably settle for anything that doesn’t literally fall apart, not even 3 years in, like the Hyundai did.
1 RPM
. This is a rather aggressive rate limit actually. This basically makes Github inaccessible and useless for basically anything unless you're logged in. You can basically kiss "pursuing" casually, anonymously goodbye.
@bender@twtxt.net 5, 4, 3, 2, 1 🤣
@kat@yarn.girlonthemoon.xyz i’m so obsessed like now i actually wanna play with the site more https://bytes.4-walls.net/kat/eunoia-astro
tar
and find
were written by the devil to make sysadmins even more miserable
@kat@yarn.girlonthemoon.xyz my terrible script https://bytes.4-walls.net/kat/dotfiles/src/branch/main/scripts/Scripts/tinypin-log.sh
playing a bit of guitar this morning
https://freetar.4-walls.net/tab/fifty-fifty/cupid-twin-version-chords-4667768?no_redirect
https://freetar.4-walls.net/tab/chappell-roan/good-luck-babe-chords-5191149?no_redirect
Running - 4 miles: 4.00 miles, 00:09:40 average pace, 00:38:41 duration
nice and easy run on the treadmill. not sure how much i am going to run this week in anticipation for the final run.
#running #treadmill
slowing working away at my latest code project: learning PHP by recreating the 2000s fandom mainstay known as a fanlisting! it’s been super fun i added a dynamic nav bar and other modifications in the latest commit
fanlistings even to this day rely on old PHP scripts dating back to the early 2000s that need whole ass mySQL or postgres DBs and are incredibly insecure. you can look at them here they’re like super jank lol it’s sad that new fanlistings have to use them because there’s no other options….
Running - 4 miles: 4.78 miles, 00:08:03 average pace, 00:38:28 duration
jamming out and ran to the end of the song
#running #treadmill
i don’t think any of you know what a fan listing is but basically it was a fandom thing in the 2000s where people would make websites that other people could sign up for to show they’re a fan of something. more info here.
anyway i made a fan listing kinda thing in PHP to learn the language. it was fun af
i hosted a forgejo instance out of boredom. it’s pretty epic https://bytes.4-walls.net/kat
gah i’ve been so busy working on love4eva! TL;DR i switched image backends from the test/dev only module i was using to the S3 one, but with a catch - i’m not using S3 or cloud shit!!! i instead got it to work with minio, so it’s a middle ground between self hosting the image uploads & being compatible with the highly efficient S3 module. i’m super happy with it :)
i posted a patreon update that details the changes more: https://www.patreon.com/posts/i-am-now-working-127687614
that post says i didn’t update my guide yet but i actually did like right after i made that post lol so you can CTRL+F
for minio stuff there!
We havet an AI assistant at work, new version came out today “nearby restaurant recommendations” mentioned. Gotta try that!
Ask it where I can get a burger, knowing there’s 3 spots that had it on the menu, AI says there’s none. Ask it to list all the restaurants nearby it can check… it knows 3, of the 10 or so around, but 1/3, even has a burger, on the menu.
Ask it to list the whole menu at restaurant 1: it hallucinates random meals, none of which they had (I ate there).
Restaurant 2 (the one most people go to, so they must have at least tested it with this one): it lists the soup of the day and ¾ meals available. Incomplete, but better than false.
Restaurant 3: it says “food” and gives a general description of food. You have to be fucking kidding me!
“BuT cAnInE, tHe A(G)i ReVoLuTiOn Is NoW”
Running - 4 miles: 3.99 miles, 00:09:26 average pace, 00:37:41 duration
Trinity Desktop Environment R14.1.4 released
The Trinity Desktop Environment, the modern-day continuation of the KDE 3.x series, has released version R14.1.4. This maintenance release brings new vector wallpapers and colour schemes, support for Unicode surrogate characters and planes above zero (for emoji, among other things), tabs in kpdf, transparency and other new visual effects for Dekorator, and much more. TDE R14.1.4 is already available for a variety of Linux distributions, and c … ⌘ Read more
7
to 12
and use the first 12
characters of the base32 encoded blake2b hash. This will solve two problems, the fact that all hashes today either end in q
or a
(oops) 😅 And increasing the Twt Hash size will ensure that we never run into the chance of collision for ions to come. Chances of a 50% collision with 64 bits / 12 characters is roughly ~12.44B Twts. That ought to be enough! -- I also propose that we modify all our clients and make this change from the 1st July 2025, which will be Yarn.social's 5th birthday and 5 years since I started this whole project and endeavour! 😱 #Twtxt #Update
We have 4 clients but this should be 6 I believe with tt2
from @lyse@lyse.isobeef.org and Twtxtory from @javivf@adn.org.es?
Can you automate the drawing with a script? On X11, you can:
#!/bin/sh
# Position the pointer at the center of the dot, then run this script.
sleep 1
start=$(xdotool getmouselocation --shell)
eval $start
r=400
steps=100
down=0
for step in $(seq $((steps + 1)) )
do
# pi = 4 * atan(1)
new_x=$(printf '%s + %s * c(%s / %s * 2 * (4 * a(1)))\n' $X $r $step $steps | bc -l)
new_y=$(printf '%s + %s * s(%s / %s * 2 * (4 * a(1)))\n' $Y $r $step $steps | bc -l)
xte "mousemove ${new_x%%.*} ${new_y%%.*}"
if ! (( down ))
then
xte 'mousedown 1'
down=1
fi
done
xte 'mouseup 1'
xte "mousemove $X $Y"
Interestingly, you can abuse the scoring system (not manually, only with a script). Since the mouse jumps to the locations along the circle, you can just use very few steps and still get a great score because every step you make is very accurate – but the result looks funny:
🥴
Model 7-0-6 8-0-7-3 4-21, Robot sonic!
Pinellas County - 4 miles: 4.01 miles, 00:08:20 average pace, 00:33:27 duration
moved this to today since tomorrow we have to wake up early and drive to TN. half a pizza and two pints sloshing around still felt okay. the pepperoni definitely gave me some additional heartburn though!
#running