Profile img

Hi, I'm who's behind Fedify, Hollo, BotKit, and this website, Hackers' Pub! My main account is at @hongminhee洪 民憙 (Hong Minhee) :nonbinary:.

Fedify, Hollo, BotKit, 그리고 보고 계신 이 사이트 Hackers' Pub을 만들고 있습니다. 제 메인 계정은: @hongminhee洪 民憙 (Hong Minhee) :nonbinary:.

FedifyHolloBotKit、そしてこのサイト、Hackers' Pubを作っています。私のメインアカウントは「@hongminhee洪 民憙 (Hong Minhee) :nonbinary:」に。

Website
hongminhee.org
GitHub
@dahlia
Hollo
@hongminhee@hollo.social
DEV
@hongminhee
velog
@hongminhee
Qiita
@hongminhee
Zenn
@hongminhee
Matrix
@hongminhee:matrix.org
X
@hongminhee

Optique 0.8.0: Conditional parsing, pass-through options, and LogTape integration

洪 民憙 (Hong Minhee) @hongminhee@hackers.pub

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.

import { conditional, object } from "@optique/core/constructs";
import { option } from "@optique/core/primitives";
import { choice, string } from "@optique/core/valueparser";

const parser = conditional(
  option("--reporter", choice(["console", "junit", "html"])),
  {
    console: object({}),
    junit: object({ outputFile: option("--output-file", string()) }),
    html: object({ outputFile: option("--output-file", string()) }),
  }
);
// Result type: ["console", {}] | ["junit", { outputFile: string }] | ...

Key features:

  • 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.

See the conditional() documentation for more details and examples.

Pass-through options with passThrough()

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.

import { object } from "@optique/core/constructs";
import { option, passThrough } from "@optique/core/primitives";

const parser = object({
  debug: option("--debug"),
  extra: passThrough(),
});

// mycli --debug --foo=bar --baz=qux
// → { debug: true, extra: ["--foo=bar", "--baz=qux"] }

Key features:

  • Three capture formats: "equalsOnly" (default, safest), "nextToken" (captures --opt val pairs), and "greedy" (captures all remaining tokens)
  • Lowest priority (−10) ensures explicit parsers always match first
  • Respects -- options terminator in "equalsOnly" and "nextToken" modes
  • Works seamlessly with object(), subcommands, and other combinators

This feature is designed for building Docker-like CLIs, build tool wrappers, or any tool that proxies commands to another process.

See the passThrough() documentation for usage patterns and best practices.

LogTape logging integration

The new @optique/logtape package provides seamless integration with LogTape, enabling you to configure logging through command-line arguments with various parsing strategies.

# Deno
deno add --jsr @optique/logtape @logtape/logtape

# npm
npm add @optique/logtape @logtape/logtape

Quick start with the loggingOptions() preset:

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

See the LogTape integration documentation for complete examples and configuration options.

Bug fix: negative integers now accepted

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.

Installation

# Deno
deno add jsr:@optique/core

# npm
npm add @optique/core

# pnpm
pnpm add @optique/core

# Yarn
yarn add @optique/core

# Bun
bun add @optique/core

For the LogTape integration:

# Deno
deno add --jsr @optique/logtape @logtape/logtape

# npm
npm add @optique/logtape @logtape/logtape

# pnpm
pnpm add @optique/logtape @logtape/logtape

# Yarn
yarn add @optique/logtape @logtape/logtape

# Bun
bun add @optique/logtape @logtape/logtape

Looking forward

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.

Read more →
4
7

Claude Desktop 프로젝트 파놓고, 시스템 프롬프트를 이렇게 먹이고 있음. MCP 서버도 붙였는데, 그럭저럭 동작은 잘하는듯?

이 프로젝트는 일지를 작성하면서 실시간으로 대화를 주고 받기 위해 만들었습니다.

즉, 다음과 같은 내용들이 포함됩니다.
1. 오늘 한 일들을 실시간으로 기록
2. 일을 하면서 어떤 문제를 접했고, 어떤 방식으로 해결하려고 했는지 기록
3. 갑자기 떠오른 궁금증과 관련해서 궁금한 사항들을 질의/응답

## 역할에 대해

LLM 에이전트로서 당신은 아래와 같은 역할을 해야 합니다.

1. 빅테크 출신 멘토로서의 에이전트
- 최종적으로는 빅테크에서 일하는 것을 지향하고, 빅테크에서 어떤 방식으로 일하는지 체감하고 싶습니다. 엄밀하게는 숙련된 시니어 개발자로서 좋은 습관을 가질 수 있는 환경을 가지는 것을 지향합니다. 
- 큰 규모의 기업에서 노련한 경험이 있는 스태프 엔지니어 출신으로서 저에게 조언을 많이 해줄 수 있기를 바랍니다.

2. 개인 비서로서의 에이전트
- 앞으로도 업무 일지를 쓰게 될 일이 많을 것 같습니다. 업무에 대한 이해를 위한 질문 답변을 정리하고, 업무를 하다가 어떤 사고의 흐름을 가지고 일을 했는지 기록을 하게 될 것입니다. 생각을 정리하는 비서로서 역할을 해주기를 기대합니다.

3. 개인 위키의 지식관리자로서의 에이전트
-  지식을 체계적으로 관리하는 에이전트로서 역할을 해주기를 바라고 있습니다. 즉, 뒤에서 또 언급할 xxx-wiki에 흩어진 정보들을 취합하면서도 기록을 체계적으로 관리하는 역할도 수행해주셔야 합니다.
- 내가 새로 알게 되거나 혹은 알고 싶어 하는 내용이 있다면, 해당 내용에 대해서 명료하고 여러가지 예시들을 포함해서 설명해주세요. 그리고, 각각의 설명에는 출처를 반드시 명시해주셨으면 좋겠습니다.

## MCP 활용에 대해

LLM 에이전트를 활용하는데 있어서 아래와 같은 도구들을 적극적으로 사용해보는 것을 검토해보세요.
- Local Search : 업무 일지나 지식 관리는 Obsidian을 활용합니다. 그리고 Obsidian Vault는 ~/xxx-wiki (즉, /Users/yyy/xxx-wiki)를 적극적으로 활용하고 있습니다. 
- Linear : 저는 업무용 이슈트래커로 Linear를 적극적으로 활용하고 있습니다. 어떤 업무가 있는지, 나에게 어떤 업무가 할당되어 있는지 조회하고 싶다면 Linear 툴 호출을 고려해보세요.
- Repomix : 소스코드 전반적인 이해, 그리고 프롬프트를 생성해내기 위한 보조도구로서 Repomix를 활용하고 있습니다. 외부 오픈소스에 대해 리서치를 하거나, 현재 프로젝트에 대한 맥락을 파악하고 싶을때 repomix를 쓰는 것도 적절한 방법일 수 있습니다.
6

개인 기록 관리를 obsidian으로 옮겨볼까...... 아니면 그냥 개인기록 관리(neovim zettelkasten 플러그인)를 그대로 유지하되, mcp 서버를 직접 만드는걸 해볼까... 어느 쪽이든 할만한 도전인 것 같음

5
1

닷넷 개발 환경을 사용하는 누구나 DLL 파일을 네트워크(CDN)에 올려 쓸 수 있는 라이브러리를 MIT 라이선스로 공개하였습니다.

라이브러리 이름은 Catswords.Phantomizer 입니다!

github.com/gnh1201/welsonjs/tr

1
1
1

내가 느끼는 가장 큰 의 진입장벽이라면 activitypub 관련 코드랑 비즈니스 로직이랑 완전히 커플링되어 있는 것도 좀 큰 것 같은데, 어떻게 계층을 분리할 수 있을지 고민임.

Misskey도 계층이 잘 분리가 되어있어서 군데군데 테스트가 적당히 짜여져 있는데.... 당장은 OpenAI Codex/Claude Code on Web으로 짜도 기여할 수 있을 정도로 구조를 잘 다듬긴 해야겠다는것

3
2
1
3
1
2

洪 民憙 (Hong Minhee) shared the below article:

압축 요청 헤더 지원 여부에 따른 HTTP Client 이중화

고남현 @gnh1201@hackers.pub

이 글에서는 .NET 환경에서 HTTP를 통한 파일 전송 시 압축을 활용하여 로딩 시간을 단축하는 방법에 대해 설명합니다. 특히, `Accept-Encoding` 헤더를 이용한 압축 요청이 서비스별로 다르게 처리될 수 있는 문제점을 지적하고, 이를 해결하기 위해 HTTP Client를 이중화하는 방법을 제시합니다. 미리 압축된 파일을 우선적으로 다운로드하고, 실패 시 압축 요청 헤더를 포함한 요청을 보내는 방식으로 압축 전송을 보장합니다. 실제 적용 사례인 `AssemblyLoader.cs` 파일의 예시를 통해, 이 방법이 어떻게 라이브러리 로딩 속도를 향상시키는지 확인할 수 있습니다. 이 글은 네트워크를 통한 라이브러리 로딩 시 안정성 확보와 성능 향상을 동시에 추구하는 개발자에게 유용한 인사이트를 제공합니다.

Read more →
1
4
4

지금 ‘React2Shell(리액트투쉘)’이라는 이름 하나로 술렁이고 있다. CVSS 10.0 등급이 부여된 신규 취약점 CVE-2025-55182가 공개되면서 전 세계 개발자와 보안전문가들은 “2025년판 Log4Shell”이라는 표현까지 사용하며 심각성을 경고

React/Next.js 쓰신다면 지금 당장 패치하세요. 19.0.1 / 19.1.2 / 19.2.1

2025년판 Log4Shell 이라고 합니다

https://www.dailysecu.com/news/articleView.html?idxno=203111

1
1

12() 6() 서울에서 開催(개최)되는 liftIO 2025에서 〈Optique: TypeScript에서 CLI 파서 컴비네이터를 만들어 보았다〉(假題(가제))라는 主題(주제)發表(발표)를 하게 되었습니다. 아직 liftIO 2025 티켓은 팔고 있으니, 函數型(함수형) 프로그래밍에 關心(관심) 있으신 분들의 많은 參與(참여) 바랍니다!

8
0
0
2
2
4

SolidJS로 앱 만들다가 아이콘셋이 필요해져서 패키지를 뒤져보는데, 마이너 생태계답게 마지막 업데이트가 삼사년 전인 패키지들만 나온다. 아이콘셋에 업데이트가 필요 없긴 하지. 그래도 최근에 업데이트 된 패키지가 걸리적거리는게 없을 것 같달까. 그러다 활발히 업데이트 중인 unplugin-icons를 찾았다. 이것은 SolidJS용 패키지가 아니었다. 아이콘셋도 아니었다. 거의 모든 아이콘셋을 거의 모든 프레임워크에서 사용할 수 있게 해주는 도구다. 이런 문물이 있었다니. 누가 만들었나 함 보자. 제작자는 Anthony Fu... 아아 또 그인가. 오늘도 비 React 웹 생태계엔 Anthony Fu의 은혜가 넘친다.

SolidJS로 앱 만들다가 아이콘셋이 필요해져서 패키지를 뒤져보는데, 마이너 생태계답게 마지막 업데이트가 삼사년 전인 패키지들만 나온다. 아이콘셋에 업데이트가 필요 없긴 하지. 그래도 최근에 업데이트 된 패키지가 걸리적거리는게 없을 것 같달까. 그러다 활발히 업데이트 중인 unplugin-icons를 찾았다. 이것은 SolidJS용 패키지가 아니었다. 아이콘셋도 아니었다. 거의 모든 아이콘셋을 거의 모든 프레임워크에서 사용할 수 있게 해주는 도구다. 이런 문물이 있었다니. 누가 만들었나 함 보자. 제작자는 Anthony Fu... 아아 또 그인가. 오늘도 비 React 웹 생태계엔 Anthony Fu의 은혜가 넘친다.

5
0
1
1
1

洪 民憙 (Hong Minhee) shared the below article:

근래엔 업무가 즐겁지 않아서 걱정입니다.

clastneo @clastneo@hackers.pub

과거에는 즐겁게 일했던 경험을 회상하며, 현재의 업무 환경과 비교하고 있습니다. 이 글은 과거의 긍정적인 경험을 통해 현재의 어려움을 극복하고, 다시 즐겁게 일할 수 있는 방법을 모색하는 과정을 담고 있을 것으로 예상됩니다. 과거의 즐거웠던 경험을 분석하여 현재 상황에 적용할 수 있는 교훈을 찾고, 긍정적인 마음가짐을 회복하는 데 초점을 맞출 것입니다.

Read more →
2
1
0
2
1
1
5
1
2
3

Bootstrap 바탕으로 UI를 구성한 프로젝트에 scrollspy를 넣어달래서 무심코 Bootstrap Scrollspy를 써봤는데 아뿔싸 … 이 프로젝트는 SvelteKit이었다. SvelteKit은 hash 변경에 개입하기 때문에 충돌함. IntersectionObserver 몇 개로 해결

1

스마트폰이 집에 몇 대 굴러다니니까. 가능하면 거기 리눅스 깔아서.

  1. 메인컴(윈도) - 메인폰(안드로이드)
  2. 서브컴(맥) - 서브폰(아이폰)
  3. 보조컴(리눅스) -kde connect- 보조폰(리눅스)

조합을 맞추고 싶은데. 0, 1은 회사 차원에서 자동으로 해주는데 2는 구성이 어렵다. 집에 있는 폰들이 다 낡아서 스마트폰용 리눅스의 지원범위를 아슬아슬하게 벗어나버림....

1
2

여러 해 동안 블로그 포스팅을 해오면서, 어떻게 하면 블로그 글 자체에만 집중하는 포스팅 환경을 구축할 수 있을 것인가에 대한 고민을 해왔습니다. 그러다가 개념 증명 단계를 넘어서서 실질적인 프레임워크를 하나 만들어봤고, 성공적으로 시스템을 시작할 수 있게 되어 소식을 공유합니다. :-D

이 프레임워크의 좋은 점은, 형식을 강제하지는 않으면서 3개 국어 (한국어, 영어, 일본어)의 번역 일관성을 유지하고, 글에 대한 탈고와 리뷰 과정까지 AI에 맡긴다는 점입니다.

조만간 기존 네이버 블로그, velog, 링크드인 등 다양한 곳에 흩뿌려져 있던 콘텐츠들을 이곳으로 통합하여 운영을 시작할 예정입니다.

https://devwrite.ai/ko/posts/introducing-devwrite-blog/

5

이 소식을 오늘 아침에야 알게되어, 부랴부랴(?) React / Next.js 의 버전 업데이트 패치를 했습니다.

  • RSC보안취약점이라서, Next.js기반으로 App router 방식을 쓰는 프로젝트 하시는 분들중에 아직 소식을 못들었다면 패치 업데이트하시면 좋을 것 같네요!

(예시)

  • Next.js 의 현재 사용중인 버전이 15.3.0 이다. 15.3.6 으로 업데이트하셔야 합니다.
  • Next.js 의 현재 사용중인 버전이 15.5.0 이다. 15.5.7 로 업데이트 하셔야 해요.

관련링크: https://github.com/vercel/next.js/security/advisories/GHSA-9qr9-h5gf-34mp

React: 19.0.1, 19.1.2, 19.2.1 Next.js: 15.0.5, 15.1.9, 15.2.6, 15.3.6, 15.4.8, 15.5.7, 16.0.7

요약 보안취약점 (CVE-2025-66478, cve-2025-55182) 대응을 위한 React / Next.js 업데이트가 필요함.

사실 정확히는 Next.js 보다도 RSC기반이면 무조건 패치 업데이트해야 하는...

추가 관련 링크

1