@shareai-lab/kode 1.1.14 → 1.1.16-dev.2
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.
- package/cli.js +77 -82
- package/dist/entrypoints/cli.js +59 -38
- package/dist/entrypoints/cli.js.map +3 -3
- package/dist/index.js +5 -26
- package/dist/package.json +4 -1
- package/package.json +11 -104
- package/dist/test/testAdapters.js +0 -88
- package/dist/test/testAdapters.js.map +0 -1
- package/src/ProjectOnboarding.tsx +0 -198
- package/src/Tool.ts +0 -83
- package/src/commands/agents.tsx +0 -3416
- package/src/commands/approvedTools.ts +0 -53
- package/src/commands/bug.tsx +0 -20
- package/src/commands/clear.ts +0 -43
- package/src/commands/compact.ts +0 -120
- package/src/commands/config.tsx +0 -19
- package/src/commands/cost.ts +0 -18
- package/src/commands/ctx_viz.ts +0 -209
- package/src/commands/doctor.ts +0 -24
- package/src/commands/help.tsx +0 -19
- package/src/commands/init.ts +0 -37
- package/src/commands/listen.ts +0 -42
- package/src/commands/login.tsx +0 -51
- package/src/commands/logout.tsx +0 -40
- package/src/commands/mcp.ts +0 -41
- package/src/commands/model.tsx +0 -40
- package/src/commands/modelstatus.tsx +0 -20
- package/src/commands/onboarding.tsx +0 -34
- package/src/commands/pr_comments.ts +0 -59
- package/src/commands/refreshCommands.ts +0 -54
- package/src/commands/release-notes.ts +0 -34
- package/src/commands/resume.tsx +0 -31
- package/src/commands/review.ts +0 -49
- package/src/commands/terminalSetup.ts +0 -221
- package/src/commands.ts +0 -139
- package/src/components/ApproveApiKey.tsx +0 -93
- package/src/components/AsciiLogo.tsx +0 -13
- package/src/components/AutoUpdater.tsx +0 -148
- package/src/components/Bug.tsx +0 -367
- package/src/components/Config.tsx +0 -293
- package/src/components/ConsoleOAuthFlow.tsx +0 -327
- package/src/components/Cost.tsx +0 -23
- package/src/components/CostThresholdDialog.tsx +0 -46
- package/src/components/CustomSelect/option-map.ts +0 -42
- package/src/components/CustomSelect/select-option.tsx +0 -78
- package/src/components/CustomSelect/select.tsx +0 -152
- package/src/components/CustomSelect/theme.ts +0 -45
- package/src/components/CustomSelect/use-select-state.ts +0 -414
- package/src/components/CustomSelect/use-select.ts +0 -35
- package/src/components/FallbackToolUseRejectedMessage.tsx +0 -15
- package/src/components/FileEditToolUpdatedMessage.tsx +0 -66
- package/src/components/Help.tsx +0 -215
- package/src/components/HighlightedCode.tsx +0 -33
- package/src/components/InvalidConfigDialog.tsx +0 -113
- package/src/components/Link.tsx +0 -32
- package/src/components/LogSelector.tsx +0 -86
- package/src/components/Logo.tsx +0 -170
- package/src/components/MCPServerApprovalDialog.tsx +0 -100
- package/src/components/MCPServerDialogCopy.tsx +0 -25
- package/src/components/MCPServerMultiselectDialog.tsx +0 -109
- package/src/components/Message.tsx +0 -221
- package/src/components/MessageResponse.tsx +0 -15
- package/src/components/MessageSelector.tsx +0 -211
- package/src/components/ModeIndicator.tsx +0 -88
- package/src/components/ModelConfig.tsx +0 -301
- package/src/components/ModelListManager.tsx +0 -227
- package/src/components/ModelSelector.tsx +0 -3387
- package/src/components/ModelStatusDisplay.tsx +0 -230
- package/src/components/Onboarding.tsx +0 -274
- package/src/components/PressEnterToContinue.tsx +0 -11
- package/src/components/PromptInput.tsx +0 -760
- package/src/components/SentryErrorBoundary.ts +0 -39
- package/src/components/Spinner.tsx +0 -129
- package/src/components/StickerRequestForm.tsx +0 -16
- package/src/components/StructuredDiff.tsx +0 -191
- package/src/components/TextInput.tsx +0 -259
- package/src/components/TodoItem.tsx +0 -47
- package/src/components/TokenWarning.tsx +0 -31
- package/src/components/ToolUseLoader.tsx +0 -40
- package/src/components/TrustDialog.tsx +0 -106
- package/src/components/binary-feedback/BinaryFeedback.tsx +0 -63
- package/src/components/binary-feedback/BinaryFeedbackOption.tsx +0 -111
- package/src/components/binary-feedback/BinaryFeedbackView.tsx +0 -172
- package/src/components/binary-feedback/utils.ts +0 -220
- package/src/components/messages/AssistantBashOutputMessage.tsx +0 -22
- package/src/components/messages/AssistantLocalCommandOutputMessage.tsx +0 -49
- package/src/components/messages/AssistantRedactedThinkingMessage.tsx +0 -19
- package/src/components/messages/AssistantTextMessage.tsx +0 -144
- package/src/components/messages/AssistantThinkingMessage.tsx +0 -40
- package/src/components/messages/AssistantToolUseMessage.tsx +0 -132
- package/src/components/messages/TaskProgressMessage.tsx +0 -32
- package/src/components/messages/TaskToolMessage.tsx +0 -58
- package/src/components/messages/UserBashInputMessage.tsx +0 -28
- package/src/components/messages/UserCommandMessage.tsx +0 -30
- package/src/components/messages/UserKodingInputMessage.tsx +0 -28
- package/src/components/messages/UserPromptMessage.tsx +0 -35
- package/src/components/messages/UserTextMessage.tsx +0 -39
- package/src/components/messages/UserToolResultMessage/UserToolCanceledMessage.tsx +0 -12
- package/src/components/messages/UserToolResultMessage/UserToolErrorMessage.tsx +0 -36
- package/src/components/messages/UserToolResultMessage/UserToolRejectMessage.tsx +0 -31
- package/src/components/messages/UserToolResultMessage/UserToolResultMessage.tsx +0 -57
- package/src/components/messages/UserToolResultMessage/UserToolSuccessMessage.tsx +0 -35
- package/src/components/messages/UserToolResultMessage/utils.tsx +0 -56
- package/src/components/permissions/BashPermissionRequest/BashPermissionRequest.tsx +0 -121
- package/src/components/permissions/FallbackPermissionRequest.tsx +0 -153
- package/src/components/permissions/FileEditPermissionRequest/FileEditPermissionRequest.tsx +0 -182
- package/src/components/permissions/FileEditPermissionRequest/FileEditToolDiff.tsx +0 -77
- package/src/components/permissions/FileWritePermissionRequest/FileWritePermissionRequest.tsx +0 -164
- package/src/components/permissions/FileWritePermissionRequest/FileWriteToolDiff.tsx +0 -83
- package/src/components/permissions/FilesystemPermissionRequest/FilesystemPermissionRequest.tsx +0 -240
- package/src/components/permissions/PermissionRequest.tsx +0 -101
- package/src/components/permissions/PermissionRequestTitle.tsx +0 -69
- package/src/components/permissions/hooks.ts +0 -44
- package/src/components/permissions/toolUseOptions.ts +0 -59
- package/src/components/permissions/utils.ts +0 -23
- package/src/constants/betas.ts +0 -5
- package/src/constants/claude-asterisk-ascii-art.tsx +0 -238
- package/src/constants/figures.ts +0 -4
- package/src/constants/keys.ts +0 -3
- package/src/constants/macros.ts +0 -11
- package/src/constants/modelCapabilities.ts +0 -179
- package/src/constants/models.ts +0 -1025
- package/src/constants/oauth.ts +0 -18
- package/src/constants/product.ts +0 -17
- package/src/constants/prompts.ts +0 -168
- package/src/constants/releaseNotes.ts +0 -7
- package/src/context/PermissionContext.tsx +0 -149
- package/src/context.ts +0 -278
- package/src/cost-tracker.ts +0 -84
- package/src/entrypoints/cli.tsx +0 -1561
- package/src/entrypoints/mcp.ts +0 -175
- package/src/history.ts +0 -25
- package/src/hooks/useApiKeyVerification.ts +0 -59
- package/src/hooks/useArrowKeyHistory.ts +0 -55
- package/src/hooks/useCanUseTool.ts +0 -138
- package/src/hooks/useCancelRequest.ts +0 -39
- package/src/hooks/useDoublePress.ts +0 -41
- package/src/hooks/useExitOnCtrlCD.ts +0 -31
- package/src/hooks/useInterval.ts +0 -25
- package/src/hooks/useLogMessages.ts +0 -16
- package/src/hooks/useLogStartupTime.ts +0 -12
- package/src/hooks/useNotifyAfterTimeout.ts +0 -65
- package/src/hooks/usePermissionRequestLogging.ts +0 -44
- package/src/hooks/useTerminalSize.ts +0 -49
- package/src/hooks/useTextInput.ts +0 -317
- package/src/hooks/useUnifiedCompletion.ts +0 -1405
- package/src/index.ts +0 -34
- package/src/messages.ts +0 -38
- package/src/permissions.ts +0 -268
- package/src/query.ts +0 -720
- package/src/screens/ConfigureNpmPrefix.tsx +0 -197
- package/src/screens/Doctor.tsx +0 -219
- package/src/screens/LogList.tsx +0 -68
- package/src/screens/REPL.tsx +0 -813
- package/src/screens/ResumeConversation.tsx +0 -68
- package/src/services/adapters/base.ts +0 -38
- package/src/services/adapters/chatCompletions.ts +0 -90
- package/src/services/adapters/responsesAPI.ts +0 -170
- package/src/services/browserMocks.ts +0 -66
- package/src/services/claude.ts +0 -2197
- package/src/services/customCommands.ts +0 -704
- package/src/services/fileFreshness.ts +0 -377
- package/src/services/gpt5ConnectionTest.ts +0 -340
- package/src/services/mcpClient.ts +0 -564
- package/src/services/mcpServerApproval.tsx +0 -50
- package/src/services/mentionProcessor.ts +0 -273
- package/src/services/modelAdapterFactory.ts +0 -69
- package/src/services/notifier.ts +0 -40
- package/src/services/oauth.ts +0 -357
- package/src/services/openai.ts +0 -1359
- package/src/services/responseStateManager.ts +0 -90
- package/src/services/sentry.ts +0 -3
- package/src/services/statsig.ts +0 -172
- package/src/services/statsigStorage.ts +0 -86
- package/src/services/systemReminder.ts +0 -507
- package/src/services/vcr.ts +0 -161
- package/src/test/testAdapters.ts +0 -96
- package/src/tools/ArchitectTool/ArchitectTool.tsx +0 -135
- package/src/tools/ArchitectTool/prompt.ts +0 -15
- package/src/tools/AskExpertModelTool/AskExpertModelTool.tsx +0 -576
- package/src/tools/BashTool/BashTool.tsx +0 -243
- package/src/tools/BashTool/BashToolResultMessage.tsx +0 -38
- package/src/tools/BashTool/OutputLine.tsx +0 -49
- package/src/tools/BashTool/prompt.ts +0 -174
- package/src/tools/BashTool/utils.ts +0 -56
- package/src/tools/FileEditTool/FileEditTool.tsx +0 -319
- package/src/tools/FileEditTool/prompt.ts +0 -51
- package/src/tools/FileEditTool/utils.ts +0 -58
- package/src/tools/FileReadTool/FileReadTool.tsx +0 -404
- package/src/tools/FileReadTool/prompt.ts +0 -7
- package/src/tools/FileWriteTool/FileWriteTool.tsx +0 -301
- package/src/tools/FileWriteTool/prompt.ts +0 -10
- package/src/tools/GlobTool/GlobTool.tsx +0 -119
- package/src/tools/GlobTool/prompt.ts +0 -8
- package/src/tools/GrepTool/GrepTool.tsx +0 -147
- package/src/tools/GrepTool/prompt.ts +0 -11
- package/src/tools/MCPTool/MCPTool.tsx +0 -107
- package/src/tools/MCPTool/prompt.ts +0 -3
- package/src/tools/MemoryReadTool/MemoryReadTool.tsx +0 -127
- package/src/tools/MemoryReadTool/prompt.ts +0 -3
- package/src/tools/MemoryWriteTool/MemoryWriteTool.tsx +0 -89
- package/src/tools/MemoryWriteTool/prompt.ts +0 -3
- package/src/tools/MultiEditTool/MultiEditTool.tsx +0 -388
- package/src/tools/MultiEditTool/prompt.ts +0 -45
- package/src/tools/NotebookEditTool/NotebookEditTool.tsx +0 -298
- package/src/tools/NotebookEditTool/prompt.ts +0 -3
- package/src/tools/NotebookReadTool/NotebookReadTool.tsx +0 -258
- package/src/tools/NotebookReadTool/prompt.ts +0 -3
- package/src/tools/StickerRequestTool/StickerRequestTool.tsx +0 -107
- package/src/tools/StickerRequestTool/prompt.ts +0 -19
- package/src/tools/TaskTool/TaskTool.tsx +0 -438
- package/src/tools/TaskTool/constants.ts +0 -1
- package/src/tools/TaskTool/prompt.ts +0 -92
- package/src/tools/ThinkTool/ThinkTool.tsx +0 -54
- package/src/tools/ThinkTool/prompt.ts +0 -12
- package/src/tools/TodoWriteTool/TodoWriteTool.tsx +0 -313
- package/src/tools/TodoWriteTool/prompt.ts +0 -63
- package/src/tools/URLFetcherTool/URLFetcherTool.tsx +0 -178
- package/src/tools/URLFetcherTool/cache.ts +0 -55
- package/src/tools/URLFetcherTool/htmlToMarkdown.ts +0 -55
- package/src/tools/URLFetcherTool/prompt.ts +0 -17
- package/src/tools/WebSearchTool/WebSearchTool.tsx +0 -103
- package/src/tools/WebSearchTool/prompt.ts +0 -13
- package/src/tools/WebSearchTool/searchProviders.ts +0 -66
- package/src/tools/lsTool/lsTool.tsx +0 -272
- package/src/tools/lsTool/prompt.ts +0 -2
- package/src/tools.ts +0 -67
- package/src/types/PermissionMode.ts +0 -120
- package/src/types/RequestContext.ts +0 -72
- package/src/types/common.d.ts +0 -2
- package/src/types/conversation.ts +0 -51
- package/src/types/logs.ts +0 -58
- package/src/types/modelCapabilities.ts +0 -64
- package/src/types/notebook.ts +0 -87
- package/src/utils/Cursor.ts +0 -436
- package/src/utils/PersistentShell.ts +0 -552
- package/src/utils/advancedFuzzyMatcher.ts +0 -290
- package/src/utils/agentLoader.ts +0 -278
- package/src/utils/agentStorage.ts +0 -97
- package/src/utils/array.ts +0 -3
- package/src/utils/ask.tsx +0 -99
- package/src/utils/auth.ts +0 -13
- package/src/utils/autoCompactCore.ts +0 -223
- package/src/utils/autoUpdater.ts +0 -458
- package/src/utils/betas.ts +0 -20
- package/src/utils/browser.ts +0 -14
- package/src/utils/cleanup.ts +0 -72
- package/src/utils/commands.ts +0 -261
- package/src/utils/commonUnixCommands.ts +0 -161
- package/src/utils/config.ts +0 -945
- package/src/utils/conversationRecovery.ts +0 -55
- package/src/utils/debugLogger.ts +0 -1235
- package/src/utils/diff.ts +0 -42
- package/src/utils/env.ts +0 -57
- package/src/utils/errors.ts +0 -21
- package/src/utils/exampleCommands.ts +0 -109
- package/src/utils/execFileNoThrow.ts +0 -51
- package/src/utils/expertChatStorage.ts +0 -136
- package/src/utils/file.ts +0 -405
- package/src/utils/fileRecoveryCore.ts +0 -71
- package/src/utils/format.tsx +0 -44
- package/src/utils/fuzzyMatcher.ts +0 -328
- package/src/utils/generators.ts +0 -62
- package/src/utils/git.ts +0 -92
- package/src/utils/globalLogger.ts +0 -77
- package/src/utils/http.ts +0 -10
- package/src/utils/imagePaste.ts +0 -38
- package/src/utils/json.ts +0 -13
- package/src/utils/log.ts +0 -382
- package/src/utils/markdown.ts +0 -213
- package/src/utils/messageContextManager.ts +0 -294
- package/src/utils/messages.tsx +0 -945
- package/src/utils/model.ts +0 -914
- package/src/utils/permissions/filesystem.ts +0 -127
- package/src/utils/responseState.ts +0 -23
- package/src/utils/ripgrep.ts +0 -167
- package/src/utils/secureFile.ts +0 -564
- package/src/utils/sessionState.ts +0 -49
- package/src/utils/state.ts +0 -25
- package/src/utils/style.ts +0 -29
- package/src/utils/terminal.ts +0 -50
- package/src/utils/theme.ts +0 -127
- package/src/utils/thinking.ts +0 -144
- package/src/utils/todoStorage.ts +0 -431
- package/src/utils/tokens.ts +0 -43
- package/src/utils/toolExecutionController.ts +0 -163
- package/src/utils/unaryLogging.ts +0 -26
- package/src/utils/user.ts +0 -37
- package/src/utils/validate.ts +0 -165
|
@@ -1,327 +0,0 @@
|
|
|
1
|
-
import React, { useEffect, useState, useCallback } from 'react'
|
|
2
|
-
import { Static, Box, Text, useInput } from 'ink'
|
|
3
|
-
import TextInput from './TextInput'
|
|
4
|
-
import { OAuthService, createAndStoreApiKey } from '../services/oauth'
|
|
5
|
-
import { getTheme } from '../utils/theme'
|
|
6
|
-
import { logEvent } from '../services/statsig'
|
|
7
|
-
import { AsciiLogo } from './AsciiLogo'
|
|
8
|
-
import { useTerminalSize } from '../hooks/useTerminalSize'
|
|
9
|
-
import { logError } from '../utils/log'
|
|
10
|
-
import { clearTerminal } from '../utils/terminal'
|
|
11
|
-
import { SimpleSpinner } from './Spinner'
|
|
12
|
-
import { WelcomeBox } from './Onboarding'
|
|
13
|
-
import { PRODUCT_NAME } from '../constants/product'
|
|
14
|
-
import { sendNotification } from '../services/notifier'
|
|
15
|
-
|
|
16
|
-
type Props = {
|
|
17
|
-
onDone(): void
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
type OAuthStatus =
|
|
21
|
-
| { state: 'idle' }
|
|
22
|
-
| { state: 'ready_to_start' }
|
|
23
|
-
| { state: 'waiting_for_login'; url: string }
|
|
24
|
-
| { state: 'creating_api_key' }
|
|
25
|
-
| { state: 'about_to_retry'; nextState: OAuthStatus }
|
|
26
|
-
| { state: 'success'; apiKey: string }
|
|
27
|
-
| {
|
|
28
|
-
state: 'error'
|
|
29
|
-
message: string
|
|
30
|
-
toRetry?: OAuthStatus
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const PASTE_HERE_MSG = 'Paste code here if prompted > '
|
|
34
|
-
|
|
35
|
-
export function ConsoleOAuthFlow({ onDone }: Props): React.ReactNode {
|
|
36
|
-
const [oauthStatus, setOAuthStatus] = useState<OAuthStatus>({
|
|
37
|
-
state: 'idle',
|
|
38
|
-
})
|
|
39
|
-
const theme = getTheme()
|
|
40
|
-
|
|
41
|
-
const [pastedCode, setPastedCode] = useState('')
|
|
42
|
-
const [cursorOffset, setCursorOffset] = useState(0)
|
|
43
|
-
const [oauthService] = useState(() => new OAuthService())
|
|
44
|
-
// After a few seconds we suggest the user to copy/paste url if the
|
|
45
|
-
// browser did not open automatically. In this flow we expect the user to
|
|
46
|
-
// copy the code from the browser and paste it in the terminal
|
|
47
|
-
const [showPastePrompt, setShowPastePrompt] = useState(false)
|
|
48
|
-
// we need a special clearing state to correctly re-render Static elements
|
|
49
|
-
const [isClearing, setIsClearing] = useState(false)
|
|
50
|
-
|
|
51
|
-
const textInputColumns = useTerminalSize().columns - PASTE_HERE_MSG.length - 1
|
|
52
|
-
|
|
53
|
-
useEffect(() => {
|
|
54
|
-
if (isClearing) {
|
|
55
|
-
clearTerminal()
|
|
56
|
-
setIsClearing(false)
|
|
57
|
-
}
|
|
58
|
-
}, [isClearing])
|
|
59
|
-
|
|
60
|
-
// Retry logic
|
|
61
|
-
useEffect(() => {
|
|
62
|
-
if (oauthStatus.state === 'about_to_retry') {
|
|
63
|
-
setIsClearing(true)
|
|
64
|
-
setTimeout(() => {
|
|
65
|
-
setOAuthStatus(oauthStatus.nextState)
|
|
66
|
-
}, 1000)
|
|
67
|
-
}
|
|
68
|
-
}, [oauthStatus])
|
|
69
|
-
|
|
70
|
-
useInput(async (_, key) => {
|
|
71
|
-
if (key.return) {
|
|
72
|
-
if (oauthStatus.state === 'idle') {
|
|
73
|
-
logEvent('tengu_oauth_start', {})
|
|
74
|
-
setOAuthStatus({ state: 'ready_to_start' })
|
|
75
|
-
} else if (oauthStatus.state === 'success') {
|
|
76
|
-
logEvent('tengu_oauth_success', {})
|
|
77
|
-
await clearTerminal() // needed to clear out Static components
|
|
78
|
-
onDone()
|
|
79
|
-
} else if (oauthStatus.state === 'error' && oauthStatus.toRetry) {
|
|
80
|
-
setPastedCode('')
|
|
81
|
-
setOAuthStatus({
|
|
82
|
-
state: 'about_to_retry',
|
|
83
|
-
nextState: oauthStatus.toRetry,
|
|
84
|
-
})
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
async function handleSubmitCode(value: string, url: string) {
|
|
90
|
-
try {
|
|
91
|
-
// Expecting format "authorizationCode#state" from the authorization callback URL
|
|
92
|
-
const [authorizationCode, state] = value.split('#')
|
|
93
|
-
|
|
94
|
-
if (!authorizationCode || !state) {
|
|
95
|
-
setOAuthStatus({
|
|
96
|
-
state: 'error',
|
|
97
|
-
message: 'Invalid code. Please make sure the full code was copied',
|
|
98
|
-
toRetry: { state: 'waiting_for_login', url },
|
|
99
|
-
})
|
|
100
|
-
return
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
// Track which path the user is taking (manual code entry)
|
|
104
|
-
logEvent('tengu_oauth_manual_entry', {})
|
|
105
|
-
oauthService.processCallback({
|
|
106
|
-
authorizationCode,
|
|
107
|
-
state,
|
|
108
|
-
useManualRedirect: true,
|
|
109
|
-
})
|
|
110
|
-
} catch (err) {
|
|
111
|
-
logError(err)
|
|
112
|
-
setOAuthStatus({
|
|
113
|
-
state: 'error',
|
|
114
|
-
message: (err as Error).message,
|
|
115
|
-
toRetry: { state: 'waiting_for_login', url },
|
|
116
|
-
})
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
const startOAuth = useCallback(async () => {
|
|
121
|
-
try {
|
|
122
|
-
const result = await oauthService
|
|
123
|
-
.startOAuthFlow(async url => {
|
|
124
|
-
setOAuthStatus({ state: 'waiting_for_login', url })
|
|
125
|
-
setTimeout(() => setShowPastePrompt(true), 3000)
|
|
126
|
-
})
|
|
127
|
-
.catch(err => {
|
|
128
|
-
// Handle token exchange errors specifically
|
|
129
|
-
if (err.message.includes('Token exchange failed')) {
|
|
130
|
-
setOAuthStatus({
|
|
131
|
-
state: 'error',
|
|
132
|
-
message:
|
|
133
|
-
'Failed to exchange authorization code for access token. Please try again.',
|
|
134
|
-
toRetry: { state: 'ready_to_start' },
|
|
135
|
-
})
|
|
136
|
-
logEvent('tengu_oauth_token_exchange_error', { error: err.message })
|
|
137
|
-
} else {
|
|
138
|
-
// Handle other errors
|
|
139
|
-
setOAuthStatus({
|
|
140
|
-
state: 'error',
|
|
141
|
-
message: err.message,
|
|
142
|
-
toRetry: { state: 'ready_to_start' },
|
|
143
|
-
})
|
|
144
|
-
}
|
|
145
|
-
throw err
|
|
146
|
-
})
|
|
147
|
-
|
|
148
|
-
setOAuthStatus({ state: 'creating_api_key' })
|
|
149
|
-
|
|
150
|
-
const apiKey = await createAndStoreApiKey(result.accessToken).catch(
|
|
151
|
-
err => {
|
|
152
|
-
setOAuthStatus({
|
|
153
|
-
state: 'error',
|
|
154
|
-
message: 'Failed to create API key: ' + err.message,
|
|
155
|
-
toRetry: { state: 'ready_to_start' },
|
|
156
|
-
})
|
|
157
|
-
logEvent('tengu_oauth_api_key_error', { error: err.message })
|
|
158
|
-
throw err
|
|
159
|
-
},
|
|
160
|
-
)
|
|
161
|
-
|
|
162
|
-
if (apiKey) {
|
|
163
|
-
setOAuthStatus({ state: 'success', apiKey })
|
|
164
|
-
sendNotification({ message: 'Kode login successful' })
|
|
165
|
-
} else {
|
|
166
|
-
setOAuthStatus({
|
|
167
|
-
state: 'error',
|
|
168
|
-
message:
|
|
169
|
-
"Unable to create API key. The server accepted the request but didn't return a key.",
|
|
170
|
-
toRetry: { state: 'ready_to_start' },
|
|
171
|
-
})
|
|
172
|
-
logEvent('tengu_oauth_api_key_error', {
|
|
173
|
-
error: 'server_returned_no_key',
|
|
174
|
-
})
|
|
175
|
-
}
|
|
176
|
-
} catch (err) {
|
|
177
|
-
const errorMessage = (err as Error).message
|
|
178
|
-
logEvent('tengu_oauth_error', { error: errorMessage })
|
|
179
|
-
}
|
|
180
|
-
}, [oauthService, setShowPastePrompt])
|
|
181
|
-
|
|
182
|
-
useEffect(() => {
|
|
183
|
-
if (oauthStatus.state === 'ready_to_start') {
|
|
184
|
-
startOAuth()
|
|
185
|
-
}
|
|
186
|
-
}, [oauthStatus.state, startOAuth])
|
|
187
|
-
|
|
188
|
-
// Helper function to render the appropriate status message
|
|
189
|
-
function renderStatusMessage(): React.ReactNode {
|
|
190
|
-
switch (oauthStatus.state) {
|
|
191
|
-
case 'idle':
|
|
192
|
-
return (
|
|
193
|
-
<Box flexDirection="column" gap={1}>
|
|
194
|
-
<Text bold>
|
|
195
|
-
{PRODUCT_NAME} is billed based on API usage through your Anthropic
|
|
196
|
-
Console account.
|
|
197
|
-
</Text>
|
|
198
|
-
|
|
199
|
-
<Box>
|
|
200
|
-
<Text>
|
|
201
|
-
Pricing may evolve as we move towards general availability.
|
|
202
|
-
</Text>
|
|
203
|
-
</Box>
|
|
204
|
-
|
|
205
|
-
<Box marginTop={1}>
|
|
206
|
-
<Text color={theme.permission}>
|
|
207
|
-
Press <Text bold>Enter</Text> to login to your Anthropic Console
|
|
208
|
-
account…
|
|
209
|
-
</Text>
|
|
210
|
-
</Box>
|
|
211
|
-
</Box>
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
case 'waiting_for_login':
|
|
215
|
-
return (
|
|
216
|
-
<Box flexDirection="column" gap={1}>
|
|
217
|
-
{!showPastePrompt && (
|
|
218
|
-
<Box>
|
|
219
|
-
<SimpleSpinner />
|
|
220
|
-
<Text>Opening browser to sign in…</Text>
|
|
221
|
-
</Box>
|
|
222
|
-
)}
|
|
223
|
-
|
|
224
|
-
{showPastePrompt && (
|
|
225
|
-
<Box>
|
|
226
|
-
<Text>{PASTE_HERE_MSG}</Text>
|
|
227
|
-
<TextInput
|
|
228
|
-
value={pastedCode}
|
|
229
|
-
onChange={setPastedCode}
|
|
230
|
-
onSubmit={(value: string) =>
|
|
231
|
-
handleSubmitCode(value, oauthStatus.url)
|
|
232
|
-
}
|
|
233
|
-
cursorOffset={cursorOffset}
|
|
234
|
-
onChangeCursorOffset={setCursorOffset}
|
|
235
|
-
columns={textInputColumns}
|
|
236
|
-
/>
|
|
237
|
-
</Box>
|
|
238
|
-
)}
|
|
239
|
-
</Box>
|
|
240
|
-
)
|
|
241
|
-
|
|
242
|
-
case 'creating_api_key':
|
|
243
|
-
return (
|
|
244
|
-
<Box flexDirection="column" gap={1}>
|
|
245
|
-
<Box>
|
|
246
|
-
<SimpleSpinner />
|
|
247
|
-
<Text>Creating API key for Kode…</Text>
|
|
248
|
-
</Box>
|
|
249
|
-
</Box>
|
|
250
|
-
)
|
|
251
|
-
|
|
252
|
-
case 'about_to_retry':
|
|
253
|
-
return (
|
|
254
|
-
<Box flexDirection="column" gap={1}>
|
|
255
|
-
<Text color={theme.permission}>Retrying…</Text>
|
|
256
|
-
</Box>
|
|
257
|
-
)
|
|
258
|
-
|
|
259
|
-
case 'success':
|
|
260
|
-
return (
|
|
261
|
-
<Box flexDirection="column" gap={1}>
|
|
262
|
-
<Text color={theme.success}>
|
|
263
|
-
Login successful. Press <Text bold>Enter</Text> to continue…
|
|
264
|
-
</Text>
|
|
265
|
-
</Box>
|
|
266
|
-
)
|
|
267
|
-
|
|
268
|
-
case 'error':
|
|
269
|
-
return (
|
|
270
|
-
<Box flexDirection="column" gap={1}>
|
|
271
|
-
<Text color={theme.error}>OAuth error: {oauthStatus.message}</Text>
|
|
272
|
-
|
|
273
|
-
{oauthStatus.toRetry && (
|
|
274
|
-
<Box marginTop={1}>
|
|
275
|
-
<Text color={theme.permission}>
|
|
276
|
-
Press <Text bold>Enter</Text> to retry.
|
|
277
|
-
</Text>
|
|
278
|
-
</Box>
|
|
279
|
-
)}
|
|
280
|
-
</Box>
|
|
281
|
-
)
|
|
282
|
-
|
|
283
|
-
default:
|
|
284
|
-
return null
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// We need to render the copy-able URL statically to prevent Ink <Text> from inserting
|
|
289
|
-
// newlines in the middle of the URL (this breaks Safari). Because <Static> components are
|
|
290
|
-
// only rendered once top-to-bottom, we also need to make everything above the URL static.
|
|
291
|
-
const staticItems: Record<string, React.JSX.Element> = {}
|
|
292
|
-
if (!isClearing) {
|
|
293
|
-
staticItems.header = (
|
|
294
|
-
<Box key="header" flexDirection="column" gap={1}>
|
|
295
|
-
<WelcomeBox />
|
|
296
|
-
<Box paddingBottom={1} paddingLeft={1}>
|
|
297
|
-
<AsciiLogo />
|
|
298
|
-
</Box>
|
|
299
|
-
</Box>
|
|
300
|
-
)
|
|
301
|
-
}
|
|
302
|
-
if (oauthStatus.state === 'waiting_for_login' && showPastePrompt) {
|
|
303
|
-
staticItems.urlToCopy = (
|
|
304
|
-
<Box flexDirection="column" key="urlToCopy" gap={1} paddingBottom={1}>
|
|
305
|
-
<Box paddingX={1}>
|
|
306
|
-
<Text dimColor>
|
|
307
|
-
Browser didn't open? Use the url below to sign in:
|
|
308
|
-
</Text>
|
|
309
|
-
</Box>
|
|
310
|
-
<Box width={1000}>
|
|
311
|
-
<Text dimColor>{oauthStatus.url}</Text>
|
|
312
|
-
</Box>
|
|
313
|
-
</Box>
|
|
314
|
-
)
|
|
315
|
-
}
|
|
316
|
-
return (
|
|
317
|
-
<Box flexDirection="column" gap={1}>
|
|
318
|
-
<Static
|
|
319
|
-
items={Object.keys(staticItems)}
|
|
320
|
-
children={(item: string) => staticItems[item]}
|
|
321
|
-
/>
|
|
322
|
-
<Box paddingLeft={1} flexDirection="column" gap={1}>
|
|
323
|
-
{renderStatusMessage()}
|
|
324
|
-
</Box>
|
|
325
|
-
</Box>
|
|
326
|
-
)
|
|
327
|
-
}
|
package/src/components/Cost.tsx
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import * as React from 'react'
|
|
2
|
-
import { Box, Text } from 'ink'
|
|
3
|
-
|
|
4
|
-
type Props = {
|
|
5
|
-
costUSD: number
|
|
6
|
-
durationMs: number
|
|
7
|
-
debug: boolean
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export function Cost({ costUSD, durationMs, debug }: Props): React.ReactNode {
|
|
11
|
-
if (!debug) {
|
|
12
|
-
return null
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const durationInSeconds = (durationMs / 1000).toFixed(1)
|
|
16
|
-
return (
|
|
17
|
-
<Box flexDirection="column" minWidth={23} width={23}>
|
|
18
|
-
<Text dimColor>
|
|
19
|
-
Cost: ${costUSD.toFixed(4)} ({durationInSeconds}s)
|
|
20
|
-
</Text>
|
|
21
|
-
</Box>
|
|
22
|
-
)
|
|
23
|
-
}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { Box, Text, useInput } from 'ink'
|
|
2
|
-
import React from 'react'
|
|
3
|
-
import { Select } from './CustomSelect/select'
|
|
4
|
-
import { getTheme } from '../utils/theme'
|
|
5
|
-
import Link from './Link'
|
|
6
|
-
|
|
7
|
-
interface Props {
|
|
8
|
-
onDone: () => void
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export function CostThresholdDialog({ onDone }: Props): React.ReactNode {
|
|
12
|
-
// Handle Ctrl+C, Ctrl+D and Esc
|
|
13
|
-
useInput((input, key) => {
|
|
14
|
-
if ((key.ctrl && (input === 'c' || input === 'd')) || key.escape) {
|
|
15
|
-
onDone()
|
|
16
|
-
}
|
|
17
|
-
})
|
|
18
|
-
|
|
19
|
-
return (
|
|
20
|
-
<Box
|
|
21
|
-
flexDirection="column"
|
|
22
|
-
borderStyle="round"
|
|
23
|
-
padding={1}
|
|
24
|
-
borderColor={getTheme().secondaryBorder}
|
|
25
|
-
>
|
|
26
|
-
<Box marginBottom={1} flexDirection="column">
|
|
27
|
-
<Text bold>
|
|
28
|
-
You've spent $5 on AI model API calls this session.
|
|
29
|
-
</Text>
|
|
30
|
-
<Text>Learn more about monitoring your AI usage costs:</Text>
|
|
31
|
-
<Link url="https://github.com/anthropics/claude-code/docs/cost-monitoring" />
|
|
32
|
-
</Box>
|
|
33
|
-
<Box>
|
|
34
|
-
<Select
|
|
35
|
-
options={[
|
|
36
|
-
{
|
|
37
|
-
value: 'ok',
|
|
38
|
-
label: 'Got it, thanks!',
|
|
39
|
-
},
|
|
40
|
-
]}
|
|
41
|
-
onChange={onDone}
|
|
42
|
-
/>
|
|
43
|
-
</Box>
|
|
44
|
-
</Box>
|
|
45
|
-
)
|
|
46
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import { type Option } from '@inkjs/ui'
|
|
2
|
-
import { optionHeaderKey, type OptionHeader } from './select'
|
|
3
|
-
|
|
4
|
-
type OptionMapItem = (Option | OptionHeader) & {
|
|
5
|
-
previous: OptionMapItem | undefined
|
|
6
|
-
next: OptionMapItem | undefined
|
|
7
|
-
index: number
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export default class OptionMap extends Map<string, OptionMapItem> {
|
|
11
|
-
readonly first: OptionMapItem | undefined
|
|
12
|
-
|
|
13
|
-
constructor(options: (Option | OptionHeader)[]) {
|
|
14
|
-
const items: Array<[string, OptionMapItem]> = []
|
|
15
|
-
let firstItem: OptionMapItem | undefined
|
|
16
|
-
let previous: OptionMapItem | undefined
|
|
17
|
-
let index = 0
|
|
18
|
-
|
|
19
|
-
for (const option of options) {
|
|
20
|
-
const item = {
|
|
21
|
-
...option,
|
|
22
|
-
previous,
|
|
23
|
-
next: undefined,
|
|
24
|
-
index,
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
if (previous) {
|
|
28
|
-
previous.next = item
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
firstItem ||= item
|
|
32
|
-
|
|
33
|
-
const key = 'value' in option ? option.value : optionHeaderKey(option)
|
|
34
|
-
items.push([key, item])
|
|
35
|
-
index++
|
|
36
|
-
previous = item
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
super(items)
|
|
40
|
-
this.first = firstItem
|
|
41
|
-
}
|
|
42
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import figures from 'figures'
|
|
2
|
-
import { Box, Text } from 'ink'
|
|
3
|
-
import React, { type ReactNode } from 'react'
|
|
4
|
-
import { type Theme } from './theme'
|
|
5
|
-
import { getTheme } from '../../utils/theme'
|
|
6
|
-
|
|
7
|
-
export type SelectOptionProps = {
|
|
8
|
-
/**
|
|
9
|
-
* Determines if option is focused.
|
|
10
|
-
*/
|
|
11
|
-
readonly isFocused: boolean
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Determines if option is selected.
|
|
15
|
-
*/
|
|
16
|
-
readonly isSelected: boolean
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* Determines if pointer is shown when selected
|
|
20
|
-
*/
|
|
21
|
-
readonly smallPointer?: boolean
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Option label.
|
|
25
|
-
*/
|
|
26
|
-
readonly children: ReactNode
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* React key prop (handled internally by React)
|
|
30
|
-
*/
|
|
31
|
-
readonly key?: React.Key
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export function SelectOption({
|
|
35
|
-
isFocused,
|
|
36
|
-
isSelected,
|
|
37
|
-
smallPointer,
|
|
38
|
-
children,
|
|
39
|
-
...props
|
|
40
|
-
}: SelectOptionProps) {
|
|
41
|
-
const appTheme = getTheme()
|
|
42
|
-
const styles = {
|
|
43
|
-
option: ({ isFocused }: { isFocused: boolean }) => ({
|
|
44
|
-
paddingLeft: 2,
|
|
45
|
-
paddingRight: 1,
|
|
46
|
-
}),
|
|
47
|
-
focusIndicator: () => ({
|
|
48
|
-
color: appTheme.kode,
|
|
49
|
-
}),
|
|
50
|
-
label: ({ isFocused, isSelected }: { isFocused: boolean; isSelected: boolean }) => ({
|
|
51
|
-
color: isSelected
|
|
52
|
-
? appTheme.success
|
|
53
|
-
: isFocused
|
|
54
|
-
? appTheme.kode
|
|
55
|
-
: appTheme.text,
|
|
56
|
-
bold: isSelected,
|
|
57
|
-
}),
|
|
58
|
-
selectedIndicator: () => ({
|
|
59
|
-
color: appTheme.success,
|
|
60
|
-
}),
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
return (
|
|
64
|
-
<Box {...styles.option({ isFocused })}>
|
|
65
|
-
{isFocused && (
|
|
66
|
-
<Text {...styles.focusIndicator()}>
|
|
67
|
-
{smallPointer ? figures.triangleDownSmall : figures.pointer}
|
|
68
|
-
</Text>
|
|
69
|
-
)}
|
|
70
|
-
|
|
71
|
-
<Text {...styles.label({ isFocused, isSelected })}>{children}</Text>
|
|
72
|
-
|
|
73
|
-
{isSelected && (
|
|
74
|
-
<Text {...styles.selectedIndicator()}>{figures.tick}</Text>
|
|
75
|
-
)}
|
|
76
|
-
</Box>
|
|
77
|
-
)
|
|
78
|
-
}
|
|
@@ -1,152 +0,0 @@
|
|
|
1
|
-
import { Box, Text } from 'ink'
|
|
2
|
-
import React, { type ReactNode } from 'react'
|
|
3
|
-
import { SelectOption } from './select-option'
|
|
4
|
-
import { type Theme } from './theme'
|
|
5
|
-
import { useSelectState } from './use-select-state'
|
|
6
|
-
import { useSelect } from './use-select'
|
|
7
|
-
import { Option } from '@inkjs/ui'
|
|
8
|
-
import { getTheme } from '../../utils/theme'
|
|
9
|
-
|
|
10
|
-
export type OptionSubtree = {
|
|
11
|
-
/**
|
|
12
|
-
* Header to show above sub-options.
|
|
13
|
-
*/
|
|
14
|
-
readonly header?: string
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Options.
|
|
18
|
-
*/
|
|
19
|
-
readonly options: (Option | OptionSubtree)[]
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export type OptionHeader = {
|
|
23
|
-
readonly header: string
|
|
24
|
-
|
|
25
|
-
readonly optionValues: string[]
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export const optionHeaderKey = (optionHeader: OptionHeader): string =>
|
|
29
|
-
`HEADER-${optionHeader.optionValues.join(',')}`
|
|
30
|
-
|
|
31
|
-
export type SelectProps = {
|
|
32
|
-
/**
|
|
33
|
-
* When disabled, user input is ignored.
|
|
34
|
-
*
|
|
35
|
-
* @default false
|
|
36
|
-
*/
|
|
37
|
-
readonly isDisabled?: boolean
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Number of visible options.
|
|
41
|
-
*
|
|
42
|
-
* @default 5
|
|
43
|
-
*/
|
|
44
|
-
readonly visibleOptionCount?: number
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* Highlight text in option labels.
|
|
48
|
-
*/
|
|
49
|
-
readonly highlightText?: string
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Options.
|
|
53
|
-
*/
|
|
54
|
-
readonly options: (Option | OptionSubtree)[]
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Default value.
|
|
58
|
-
*/
|
|
59
|
-
readonly defaultValue?: string
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Callback when selected option changes.
|
|
63
|
-
*/
|
|
64
|
-
readonly onChange?: (value: string) => void
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Callback when focused option changes.
|
|
68
|
-
*/
|
|
69
|
-
readonly onFocus?: (value: string) => void
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Value to focus
|
|
73
|
-
*/
|
|
74
|
-
readonly focusValue?: string
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export function Select({
|
|
78
|
-
isDisabled = false,
|
|
79
|
-
visibleOptionCount = 5,
|
|
80
|
-
highlightText,
|
|
81
|
-
options,
|
|
82
|
-
defaultValue,
|
|
83
|
-
onChange,
|
|
84
|
-
onFocus,
|
|
85
|
-
focusValue,
|
|
86
|
-
}: SelectProps) {
|
|
87
|
-
const state = useSelectState({
|
|
88
|
-
visibleOptionCount,
|
|
89
|
-
options,
|
|
90
|
-
defaultValue,
|
|
91
|
-
onChange,
|
|
92
|
-
onFocus,
|
|
93
|
-
focusValue,
|
|
94
|
-
})
|
|
95
|
-
|
|
96
|
-
useSelect({ isDisabled, state })
|
|
97
|
-
|
|
98
|
-
const appTheme = getTheme()
|
|
99
|
-
const styles = {
|
|
100
|
-
container: () => ({
|
|
101
|
-
flexDirection: 'column' as const,
|
|
102
|
-
}),
|
|
103
|
-
highlightedText: () => ({
|
|
104
|
-
color: appTheme.text,
|
|
105
|
-
backgroundColor: appTheme.warning,
|
|
106
|
-
}),
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return (
|
|
110
|
-
<Box {...styles.container()}>
|
|
111
|
-
{state.visibleOptions.map(option => {
|
|
112
|
-
const key = 'value' in option ? option.value : optionHeaderKey(option)
|
|
113
|
-
const isFocused =
|
|
114
|
-
!isDisabled &&
|
|
115
|
-
state.focusedValue !== undefined &&
|
|
116
|
-
('value' in option
|
|
117
|
-
? state.focusedValue === option.value
|
|
118
|
-
: option.optionValues.includes(state.focusedValue))
|
|
119
|
-
const isSelected =
|
|
120
|
-
!!state.value &&
|
|
121
|
-
('value' in option
|
|
122
|
-
? state.value === option.value
|
|
123
|
-
: option.optionValues.includes(state.value))
|
|
124
|
-
const smallPointer = 'header' in option
|
|
125
|
-
const labelText = 'label' in option ? option.label : option.header
|
|
126
|
-
let label: ReactNode = labelText
|
|
127
|
-
|
|
128
|
-
if (highlightText && labelText.includes(highlightText)) {
|
|
129
|
-
const index = labelText.indexOf(highlightText)
|
|
130
|
-
|
|
131
|
-
label = (
|
|
132
|
-
<>
|
|
133
|
-
{labelText.slice(0, index)}
|
|
134
|
-
<Text {...styles.highlightedText()}>{highlightText}</Text>
|
|
135
|
-
{labelText.slice(index + highlightText.length)}
|
|
136
|
-
</>
|
|
137
|
-
)
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
return (
|
|
141
|
-
<SelectOption
|
|
142
|
-
key={key}
|
|
143
|
-
isFocused={isFocused}
|
|
144
|
-
isSelected={isSelected}
|
|
145
|
-
smallPointer={smallPointer}
|
|
146
|
-
children={label}
|
|
147
|
-
/>
|
|
148
|
-
)
|
|
149
|
-
})}
|
|
150
|
-
</Box>
|
|
151
|
-
)
|
|
152
|
-
}
|