@shareai-lab/kode 1.1.13 → 1.1.16

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 (288) hide show
  1. package/dist/entrypoints/cli.js +2 -1
  2. package/dist/entrypoints/cli.js.map +2 -2
  3. package/dist/index.js +5 -26
  4. package/dist/package.json +4 -1
  5. package/package.json +9 -104
  6. package/dist/test/testAdapters.js +0 -88
  7. package/dist/test/testAdapters.js.map +0 -1
  8. package/src/ProjectOnboarding.tsx +0 -198
  9. package/src/Tool.ts +0 -83
  10. package/src/commands/agents.tsx +0 -3416
  11. package/src/commands/approvedTools.ts +0 -53
  12. package/src/commands/bug.tsx +0 -20
  13. package/src/commands/clear.ts +0 -43
  14. package/src/commands/compact.ts +0 -120
  15. package/src/commands/config.tsx +0 -19
  16. package/src/commands/cost.ts +0 -18
  17. package/src/commands/ctx_viz.ts +0 -209
  18. package/src/commands/doctor.ts +0 -24
  19. package/src/commands/help.tsx +0 -19
  20. package/src/commands/init.ts +0 -37
  21. package/src/commands/listen.ts +0 -42
  22. package/src/commands/login.tsx +0 -51
  23. package/src/commands/logout.tsx +0 -40
  24. package/src/commands/mcp.ts +0 -41
  25. package/src/commands/model.tsx +0 -40
  26. package/src/commands/modelstatus.tsx +0 -20
  27. package/src/commands/onboarding.tsx +0 -34
  28. package/src/commands/pr_comments.ts +0 -59
  29. package/src/commands/refreshCommands.ts +0 -54
  30. package/src/commands/release-notes.ts +0 -34
  31. package/src/commands/resume.tsx +0 -31
  32. package/src/commands/review.ts +0 -49
  33. package/src/commands/terminalSetup.ts +0 -221
  34. package/src/commands.ts +0 -139
  35. package/src/components/ApproveApiKey.tsx +0 -93
  36. package/src/components/AsciiLogo.tsx +0 -13
  37. package/src/components/AutoUpdater.tsx +0 -148
  38. package/src/components/Bug.tsx +0 -367
  39. package/src/components/Config.tsx +0 -293
  40. package/src/components/ConsoleOAuthFlow.tsx +0 -327
  41. package/src/components/Cost.tsx +0 -23
  42. package/src/components/CostThresholdDialog.tsx +0 -46
  43. package/src/components/CustomSelect/option-map.ts +0 -42
  44. package/src/components/CustomSelect/select-option.tsx +0 -78
  45. package/src/components/CustomSelect/select.tsx +0 -152
  46. package/src/components/CustomSelect/theme.ts +0 -45
  47. package/src/components/CustomSelect/use-select-state.ts +0 -414
  48. package/src/components/CustomSelect/use-select.ts +0 -35
  49. package/src/components/FallbackToolUseRejectedMessage.tsx +0 -15
  50. package/src/components/FileEditToolUpdatedMessage.tsx +0 -66
  51. package/src/components/Help.tsx +0 -215
  52. package/src/components/HighlightedCode.tsx +0 -33
  53. package/src/components/InvalidConfigDialog.tsx +0 -113
  54. package/src/components/Link.tsx +0 -32
  55. package/src/components/LogSelector.tsx +0 -86
  56. package/src/components/Logo.tsx +0 -170
  57. package/src/components/MCPServerApprovalDialog.tsx +0 -100
  58. package/src/components/MCPServerDialogCopy.tsx +0 -25
  59. package/src/components/MCPServerMultiselectDialog.tsx +0 -109
  60. package/src/components/Message.tsx +0 -221
  61. package/src/components/MessageResponse.tsx +0 -15
  62. package/src/components/MessageSelector.tsx +0 -211
  63. package/src/components/ModeIndicator.tsx +0 -88
  64. package/src/components/ModelConfig.tsx +0 -301
  65. package/src/components/ModelListManager.tsx +0 -227
  66. package/src/components/ModelSelector.tsx +0 -3387
  67. package/src/components/ModelStatusDisplay.tsx +0 -230
  68. package/src/components/Onboarding.tsx +0 -274
  69. package/src/components/PressEnterToContinue.tsx +0 -11
  70. package/src/components/PromptInput.tsx +0 -760
  71. package/src/components/SentryErrorBoundary.ts +0 -39
  72. package/src/components/Spinner.tsx +0 -129
  73. package/src/components/StickerRequestForm.tsx +0 -16
  74. package/src/components/StructuredDiff.tsx +0 -191
  75. package/src/components/TextInput.tsx +0 -259
  76. package/src/components/TodoItem.tsx +0 -47
  77. package/src/components/TokenWarning.tsx +0 -31
  78. package/src/components/ToolUseLoader.tsx +0 -40
  79. package/src/components/TrustDialog.tsx +0 -106
  80. package/src/components/binary-feedback/BinaryFeedback.tsx +0 -63
  81. package/src/components/binary-feedback/BinaryFeedbackOption.tsx +0 -111
  82. package/src/components/binary-feedback/BinaryFeedbackView.tsx +0 -172
  83. package/src/components/binary-feedback/utils.ts +0 -220
  84. package/src/components/messages/AssistantBashOutputMessage.tsx +0 -22
  85. package/src/components/messages/AssistantLocalCommandOutputMessage.tsx +0 -49
  86. package/src/components/messages/AssistantRedactedThinkingMessage.tsx +0 -19
  87. package/src/components/messages/AssistantTextMessage.tsx +0 -144
  88. package/src/components/messages/AssistantThinkingMessage.tsx +0 -40
  89. package/src/components/messages/AssistantToolUseMessage.tsx +0 -132
  90. package/src/components/messages/TaskProgressMessage.tsx +0 -32
  91. package/src/components/messages/TaskToolMessage.tsx +0 -58
  92. package/src/components/messages/UserBashInputMessage.tsx +0 -28
  93. package/src/components/messages/UserCommandMessage.tsx +0 -30
  94. package/src/components/messages/UserKodingInputMessage.tsx +0 -28
  95. package/src/components/messages/UserPromptMessage.tsx +0 -35
  96. package/src/components/messages/UserTextMessage.tsx +0 -39
  97. package/src/components/messages/UserToolResultMessage/UserToolCanceledMessage.tsx +0 -12
  98. package/src/components/messages/UserToolResultMessage/UserToolErrorMessage.tsx +0 -36
  99. package/src/components/messages/UserToolResultMessage/UserToolRejectMessage.tsx +0 -31
  100. package/src/components/messages/UserToolResultMessage/UserToolResultMessage.tsx +0 -57
  101. package/src/components/messages/UserToolResultMessage/UserToolSuccessMessage.tsx +0 -35
  102. package/src/components/messages/UserToolResultMessage/utils.tsx +0 -56
  103. package/src/components/permissions/BashPermissionRequest/BashPermissionRequest.tsx +0 -121
  104. package/src/components/permissions/FallbackPermissionRequest.tsx +0 -153
  105. package/src/components/permissions/FileEditPermissionRequest/FileEditPermissionRequest.tsx +0 -182
  106. package/src/components/permissions/FileEditPermissionRequest/FileEditToolDiff.tsx +0 -77
  107. package/src/components/permissions/FileWritePermissionRequest/FileWritePermissionRequest.tsx +0 -164
  108. package/src/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.tsx +0 -83
  109. package/src/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.tsx +0 -240
  110. package/src/components/permissions/PermissionRequest.tsx +0 -101
  111. package/src/components/permissions/PermissionRequestTitle.tsx +0 -69
  112. package/src/components/permissions/hooks.ts +0 -44
  113. package/src/components/permissions/toolUseOptions.ts +0 -59
  114. package/src/components/permissions/utils.ts +0 -23
  115. package/src/constants/betas.ts +0 -5
  116. package/src/constants/claude-asterisk-ascii-art.tsx +0 -238
  117. package/src/constants/figures.ts +0 -4
  118. package/src/constants/keys.ts +0 -3
  119. package/src/constants/macros.ts +0 -11
  120. package/src/constants/modelCapabilities.ts +0 -179
  121. package/src/constants/models.ts +0 -1025
  122. package/src/constants/oauth.ts +0 -18
  123. package/src/constants/product.ts +0 -17
  124. package/src/constants/prompts.ts +0 -168
  125. package/src/constants/releaseNotes.ts +0 -7
  126. package/src/context/PermissionContext.tsx +0 -149
  127. package/src/context.ts +0 -278
  128. package/src/cost-tracker.ts +0 -84
  129. package/src/entrypoints/cli.tsx +0 -1561
  130. package/src/entrypoints/mcp.ts +0 -175
  131. package/src/history.ts +0 -25
  132. package/src/hooks/useApiKeyVerification.ts +0 -59
  133. package/src/hooks/useArrowKeyHistory.ts +0 -55
  134. package/src/hooks/useCanUseTool.ts +0 -138
  135. package/src/hooks/useCancelRequest.ts +0 -39
  136. package/src/hooks/useDoublePress.ts +0 -41
  137. package/src/hooks/useExitOnCtrlCD.ts +0 -31
  138. package/src/hooks/useInterval.ts +0 -25
  139. package/src/hooks/useLogMessages.ts +0 -16
  140. package/src/hooks/useLogStartupTime.ts +0 -12
  141. package/src/hooks/useNotifyAfterTimeout.ts +0 -65
  142. package/src/hooks/usePermissionRequestLogging.ts +0 -44
  143. package/src/hooks/useTerminalSize.ts +0 -49
  144. package/src/hooks/useTextInput.ts +0 -317
  145. package/src/hooks/useUnifiedCompletion.ts +0 -1405
  146. package/src/index.ts +0 -34
  147. package/src/messages.ts +0 -38
  148. package/src/permissions.ts +0 -268
  149. package/src/query.ts +0 -720
  150. package/src/screens/ConfigureNpmPrefix.tsx +0 -197
  151. package/src/screens/Doctor.tsx +0 -219
  152. package/src/screens/LogList.tsx +0 -68
  153. package/src/screens/REPL.tsx +0 -813
  154. package/src/screens/ResumeConversation.tsx +0 -68
  155. package/src/services/adapters/base.ts +0 -38
  156. package/src/services/adapters/chatCompletions.ts +0 -90
  157. package/src/services/adapters/responsesAPI.ts +0 -170
  158. package/src/services/browserMocks.ts +0 -66
  159. package/src/services/claude.ts +0 -2197
  160. package/src/services/customCommands.ts +0 -704
  161. package/src/services/fileFreshness.ts +0 -377
  162. package/src/services/gpt5ConnectionTest.ts +0 -340
  163. package/src/services/mcpClient.ts +0 -564
  164. package/src/services/mcpServerApproval.tsx +0 -50
  165. package/src/services/mentionProcessor.ts +0 -273
  166. package/src/services/modelAdapterFactory.ts +0 -69
  167. package/src/services/notifier.ts +0 -40
  168. package/src/services/oauth.ts +0 -357
  169. package/src/services/openai.ts +0 -1359
  170. package/src/services/responseStateManager.ts +0 -90
  171. package/src/services/sentry.ts +0 -3
  172. package/src/services/statsig.ts +0 -172
  173. package/src/services/statsigStorage.ts +0 -86
  174. package/src/services/systemReminder.ts +0 -507
  175. package/src/services/vcr.ts +0 -161
  176. package/src/test/testAdapters.ts +0 -96
  177. package/src/tools/ArchitectTool/ArchitectTool.tsx +0 -135
  178. package/src/tools/ArchitectTool/prompt.ts +0 -15
  179. package/src/tools/AskExpertModelTool/AskExpertModelTool.tsx +0 -576
  180. package/src/tools/BashTool/BashTool.tsx +0 -243
  181. package/src/tools/BashTool/BashToolResultMessage.tsx +0 -38
  182. package/src/tools/BashTool/OutputLine.tsx +0 -49
  183. package/src/tools/BashTool/prompt.ts +0 -174
  184. package/src/tools/BashTool/utils.ts +0 -56
  185. package/src/tools/FileEditTool/FileEditTool.tsx +0 -319
  186. package/src/tools/FileEditTool/prompt.ts +0 -51
  187. package/src/tools/FileEditTool/utils.ts +0 -58
  188. package/src/tools/FileReadTool/FileReadTool.tsx +0 -404
  189. package/src/tools/FileReadTool/prompt.ts +0 -7
  190. package/src/tools/FileWriteTool/FileWriteTool.tsx +0 -301
  191. package/src/tools/FileWriteTool/prompt.ts +0 -10
  192. package/src/tools/GlobTool/GlobTool.tsx +0 -119
  193. package/src/tools/GlobTool/prompt.ts +0 -8
  194. package/src/tools/GrepTool/GrepTool.tsx +0 -147
  195. package/src/tools/GrepTool/prompt.ts +0 -11
  196. package/src/tools/MCPTool/MCPTool.tsx +0 -107
  197. package/src/tools/MCPTool/prompt.ts +0 -3
  198. package/src/tools/MemoryReadTool/MemoryReadTool.tsx +0 -127
  199. package/src/tools/MemoryReadTool/prompt.ts +0 -3
  200. package/src/tools/MemoryWriteTool/MemoryWriteTool.tsx +0 -89
  201. package/src/tools/MemoryWriteTool/prompt.ts +0 -3
  202. package/src/tools/MultiEditTool/MultiEditTool.tsx +0 -388
  203. package/src/tools/MultiEditTool/prompt.ts +0 -45
  204. package/src/tools/NotebookEditTool/NotebookEditTool.tsx +0 -298
  205. package/src/tools/NotebookEditTool/prompt.ts +0 -3
  206. package/src/tools/NotebookReadTool/NotebookReadTool.tsx +0 -258
  207. package/src/tools/NotebookReadTool/prompt.ts +0 -3
  208. package/src/tools/StickerRequestTool/StickerRequestTool.tsx +0 -107
  209. package/src/tools/StickerRequestTool/prompt.ts +0 -19
  210. package/src/tools/TaskTool/TaskTool.tsx +0 -438
  211. package/src/tools/TaskTool/constants.ts +0 -1
  212. package/src/tools/TaskTool/prompt.ts +0 -92
  213. package/src/tools/ThinkTool/ThinkTool.tsx +0 -54
  214. package/src/tools/ThinkTool/prompt.ts +0 -12
  215. package/src/tools/TodoWriteTool/TodoWriteTool.tsx +0 -313
  216. package/src/tools/TodoWriteTool/prompt.ts +0 -63
  217. package/src/tools/URLFetcherTool/URLFetcherTool.tsx +0 -178
  218. package/src/tools/URLFetcherTool/cache.ts +0 -55
  219. package/src/tools/URLFetcherTool/htmlToMarkdown.ts +0 -55
  220. package/src/tools/URLFetcherTool/prompt.ts +0 -17
  221. package/src/tools/WebSearchTool/WebSearchTool.tsx +0 -103
  222. package/src/tools/WebSearchTool/prompt.ts +0 -13
  223. package/src/tools/WebSearchTool/searchProviders.ts +0 -66
  224. package/src/tools/lsTool/lsTool.tsx +0 -272
  225. package/src/tools/lsTool/prompt.ts +0 -2
  226. package/src/tools.ts +0 -67
  227. package/src/types/PermissionMode.ts +0 -120
  228. package/src/types/RequestContext.ts +0 -72
  229. package/src/types/common.d.ts +0 -2
  230. package/src/types/conversation.ts +0 -51
  231. package/src/types/logs.ts +0 -58
  232. package/src/types/modelCapabilities.ts +0 -64
  233. package/src/types/notebook.ts +0 -87
  234. package/src/utils/Cursor.ts +0 -436
  235. package/src/utils/PersistentShell.ts +0 -552
  236. package/src/utils/advancedFuzzyMatcher.ts +0 -290
  237. package/src/utils/agentLoader.ts +0 -278
  238. package/src/utils/agentStorage.ts +0 -97
  239. package/src/utils/array.ts +0 -3
  240. package/src/utils/ask.tsx +0 -99
  241. package/src/utils/auth.ts +0 -13
  242. package/src/utils/autoCompactCore.ts +0 -223
  243. package/src/utils/autoUpdater.ts +0 -458
  244. package/src/utils/betas.ts +0 -20
  245. package/src/utils/browser.ts +0 -14
  246. package/src/utils/cleanup.ts +0 -72
  247. package/src/utils/commands.ts +0 -261
  248. package/src/utils/commonUnixCommands.ts +0 -161
  249. package/src/utils/config.ts +0 -945
  250. package/src/utils/conversationRecovery.ts +0 -55
  251. package/src/utils/debugLogger.ts +0 -1235
  252. package/src/utils/diff.ts +0 -42
  253. package/src/utils/env.ts +0 -57
  254. package/src/utils/errors.ts +0 -21
  255. package/src/utils/exampleCommands.ts +0 -109
  256. package/src/utils/execFileNoThrow.ts +0 -51
  257. package/src/utils/expertChatStorage.ts +0 -136
  258. package/src/utils/file.ts +0 -405
  259. package/src/utils/fileRecoveryCore.ts +0 -71
  260. package/src/utils/format.tsx +0 -44
  261. package/src/utils/fuzzyMatcher.ts +0 -328
  262. package/src/utils/generators.ts +0 -62
  263. package/src/utils/git.ts +0 -92
  264. package/src/utils/globalLogger.ts +0 -77
  265. package/src/utils/http.ts +0 -10
  266. package/src/utils/imagePaste.ts +0 -38
  267. package/src/utils/json.ts +0 -13
  268. package/src/utils/log.ts +0 -382
  269. package/src/utils/markdown.ts +0 -213
  270. package/src/utils/messageContextManager.ts +0 -294
  271. package/src/utils/messages.tsx +0 -945
  272. package/src/utils/model.ts +0 -914
  273. package/src/utils/permissions/filesystem.ts +0 -127
  274. package/src/utils/responseState.ts +0 -23
  275. package/src/utils/ripgrep.ts +0 -167
  276. package/src/utils/secureFile.ts +0 -564
  277. package/src/utils/sessionState.ts +0 -49
  278. package/src/utils/state.ts +0 -25
  279. package/src/utils/style.ts +0 -29
  280. package/src/utils/terminal.ts +0 -50
  281. package/src/utils/theme.ts +0 -127
  282. package/src/utils/thinking.ts +0 -144
  283. package/src/utils/todoStorage.ts +0 -431
  284. package/src/utils/tokens.ts +0 -43
  285. package/src/utils/toolExecutionController.ts +0 -163
  286. package/src/utils/unaryLogging.ts +0 -26
  287. package/src/utils/user.ts +0 -37
  288. package/src/utils/validate.ts +0 -165
@@ -1,357 +0,0 @@
1
- import * as crypto from 'crypto'
2
- import * as http from 'http'
3
- import { IncomingMessage, ServerResponse } from 'http'
4
- import * as url from 'url'
5
-
6
- import { OAUTH_CONFIG } from '../constants/oauth'
7
- import { openBrowser } from '../utils/browser'
8
- import { logEvent } from '../services/statsig'
9
- import { logError } from '../utils/log'
10
- import { resetAnthropicClient } from './claude'
11
- import {
12
- AccountInfo,
13
- getGlobalConfig,
14
- saveGlobalConfig,
15
- normalizeApiKeyForConfig,
16
- } from '../utils/config.js'
17
-
18
- // Base64URL encoding function (RFC 4648)
19
- function base64URLEncode(buffer: Buffer): string {
20
- return buffer
21
- .toString('base64')
22
- .replace(/\+/g, '-')
23
- .replace(/\//g, '_')
24
- .replace(/=/g, '')
25
- }
26
-
27
- function generateCodeVerifier(): string {
28
- return base64URLEncode(crypto.randomBytes(32))
29
- }
30
-
31
- async function generateCodeChallenge(verifier: string): Promise<string> {
32
- const encoder = new TextEncoder()
33
- const data = encoder.encode(verifier)
34
- const digest = await crypto.subtle.digest('SHA-256', data)
35
- return base64URLEncode(Buffer.from(digest))
36
- }
37
-
38
- type OAuthTokenExchangeResponse = {
39
- access_token: string
40
- account?: {
41
- uuid: string
42
- email_address: string
43
- }
44
- organization?: {
45
- uuid: string
46
- name: string
47
- }
48
- }
49
-
50
- export type OAuthResult = {
51
- accessToken: string
52
- }
53
-
54
- export class OAuthService {
55
- private server: http.Server | null = null
56
- private codeVerifier: string
57
- private expectedState: string | null = null
58
- private pendingCodePromise: {
59
- resolve: (result: {
60
- authorizationCode: string
61
- useManualRedirect: boolean
62
- }) => void
63
- reject: (err: Error) => void
64
- } | null = null
65
-
66
- constructor() {
67
- this.codeVerifier = generateCodeVerifier()
68
- }
69
-
70
- private generateAuthUrls(
71
- codeChallenge: string,
72
- state: string,
73
- ): { autoUrl: string; manualUrl: string } {
74
- function makeUrl(isManual: boolean): string {
75
- const authUrl = new URL(OAUTH_CONFIG.AUTHORIZE_URL)
76
- authUrl.searchParams.append('client_id', OAUTH_CONFIG.CLIENT_ID)
77
- authUrl.searchParams.append('response_type', 'code')
78
- authUrl.searchParams.append(
79
- 'redirect_uri',
80
- isManual
81
- ? OAUTH_CONFIG.MANUAL_REDIRECT_URL
82
- : `http://localhost:${OAUTH_CONFIG.REDIRECT_PORT}/callback`,
83
- )
84
- authUrl.searchParams.append('scope', OAUTH_CONFIG.SCOPES.join(' '))
85
- authUrl.searchParams.append('code_challenge', codeChallenge)
86
- authUrl.searchParams.append('code_challenge_method', 'S256')
87
- authUrl.searchParams.append('state', state)
88
- return authUrl.toString()
89
- }
90
-
91
- return {
92
- autoUrl: makeUrl(false),
93
- manualUrl: makeUrl(true),
94
- }
95
- }
96
-
97
- async startOAuthFlow(
98
- authURLHandler: (url: string) => Promise<void>,
99
- ): Promise<OAuthResult> {
100
- const codeChallenge = await generateCodeChallenge(this.codeVerifier)
101
- const state = base64URLEncode(crypto.randomBytes(32))
102
- this.expectedState = state
103
- const { autoUrl, manualUrl } = this.generateAuthUrls(codeChallenge, state)
104
-
105
- const onReady = async () => {
106
- await authURLHandler(manualUrl)
107
- await openBrowser(autoUrl)
108
- }
109
-
110
- const { authorizationCode, useManualRedirect } = await new Promise<{
111
- authorizationCode: string
112
- useManualRedirect: boolean
113
- }>((resolve, reject) => {
114
- this.pendingCodePromise = { resolve, reject }
115
- this.startLocalServer(state, onReady)
116
- })
117
-
118
- // Exchange code for tokens
119
- const {
120
- access_token: accessToken,
121
- account,
122
- organization,
123
- } = await this.exchangeCodeForTokens(
124
- authorizationCode,
125
- state,
126
- useManualRedirect,
127
- )
128
-
129
- // Store account info
130
- if (account) {
131
- const accountInfo: AccountInfo = {
132
- accountUuid: account.uuid,
133
- emailAddress: account.email_address,
134
- organizationUuid: organization?.uuid,
135
- }
136
- const config = getGlobalConfig()
137
- config.oauthAccount = accountInfo
138
- saveGlobalConfig(config)
139
- }
140
-
141
- return { accessToken }
142
- }
143
-
144
- private startLocalServer(state: string, onReady?: () => void): void {
145
- if (this.server) {
146
- this.closeServer()
147
- }
148
- this.server = http.createServer(
149
- (req: IncomingMessage, res: ServerResponse) => {
150
- const parsedUrl = url.parse(req.url || '', true)
151
-
152
- if (parsedUrl.pathname === '/callback') {
153
- const authorizationCode = parsedUrl.query.code as string
154
- const returnedState = parsedUrl.query.state as string
155
-
156
- if (!authorizationCode) {
157
- res.writeHead(400)
158
- res.end('Authorization code not found')
159
- if (this.pendingCodePromise) {
160
- this.pendingCodePromise.reject(
161
- new Error('No authorization code received'),
162
- )
163
- }
164
- return
165
- }
166
-
167
- if (returnedState !== state) {
168
- res.writeHead(400)
169
- res.end('Invalid state parameter')
170
- if (this.pendingCodePromise) {
171
- this.pendingCodePromise.reject(
172
- new Error('Invalid state parameter'), // Possible CSRF attack
173
- )
174
- }
175
- return
176
- }
177
-
178
- res.writeHead(302, {
179
- Location: OAUTH_CONFIG.SUCCESS_URL,
180
- })
181
- res.end()
182
-
183
- // Track which path the user is taking (automatic browser redirect)
184
- logEvent('tengu_oauth_automatic_redirect', {})
185
-
186
- this.processCallback({
187
- authorizationCode,
188
- state,
189
- useManualRedirect: false,
190
- })
191
- } else {
192
- res.writeHead(404)
193
- res.end()
194
- }
195
- },
196
- )
197
-
198
- this.server.listen(OAUTH_CONFIG.REDIRECT_PORT, async () => {
199
- onReady?.()
200
- })
201
-
202
- this.server.on('error', (err: Error) => {
203
- const portError = err as NodeJS.ErrnoException
204
- if (portError.code === 'EADDRINUSE') {
205
- const error = new Error(
206
- `Port ${OAUTH_CONFIG.REDIRECT_PORT} is already in use. Please ensure no other applications are using this port.`,
207
- )
208
- logError(error)
209
- this.closeServer()
210
- if (this.pendingCodePromise) {
211
- this.pendingCodePromise.reject(error)
212
- }
213
- return
214
- } else {
215
- logError(err)
216
- this.closeServer()
217
- if (this.pendingCodePromise) {
218
- this.pendingCodePromise.reject(err)
219
- }
220
- return
221
- }
222
- })
223
- }
224
-
225
- private async exchangeCodeForTokens(
226
- authorizationCode: string,
227
- state: string,
228
- useManualRedirect: boolean = false,
229
- ): Promise<OAuthTokenExchangeResponse> {
230
- const requestBody = {
231
- grant_type: 'authorization_code',
232
- code: authorizationCode,
233
- redirect_uri: useManualRedirect
234
- ? OAUTH_CONFIG.MANUAL_REDIRECT_URL
235
- : `http://localhost:${OAUTH_CONFIG.REDIRECT_PORT}/callback`,
236
- client_id: OAUTH_CONFIG.CLIENT_ID,
237
- code_verifier: this.codeVerifier,
238
- state,
239
- }
240
-
241
- const response = await fetch(OAUTH_CONFIG.TOKEN_URL, {
242
- method: 'POST',
243
- headers: {
244
- 'Content-Type': 'application/json',
245
- },
246
- body: JSON.stringify(requestBody),
247
- })
248
-
249
- if (!response.ok) {
250
- throw new Error(`Token exchange failed: ${response.statusText}`)
251
- }
252
-
253
- const data = await response.json()
254
- return data
255
- }
256
-
257
- processCallback({
258
- authorizationCode,
259
- state,
260
- useManualRedirect,
261
- }: {
262
- authorizationCode: string
263
- state: string
264
- useManualRedirect: boolean
265
- }): void {
266
- this.closeServer()
267
-
268
- if (state !== this.expectedState) {
269
- if (this.pendingCodePromise) {
270
- this.pendingCodePromise.reject(
271
- new Error('Invalid state parameter'), // Possible CSRF attack
272
- )
273
- this.pendingCodePromise = null
274
- }
275
- return
276
- }
277
-
278
- if (this.pendingCodePromise) {
279
- this.pendingCodePromise.resolve({ authorizationCode, useManualRedirect })
280
- this.pendingCodePromise = null
281
- }
282
- }
283
-
284
- private closeServer(): void {
285
- if (this.server) {
286
- this.server.close()
287
- this.server = null
288
- }
289
- }
290
- }
291
-
292
- export async function createAndStoreApiKey(
293
- accessToken: string,
294
- ): Promise<string | null> {
295
- try {
296
- // Call create_api_key endpoint
297
- const createApiKeyResp = await fetch(OAUTH_CONFIG.API_KEY_URL, {
298
- method: 'POST',
299
- headers: { Authorization: `Bearer ${accessToken}` },
300
- })
301
-
302
- let apiKeyData
303
- let errorText = ''
304
-
305
- try {
306
- apiKeyData = await createApiKeyResp.json()
307
- } catch (_e) {
308
- // If response is not valid JSON, get as text for error logging
309
- errorText = await createApiKeyResp.text()
310
- }
311
-
312
- logEvent('tengu_oauth_api_key', {
313
- status: createApiKeyResp.ok ? 'success' : 'failure',
314
- statusCode: createApiKeyResp.status.toString(),
315
- error: createApiKeyResp.ok ? '' : errorText || JSON.stringify(apiKeyData),
316
- })
317
-
318
- if (createApiKeyResp.ok && apiKeyData && apiKeyData.raw_key) {
319
- const apiKey = apiKeyData.raw_key
320
-
321
- // Store in global config
322
- const config = getGlobalConfig()
323
-
324
- // Note: API key is now managed per model profile
325
-
326
- // Add to approved list
327
- if (!config.customApiKeyResponses) {
328
- config.customApiKeyResponses = { approved: [], rejected: [] }
329
- }
330
- if (!config.customApiKeyResponses.approved) {
331
- config.customApiKeyResponses.approved = []
332
- }
333
-
334
- const normalizedKey = normalizeApiKeyForConfig(apiKey)
335
- if (!config.customApiKeyResponses.approved.includes(normalizedKey)) {
336
- config.customApiKeyResponses.approved.push(normalizedKey)
337
- }
338
-
339
- // Save config
340
- saveGlobalConfig(config)
341
-
342
- // Reset the Anthropic client to force creation with new API key
343
- resetAnthropicClient()
344
-
345
- return apiKey
346
- }
347
-
348
- return null
349
- } catch (error) {
350
- logEvent('tengu_oauth_api_key', {
351
- status: 'failure',
352
- statusCode: 'exception',
353
- error: error instanceof Error ? error.message : String(error),
354
- })
355
- throw error
356
- }
357
- }