Optique 0.8.0: Conditional parsing, pass-through options, and LogTape integration https://lobste.rs/s/wh35st #javascript
https://hackers.pub/@hongminhee/2025/optique-080
洪 民憙 (Hong Minhee)
@hongminhee@hackers.pub · 1001 following · 704 followers
Hi, I'm who's behind Fedify, Hollo, BotKit, and this website, Hackers' Pub! My main account is at
@hongminhee洪 民憙 (Hong Minhee)
.
Fedify, Hollo, BotKit, 그리고 보고 계신 이 사이트 Hackers' Pub을 만들고 있습니다. 제 메인 계정은:
@hongminhee洪 民憙 (Hong Minhee)
.
Fedify、Hollo、BotKit、そしてこのサイト、Hackers' Pubを作っています。私のメインアカウントは「
@hongminhee洪 民憙 (Hong Minhee)
」に。
Website
- hongminhee.org
GitHub
- @dahlia
Hollo
- @hongminhee@hollo.social
DEV
- @hongminhee
velog
- @hongminhee
Qiita
- @hongminhee
Zenn
- @hongminhee
Matrix
- @hongminhee:matrix.org
X
- @hongminhee
Vercel 제품들은 딱 봐도 설계가 너무 구리게 느껴지는데, 그렇다고 깊게 생각해보진 않고 또 쨋든 사람들이 젤 많이 쓰긴하니까, 내 느낌이 잘못된건지 헷갈린다.
https://github.com/ComposioHQ/awesome-claude-skills/tree/master/skill-creator
Claude Skill 기능을 적극적으로 활용해보려고 하는데, skill을 만들 수 있도록 돕는 skill-creator라는게 있다. 이걸 좀 더 참고해서 어떻게 나한테 쓸만한걸 만들 수 있는지 한번 살펴봐야겠다.
Hackers Pub 송년회 라이트닝토크에서 발표 안하려고 했는데? 뭔가 소소하게 공유할꺼리가 생겼다. 그리고.......... Hackers Pub에서 LLM 활용하는 방법 굉장히 과한 밀도로 공유하게 될 것 같다.... 당장 내가 일하는 회사도 LLM을 엄청 적극적으로 활용하고 있기도 하고, 그걸로 사업하는 회사여서 더욱 가속도가 붙는 것도 있는 듯.
CLIパーサーの新しい記事を書きました。--reporterの値によって--output-fileが必須になったり禁止になったり…そういう関係、型で表現できたら楽じゃないですか?
린터 규칙을 새로 작성할 때 마다 꽤 곤란한데 뭔가 좋은 방법이 없을까
최적화 작업이 무사히 끝났다. 꽤 만족스러운 시간들이였음
Hackers' Pub 외부 사용자를 팔로 요청하면 상대가 수락을 해도 계속 요청 대기 상태로 유지되는 버그[1]를 고쳤습니다. 혹시 해당 현상을 겪으신 분이 있다면, 팔로 요청을 취소했다가 다시 팔로 요청을 보내보시기 바랍니다.
The Sass if() syntax is deprecated in favor of the modern CSS syntax.
https://sass-lang.com/documentation/breaking-changes/if-function/
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 valpairs), 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/-vvvpattern where each flag increases verbosity (no flags →"warning",-v→"info",-vv→"debug",-vvv→"trace")debug()parser: Simple--debug/-dflag that toggles between normal and debug levelslogLevel()value parser: Explicit--log-level=debugoption for direct level selectionlogOutput()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.
앗! 해커스펍! 코드스니펫 공유하는게 GitHub Gist보다 편하다!!!
# 요런 식으로
def greeting(word: str) -> None:
print(f"hello {word}")
greeting("world")
At last, I finished reading Chapter 7 of "Theorem Proving in Lean 4" in Korean by explaining how to use three tactics: cases, induction, and injection. https://youtu.be/N-ELdwO-vN4?si=kfemVPbbNP-Gf0m8
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를 쓰는 것도 적절한 방법일 수 있습니다.
개인 기록 관리를 obsidian으로 옮겨볼까...... 아니면 그냥 개인기록 관리(neovim zettelkasten 플러그인)를 그대로 유지하되, mcp 서버를 직접 만드는걸 해볼까... 어느 쪽이든 할만한 도전인 것 같음
고심끝에 그냥 Obsidian 쓰기로 함. 마크다운 에디터로서 가독성이 좋기도 하고, Vim 키맵도 지원되고, MCP도 비벼볼 수 있고, 여러모로 해볼 수 있는게 많음.
개인 기록 관리를 obsidian으로 옮겨볼까...... 아니면 그냥 개인기록 관리(neovim zettelkasten 플러그인)를 그대로 유지하되, mcp 서버를 직접 만드는걸 해볼까... 어느 쪽이든 할만한 도전인 것 같음
닷넷 개발 환경을 사용하는 누구나 DLL 파일을 네트워크(CDN)에 올려 쓸 수 있는 라이브러리를 MIT 라이선스로 공개하였습니다.
라이브러리 이름은 Catswords.Phantomizer 입니다!
https://github.com/gnh1201/welsonjs/tree/dev/WelsonJS.Toolkit/Catswords.Phantomizer
나도 세부 디테일과 맥락을 잃어가면서 헛다리를 계속 짚게된다 이것이 관리직?
vscode의 inline suggestion이 에디터 중에서 제일 사용감이 좋지 않다;
내가 느끼는 가장 큰 #cosmoslide 의 진입장벽이라면 activitypub 관련 코드랑 비즈니스 로직이랑 완전히 커플링되어 있는 것도 좀 큰 것 같은데, 어떻게 계층을 분리할 수 있을지 고민임.
Misskey도 계층이 잘 분리가 되어있어서 군데군데 테스트가 적당히 짜여져 있는데.... 당장은 OpenAI Codex/Claude Code on Web으로 짜도 기여할 수 있을 정도로 구조를 잘 다듬긴 해야겠다는것
호시탐탐 노리던 이슈가 하나 있었는데 괜찮으면 내가 기여해보면 어떨까? 물어봤는데 feel free to open a pr 이라니
software gore
업데이트를 하도 미뤄서 아직 리액트 18이라 문제가 없었다고 한다...
사실은 eatch.dev도 next.js인데 SSG로 올려서 그런지 React2Shell 뚫리는지 보니까 안되더라 (그래도 업데이트는 했습니다.)
next.js 제거를 6개월 간 미루었는데 결국 이런 일이 생겼습니다..
洪 民憙 (Hong Minhee) shared the below article:
압축 요청 헤더 지원 여부에 따른 HTTP Client 이중화
고남현 @gnh1201@hackers.pub
이 글에서는 .NET 환경에서 HTTP를 통한 파일 전송 시 압축을 활용하여 로딩 시간을 단축하는 방법에 대해 설명합니다. 특히, `Accept-Encoding` 헤더를 이용한 압축 요청이 서비스별로 다르게 처리될 수 있는 문제점을 지적하고, 이를 해결하기 위해 HTTP Client를 이중화하는 방법을 제시합니다. 미리 압축된 파일을 우선적으로 다운로드하고, 실패 시 압축 요청 헤더를 포함한 요청을 보내는 방식으로 압축 전송을 보장합니다. 실제 적용 사례인 `AssemblyLoader.cs` 파일의 예시를 통해, 이 방법이 어떻게 라이브러리 로딩 속도를 향상시키는지 확인할 수 있습니다. 이 글은 네트워크를 통한 라이브러리 로딩 시 안정성 확보와 성능 향상을 동시에 추구하는 개발자에게 유용한 인사이트를 제공합니다.
Read more →원래 경품, 상품 등하고 인연이 없는데 웬일이지. liftIO2025 도메인 모델링 발표 끝날 즈음 퀴즈에 아무도 답을 안해서, 그냥 오디오 공백을 없애려고, 손들었는데 정답을 맞춰버렸다. 정답일거라 예상을 못해서 리액션을 못했다.
liftIO 2025 굿즈로 준비한 함수형 언어별 키캡 중 하스켈 키캡이 제일 먼저 동났다. 선호하는 언어 키캡을 자유롭게 가져가는 거였는데 의외다.
지금 ‘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
@minsoo 안녕하세요! 반갑습니다!
12月 6日 서울에서 開催되는 liftIO 2025에서 〈Optique: TypeScript에서 CLI 파서 컴비네이터를 만들어 보았다〉(假題)라는 主題로 發表를 하게 되었습니다. 아직 liftIO 2025 티켓은 팔고 있으니, 函數型 프로그래밍에 關心 있으신 분들의 많은 參與 바랍니다!
오늘 liftIO 2025에서 發表한 〈Optique: TypeScript의 타입 推論으로 CLI 有效性 檢査를 代替하기〉의 發表 資料를 共有합니다! 들어주신 모든 분들께 感謝 드립니다.
의외로 프리파스칼 컴파일러도 여기저기 포팅이 많이 되는 거 같던데. 라자루스가 좀 더 흥하면 좋겠다.
하지만 요즘은 네이티브 GUI 프로그램 만드는 사람 잘 안 보이긴 한다.
https://djot.net/ djot이라고 Markdown 개발자가 Markdown의 문제점을 고쳐서 내놓은 마크업 언어이다. 이러고보니 Deno같군.
@bglbgl gwyng 제가 알기로는 Markdown 만든 사람은 아니고 Pandoc 제작자이자 CommonMark 스펙 공동 저자이신 분이예요!
https://djot.net/ djot이라고 Markdown 개발자가 Markdown의 문제점을 고쳐서 내놓은 마크업 언어이다. 이러고보니 Deno같군.
SolidJS로 앱 만들다가 아이콘셋이 필요해져서 패키지를 뒤져보는데, 마이너 생태계답게 마지막 업데이트가 삼사년 전인 패키지들만 나온다. 아이콘셋에 업데이트가 필요 없긴 하지. 그래도 최근에 업데이트 된 패키지가 걸리적거리는게 없을 것 같달까. 그러다 활발히 업데이트 중인 unplugin-icons를 찾았다. 이것은 SolidJS용 패키지가 아니었다. 아이콘셋도 아니었다. 거의 모든 아이콘셋을 거의 모든 프레임워크에서 사용할 수 있게 해주는 도구다. 이런 문물이 있었다니. 누가 만들었나 함 보자. 제작자는 Anthony Fu... 아아 또 그인가. 오늘도 비 React 웹 생태계엔 Anthony Fu의 은혜가 넘친다.
SolidJS로 앱 만들다가 아이콘셋이 필요해져서 패키지를 뒤져보는데, 마이너 생태계답게 마지막 업데이트가 삼사년 전인 패키지들만 나온다. 아이콘셋에 업데이트가 필요 없긴 하지. 그래도 최근에 업데이트 된 패키지가 걸리적거리는게 없을 것 같달까. 그러다 활발히 업데이트 중인 unplugin-icons를 찾았다. 이것은 SolidJS용 패키지가 아니었다. 아이콘셋도 아니었다. 거의 모든 아이콘셋을 거의 모든 프레임워크에서 사용할 수 있게 해주는 도구다. 이런 문물이 있었다니. 누가 만들었나 함 보자. 제작자는 Anthony Fu... 아아 또 그인가. 오늘도 비 React 웹 생태계엔 Anthony Fu의 은혜가 넘친다.
@hongminhee洪 民憙 (Hong Minhee)
@bglbgl gwyng 그럼 저는 기대는 안하고 경청하겠습니다 화이팅!
@yihyunjoon이현준
@bglbgl gwyng 감사합니다…!! 😂
@hongminhee洪 民憙 (Hong Minhee) 기대하겠습니다!
@bglbgl gwyng 흑… 기대하지 마세요!!
@z9mb1wwj
@wildwestromChristian Westrom Oh, no… 🤦
아아 이번 주 마지막 작업 기회가 npm 500 오류로 날아갔다
클플이 죽었나? 그런데 왜 해커스펍은 되지..
I'm very proud of myself :3 https://www.shadertoy.com/view/tcKyzK
@wildwestromChristian Westrom Oh, did you write it?
洪 民憙 (Hong Minhee) shared the below article:
근래엔 업무가 즐겁지 않아서 걱정입니다.
clastneo @clastneo@hackers.pub
과거에는 즐겁게 일했던 경험을 회상하며, 현재의 업무 환경과 비교하고 있습니다. 이 글은 과거의 긍정적인 경험을 통해 현재의 어려움을 극복하고, 다시 즐겁게 일할 수 있는 방법을 모색하는 과정을 담고 있을 것으로 예상됩니다. 과거의 즐거웠던 경험을 분석하여 현재 상황에 적용할 수 있는 교훈을 찾고, 긍정적인 마음가짐을 회복하는 데 초점을 맞출 것입니다.
Read more →Hello, World!
@dsscrolls사해문서 어서 오세요…!
예전에 보고 넘겼다가 오늘 우연히 가입하게 되었는데. UI부터가 motif 내음이 나네요.
#해커즈펍송년회 주문했습니다. 디자인이 맘에 안들어도 그렇구나 하고 받아들이세요.
아 근데 여전히 activitipub 기반 멀티버스 SNS는 헷갈린다....










