洪 民憙 (Hong Minhee) :nonbinary:'s avatar

洪 民憙 (Hong Minhee) :nonbinary:

@hongminhee@hollo.social

1,107 following1,897 followers

An intersectionalist, feminist, and socialist living in Seoul (UTC+09:00). @tokolovesme's spouse. Who's behind @fedify, @hollo, and @botkit. Write some free software in , , , & . They/them.

서울에 사는 交叉女性主義者이자 社會主義者. 金剛兔(@tokolovesme)의 配偶者. @fedify, @hollo, @botkit 메인테이너. , , , 等으로 自由 소프트웨어 만듦.

()

Pinned

@hongminhee@hollo.social

Hello! I'm Hong Minhee (洪 民憙), an open source software engineer in my late 30s, living in Seoul, Korea. I'm bisexual and non-binary (they/them), and an enthusiastic advocate of free/open source software and the fediverse.

I work full-time on @fedify, an ActivityPub server framework in TypeScript, funded by @sovtechfund. I'm also the creator of @hollo, a single-user ActivityPub microblog; @botkit, an ActivityPub bot framework; Hackers' Pub, a fediverse platform for software developers; and LogTape, a logging library for JavaScript and TypeScript.

I have a long interest in East Asian languages (CJK) and Unicode. I post mostly in English here, though occasionally in Japanese or in mixed-script Korean (國漢文混用體), a traditional writing style that interleaves Chinese characters with the native Korean alphabet. Wanting to write in that style was actually one of the reasons I joined the fediverse. Feel free to talk to me in English, Korean, Japanese, or even Literary Chinese!

en.wikipedia.org

Korean mixed script - Wikipedia

Pinned

はじめまして!ソウル在住の30代後半のオープンソースソフトウェアエンジニア、洪 民憙ホン・ミンヒと申します。バイセクシュアル(bisexual)・ノンバイナリー(non-binary)で、自由・オープンソースソフトウェア(F/OSS)とフェディバース(fediverse)の熱烈な支持者です。

STF(@sovtechfund)の支援を受け、TypeScript用ActivityPubサーバーフレームワーク「@fedify」の開発に専念しています。他にも、おひとり様向けのActivityPubマイクロブログ「@hollo」、ActivityPubボットフレームワーク「@botkit」、ソフトウェア開発者向けフェディバースプラットフォームHackers' Pub、JavaScript・TypeScript用ロギングライブラリLogTapeなどの制作者でもあります。

東アジア言語(いわゆるCJK)とUnicodeにも興味があります。このアカウントでは主に英語で投稿していますが、時々日本語や国漢文混用体(漢字ハングル混じり文)の韓国語でも書いています。実はこの文体で書きたくてフェディバースを始めた、という経緯もあります。日本語、英語、韓国語、漢文でも気軽に話しかけてください!

speakerdeck.com

国漢文混用体からHolloまで

本発表では、韓国語の「国漢文混用体」(漢字ハングル混じり文)を自分のフェディバース投稿に実装したいという小さな目標から始まった旅路を共有します。 この目標を達成するために、ActivityPubのJSON-LDの複雑さやHTTP Signatures、WebFingerなどの仕様を理解する必要性に…

Pinned

安寧(안녕)하세요! 저는 서울에 살고 있는 30() 後半(후반)의 오픈 소스 소프트웨어 엔지니어 洪民憙(홍민희)입니다. 兩性愛者(양성애자)(bisexual)이자 논바이너리(non-binary)이며, 自由(자유)·오픈 소스 소프트웨어(F/OSS)와 聯合宇宙(연합우주)(fediverse)의 熱烈(열렬)支持者(지지자)이기도 합니다.

STF(@sovtechfund)의 支援(지원)을 받아 TypeScript() ActivityPub 서버 프레임워크 @fedify 開發(개발)專業(전업)으로 ()하고 있습니다. 그 ()에도 싱글 유저() ActivityPub 마이크로블로그 @hollo, ActivityPub 봇 프레임워크 @botkit, 소프트웨어 開發者(개발자)를 위한 聯合宇宙(연합우주) 플랫폼 Hackers' Pub, JavaScript·TypeScript() 로깅 라이브러리 LogTape ()製作者(제작자)이기도 합니다.

()아시아 言語(언어)(이른바 CJK)와 Unicode에도 關心(관심)이 많습니다. 이 計定(계정)에서는 ()英語(영어)로 포스팅하지만, 때때로 日本語(일본어)國漢文混用體(국한문 혼용체) 韓國語(한국어)로도 씁니다. 聯合宇宙(연합우주)에 오게 된 動機(동기) () 하나가 바로 國漢文混用體(국한문 혼용체)로 글을 쓰고 싶었기 때문이기도 하고요. 韓國語(한국어), 英語(영어), 日本語(일본어), 아니면 漢文(한문)으로도 말을 걸어주세요!

logtape.org

LogTape

Unobtrusive logging library with zero dependencies—library-first design for Deno, Node.js, Bun, browsers, and edge functions

@samhenrigold@hachyderm.io

Did you know your MacBook has a sensor that knows the exact angle of the screen hinge?

It’s not exposed as a public API, but I figured out a way to read it and make it sound like an old wooden door.

Source code and a downloadable app to try it yourself: github.com/samhenrigold/LidAng

@hongminhee@hackers.pub

I have this bad habit. When something annoys me enough times, I end up building a library for it. This time, it was CLI validation code.

See, I spend a lot of time reading other people's code. Open source projects, work stuff, random GitHub repos I stumble upon at 2 AM. And I kept noticing this thing: every CLI tool has the same ugly validation code tucked away somewhere. You know the kind:

if (!opts.server && opts.port) {
  throw new Error("--port requires --server flag");
}

if (opts.server && !opts.port) {
  opts.port = 3000; // default port
}

// wait, what if they pass --port without a value?
// what if the port is out of range?
// what if...

It's not even that this code is hard to write. It's that it's everywhere. Every project. Every CLI tool. The same patterns, slightly different flavors. Options that depend on other options. Flags that can't be used together. Arguments that only make sense in certain modes.

And here's what really got me: we solved this problem years ago for other types of data. Just… not for CLIs.

The problem with validation

There's this blog post that completely changed how I think about parsing. It's called Parse, don't validate by Alexis King. The gist? Don't parse data into a loose type and then check if it's valid. Parse it directly into a type that can only be valid.

Think about it. When you get JSON from an API, you don't just parse it as any and then write a bunch of if-statements. You use something like Zod to parse it directly into the shape you want. Invalid data? The parser rejects it. Done.

But with CLIs? We parse arguments into some bag of properties and then spend the next 100 lines checking if that bag makes sense. It's backwards.

So yeah, I built Optique. Not because the world desperately needed another CLI parser (it didn't), but because I was tired of seeing—and writing—the same validation code everywhere.

Three patterns I was sick of validating

Dependent options

This one's everywhere. You have an option that only makes sense when another option is enabled.

The old way? Parse everything, then check:

const opts = parseArgs(process.argv);
if (!opts.server && opts.port) {
  throw new Error("--port requires --server");
}
if (opts.server && !opts.port) {
  opts.port = 3000;
}
// More validation probably lurking elsewhere...

With Optique, you just describe what you want:

const config = withDefault(
  object({
    server: flag("--server"),
    port: option("--port", integer()),
    workers: option("--workers", integer())
  }),
  { server: false }
);

Here's what TypeScript infers for config's type:

type Config = 
  | { readonly server: false }
  | { readonly server: true; readonly port: number; readonly workers: number }

The type system now understands that when server is false, port literally doesn't exist. Not undefined, not null—it's not there. Try to access it and TypeScript yells at you. No runtime validation needed.

Mutually exclusive options

Another classic. Pick one output format: JSON, YAML, or XML. But definitely not two.

I used to write this mess:

if ((opts.json ? 1 : 0) + (opts.yaml ? 1 : 0) + (opts.xml ? 1 : 0) > 1) {
  throw new Error('Choose only one output format');
}

(Don't judge me, you've written something similar.)

Now?

const format = or(
  map(option("--json"), () => "json" as const),
  map(option("--yaml"), () => "yaml" as const),
  map(option("--xml"), () => "xml" as const)
);

The or() combinator means exactly one succeeds. The result is just "json" | "yaml" | "xml". A single string. Not three booleans to juggle.

Environment-specific requirements

Production needs auth. Development needs debug flags. Docker needs different options than local. You know the drill.

Instead of a validation maze, you just describe each environment:

const envConfig = or(
  object({
    env: constant("prod"),
    auth: option("--auth", string()),      // Required in prod
    ssl: option("--ssl"),
    monitoring: option("--monitoring", url())
  }),
  object({
    env: constant("dev"),
    debug: optional(option("--debug")),    // Optional in dev
    verbose: option("--verbose")
  })
);

No auth in production? Parser fails immediately. Trying to access --auth in dev mode? TypeScript won't let you—the field doesn't exist on that type.

“But parser combinators though…”

I know, I know. “Parser combinators” sounds like something you'd need a CS degree to understand.

Here's the thing: I don't have a CS degree. Actually, I don't have any degree. But I've been using parser combinators for years because they're actually… not that hard? It's just that the name makes them sound way scarier than they are.

I'd been using them for other stuff—parsing config files, DSLs, whatever. But somehow it never clicked that you could use them for CLI parsing until I saw Haskell's optparse-applicative. That was a real “wait, of course” moment. Like, why are we doing this any other way?

Turns out it's stupidly simple. A parser is just a function. Combinators are just functions that take parsers and return new parsers. That's it.

// This is a parser
const port = option("--port", integer());

// This is also a parser (made from smaller parsers)
const server = object({
  port: port,
  host: option("--host", string())
});

// Still a parser (parsers all the way down)
const config = or(server, client);

No monads. No category theory. Just functions. Boring, beautiful functions.

TypeScript does the heavy lifting

Here's the thing that still feels like cheating: I don't write types for my CLI configs anymore. TypeScript just… figures it out.

const cli = or(
  command("deploy", object({
    action: constant("deploy"),
    environment: argument(string()),
    replicas: option("--replicas", integer())
  })),
  command("rollback", object({
    action: constant("rollback"),
    version: argument(string()),
    force: option("--force")
  }))
);

// TypeScript infers this type automatically:
type Cli = 
  | { 
      readonly action: "deploy"
      readonly environment: string
      readonly replicas: number
    }
  | { 
      readonly action: "rollback"
      readonly version: string
      readonly force: boolean
    }

TypeScript knows that if action is "deploy", then environment exists but version doesn't. It knows replicas is a number. It knows force is a boolean. I didn't tell it any of this.

This isn't just about nice autocomplete (though yeah, the autocomplete is great). It's about catching bugs before they happen. Forget to handle a new option somewhere? Code won't compile.

What actually changed for me

I've been dogfooding this for a few weeks. Some real talk:

I delete code now. Not refactor. Delete. That validation logic that used to be 30% of my CLI code? Gone. It feels weird every time.

Refactoring isn't scary. Want to know something that usually terrifies me? Changing how a CLI takes its arguments. Like going from --input file.txt to just file.txt as a positional argument. With traditional parsers, you're hunting down validation logic everywhere. With this? You change the parser definition, TypeScript immediately shows you every place that breaks, you fix them, done. What used to be an hour of “did I catch everything?” is now “fix the red squiggles and move on.”

My CLIs got fancier. When adding complex option relationships doesn't mean writing complex validation, you just… add them. Mutually exclusive groups? Sure. Context-dependent options? Why not. The parser handles it.

The reusability is real too:

const networkOptions = object({
  host: option("--host", string()),
  port: option("--port", integer())
});

// Reuse everywhere, compose differently
const devServer = merge(networkOptions, debugOptions);
const prodServer = merge(networkOptions, authOptions);
const testServer = merge(networkOptions, mockOptions);

But honestly? The biggest change is trust. If it compiles, the CLI logic works. Not “probably works” or “works unless someone passes weird arguments.” It just works.

Should you care?

If you're writing a 10-line script that takes one argument, you don't need this. process.argv[2] and call it a day.

But if you've ever:

  • Had validation logic get out of sync with your actual options
  • Discovered in production that certain option combinations explode
  • Spent an afternoon tracking down why --verbose breaks when used with --json
  • Written the same “option A requires option B” check for the fifth time

Then yeah, maybe you're tired of this stuff too.

Fair warning: Optique is young. I'm still figuring things out, the API might shift a bit. But the core idea—parse, don't validate—that's solid. And I haven't written validation code in months.

Still feels weird. Good weird.

Try it or don't

If this resonates:

I'm not saying Optique is the answer to all CLI problems. I'm just saying I was tired of writing the same validation code everywhere, so I built something that makes it unnecessary.

Take it or leave it. But that validation code you're about to write? You probably don't need it.

github.com

GitHub - dahlia/optique: Type-safe combinatorial CLI parser for TypeScript

Type-safe combinatorial CLI parser for TypeScript. Contribute to dahlia/optique development by creating an account on GitHub.

@FediFollows@social.growyourown.services

picks of the day:

➡️ @gnome - Official GNOME account in English

➡️ @gnome_br - GNOME in Portuguese

➡️ @haeckerfelix - GNOME developer, foundation member, author of "This Week in GNOME"

➡️ @Tuba - FOSS Fediverse app for GNOME, forked from Tootle

➡️ @WebKitGTK - GTK port of WebKit, official browser engine in GNOME

➡️ @GTK - FOSS cross-platform toolkit for creating GUIs

➡️ @EvolutionGnome - Free open source personal information manager software

🧵 1/2

@hongminhee@hackers.pub

참고로 Hackers' Pub은 패스키 인증을 지원하고 있습니다. ✌️

purengom.com

일본은 패스키로 진격하는데, 한국은 왜 제자리인가요? - Purengom's Monologue

금융부터 전자상거래까지 확산된 일본의 FIDO2 패스키 전략, 한국은 ‘간편 인증’에 머무른 채 방향성조차 흐릿합니다 보안 사고가 촉발한 일본의 급반전 2025년 상반기, 일본 증권 업계를 강타한 대규모 불법 로그인 및 부정 거래 사태는 단순한 해킹 사건을 넘어, 디지털 인증 체계에 대한 신뢰 자체를 뒤흔드는 사건이었습니다. 수천 건의 계좌 탈취와 수백억 엔…

@purengom@purengom.com
금융부터 전자상거래까지 확산된 일본의 FIDO2 패스키 전략, 한국은 ‘간편 인증’에 머무른 채 방향성조차 흐릿합니다 보안 사고가 촉발한 일본의 급반전 2025년 상반기, 일본 증권 업계를 강타한 대규모 불법 로그인 및 부정 거래 사태는 단순한 해킹 사건을 넘어, 디지털 인증 체계에 대한 신뢰 자체를 뒤흔드는 사건이었습니다. 수천 건의 계좌 탈취와 수백억 엔 규모의 […]
자물쇠와 지문 보안 아이콘

금융부터 전자상거래까지 확산된 일본의 FIDO2 패스키 전략, 한국은 ‘간편 인증’에 머무른 채 방향성조차 흐릿합니다


보안 사고가 촉발한 일본의 급반전

FIDO 패스키 로고 이미지

2025년 상반기, 일본 증권 업계를 강타한 대규모 불법 로그인 및 부정 거래 사태는 단순한 해킹 사건을 넘어, 디지털 인증 체계에 대한 신뢰 자체를 뒤흔드는 사건이었습니다. 수천 건의 계좌 탈취와 수백억 엔 규모의 시장 조작 시도가 이어지자, 일본 금융청과 증권업협회는 즉각적으로 움직였고, 주요 증권사들은 FIDO2 기반의 패스키 인증 시스템을 도입하겠다고 발표했습니다.

웰스나비, 모넥스, SBI 증권, PayPay 증권 등 주요 업체들이 빠르게 패스키 로그인 방식을 적용했고, 기존의 SMS나 OTP 인증보다 몇 배 빠르면서도 피싱에 강한 패스키의 특성은 사용성과 보안성 양면에서 효과를 입증했습니다.
실제로 메르카리, 야후재팬, au ID, 도코모 등 주요 전자상거래 및 플랫폼 기업에서도 패스키 도입이 확산되면서, 로그인 속도 향상, 성공률 증가, 고객센터 문의 감소 등 긍정적인 결과를 수치로 입증하고 있습니다. 특히 대형 중고거래 사이트인 메르카리는 월등히 높은 로그인 성공률, 4배 가까운 속도 감소 등을 보였습니다.

이는 정책, 업계, 기술이 유기적으로 맞물려 이루어진 결과라고 볼 수 있습니다. 일본 금융청은 패스키를 “피싱 저항 인증의 기본”으로 명시하며 업계 전반에 도입을 권고했고, FIDO Alliance Japan Working Group은 기술 보급과 사례 공유를 통해 확산을 이끌었습니다.


한국, 기술은 있는데 방향이 없습니다

반면 한국의 상황은 정반대입니다. 소비자 대상 FIDO2 패스키 도입을 완료한 금융기관은 현재까지 단 한 곳도 없습니다.

신한은행이나 우리은행 등 일부 은행에서 FIDO 기반 생체 인증을 도입한 사례는 존재하지만, 이는 FIDO2 패스키 방식과는 다르며, 주로 내부 인증이나 보조 로그인 수단으로 제한적으로 활용되고 있습니다. 고객용 인터넷 뱅킹이나 모바일 앱에서 비밀번호 없이 완전히 로그인할 수 있는 구조는 아직 갖춰지지 않았습니다.

IT 업계에서도 사정은 비슷합니다. 카카오, 네이버, SK텔레콤, KT 등 일부 대기업에서 패스키를 도입하긴 했지만, 적용 범위는 제한적이며, 사용자 기반 확산도 매우 미미한 수준입니다. 생태계 차원의 연동성이나 범용 인증 체계 구축도 이뤄지지 않고 있습니다.


제도는 마련됐지만 실행 의지가 부족합니다

이미 일본에서 효과를 본 패스키입니다만, 한국에서 이를 실행에 옮기려는 업계의 움직임은 매우 소극적입니다. 한국은 보안 사고에 대한 대응 속도는 빠른 편이지만, 인증 기술을 선제적으로 고도화하려는 전략적인 의지나 비전은 부족한 상황입니다. 공인인증서가 폐지된 이후에도 여전히 휴대폰 본인확인, 공동인증서, 일회용 비밀번호(OTP) 등 기존의 불편한 방식을 그대로 유지하고 있습니다.

정부나 금융당국 차원에서도 FIDO2 패스키를 채택하도록 유도하거나, 업계 협업을 통해 표준을 만들려는 노력이 거의 없습니다. ‘간편 인증’이 곧 사용자 경험 개선이라고 착각하는 단편적인 인식이 시장 전체를 가로막고 있는 현실입니다.


일본은 인증을 “보안”으로, 한국은 “편의”로만 보고 있습니다

결국 일본과 한국의 차이는 인증에 대한 관점의 차이에서 비롯된다고 볼 수 있습니다. 일본은 패스키를 단순한 편의 기능이 아니라, 신뢰 가능한 보안 인프라의 핵심 기술로 보고 전방위적으로 투자하고 있습니다. 반면 한국은 여전히 ‘편한 인증 수단’ 정도로만 이해하고 있으며, 보안에 미치는 영향에 대해서는 소극적인 태도를 보이고 있습니다.

패스키는 단순한 로그인 도구가 아니라, 사용자 식별과 신뢰 기반을 재정립하는 차세대 인증 기술입니다. 일본은 이를 과감히 수용했지만, 한국은 기술이 있음에도 불구하고 실행력과 추진 의지가 부족한 상황입니다.


언제까지 “안전하지만 불편한 인증”에 머물러야 할까요?

지금도 많은 금융기관은 ‘비밀번호 + OTP’ 혹은 ‘비밀번호 + 인증서’ 방식에 의존하고 있습니다. 하지만 점점 더 교묘해지는 피싱과 계정 탈취 수법을 고려할 때, 더 이상 구식 인증 방식에 의존할 수는 없습니다.

“패스워드 없는 세상”은 기술의 문제가 아니라 의지의 문제입니다. 일본은 보안 사고를 계기로 신속하게 움직였고, 지금은 눈에 보이는 성과를 만들어내고 있습니다. 한국은 언제까지 사용자에게 불편을 강요하면서, 보안을 지키고 있다고 착각하는 구조에 머무를 것인지 되묻고 싶습니다.

이제는 질문을 던져야 할 시점입니다.
“한국의 디지털 보안은 앞으로 10년 동안도 여전히 비밀번호에 기대야 할까요?”

FIDO 패스키 로고 이미지
ALT text

FIDO 패스키 로고 이미지

자물쇠와 지문 보안 아이콘
ALT text

자물쇠와 지문 보안 아이콘

@purengom@purengom.com
금융부터 전자상거래까지 확산된 일본의 FIDO2 패스키 전략, 한국은 ‘간편 인증’에 머무른 채 방향성조차 흐릿합니다 보안 사고가 촉발한 일본의 급반전 2025년 상반기, 일본 증권 업계를 강타한 대규모 불법 로그인 및 부정 거래 사태는 단순한 해킹 사건을 넘어, 디지털 인증 체계에 대한 신뢰 자체를 뒤흔드는 사건이었습니다. 수천 건의 계좌 탈취와 수백억 엔 규모의 […]
자물쇠와 지문 보안 아이콘

금융부터 전자상거래까지 확산된 일본의 FIDO2 패스키 전략, 한국은 ‘간편 인증’에 머무른 채 방향성조차 흐릿합니다


보안 사고가 촉발한 일본의 급반전

FIDO 패스키 로고 이미지

2025년 상반기, 일본 증권 업계를 강타한 대규모 불법 로그인 및 부정 거래 사태는 단순한 해킹 사건을 넘어, 디지털 인증 체계에 대한 신뢰 자체를 뒤흔드는 사건이었습니다. 수천 건의 계좌 탈취와 수백억 엔 규모의 시장 조작 시도가 이어지자, 일본 금융청과 증권업협회는 즉각적으로 움직였고, 주요 증권사들은 FIDO2 기반의 패스키 인증 시스템을 도입하겠다고 발표했습니다.

웰스나비, 모넥스, SBI 증권, PayPay 증권 등 주요 업체들이 빠르게 패스키 로그인 방식을 적용했고, 기존의 SMS나 OTP 인증보다 몇 배 빠르면서도 피싱에 강한 패스키의 특성은 사용성과 보안성 양면에서 효과를 입증했습니다.
실제로 메르카리, 야후재팬, au ID, 도코모 등 주요 전자상거래 및 플랫폼 기업에서도 패스키 도입이 확산되면서, 로그인 속도 향상, 성공률 증가, 고객센터 문의 감소 등 긍정적인 결과를 수치로 입증하고 있습니다. 특히 대형 중고거래 사이트인 메르카리는 월등히 높은 로그인 성공률, 4배 가까운 속도 감소 등을 보였습니다.

이는 정책, 업계, 기술이 유기적으로 맞물려 이루어진 결과라고 볼 수 있습니다. 일본 금융청은 패스키를 “피싱 저항 인증의 기본”으로 명시하며 업계 전반에 도입을 권고했고, FIDO Alliance Japan Working Group은 기술 보급과 사례 공유를 통해 확산을 이끌었습니다.


한국, 기술은 있는데 방향이 없습니다

반면 한국의 상황은 정반대입니다. 소비자 대상 FIDO2 패스키 도입을 완료한 금융기관은 현재까지 단 한 곳도 없습니다.

신한은행이나 우리은행 등 일부 은행에서 FIDO 기반 생체 인증을 도입한 사례는 존재하지만, 이는 FIDO2 패스키 방식과는 다르며, 주로 내부 인증이나 보조 로그인 수단으로 제한적으로 활용되고 있습니다. 고객용 인터넷 뱅킹이나 모바일 앱에서 비밀번호 없이 완전히 로그인할 수 있는 구조는 아직 갖춰지지 않았습니다.

IT 업계에서도 사정은 비슷합니다. 카카오, 네이버, SK텔레콤, KT 등 일부 대기업에서 패스키를 도입하긴 했지만, 적용 범위는 제한적이며, 사용자 기반 확산도 매우 미미한 수준입니다. 생태계 차원의 연동성이나 범용 인증 체계 구축도 이뤄지지 않고 있습니다.


제도는 마련됐지만 실행 의지가 부족합니다

이미 일본에서 효과를 본 패스키입니다만, 한국에서 이를 실행에 옮기려는 업계의 움직임은 매우 소극적입니다. 한국은 보안 사고에 대한 대응 속도는 빠른 편이지만, 인증 기술을 선제적으로 고도화하려는 전략적인 의지나 비전은 부족한 상황입니다. 공인인증서가 폐지된 이후에도 여전히 휴대폰 본인확인, 공동인증서, 일회용 비밀번호(OTP) 등 기존의 불편한 방식을 그대로 유지하고 있습니다.

정부나 금융당국 차원에서도 FIDO2 패스키를 채택하도록 유도하거나, 업계 협업을 통해 표준을 만들려는 노력이 거의 없습니다. ‘간편 인증’이 곧 사용자 경험 개선이라고 착각하는 단편적인 인식이 시장 전체를 가로막고 있는 현실입니다.


일본은 인증을 “보안”으로, 한국은 “편의”로만 보고 있습니다

결국 일본과 한국의 차이는 인증에 대한 관점의 차이에서 비롯된다고 볼 수 있습니다. 일본은 패스키를 단순한 편의 기능이 아니라, 신뢰 가능한 보안 인프라의 핵심 기술로 보고 전방위적으로 투자하고 있습니다. 반면 한국은 여전히 ‘편한 인증 수단’ 정도로만 이해하고 있으며, 보안에 미치는 영향에 대해서는 소극적인 태도를 보이고 있습니다.

패스키는 단순한 로그인 도구가 아니라, 사용자 식별과 신뢰 기반을 재정립하는 차세대 인증 기술입니다. 일본은 이를 과감히 수용했지만, 한국은 기술이 있음에도 불구하고 실행력과 추진 의지가 부족한 상황입니다.


언제까지 “안전하지만 불편한 인증”에 머물러야 할까요?

지금도 많은 금융기관은 ‘비밀번호 + OTP’ 혹은 ‘비밀번호 + 인증서’ 방식에 의존하고 있습니다. 하지만 점점 더 교묘해지는 피싱과 계정 탈취 수법을 고려할 때, 더 이상 구식 인증 방식에 의존할 수는 없습니다.

“패스워드 없는 세상”은 기술의 문제가 아니라 의지의 문제입니다. 일본은 보안 사고를 계기로 신속하게 움직였고, 지금은 눈에 보이는 성과를 만들어내고 있습니다. 한국은 언제까지 사용자에게 불편을 강요하면서, 보안을 지키고 있다고 착각하는 구조에 머무를 것인지 되묻고 싶습니다.

이제는 질문을 던져야 할 시점입니다.
“한국의 디지털 보안은 앞으로 10년 동안도 여전히 비밀번호에 기대야 할까요?”

FIDO 패스키 로고 이미지
ALT text

FIDO 패스키 로고 이미지

자물쇠와 지문 보안 아이콘
ALT text

자물쇠와 지문 보안 아이콘

@thaumiel999@mastodon.social

@activitypub.blog
워드프레스 액티비티펍 플러그인의 한국어 설명 페이지를 대대적으로 수정했습니다.
자동번역을 전체적으로 검토하고 맥락에 맞게 수정해 가독성과 번역 품질을 대폭 개선했습니다!

이제 한국어 사용자들도 페디버스와 워드프레스의 연결을 보다 더 쉽게 이해하고 활용할 수 있습니다. 앞으로도 최신 문서와 기능 번역을 계속 업데이트할 예정이니 많은 관심과 피드백 부탁드립니다.
@pfefferle @obenland



ko.wordpress.org/plugins/activ

ko.wordpress.org

액티비티펍(ActivityPub)

ActivityPub 프로토콜은 ActivityStreams 2.0 데이터 포맷을 기반으로 하는 탈중앙화된 소셜 네트워킹 프로토콜입니다.

@thisismissem@hachyderm.io

Recently there has been a lot of discourse about ActivityPub and AT Protocol which has been quite dividing and heated.

Yesterday at the Social Web CG meeting (the group that maintains the ActivityPub and related specifications), I proposed releasing a statement that counters the narrative that one of these protocols must win, when both protocols can co-exist and have a lot to learn from each other.

The statement has been co-signed by various members of both Social Web CG, SocialCG, and the AT Protocol community.

“We do not win by tearing each other down, which only emboldens and empowers those who do not want either protocol to succeed.”

“Arguing between us only emboldens those that seek to derail and destroy efforts to build an open social web.”

You can read the full statement here:
writings.thisismissem.social/s

This was originally in the swicg/general repository, and you can learn about that here:
github.com/swicg/general/blob/

github.com

general/statements/2025-09-05-activitypub-and-atproto-discourse.md at master · swicg/general

General issue tracker for the group. Contribute to swicg/general development by creating an account on GitHub.

@jiyu@hackers.pub

그래도 한 5%정도 사이트의 꼬라지를 갖춰간다... 이번달 안에 (테스트로) 공개할 수 있겠지...?

소셜 네트워크 사이트의 프로필과 팔로잉 목록
ALT text

소셜 네트워크 사이트의 프로필과 팔로잉 목록

@hongminhee@hollo.social

Optique 0.4.0 Released!

Big update for our type-safe combinatorial parser for :

  • Labeled merge groups: organize options logically
  • Rich docs: brief, description & footer support
  • @optique/temporal: new package for date/time parsing
  • showDefault: automatic default value display

The help text has never looked this good!

.js

hackers.pub

Optique 0.4.0: Better help, rich docs, and Temporal support

Optique 0.4.0 introduces enhancements to streamline CLI development in TypeScript. This release focuses on improving help text organization through labeled merge groups and a new `group()` combinator, making complex CLIs more user-friendly by organizing options under clear sections. Comprehensive documentation support is added via the `run()` function, allowing brief descriptions, detailed explanations, and footers without altering parser definitions. The update also includes Temporal API support with the `@optique/temporal` package, enabling type-safe parsing for dates, times, and time zones. Improved type inference for `merge()` and `tuple()` combinators enhances type safety, alongside minor breaking changes. These updates aim to make CLI construction more intuitive and maintainable, offering developers greater control over user experience and code structure.

@hongminhee@hackers.pub

We're excited to announce Optique 0.4.0, which brings significant improvements to help text organization, enhanced documentation capabilities, and introduces comprehensive Temporal API support.

Optique is a type-safe combinatorial CLI parser for TypeScript that makes building command-line interfaces intuitive and maintainable. This release focuses on making your CLI applications more user-friendly and maintainable.

Better help text organization

One of the most visible improvements in Optique 0.4.0 is the enhanced help text organization. You can now label and group your options more effectively, making complex CLIs much more approachable for users.

Labeled merge groups

The merge() combinator now accepts an optional label parameter, solving a common pain point where developers had to choose between clean code structure and organized help output:

// Before: unlabeled merged options appeared scattered
const config = merge(connectionOptions, performanceOptions);

// Now: group related options under a clear section
const config = merge(
  "Server Configuration",  // New label parameter
  connectionOptions,
  performanceOptions
);

This simple addition makes a huge difference in help text readability, especially for CLIs with many options spread across multiple reusable modules.

The resulting help output clearly organizes options under the Server Configuration section:

Demo app showcasing labeled merge groups
Usage: demo-merge.ts --host STRING --port INTEGER --timeout INTEGER --retries
       INTEGER

Server Configuration:
  --host STRING               Server hostname or IP address
  --port INTEGER              Port number for the connection
  --timeout INTEGER           Connection timeout in seconds
  --retries INTEGER           Number of retry attempts

The new group() combinator

For cases where merge() doesn't apply, the new group() combinator lets you wrap any parser with a documentation label:

// Group mutually exclusive options under a clear section
const outputFormat = group(
  "Output Format",
  or(
    map(flag("--json"), () => "json"),
    map(flag("--yaml"), () => "yaml"),
    map(flag("--xml"), () => "xml"),
  )
);

This is particularly useful for organizing mutually exclusive flags, multiple inputs, or any parser that doesn't natively support labeling. The resulting help text becomes much more scannable and user-friendly.

Here's how the grouped output format options appear in the help text:

Demo app showcasing group combinator
Usage: demo-group.ts --json
       demo-group.ts --yaml
       demo-group.ts --xml

Output Format:
  --json                      Output in JSON format
  --yaml                      Output in YAML format
  --xml                       Output in XML format

Rich documentation support

Optique 0.4.0 introduces comprehensive documentation fields that can be added directly through the run() function, eliminating the need to modify parser definitions for documentation purposes.

Brief descriptions, detailed explanations, and footers

Both @optique/core/facade and @optique/run now support brief, description, and footer options through the run() function:

import { run } from "@optique/run";
import { message } from "@optique/core/message";

const result = run(parser, {
  brief: message`A powerful data processing tool`,
  description: message`This tool provides comprehensive data processing capabilities with support for multiple formats and transformations. It can handle JSON, YAML, and CSV files with automatic format detection.`,
  footer: message`Examples:
  myapp process data.json --format yaml
  myapp validate config.toml --strict

For more information, visit https://example.com/docs`,
  help: "option"
});

These documentation fields appear in both help output and error messages (when configured), providing consistent context throughout your CLI's user experience.

The complete help output demonstrates the rich documentation features with brief description, detailed explanation, option descriptions, default values, and footer information:

A powerful data processing tool
Usage: demo-rich-docs.ts [--port INTEGER] [--format STRING] --verbose STRING

This tool provides comprehensive data processing capabilities with support for
multiple formats and transformations. It can handle JSON, YAML, and CSV files
with automatic format detection.

  --port INTEGER              Server port number [3000]
  --format STRING             Output format [json]
  --verbose STRING            Verbosity level

Examples:
  myapp process data.json --format yaml
  myapp validate config.toml --strict

For more information, visit https://example.com/docs

These documentation fields appear in both help output and error messages (when configured), providing consistent context throughout your CLI's user experience.

Display default values

A frequently requested feature is now available: showing default values directly in help text. Enable this with the new showDefault option when using withDefault():

const parser = object({
  port: withDefault(
    option("--port", integer(), { description: message`Server port number` }),
    3000,
  ),
  format: withDefault(
    option("--format", string(), { description: message`Output format` }),
    "json",
  ),
});

run(parser, { showDefault: true });

// Or with custom formatting:
run(parser, {
  showDefault: {
    prefix: " (default: ",
    suffix: ")"
  }  // Shows: --port (default: 3000)
});

Default values are automatically dimmed when colors are enabled, making them visually distinct while remaining readable.

The help output shows default values clearly marked next to each option:

Usage: demo-defaults.ts [--port INTEGER] [--format STRING]

  --port INTEGER              Server port number [3000]
  --format STRING             Output format [json]

Temporal API support

Optique 0.4.0 introduces a new package, @optique/temporal, providing comprehensive support for the modern Temporal API. This brings type-safe parsing for dates, times, durations, and time zones:

import { instant, duration, zonedDateTime } from "@optique/temporal";
import { option } from "@optique/core/parser";

const parser = object({
  // Parse ISO 8601 timestamps
  timestamp: option("--at", instant()),

  // Parse durations like "PT30M" or "P1DT2H"
  timeout: option("--timeout", duration()),

  // Parse zoned datetime with timezone info
  meeting: option("--meeting", zonedDateTime()),
});

The temporal parsers return native Temporal objects with full functionality:

const result = parse(timestampArg, ["2023-12-25T10:30:00Z"]);
if (result.success) {
  const instant = result.value;
  console.log(`UTC: ${instant.toString()}`);
  console.log(`Seoul: ${instant.toZonedDateTimeISO("Asia/Seoul")}`);
}

Install the new package with:

npm add @optique/temporal

Improved type inference

The merge() combinator now supports up to 10 parsers (previously 5), and the tuple() parser has improved type inference using TypeScript's const type parameter. These enhancements enable more complex CLI structures while maintaining perfect type safety.

Breaking changes

While we've maintained backward compatibility for most APIs, there are a few changes to be aware of:

  • The Parser.getDocFragments() method now uses DocState<TState> instead of direct state values (only affects custom parser implementations)
  • The merge() combinator now enforces stricter type constraints at compile time, rejecting non-object-producing parsers

Learn more

For a complete list of changes, bug fixes, and improvements, see the full changelog.

Check out the updated documentation:

Installation

Upgrade to Optique 0.4.0:

npm update @optique/core @optique/run
# or
deno add jsr:@optique/core@^0.4.0 jsr:@optique/run@^0.4.0

Add temporal support (optional):

npm add @optique/temporal
# or
deno add jsr:@optique/temporal

We hope these improvements make building CLI applications with Optique even more enjoyable. As always, we welcome your feedback and contributions on GitHub.

github.com

GitHub - dahlia/optique: Type-safe combinatorial CLI parser for TypeScript

Type-safe combinatorial CLI parser for TypeScript. Contribute to dahlia/optique development by creating an account on GitHub.

@hongminhee@hackers.pub

We're excited to announce Optique 0.4.0, which brings significant improvements to help text organization, enhanced documentation capabilities, and introduces comprehensive Temporal API support.

Optique is a type-safe combinatorial CLI parser for TypeScript that makes building command-line interfaces intuitive and maintainable. This release focuses on making your CLI applications more user-friendly and maintainable.

Better help text organization

One of the most visible improvements in Optique 0.4.0 is the enhanced help text organization. You can now label and group your options more effectively, making complex CLIs much more approachable for users.

Labeled merge groups

The merge() combinator now accepts an optional label parameter, solving a common pain point where developers had to choose between clean code structure and organized help output:

// Before: unlabeled merged options appeared scattered
const config = merge(connectionOptions, performanceOptions);

// Now: group related options under a clear section
const config = merge(
  "Server Configuration",  // New label parameter
  connectionOptions,
  performanceOptions
);

This simple addition makes a huge difference in help text readability, especially for CLIs with many options spread across multiple reusable modules.

The resulting help output clearly organizes options under the Server Configuration section:

Demo app showcasing labeled merge groups
Usage: demo-merge.ts --host STRING --port INTEGER --timeout INTEGER --retries
       INTEGER

Server Configuration:
  --host STRING               Server hostname or IP address
  --port INTEGER              Port number for the connection
  --timeout INTEGER           Connection timeout in seconds
  --retries INTEGER           Number of retry attempts

The new group() combinator

For cases where merge() doesn't apply, the new group() combinator lets you wrap any parser with a documentation label:

// Group mutually exclusive options under a clear section
const outputFormat = group(
  "Output Format",
  or(
    map(flag("--json"), () => "json"),
    map(flag("--yaml"), () => "yaml"),
    map(flag("--xml"), () => "xml"),
  )
);

This is particularly useful for organizing mutually exclusive flags, multiple inputs, or any parser that doesn't natively support labeling. The resulting help text becomes much more scannable and user-friendly.

Here's how the grouped output format options appear in the help text:

Demo app showcasing group combinator
Usage: demo-group.ts --json
       demo-group.ts --yaml
       demo-group.ts --xml

Output Format:
  --json                      Output in JSON format
  --yaml                      Output in YAML format
  --xml                       Output in XML format

Rich documentation support

Optique 0.4.0 introduces comprehensive documentation fields that can be added directly through the run() function, eliminating the need to modify parser definitions for documentation purposes.

Brief descriptions, detailed explanations, and footers

Both @optique/core/facade and @optique/run now support brief, description, and footer options through the run() function:

import { run } from "@optique/run";
import { message } from "@optique/core/message";

const result = run(parser, {
  brief: message`A powerful data processing tool`,
  description: message`This tool provides comprehensive data processing capabilities with support for multiple formats and transformations. It can handle JSON, YAML, and CSV files with automatic format detection.`,
  footer: message`Examples:
  myapp process data.json --format yaml
  myapp validate config.toml --strict

For more information, visit https://example.com/docs`,
  help: "option"
});

These documentation fields appear in both help output and error messages (when configured), providing consistent context throughout your CLI's user experience.

The complete help output demonstrates the rich documentation features with brief description, detailed explanation, option descriptions, default values, and footer information:

A powerful data processing tool
Usage: demo-rich-docs.ts [--port INTEGER] [--format STRING] --verbose STRING

This tool provides comprehensive data processing capabilities with support for
multiple formats and transformations. It can handle JSON, YAML, and CSV files
with automatic format detection.

  --port INTEGER              Server port number [3000]
  --format STRING             Output format [json]
  --verbose STRING            Verbosity level

Examples:
  myapp process data.json --format yaml
  myapp validate config.toml --strict

For more information, visit https://example.com/docs

These documentation fields appear in both help output and error messages (when configured), providing consistent context throughout your CLI's user experience.

Display default values

A frequently requested feature is now available: showing default values directly in help text. Enable this with the new showDefault option when using withDefault():

const parser = object({
  port: withDefault(
    option("--port", integer(), { description: message`Server port number` }),
    3000,
  ),
  format: withDefault(
    option("--format", string(), { description: message`Output format` }),
    "json",
  ),
});

run(parser, { showDefault: true });

// Or with custom formatting:
run(parser, {
  showDefault: {
    prefix: " (default: ",
    suffix: ")"
  }  // Shows: --port (default: 3000)
});

Default values are automatically dimmed when colors are enabled, making them visually distinct while remaining readable.

The help output shows default values clearly marked next to each option:

Usage: demo-defaults.ts [--port INTEGER] [--format STRING]

  --port INTEGER              Server port number [3000]
  --format STRING             Output format [json]

Temporal API support

Optique 0.4.0 introduces a new package, @optique/temporal, providing comprehensive support for the modern Temporal API. This brings type-safe parsing for dates, times, durations, and time zones:

import { instant, duration, zonedDateTime } from "@optique/temporal";
import { option } from "@optique/core/parser";

const parser = object({
  // Parse ISO 8601 timestamps
  timestamp: option("--at", instant()),

  // Parse durations like "PT30M" or "P1DT2H"
  timeout: option("--timeout", duration()),

  // Parse zoned datetime with timezone info
  meeting: option("--meeting", zonedDateTime()),
});

The temporal parsers return native Temporal objects with full functionality:

const result = parse(timestampArg, ["2023-12-25T10:30:00Z"]);
if (result.success) {
  const instant = result.value;
  console.log(`UTC: ${instant.toString()}`);
  console.log(`Seoul: ${instant.toZonedDateTimeISO("Asia/Seoul")}`);
}

Install the new package with:

npm add @optique/temporal

Improved type inference

The merge() combinator now supports up to 10 parsers (previously 5), and the tuple() parser has improved type inference using TypeScript's const type parameter. These enhancements enable more complex CLI structures while maintaining perfect type safety.

Breaking changes

While we've maintained backward compatibility for most APIs, there are a few changes to be aware of:

  • The Parser.getDocFragments() method now uses DocState<TState> instead of direct state values (only affects custom parser implementations)
  • The merge() combinator now enforces stricter type constraints at compile time, rejecting non-object-producing parsers

Learn more

For a complete list of changes, bug fixes, and improvements, see the full changelog.

Check out the updated documentation:

Installation

Upgrade to Optique 0.4.0:

npm update @optique/core @optique/run
# or
deno add jsr:@optique/core@^0.4.0 jsr:@optique/run@^0.4.0

Add temporal support (optional):

npm add @optique/temporal
# or
deno add jsr:@optique/temporal

We hope these improvements make building CLI applications with Optique even more enjoyable. As always, we welcome your feedback and contributions on GitHub.

github.com

GitHub - dahlia/optique: Type-safe combinatorial CLI parser for TypeScript

Type-safe combinatorial CLI parser for TypeScript. Contribute to dahlia/optique development by creating an account on GitHub.

@hongminhee@hollo.social

Optique 0.4.0 Released!

Big update for our type-safe combinatorial parser for :

  • Labeled merge groups: organize options logically
  • Rich docs: brief, description & footer support
  • @optique/temporal: new package for date/time parsing
  • showDefault: automatic default value display

The help text has never looked this good!

.js

hackers.pub

Optique 0.4.0: Better help, rich docs, and Temporal support

Optique 0.4.0 introduces enhancements to streamline CLI development in TypeScript. This release focuses on improving help text organization through labeled merge groups and a new `group()` combinator, making complex CLIs more user-friendly by organizing options under clear sections. Comprehensive documentation support is added via the `run()` function, allowing brief descriptions, detailed explanations, and footers without altering parser definitions. The update also includes Temporal API support with the `@optique/temporal` package, enabling type-safe parsing for dates, times, and time zones. Improved type inference for `merge()` and `tuple()` combinators enhances type safety, alongside minor breaking changes. These updates aim to make CLI construction more intuitive and maintainable, offering developers greater control over user experience and code structure.

@hongminhee@hackers.pub

We're excited to announce Optique 0.4.0, which brings significant improvements to help text organization, enhanced documentation capabilities, and introduces comprehensive Temporal API support.

Optique is a type-safe combinatorial CLI parser for TypeScript that makes building command-line interfaces intuitive and maintainable. This release focuses on making your CLI applications more user-friendly and maintainable.

Better help text organization

One of the most visible improvements in Optique 0.4.0 is the enhanced help text organization. You can now label and group your options more effectively, making complex CLIs much more approachable for users.

Labeled merge groups

The merge() combinator now accepts an optional label parameter, solving a common pain point where developers had to choose between clean code structure and organized help output:

// Before: unlabeled merged options appeared scattered
const config = merge(connectionOptions, performanceOptions);

// Now: group related options under a clear section
const config = merge(
  "Server Configuration",  // New label parameter
  connectionOptions,
  performanceOptions
);

This simple addition makes a huge difference in help text readability, especially for CLIs with many options spread across multiple reusable modules.

The resulting help output clearly organizes options under the Server Configuration section:

Demo app showcasing labeled merge groups
Usage: demo-merge.ts --host STRING --port INTEGER --timeout INTEGER --retries
       INTEGER

Server Configuration:
  --host STRING               Server hostname or IP address
  --port INTEGER              Port number for the connection
  --timeout INTEGER           Connection timeout in seconds
  --retries INTEGER           Number of retry attempts

The new group() combinator

For cases where merge() doesn't apply, the new group() combinator lets you wrap any parser with a documentation label:

// Group mutually exclusive options under a clear section
const outputFormat = group(
  "Output Format",
  or(
    map(flag("--json"), () => "json"),
    map(flag("--yaml"), () => "yaml"),
    map(flag("--xml"), () => "xml"),
  )
);

This is particularly useful for organizing mutually exclusive flags, multiple inputs, or any parser that doesn't natively support labeling. The resulting help text becomes much more scannable and user-friendly.

Here's how the grouped output format options appear in the help text:

Demo app showcasing group combinator
Usage: demo-group.ts --json
       demo-group.ts --yaml
       demo-group.ts --xml

Output Format:
  --json                      Output in JSON format
  --yaml                      Output in YAML format
  --xml                       Output in XML format

Rich documentation support

Optique 0.4.0 introduces comprehensive documentation fields that can be added directly through the run() function, eliminating the need to modify parser definitions for documentation purposes.

Brief descriptions, detailed explanations, and footers

Both @optique/core/facade and @optique/run now support brief, description, and footer options through the run() function:

import { run } from "@optique/run";
import { message } from "@optique/core/message";

const result = run(parser, {
  brief: message`A powerful data processing tool`,
  description: message`This tool provides comprehensive data processing capabilities with support for multiple formats and transformations. It can handle JSON, YAML, and CSV files with automatic format detection.`,
  footer: message`Examples:
  myapp process data.json --format yaml
  myapp validate config.toml --strict

For more information, visit https://example.com/docs`,
  help: "option"
});

These documentation fields appear in both help output and error messages (when configured), providing consistent context throughout your CLI's user experience.

The complete help output demonstrates the rich documentation features with brief description, detailed explanation, option descriptions, default values, and footer information:

A powerful data processing tool
Usage: demo-rich-docs.ts [--port INTEGER] [--format STRING] --verbose STRING

This tool provides comprehensive data processing capabilities with support for
multiple formats and transformations. It can handle JSON, YAML, and CSV files
with automatic format detection.

  --port INTEGER              Server port number [3000]
  --format STRING             Output format [json]
  --verbose STRING            Verbosity level

Examples:
  myapp process data.json --format yaml
  myapp validate config.toml --strict

For more information, visit https://example.com/docs

These documentation fields appear in both help output and error messages (when configured), providing consistent context throughout your CLI's user experience.

Display default values

A frequently requested feature is now available: showing default values directly in help text. Enable this with the new showDefault option when using withDefault():

const parser = object({
  port: withDefault(
    option("--port", integer(), { description: message`Server port number` }),
    3000,
  ),
  format: withDefault(
    option("--format", string(), { description: message`Output format` }),
    "json",
  ),
});

run(parser, { showDefault: true });

// Or with custom formatting:
run(parser, {
  showDefault: {
    prefix: " (default: ",
    suffix: ")"
  }  // Shows: --port (default: 3000)
});

Default values are automatically dimmed when colors are enabled, making them visually distinct while remaining readable.

The help output shows default values clearly marked next to each option:

Usage: demo-defaults.ts [--port INTEGER] [--format STRING]

  --port INTEGER              Server port number [3000]
  --format STRING             Output format [json]

Temporal API support

Optique 0.4.0 introduces a new package, @optique/temporal, providing comprehensive support for the modern Temporal API. This brings type-safe parsing for dates, times, durations, and time zones:

import { instant, duration, zonedDateTime } from "@optique/temporal";
import { option } from "@optique/core/parser";

const parser = object({
  // Parse ISO 8601 timestamps
  timestamp: option("--at", instant()),

  // Parse durations like "PT30M" or "P1DT2H"
  timeout: option("--timeout", duration()),

  // Parse zoned datetime with timezone info
  meeting: option("--meeting", zonedDateTime()),
});

The temporal parsers return native Temporal objects with full functionality:

const result = parse(timestampArg, ["2023-12-25T10:30:00Z"]);
if (result.success) {
  const instant = result.value;
  console.log(`UTC: ${instant.toString()}`);
  console.log(`Seoul: ${instant.toZonedDateTimeISO("Asia/Seoul")}`);
}

Install the new package with:

npm add @optique/temporal

Improved type inference

The merge() combinator now supports up to 10 parsers (previously 5), and the tuple() parser has improved type inference using TypeScript's const type parameter. These enhancements enable more complex CLI structures while maintaining perfect type safety.

Breaking changes

While we've maintained backward compatibility for most APIs, there are a few changes to be aware of:

  • The Parser.getDocFragments() method now uses DocState<TState> instead of direct state values (only affects custom parser implementations)
  • The merge() combinator now enforces stricter type constraints at compile time, rejecting non-object-producing parsers

Learn more

For a complete list of changes, bug fixes, and improvements, see the full changelog.

Check out the updated documentation:

Installation

Upgrade to Optique 0.4.0:

npm update @optique/core @optique/run
# or
deno add jsr:@optique/core@^0.4.0 jsr:@optique/run@^0.4.0

Add temporal support (optional):

npm add @optique/temporal
# or
deno add jsr:@optique/temporal

We hope these improvements make building CLI applications with Optique even more enjoyable. As always, we welcome your feedback and contributions on GitHub.

github.com

GitHub - dahlia/optique: Type-safe combinatorial CLI parser for TypeScript

Type-safe combinatorial CLI parser for TypeScript. Contribute to dahlia/optique development by creating an account on GitHub.

@thisismissem@hachyderm.io

Oh no y'all, I started writing something:

Screenshot of text for a heading titled “ActivityPub & AT Proto: More alike than different”
ALT text

Screenshot of text for a heading titled “ActivityPub & AT Proto: More alike than different”

@cocoa@hackers.pub · Reply to AmaseCocoa

nodeinfo path is auto-generated by starlette (fastapi)

/.well-known/nodeinfo page
ALT text

/.well-known/nodeinfo page

source code of apkit/server/routes/nodeinfo.py
ALT text

source code of apkit/server/routes/nodeinfo.py

@thisismissem@hachyderm.io

Are you a moderator on the Fediverse? A server operator?

If so, you should definitely fill out the IFTAS Moderator Needs Assessment:

(IFTAS doesn't require you to identify yourself, so you can remain anonymous if you wish)

about.iftas.org/moderator-need

about.iftas.org

Annual Needs Assessment

Our work is directed by the needs of the communities we serve, and we conduct an open survey of administrators, moderators, and community managers to ascertain their needs and priorities. Current A…

@hongminhee@hackers.pub

個人的には、一時的に開発目的で使うActivityPubサーバーにはngrokfedify tunnelなどを活用し、長期的に継続して開発するActivityPubサーバーであればTailscale FunnelCloudflare Tunnelを使用しています。

kalaclista.com

Post by にゃるら / カラクリスタ, @nyarla@kalaclista.com

Fediverseの開発環境、自分は何回か作り直しては崩してをしてるんだけど、現実どうするといいんだろうな 自分の環境の場合 tailscale + ローカルホスト用自前ドメインでローカルに閉じた https 環境を用意出来てるんだけど、この環境、コンテナだとホストのネットワークを使わないと tailscale の ip へ到達できないんだよね

@nyarla@kalaclista.com

Fediverseの開発環境、自分は何回か作り直しては崩してをしてるんだけど、現実どうするといいんだろうな

自分の環境の場合 tailscale + ローカルホスト用自前ドメインでローカルに閉じた https 環境を用意出来てるんだけど、この環境、コンテナだとホストのネットワークを使わないと tailscale の ip へ到達できないんだよね

今のところローカル専用の https ドメインはメインマシンに建てた caddy へ流してそこから各アプリケーションに分岐してるんよね

で let's encrypt の証明書は DNS チャレンジでワイルドカード証明書を取ってるんで取得には問題無いんだけど、ローカルのネットワークルーティングをどうするかが非常に悩ましい

@nyarla@kalaclista.com

Fediverseの開発環境、自分は何回か作り直しては崩してをしてるんだけど、現実どうするといいんだろうな

自分の環境の場合 tailscale + ローカルホスト用自前ドメインでローカルに閉じた https 環境を用意出来てるんだけど、この環境、コンテナだとホストのネットワークを使わないと tailscale の ip へ到達できないんだよね

@hongminhee@hackers.pub

割とモダンな言語」というわけではないが、Haskellもかなり昔からnewtypeというキーワードでサポートしていた。

misskey.niri.la

夏色スターまりん :meow_surprised: (@kisaragi_marine)

最近はScalaとかSwiftとかの「<i>割とモダンな言語</i>」が基底型に型消去するみたいなコンパイルテクでゼロオーバーヘッドのラッパー定義できる言語が増えてる気がしているので、別にRustだけではないと思う。 Rustが気軽に定義できるって話なら、そりゃそうだと思うけれど

最近はScalaとかSwiftとかの「割とモダンな言語」が基底型に型消去するみたいなコンパイルテクでゼロオーバーヘッドのラッパー定義できる言語が増えてる気がしているので、別にRustだけではないと思う。
Rustが気軽に定義できるって話なら、そりゃそうだと思うけれど

最近はScalaとかSwiftとかの「割とモダンな言語」が基底型に型消去するみたいなコンパイルテクでゼロオーバーヘッドのラッパー定義できる言語が増えてる気がしているので、別にRustだけではないと思う。
Rustが気軽に定義できるって話なら、そりゃそうだと思うけれど

@qnighy@qnmd.info

Value Objectが好きだけどオーバーヘッドが看過できない人向けの言語 → Rustすぎる

@kodingwarrior@hackers.pub

1시간 만에 완판! 걱정마세요 아직 대기 신청이 남아있습니다!

hackers.pub

✨ Hackers' Public 첫 오프라인 모임! ✨ Hackers' Pub 사용자들의 자발적인 모임, Hackers' Public이📅 9월 14일(일) 오후 3시 ~ 6시 열립니다. 이번 모임에서는 많은 분들이 흥미로워할 두 가지 발표가 준비되어 있습니다: 🎨 Code As a Canvas: 코드에서 예술작품이 되기까지 ✍️ 폰트는 어떻게 만들어지는가 – Neo둥근모 개발 후일담 또한 자유롭게 교류할 수 있는 네트워킹 시간도 마련되어 있으니 많은 관심 부탁드립니다 🙌 현재는 2차 모집 단계이며,👉 신청은 포스터의 QR코드 또는 http://public.hackers.pub에서 가능합니다. (두 경로 모두 동일한 이벤트 페이지로 연결됩니다) 2차 모집 기간은 9월 7일까지이며, 완판이 되었더라도 참가자 신청 대기하신 분 중에서 두분 정도 선정할 예정입니다!

✨ Hackers' Public 첫 오프라인 모임! ✨ Hackers' Pub 사용자들의 자발적인 모임, Hackers' Public이📅 9월 14일(일) 오후 3시 ~ 6시 열립니다. 이번 모임에서는 많은 분들이 흥미로워할 두 가지 발표가 준비되어 있습니다: 🎨 Code As a Canvas: 코드에서 예술작품이 되기까지 ✍️ 폰트는 어떻게 만들어지는가 – Neo둥근모 개발 후일담 또한 자유롭게 교류할 수 있는 네트워킹 시간도 마련되어 있으니 많은 관심 부탁드립니다 🙌 현재는 2차 모집 단계이며,👉 신청은 포스터의 QR코드 또는 http://public.hackers.pub에서 가능합니다. (두 경로 모두 동일한 이벤트 페이지로 연결됩니다) 2차 모집 기간은 9월 7일까지이며, 완판이 되었더라도 참가자 신청 대기하신 분 중에서 두분 정도 선정할 예정입니다!

@kodingwarrior@hackers.pub

✨ Hackers' Public 첫 오프라인 모임! ✨

Hackers' Pub 사용자들의 자발적인 모임, Hackers' Public이 📅 9월 14일(일) 오후 3시 ~ 6시 열립니다.

이번 모임에서는 많은 분들이 흥미로워할 두 가지 발표가 준비되어 있습니다:

  • 🎨 Code As a Canvas: 코드에서 예술작품이 되기까지
  • ✍️ 폰트는 어떻게 만들어지는가 – Neo둥근모 개발 후일담

또한 자유롭게 교류할 수 있는 네트워킹 시간도 마련되어 있으니 많은 관심 부탁드립니다 🙌

현재는 2차 모집 단계이며, 👉 신청은 포스터의 QR코드 또는 http://public.hackers.pub 에서 가능합니다. (두 경로 모두 동일한 이벤트 페이지로 연결됩니다)

2차 모집 기간은 9월 7일까지이며, 완판이 되었더라도 참가자 신청 대기하신 분 중에서 두분 정도 선정할 예정입니다!

Hackers Public 1회차 모임 포스터
ALT text

Hackers Public 1회차 모임 포스터