Skip to content

feat: npm 배포 (N-API 브리지) - #191

Open
yyuneu wants to merge 5 commits into
dev-five-git:mainfrom
yyuneu:feat/cli-lib-entry
Open

feat: npm 배포 (N-API 브리지)#191
yyuneu wants to merge 5 commits into
dev-five-git:mainfrom
yyuneu:feat/cli-lib-entry

Conversation

@yyuneu

@yyuneu yyuneu commented Sep 8, 2026

Copy link
Copy Markdown
Contributor

개요

Vespertide CLI를 npm 패키지 vespertide로 배포합니다. Rust 툴체인 없이 npm install -g vespertide 또는 npx vespertide init으로 사용할 수 있으며, 기존 바이너리의 명령어·플래그·출력·종료 코드를 유지합니다.

배포 구조는 dependency-check-updates의 napi 브리지 방식을 따랐습니다. 메인 패키지는 unscoped vespertide이며, 플랫폼별 네이티브 바이너리는 @vespertide/cli-<platform>으로 배포합니다. 플랫폼 패키지의 접두는 napi.packageName: "@vespertide/cli"로 지정했습니다.

주요 변경 사항

CLI 라이브러리와 바이너리 분리

crates/vespertide-cli를 lib + bin 구조로 분리했습니다.

  • run: 명령 디스패치
  • main(args): try_parse_from을 통한 인자 파싱 및 실행
  • run_cli(args) -> u8: 오류 출력 및 종료 코드 반환
  • 바이너리 진입점: ExitCode::from(run_cli(args_os()))

라이브러리 내부에서는 process::exit을 호출하지 않습니다. 실행 실패 시 표준 Termination과 동일하게 stderr에 Error: {err:?}를 출력하고 1을 반환합니다. Rust 진입점은 args_os()를 통해 non-UTF-8 인자도 clap에 그대로 전달합니다.

브리지에서 CLI 라이브러리를 참조하므로 [workspace.dependencies]에 다른 내부 크레이트와 동일하게 = 버전 핀을 추가했습니다.

Node.js 브리지

bridge/node에 napi 기반 cdylib 크레이트와 Node.js 진입점 main.js를 추가했습니다. #[napi] async fn main(args) -> i32는 CLI의 종료 코드를 그대로 반환합니다.

npm 패키지에는 5개 플랫폼 타깃과 prepublishOnly: napi prepublish -t npm --no-gh-release를 설정했으며, 실제 Node.js 프로세스를 실행하는 Bun 스모크 테스트를 추가했습니다.

기존 apps/vscode-extension의 패키지명도 vespertide이므로, 이름 충돌을 피하기 위해 루트 Bun 워크스페이스에는 포함하지 않고 별도 lockfile을 사용합니다.

CI 및 배포

  • node-build: lsp-release와 동일한 5개 타깃 빌드. aarch64-linuxcross 사용
  • node-publish: publish 호스트에서 빌드해 gitignore된 index.js를 재생성한 뒤, napi create-npm-dirsnapi artifacts → 릴리스 자산 업로드 → npm publish 수행

lsp-release와 동일하게 PR에서는 실행되지 않고, 머지 이후 릴리스 웨이브에서 동작합니다. NPM_TOKEN이 없으면 경고 후 npm 게시를 건너뛰며 작업은 정상 종료됩니다.

Changepacks 및 문서

bridge/node/package.json 추적, publish 오버라이드와 updateOn을 추가해 npm 패키지가 매 크레이트 릴리스 웨이브에 Patch로 따라가도록 구성했습니다.

이번 descriptor는 CLI와 npm 매니페스트에 Minor를 지정했습니다. CLI는 게시되는 다른 크레이트가 의존하지 않는 leaf 크레이트이므로, 해당 크레이트들의 의존 버전 변경 없이 단독 Minor로 올립니다.

README에 npm 설치 방법을 추가하고, AGENTS.md의 릴리스 절차를 갱신했습니다.

검증

다음 종료 코드와 오류 출력 동작을 확인했습니다.

  • --help·--version: 종료 코드 0
  • 사용 오류: 메시지 1회 출력 및 종료 코드 2
  • 실행 실패: stderr에 Error: 출력 및 종료 코드 1

바이너리 통합 테스트에 종료 코드 21 사례를 추가했습니다. 기존 통합 테스트의 검증 내용은 유지했으며, 테스트는 모두 통과했습니다.

Windows에서 node main.js로 실행한 diff, status, sql, log, erd의 SVG·Mermaid·DOT 출력이 Cargo 바이너리와 바이트 단위로 동일함을 확인했습니다. revisiondialoguer 프롬프트도 ConPTY에서 기존 바이너리와 동일한 흐름으로 동작했습니다.

브리지는 동일 프로세스 안에서 CLI를 호출하므로 run_cli 종료 전에 stdout을 명시적으로 flush합니다.

테스트가 bin에서 lib 타깃으로 이동하면서 Insta 스냅샷 4개의 파일명 접두사가 vespertide__에서 vespertide_cli__로 변경되었습니다. 스냅샷 내용은 동일합니다.

요청 사항

npm 배포 구현은 완료했으며, 패키지 소유권과 관리자 권한이 필요한 @vespertide 조직 생성, vespertide 패키지명 확보 및 저장소의 NPM_TOKEN 등록은 멘토님께 부탁드립니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant