1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
import { App } from "../../app/app"
import { AuthAnthropic } from "../../auth/anthropic"
import { AuthKeys } from "../../auth/keys"
import { cmd } from "./cmd"
import * as prompts from "@clack/prompts"
import open from "open"
import { VERSION } from "../version"
import { Provider } from "../../provider/provider"
export const ProviderCommand = cmd({
command: "provider",
builder: (yargs) =>
yargs
.command(ProviderAddCommand)
.command(ProviderListCommand)
.demandCommand(),
describe: "initialize opencode",
async handler() {},
})
export const ProviderListCommand = cmd({
command: "list",
aliases: ["ls"],
describe: "list providers",
async handler() {
await App.provide({ cwd: process.cwd(), version: VERSION }, async () => {
prompts.intro("Providers")
const providers = await Provider.list().then((x) => Object.values(x))
for (const value of providers) {
prompts.log.success(value.info.name + " (" + value.source + ")")
}
prompts.outro(`${providers.length} configured`)
})
},
})
export const ProviderAddCommand = cmd({
command: "add",
describe: "add credentials for various providers",
async handler() {
await App.provide({ cwd: process.cwd(), version: VERSION }, async () => {
const providers = await Provider.list()
prompts.intro("Add provider")
const provider = await prompts.select({
message: "Select",
maxItems: 2,
options: [
{
label: "Anthropic",
value: "anthropic",
hint: providers["anthropic"] ? "configured" : "",
},
{
label: "OpenAI",
value: "openai",
hint: providers["openai"] ? "configured" : "",
},
{
label: "Google",
value: "google",
hint: providers["google"] ? "configured" : "",
},
],
})
if (prompts.isCancel(provider)) return
if (provider === "anthropic") {
const method = await prompts.select({
message: "Login method",
options: [
{
label: "Claude Pro/Max",
value: "oauth",
},
{
label: "API Key",
value: "api",
},
],
})
if (prompts.isCancel(method)) return
if (method === "oauth") {
// some weird bug where program exits without this
await new Promise((resolve) => setTimeout(resolve, 10))
const { url, verifier } = await AuthAnthropic.authorize()
prompts.note("Opening browser...")
await open(url)
prompts.log.info(url)
const code = await prompts.text({
message: "Paste the authorization code here: ",
validate: (x) => (x.length > 0 ? undefined : "Required"),
})
if (prompts.isCancel(code)) return
await AuthAnthropic.exchange(code, verifier)
.then(() => {
prompts.log.success("Login successful")
})
.catch(() => {
prompts.log.error("Invalid code")
})
prompts.outro("Done")
return
}
}
const key = await prompts.password({
message: "Enter your API key",
validate: (x) => (x.length > 0 ? undefined : "Required"),
})
if (prompts.isCancel(key)) return
await AuthKeys.set(provider, key)
prompts.outro("Done")
})
},
})
|