xenocast CLI 레퍼런스
API 키 모드의 xenocast 명령 전체, 옵션, 출력, 환경 변수, 종료 코드
xenocast는 API 키가 있으면 새 러너 API(/api/runner/v1)를 씁니다. 이 페이지는 그 모드의 명령 전체입니다. 옛 이름 xenoci도 같은 명령으로 동작합니다
모드와 인증
다음 중 하나가 있으면 API 키 모드입니다
- 환경 변수
XENOCI_API_KEY(저장된 키보다 우선) xenocast config set api-key로 저장한 키XENOCI_RUNNER2=1또는--runner2플래그
이 모드에서 login, logout, token은 쓰지 않고 종료 코드 2로 거절됩니다. 쓸 수 있는 명령은 config, whoami, credits, usage, build, status, jobs, logs, cancel, wait, artifacts, mcp입니다. 다른 명령은 runner2_unsupported로 거절됩니다
xenocast --help공통 옵션
| 옵션 | 설명 |
|---|---|
--json | 기계가 읽는 JSON 한 개만 표준 출력에 씁니다. 오류도 {"error":{...}} JSON입니다. build와 logs --wait에서는 로그가 표준 오류로 갑니다 |
--api-url URL | API 주소(기본 https://xenoci.com) |
--help | 명령별 사용법 |
--version | CLI 버전 |
--이름=값과 --이름 값은 같습니다. 출력에 섞인 xci_live_… 문자열은 [REDACTED]로 가립니다
환경 변수
| 변수 | 설명 |
|---|---|
XENOCI_API_KEY | API 키(xci_live_…). 형식이 아니면 invalid_api_key_format으로 거절 |
XENOCI_API_URL | API 주소, 기본 https://xenoci.com |
XENOCI_RUNNER2 | 1이면 키가 없어도 API 키 모드 |
XENOCI_CONFIG_DIR | 저장된 키와 메타데이터 위치 |
XENOCAST_CREDENTIAL_STORE | 저장소 강제: keychain, wincred, secret-service, file |
XENOCI_SOURCE_KIND | 잡의 source_kind(cli, mcp, github_action, api). 액션이 github_action으로 넣습니다 |
GITHUB_ACTIONS | true이면 잔액과 한도 오류를 ::error 주석으로도 남깁니다 |
config
xenocast config show
xenocast config set api-key [--key-env VAR]
xenocast config unset api-keyshow: 키 출처(XENOCI_API_KEY또는 저장된 키)와 가린 값(xci_live_…abcd), API 주소를 보여 줍니다set api-key: 키를 표준 입력으로 받거나--key-env 변수이름에서 읽어 저장합니다. 명령줄 인자로는 받지 않습니다. 저장 뒤XENOCI_API_KEY가 있으면 그것이 우선합니다unset api-key: 저장된 키를 지웁니다
printf %s "$XENOCI_API_KEY" | xenocast config set api-key
xenocast config set api-key --key-env MY_KEYwhoami
xenocast whoami키의 조직, 워크스페이스, 키 이름과 ID, 권한(run 또는 read), 키 출처, 사용 가능 잔액과 충전 링크를 보여 줍니다. --json이면 GET /v1/me 응답 그대로입니다
credits
xenocast credits
xenocast credits topup [--open]credits는 GET /v1/balance를 읽습니다
잔액 $20.0000 (사용 가능 $19.9208, 실행 중 잡 $0.0792)
분당 $0.0396
만료 예정 $20.0000 (2027-10-11T03:00:00.000Z)
충전: https://xenoci.com/console/billing (로그인한 사람이 콘솔에서 결제)사용 가능은 살아 있는 크레딧에서 실행 중 잡이 이미 쓴 금액을 뺀 값입니다- 잔액이 적으면
잔액이 적습니다 (기준 $1.1880 미만)줄이 더 붙습니다 topup은 충전 링크만 출력합니다.--open은 브라우저로 엽니다. CLI는 결제하지 않습니다
usage
xenocast usage [--from YYYY-MM-DD] [--to YYYY-MM-DD] [--by day|workspace|api_key]GET /v1/usage를 읽어 묶음마다 잡 수, 과금 분, 금액(USD)을 한 줄씩 내고 합계를 붙입니다. 날짜는 UTC이고 양끝 포함, 최대 366일, 비우면 이번 달 1일부터 오늘까지입니다. 키로 부르면 키의 워크스페이스만 집계합니다
2026-10-11 잡 4개 7분 $0.2772
합계 잡 4개 7분 $0.2772build
xenocast build --script FILE_OR_COMMAND
[--dir DIR | --repo owner/name [--ref REF] | --repo-url URL [--ref REF]]
[--xcode VERSION] [--timeout MINUTES] [--artifacts GLOBS] [--no-wait]| 옵션 | 설명 |
|---|---|
--script | 필수. 올릴 폴더 안의 스크립트 파일 경로, 또는 공백이나 셸 기호가 있는 명령 문자열('xcodebuild -version'). git 소스일 때 파일이 없으면 저장소 안의 bash <경로>로 실행 |
--dir DIR | 올릴 폴더(기본 현재 폴더). tar.gz로 묶어 POST /v1/uploads에 올립니다 |
--repo owner/name | https://github.com/owner/name.git을 VM이 직접 받습니다(공개 저장소만). --dir와 함께 주면 폴더를 올리고 저장소 이름은 사용량 표시용으로만 기록 |
--repo-url URL | 공개 git https 주소를 직접 지정 |
--ref REF | 브랜치, 태그, 커밋 |
--xcode VERSION | Xcode 버전. 환경 화면의 목록에 없는 값은 invalid_request |
--timeout MINUTES | 제한 시간 1~360(기본 60). 넘으면 timed_out |
--artifacts GLOBS | 쉼표로 나눈 결과물 경로 글롭(작업 폴더 기준). 예: 'build/*.ipa,build/*.xcarchive' |
--no-wait | 접수만 하고 {"id":"job_…","status":"queued"}를 출력한 뒤 끝냅니다 |
동작
- 소스를 올리고
업로드: 파일 N개 (MB)를 표준 오류에 씁니다 POST /v1/jobs로 접수하고잡 접수: job_…를 씁니다. 대기 중이면(대기: 동시 실행 한도)또는(대기: 용량)이 붙습니다- 로그를 2초 간격으로 받아 표준 출력에 그대로 씁니다
- 끝나면 요약 한 줄을 표준 오류에 씁니다
잡 job_Ab12Cd34 succeeded (종료 코드 0), 실행 125초, 과금 3분, 금액 $0.1188, 남은 잔액 $19.8812Ctrl+C(SIGINT)나 CI 중단(SIGTERM)을 받으면 접수된 잡을 취소하고 130 또는 143으로 끝납니다
--json의 최종 출력
{"id":"job_Ab12Cd34","status":"succeeded","exit_code":0,"run_seconds":125,"billed_minutes":3,"amount_micro_usd":118800,"amount_usd":"0.118800","balance":{"available_micro_usd":19881200,"available_usd":"19.881200","topup_url":"https://xenoci.com/console/billing"}}실패한 잡은 failure_excerpt(마지막 로그에서 고른 오류 발췌)가 더 붙습니다
옛 임대 모드 옵션(--mac, --runner, --persist, --priority, --pr, --commit, --github-status, --notify 등)은 이 모드에서 쓰지 않으며 주면 사용법 오류입니다
status
xenocast status job_Ab12Cd34GET /v1/jobs/{job_id}의 요약 한 줄(상태, 종료 코드, 실행 초, 과금 분, 금액)을 씁니다. 잔액이 적으면 경고 줄이 표준 오류에 붙습니다. --json이면 잡 객체 전체입니다
| 필드 | 설명 |
|---|---|
id, status, queued_reason, end_reason, exit_code | 상태와 끝난 이유 |
created_at, started_at, ended_at | 접수, 과금 시작, 종료 시각(UTC) |
run_seconds, billed_minutes | 실행 초와 올림한 과금 분 |
rate_micro_usd_per_min, rate_usd_per_min | 잡 시작 때 고정된 분당 요금 |
amount_micro_usd, amount_usd | 금액(실행 중이면 지금까지 확정된 분) |
error | { code, message, retryable, fault, details } |
log_url, repository, source_kind | 로그 경로, 저장소 이름, 출처 |
jobs
xenocast jobs [--status STATUS] [--limit N] [--cursor CURSOR]GET /v1/jobs로 최신순 목록을 JSON으로 냅니다. --limit는 1~100(기본 20), 다음 페이지는 응답의 next_cursor를 --cursor에 넘깁니다. --status는 queued, preparing, running, succeeded, failed, cancelled, credit_exhausted, platform_error, timed_out 중 하나입니다
logs
xenocast logs job_Ab12Cd34
xenocast logs job_Ab12Cd34 --wait
xenocast logs job_Ab12Cd34 --tail 200
xenocast logs job_Ab12Cd34 --failure- 옵션 없이: 지금까지의 로그 전체를 표준 출력에 씁니다
--wait: 끝날 때까지 따라가며 출력하고, 끝나면 요약 줄을 쓰고 잡의 종료 코드로 끝납니다--tail N: 마지막 N줄--failure: 오류로 보이는 부분만 발췌
로그는 GET /v1/jobs/{job_id}/logs?offset=으로 받고 잡당 5MB까지 보관합니다
cancel
xenocast cancel job_Ab12Cd34대기 중이거나 실행 중인 잡을 멈추고 바뀐 잡 객체를 출력합니다. 이미 시작한 분까지는 과금됩니다. 이미 취소된 잡을 다시 취소하면 그대로 잡을 돌려줍니다
wait
xenocast wait job_Ab12Cd34 [--timeout SECONDS]잡이 끝날 때까지 2초 간격으로 확인합니다. --timeout(기본 60초) 안에 끝나지 않으면 잡 객체를 출력하고 종료 코드 124로 끝납니다. 끝났으면 요약 줄을 쓰고 잡의 종료 코드를 돌려줍니다
xenocast wait job_Ab12Cd34 --timeout 1800 && ./deploy.shartifacts
xenocast artifacts job_Ab12Cd34
xenocast artifacts job_Ab12Cd34 --out ./dist- 옵션 없이:
GET /v1/jobs/{job_id}/artifacts목록(id,name,path,bytes,sha256,expires_at)을 JSON으로 출력 --out DIR: 각 결과물을 받아DIR/<이름>에 저장하고[xenocast] App.ipa 12.3MB → ./dist를 표준 오류에 씁니다
mcp
xenocast mcp표준 입출력 MCP 서버를 띄웁니다. 같은 키 규칙을 쓰고 설정 파일에 키를 넣지 않아도 됩니다. 도구와 등록 방법은 MCP 서버에 있습니다
종료 코드
| 코드 | 뜻 |
|---|---|
| 0 | 성공. build, logs --wait, wait에서는 잡의 스크립트가 0으로 끝남 |
| 1 | 실패. 잡은 스크립트의 종료 코드를 그대로 쓰고, 코드가 없으면 1 |
| 2 | 사용법 오류, 키 없음(api_key_required), 키 형식 오류, 이 모드에서 쓰지 않는 명령(api_key_mode, runner2_unsupported) |
| 3 | 잔액과 한도: insufficient_credit, credit_exhausted, workspace_spend_limit, tier_monthly_limit, tier_concurrency_limit |
| 124 | wait가 제한 시간 안에 끝을 보지 못함 |
| 130, 143 | SIGINT, SIGTERM으로 중단(접수된 잡은 취소) |
잔액과 한도 메시지
종료 코드 3일 때 표준 오류에 한국어 한 줄과 충전 링크가 나옵니다
| 코드 | HTTP | 메시지 |
|---|---|---|
insufficient_credit | 402 | 잔액이 부족해 잡을 시작하지 않았습니다 (사용 가능 $…, 1분 요금 $…). 충전: … |
credit_exhausted | 잡 end_reason | 잔액이 바닥나 실행 중인 잡을 분 경계에서 멈췄습니다 (남은 잔액 $…). 충전: … |
workspace_spend_limit | 402 | 워크스페이스의 이번 달 지출 한도에 닿아 잡을 시작하지 않았습니다 (사용 $… / 한도 $…). 소유자나 관리자가 콘솔에서 한도를 올릴 수 있습니다 |
tier_monthly_limit | 402 | 조직 티어의 월 사용 한도에 닿아 잡을 시작하지 않았습니다. 매달 1일 00:00 UTC나 티어가 오르면 다시 열립니다 |
tier_concurrency_limit | 429 | 동시 실행 한도에 닿았고 대기열도 가득 찼습니다. N초 뒤 다시 시도하세요 |
--json에서는 {"error":{"code":"insufficient_credit","message":"<한국어 한 줄>","retryable":false,"topup_url":"…","next_action":"…"}} 형식입니다