洪 民憙 (Hong Minhee) :nonbinary:
banner
hongminhee.hollo.social.ap.brid.gy
洪 民憙 (Hong Minhee) :nonbinary:
@hongminhee.hollo.social.ap.brid.gy
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 […]

🌉 bridged from ⁂ https://hollo.social/@hongminhee, follow @ap.brid.gy to interact
A while back I mentioned the idea of “Fedify Studio”—a web-based toolkit for #activitypub debugging and development. I've been quietly working on shaping that idea into something more concrete.

Nothing to announce yet, but it's looking like this might become a team effort rather than a solo […]
November 28, 2025 at 1:43 PM
Reposted by 洪 民憙 (Hong Minhee) :nonbinary:
이게 금방 매진이 되려고 하네......
## Hackers Public @ Seoul 송년회 ---- 2025년의 마지막을 해커들과 함께해요.

Hackers' Public @ Seoul 송년 네트워킹 밋업은 발표보다 대화, 형식보다 연결을 중심으로 진행됩니다. 라이트닝 토크도 지원받습니다. 만들었던 것·배운 것·고민했던 이야기를 자유롭게 얘기해보도록 해요.

많은 관심 부탁드립니다~

* 🗓 12/21(일) 14:30~18:30
* 🎤 라이트닝 토크 5분 자유 참여
* 📌 1차 모집: 11.26~12.5 (회원 대상)
* 신청하기 👉 […]
Original post on hackers.pub
hackers.pub
November 28, 2025 at 10:31 AM
아무래도 來年(내년)에는 海外(해외) 컨퍼런스에 많이 參加(참가)하게 될 것 같다. 一旦(일단) 只今(지금) 생각나는 것만으로도 네 個(개)나 있음:

* FOSDEM 2026 (브뤼셀)
* FediCon 2026 (밴쿠버)
* COSCUP 2026 (臺北(타이베이))
* TSKaigi 2026 (東京(도쿄))

November 28, 2025 at 7:40 AM
Reposted by 洪 民憙 (Hong Minhee) :nonbinary:
RE: https://mastodon.social/@dansup/115497711169256588

Seems like bsky starts experimenting using mediabunny (https://mediabunny.dev/) to compress videos https://github.com/bluesky-social/social-app/commit/0a7209c623fbaf1e34e6143017c907f30a3c8bb4

Loops did the same too.

The bundle size is […]
Original post on mastodon.social
mastodon.social
November 27, 2025 at 2:59 PM
Reposted by 洪 民憙 (Hong Minhee) :nonbinary:
Small note: the previous figure I'd shared for community support accidentally omitted the €1730 from GitHub Sponsors because I don't see that in my normal Stripe dashboard

The NLNet amount also jumped up as I was able to submit another request for payment, which has since been approved.

I've […]
Original post on hachyderm.io
hachyderm.io
November 27, 2025 at 3:41 PM
Reposted by 洪 民憙 (Hong Minhee) :nonbinary:
Hey #fediverse people, I've an ask: If you appreciate all that I do for the fediverse and open social web, and you'd like to see me continue to do that work, please support my work financially.

Right now I'm having to look for work outside of the Fediverse because I simply cannot make ends meet […]
Original post on hachyderm.io
hachyderm.io
November 27, 2025 at 3:12 PM
Reposted by 洪 民憙 (Hong Minhee) :nonbinary:
## Hackers Public @ Seoul 송년회 ---- 2025년의 마지막을 해커들과 함께해요.

Hackers' Public @ Seoul 송년 네트워킹 밋업은 발표보다 대화, 형식보다 연결을 중심으로 진행됩니다. 라이트닝 토크도 지원받습니다. 만들었던 것·배운 것·고민했던 이야기를 자유롭게 얘기해보도록 해요.

많은 관심 부탁드립니다~

* 🗓 12/21(일) 14:30~18:30
* 🎤 라이트닝 토크 5분 자유 참여
* 📌 1차 모집: 11.26~12.5 (회원 대상)
* 신청하기 👉 […]
Original post on hackers.pub
hackers.pub
November 26, 2025 at 6:21 AM
It looks like a new minor release of #hollo (v0.7.0) will be out soon, the first in several months.
November 27, 2025 at 3:47 AM
Reposted by 洪 民憙 (Hong Minhee) :nonbinary:
GitHub Action Rerunner
# GitHub Action Rerunner 사용해보기 실패한 GitHub Actions를 팀원들이 직접 재실행할 수 있도록 권한을 위임하는 웹 애플리케이션입니다. ## 🎯 왜 만들었나요? GitHub Actions가 실패했을 때, 재실행하려면 해당 레포지토리에 대한 Write 권한이 필요합니다. 하지만 보안상의 이유로 모든 팀원에게 Write 권한을 주기는 어렵습니다. **GitHub Action Rerunner** 는 이 문제를 해결합니다. 레포지토리 소유자가 토큰을 등록하면, 팀원들은 **자신에게 할당된 PR** 의 실패한 Action만 재실행해 레포지토리에 대한 직접적인 권한 없이도 CI/CD를 다시 돌릴 수 있습니다! ## ✨ 주요 기능 ### 레포지토리 소유자 (Owner) * 📦 개인 및 조직 레포지토리 등록 * 🔑 GitHub Personal Access Token 등록 (암호화 저장) * 🔗 공유 가능한 고유 링크 생성 * 👀 모든 실패한 PR 확인 및 재실행 * ⚙️ 레포지토리 설정 관리 ### 팀원 (Assignee) * 📋 자신에게 할당된 PR 목록 확인 * 🔄 실패한 GitHub Action 원클릭 재실행 * 📊 워크플로우 상태 실시간 확인 ### 계정 관리 * 🔐 GitHub OAuth 로그인 * 👥 여러 GitHub 계정 연동 지원 * 🔀 계정 간 쉬운 전환 ## 🛠 기술 스택 * **Frontend** : Next.js 16 (App Router), React 19, Tailwind CSS 4 * **Backend** : Next.js API Routes * **Authentication** : NextAuth.js v5 (GitHub OAuth) * **Database** : PostgreSQL + Prisma ORM * **GitHub API** : Octokit ## 🚀 직접 배포하기 현재 프로젝트는 이미 배포되어 있으나, 민감한 토큰을 다루기 때문에 직접 배포하시고 싶다면 아래 가이드를 참고하세요. ### 1. 환경 변수 설정 `.env` 파일을 생성하고 다음 값을 설정하세요: # DB (PostgreSQL) DATABASE_URL="postgresql://..." DIRECT_URL="postgresql://..." # NextAuth.js AUTH_SECRET="use `npx auth secret`" AUTH_GITHUB_ID="your-github-oauth-app-id" AUTH_GITHUB_SECRET="your-github-oauth-app-secret" # Token Encryption (32자) ENCRYPTION_KEY="your-32-character-encryption-key" ### 2. GitHub OAuth App 생성 1. GitHub Developer Settings에서 OAuth App 생성 2. **Authorization callback URL** : `http://localhost:3000/api/auth/callback/github` 3. Client ID와 Client Secret을 환경 변수에 설정 ### 3. 개발 서버 실행 # 의존성 설치 pnpm install # Prisma 클라이언트 생성 npx prisma generate # 데이터베이스 마이그레이션 npx prisma migrate dev # 개발 서버 실행 pnpm dev http://localhost:3000에서 확인하세요. ## 📖 사용 방법 ### 레포지토리 등록 (소유자) 1. GitHub으로 로그인 2. 대시보드 → 레포지토리 등록 3. 등록할 레포지토리 선택 4. 설정 페이지에서 Personal Access Token 등록 * Token에 `repo` 및 `actions` 권한 필요 5. 생성된 링크를 팀원들과 공유 ### Action 재실행 (팀원) 1. 공유받은 링크로 접속 2. GitHub으로 로그인 3. 자신에게 할당된 PR 목록 확인 4. 실패한 워크플로우 옆 "Rerun" 버튼 클릭 ## 🔒 보안 * Personal Access Token은 AES-256-GCM으로 암호화되어 저장됩니다. * 팀원은 자신에게 할당된 PR의 Action만 재실행할 수 있습니다. * 모든 API 요청은 세션 기반 인증을 거칩니다.
hackers.pub
November 26, 2025 at 7:58 AM
Reposted by 洪 民憙 (Hong Minhee) :nonbinary:
Optique 0.7.0 released!

* “Did you mean?” typo suggestions
* Zod & Valibot schema validation
* Duplicate option detection
* Context-aware error messages

Type-safe CLI parsing for TypeScript just got friendlier.

https://hackers.pub/@hongminhee/2025/optique-070
Optique 0.7.0: Smarter error messages and validation library integrations
We're thrilled to announce Optique 0.7.0, a release focused on developer experience improvements and expanding Optique's ecosystem with validation library integrations. Optique is a type-safe, combinatorial CLI argument parser for TypeScript. Unlike traditional CLI libraries that rely on configuration objects, Optique lets you compose parsers from small, reusable functions—bringing the same functional composition patterns that make Zod powerful to CLI development. If you're new to Optique, check out _Why Optique?_ to learn how this approach unlocks possibilities that configuration-based libraries simply can't match. This release introduces automatic “Did you mean?” suggestions for typos, seamless integration with Zod and Valibot validation libraries, duplicate option name detection for catching configuration bugs early, and context-aware error messages that help users understand exactly what went wrong. ## “Did you mean?”: Automatic typo suggestions We've all been there: you type `--verbos` instead of `--verbose`, and the CLI responds with an unhelpful “unknown option” error. Optique 0.7.0 changes this by automatically suggesting similar options when users make typos: const parser = object({ verbose: option("-v", "--verbose"), version: option("--version"), }); // User types: --verbos (typo) const result = parse(parser, ["--verbos"]); // Error: Unexpected option or argument: --verbos. // // Did you mean one of these? // --verbose // --version The suggestion system uses Levenshtein distance to find similar names, suggesting up to 3 alternatives when the edit distance is within a reasonable threshold. Suggestions work automatically for both option names and subcommand names across all parser types—`option()`, `flag()`, `command()`, `object()`, `or()`, and `longestMatch()`. See the automatic suggestions documentation for more details. ### Customizing suggestions You can customize how suggestions are formatted or disable them entirely through the `errors` option: // Custom suggestion format for option/flag parsers const portOption = option("--port", integer(), { errors: { noMatch: (invalidOption, suggestions) => suggestions.length > 0 ? message`Unknown option ${invalidOption}. Try: ${values(suggestions)}` : message`Unknown option ${invalidOption}.` } }); // Custom suggestion format for combinators const config = object({ host: option("--host", string()), port: option("--port", integer()) }, { errors: { suggestions: (suggestions) => suggestions.length > 0 ? message`Available options: ${values(suggestions)}` : [] } }); ## Zod and Valibot integrations Two new packages join the Optique family, bringing powerful validation capabilities from the TypeScript ecosystem to your CLI parsers. ### @optique/zod The new `@optique/zod` package lets you use Zod schemas directly as value parsers: import { option, object } from "@optique/core"; import { zod } from "@optique/zod"; import { z } from "zod"; const parser = object({ email: option("--email", zod(z.string().email())), port: option("--port", zod(z.coerce.number().int().min(1).max(65535))), format: option("--format", zod(z.enum(["json", "yaml", "xml"]))), }); The package supports both Zod v3.25.0+ and v4.0.0+, with automatic error formatting that integrates seamlessly with Optique's message system. See the Zod integration guide for complete usage examples. ### @optique/valibot For those who prefer a lighter bundle, `@optique/valibot` integrates with Valibot—a validation library with a significantly smaller footprint (~10KB vs Zod's ~52KB): import { option, object } from "@optique/core"; import { valibot } from "@optique/valibot"; import * as v from "valibot"; const parser = object({ email: option("--email", valibot(v.pipe(v.string(), v.email()))), port: option("--port", valibot(v.pipe( v.string(), v.transform(Number), v.integer(), v.minValue(1), v.maxValue(65535) ))), }); Both packages support custom error messages through their respective error handler options (`zodError` and `valibotError`), giving you full control over how validation failures are presented to users. See the Valibot integration guide for complete usage examples. ## Duplicate option name detection A common source of bugs in CLI applications is accidentally using the same option name in multiple places. Previously, this would silently cause ambiguous parsing where the first matching parser consumed the option. Optique 0.7.0 now validates option names at parse time and fails with a clear error message when duplicates are detected: const parser = object({ input: option("-i", "--input", string()), interactive: option("-i", "--interactive"), // Oops! -i is already used }); // Error: Duplicate option name -i found in fields: input, interactive. // Each option name must be unique within a parser combinator. This validation applies to `object()`, `tuple()`, `merge()`, and `group()` combinators. The `or()` combinator continues to allow duplicate option names since its branches are mutually exclusive. See the duplicate detection documentation for more details. If you have a legitimate use case for duplicate option names, you can opt out with `allowDuplicates: true`: const parser = object({ input: option("-i", "--input", string()), interactive: option("-i", "--interactive"), }, { allowDuplicates: true }); ## Context-aware error messages Error messages from combinators are now smarter about what they report. Instead of generic "No matching option or command found" messages, Optique now analyzes what the parser expects and provides specific feedback: // When only arguments are expected const parser1 = or(argument(string()), argument(integer())); // Error: Missing required argument. // When only commands are expected const parser2 = or(command("add", addParser), command("remove", removeParser)); // Error: No matching command found. // When both options and arguments are expected const parser3 = object({ port: option("--port", integer()), file: argument(string()), }); // Error: No matching option or argument found. ### Dynamic error messages with `NoMatchContext` For applications that need internationalization or context-specific messaging, the `errors.noMatch` option now accepts a function that receives a `NoMatchContext` object: const parser = or( command("add", addParser), command("remove", removeParser), { errors: { noMatch: ({ hasOptions, hasCommands, hasArguments }) => { if (hasCommands && !hasOptions && !hasArguments) { return message`일치하는 명령을 찾을 수 없습니다.`; // Korean } return message`잘못된 입력입니다.`; } } } ); ## Shell completion naming conventions The `run()` function now supports configuring whether shell completions use singular or plural naming conventions: run(parser, { completion: { name: "plural", // Uses "completions" and "--completions" } }); // Or for singular only run(parser, { completion: { name: "singular", // Uses "completion" and "--completion" } }); The default `"both"` accepts either form, maintaining backward compatibility while letting you enforce a consistent style in your CLI. ## Additional improvements * **Line break handling** : `formatMessage()` now distinguishes between soft breaks (single `\n`, converted to spaces) and hard breaks (double `\n\n`, creating paragraph separations), improving multi-line error message formatting. * **New utility functions** : Added `extractOptionNames()` and `extractArgumentMetavars()` to the `@optique/core/usage` module for programmatic access to parser metadata. ## Installation deno add --jsr @optique/core @optique/run npm add @optique/core @optique/run pnpm add @optique/core @optique/run yarn add @optique/core @optique/run bun add @optique/core @optique/run For validation library integrations: # Zod integration deno add jsr:@optique/zod # Deno npm add @optique/zod # npm/pnpm/yarn/bun # Valibot integration deno add jsr:@optique/valibot # Deno npm add @optique/valibot # npm/pnpm/yarn/bun ## Looking forward This release represents our commitment to making CLI development in TypeScript as smooth as possible. The “Did you mean?” suggestions and validation library integrations were among the most requested features, and we're excited to see how they improve your CLI applications. For detailed documentation and examples, visit the Optique documentation. We welcome your feedback and contributions on GitHub!
hackers.pub
November 25, 2025 at 3:16 PM
Optique 0.7.0 released!

* “Did you mean?” typo suggestions
* Zod & Valibot schema validation
* Duplicate option detection
* Context-aware error messages

Type-safe CLI parsing for TypeScript just got friendlier.

https://hackers.pub/@hongminhee/2025/optique-070
Optique 0.7.0: Smarter error messages and validation library integrations
We're thrilled to announce Optique 0.7.0, a release focused on developer experience improvements and expanding Optique's ecosystem with validation library integrations. Optique is a type-safe, combinatorial CLI argument parser for TypeScript. Unlike traditional CLI libraries that rely on configuration objects, Optique lets you compose parsers from small, reusable functions—bringing the same functional composition patterns that make Zod powerful to CLI development. If you're new to Optique, check out _Why Optique?_ to learn how this approach unlocks possibilities that configuration-based libraries simply can't match. This release introduces automatic “Did you mean?” suggestions for typos, seamless integration with Zod and Valibot validation libraries, duplicate option name detection for catching configuration bugs early, and context-aware error messages that help users understand exactly what went wrong. ## “Did you mean?”: Automatic typo suggestions We've all been there: you type `--verbos` instead of `--verbose`, and the CLI responds with an unhelpful “unknown option” error. Optique 0.7.0 changes this by automatically suggesting similar options when users make typos: const parser = object({ verbose: option("-v", "--verbose"), version: option("--version"), }); // User types: --verbos (typo) const result = parse(parser, ["--verbos"]); // Error: Unexpected option or argument: --verbos. // // Did you mean one of these? // --verbose // --version The suggestion system uses Levenshtein distance to find similar names, suggesting up to 3 alternatives when the edit distance is within a reasonable threshold. Suggestions work automatically for both option names and subcommand names across all parser types—`option()`, `flag()`, `command()`, `object()`, `or()`, and `longestMatch()`. See the automatic suggestions documentation for more details. ### Customizing suggestions You can customize how suggestions are formatted or disable them entirely through the `errors` option: // Custom suggestion format for option/flag parsers const portOption = option("--port", integer(), { errors: { noMatch: (invalidOption, suggestions) => suggestions.length > 0 ? message`Unknown option ${invalidOption}. Try: ${values(suggestions)}` : message`Unknown option ${invalidOption}.` } }); // Custom suggestion format for combinators const config = object({ host: option("--host", string()), port: option("--port", integer()) }, { errors: { suggestions: (suggestions) => suggestions.length > 0 ? message`Available options: ${values(suggestions)}` : [] } }); ## Zod and Valibot integrations Two new packages join the Optique family, bringing powerful validation capabilities from the TypeScript ecosystem to your CLI parsers. ### @optique/zod The new `@optique/zod` package lets you use Zod schemas directly as value parsers: import { option, object } from "@optique/core"; import { zod } from "@optique/zod"; import { z } from "zod"; const parser = object({ email: option("--email", zod(z.string().email())), port: option("--port", zod(z.coerce.number().int().min(1).max(65535))), format: option("--format", zod(z.enum(["json", "yaml", "xml"]))), }); The package supports both Zod v3.25.0+ and v4.0.0+, with automatic error formatting that integrates seamlessly with Optique's message system. See the Zod integration guide for complete usage examples. ### @optique/valibot For those who prefer a lighter bundle, `@optique/valibot` integrates with Valibot—a validation library with a significantly smaller footprint (~10KB vs Zod's ~52KB): import { option, object } from "@optique/core"; import { valibot } from "@optique/valibot"; import * as v from "valibot"; const parser = object({ email: option("--email", valibot(v.pipe(v.string(), v.email()))), port: option("--port", valibot(v.pipe( v.string(), v.transform(Number), v.integer(), v.minValue(1), v.maxValue(65535) ))), }); Both packages support custom error messages through their respective error handler options (`zodError` and `valibotError`), giving you full control over how validation failures are presented to users. See the Valibot integration guide for complete usage examples. ## Duplicate option name detection A common source of bugs in CLI applications is accidentally using the same option name in multiple places. Previously, this would silently cause ambiguous parsing where the first matching parser consumed the option. Optique 0.7.0 now validates option names at parse time and fails with a clear error message when duplicates are detected: const parser = object({ input: option("-i", "--input", string()), interactive: option("-i", "--interactive"), // Oops! -i is already used }); // Error: Duplicate option name -i found in fields: input, interactive. // Each option name must be unique within a parser combinator. This validation applies to `object()`, `tuple()`, `merge()`, and `group()` combinators. The `or()` combinator continues to allow duplicate option names since its branches are mutually exclusive. See the duplicate detection documentation for more details. If you have a legitimate use case for duplicate option names, you can opt out with `allowDuplicates: true`: const parser = object({ input: option("-i", "--input", string()), interactive: option("-i", "--interactive"), }, { allowDuplicates: true }); ## Context-aware error messages Error messages from combinators are now smarter about what they report. Instead of generic "No matching option or command found" messages, Optique now analyzes what the parser expects and provides specific feedback: // When only arguments are expected const parser1 = or(argument(string()), argument(integer())); // Error: Missing required argument. // When only commands are expected const parser2 = or(command("add", addParser), command("remove", removeParser)); // Error: No matching command found. // When both options and arguments are expected const parser3 = object({ port: option("--port", integer()), file: argument(string()), }); // Error: No matching option or argument found. ### Dynamic error messages with `NoMatchContext` For applications that need internationalization or context-specific messaging, the `errors.noMatch` option now accepts a function that receives a `NoMatchContext` object: const parser = or( command("add", addParser), command("remove", removeParser), { errors: { noMatch: ({ hasOptions, hasCommands, hasArguments }) => { if (hasCommands && !hasOptions && !hasArguments) { return message`일치하는 명령을 찾을 수 없습니다.`; // Korean } return message`잘못된 입력입니다.`; } } } ); ## Shell completion naming conventions The `run()` function now supports configuring whether shell completions use singular or plural naming conventions: run(parser, { completion: { name: "plural", // Uses "completions" and "--completions" } }); // Or for singular only run(parser, { completion: { name: "singular", // Uses "completion" and "--completion" } }); The default `"both"` accepts either form, maintaining backward compatibility while letting you enforce a consistent style in your CLI. ## Additional improvements * **Line break handling** : `formatMessage()` now distinguishes between soft breaks (single `\n`, converted to spaces) and hard breaks (double `\n\n`, creating paragraph separations), improving multi-line error message formatting. * **New utility functions** : Added `extractOptionNames()` and `extractArgumentMetavars()` to the `@optique/core/usage` module for programmatic access to parser metadata. ## Installation deno add --jsr @optique/core @optique/run npm add @optique/core @optique/run pnpm add @optique/core @optique/run yarn add @optique/core @optique/run bun add @optique/core @optique/run For validation library integrations: # Zod integration deno add jsr:@optique/zod # Deno npm add @optique/zod # npm/pnpm/yarn/bun # Valibot integration deno add jsr:@optique/valibot # Deno npm add @optique/valibot # npm/pnpm/yarn/bun ## Looking forward This release represents our commitment to making CLI development in TypeScript as smooth as possible. The “Did you mean?” suggestions and validation library integrations were among the most requested features, and we're excited to see how they improve your CLI applications. For detailed documentation and examples, visit the Optique documentation. We welcome your feedback and contributions on GitHub!
hackers.pub
November 25, 2025 at 3:16 PM
Reposted by 洪 民憙 (Hong Minhee) :nonbinary:
Optique 0.7.0: Smarter error messages and validation library integrations
We're thrilled to announce Optique 0.7.0, a release focused on developer experience improvements and expanding Optique's ecosystem with validation library integrations. Optique is a type-safe, combinatorial CLI argument parser for TypeScript. Unlike traditional CLI libraries that rely on configuration objects, Optique lets you compose parsers from small, reusable functions—bringing the same functional composition patterns that make Zod powerful to CLI development. If you're new to Optique, check out _Why Optique?_ to learn how this approach unlocks possibilities that configuration-based libraries simply can't match. This release introduces automatic “Did you mean?” suggestions for typos, seamless integration with Zod and Valibot validation libraries, duplicate option name detection for catching configuration bugs early, and context-aware error messages that help users understand exactly what went wrong. ## “Did you mean?”: Automatic typo suggestions We've all been there: you type `--verbos` instead of `--verbose`, and the CLI responds with an unhelpful “unknown option” error. Optique 0.7.0 changes this by automatically suggesting similar options when users make typos: const parser = object({ verbose: option("-v", "--verbose"), version: option("--version"), }); // User types: --verbos (typo) const result = parse(parser, ["--verbos"]); // Error: Unexpected option or argument: --verbos. // // Did you mean one of these? // --verbose // --version The suggestion system uses Levenshtein distance to find similar names, suggesting up to 3 alternatives when the edit distance is within a reasonable threshold. Suggestions work automatically for both option names and subcommand names across all parser types—`option()`, `flag()`, `command()`, `object()`, `or()`, and `longestMatch()`. See the automatic suggestions documentation for more details. ### Customizing suggestions You can customize how suggestions are formatted or disable them entirely through the `errors` option: // Custom suggestion format for option/flag parsers const portOption = option("--port", integer(), { errors: { noMatch: (invalidOption, suggestions) => suggestions.length > 0 ? message`Unknown option ${invalidOption}. Try: ${values(suggestions)}` : message`Unknown option ${invalidOption}.` } }); // Custom suggestion format for combinators const config = object({ host: option("--host", string()), port: option("--port", integer()) }, { errors: { suggestions: (suggestions) => suggestions.length > 0 ? message`Available options: ${values(suggestions)}` : [] } }); ## Zod and Valibot integrations Two new packages join the Optique family, bringing powerful validation capabilities from the TypeScript ecosystem to your CLI parsers. ### @optique/zod The new `@optique/zod` package lets you use Zod schemas directly as value parsers: import { option, object } from "@optique/core"; import { zod } from "@optique/zod"; import { z } from "zod"; const parser = object({ email: option("--email", zod(z.string().email())), port: option("--port", zod(z.coerce.number().int().min(1).max(65535))), format: option("--format", zod(z.enum(["json", "yaml", "xml"]))), }); The package supports both Zod v3.25.0+ and v4.0.0+, with automatic error formatting that integrates seamlessly with Optique's message system. See the Zod integration guide for complete usage examples. ### @optique/valibot For those who prefer a lighter bundle, `@optique/valibot` integrates with Valibot—a validation library with a significantly smaller footprint (~10KB vs Zod's ~52KB): import { option, object } from "@optique/core"; import { valibot } from "@optique/valibot"; import * as v from "valibot"; const parser = object({ email: option("--email", valibot(v.pipe(v.string(), v.email()))), port: option("--port", valibot(v.pipe( v.string(), v.transform(Number), v.integer(), v.minValue(1), v.maxValue(65535) ))), }); Both packages support custom error messages through their respective error handler options (`zodError` and `valibotError`), giving you full control over how validation failures are presented to users. See the Valibot integration guide for complete usage examples. ## Duplicate option name detection A common source of bugs in CLI applications is accidentally using the same option name in multiple places. Previously, this would silently cause ambiguous parsing where the first matching parser consumed the option. Optique 0.7.0 now validates option names at parse time and fails with a clear error message when duplicates are detected: const parser = object({ input: option("-i", "--input", string()), interactive: option("-i", "--interactive"), // Oops! -i is already used }); // Error: Duplicate option name -i found in fields: input, interactive. // Each option name must be unique within a parser combinator. This validation applies to `object()`, `tuple()`, `merge()`, and `group()` combinators. The `or()` combinator continues to allow duplicate option names since its branches are mutually exclusive. See the duplicate detection documentation for more details. If you have a legitimate use case for duplicate option names, you can opt out with `allowDuplicates: true`: const parser = object({ input: option("-i", "--input", string()), interactive: option("-i", "--interactive"), }, { allowDuplicates: true }); ## Context-aware error messages Error messages from combinators are now smarter about what they report. Instead of generic "No matching option or command found" messages, Optique now analyzes what the parser expects and provides specific feedback: // When only arguments are expected const parser1 = or(argument(string()), argument(integer())); // Error: Missing required argument. // When only commands are expected const parser2 = or(command("add", addParser), command("remove", removeParser)); // Error: No matching command found. // When both options and arguments are expected const parser3 = object({ port: option("--port", integer()), file: argument(string()), }); // Error: No matching option or argument found. ### Dynamic error messages with `NoMatchContext` For applications that need internationalization or context-specific messaging, the `errors.noMatch` option now accepts a function that receives a `NoMatchContext` object: const parser = or( command("add", addParser), command("remove", removeParser), { errors: { noMatch: ({ hasOptions, hasCommands, hasArguments }) => { if (hasCommands && !hasOptions && !hasArguments) { return message`일치하는 명령을 찾을 수 없습니다.`; // Korean } return message`잘못된 입력입니다.`; } } } ); ## Shell completion naming conventions The `run()` function now supports configuring whether shell completions use singular or plural naming conventions: run(parser, { completion: { name: "plural", // Uses "completions" and "--completions" } }); // Or for singular only run(parser, { completion: { name: "singular", // Uses "completion" and "--completion" } }); The default `"both"` accepts either form, maintaining backward compatibility while letting you enforce a consistent style in your CLI. ## Additional improvements * **Line break handling** : `formatMessage()` now distinguishes between soft breaks (single `\n`, converted to spaces) and hard breaks (double `\n\n`, creating paragraph separations), improving multi-line error message formatting. * **New utility functions** : Added `extractOptionNames()` and `extractArgumentMetavars()` to the `@optique/core/usage` module for programmatic access to parser metadata. ## Installation deno add --jsr @optique/core @optique/run npm add @optique/core @optique/run pnpm add @optique/core @optique/run yarn add @optique/core @optique/run bun add @optique/core @optique/run For validation library integrations: # Zod integration deno add jsr:@optique/zod # Deno npm add @optique/zod # npm/pnpm/yarn/bun # Valibot integration deno add jsr:@optique/valibot # Deno npm add @optique/valibot # npm/pnpm/yarn/bun ## Looking forward This release represents our commitment to making CLI development in TypeScript as smooth as possible. The “Did you mean?” suggestions and validation library integrations were among the most requested features, and we're excited to see how they improve your CLI applications. For detailed documentation and examples, visit the Optique documentation. We welcome your feedback and contributions on GitHub!
hackers.pub
November 25, 2025 at 3:06 PM
Reposted by 洪 民憙 (Hong Minhee) :nonbinary:
**FEP-9f9f: Collections**

Collections are the most under-specified entities in #ActivityPub. I've started documenting them in a FEP:

https://codeberg.org/silverpill/feps/src/branch/main/9f9f/fep-9f9f.md
feps/9f9f/fep-9f9f.md at main
feps - My FEPs
codeberg.org
November 25, 2025 at 1:09 PM
Reposted by 洪 民憙 (Hong Minhee) :nonbinary:
フェディバースのアドベントカレンダー、去年も参加したんだ。今年も参加しなきゃ!
Fediverseのアドベントカレンダー、2025年も会場をご用意しています。

アドベントカレンダーはキリストの降誕祭・待降節に由来するもので、

12月1日(クリスマスの4つ前の日曜日)〜12月24日、毎日印をつけたり、毎週キャンドルを灯しながら数えていく習慣がありまして、

クリスマスを待つ子供達に、お菓子やおもちゃが入った扉がついているカレンダーがつくられ、毎日ひとつずつ開けていく習慣が根付いています。

大人向けの、紅茶とか化粧品の入ったカレンダーも、だいぶメジャーになってきましたよね。

で、これになぞらえ […]

[Original post on fedibird.com]
November 25, 2025 at 12:57 PM
링크가 살아 있는 것 中(중)에서는 가장 오래된 聯合宇宙(연합우주)에서의 내 글:

https://mastodon.social/@hongminhee/6595450
mastodon.social
November 25, 2025 at 7:43 AM
今日から3泊4日で福岡旅行!これから仁川空港に向かいます。
November 21, 2025 at 3:21 AM
I try to be polite when I write prompts for LLMs. Especially in languages like Korean or Japanese that have grammatical honorifics, I make sure to use the formal, respectful form of speech (what's known as 敬語— _gyeongeo_ or _keigo_). I joke with my friends that I'm using polite language early on […]
Original post on hollo.social
hollo.social
November 20, 2025 at 10:45 AM
Reposted by 洪 民憙 (Hong Minhee) :nonbinary:
November 18, 2025 at 2:40 PM
Optique 0.7.0 will support Zod schemas as value parsers.

Seemed like a natural fit—same validation logic for both CLI and app code.

https://github.com/dahlia/optique/issues/39
@optique/zod package for Zod schema integration · Issue #39 · dahlia/optique
Summary Add a new @optique/zod package that provides seamless integration between Optique and Zod schemas, enabling users to leverage Zod's powerful validation capabilities for CLI argument parsing...
github.com
November 18, 2025 at 3:35 PM
Reposted by 洪 民憙 (Hong Minhee) :nonbinary:
We’re also looking ahead to what comes next. In another blog post published today, we introduced Mastodon’s new leadership team. Our Executive Director is @mellifluousbox (formerly, CFO of Mastodon gGmbH), who has already represented Mastodon on international stages.

We also shared an […]
Original post on mastodon.social
mastodon.social
November 18, 2025 at 8:06 AM
Reposted by 洪 民憙 (Hong Minhee) :nonbinary:
Our Founder, @Gargron is stepping down from his position as CEO. He shared a reflection on his time building and growing Mastodon on our blog.

We want to take a moment to express the Mastodon team’s deep gratitude and admiration for Eugen, and for the technology and community he has built here […]
Original post on mastodon.social
mastodon.social
November 18, 2025 at 8:06 AM
Reposted by 洪 民憙 (Hong Minhee) :nonbinary:
Hey everyone, we have some pretty big news to share. You might remember that we announced a big restructuring for the Mastodon team earlier this year. Today marks an important milestone in this transition.

#mastodon #fediverse #socialweb
November 18, 2025 at 8:05 AM
If you're a software developer and need to create a presentation with a lot of code, I highly recommend you consider Slidev (by @antfu.me). Especially if you need to include TypeScript code!

Slidev is web-based presentation software made for software developers. It offers a wide variety of ways […]
Original post on hollo.social
hollo.social
November 18, 2025 at 6:54 AM
어려운 사람 테스트: 난 함께 지내기 매우 쉬운 사람입니다. https://www.idrlabs.com/kr/difficult-person/20-30-10-10-15-15-10/result.php
November 16, 2025 at 9:38 PM