claude-credentials-path.ts is imported by token-refresh/claude-usage/ agent-runner-environment/runtime-inventory; committed tree already depends on it. claude_relogin.sh is referenced by token-refresh.ts as the manual recovery step; codex_relogin.sh mirrors the Codex re-auth runbook. Drop stray empty .codex file. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
96 lines
4.0 KiB
Bash
Executable File
96 lines
4.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# codex_relogin.sh — Codex(ChatGPT) 계정을 device-code OAuth 로 재로그인한다.
|
|
#
|
|
# 사용법:
|
|
# ./codex_relogin.sh # 기본 슬롯(0) 재로그인
|
|
# ./codex_relogin.sh 1 # ~/.codex-accounts/1 슬롯 재로그인
|
|
#
|
|
# 참고:
|
|
# * Codex 로그인은 이 호스트에서 두 봇(EJClaw / KAClaw)이 "공유"한다.
|
|
# 계정 저장 위치가 폴더별이 아니라 ~/.codex-accounts/{n} 이기 때문.
|
|
# → 한 번만 재로그인하면 두 봇 모두에 반영된다.
|
|
# * codex CLI 가 URL + 일회용 코드를 출력한다(15분 유효). 브라우저에서
|
|
# 로그인/코드입력을 마치면 codex 가 auth.json 을 자동 저장한다.
|
|
#
|
|
set -euo pipefail
|
|
|
|
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
cd "$DIR"
|
|
|
|
# --- codex 실행 파일 찾기 --------------------------------------------------
|
|
CODEX="$(command -v codex 2>/dev/null || true)"
|
|
if [ -z "$CODEX" ]; then
|
|
# fnm 로 설치된 node 전역 bin 에서 탐색
|
|
for c in "$HOME"/.local/share/fnm/node-versions/*/installation/bin/codex; do
|
|
[ -x "$c" ] && CODEX="$c" && break
|
|
done
|
|
fi
|
|
if [ -z "$CODEX" ]; then
|
|
echo "❌ codex CLI 를 찾을 수 없습니다. 'command -v codex' 로 확인하세요." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# --- 대상 슬롯 결정 --------------------------------------------------------
|
|
# 앱은 ~/.codex-accounts/{n}/auth.json 를 읽는다. 없으면 ~/.codex 로 폴백.
|
|
SLOT="${1:-0}"
|
|
ACCOUNTS_DIR="$HOME/.codex-accounts"
|
|
if [ -d "$ACCOUNTS_DIR/$SLOT" ]; then
|
|
CODEX_TARGET="$ACCOUNTS_DIR/$SLOT"
|
|
elif [ -d "$ACCOUNTS_DIR" ] && ls -d "$ACCOUNTS_DIR"/[0-9]* >/dev/null 2>&1; then
|
|
echo "❌ 슬롯 '$SLOT' 이(가) 없습니다. 사용 가능한 슬롯:" >&2
|
|
ls -d "$ACCOUNTS_DIR"/[0-9]* 2>/dev/null | sed 's#.*/# - #' >&2
|
|
exit 1
|
|
else
|
|
# accounts 디렉터리가 비어있으면 기본 codex home 사용
|
|
CODEX_TARGET="$HOME/.codex"
|
|
fi
|
|
export CODEX_HOME="$CODEX_TARGET"
|
|
|
|
# --- 서비스명 자동 감지 (폴더명 소문자 + .service) -------------------------
|
|
SERVICE="$(basename "$DIR" | tr '[:upper:]' '[:lower:]').service"
|
|
|
|
echo "======================================================================"
|
|
echo " Codex 재로그인 (device-code OAuth)"
|
|
echo " codex : $CODEX"
|
|
echo " CODEX_HOME : $CODEX_HOME (auth.json 저장 위치)"
|
|
echo " 서비스 : $SERVICE"
|
|
echo " ※ Codex 로그인은 EJClaw/KAClaw 두 봇이 공유합니다."
|
|
echo "======================================================================"
|
|
echo
|
|
echo "▶ 아래 안내대로 브라우저에서 URL 을 열고 표시되는 코드를 입력하세요."
|
|
echo " (로그인이 끝나면 자동으로 저장되고 이 창이 넘어갑니다.)"
|
|
echo "----------------------------------------------------------------------"
|
|
|
|
# --- 로그인 실행 (codex 가 URL/코드 출력 + 폴링까지 담당) ------------------
|
|
if "$CODEX" login --device-auth; then
|
|
echo "----------------------------------------------------------------------"
|
|
echo "✅ Codex 로그인 성공 — auth.json 저장: $CODEX_HOME/auth.json"
|
|
else
|
|
echo "----------------------------------------------------------------------"
|
|
echo "❌ Codex 로그인 실패 또는 취소됨. 다시 실행해 시도하세요." >&2
|
|
exit 1
|
|
fi
|
|
|
|
# --- 상태 확인 -------------------------------------------------------------
|
|
echo
|
|
echo "▶ 로그인 상태 확인:"
|
|
"$CODEX" login status 2>&1 | sed 's/^/ /' || true
|
|
|
|
# --- 서비스 재시작 ---------------------------------------------------------
|
|
echo
|
|
echo "▶ $SERVICE 재시작..."
|
|
if systemctl --user restart "$SERVICE" 2>/dev/null; then
|
|
sleep 1
|
|
STATE="$(systemctl --user is-active "$SERVICE" 2>/dev/null || true)"
|
|
echo "✅ $SERVICE 상태: $STATE"
|
|
echo " (공유 계정이므로 다른 봇도 새 로그인을 사용합니다. 필요하면"
|
|
echo " 상대 봇도 재시작하세요: systemctl --user restart <다른서비스>)"
|
|
else
|
|
echo "⚠ $SERVICE 재시작 건너뜀(서비스 없음/권한 없음). 수동 재시작:" >&2
|
|
echo " systemctl --user restart $SERVICE" >&2
|
|
fi
|
|
|
|
echo
|
|
echo "완료. 🎉"
|