mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-18 14:25:51 +00:00
更新大量 tsx 原始文件; 已经迁移 login panel; 部分 (#121)
* style(B1-1): 格式化 ink/buddy/cli/context/screens/tasks/services/keybindings/state (43 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 修复了 Box.tsx 和 ScrollBox.tsx 中无效的 global.d.ts import。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-2): 格式化 commands (79 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-3): 格式化 components/messages,permissions,mcp,sandbox,shell (104 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-4): 格式化 components/PromptInput,FeedbackSurvey,tasks,agents,skills,design-system,wizard (73 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-5): 格式化 components其余 + hooks + tools (232 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-6): 格式化 main/entrypoints/utils/moreright (21 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: 更新 README,新增 Run.ps1/TODO.md,删除 V6.md - README.md: 大幅重写,更详细版本历史和配置示例 - Run.ps1: 新增 Windows 启动脚本 - TODO.md: 新增包完成清单 - V6.md: 删除(架构重构规划已不适用) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: 修复以前的问题 * fix: 修复 login 面板的问题 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,230 +1,152 @@
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import React, { useCallback, useState } from 'react';
|
||||
import TextInput from '../../components/TextInput.js';
|
||||
import { useTerminalSize } from '../../hooks/useTerminalSize.js';
|
||||
import { Box, color, Text, useTheme } from '../../ink.js';
|
||||
import { useKeybindings } from '../../keybindings/useKeybinding.js';
|
||||
import React, { useCallback, useState } from 'react'
|
||||
import TextInput from '../../components/TextInput.js'
|
||||
import { useTerminalSize } from '../../hooks/useTerminalSize.js'
|
||||
import { Box, color, Text, useTheme } from '../../ink.js'
|
||||
import { useKeybindings } from '../../keybindings/useKeybinding.js'
|
||||
|
||||
interface ApiKeyStepProps {
|
||||
existingApiKey: string | null;
|
||||
useExistingKey: boolean;
|
||||
apiKeyOrOAuthToken: string;
|
||||
onApiKeyChange: (value: string) => void;
|
||||
onToggleUseExistingKey: (useExisting: boolean) => void;
|
||||
onSubmit: () => void;
|
||||
onCreateOAuthToken?: () => void;
|
||||
selectedOption?: 'existing' | 'new' | 'oauth';
|
||||
onSelectOption?: (option: 'existing' | 'new' | 'oauth') => void;
|
||||
existingApiKey: string | null
|
||||
useExistingKey: boolean
|
||||
apiKeyOrOAuthToken: string
|
||||
onApiKeyChange: (value: string) => void
|
||||
onToggleUseExistingKey: (useExisting: boolean) => void
|
||||
onSubmit: () => void
|
||||
onCreateOAuthToken?: () => void
|
||||
selectedOption?: 'existing' | 'new' | 'oauth'
|
||||
onSelectOption?: (option: 'existing' | 'new' | 'oauth') => void
|
||||
}
|
||||
export function ApiKeyStep(t0) {
|
||||
const $ = _c(55);
|
||||
const {
|
||||
existingApiKey,
|
||||
apiKeyOrOAuthToken,
|
||||
onApiKeyChange,
|
||||
onSubmit,
|
||||
onToggleUseExistingKey,
|
||||
|
||||
export function ApiKeyStep({
|
||||
existingApiKey,
|
||||
apiKeyOrOAuthToken,
|
||||
onApiKeyChange,
|
||||
onSubmit,
|
||||
onToggleUseExistingKey,
|
||||
onCreateOAuthToken,
|
||||
selectedOption = existingApiKey
|
||||
? 'existing'
|
||||
: onCreateOAuthToken
|
||||
? 'oauth'
|
||||
: 'new',
|
||||
onSelectOption,
|
||||
}: ApiKeyStepProps) {
|
||||
const [cursorOffset, setCursorOffset] = useState(0)
|
||||
const terminalSize = useTerminalSize()
|
||||
const [theme] = useTheme()
|
||||
|
||||
const handlePrevious = useCallback(() => {
|
||||
if (selectedOption === 'new' && onCreateOAuthToken) {
|
||||
// From 'new' go up to 'oauth'
|
||||
onSelectOption?.('oauth')
|
||||
} else if (selectedOption === 'oauth' && existingApiKey) {
|
||||
// From 'oauth' go up to 'existing' (only if it exists)
|
||||
onSelectOption?.('existing')
|
||||
onToggleUseExistingKey(true)
|
||||
}
|
||||
}, [
|
||||
selectedOption,
|
||||
onCreateOAuthToken,
|
||||
selectedOption: t1,
|
||||
onSelectOption
|
||||
} = t0;
|
||||
const selectedOption = t1 === undefined ? existingApiKey ? "existing" : onCreateOAuthToken ? "oauth" : "new" : t1;
|
||||
const [cursorOffset, setCursorOffset] = useState(0);
|
||||
const terminalSize = useTerminalSize();
|
||||
const [theme] = useTheme();
|
||||
let t2;
|
||||
if ($[0] !== existingApiKey || $[1] !== onCreateOAuthToken || $[2] !== onSelectOption || $[3] !== onToggleUseExistingKey || $[4] !== selectedOption) {
|
||||
t2 = () => {
|
||||
if (selectedOption === "new" && onCreateOAuthToken) {
|
||||
onSelectOption?.("oauth");
|
||||
} else {
|
||||
if (selectedOption === "oauth" && existingApiKey) {
|
||||
onSelectOption?.("existing");
|
||||
onToggleUseExistingKey(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
$[0] = existingApiKey;
|
||||
$[1] = onCreateOAuthToken;
|
||||
$[2] = onSelectOption;
|
||||
$[3] = onToggleUseExistingKey;
|
||||
$[4] = selectedOption;
|
||||
$[5] = t2;
|
||||
} else {
|
||||
t2 = $[5];
|
||||
}
|
||||
const handlePrevious = t2;
|
||||
let t3;
|
||||
if ($[6] !== onCreateOAuthToken || $[7] !== onSelectOption || $[8] !== onToggleUseExistingKey || $[9] !== selectedOption) {
|
||||
t3 = () => {
|
||||
if (selectedOption === "existing") {
|
||||
onSelectOption?.(onCreateOAuthToken ? "oauth" : "new");
|
||||
onToggleUseExistingKey(false);
|
||||
} else {
|
||||
if (selectedOption === "oauth") {
|
||||
onSelectOption?.("new");
|
||||
}
|
||||
}
|
||||
};
|
||||
$[6] = onCreateOAuthToken;
|
||||
$[7] = onSelectOption;
|
||||
$[8] = onToggleUseExistingKey;
|
||||
$[9] = selectedOption;
|
||||
$[10] = t3;
|
||||
} else {
|
||||
t3 = $[10];
|
||||
}
|
||||
const handleNext = t3;
|
||||
let t4;
|
||||
if ($[11] !== onCreateOAuthToken || $[12] !== onSubmit || $[13] !== selectedOption) {
|
||||
t4 = () => {
|
||||
if (selectedOption === "oauth" && onCreateOAuthToken) {
|
||||
onCreateOAuthToken();
|
||||
} else {
|
||||
onSubmit();
|
||||
}
|
||||
};
|
||||
$[11] = onCreateOAuthToken;
|
||||
$[12] = onSubmit;
|
||||
$[13] = selectedOption;
|
||||
$[14] = t4;
|
||||
} else {
|
||||
t4 = $[14];
|
||||
}
|
||||
const handleConfirm = t4;
|
||||
const isTextInputVisible = selectedOption === "new";
|
||||
let t5;
|
||||
if ($[15] !== handleConfirm || $[16] !== handleNext || $[17] !== handlePrevious) {
|
||||
t5 = {
|
||||
"confirm:previous": handlePrevious,
|
||||
"confirm:next": handleNext,
|
||||
"confirm:yes": handleConfirm
|
||||
};
|
||||
$[15] = handleConfirm;
|
||||
$[16] = handleNext;
|
||||
$[17] = handlePrevious;
|
||||
$[18] = t5;
|
||||
} else {
|
||||
t5 = $[18];
|
||||
}
|
||||
const t6 = !isTextInputVisible;
|
||||
let t7;
|
||||
if ($[19] !== t6) {
|
||||
t7 = {
|
||||
context: "Confirmation",
|
||||
isActive: t6
|
||||
};
|
||||
$[19] = t6;
|
||||
$[20] = t7;
|
||||
} else {
|
||||
t7 = $[20];
|
||||
}
|
||||
useKeybindings(t5, t7);
|
||||
let t8;
|
||||
if ($[21] !== handleNext || $[22] !== handlePrevious) {
|
||||
t8 = {
|
||||
"confirm:previous": handlePrevious,
|
||||
"confirm:next": handleNext
|
||||
};
|
||||
$[21] = handleNext;
|
||||
$[22] = handlePrevious;
|
||||
$[23] = t8;
|
||||
} else {
|
||||
t8 = $[23];
|
||||
}
|
||||
let t9;
|
||||
if ($[24] !== isTextInputVisible) {
|
||||
t9 = {
|
||||
context: "Confirmation",
|
||||
isActive: isTextInputVisible
|
||||
};
|
||||
$[24] = isTextInputVisible;
|
||||
$[25] = t9;
|
||||
} else {
|
||||
t9 = $[25];
|
||||
}
|
||||
useKeybindings(t8, t9);
|
||||
let t10;
|
||||
if ($[26] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t10 = <Box flexDirection="column" marginBottom={1}><Text bold={true}>Install GitHub App</Text><Text dimColor={true}>Choose API key</Text></Box>;
|
||||
$[26] = t10;
|
||||
} else {
|
||||
t10 = $[26];
|
||||
}
|
||||
let t11;
|
||||
if ($[27] !== existingApiKey || $[28] !== selectedOption || $[29] !== theme) {
|
||||
t11 = existingApiKey && <Box marginBottom={1}><Text>{selectedOption === "existing" ? color("success", theme)("> ") : " "}Use your existing Claude Code API key</Text></Box>;
|
||||
$[27] = existingApiKey;
|
||||
$[28] = selectedOption;
|
||||
$[29] = theme;
|
||||
$[30] = t11;
|
||||
} else {
|
||||
t11 = $[30];
|
||||
}
|
||||
let t12;
|
||||
if ($[31] !== onCreateOAuthToken || $[32] !== selectedOption || $[33] !== theme) {
|
||||
t12 = onCreateOAuthToken && <Box marginBottom={1}><Text>{selectedOption === "oauth" ? color("success", theme)("> ") : " "}Create a long-lived token with your Claude subscription</Text></Box>;
|
||||
$[31] = onCreateOAuthToken;
|
||||
$[32] = selectedOption;
|
||||
$[33] = theme;
|
||||
$[34] = t12;
|
||||
} else {
|
||||
t12 = $[34];
|
||||
}
|
||||
let t13;
|
||||
if ($[35] !== selectedOption || $[36] !== theme) {
|
||||
t13 = selectedOption === "new" ? color("success", theme)("> ") : " ";
|
||||
$[35] = selectedOption;
|
||||
$[36] = theme;
|
||||
$[37] = t13;
|
||||
} else {
|
||||
t13 = $[37];
|
||||
}
|
||||
let t14;
|
||||
if ($[38] !== t13) {
|
||||
t14 = <Box marginBottom={1}><Text>{t13}Enter a new API key</Text></Box>;
|
||||
$[38] = t13;
|
||||
$[39] = t14;
|
||||
} else {
|
||||
t14 = $[39];
|
||||
}
|
||||
let t15;
|
||||
if ($[40] !== apiKeyOrOAuthToken || $[41] !== cursorOffset || $[42] !== onApiKeyChange || $[43] !== onSubmit || $[44] !== selectedOption || $[45] !== terminalSize) {
|
||||
t15 = selectedOption === "new" && <TextInput value={apiKeyOrOAuthToken} onChange={onApiKeyChange} onSubmit={onSubmit} onPaste={onApiKeyChange} focus={true} placeholder={"sk-ant\u2026 (Create a new key at https://platform.claude.com/settings/keys)"} mask="*" columns={terminalSize.columns} cursorOffset={cursorOffset} onChangeCursorOffset={setCursorOffset} showCursor={true} />;
|
||||
$[40] = apiKeyOrOAuthToken;
|
||||
$[41] = cursorOffset;
|
||||
$[42] = onApiKeyChange;
|
||||
$[43] = onSubmit;
|
||||
$[44] = selectedOption;
|
||||
$[45] = terminalSize;
|
||||
$[46] = t15;
|
||||
} else {
|
||||
t15 = $[46];
|
||||
}
|
||||
let t16;
|
||||
if ($[47] !== t11 || $[48] !== t12 || $[49] !== t14 || $[50] !== t15) {
|
||||
t16 = <Box flexDirection="column" borderStyle="round" paddingX={1}>{t10}{t11}{t12}{t14}{t15}</Box>;
|
||||
$[47] = t11;
|
||||
$[48] = t12;
|
||||
$[49] = t14;
|
||||
$[50] = t15;
|
||||
$[51] = t16;
|
||||
} else {
|
||||
t16 = $[51];
|
||||
}
|
||||
let t17;
|
||||
if ($[52] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t17 = <Box marginLeft={3}><Text dimColor={true}>↑/↓ to select · Enter to continue</Text></Box>;
|
||||
$[52] = t17;
|
||||
} else {
|
||||
t17 = $[52];
|
||||
}
|
||||
let t18;
|
||||
if ($[53] !== t16) {
|
||||
t18 = <>{t16}{t17}</>;
|
||||
$[53] = t16;
|
||||
$[54] = t18;
|
||||
} else {
|
||||
t18 = $[54];
|
||||
}
|
||||
return t18;
|
||||
existingApiKey,
|
||||
onSelectOption,
|
||||
onToggleUseExistingKey,
|
||||
])
|
||||
|
||||
const handleNext = useCallback(() => {
|
||||
if (selectedOption === 'existing') {
|
||||
// From 'existing' go down to 'oauth' (if available) or 'new'
|
||||
onSelectOption?.(onCreateOAuthToken ? 'oauth' : 'new')
|
||||
onToggleUseExistingKey(false)
|
||||
} else if (selectedOption === 'oauth') {
|
||||
// From 'oauth' go down to 'new'
|
||||
onSelectOption?.('new')
|
||||
}
|
||||
}, [
|
||||
selectedOption,
|
||||
onCreateOAuthToken,
|
||||
onSelectOption,
|
||||
onToggleUseExistingKey,
|
||||
])
|
||||
|
||||
const handleConfirm = useCallback(() => {
|
||||
if (selectedOption === 'oauth' && onCreateOAuthToken) {
|
||||
onCreateOAuthToken()
|
||||
} else {
|
||||
onSubmit()
|
||||
}
|
||||
}, [selectedOption, onCreateOAuthToken, onSubmit])
|
||||
|
||||
// When the text input is visible, omit confirm:yes so bare 'y' passes
|
||||
// through to the input instead of submitting. TextInput's onSubmit handles
|
||||
// Enter. Keep the Confirmation context (not Settings) to avoid j/k bindings.
|
||||
const isTextInputVisible = selectedOption === 'new'
|
||||
useKeybindings(
|
||||
{
|
||||
'confirm:previous': handlePrevious,
|
||||
'confirm:next': handleNext,
|
||||
'confirm:yes': handleConfirm,
|
||||
},
|
||||
{ context: 'Confirmation', isActive: !isTextInputVisible },
|
||||
)
|
||||
useKeybindings(
|
||||
{
|
||||
'confirm:previous': handlePrevious,
|
||||
'confirm:next': handleNext,
|
||||
},
|
||||
{ context: 'Confirmation', isActive: isTextInputVisible },
|
||||
)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Box flexDirection="column" borderStyle="round" paddingX={1}>
|
||||
<Box flexDirection="column" marginBottom={1}>
|
||||
<Text bold>Install GitHub App</Text>
|
||||
<Text dimColor>Choose API key</Text>
|
||||
</Box>
|
||||
{existingApiKey && (
|
||||
<Box marginBottom={1}>
|
||||
<Text>
|
||||
{selectedOption === 'existing'
|
||||
? color('success', theme)('> ')
|
||||
: ' '}
|
||||
Use your existing Claude Code API key
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
{onCreateOAuthToken && (
|
||||
<Box marginBottom={1}>
|
||||
<Text>
|
||||
{selectedOption === 'oauth'
|
||||
? color('success', theme)('> ')
|
||||
: ' '}
|
||||
Create a long-lived token with your Claude subscription
|
||||
</Text>
|
||||
</Box>
|
||||
)}
|
||||
<Box marginBottom={1}>
|
||||
<Text>
|
||||
{selectedOption === 'new' ? color('success', theme)('> ') : ' '}
|
||||
Enter a new API key
|
||||
</Text>
|
||||
</Box>
|
||||
{selectedOption === 'new' && (
|
||||
<TextInput
|
||||
value={apiKeyOrOAuthToken}
|
||||
onChange={onApiKeyChange}
|
||||
onSubmit={onSubmit}
|
||||
onPaste={onApiKeyChange}
|
||||
focus={true}
|
||||
placeholder="sk-ant… (Create a new key at https://platform.claude.com/settings/keys)"
|
||||
mask="*"
|
||||
columns={terminalSize.columns}
|
||||
cursorOffset={cursorOffset}
|
||||
onChangeCursorOffset={setCursorOffset}
|
||||
showCursor={true}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
<Box marginLeft={3}>
|
||||
<Text dimColor>↑/↓ to select · Enter to continue</Text>
|
||||
</Box>
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user