From ee5995ae16a9fa5a7a350c53f07243710bd1d6fe Mon Sep 17 00:00:00 2001 From: gavrielc Date: Tue, 21 Apr 2026 17:38:43 +0300 Subject: [PATCH] feat(setup): add register-claude-token.sh MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Bash helper that registers an Anthropic credential in OneCLI via three paths: Claude subscription (runs `claude setup-token` under script(1) for PTY capture), paste an existing sk-ant-oat… OAuth token, or paste an sk-ant-api… API key. On bash 4+ the `claude setup-token` command is pre-filled in the readline buffer so Enter submits it. On bash 3.2 (macOS default /bin/bash) we fall back to a plain confirmation prompt. Token extraction strips ANSI + TTY-wrap line breaks and anchors on sk-ant-oat…AA with a length cap (via perl; BSD grep caps {n,m} at 255). Co-Authored-By: Claude Opus 4.7 (1M context) --- setup/register-claude-token.sh | 127 +++++++++++++++++++++++++++++++++ 1 file changed, 127 insertions(+) create mode 100755 setup/register-claude-token.sh diff --git a/setup/register-claude-token.sh b/setup/register-claude-token.sh new file mode 100755 index 000000000..2c0860d2d --- /dev/null +++ b/setup/register-claude-token.sh @@ -0,0 +1,127 @@ +#!/usr/bin/env bash +set -euo pipefail + +# Prefer bash 4+ (for `read -e -i` readline preload). macOS ships 3.2 in +# /bin/bash, but Homebrew users usually have 5.x first on PATH. The readline +# preload is optional — on 3.x we fall back to a plain confirmation prompt. + +# Register an Anthropic credential with OneCLI. Three paths: +# 1) Claude subscription — run `claude setup-token` (browser sign-in) +# and capture the resulting OAuth token. +# 2) Paste an existing sk-ant-oat… OAuth token you already have. +# 3) Paste an Anthropic API key (sk-ant-api…). +# +# Env overrides: +# SECRET_NAME OneCLI secret name (default: Anthropic) +# HOST_PATTERN OneCLI host pattern (default: api.anthropic.com) + +SECRET_NAME="${SECRET_NAME:-Anthropic}" +HOST_PATTERN="${HOST_PATTERN:-api.anthropic.com}" + +command -v onecli >/dev/null \ + || { echo "onecli not found. Install it first (see /setup §4)." >&2; exit 1; } + +TOKEN="" + +capture_via_claude_setup_token() { + command -v claude >/dev/null \ + || { echo "claude CLI not found. Install from https://claude.ai/download" >&2; exit 1; } + command -v script >/dev/null \ + || { echo "script(1) is required for PTY capture." >&2; exit 1; } + + local tmpfile + tmpfile=$(mktemp -t claude-setup-token.XXXXXX) + trap 'rm -f "$tmpfile"' RETURN + + cat <<'EOF' +A browser window will open for sign-in. Token is captured automatically. +Press Enter to run, or edit the command first. + +EOF + + local cmd="claude setup-token" + if [[ ${BASH_VERSINFO[0]:-0} -ge 4 ]]; then + # bash 4+: pre-fill the readline buffer so Enter literally submits. + read -r -e -i "$cmd" -p "$ " cmd /dev/null | grep -q util-linux; then + script -q -c "$cmd" "$tmpfile" + else + # BSD script: command is argv after the file, so let it word-split. + # shellcheck disable=SC2086 + script -q "$tmpfile" $cmd + fi + + # Strip ANSI codes + newlines (TTY wraps the token mid-string), then match + # the sk-ant-oat…AA token. perl because BSD grep caps {n,m} at 255. + TOKEN=$(sed $'s/\x1b\\[[0-9;]*[a-zA-Z]//g' "$tmpfile" \ + | tr -d '\n\r' \ + | perl -ne 'print "$1\n" while /(sk-ant-oat[A-Za-z0-9_-]{80,500}AA)/g' \ + | tail -1 || true) + + if [[ -z "$TOKEN" ]]; then + local keep + keep=$(mktemp -t claude-setup-token-log.XXXXXX) + cp "$tmpfile" "$keep" + echo >&2 + echo "No sk-ant-oat…AA token found. Raw log: $keep" >&2 + exit 1 + fi +} + +prompt_for_pasted() { + local prefix="$1" # "oat" or "api" + local value + echo + echo "Paste your sk-ant-${prefix}… credential and press Enter." + echo "(Input is hidden for safety.)" + read -r -s -p "> " value &2 + exit 1 + fi + if [[ ! "$value" =~ ^sk-ant-${prefix} ]]; then + echo "Value does not start with sk-ant-${prefix}. Aborting." >&2 + exit 1 + fi + TOKEN="$value" +} + +cat <&2; exit 1 ;; +esac + +echo +echo "Got token: ${TOKEN:0:16}…${TOKEN: -4}" +echo "Registering with OneCLI as '$SECRET_NAME' (host pattern: $HOST_PATTERN)…" + +onecli secrets create \ + --name "$SECRET_NAME" \ + --type anthropic \ + --value "$TOKEN" \ + --host-pattern "$HOST_PATTERN" + +echo "Done."