CLI for HR systems. Supports Greeting HR (app.greetinghr.com) and goorm (<tenant>.goorm.io coding-test platform); structured to grow with additional providers as subcommands under the same hr binary.
# Homebrew
brew install zigbang-smarthome/tap/hr-cli
# npm
npm install -g @zigbang-smarthome/hr-cli
# Direct
curl -fsSL https://github.com/zigbang-smarthome/hr-cli/releases/latest/download/install.sh | shEmail + password login. Server returns a 30-day JWT, stored at ~/.config/greeting/credentials.json (mode 0600). Password is never persisted — only the token returned by POST /authn/login/password.
hr greeting auth login # interactive prompt
hr greeting auth login --email yg@zigbang.com --workspace-id 1724
hr greeting auth status
hr greeting auth logoutNon-interactive (CI):
HR_GREETING_EMAIL=... HR_GREETING_PASSWORD=... hr greeting auth login --workspace-id 17242FA-enabled accounts cannot use programmatic login at present.
hr
└── greeting Greeting HR (app.greetinghr.com)
├── auth
│ ├── login POST /authn/login/password (MD5'd password)
│ ├── logout remove ~/.config/greeting/credentials.json
│ └── status show stored credentials state
├── opening
│ ├── list [--status ALL|OPEN|CLOSED] [--page-size]
│ ├── show <id> opening abstract-info
│ ├── processes <id> hiring stages (지원 접수 / 코딩테스트 / ...)
│ └── tags <id> tags defined on the opening
└── applicant
├── list [--opening] [--since YYYY-MM-DD] [--status] [--process-id]
│ also populates the local opening-cache
├── show <id> [--opening <id>] [--minimal] detail + tags + memos + evals + meetings + docs (JSON)
├── view <id> [--opening <id>] open in default browser
├── documents <id> [--opening <id>] [--download <dir>] list / download resume PDFs
├── notes <id> [--opening <id>] list internal notes (memos)
├── note-add <id> [--message <text> | --file <path>|-] add an internal note (memo)
├── note-remove <id> <memoId> delete an internal note
├── evaluations <id> [--opening <id>] list per-process scores / comments
├── eval-add <id> --score <s> --comment <c> [--private] submit an evaluation (current-process default)
├── eval-update <id> <contentId> --score <s> --comment <c> update an existing evaluation
├── eval-delete <id> <contentId> --reason <r> delete an evaluation (with reason)
├── tags <id> [--opening <id>] tags attached to the applicant
├── tag-add <id> <name> [<name>...] attach tags (auto-creates new ones)
└── tag-remove <id> <tagId> detach a tag by id
--opening is always optional for applicant subcommands. When omitted, the CLI looks up the opening from a local cache at ~/.config/greeting/cache.json (populated by applicant list). Cache miss falls back to scanning openings — first one that returns a 200 wins.
# 1. Pull today's applicants (also caches them — subsequent commands won't need --opening)
hr greeting applicant list --since 2026-04-28
# 2. Drill into one applicant — no --opening needed
hr greeting applicant show 7469555
hr greeting applicant view 7469555
hr greeting applicant documents 7469555 --download ./resumes
hr greeting applicant notes 7469555
# 3. Evaluation writes (current process auto-resolved)
hr greeting applicant eval-add 7469555 --score 매우적합 --comment "1차 18/20 — 핵심 evidence 한 줄"
hr greeting applicant evaluations 7469555 # find contentId
hr greeting applicant eval-update 7469555 <contentId> --score 적합 --comment "수정"
hr greeting applicant eval-delete 7469555 <contentId> --reason "오등록"
# Score values:
# STEP5 (default for new openings): 100 매우적합 | 75 적합 | 50 보통 | 25 부적합 | 0 매우부적합
# --score accepts numeric (100/75/...) or aliases (매우적합/적합/...) or English (perfect/strong/ok/weak/reject)
# Comment: plain text only (no markdown rendering), 50,000 char max.
# 4. Tag / memo writes (require manager permission on the opening)
hr greeting applicant tag-add 7469555 서류-합격-yg
hr greeting applicant tags 7469555 # find tagId
hr greeting applicant tag-remove 7469555 <tagId>
hr greeting applicant note-add 7469555 --message "1차 스크리닝 18/20"
echo "longer body…" | hr greeting applicant note-add 7469555 --file -
hr greeting applicant note-remove 7469555 <memoId>Note:
tag-add/tag-removeneed manager permission (isManager: trueon the opening). Note and eval writes only need joined access. A 403 지원서 기본 정보 관리 권한이 없습니다 means your account is joined but not a manager — ask the HR admin to upgrade.
Google OAuth via Playwright. The CLI launches a headed Chromium window; you sign in with Google, and on landing back at /manage/my the cookies are captured and stored at ~/.config/goorm/credentials.json (mode 0600). Subsequent requests use those cookies via plain fetch.
hr goorm auth login # opens Chromium for the default channel (zigbang)
hr goorm auth login --channel <slug> # other goorm tenant
hr goorm auth status
hr goorm auth logoutPlaywright is a peer-style dev dep — install it once if missing:
bun add playwright && bunx playwright install chromiumThe goormaccounts.sid JWT is good for ~30 days; the CLI prints a warning when fewer than 3 days remain.
hr goorm goorm.io 코딩테스트 (zigbang.goorm.io)
├── auth
│ ├── login [--channel zigbang] [--timeout 600] Google OAuth via headed Chromium
│ ├── logout remove ~/.config/goorm/credentials.json
│ └── status stored credentials state + JWT expiry
├── lecture
│ ├── list GET /api/lecture/assessment
│ └── show <index|sequence> GET /api/lecture/<index> (full JSON)
├── student
│ └── list <index|sequence> GET /api/lecture/<index>/students
├── exam
│ ├── list <index|sequence> [--limit 100] [--page 0] GET /api/lecture/<index>/admin/exam-list (per-exam metadata)
│ └── stats <index|sequence> GET /api/exam/staticsdata (submit_rate, avg_score)
├── group
│ └── list <index|sequence> GET /api/lecture/<index>/groups (Frontend/Backend Engineer 등)
└── message
└── templates [--show <id>] GET /api/message/template/list
Lecture identifiers: pass either the sequence (URL number, e.g. 54904) or the index (lec_xxx). The CLI resolves sequence → index automatically by hitting /api/lecture/assessment first.
hr goorm lecture list
hr goorm student list 54904 # by sequence
hr goorm student list lec_FRhmn_1740557398622 # by index
hr goorm lecture show 54904 | jq '.subject, .student_count'
hr goorm exam list 54904 # 시험 목록 (제목, 그룹, 작성자, 제한시간)
hr goorm exam stats 54904 # 제출률 / 평균점수
hr goorm group list 54904 # 그룹별 학생 분포
hr goorm message templates # 코테 발송 템플릿
hr goorm message templates --show <template-id> # 본문 출력 (HTML)Owner-only features (not exposed to educator role like yg's account):
- POST 코테 발송 / invite (button hidden in UI for non-owners)
- per-student exam result / submission (
/api/exam/result/<exam>returnsfalsefor non-owners)
For Smarthome's flow, send-out is handled by the lecture owner (e.g. 장혜연) via the goorm web UI; yg's CLI usage is read-only on stats/groups/templates.
- Greeting API base:
https://api.greetinghr.com - Greeting auth header:
Authorization: <token>(noBearerprefix) - Greeting required headers per request:
X-Greeting-Workspace-Id,X-Greeting-Opening-Id(when scoped to opening) - Goorm API base:
https://<channel>.goorm.io - Goorm auth:
Cookie:header with the captured browser cookies (Google OAuth session) - Endpoints reverse-engineered from the SPA; not officially supported by Greeting HR