Compare commits

...

8 Commits

Author SHA1 Message Date
github-actions[bot]
ad11414def chore(main): release 0.2.1 (#629)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-04-13 00:41:31 +08:00
Jeevan Mohan Pawar
9419e8a4a2 fix(provider): add recovery guidance for missing OpenAI API key (#616) 2026-04-13 00:37:04 +08:00
Kevin Codex
41a86d05fa ci: publish from release events (#628) 2026-04-13 00:33:43 +08:00
Kevin Codex
fa4b6a96c0 Fix/manual publish current release (#627)
* ci: keep manual publish path for current release

* ci: fix trusted publishing metadata
2026-04-13 00:23:00 +08:00
Kevin Codex
d03d77b110 ci: keep manual publish path for current release (#626) 2026-04-13 00:18:43 +08:00
Kevin Codex
15de1d6190 Fix/release please invalid input (#624)
* ci: remove invalid release-please input

* ci: add npm publish debug diagnostics

* ci: allow manual publish of existing release tags
2026-04-12 23:59:19 +08:00
Kevin Codex
812facf024 Fix/release please invalid input (#622)
* ci: remove invalid release-please input

* ci: add npm publish debug diagnostics
2026-04-12 23:33:22 +08:00
Kevin Codex
2e39d2607a Fix/release please invalid input (#620)
* ci: remove invalid release-please input

* ci: add npm publish debug diagnostics
2026-04-12 23:24:39 +08:00
6 changed files with 61 additions and 11 deletions

View File

@@ -4,6 +4,9 @@ on:
push: push:
branches: branches:
- main - main
release:
types:
- published
concurrency: concurrency:
group: auto-release-${{ github.ref }} group: auto-release-${{ github.ref }}
@@ -12,6 +15,7 @@ concurrency:
jobs: jobs:
release-please: release-please:
name: Release Please name: Release Please
if: ${{ github.event_name == 'push' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
permissions: permissions:
contents: write contents: write
@@ -30,8 +34,7 @@ jobs:
publish-npm: publish-npm:
name: Publish to npm name: Publish to npm
needs: release-please if: ${{ github.event_name == 'release' }}
if: ${{ needs.release-please.outputs.release_created == 'true' }}
runs-on: ubuntu-latest runs-on: ubuntu-latest
environment: release environment: release
permissions: permissions:
@@ -41,13 +44,13 @@ jobs:
- name: Checkout release tag - name: Checkout release tag
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with: with:
ref: ${{ needs.release-please.outputs.tag_name }} ref: ${{ github.event.release.tag_name }}
fetch-depth: 0 fetch-depth: 0
- name: Set up Node.js - name: Set up Node.js
uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020
with: with:
node-version: 20 node-version: 24
registry-url: https://registry.npmjs.org registry-url: https://registry.npmjs.org
- name: Set up Bun - name: Set up Bun
@@ -70,14 +73,19 @@ jobs:
- name: Dry-run package - name: Dry-run package
run: npm pack --dry-run run: npm pack --dry-run
- name: Clear token auth for trusted publishing
run: |
unset NODE_AUTH_TOKEN
echo "NODE_AUTH_TOKEN=" >> "$GITHUB_ENV"
- name: Publish to npm - name: Publish to npm
run: npm publish --access public --provenance run: npm publish --access public --provenance
- name: Release summary - name: Release summary
run: | run: |
{ {
echo "## Released ${{ needs.release-please.outputs.tag_name }}" echo "## Released ${{ github.event.release.tag_name }}"
echo echo
echo "- npm: https://www.npmjs.com/package/@gitlawb/openclaude" echo "- npm: https://www.npmjs.com/package/@gitlawb/openclaude"
echo "- GitHub: https://github.com/Gitlawb/openclaude/releases/tag/${{ needs.release-please.outputs.tag_name }}" echo "- GitHub: https://github.com/Gitlawb/openclaude/releases/tag/${{ github.event.release.tag_name }}"
} >> "$GITHUB_STEP_SUMMARY" } >> "$GITHUB_STEP_SUMMARY"

View File

@@ -1,3 +1,3 @@
{ {
".": "0.2.0" ".": "0.2.1"
} }

View File

@@ -1,5 +1,12 @@
# Changelog # Changelog
## [0.2.1](https://github.com/Gitlawb/openclaude/compare/v0.2.0...v0.2.1) (2026-04-12)
### Bug Fixes
* **provider:** add recovery guidance for missing OpenAI API key ([#616](https://github.com/Gitlawb/openclaude/issues/616)) ([9419e8a](https://github.com/Gitlawb/openclaude/commit/9419e8a4a21b3771d9ddb10f7072e0a8c5b5b631))
## [0.2.0](https://github.com/Gitlawb/openclaude/compare/v0.1.8...v0.2.0) (2026-04-12) ## [0.2.0](https://github.com/Gitlawb/openclaude/compare/v0.1.8...v0.2.0) (2026-04-12)

View File

@@ -1,6 +1,6 @@
{ {
"name": "@gitlawb/openclaude", "name": "@gitlawb/openclaude",
"version": "0.2.0", "version": "0.2.1",
"description": "Claude Code opened to any LLM — OpenAI, Gemini, DeepSeek, Ollama, and 200+ models", "description": "Claude Code opened to any LLM — OpenAI, Gemini, DeepSeek, Ollama, and 200+ models",
"type": "module", "type": "module",
"bin": { "bin": {
@@ -140,7 +140,7 @@
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://gitlawb.com/z6MkqDnb7Siv3Cwj7pGJq4T5EsUisECqR8KpnDLwcaZq5TPr/openclaude" "url": "https://github.com/Gitlawb/openclaude.git"
}, },
"keywords": [ "keywords": [
"claude-code", "claude-code",

View File

@@ -3,6 +3,9 @@ import { afterEach, expect, test } from 'bun:test'
import { getProviderValidationError } from './providerValidation.ts' import { getProviderValidationError } from './providerValidation.ts'
const originalEnv = { const originalEnv = {
CLAUDE_CODE_USE_OPENAI: process.env.CLAUDE_CODE_USE_OPENAI,
OPENAI_API_KEY: process.env.OPENAI_API_KEY,
OPENAI_BASE_URL: process.env.OPENAI_BASE_URL,
CLAUDE_CODE_USE_GEMINI: process.env.CLAUDE_CODE_USE_GEMINI, CLAUDE_CODE_USE_GEMINI: process.env.CLAUDE_CODE_USE_GEMINI,
GEMINI_API_KEY: process.env.GEMINI_API_KEY, GEMINI_API_KEY: process.env.GEMINI_API_KEY,
GOOGLE_API_KEY: process.env.GOOGLE_API_KEY, GOOGLE_API_KEY: process.env.GOOGLE_API_KEY,
@@ -20,6 +23,9 @@ function restoreEnv(key: string, value: string | undefined): void {
} }
afterEach(() => { afterEach(() => {
restoreEnv('CLAUDE_CODE_USE_OPENAI', originalEnv.CLAUDE_CODE_USE_OPENAI)
restoreEnv('OPENAI_API_KEY', originalEnv.OPENAI_API_KEY)
restoreEnv('OPENAI_BASE_URL', originalEnv.OPENAI_BASE_URL)
restoreEnv('CLAUDE_CODE_USE_GEMINI', originalEnv.CLAUDE_CODE_USE_GEMINI) restoreEnv('CLAUDE_CODE_USE_GEMINI', originalEnv.CLAUDE_CODE_USE_GEMINI)
restoreEnv('GEMINI_API_KEY', originalEnv.GEMINI_API_KEY) restoreEnv('GEMINI_API_KEY', originalEnv.GEMINI_API_KEY)
restoreEnv('GOOGLE_API_KEY', originalEnv.GOOGLE_API_KEY) restoreEnv('GOOGLE_API_KEY', originalEnv.GOOGLE_API_KEY)
@@ -71,3 +77,19 @@ test('still errors when no Gemini credential source is available', async () => {
'GEMINI_API_KEY, GOOGLE_API_KEY, GEMINI_ACCESS_TOKEN, or Google ADC credentials are required when CLAUDE_CODE_USE_GEMINI=1.', 'GEMINI_API_KEY, GOOGLE_API_KEY, GEMINI_ACCESS_TOKEN, or Google ADC credentials are required when CLAUDE_CODE_USE_GEMINI=1.',
) )
}) })
test('openai missing key error includes recovery guidance and config locations', async () => {
process.env.CLAUDE_CODE_USE_OPENAI = '1'
process.env.OPENAI_BASE_URL = 'https://api.openai.com/v1'
delete process.env.OPENAI_API_KEY
const message = await getProviderValidationError(process.env)
expect(message).toContain(
'OPENAI_API_KEY is required when CLAUDE_CODE_USE_OPENAI=1 and OPENAI_BASE_URL is not local.',
)
expect(message).toContain(
'set CLAUDE_CODE_USE_OPENAI=0 in your shell environment',
)
expect(message).toContain('Saved startup settings can come from')
expect(message).toContain('.openclaude-profile.json')
})

View File

@@ -1,14 +1,16 @@
import { resolve } from 'node:path'
import { import {
getGithubEndpointType, getGithubEndpointType,
isLocalProviderUrl, isLocalProviderUrl,
resolveCodexApiCredentials, resolveCodexApiCredentials,
resolveProviderRequest, resolveProviderRequest,
} from '../services/api/providerConfig.js' } from '../services/api/providerConfig.js'
import { getGlobalClaudeFile } from './env.js'
import { import {
type GeminiResolvedCredential, type GeminiResolvedCredential,
resolveGeminiCredential, resolveGeminiCredential,
} from './geminiAuth.js' } from './geminiAuth.js'
import { redactSecretValueForDisplay } from './providerProfile.js' import { PROFILE_FILE_NAME, redactSecretValueForDisplay } from './providerProfile.js'
function isEnvTruthy(value: string | undefined): boolean { function isEnvTruthy(value: string | undefined): boolean {
if (!value) return false if (!value) return false
@@ -61,6 +63,17 @@ function checkGithubTokenStatus(
return 'valid' return 'valid'
} }
function getOpenAIMissingKeyMessage(): string {
const globalConfigPath = getGlobalClaudeFile()
const profilePath = resolve(process.cwd(), PROFILE_FILE_NAME)
return [
'OPENAI_API_KEY is required when CLAUDE_CODE_USE_OPENAI=1 and OPENAI_BASE_URL is not local.',
`To recover, run /provider and switch provider, or set CLAUDE_CODE_USE_OPENAI=0 in your shell environment.`,
`Saved startup settings can come from ${globalConfigPath} or ${profilePath}.`,
].join('\n')
}
export async function getProviderValidationError( export async function getProviderValidationError(
env: NodeJS.ProcessEnv = process.env, env: NodeJS.ProcessEnv = process.env,
options?: { options?: {
@@ -137,7 +150,7 @@ export async function getProviderValidationError(
if (useGithub && hasGithubToken) { if (useGithub && hasGithubToken) {
return null return null
} }
return 'OPENAI_API_KEY is required when CLAUDE_CODE_USE_OPENAI=1 and OPENAI_BASE_URL is not local.' return getOpenAIMissingKeyMessage()
} }
return null return null