core: rename auth command to providers for clearer credential management
The auth command has been renamed to providers to better reflect its purpose of managing AI provider credentials. This makes it easier for users to discover and use the credential management features when configuring different AI providers.
This commit is contained in:
parent
d1938a472d
commit
9dbf3a2042
5 changed files with 19 additions and 26 deletions
|
|
@ -111,3 +111,7 @@ const table = sqliteTable("session", {
|
||||||
- Avoid mocks as much as possible
|
- Avoid mocks as much as possible
|
||||||
- Test actual implementation, do not duplicate logic into tests
|
- Test actual implementation, do not duplicate logic into tests
|
||||||
- Tests cannot run from repo root (guard: `do-not-run-tests-from-root`); run from package dirs like `packages/opencode`.
|
- Tests cannot run from repo root (guard: `do-not-run-tests-from-root`); run from package dirs like `packages/opencode`.
|
||||||
|
|
||||||
|
## Type Checking
|
||||||
|
|
||||||
|
- Always run `bun typecheck` from package directories (e.g., `packages/opencode`), never `tsc` directly.
|
||||||
|
|
|
||||||
|
|
@ -16,10 +16,6 @@ import { text } from "node:stream/consumers"
|
||||||
|
|
||||||
type PluginAuth = NonNullable<Hooks["auth"]>
|
type PluginAuth = NonNullable<Hooks["auth"]>
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle plugin-based authentication flow.
|
|
||||||
* Returns true if auth was handled, false if it should fall through to default handling.
|
|
||||||
*/
|
|
||||||
async function handlePluginAuth(plugin: { auth: PluginAuth }, provider: string): Promise<boolean> {
|
async function handlePluginAuth(plugin: { auth: PluginAuth }, provider: string): Promise<boolean> {
|
||||||
let index = 0
|
let index = 0
|
||||||
if (plugin.auth.methods.length > 1) {
|
if (plugin.auth.methods.length > 1) {
|
||||||
|
|
@ -37,7 +33,6 @@ async function handlePluginAuth(plugin: { auth: PluginAuth }, provider: string):
|
||||||
}
|
}
|
||||||
const method = plugin.auth.methods[index]
|
const method = plugin.auth.methods[index]
|
||||||
|
|
||||||
// Handle prompts for all auth types
|
|
||||||
await Bun.sleep(10)
|
await Bun.sleep(10)
|
||||||
const inputs: Record<string, string> = {}
|
const inputs: Record<string, string> = {}
|
||||||
if (method.prompts) {
|
if (method.prompts) {
|
||||||
|
|
@ -161,11 +156,6 @@ async function handlePluginAuth(plugin: { auth: PluginAuth }, provider: string):
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Build a deduplicated list of plugin-registered auth providers that are not
|
|
||||||
* already present in models.dev, respecting enabled/disabled provider lists.
|
|
||||||
* Pure function with no side effects; safe to test without mocking.
|
|
||||||
*/
|
|
||||||
export function resolvePluginProviders(input: {
|
export function resolvePluginProviders(input: {
|
||||||
hooks: Hooks[]
|
hooks: Hooks[]
|
||||||
existingProviders: Record<string, unknown>
|
existingProviders: Record<string, unknown>
|
||||||
|
|
@ -193,19 +183,20 @@ export function resolvePluginProviders(input: {
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AuthCommand = cmd({
|
export const ProvidersCommand = cmd({
|
||||||
command: "auth",
|
command: "providers",
|
||||||
describe: "manage credentials",
|
aliases: ["auth"],
|
||||||
|
describe: "manage AI providers and credentials",
|
||||||
builder: (yargs) =>
|
builder: (yargs) =>
|
||||||
yargs.command(AuthLoginCommand).command(AuthLogoutCommand).command(AuthListCommand).demandCommand(),
|
yargs.command(ProvidersListCommand).command(ProvidersLoginCommand).command(ProvidersLogoutCommand).demandCommand(),
|
||||||
async handler() {},
|
async handler() {},
|
||||||
})
|
})
|
||||||
|
|
||||||
export const AuthListCommand = cmd({
|
export const ProvidersListCommand = cmd({
|
||||||
command: "list",
|
command: "list",
|
||||||
aliases: ["ls"],
|
aliases: ["ls"],
|
||||||
describe: "list providers",
|
describe: "list providers and credentials",
|
||||||
async handler() {
|
async handler(_args) {
|
||||||
UI.empty()
|
UI.empty()
|
||||||
const authPath = path.join(Global.Path.data, "auth.json")
|
const authPath = path.join(Global.Path.data, "auth.json")
|
||||||
const homedir = os.homedir()
|
const homedir = os.homedir()
|
||||||
|
|
@ -221,7 +212,6 @@ export const AuthListCommand = cmd({
|
||||||
|
|
||||||
prompts.outro(`${results.length} credentials`)
|
prompts.outro(`${results.length} credentials`)
|
||||||
|
|
||||||
// Environment variables section
|
|
||||||
const activeEnvVars: Array<{ provider: string; envVar: string }> = []
|
const activeEnvVars: Array<{ provider: string; envVar: string }> = []
|
||||||
|
|
||||||
for (const [providerID, provider] of Object.entries(database)) {
|
for (const [providerID, provider] of Object.entries(database)) {
|
||||||
|
|
@ -248,7 +238,7 @@ export const AuthListCommand = cmd({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export const AuthLoginCommand = cmd({
|
export const ProvidersLoginCommand = cmd({
|
||||||
command: "login [url]",
|
command: "login [url]",
|
||||||
describe: "log in to a provider",
|
describe: "log in to a provider",
|
||||||
builder: (yargs) =>
|
builder: (yargs) =>
|
||||||
|
|
@ -371,7 +361,6 @@ export const AuthLoginCommand = cmd({
|
||||||
provider = provider.replace(/^@ai-sdk\//, "")
|
provider = provider.replace(/^@ai-sdk\//, "")
|
||||||
if (prompts.isCancel(provider)) throw new UI.CancelledError()
|
if (prompts.isCancel(provider)) throw new UI.CancelledError()
|
||||||
|
|
||||||
// Check if a plugin provides auth for this custom provider
|
|
||||||
const customPlugin = await Plugin.list().then((x) => x.findLast((x) => x.auth?.provider === provider))
|
const customPlugin = await Plugin.list().then((x) => x.findLast((x) => x.auth?.provider === provider))
|
||||||
if (customPlugin && customPlugin.auth) {
|
if (customPlugin && customPlugin.auth) {
|
||||||
const handled = await handlePluginAuth({ auth: customPlugin.auth }, provider)
|
const handled = await handlePluginAuth({ auth: customPlugin.auth }, provider)
|
||||||
|
|
@ -423,10 +412,10 @@ export const AuthLoginCommand = cmd({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
export const AuthLogoutCommand = cmd({
|
export const ProvidersLogoutCommand = cmd({
|
||||||
command: "logout",
|
command: "logout",
|
||||||
describe: "log out from a configured provider",
|
describe: "log out from a configured provider",
|
||||||
async handler() {
|
async handler(_args) {
|
||||||
UI.empty()
|
UI.empty()
|
||||||
const credentials = await Auth.all().then((x) => Object.entries(x))
|
const credentials = await Auth.all().then((x) => Object.entries(x))
|
||||||
prompts.intro("Remove credential")
|
prompts.intro("Remove credential")
|
||||||
|
|
@ -3,7 +3,7 @@ import { hideBin } from "yargs/helpers"
|
||||||
import { RunCommand } from "./cli/cmd/run"
|
import { RunCommand } from "./cli/cmd/run"
|
||||||
import { GenerateCommand } from "./cli/cmd/generate"
|
import { GenerateCommand } from "./cli/cmd/generate"
|
||||||
import { Log } from "./util/log"
|
import { Log } from "./util/log"
|
||||||
import { AuthCommand } from "./cli/cmd/auth"
|
import { ProvidersCommand } from "./cli/cmd/providers"
|
||||||
import { AgentCommand } from "./cli/cmd/agent"
|
import { AgentCommand } from "./cli/cmd/agent"
|
||||||
import { UpgradeCommand } from "./cli/cmd/upgrade"
|
import { UpgradeCommand } from "./cli/cmd/upgrade"
|
||||||
import { UninstallCommand } from "./cli/cmd/uninstall"
|
import { UninstallCommand } from "./cli/cmd/uninstall"
|
||||||
|
|
@ -129,7 +129,7 @@ let cli = yargs(hideBin(process.argv))
|
||||||
.command(RunCommand)
|
.command(RunCommand)
|
||||||
.command(GenerateCommand)
|
.command(GenerateCommand)
|
||||||
.command(DebugCommand)
|
.command(DebugCommand)
|
||||||
.command(AuthCommand)
|
.command(ProvidersCommand)
|
||||||
.command(AgentCommand)
|
.command(AgentCommand)
|
||||||
.command(UpgradeCommand)
|
.command(UpgradeCommand)
|
||||||
.command(UninstallCommand)
|
.command(UninstallCommand)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { test, expect, describe } from "bun:test"
|
import { test, expect, describe } from "bun:test"
|
||||||
import { resolvePluginProviders } from "../../src/cli/cmd/auth"
|
import { resolvePluginProviders } from "../../src/cli/cmd/providers"
|
||||||
import type { Hooks } from "@opencode-ai/plugin"
|
import type { Hooks } from "@opencode-ai/plugin"
|
||||||
|
|
||||||
function hookWithAuth(provider: string): Hooks {
|
function hookWithAuth(provider: string): Hooks {
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
"globalPassThroughEnv": ["CI", "OPENCODE_DISABLE_SHARE"],
|
"globalPassThroughEnv": ["CI", "OPENCODE_DISABLE_SHARE"],
|
||||||
"tasks": {
|
"tasks": {
|
||||||
"typecheck": {
|
"typecheck": {
|
||||||
"dependsOn": ["^build"]
|
"dependsOn": []
|
||||||
},
|
},
|
||||||
"build": {
|
"build": {
|
||||||
"dependsOn": ["^build"],
|
"dependsOn": ["^build"],
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue