@@ -122,7 +122,10 @@ if [[ "$CLI_PROVIDER" == "claude-cli" && "$CLI_AUTH_MODE" == "subscription" ]];
122122 CLAUDE_CREDS_FILE=" $HOME /.claude/.credentials.json"
123123 CLAUDE_SUBSCRIPTION_AUTH_SOURCE=" "
124124 CLAUDE_SUBSCRIPTION_TYPE=" "
125- if [[ -f " $CLAUDE_CREDS_FILE " ]]; then
125+ if [[ -n " ${CLAUDE_CODE_OAUTH_TOKEN:- } " ]]; then
126+ CLAUDE_SUBSCRIPTION_TYPE=" oauth-token"
127+ CLAUDE_SUBSCRIPTION_AUTH_SOURCE=" env-token"
128+ elif [[ -f " $CLAUDE_CREDS_FILE " ]]; then
126129 CLAUDE_SUBSCRIPTION_TYPE=" $(
127130 node -e '
128131 const fs = require("node:fs");
@@ -138,9 +141,6 @@ if [[ "$CLI_PROVIDER" == "claude-cli" && "$CLI_AUTH_MODE" == "subscription" ]];
138141 exit 1
139142 }
140143 CLAUDE_SUBSCRIPTION_AUTH_SOURCE=" credentials-file"
141- elif [[ -n " ${CLAUDE_CODE_OAUTH_TOKEN:- } " ]]; then
142- CLAUDE_SUBSCRIPTION_TYPE=" oauth-token"
143- CLAUDE_SUBSCRIPTION_AUTH_SOURCE=" env-token"
144144 else
145145 echo " ERROR: Claude subscription auth requires either:" >&2
146146 echo " - $CLAUDE_CREDS_FILE with claudeAiOauth.subscriptionType, or" >&2
@@ -200,6 +200,16 @@ else
200200 AUTH_FILES+=(" $auth_file " )
201201 done < <( openclaw_live_collect_auth_files_from_csv " $CLI_PROVIDER " )
202202fi
203+ if [[ " ${CLAUDE_SUBSCRIPTION_AUTH_SOURCE:- } " == " env-token" ]]; then
204+ retained_auth_files=()
205+ for auth_file in " ${AUTH_FILES[@]} " ; do
206+ case " $auth_file " in
207+ .claude.json | .claude/.credentials.json) ;;
208+ * ) retained_auth_files+=(" $auth_file " ) ;;
209+ esac
210+ done
211+ AUTH_FILES=(" ${retained_auth_files[@]} " )
212+ fi
203213AUTH_DIRS_CSV=" "
204214if (( ${# AUTH_DIRS[@]} > 0 )) ; then
205215 AUTH_DIRS_CSV=" $( openclaw_live_join_csv " ${AUTH_DIRS[@]} " ) "
@@ -327,15 +337,15 @@ if [ "$provider" = "claude-cli" ]; then
327337 node - <<'NODE'
328338const fs = require("node:fs");
329339const file = `${process.env.HOME}/.claude/.credentials.json`;
330- if (fs.existsSync(file)) {
340+ if (process.env.CLAUDE_CODE_OAUTH_TOKEN?.trim()) {
341+ console.error("[claude-subscription] using CLAUDE_CODE_OAUTH_TOKEN from environment");
342+ } else if (fs.existsSync(file)) {
331343 const data = JSON.parse(fs.readFileSync(file, "utf8"));
332344 const subscriptionType = String(data?.claudeAiOauth?.subscriptionType ?? "").trim();
333345 if (!subscriptionType || subscriptionType === "unknown") {
334346 throw new Error("Claude subscription OAuth credentials are missing subscriptionType.");
335347 }
336348 console.error(`[claude-subscription] subscriptionType=${subscriptionType}`);
337- } else if (process.env.CLAUDE_CODE_OAUTH_TOKEN?.trim()) {
338- console.error("[claude-subscription] using CLAUDE_CODE_OAUTH_TOKEN from environment");
339349} else {
340350 throw new Error("Claude subscription OAuth token or credentials file is required.");
341351}
@@ -365,17 +375,30 @@ WRAP
365375 if [ "$auth_mode" = "subscription" ]; then
366376 claude --version
367377 direct_token="OPENCLAW-CLAUDE-SUBSCRIPTION-DIRECT"
368- direct_output="$(
369- claude \
370- -p "Reply exactly: $direct_token" \
371- --output-format text \
372- --model sonnet \
373- --permission-mode bypassPermissions \
374- --setting-sources user \
375- --strict-mcp-config \
376- --mcp-config '{"mcpServers":{}}' \
377- --no-session-persistence
378- )"
378+ direct_probe_log="$(mktemp)"
379+ set +e
380+ claude \
381+ -p "Reply exactly: $direct_token" \
382+ --output-format text \
383+ --model sonnet \
384+ --permission-mode bypassPermissions \
385+ --setting-sources user \
386+ --strict-mcp-config \
387+ --mcp-config '{"mcpServers":{}}' \
388+ --no-session-persistence >"$direct_probe_log" 2>&1
389+ direct_probe_status=$?
390+ set -e
391+ direct_output="$(<"$direct_probe_log")"
392+ if [ "$direct_probe_status" -ne 0 ]; then
393+ echo "ERROR: direct Claude subscription probe exited with status $direct_probe_status." >&2
394+ sed -E \
395+ -e 's/[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}/<redacted-email>/g' \
396+ -e 's/(sk-ant-|sk-)[A-Za-z0-9_-]+/<redacted-secret>/g' \
397+ "$direct_probe_log" >&2
398+ rm -f "$direct_probe_log"
399+ exit "$direct_probe_status"
400+ fi
401+ rm -f "$direct_probe_log"
379402 if [[ "$direct_output" != *"$direct_token"* ]]; then
380403 echo "ERROR: direct Claude subscription probe did not return expected token." >&2
381404 echo "$direct_output" >&2
0 commit comments