diff --git a/action.yml b/action.yml index 51f1987..0a325e9 100644 --- a/action.yml +++ b/action.yml @@ -52,42 +52,6 @@ runs: - name: 取得登入帳號 id: account run: | - cat > "$RUNNER_TEMP/codex_account.py" <<'PY' - import json, subprocess, time - - p = subprocess.Popen( - ["codex", "app-server"], - stdin=subprocess.PIPE, stdout=subprocess.PIPE, - stderr=subprocess.DEVNULL, text=True, bufsize=1, - ) - - def send(obj): - p.stdin.write(json.dumps(obj) + "\n") - p.stdin.flush() - - send({"jsonrpc": "2.0", "id": 1, "method": "initialize", - "params": {"clientInfo": {"name": "ci", "version": "1.0"}}}) - send({"jsonrpc": "2.0", "method": "initialized", "params": {}}) - send({"jsonrpc": "2.0", "id": 2, "method": "account/read", "params": {}}) - - email = "" - deadline = time.time() + 25 - while time.time() < deadline: - line = p.stdout.readline() - if not line: - break - try: - msg = json.loads(line) - except Exception: - continue - if msg.get("id") == 2: - account = (msg.get("result") or {}).get("account") or {} - email = account.get("email") or "" - break - - p.terminate() - print(email) - PY - email="$(python3 "$RUNNER_TEMP/codex_account.py")" + email="$(python3 "$GITHUB_ACTION_PATH/app/codex_account.py")" printf 'email=%s\n' "$email" >> "$GITHUB_OUTPUT" shell: bash diff --git a/app/codex_account.py b/app/codex_account.py new file mode 100644 index 0000000..10f5648 --- /dev/null +++ b/app/codex_account.py @@ -0,0 +1,57 @@ +"""透過 codex app-server 的 JSON-RPC account/read 取得目前登入帳號的 email。 + +這是 TUI `/status` Account 欄位的程式化來源,不解析本地 OAuth token, +而是由 codex 自身回報登入帳號。將 email 印到 stdout(取不到時印空字串)。 +""" + +import json +import subprocess +import time + + +def read_account_email(timeout_seconds: float = 25.0) -> str: + process = subprocess.Popen( + ["codex", "app-server"], + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.DEVNULL, + text=True, + bufsize=1, + ) + + def send(obj): + process.stdin.write(json.dumps(obj) + "\n") + process.stdin.flush() + + send({ + "jsonrpc": "2.0", + "id": 1, + "method": "initialize", + "params": {"clientInfo": {"name": "ci", "version": "1.0"}}, + }) + send({"jsonrpc": "2.0", "method": "initialized", "params": {}}) + send({"jsonrpc": "2.0", "id": 2, "method": "account/read", "params": {}}) + + email = "" + deadline = time.time() + timeout_seconds + try: + while time.time() < deadline: + line = process.stdout.readline() + if not line: + break + try: + message = json.loads(line) + except ValueError: + continue + if message.get("id") == 2: + account = (message.get("result") or {}).get("account") or {} + email = account.get("email") or "" + break + finally: + process.terminate() + + return email + + +if __name__ == "__main__": + print(read_account_email())