opencode-kilocode-auth 1.0.1 → 1.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/plugin.ts +24 -89
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "opencode-kilocode-auth",
3
3
  "module": "index.ts",
4
- "version": "1.0.1",
4
+ "version": "1.0.3",
5
5
  "author": "ported from Kilo Code",
6
6
  "description": "OpenCode plugin for Kilo Code authentication with support for various models including Giga Potato",
7
7
  "files": [
package/src/plugin.ts CHANGED
@@ -1,28 +1,23 @@
1
1
  import type { Hooks, PluginInput } from "@opencode-ai/plugin"
2
2
  import {
3
3
  KILOCODE_PROVIDER_ID,
4
- KILOCODE_API_BASE_URL,
5
- DEFAULT_HEADERS,
6
4
  DEFAULT_MODEL_ID,
7
- DEVICE_AUTH_POLL_INTERVAL_MS,
8
5
  } from "./constants"
9
6
  import {
10
- initiateDeviceAuth,
11
- pollDeviceAuth,
12
7
  getKilocodeProfile,
13
8
  getKilocodeDefaultModel,
14
9
  getKilocodeModels,
15
- openBrowserUrl,
16
10
  getApiUrl,
17
11
  } from "./kilocode/auth"
18
12
 
19
13
  interface KilocodeAuth {
20
- type: "oauth"
21
- refresh: string // token
14
+ type: "oauth" | "api"
15
+ refresh?: string // token (for oauth)
22
16
  access?: string
23
17
  expires?: number
24
18
  organizationId?: string
25
19
  model?: string
20
+ apiKey?: string // for api type
26
21
  }
27
22
 
28
23
  /**
@@ -40,10 +35,13 @@ export async function KilocodeAuthPlugin(input: PluginInput): Promise<Hooks> {
40
35
 
41
36
  async loader(getAuth, provider) {
42
37
  const auth = await getAuth()
43
- if (!auth || auth.type !== "oauth") return {}
38
+ if (!auth) return {}
44
39
 
45
40
  const kilocodeAuth = auth as KilocodeAuth
46
- const token = kilocodeAuth.refresh
41
+ // Support both OAuth (refresh token) and API key authentication
42
+ const token = kilocodeAuth.type === "api"
43
+ ? kilocodeAuth.apiKey
44
+ : kilocodeAuth.refresh
47
45
 
48
46
  if (!token) return {}
49
47
 
@@ -72,12 +70,18 @@ export async function KilocodeAuthPlugin(input: PluginInput): Promise<Hooks> {
72
70
 
73
71
  async fetch(requestInput: RequestInfo | URL, init?: RequestInit) {
74
72
  const currentAuth = await getAuth()
75
- if (!currentAuth || currentAuth.type !== "oauth") {
73
+ if (!currentAuth) {
76
74
  return fetch(requestInput, init)
77
75
  }
78
76
 
79
77
  const currentKilocodeAuth = currentAuth as KilocodeAuth
80
- const currentToken = currentKilocodeAuth.refresh
78
+ const currentToken = currentKilocodeAuth.type === "api"
79
+ ? currentKilocodeAuth.apiKey
80
+ : currentKilocodeAuth.refresh
81
+
82
+ if (!currentToken) {
83
+ return fetch(requestInput, init)
84
+ }
81
85
 
82
86
  // Build headers
83
87
  const headers = new Headers()
@@ -95,9 +99,13 @@ export async function KilocodeAuthPlugin(input: PluginInput): Promise<Hooks> {
95
99
  }
96
100
  }
97
101
 
98
- // Set Kilo Code authorization
102
+ // Set Kilo Code authorization and required headers
99
103
  headers.set("Authorization", `Bearer ${currentToken}`)
100
- headers.set("X-KILOCODE-EDITORNAME", "opencode")
104
+ headers.set("HTTP-Referer", "https://kilocode.ai")
105
+ headers.set("X-Title", "Kilo Code")
106
+ headers.set("X-KiloCode-Version", "3.16.3")
107
+ headers.set("User-Agent", "Kilo-Code/3.16.3")
108
+ headers.set("X-KiloCode-EditorName", "Visual Studio Code 1.96.0")
101
109
 
102
110
  // Add organization header if present
103
111
  if (currentKilocodeAuth.organizationId) {
@@ -130,81 +138,10 @@ export async function KilocodeAuthPlugin(input: PluginInput): Promise<Hooks> {
130
138
  },
131
139
 
132
140
  methods: [
133
- {
134
- type: "oauth",
135
- label: "Login with Kilo Code",
136
- async authorize() {
137
- // Initiate device auth flow
138
- const authData = await initiateDeviceAuth()
139
- const { code, verificationUrl, expiresIn } = authData
140
-
141
- // Open browser for user
142
- openBrowserUrl(verificationUrl)
143
-
144
- return {
145
- url: verificationUrl,
146
- instructions: `Enter code: ${code}`,
147
- method: "auto" as const,
148
-
149
- async callback() {
150
- // Poll for authorization
151
- const maxAttempts = Math.ceil((expiresIn * 1000) / DEVICE_AUTH_POLL_INTERVAL_MS)
152
- let attempt = 0
153
-
154
- while (attempt < maxAttempts) {
155
- await new Promise((resolve) => setTimeout(resolve, DEVICE_AUTH_POLL_INTERVAL_MS))
156
-
157
- try {
158
- const pollResult = await pollDeviceAuth(code)
159
-
160
- if (pollResult.status === "approved" && pollResult.token) {
161
- // Get profile for organization
162
- let organizationId: string | undefined
163
- try {
164
- const profile = await getKilocodeProfile(pollResult.token)
165
- if (profile.organizations && profile.organizations.length > 0) {
166
- organizationId = profile.organizations[0].id
167
- }
168
- } catch {
169
- // Continue without organization
170
- }
171
-
172
- // Get default model
173
- const model = await getKilocodeDefaultModel(pollResult.token, organizationId)
174
-
175
- return {
176
- type: "success" as const,
177
- refresh: pollResult.token,
178
- access: pollResult.token,
179
- expires: Date.now() + 365 * 24 * 60 * 60 * 1000, // 1 year (tokens don't expire normally)
180
- // Store extra info in the auth
181
- organizationId,
182
- model,
183
- } as any
184
- }
185
-
186
- if (pollResult.status === "denied") {
187
- return { type: "failed" as const }
188
- }
189
-
190
- if (pollResult.status === "expired") {
191
- return { type: "failed" as const }
192
- }
193
- } catch {
194
- // Continue polling on error
195
- }
196
-
197
- attempt++
198
- }
199
-
200
- return { type: "failed" as const }
201
- },
202
- }
203
- },
204
- },
141
+ // API key is the primary method - get it from https://app.kilo.ai
205
142
  {
206
143
  type: "api",
207
- label: "Enter Kilo Code API Token",
144
+ label: "Enter API Key (get from app.kilo.ai)",
208
145
  },
209
146
  ],
210
147
  },
@@ -221,8 +158,6 @@ export async function KilocodeAuthPlugin(input: PluginInput): Promise<Hooks> {
221
158
 
222
159
  // Export utilities for external use
223
160
  export {
224
- initiateDeviceAuth,
225
- pollDeviceAuth,
226
161
  getKilocodeProfile,
227
162
  getKilocodeDefaultModel,
228
163
  getKilocodeModels,