# jocohunt-cli
`jocohunt-cli`๋ [์กฐ์ฝํํธ](https://jocohunt.jocoding.io/) ์ ํ ๋ชฉ๋ก ์กฐํ์ ์ ํ ๋ฑ๋ก์ ํฐ๋ฏธ๋์์ ์ฒ๋ฆฌํ๋ npm ๋ฐฐํฌ Go CLI์
๋๋ค. **๋น์ ์ ์์ด๋์ด๋ฅผ ์์ด์ ํธ๊ฐ ์๋ฆฌ๊ฒ ํ์ธ์.**
- ์ ์ฅ์: <https://github.com/code-yeongyu/joco>
- npm: <https://www.npmjs.com/package/jocohunt-cli>
## ์ค์น
๊ฐ์ฅ ๋น ๋ฅธ ์ค์น ๊ฒฝ๋ก๋ npm์
๋๋ค. ํจํค์ง๋ ํ์ฌ ํ๋ซํผ์ ๋ง๋ Go ๋ฐ์ด๋๋ฆฌ๋ฅผ ํฌํจํ๊ณ , ์ ์ญ ์ค์น ํ `jocohunt-cli` ๋ช
๋ น์ ์ ๊ณตํฉ๋๋ค.
### 1) npm์ผ๋ก ์ค์น
```bash
npm install -g jocohunt-cli
jocohunt-cli products --limit 5
```
๊ธฐ์กด ์คํฌ๋ฆฝํธ ํธํ์ ์ํด `jocohunt` ๋ณ์นญ๋ ํจ๊ป ์ ๊ณตํฉ๋๋ค.
### 2) `go install`๋ก ๋ฐ๋ก ์ค์น
```bash
go install github.com/yeongyu/jocohunt/cmd/jocohunt@latest
jocohunt products --limit 5
```
### 3) ์์ค๋ฅผ ํด๋ก ํด ๋น๋
```bash
git clone https://github.com/code-yeongyu/joco.git
cd joco
go build -o jocohunt ./cmd/jocohunt
./jocohunt products --limit 5
```
> Go 1.24+ ๊ฐ ํ์ํฉ๋๋ค. ๋น๋ํ ๋ฐ์ด๋๋ฆฌ๋ฅผ `PATH`์ ๋๋ฉด ์ด๋์๋ `jocohunt`๋ก ์คํํ ์ ์์ต๋๋ค.
## ์ฌ์ฉ๋ฒ
```bash
jocohunt-cli products --limit 10
jocohunt-cli submit --title "๋ด ์ ํ" --url "https://example.com" --tagline "ํ ์ค ์๊ฐ" --dry-run
# ๊ธฐ์กด ๋ณ์นญ๋ ๋์ํฉ๋๋ค.
jocohunt products --limit 10
jocohunt products --category ai-tools --json
jocohunt ideas --tab recent
jocohunt leaderboard --period weekly
jocohunt inspect
jocohunt auth login --print-url
```
## ๋ก๊ทธ์ธ
CLI์์ GitHub OAuth URL์ ๋ง๋ค๊ณ , ๊ฐ๋ฅํ๋ฉด **๋ธ๋ผ์ฐ์ ์์ ์ธ์
์ฟ ํค๋ฅผ ์๋์ผ๋ก ์บก์ฒ**ํด ์ ์ฅํฉ๋๋ค.
```bash
jocohunt auth login
```
๋ธ๋ผ์ฐ์ ๋ฅผ ๋์ฐ์ง ์๊ณ URL๋ง ์ถ๋ ฅํ๋ ค๋ฉด:
```bash
jocohunt auth login --print-url
```
๋ธ๋ผ์ฐ์ ์๋ ์บก์ฒ๊ฐ ์ด๋ ค์ด ํ๊ฒฝ์์๋ URL์ ์ด๊ณ , `--session-cookie`๋ก ์ธ์
์ ์๋ ์ ์ฅํ ์ ์์ต๋๋ค. ์ ์ฅ ํ์ผ์ ๊ธฐ๋ณธ์ ์ผ๋ก ์ฌ์ฉ์ config ๋๋ ํฐ๋ฆฌ์ `jocohunt/session.json`์ด๋ฉฐ ๊ถํ์ `0600`์
๋๋ค.
```bash
jocohunt auth login --session-cookie 'better-auth.session_token=...' --csrf-token '...'
jocohunt auth status
jocohunt auth logout
```
ํค๋๋ฆฌ์ค๋ก ์คํํ๋ ค๋ฉด:
```bash
jocohunt auth login --headless
```
ํน์ Chrome/Chromium ๊ฒฝ๋ก๋ฅผ ์ฐ๋ ค๋ฉด:
```bash
jocohunt auth login --browser "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"
```
์ ์ฅ๋ ์ธ์
์ ์ ์ฅ ๋น์์ `--base-url` ์ค๋ฆฌ์ง์๋ง ์ฌ์ฌ์ฉํฉ๋๋ค. ๋ค๋ฅธ `--base-url`๋ก ์์ฒญ์ ๋ณด๋ผ ๋๋ ์ ์ฅ๋ ์ธ์
์ ์๋์ผ๋ก ์ฌ์ฉํ์ง ์์ต๋๋ค(์ฟ ํค ์ ์ถ ๋ฐฉ์ง).
ํ
์คํธ๋ ์๋ํ์์๋ `JOCOHUNT_CONFIG_DIR`๋ก ์ ์ฅ ์์น๋ฅผ ๋ฐ๊ฟ ์ ์์ต๋๋ค.
## ์ ํ ๋ฑ๋ก
`auth login --session-cookie`๋ก ์ธ์
์ ์ ์ฅํด๋๋ฉด CLI์์ ๋ฐ๋ก ์ ํ์ ๋ฑ๋กํ ์ ์์ต๋๋ค.
```bash
jocohunt submit \
--title "๋ด ์ ํ" \
--url "https://example.com" \
--tagline "ํ ์ค ์๊ฐ" \
--description "์กฐ๊ธ ๋ ๊ธด ์ค๋ช
" \
--category "ai-tools" \
--confirm
```
๋ฑ๋ก ์ ์์ฒญ ๋ณธ๋ฌธ๋ง ํ์ธํ๋ ค๋ฉด `--dry-run`์ ์ฌ์ฉํฉ๋๋ค.
```bash
jocohunt submit --title "๋ด ์ ํ" --url "https://example.com" --tagline "ํ ์ค ์๊ฐ" --dry-run
```
์ธ์
์ฟ ํค๋ฅผ ํ๋๊ทธ๋ก ์ง์ ๋๊ธธ ์๋ ์์ต๋๋ค.
```bash
jocohunt submit --title "๋ด ์ ํ" --url "https://example.com" --tagline "ํ ์ค ์๊ฐ" \
--session-cookie 'better-auth.session_token=...' --confirm
```
์กฐ์ฝํํธ API ๊ฒฝ๋ก๊ฐ ๋ฐ๋๋ฉด `--submit-endpoint`๋ก ๋ฐ๊ฟ ์ฐ๋ฅผ ์ ์์ต๋๋ค. ๊ธฐ๋ณธ๊ฐ์ `/api/submit`์
๋๋ค. ์๋ฒ๊ฐ CSRF ํ ํฐ์ ์๊ตฌํ๋ ๋ฐฐํฌ์์๋ `--csrf-token` ๋๋ `JOCOHUNT_CSRF_TOKEN`์ ๊ฐ์ด ๋ฃ์ผ์ธ์.
๋ณด์์ ์ํด `--submit-endpoint`๋ **์๋ ๊ฒฝ๋ก๋ง ํ์ฉ**ํฉ๋๋ค(์: `/api/submit`). ์ ๋ URL์ด๋ `//host/path` ํํ๋ ๊ฑฐ๋ถํฉ๋๋ค.
## ๋ณด์ ๋ฒ์
์กฐํ ๋ช
๋ น์ ๊ณต๊ฐ HTML๊ณผ JSON-LD๋ง ์ฝ์ต๋๋ค. `auth login`์ GitHub OAuth URL์ ๋ง๋ค๊ณ , ๊ฐ๋ฅํ๋ฉด ๋ธ๋ผ์ฐ์ ์์ ์ธ์
์ฟ ํค๋ฅผ ์บก์ฒํด ๋ก์ปฌ์ ์ ์ฅํฉ๋๋ค. `submit`/`upload` ๋ช
๋ น๋ง ๋ก๊ทธ์ธ ์ธ์
์ฟ ํค๋ฅผ ์ฌ์ฉํด `/api/submit`์ POSTํฉ๋๋ค. ๋ผ์ด๋ธ ๋ฑ๋ก์๋ ์ค์ ๋ฐฉ์ง๋ฅผ ์ํด `--confirm`์ด ํ์ํฉ๋๋ค.
## npm ๋ฐ์ด๋๋ฆฌ ๋ฐฐํฌ
๋ฆด๋ฆฌ์ค ์ ์ ํ๋ซํผ๋ณ Go ๋ฐ์ด๋๋ฆฌ๋ฅผ ์์ฑํฉ๋๋ค.
```bash
npm run build:binaries
npm test
npm pack --dry-run
```
`npm/bin.js`๋ Node์ ํ๋ซํผ๋ช
(`win32`, `x64` ๋ฑ)์ Go ๋์๋ช
(`windows`, `amd64` ๋ฑ)์ผ๋ก ๋ณํํ ๋ค `npm/jocohunt-<goos>-<goarch>` ๋ฐ์ด๋๋ฆฌ๋ฅผ ์คํํฉ๋๋ค. ํ๋ซํผ ๋ฐ์ด๋๋ฆฌ๊ฐ ์์ผ๋ฉด ๋ก์ปฌ ๊ฐ๋ฐ์ฉ `npm/jocohunt` fallback์ ์ฌ์ฉํฉ๋๋ค. npm ํจํค์ง๋ `jocohunt-cli` ๋ช
๋ น์ ๊ธฐ๋ณธ์ผ๋ก ๋
ธ์ถํ๊ณ , ๊ธฐ์กด `jocohunt` ๋ช
๋ น๋ ๋ณ์นญ์ผ๋ก ์ ์งํฉ๋๋ค.
ํจํค์ง์ ํฌํจ๋๋ ํ๋ซํผ ๋ฐ์ด๋๋ฆฌ:
- macOS: arm64, x64
- Linux: armv7, arm64, x64
- Windows: arm64, x64
๋ก์ปฌ์์ ์ง์ ๋ฐฐํฌํ ๋๋ npm ๋ก๊ทธ์ธ ์ํ๋ฅผ ํ์ธํ ๋ค ์๋ ์์๋ก ๋ฐฐํฌํฉ๋๋ค.
```bash
npm whoami
npm publish
```
## CI
GitHub Actions๋ ๋ค์์ ๊ฒ์ฌํฉ๋๋ค.
- `go test -race -shuffle=on -count=1 ./...`
- `npm test`
- `npm pack --dry-run`
- ํ๋ซํผ๋ณ ๋ฐ์ด๋๋ฆฌ ๋น๋
- ์ค์ ์ฌ์ดํธ์ ๋ํ ์ฝ๊ธฐ ์ ์ฉ smoke test
## ๋ฆด๋ฆฌ์ค
1. ๋ฒ์ ์ ์ฌ๋ฆฝ๋๋ค.
2. `npm run build:binaries`๋ฅผ ์คํํฉ๋๋ค.
3. ํ๊ทธ๋ฅผ ํธ์ํฉ๋๋ค.
4. `release.yml`์ด ํ
์คํธ, ๋ฐ์ด๋๋ฆฌ ๋น๋, `npm pack`, OIDC ๊ธฐ๋ฐ `npm publish`, GitHub Release ์์ฑ์ ์์๋๋ก ์คํํฉ๋๋ค.
5. npm ๋ฐฐํฌ๋ `jocohunt-cli` ํจํค์ง์ Trusted Publisher ์ค์ ์ผ๋ก GitHub Actions OIDC๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๋ฆด๋ฆฌ์ค ์ํฌํ๋ก๋ ํ๊ทธ `v*`์์๋ง ๋์ํฉ๋๋ค. ๋ฐฐํฌ ์ ์ ๋ก์ปฌ์์ ์๋ ๋ช
๋ น์ผ๋ก ํจํค์ง ํฌํจ ํ์ผ์ ํ์ธํ์ธ์.
```bash
npm pack --dry-run
```