Hello, I'm an open source software engineer in my late 30s living in #Seoul, #Korea, and an avid advocate of #FLOSS and the #fediverse.
I'm the creator of @fedify, an #ActivityPub server framework in #TypeScript, @hollo, an ActivityPub-enabled microblogging software for single users, and @botkit, a simple ActivityPub bot framework.
Released Optique 0.8.0, a type-safe CLI parser for TypeScript.
This version adds conditional() for branching based on a discriminator option, passThrough() for forwarding unknown options to underlying tools, and a new @optique/logtape package for configuring LogTape via CLI.
We're excited to announce Optique 0.8.0! This release introduces powerful new features for building sophisticated CLI applications: the conditional() combinator for discriminated union patterns, the passThrough() parser for wrapper tools, and the new @optique/logtape package for seamless logging configuration.
Optique is a type-safe combinatorial CLI parser for TypeScript, providing a functional approach to building command-line interfaces with composable parsers and full type inference.
New conditional parsing with conditional()
Ever needed to enable different sets of options based on a discriminator value? The new conditional() combinator makes this pattern first-class. It creates discriminated unions where certain options only become valid when a specific discriminator value is selected.
Explicit discriminator option determines which branch is selected
Tuple result [discriminator, branchValue] for clear type narrowing
Optional default branch for when discriminator is not provided
Clear error messages indicating which options are required for each discriminator value
The conditional() parser provides a more structured alternative to or() for discriminated union patterns. Use it when you have an explicit discriminator option that determines which set of options is valid.
Building wrapper CLI tools that need to forward unrecognized options to an underlying tool? The new passThrough() parser enables legitimate wrapper/proxy patterns by capturing unknown options without validation errors.
The new @optique/logtape package provides seamless integration with LogTape, enabling you to configure logging through command-line arguments with various parsing strategies.
import { loggingOptions, createLoggingConfig } from "@optique/logtape";import { object } from "@optique/core/constructs";import { parse } from "@optique/core/parser";import { configure } from "@logtape/logtape";const parser = object({ logging: loggingOptions({ level: "verbosity" }),});const args = ["-vv", "--log-output=-"];const result = parse(parser, args);if (result.success) { const config = await createLoggingConfig(result.value.logging); await configure(config);}
The package offers multiple approaches to control log verbosity:
verbosity() parser: The classic -v/-vv/-vvv pattern where each flag increases verbosity (no flags → "warning", -v → "info", -vv → "debug", -vvv → "trace")
debug() parser: Simple --debug/-d flag that toggles between normal and debug levels
logLevel() value parser: Explicit --log-level=debug option for direct level selection
logOutput() parser: Log output destination with - for console or file path for file output
Fixed an issue where the integer() value parser rejected negative integers when using type: "number". The regex pattern has been updated from /^\d+$/ to /^-?\d+$/ to correctly handle values like -42. Note that type: "bigint" already accepted negative integers, so this change brings consistency between the two types.
Optique 0.8.0 continues our focus on making CLI development more expressive and type-safe. The conditional() combinator brings discriminated union patterns to the forefront, passThrough() enables new wrapper tool use cases, and the LogTape integration makes logging configuration a breeze.
As always, all new features maintain full backward compatibility—your existing parsers continue to work unchanged.
We're grateful to the community for feedback and suggestions. If you have ideas for future improvements or encounter any issues, please let us know through GitHub Issues. For more information about Optique and its features, visit the documentation or check out the full changelog.
We're excited to announce Optique 0.8.0! This release introduces powerful new features for building sophisticated CLI applications: the conditional() combinator for discriminated union patterns, the passThrough() parser for wrapper tools, and the new @optique/logtape package for seamless logging configuration.
Optique is a type-safe combinatorial CLI parser for TypeScript, providing a functional approach to building command-line interfaces with composable parsers and full type inference.
New conditional parsing with conditional()
Ever needed to enable different sets of options based on a discriminator value? The new conditional() combinator makes this pattern first-class. It creates discriminated unions where certain options only become valid when a specific discriminator value is selected.
Explicit discriminator option determines which branch is selected
Tuple result [discriminator, branchValue] for clear type narrowing
Optional default branch for when discriminator is not provided
Clear error messages indicating which options are required for each discriminator value
The conditional() parser provides a more structured alternative to or() for discriminated union patterns. Use it when you have an explicit discriminator option that determines which set of options is valid.
Building wrapper CLI tools that need to forward unrecognized options to an underlying tool? The new passThrough() parser enables legitimate wrapper/proxy patterns by capturing unknown options without validation errors.
The new @optique/logtape package provides seamless integration with LogTape, enabling you to configure logging through command-line arguments with various parsing strategies.
import { loggingOptions, createLoggingConfig } from "@optique/logtape";import { object } from "@optique/core/constructs";import { parse } from "@optique/core/parser";import { configure } from "@logtape/logtape";const parser = object({ logging: loggingOptions({ level: "verbosity" }),});const args = ["-vv", "--log-output=-"];const result = parse(parser, args);if (result.success) { const config = await createLoggingConfig(result.value.logging); await configure(config);}
The package offers multiple approaches to control log verbosity:
verbosity() parser: The classic -v/-vv/-vvv pattern where each flag increases verbosity (no flags → "warning", -v → "info", -vv → "debug", -vvv → "trace")
debug() parser: Simple --debug/-d flag that toggles between normal and debug levels
logLevel() value parser: Explicit --log-level=debug option for direct level selection
logOutput() parser: Log output destination with - for console or file path for file output
Fixed an issue where the integer() value parser rejected negative integers when using type: "number". The regex pattern has been updated from /^\d+$/ to /^-?\d+$/ to correctly handle values like -42. Note that type: "bigint" already accepted negative integers, so this change brings consistency between the two types.
Optique 0.8.0 continues our focus on making CLI development more expressive and type-safe. The conditional() combinator brings discriminated union patterns to the forefront, passThrough() enables new wrapper tool use cases, and the LogTape integration makes logging configuration a breeze.
As always, all new features maintain full backward compatibility—your existing parsers continue to work unchanged.
We're grateful to the community for feedback and suggestions. If you have ideas for future improvements or encounter any issues, please let us know through GitHub Issues. For more information about Optique and its features, visit the documentation or check out the full changelog.
As a multi language speaker I'd love to have some built-in language selector in the web browser for each website. This feature shouldn't be part of the website but rather the browser...
EU Commission's X account has been removed after the EU fined X for transparency failures at the tune $150,000,000. I hope someone at the EU is paying attention to X's behavior as well as our growing community here on the #fediverse .
Lately, I've been wanting to get a new, full aluminum keyboard with an HHKB layout. I'm holding back though, since I already have so many keyboards at home…
I think I have identified a fairly significant flaw in how the #Fediverse currently operates. Hear me out.
The Fediverse currently consists of all sorts of different systems - #Mastodon, #Friendica , #Pixelfed , #PeerTube, #BookWyrm , and so forth. And while they are all connected via the #ActivityPub protocol, they all have different functionalities and different ways of presenting themselves. Which is as it should be, because Diversity Is Our Strength(TM).
However, it is here that the ActivityPub-based interactivity hits its limits - for usually, you can either experience the relevant system as it was intended, or you can interact with it, but not both - _unless_ you have an account on the same system (though not necessarily on the same instance).
Let's say that you are a Mastodon user who looks at another person's BookWyrm page. You scroll through their books, posts, and comments. Then you see some comment you want to comment on yourself, but can you do so?
Not directly. You need to figure out the URL of their comment, and then copy and paste that comment into the search bar of your Mastodon instance. Then it will show up in the same format as a Mastodon post, and you can interact with it - boost it, like it, comment on it.
Sure, it works, but it's a whole lot of tedious effort.
Or you can search for the user account in Mastodon and scroll through all their posts and comments as if they were a Mastodon user - and thus, you will miss out on all the unique user interface features of BookWyrm.
So what is missing?
Well, Mastodon already has an "Open original page" feature when looking at someone's post. What we need is an "Open original page AND AUTHENTICATE" feature. This way, the target instance (whatever software they are using) could acknowledge the viewer as an external user who could nevertheless fully interact with the local user interface, including the ability to boost, like, and make comments.
This is something that should be theoretically possible to implement, right? #FediHelp
ALT text detailsA Mastodon menu that pops up when clicking on another user's post, showing the options:
"Expand this post
Open original page
Copy link to post"
I asked Nano Banana to draw an ad poster for a fictional McDonald's menu item called the “McBook,” and this is the image that was generated.
ALT text detailsA satirical advertisement poster showing a McDonald's meal where the burger has been replaced by an open laptop designed to look like a cheeseburger. The laptop lid is a sesame seed bun with a yellow Golden Arches logo, the keyboard area is a beef patty with lettuce and cheese, and green wires act as garnish. It rests on a tray with french fries and a drink in a McDonald's booth. Text on the poster reads “McBook. Served Hot.” and “I'm lovin' it. Powered by the M-Series Chip.”