Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/recap-claude-oauth-token.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@agent-native/recap-cli": minor
"@agent-native/core": patch
---

Accept `CLAUDE_CODE_OAUTH_TOKEN` as an alternative to `ANTHROPIC_API_KEY` for the PR visual recap claude backend, so recaps can bill a Claude subscription instead of API credits. `recapRequiredSecrets` now returns interchangeable secret names, and `recap setup` / `recap doctor` accept either credential.
12 changes: 11 additions & 1 deletion .github/workflows/pr-visual-recap-fork.yml
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ jobs:
# Presence-only signals — never expose secret VALUES to the gate.
HAS_PLAN: ${{ secrets.PLAN_RECAP_TOKEN != '' }}
HAS_ANTHROPIC: ${{ secrets.ANTHROPIC_API_KEY != '' }}
HAS_CLAUDE_OAUTH: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN != '' }}
HAS_OPENAI: ${{ secrets.OPENAI_API_KEY != '' }}
HAS_COMPATIBLE: ${{ secrets.VISUAL_RECAP_API_KEY != '' }}
AGENT: ${{ env.VISUAL_RECAP_AGENT }}
Expand Down Expand Up @@ -196,7 +197,7 @@ jobs:
} else if (agent === 'codex') {
if (process.env.HAS_OPENAI !== 'true') reasons.push('OPENAI_API_KEY not configured (codex backend)');
} else if (agent === 'claude') {
if (process.env.HAS_ANTHROPIC !== 'true') reasons.push('ANTHROPIC_API_KEY not configured (claude backend)');
if (process.env.HAS_ANTHROPIC !== 'true' && process.env.HAS_CLAUDE_OAUTH !== 'true') reasons.push('neither ANTHROPIC_API_KEY nor CLAUDE_CODE_OAUTH_TOKEN configured (claude backend)');
} else {
if (process.env.HAS_COMPATIBLE !== 'true') reasons.push('VISUAL_RECAP_API_KEY not configured (openai-compatible backend)');
if (!(process.env.VISUAL_RECAP_MODEL || '').trim()) reasons.push('VISUAL_RECAP_MODEL is required (openai-compatible backend)');
Expand Down Expand Up @@ -579,8 +580,14 @@ jobs:
continue-on-error: true
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
run: |
set -uo pipefail
# A secret the repo never configured still arrives here as an empty
# env var. Drop those so the CLI picks the credential that is actually
# set instead of treating an empty one as the chosen auth path.
[ -n "${ANTHROPIC_API_KEY:-}" ] || unset ANTHROPIC_API_KEY
[ -n "${CLAUDE_CODE_OAUTH_TOKEN:-}" ] || unset CLAUDE_CODE_OAUTH_TOKEN
CLAUDE_ALLOWED_TOOLS="Read,Write,Bash(git diff:*)"
CLAUDE_ARGS=(-p "$(cat recap-prompt.md)" --allowedTools "$CLAUDE_ALLOWED_TOOLS" --permission-mode dontAsk --output-format json)
CLAUDE_ARGS+=(--model "${VISUAL_RECAP_MODEL:-claude-sonnet-5}")
Expand Down Expand Up @@ -746,8 +753,11 @@ jobs:
continue-on-error: true
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
run: |
set -uo pipefail
[ -n "${ANTHROPIC_API_KEY:-}" ] || unset ANTHROPIC_API_KEY
[ -n "${CLAUDE_CODE_OAUTH_TOKEN:-}" ] || unset CLAUDE_CODE_OAUTH_TOKEN
CLAUDE_ALLOWED_TOOLS="Read,Write"
CLAUDE_ARGS=(-p "$(cat recap-repair-prompt.md)" --allowedTools "$CLAUDE_ALLOWED_TOOLS" --permission-mode dontAsk --output-format json)
CLAUDE_ARGS+=(--model "${VISUAL_RECAP_MODEL:-claude-sonnet-5}")
Expand Down
20 changes: 19 additions & 1 deletion .github/workflows/pr-visual-recap-reusable.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ name: PR Visual Recap (reusable)
# secrets:
# PLAN_RECAP_TOKEN: ${{ secrets.PLAN_RECAP_TOKEN }}
# ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
# # …or bill the claude backend to a Claude subscription instead:
# # CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
#
# IMPORTANT: callers must trigger on the same pull_request event types as this
# file declares in its on.workflow_call section (opened, synchronize, reopened,
Expand Down Expand Up @@ -110,6 +112,12 @@ on:
# Required for the default claude backend; optional when agent=codex.
ANTHROPIC_API_KEY:
required: false
# Alternative to ANTHROPIC_API_KEY for the claude backend: a Claude Code
# subscription OAuth token minted with `claude setup-token`, which bills
# the run to the subscription instead of API credits. Set exactly one —
# with both configured the billing path is whichever the CLI prefers.
CLAUDE_CODE_OAUTH_TOKEN:
required: false
# Required when agent=codex; ignored otherwise.
OPENAI_API_KEY:
required: false
Expand Down Expand Up @@ -152,6 +160,7 @@ jobs:
# Presence-only signals — never expose secret VALUES to the gate.
HAS_PLAN: ${{ secrets.PLAN_RECAP_TOKEN != '' }}
HAS_ANTHROPIC: ${{ secrets.ANTHROPIC_API_KEY != '' }}
HAS_CLAUDE_OAUTH: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN != '' }}
HAS_OPENAI: ${{ secrets.OPENAI_API_KEY != '' }}
HAS_COMPATIBLE: ${{ secrets.VISUAL_RECAP_API_KEY != '' }}
AGENT: ${{ inputs.agent }}
Expand Down Expand Up @@ -230,7 +239,7 @@ jobs:
} else if (agent === 'codex') {
if (process.env.HAS_OPENAI !== 'true') reasons.push('OPENAI_API_KEY not configured (codex backend)');
} else if (agent === 'claude') {
if (process.env.HAS_ANTHROPIC !== 'true') reasons.push('ANTHROPIC_API_KEY not configured (claude backend)');
if (process.env.HAS_ANTHROPIC !== 'true' && process.env.HAS_CLAUDE_OAUTH !== 'true') reasons.push('neither ANTHROPIC_API_KEY nor CLAUDE_CODE_OAUTH_TOKEN configured (claude backend)');
} else {
if (process.env.HAS_COMPATIBLE !== 'true') reasons.push('VISUAL_RECAP_API_KEY not configured (openai-compatible backend)');
if (!(process.env.VISUAL_RECAP_MODEL || '').trim()) reasons.push('VISUAL_RECAP_MODEL is required (openai-compatible backend)');
Expand Down Expand Up @@ -588,8 +597,14 @@ jobs:
continue-on-error: true
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
run: |
set -uo pipefail
# A secret the caller never configured still arrives here as an empty
# env var. Drop those so the CLI picks the credential that is actually
# set instead of treating an empty one as the chosen auth path.
[ -n "${ANTHROPIC_API_KEY:-}" ] || unset ANTHROPIC_API_KEY
[ -n "${CLAUDE_CODE_OAUTH_TOKEN:-}" ] || unset CLAUDE_CODE_OAUTH_TOKEN
CLAUDE_ALLOWED_TOOLS="Read,Write,Bash(git diff:*)"
CLAUDE_ARGS=(-p "$(cat recap-prompt.md)" --allowedTools "$CLAUDE_ALLOWED_TOOLS" --permission-mode dontAsk --output-format json)
CLAUDE_ARGS+=(--model "${VISUAL_RECAP_MODEL:-claude-sonnet-5}")
Expand Down Expand Up @@ -755,8 +770,11 @@ jobs:
continue-on-error: true
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
run: |
set -uo pipefail
[ -n "${ANTHROPIC_API_KEY:-}" ] || unset ANTHROPIC_API_KEY
[ -n "${CLAUDE_CODE_OAUTH_TOKEN:-}" ] || unset CLAUDE_CODE_OAUTH_TOKEN
CLAUDE_ALLOWED_TOOLS="Read,Write"
CLAUDE_ARGS=(-p "$(cat recap-repair-prompt.md)" --allowedTools "$CLAUDE_ALLOWED_TOOLS" --permission-mode dontAsk --output-format json)
CLAUDE_ARGS+=(--model "${VISUAL_RECAP_MODEL:-claude-sonnet-5}")
Expand Down
12 changes: 11 additions & 1 deletion .github/workflows/pr-visual-recap.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ jobs:
# Presence-only signals — never expose secret VALUES to the gate.
HAS_PLAN: ${{ secrets.PLAN_RECAP_TOKEN != '' }}
HAS_ANTHROPIC: ${{ secrets.ANTHROPIC_API_KEY != '' }}
HAS_CLAUDE_OAUTH: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN != '' }}
HAS_OPENAI: ${{ secrets.OPENAI_API_KEY != '' }}
HAS_COMPATIBLE: ${{ secrets.VISUAL_RECAP_API_KEY != '' }}
AGENT: ${{ env.VISUAL_RECAP_AGENT }}
Expand Down Expand Up @@ -125,7 +126,7 @@ jobs:
} else if (agent === 'codex') {
if (process.env.HAS_OPENAI !== 'true') reasons.push('OPENAI_API_KEY not configured (codex backend)');
} else if (agent === 'claude') {
if (process.env.HAS_ANTHROPIC !== 'true') reasons.push('ANTHROPIC_API_KEY not configured (claude backend)');
if (process.env.HAS_ANTHROPIC !== 'true' && process.env.HAS_CLAUDE_OAUTH !== 'true') reasons.push('neither ANTHROPIC_API_KEY nor CLAUDE_CODE_OAUTH_TOKEN configured (claude backend)');
} else {
if (process.env.HAS_COMPATIBLE !== 'true') reasons.push('VISUAL_RECAP_API_KEY not configured (openai-compatible backend)');
if (!(process.env.VISUAL_RECAP_MODEL || '').trim()) reasons.push('VISUAL_RECAP_MODEL is required (openai-compatible backend)');
Expand Down Expand Up @@ -522,8 +523,14 @@ jobs:
continue-on-error: true
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
run: |
set -uo pipefail
# A secret the repo never configured still arrives here as an empty
# env var. Drop those so the CLI picks the credential that is actually
# set instead of treating an empty one as the chosen auth path.
[ -n "${ANTHROPIC_API_KEY:-}" ] || unset ANTHROPIC_API_KEY
[ -n "${CLAUDE_CODE_OAUTH_TOKEN:-}" ] || unset CLAUDE_CODE_OAUTH_TOKEN
CLAUDE_ALLOWED_TOOLS="Read,Write,Bash(git diff:*)"
CLAUDE_ARGS=(-p "$(cat recap-prompt.md)" --allowedTools "$CLAUDE_ALLOWED_TOOLS" --permission-mode dontAsk --output-format json)
CLAUDE_ARGS+=(--model "${VISUAL_RECAP_MODEL:-claude-sonnet-5}")
Expand Down Expand Up @@ -694,8 +701,11 @@ jobs:
continue-on-error: true
env:
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
run: |
set -uo pipefail
[ -n "${ANTHROPIC_API_KEY:-}" ] || unset ANTHROPIC_API_KEY
[ -n "${CLAUDE_CODE_OAUTH_TOKEN:-}" ] || unset CLAUDE_CODE_OAUTH_TOKEN
CLAUDE_ALLOWED_TOOLS="Read,Write"
CLAUDE_ARGS=(-p "$(cat recap-repair-prompt.md)" --allowedTools "$CLAUDE_ALLOWED_TOOLS" --permission-mode dontAsk --output-format json)
CLAUDE_ARGS+=(--model "${VISUAL_RECAP_MODEL:-claude-sonnet-5}")
Expand Down
12 changes: 8 additions & 4 deletions packages/core/docs/content/locales/ar-SA/pr-visual-recap.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ npx @agent-native/recap-cli@latest recap doctor

إذا لم يتم تعيين المتغير، يستخدم الإجراء `claude`.

تصادق واجهة `claude` الخلفية باستخدام أيٍّ من بيانات الاعتماد: يحتسب `ANTHROPIC_API_KEY` تكلفة الرموز على حساب Anthropic API الخاص بك، بينما يحتسب `CLAUDE_CODE_OAUTH_TOKEN` — الذي يُنشأ محليًا بالأمر `claude setup-token` على اشتراك Claude — تكلفة التشغيل على ذلك الاشتراك. عيّن واحدًا فقط؛ فإذا ضُبط كلاهما، فسيعتمد مسار الفوترة على ما تفضّله واجهة Claude Code CLI.

## النموذج والمنطق

خارج الواجهة الخلفية، يوجد متغيران في المستودع يضبطان _كيف_ يعمل الوكيل:
Expand Down Expand Up @@ -190,10 +192,11 @@ npx @agent-native/recap-cli@latest recap doctor

### الأسرار (مطلوب اثنان فقط)

| سرية | الغرض |
| ------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `PLAN_RECAP_TOKEN` | رمز مميز قابل للإلغاء تم سكه بواسطة `npx @agent-native/core@latest connect`. يسمح بنشر خطة الملخّص وتحميل لقطة الشاشة. |
| `ANTHROPIC_API_KEY` | مفتاح LLM للواجهة الخلفية الافتراضية لرمز Claude. |
| سرية | الغرض |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| `PLAN_RECAP_TOKEN` | رمز مميز قابل للإلغاء تم سكه بواسطة `npx @agent-native/core@latest connect`. يسمح بنشر خطة الملخّص وتحميل لقطة الشاشة. |
| `ANTHROPIC_API_KEY` | مفتاح LLM للواجهة الخلفية الافتراضية لرمز Claude. |
| `CLAUDE_CODE_OAUTH_TOKEN` | بديل عن `ANTHROPIC_API_KEY`: رمز اشتراك Claude يُنشأ بالأمر `claude setup-token`. عيّن أحدهما فقط وليس كليهما. |

**الفرق: استخدم رمزًا مميزًا لخدمة المؤسسة.** الرمز المميز الشخصي مرتبط بالشخص
من قام بسكها - إذا تركوا المؤسسة أو أبطلوا رموزهم المميزة، فسيتم استخدام كل عملية إعادة شراء
Expand Down Expand Up @@ -494,6 +497,7 @@ jobs:
secrets:
PLAN_RECAP_TOKEN: ${{ secrets.PLAN_RECAP_TOKEN }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
PLAN_RECAP_APP_URL: ${{ secrets.PLAN_RECAP_APP_URL }}
with:
Expand Down
12 changes: 8 additions & 4 deletions packages/core/docs/content/locales/de-DE/pr-visual-recap.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ Wählen Sie mit der Repository-Variable `VISUAL_RECAP_AGENT` aus, welcher Codier

Wenn die Variable nicht gesetzt ist, verwendet die Aktion `claude`.

Das `claude`-Backend authentifiziert sich mit einem der beiden Anmeldedaten: `ANTHROPIC_API_KEY` rechnet Tokens über Ihr Anthropic-API-Konto ab, während `CLAUDE_CODE_OAUTH_TOKEN` — lokal mit `claude setup-token` auf einem Claude-Abonnement erstellt — den Lauf stattdessen über dieses Abonnement abrechnet. Setzen Sie genau eines; sind beide konfiguriert, entscheidet die Claude-Code-CLI über den Abrechnungsweg.

## Modell und Argumentation

Über das Backend hinaus optimieren zwei Repository-Variablen, _wie_ der Agent ausgeführt wird:
Expand Down Expand Up @@ -190,10 +192,11 @@ Legen Sie diese in den **Einstellungen → Geheimnisse und Variablen → Actions

### Geheimnisse (nur zwei erforderlich)

| Geheimnis | Zweck |
| ------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PLAN_RECAP_TOKEN` | Widerruflicher Token, geprägt von `npx @agent-native/core@latest connect`. Autorisiert die Veröffentlichung des Zusammenfassungsplans und des Screenshot-Uploads. |
| `ANTHROPIC_API_KEY` | Der LLM-Schlüssel für das Standard-Claude-Code-Backend. |
| Geheimnis | Zweck |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `PLAN_RECAP_TOKEN` | Widerruflicher Token, geprägt von `npx @agent-native/core@latest connect`. Autorisiert die Veröffentlichung des Zusammenfassungsplans und des Screenshot-Uploads. |
| `ANTHROPIC_API_KEY` | Der LLM-Schlüssel für das Standard-Claude-Code-Backend. |
| `CLAUDE_CODE_OAUTH_TOKEN` | Alternative zu `ANTHROPIC_API_KEY`: ein Claude-Abonnement-Token aus `claude setup-token`. Setzen Sie das eine oder das andere, nicht beides. |

**Teams: Verwenden Sie ein Organisationsdienst-Token.** Ein persönliches Token ist an die Person gebunden
Wer hat es geprägt – wenn sie die Organisation verlassen oder ihre Token widerrufen, jedes Repo mit
Expand Down Expand Up @@ -494,6 +497,7 @@ jobs:
secrets:
PLAN_RECAP_TOKEN: ${{ secrets.PLAN_RECAP_TOKEN }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
PLAN_RECAP_APP_URL: ${{ secrets.PLAN_RECAP_APP_URL }}
with:
Expand Down
12 changes: 8 additions & 4 deletions packages/core/docs/content/locales/es-ES/pr-visual-recap.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ Elija qué agente de codificación ejecuta la habilidad con la variable de repos

Si la variable no está configurada, la acción utiliza `claude`.

El backend `claude` se autentica con cualquiera de las dos credenciales: `ANTHROPIC_API_KEY` factura los tokens a su cuenta de la API de Anthropic, mientras que `CLAUDE_CODE_OAUTH_TOKEN` —generado localmente con `claude setup-token` en una suscripción de Claude— factura la ejecución a esa suscripción. Configure exactamente una; si ambas están configuradas, la vía de facturación será la que prefiera la CLI de Claude Code.

## Modelo y razonamiento

Más allá del backend, dos variables del repositorio ajustan _cómo_ se ejecuta el agente:
Expand Down Expand Up @@ -190,10 +192,11 @@ Configúrelos en **Configuración → Secretos y variables → Actions** de su r

### Secretos (solo se requieren dos)

| Secreto | Propósito |
| ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `PLAN_RECAP_TOKEN` | Token revocable acuñado por `npx @agent-native/core@latest connect`. Autoriza la publicación del plan de resumen y la carga de la captura de pantalla. |
| `ANTHROPIC_API_KEY` | La clave LLM para el backend predeterminado del código Claude. |
| Secreto | Propósito |
| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `PLAN_RECAP_TOKEN` | Token revocable acuñado por `npx @agent-native/core@latest connect`. Autoriza la publicación del plan de resumen y la carga de la captura de pantalla. |
| `ANTHROPIC_API_KEY` | La clave LLM para el backend predeterminado del código Claude. |
| `CLAUDE_CODE_OAUTH_TOKEN` | Alternativa a `ANTHROPIC_API_KEY`: un token de suscripción de Claude generado con `claude setup-token`. Configure una u otra, no ambas. |

**Equipos: utilice un token de servicio de la organización.** Un token personal está vinculado a la persona
quién lo acuñó: si abandonan la organización o revocan sus tokens, cada repositorio lo usará
Expand Down Expand Up @@ -494,6 +497,7 @@ jobs:
secrets:
PLAN_RECAP_TOKEN: ${{ secrets.PLAN_RECAP_TOKEN }}
ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
CLAUDE_CODE_OAUTH_TOKEN: ${{ secrets.CLAUDE_CODE_OAUTH_TOKEN }}
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
PLAN_RECAP_APP_URL: ${{ secrets.PLAN_RECAP_APP_URL }}
with:
Expand Down
Loading
Loading