From 888f3014b42ff48f597d0a81e9f52104d19be6db Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Sat, 21 Mar 2026 21:23:42 +0000 Subject: feat: Phase 2 — project registry, legacy field cleanup, credential path fix MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - task.Project type + storage CRUD + UpsertProject + SeedProjects - Remove AgentConfig.ProjectDir, RepositoryURL, SkipPlanning - Remove ContainerRunner fallback git init logic - Project API endpoints: GET/POST /api/projects, GET/PUT /api/projects/{id} - processResult no longer extracts changestats (pool-side only) - claude_config_dir config field; default to credentials/claude/ - New scripts: sync-credentials, fix-permissions, check-token Co-Authored-By: Claude Sonnet 4.6 --- scripts/check-token | 78 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 scripts/check-token (limited to 'scripts/check-token') diff --git a/scripts/check-token b/scripts/check-token new file mode 100644 index 0000000..40a3116 --- /dev/null +++ b/scripts/check-token @@ -0,0 +1,78 @@ +#!/usr/bin/env bash +# check-token: Verify Claude OAuth token is valid against the Anthropic API. +# Usage: check-token [--refresh] [--retry-task ] +# --refresh re-authenticate via claude CLI if token is bad +# --retry-task after a successful token check/refresh, retry that task +# +# Exit codes: 0=valid, 1=expired/invalid, 2=credentials file missing + +set -euo pipefail + +CREDS="/root/.claude/.credentials.json" +REFRESH=0 +RETRY_TASK="" + +while [[ $# -gt 0 ]]; do + case "$1" in + --refresh) REFRESH=1; shift ;; + --retry-task) RETRY_TASK="$2"; shift 2 ;; + *) echo "Unknown arg: $1" >&2; exit 2 ;; + esac +done + +if [[ ! -f "$CREDS" ]]; then + echo "ERROR: credentials file not found: $CREDS" >&2 + exit 2 +fi + +ACCESS_TOKEN=$(python3 -c " +import json, sys +d = json.load(open('$CREDS')) +tok = d.get('claudeAiOauth', {}).get('accessToken', '') +if not tok: + print('MISSING', file=sys.stderr) + sys.exit(1) +print(tok) +") + +# Test token against the API with a minimal request +HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" \ + -X POST https://api.anthropic.com/v1/messages \ + -H "anthropic-version: 2023-06-01" \ + -H "anthropic-beta: oauth-2025-04-20" \ + -H "Authorization: Bearer $ACCESS_TOKEN" \ + -H "Content-Type: application/json" \ + -d '{"model":"claude-haiku-4-5-20251001","max_tokens":1,"messages":[{"role":"user","content":"hi"}]}') + +if [[ "$HTTP_STATUS" == "200" ]]; then + echo "OK: token is valid (HTTP $HTTP_STATUS)" + if [[ -n "$RETRY_TASK" ]]; then + /workspace/claudomator/scripts/ct-task "$RETRY_TASK" retry + fi + exit 0 +elif [[ "$HTTP_STATUS" == "401" ]]; then + echo "EXPIRED: token rejected by API (HTTP 401)" + if [[ "$REFRESH" == "1" ]]; then + echo "Re-authenticating via claude CLI..." + claude --dangerously-skip-permissions /dev/null 2>&1 || true + # Check if creds were updated + NEW_TOKEN=$(python3 -c "import json; print(json.load(open('$CREDS')).get('claudeAiOauth',{}).get('accessToken',''))") + if [[ "$NEW_TOKEN" != "$ACCESS_TOKEN" ]]; then + echo "New token obtained. Syncing credentials..." + /workspace/claudomator/scripts/sync-credentials + if [[ -n "$RETRY_TASK" ]]; then + /workspace/claudomator/scripts/ct-task "$RETRY_TASK" retry + fi + exit 0 + else + echo "Token unchanged — manual re-auth required: run 'claude' in a terminal" >&2 + exit 1 + fi + else + echo "Run: check-token --refresh or re-authenticate via 'claude'" >&2 + exit 1 + fi +else + echo "WARN: unexpected HTTP $HTTP_STATUS from API (token may still be valid)" + exit 1 +fi -- cgit v1.2.3