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
4 changes: 3 additions & 1 deletion apps/cli/src/lib/copilot-oauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,9 @@ const readAuthFile = async () => {
const file = Bun.file(filepath);
if (!(await file.exists())) return {};
try {
const content = await file.json();
const text = await file.text();
if (text.trim().length === 0) return {};
const content = JSON.parse(text) as unknown;
return content && typeof content === 'object' ? (content as Record<string, unknown>) : {};
} catch {
return {};
Expand Down
4 changes: 3 additions & 1 deletion apps/cli/src/lib/opencode-oauth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,9 @@ const readAuthFile = async (): Promise<Record<string, unknown>> => {
const file = Bun.file(filepath);
if (!(await file.exists())) return {};
try {
const content = await file.json();
const text = await file.text();
if (text.trim().length === 0) return {};
const content = JSON.parse(text) as unknown;
return content && typeof content === 'object' ? (content as Record<string, unknown>) : {};
} catch {
return {};
Expand Down
5 changes: 3 additions & 2 deletions apps/docs/btca.spec.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Supported providers:
- `openai` — OAuth (no API keys)
- `openai-compat` — optional API key (requires baseURL + name in config)
- `anthropic` — API key
- `google` — API key or OAuth
- `google` — API key
- `minimax` — API key

Environment variable overrides:
Expand Down Expand Up @@ -202,7 +202,7 @@ Options:

- `-g, --global` — (flag exists; config target is still resolved by presence of project config)
- `-n, --name <name>`
- `-b, --branch <branch>` (default `main`)
- `-b, --branch <branch>` (auto-detected when omitted)
- `-s, --search-path <path...>`
- `--notes <notes>`
- `-t, --type <git|local|npm>`
Expand Down Expand Up @@ -275,6 +275,7 @@ Behavior:
- If provider/model specified, updates config.
- Otherwise, interactive provider selection (connected providers listed first), then model selection.
- Prompts for auth if required.
- Backward-compatible alias: `btca config model --provider <id> --model <id>` (deprecated).

### 4.8 `btca disconnect`

Expand Down
2 changes: 1 addition & 1 deletion apps/docs/guides/authentication.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Supported providers:
- `github-copilot` (OAuth device flow)
- `openai-compat` (optional API key)
- `anthropic` (API key)
- `google` (API key or OAuth)
- `google` (API key)
- `minimax` (API key)

Environment variable overrides:
Expand Down
4 changes: 2 additions & 2 deletions apps/server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ BTCA supports the following providers only:
- `opencode` — API key required
- `openrouter` — API key required
- `openai` — OAuth only
- `google` — API key or OAuth
- `google` — API key required
- `anthropic` — API key required

Authenticate providers via OpenCode:
Expand All @@ -173,7 +173,7 @@ opencode auth --provider <provider>
- OpenCode and OpenRouter can use environment variables or OpenCode auth.
- OpenAI requires OAuth (API keys are not supported).
- Anthropic requires an API key.
- Google supports API key or OAuth.
- Google requires an API key.

## Environment Variables

Expand Down
10 changes: 7 additions & 3 deletions apps/server/src/providers/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export namespace Auth {
openai: ['oauth'],
'openai-compat': ['api'],
anthropic: ['api'],
google: ['api', 'oauth'],
google: ['api'],
minimax: ['api']
};

Expand Down Expand Up @@ -103,7 +103,11 @@ export namespace Auth {
return {};
}

const result = await Result.tryPromise(() => file.json());
const result = await Result.tryPromise(async () => {
const text = await file.text();
if (text.trim().length === 0) return {};
return JSON.parse(text) as unknown;
});
return result.match({
ok: (content) => {
const parsed = AuthFileSchema.safeParse(content);
Expand Down Expand Up @@ -172,7 +176,7 @@ export namespace Auth {
case 'anthropic':
return 'Run "opencode auth --provider anthropic" and enter an API key.';
case 'google':
return 'Run "opencode auth --provider google" and enter an API key or OAuth.';
return 'Run "btca connect -p google" and enter an API key.';
case 'openrouter':
return 'Set OPENROUTER_API_KEY or run "opencode auth --provider openrouter".';
case 'opencode':
Expand Down