mirror of
https://github.com/Kilo-Org/kilocode.git
synced 2026-09-24 16:02:55 +08:00
fix(cli): brand xAI OAuth as Kilocode
This commit is contained in:
@@ -19,7 +19,7 @@ import { gitlabAuthPlugin as GitlabAuthPlugin } from "opencode-gitlab-auth"
|
||||
import { PoeAuthPlugin } from "opencode-poe-auth"
|
||||
import { CloudflareAIGatewayAuthPlugin, CloudflareWorkersAuthPlugin } from "./cloudflare"
|
||||
import { AzureAuthPlugin } from "./azure"
|
||||
import { XaiAuthPlugin } from "./xai"
|
||||
import { XaiAuthPlugin } from "./xai" // kilocode_change
|
||||
import { Effect, Layer, Context, Stream } from "effect"
|
||||
import { EffectBridge } from "@/effect/bridge"
|
||||
import { InstanceState } from "@/effect/instance-state"
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// kilocode_change - new file
|
||||
import type { Hooks, PluginInput } from "@kilocode/plugin" // kilocode_change
|
||||
import * as Log from "@opencode-ai/core/util/log"
|
||||
import { OAUTH_DUMMY_KEY } from "../auth"
|
||||
@@ -109,7 +110,7 @@ function authHeaders() {
|
||||
return {
|
||||
"Content-Type": "application/x-www-form-urlencoded",
|
||||
Accept: "application/json",
|
||||
"User-Agent": `opencode/${InstallationVersion}`,
|
||||
"User-Agent": `kilocode/${InstallationVersion}`,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +142,7 @@ export function buildAuthorizeUrl(
|
||||
): string {
|
||||
// `plan=generic` opts the consent screen into xAI's generic OAuth plan tier;
|
||||
// without it, accounts.x.ai rejects loopback OAuth from non-allowlisted
|
||||
// clients. `referrer=opencode` lets xAI attribute opencode-originated
|
||||
// clients. `referrer=kilocode` lets xAI attribute kilocode-originated
|
||||
// logins in their OAuth server logs (best-effort attribution while we
|
||||
// continue to reuse the Grok-CLI client_id).
|
||||
const params = new URLSearchParams({
|
||||
@@ -154,7 +155,7 @@ export function buildAuthorizeUrl(
|
||||
state,
|
||||
nonce,
|
||||
plan: "generic",
|
||||
referrer: "opencode",
|
||||
referrer: "kilocode",
|
||||
})
|
||||
return `${options.authorizeUrl ?? AUTHORIZE_URL}?${params.toString()}`
|
||||
}
|
||||
@@ -306,7 +307,7 @@ export async function pollDeviceCodeToken(
|
||||
const HTML_SUCCESS = `<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kilo - xAI Authorization Successful</title>
|
||||
<title>Kilocode - xAI Authorization Successful</title>
|
||||
<style>
|
||||
body {
|
||||
font-family:
|
||||
@@ -337,7 +338,7 @@ const HTML_SUCCESS = `<!doctype html>
|
||||
<body>
|
||||
<div class="container">
|
||||
<h1>Authorization Successful</h1>
|
||||
<p>You can close this window and return to Kilo.</p>
|
||||
<p>You can close this window and return to Kilocode.</p>
|
||||
</div>
|
||||
<script>
|
||||
setTimeout(() => window.close(), 2000)
|
||||
@@ -348,7 +349,7 @@ const HTML_SUCCESS = `<!doctype html>
|
||||
const HTML_ERROR = (error: string) => `<!doctype html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Kilo - xAI Authorization Failed</title>
|
||||
<title>Kilocode - xAI Authorization Failed</title>
|
||||
<style>
|
||||
body {
|
||||
font-family:
|
||||
@@ -504,7 +505,7 @@ async function startOAuthServer(): Promise<{ port: number; redirectUri: string }
|
||||
// After listen() succeeds, install a permanent log-only listener so
|
||||
// that subsequent server errors (e.g. accept() failures, socket-level
|
||||
// errors) don't trip Node's default "unhandled error event = throw"
|
||||
// behavior and crash the entire opencode process. Matches the silent-
|
||||
// behavior and crash the entire Kilocode process. Matches the silent-
|
||||
// swallow behavior the Codex plugin gets from its permanent
|
||||
// `oauthServer!.on("error", reject)`.
|
||||
server.on("error", (err) => log.warn("xai oauth server error", { error: err }))
|
||||
@@ -652,7 +653,7 @@ export async function XaiAuthPlugin(input: PluginInput, options: XaiAuthPluginOp
|
||||
}
|
||||
}
|
||||
headers.set("authorization", `Bearer ${currentAuth.access}`)
|
||||
headers.set("User-Agent", `opencode/${InstallationVersion}`)
|
||||
headers.set("User-Agent", `kilocode/${InstallationVersion}`)
|
||||
|
||||
return fetch(requestInput, { ...init, headers })
|
||||
},
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
// kilocode_change - new file
|
||||
import { describe, expect, test } from "bun:test"
|
||||
import { accessTokenIsExpiring, buildAuthorizeUrl, escapeHtml, pollDeviceCodeToken, requestDeviceCode, XaiAuthPlugin } from "../../src/plugin/xai"
|
||||
import { OAUTH_DUMMY_KEY } from "../../src/auth"
|
||||
@@ -87,7 +88,7 @@ describe("plugin.xai", () => {
|
||||
expect(params.get("state")).toBe("state-abc")
|
||||
expect(params.get("nonce")).toBe("nonce-xyz")
|
||||
expect(params.get("plan")).toBe("generic")
|
||||
expect(params.get("referrer")).toBe("opencode")
|
||||
expect(params.get("referrer")).toBe("kilocode")
|
||||
})
|
||||
|
||||
test("supports endpoint override for local integration tests", () => {
|
||||
@@ -142,7 +143,7 @@ describe("plugin.xai", () => {
|
||||
|
||||
expect(captured[0].get("authorization")).toBe("Bearer live-token")
|
||||
expect(captured[0].get("x-keep")).toBe("yes")
|
||||
expect(captured[0].get("user-agent")).toMatch(/^opencode\//)
|
||||
expect(captured[0].get("user-agent")).toMatch(/^kilocode\//)
|
||||
})
|
||||
|
||||
test("does not mutate caller headers and supports HeadersInit shapes", async () => {
|
||||
@@ -173,7 +174,7 @@ describe("plugin.xai", () => {
|
||||
expect(captured.map((headers) => headers.get("x-trace"))).toEqual(["plain-object", "tuple-array", "headers-instance"])
|
||||
for (const headers of captured) {
|
||||
expect(headers.get("authorization")).toBe("Bearer tok")
|
||||
expect(headers.get("user-agent")).toMatch(/^opencode\//)
|
||||
expect(headers.get("user-agent")).toMatch(/^kilocode\//)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -425,7 +426,7 @@ describe("plugin.xai", () => {
|
||||
expect(request.method).toBe("POST")
|
||||
expect(request.headers.get("content-type")).toBe("application/x-www-form-urlencoded")
|
||||
expect(request.headers.get("accept")).toBe("application/json")
|
||||
expect(request.headers.get("user-agent")).toMatch(/^opencode\//)
|
||||
expect(request.headers.get("user-agent")).toMatch(/^kilocode\//)
|
||||
capturedBody = await request.text()
|
||||
return Response.json({ device_code: "DC", user_code: "UC", verification_uri: "https://x.ai/device" })
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user