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 packages/cli/src/commands/handlers/auth/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const list = Effect.fn("cli.auth.list")(function* (input) {
integration: integration.name,
source: connection.type === "credential" ? connection.label : connection.name,
type: connection.type === "credential" ? "stored" : "environment",
id: connection.type === "credential" ? connection.id : "-",
})),
)
if (rows.length === 0) {
Expand All @@ -46,6 +47,7 @@ const list = Effect.fn("cli.auth.list")(function* (input) {
}
const width = Math.max(...rows.map((row) => row.integration.length)) + 2
process.stdout.write(
rows.map((row) => row.integration.padEnd(width) + row.source.padEnd(28) + row.type).join(EOL) + EOL,
rows.map((row) => row.integration.padEnd(width) + row.source.padEnd(28) + row.type.padEnd(13) + row.id).join(EOL) +
EOL,
)
})
19 changes: 17 additions & 2 deletions packages/cli/test/auth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ describe("auth command", () => {
expect(logout.stdout).toContain("opencode auth logout [flags] [<target>] [<credential>]")
})

test("lists stored and environment connections", async () => {
test("lists distinct stored credential IDs without changing JSON connections", async () => {
const requests: string[] = []
using server = authServer((request, url) => {
if (url.pathname === "/api/integration") {
Expand All @@ -50,6 +50,7 @@ describe("auth command", () => {
methods: [],
connections: [
{ type: "credential", method: "key", id: "cred_test", label: "default" },
{ type: "credential", method: "key", id: "cred_other", label: "default" },
{ type: "env", name: "ANTHROPIC_API_KEY" },
],
},
Expand All @@ -61,18 +62,32 @@ describe("auth command", () => {
}, requests)

const result = await cli(["auth", "list", "--format", "json", "--server", server.url.toString()])
expect(requests).toContain("/api/model/default")
expect(requests.indexOf("/api/model/default")).toBeLessThan(requests.indexOf("/api/integration"))
const table = await cli(["auth", "list", "--server", server.url.toString()])
expect({ exitCode: result.exitCode, stderr: result.stderr }).toEqual({ exitCode: 0, stderr: "" })
expect({ exitCode: table.exitCode, stderr: table.stderr }).toEqual({ exitCode: 0, stderr: "" })
expect(
table.stdout
.trim()
.split("\n")
.map((line) => line.split(/\s{2,}/)),
).toEqual([
["Anthropic", "default", "stored", "cred_test"],
["Anthropic", "default", "stored", "cred_other"],
["Anthropic", "ANTHROPIC_API_KEY", "environment", "-"],
])
expect(JSON.parse(result.stdout)).toEqual([
{
id: "anthropic",
name: "Anthropic",
connections: [
{ type: "credential", method: "key", id: "cred_test", label: "default" },
{ type: "credential", method: "key", id: "cred_other", label: "default" },
{ type: "env", name: "ANTHROPIC_API_KEY" },
],
},
])
expect(requests.indexOf("/api/model/default")).toBeLessThan(requests.indexOf("/api/integration"))
})

test("lists OpenCode Go before Zen and preserves the remaining integration order", async () => {
Expand Down
12 changes: 9 additions & 3 deletions services/www/src/docs/content/cli/commands.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -164,10 +164,14 @@ $ opencode session --help

## auth

Manages AI providers and credentials.
Manages AI providers and credentials. The default table shows the integration name, account label or environment variable,
connection type, and credential ID. Environment connections show `-` instead of an ID.

```bash
$ opencode auth list
Anthropic work stored cred_work
Anthropic work stored cred_other
Anthropic ANTHROPIC_API_KEY environment -
```

List them as JSON.
Expand All @@ -188,16 +192,18 @@ Log in with a specific authentication method.
$ opencode auth login anthropic --method key
```

Log out of a saved account.
Log out of a saved account by label or credential ID. Use the ID from `auth list` when labels are identical.

```bash
$ opencode auth logout anthropic work
$ opencode auth logout anthropic cred_other
```

Switch the active account for an integration.
Switch the active account for an integration by label or credential ID.

```bash
$ opencode auth switch anthropic work
$ opencode auth switch anthropic cred_work
```

Export saved credentials and import them on another machine. The file contains secrets.
Expand Down
Loading