更新大量 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:
claude-code-best
2026-04-04 23:24:27 +08:00
committed by GitHub
parent 02694918b5
commit 5b1a52b8e0
559 changed files with 103807 additions and 101817 deletions

View File

@@ -1,28 +1,37 @@
import { c as _c } from "react/compiler-runtime";
import React, { createContext, useCallback, useContext, useEffect, useState } from 'react';
import { useIsInsideModal, useModalScrollRef } from '../../context/modalContext.js';
import { useTerminalSize } from '../../hooks/useTerminalSize.js';
import ScrollBox from '../../ink/components/ScrollBox.js';
import type { KeyboardEvent } from '../../ink/events/keyboard-event.js';
import { stringWidth } from '../../ink/stringWidth.js';
import { Box, Text } from '../../ink.js';
import { useKeybindings } from '../../keybindings/useKeybinding.js';
import type { Theme } from '../../utils/theme.js';
import React, {
createContext,
useCallback,
useContext,
useEffect,
useState,
} from 'react'
import {
useIsInsideModal,
useModalScrollRef,
} from '../../context/modalContext.js'
import { useTerminalSize } from '../../hooks/useTerminalSize.js'
import ScrollBox from '../../ink/components/ScrollBox.js'
import type { KeyboardEvent } from '../../ink/events/keyboard-event.js'
import { stringWidth } from '../../ink/stringWidth.js'
import { Box, Text } from '../../ink.js'
import { useKeybindings } from '../../keybindings/useKeybinding.js'
import type { Theme } from '../../utils/theme.js'
type TabsProps = {
children: Array<React.ReactElement<TabProps>>;
title?: string;
color?: keyof Theme;
defaultTab?: string;
hidden?: boolean;
useFullWidth?: boolean;
children: Array<React.ReactElement<TabProps>>
title?: string
color?: keyof Theme
defaultTab?: string
hidden?: boolean
useFullWidth?: boolean
/** Controlled mode: current selected tab id/title */
selectedTab?: string;
selectedTab?: string
/** Controlled mode: callback when tab changes */
onTabChange?: (tabId: string) => void;
onTabChange?: (tabId: string) => void
/** Optional banner to display below tabs header */
banner?: React.ReactNode;
banner?: React.ReactNode
/** Disable keyboard navigation (e.g. when a child component handles arrow keys) */
disableNavigation?: boolean;
disableNavigation?: boolean
/**
* Initial focus state for the tab header row. Defaults to true (header
* focused, nav always works). Keep the default for Select/list content —
@@ -31,28 +40,30 @@ type TabsProps = {
* content actually binds left/right/tab (e.g. enum cycling), and show a
* "↑ tabs" footer hint — without it tabs look broken.
*/
initialHeaderFocused?: boolean;
initialHeaderFocused?: boolean
/**
* Fixed height for the content area. When set, all tabs render within the
* same height (overflow hidden) so switching tabs doesn't cause layout
* shifts. Shorter tabs get whitespace; taller tabs are clipped.
*/
contentHeight?: number;
contentHeight?: number
/**
* Let Tab/←/→ switch tabs from focused content. Opt-in since some
* content uses those keys; pass a reactive boolean to cede them when
* needed. Switching from content focuses the header.
*/
navFromContent?: boolean;
};
navFromContent?: boolean
}
type TabsContextValue = {
selectedTab: string | undefined;
width: number | undefined;
headerFocused: boolean;
focusHeader: () => void;
blurHeader: () => void;
registerOptIn: () => () => void;
};
selectedTab: string | undefined
width: number | undefined
headerFocused: boolean
focusHeader: () => void
blurHeader: () => void
registerOptIn: () => () => void
}
const TabsContext = createContext<TabsContextValue>({
selectedTab: undefined,
width: undefined,
@@ -61,236 +72,248 @@ const TabsContext = createContext<TabsContextValue>({
headerFocused: false,
focusHeader: () => {},
blurHeader: () => {},
registerOptIn: () => () => {}
});
export function Tabs(t0) {
const $ = _c(25);
const {
title,
color,
defaultTab,
children,
hidden,
useFullWidth,
selectedTab: controlledSelectedTab,
onTabChange,
banner,
disableNavigation,
initialHeaderFocused: t1,
contentHeight,
navFromContent: t2
} = t0;
const initialHeaderFocused = t1 === undefined ? true : t1;
const navFromContent = t2 === undefined ? false : t2;
const {
columns: terminalWidth
} = useTerminalSize();
const tabs = children.map(_temp);
const defaultTabIndex = defaultTab ? tabs.findIndex(tab => defaultTab === tab[0]) : 0;
const isControlled = controlledSelectedTab !== undefined;
const [internalSelectedTab, setInternalSelectedTab] = useState(defaultTabIndex !== -1 ? defaultTabIndex : 0);
const controlledTabIndex = isControlled ? tabs.findIndex(tab_0 => tab_0[0] === controlledSelectedTab) : -1;
const selectedTabIndex = isControlled ? controlledTabIndex !== -1 ? controlledTabIndex : 0 : internalSelectedTab;
const modalScrollRef = useModalScrollRef();
const [headerFocused, setHeaderFocused] = useState(initialHeaderFocused);
let t3;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t3 = () => setHeaderFocused(true);
$[0] = t3;
} else {
t3 = $[0];
}
const focusHeader = t3;
let t4;
if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
t4 = () => setHeaderFocused(false);
$[1] = t4;
} else {
t4 = $[1];
}
const blurHeader = t4;
const [optInCount, setOptInCount] = useState(0);
let t5;
if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
t5 = () => {
setOptInCount(_temp2);
return () => setOptInCount(_temp3);
};
$[2] = t5;
} else {
t5 = $[2];
}
const registerOptIn = t5;
const optedIn = optInCount > 0;
const handleTabChange = offset => {
const newIndex = (selectedTabIndex + tabs.length + offset) % tabs.length;
const newTabId = tabs[newIndex]?.[0];
registerOptIn: () => () => {},
})
export function Tabs({
title,
color,
defaultTab,
children,
hidden,
useFullWidth,
selectedTab: controlledSelectedTab,
onTabChange,
banner,
disableNavigation,
initialHeaderFocused = true,
contentHeight,
navFromContent = false,
}: TabsProps): React.ReactNode {
const { columns: terminalWidth } = useTerminalSize()
const tabs = children.map(child => [
child.props.id ?? child.props.title,
child.props.title,
])
const defaultTabIndex = defaultTab
? tabs.findIndex(tab => defaultTab === tab[0])
: 0
// Support both controlled and uncontrolled modes
const isControlled = controlledSelectedTab !== undefined
const [internalSelectedTab, setInternalSelectedTab] = useState(
defaultTabIndex !== -1 ? defaultTabIndex : 0,
)
// In controlled mode, find the index of the controlled tab
const controlledTabIndex = isControlled
? tabs.findIndex(tab => tab[0] === controlledSelectedTab)
: -1
const selectedTabIndex = isControlled
? controlledTabIndex !== -1
? controlledTabIndex
: 0
: internalSelectedTab
const modalScrollRef = useModalScrollRef()
// Header focus: left/right/tab only switch tabs when the header row is
// focused. Children with interactive content call focusHeader() (via
// useTabHeaderFocus) on up-arrow to hand focus back here; down-arrow
// returns it. Tabs that never call the hook see no behavior change —
// initialHeaderFocused defaults to true so nav always works.
const [headerFocused, setHeaderFocused] = useState(initialHeaderFocused)
const focusHeader = useCallback(() => setHeaderFocused(true), [])
const blurHeader = useCallback(() => setHeaderFocused(false), [])
// Count of mounted children using useTabHeaderFocus(). Down-arrow blur and
// the ↓ hint only engage when at least one child has opted in — otherwise
// pressing down on a legacy tab would strand the user with nav disabled.
const [optInCount, setOptInCount] = useState(0)
const registerOptIn = useCallback(() => {
setOptInCount(n => n + 1)
return () => setOptInCount(n => n - 1)
}, [])
const optedIn = optInCount > 0
const handleTabChange = (offset: number) => {
const newIndex = (selectedTabIndex + tabs.length + offset) % tabs.length
const newTabId = tabs[newIndex]?.[0]
if (isControlled && onTabChange && newTabId) {
onTabChange(newTabId);
onTabChange(newTabId)
} else {
setInternalSelectedTab(newIndex);
setInternalSelectedTab(newIndex)
}
setHeaderFocused(true);
};
const t6 = !hidden && !disableNavigation && headerFocused;
let t7;
if ($[3] !== t6) {
t7 = {
context: "Tabs",
isActive: t6
};
$[3] = t6;
$[4] = t7;
} else {
t7 = $[4];
// Tab switching is a header action — stay focused so the user can keep
// cycling. The newly mounted tab can blur via its own interaction.
setHeaderFocused(true)
}
useKeybindings({
"tabs:next": () => handleTabChange(1),
"tabs:previous": () => handleTabChange(-1)
}, t7);
let t8;
if ($[5] !== headerFocused || $[6] !== hidden || $[7] !== optedIn) {
t8 = e => {
if (!headerFocused || !optedIn || hidden) {
return;
}
if (e.key === "down") {
e.preventDefault();
setHeaderFocused(false);
}
};
$[5] = headerFocused;
$[6] = hidden;
$[7] = optedIn;
$[8] = t8;
} else {
t8 = $[8];
}
const handleKeyDown = t8;
const t9 = navFromContent && !headerFocused && optedIn && !hidden && !disableNavigation;
let t10;
if ($[9] !== t9) {
t10 = {
context: "Tabs",
isActive: t9
};
$[9] = t9;
$[10] = t10;
} else {
t10 = $[10];
}
useKeybindings({
"tabs:next": () => {
handleTabChange(1);
setHeaderFocused(true);
useKeybindings(
{
'tabs:next': () => handleTabChange(1),
'tabs:previous': () => handleTabChange(-1),
},
"tabs:previous": () => {
handleTabChange(-1);
setHeaderFocused(true);
{
context: 'Tabs',
isActive: !hidden && !disableNavigation && headerFocused,
},
)
// When the header is focused, down-arrow returns focus to content. Only
// active when the selected tab has opted in via useTabHeaderFocus() —
// legacy tabs have nowhere to return focus to.
const handleKeyDown = (e: KeyboardEvent) => {
if (!headerFocused || !optedIn || hidden) return
if (e.key === 'down') {
e.preventDefault()
setHeaderFocused(false)
}
}, t10);
const titleWidth = title ? stringWidth(title) + 1 : 0;
const tabsWidth = tabs.reduce(_temp4, 0);
const usedWidth = titleWidth + tabsWidth;
const spacerWidth = useFullWidth ? Math.max(0, terminalWidth - usedWidth) : 0;
const contentWidth = useFullWidth ? terminalWidth : undefined;
const T0 = Box;
const t11 = "column";
const t12 = 0;
const t13 = true;
const t14 = modalScrollRef ? 0 : undefined;
const t15 = !hidden && <Box flexDirection="row" gap={1} flexShrink={modalScrollRef ? 0 : undefined}>{title !== undefined && <Text bold={true} color={color}>{title}</Text>}{tabs.map((t16, i) => {
const [id, title_0] = t16;
const isCurrent = selectedTabIndex === i;
const hasColorCursor = color && isCurrent && headerFocused;
return <Text key={id} backgroundColor={hasColorCursor ? color : undefined} color={hasColorCursor ? "inverseText" : undefined} inverse={isCurrent && !hasColorCursor} bold={isCurrent}>{" "}{title_0}{" "}</Text>;
})}{spacerWidth > 0 && <Text>{" ".repeat(spacerWidth)}</Text>}</Box>;
let t17;
if ($[11] !== children || $[12] !== contentHeight || $[13] !== contentWidth || $[14] !== hidden || $[15] !== modalScrollRef || $[16] !== selectedTabIndex) {
t17 = modalScrollRef ? <Box width={contentWidth} marginTop={hidden ? 0 : 1} flexShrink={0}><ScrollBox key={selectedTabIndex} ref={modalScrollRef} flexDirection="column" flexShrink={0}>{children}</ScrollBox></Box> : <Box width={contentWidth} marginTop={hidden ? 0 : 1} height={contentHeight} overflowY={contentHeight !== undefined ? "hidden" : undefined}>{children}</Box>;
$[11] = children;
$[12] = contentHeight;
$[13] = contentWidth;
$[14] = hidden;
$[15] = modalScrollRef;
$[16] = selectedTabIndex;
$[17] = t17;
} else {
t17 = $[17];
}
let t18;
if ($[18] !== T0 || $[19] !== banner || $[20] !== handleKeyDown || $[21] !== t14 || $[22] !== t15 || $[23] !== t17) {
t18 = <T0 flexDirection={t11} tabIndex={t12} autoFocus={t13} onKeyDown={handleKeyDown} flexShrink={t14}>{t15}{banner}{t17}</T0>;
$[18] = T0;
$[19] = banner;
$[20] = handleKeyDown;
$[21] = t14;
$[22] = t15;
$[23] = t17;
$[24] = t18;
} else {
t18 = $[24];
}
return <TabsContext.Provider value={{
selectedTab: tabs[selectedTabIndex][0],
width: contentWidth,
headerFocused,
focusHeader,
blurHeader,
registerOptIn
}}>{t18}</TabsContext.Provider>;
}
function _temp4(sum, t0) {
const [, tabTitle] = t0;
return sum + (tabTitle ? stringWidth(tabTitle) : 0) + 2 + 1;
}
function _temp3(n_0) {
return n_0 - 1;
}
function _temp2(n) {
return n + 1;
}
function _temp(child) {
return [child.props.id ?? child.props.title, child.props.title];
// Opt-in: same tabs:next/previous actions, active from content. Focuses
// the header so subsequent presses cycle via the handler above.
useKeybindings(
{
'tabs:next': () => {
handleTabChange(1)
setHeaderFocused(true)
},
'tabs:previous': () => {
handleTabChange(-1)
setHeaderFocused(true)
},
},
{
context: 'Tabs',
isActive:
navFromContent &&
!headerFocused &&
optedIn &&
!hidden &&
!disableNavigation,
},
)
// Calculate spacing to fill the available width. No keyboard hint in the
// header row — content footers own hints (see useTabHeaderFocus docs).
const titleWidth = title ? stringWidth(title) + 1 : 0 // +1 for gap
const tabsWidth = tabs.reduce(
(sum, [, tabTitle]) => sum + (tabTitle ? stringWidth(tabTitle) : 0) + 2 + 1, // +2 for padding, +1 for gap
0,
)
const usedWidth = titleWidth + tabsWidth
const spacerWidth = useFullWidth ? Math.max(0, terminalWidth - usedWidth) : 0
const contentWidth = useFullWidth ? terminalWidth : undefined
return (
<TabsContext.Provider
value={{
selectedTab: tabs[selectedTabIndex]![0],
width: contentWidth,
headerFocused,
focusHeader,
blurHeader,
registerOptIn,
}}
>
<Box
flexDirection="column"
tabIndex={0}
autoFocus
onKeyDown={handleKeyDown}
// flexShrink=0 inside modal slot — the modal's absolute Box has no
// explicit height (grows to fit, maxHeight cap), so flexGrow=1 here
// resolves to 0 on re-render and the body blanks on Down arrow.
// See #23592. Outside modal, leave layout alone.
flexShrink={modalScrollRef ? 0 : undefined}
>
{!hidden && (
<Box
flexDirection="row"
gap={1}
flexShrink={modalScrollRef ? 0 : undefined}
>
{title !== undefined && (
<Text bold color={color}>
{title}
</Text>
)}
{tabs.map(([id, title], i) => {
const isCurrent = selectedTabIndex === i
const hasColorCursor = color && isCurrent && headerFocused
return (
<Text
key={id}
backgroundColor={hasColorCursor ? color : undefined}
color={hasColorCursor ? 'inverseText' : undefined}
inverse={isCurrent && !hasColorCursor}
bold={isCurrent}
>
{' '}
{title}{' '}
</Text>
)
})}
{spacerWidth > 0 && <Text>{' '.repeat(spacerWidth)}</Text>}
</Box>
)}
{banner}
{modalScrollRef ? (
// Inside the modal slot: own the ScrollBox here so the tabs
// header row above sits OUTSIDE the scroll area — it can never
// scroll off. The ref reaches REPL's ScrollKeybindingHandler via
// ModalContext. Keyed by selectedTabIndex → remounts on tab
// switch, resetting scrollTop to 0 without scrollTo() timing games.
<Box width={contentWidth} marginTop={hidden ? 0 : 1} flexShrink={0}>
<ScrollBox
key={selectedTabIndex}
ref={modalScrollRef}
flexDirection="column"
flexShrink={0}
>
{children}
</ScrollBox>
</Box>
) : (
<Box
width={contentWidth}
marginTop={hidden ? 0 : 1}
height={contentHeight}
overflowY={contentHeight !== undefined ? 'hidden' : undefined}
>
{children}
</Box>
)}
</Box>
</TabsContext.Provider>
)
}
type TabProps = {
title: string;
id?: string;
children: React.ReactNode;
};
export function Tab(t0) {
const $ = _c(4);
const {
title,
id,
children
} = t0;
const {
selectedTab,
width
} = useContext(TabsContext);
const insideModal = useIsInsideModal();
if (selectedTab !== (id ?? title)) {
return null;
}
const t1 = insideModal ? 0 : undefined;
let t2;
if ($[0] !== children || $[1] !== t1 || $[2] !== width) {
t2 = <Box width={width} flexShrink={t1}>{children}</Box>;
$[0] = children;
$[1] = t1;
$[2] = width;
$[3] = t2;
} else {
t2 = $[3];
}
return t2;
title: string
id?: string
children: React.ReactNode
}
export function useTabsWidth() {
const {
width
} = useContext(TabsContext);
return width;
export function Tab({ title, id, children }: TabProps): React.ReactNode {
const { selectedTab, width } = useContext(TabsContext)
const insideModal = useIsInsideModal()
if (selectedTab !== (id ?? title)) {
return null
}
return (
<Box width={width} flexShrink={insideModal ? 0 : undefined}>
{children}
</Box>
)
}
export function useTabsWidth(): number | undefined {
const { width } = useContext(TabsContext)
return width
}
/**
@@ -304,36 +327,13 @@ export function useTabsWidth() {
* no onUpFromFirstItem to recover. Split the component so the hook only runs
* when the Select renders.
*/
export function useTabHeaderFocus() {
const $ = _c(6);
const {
headerFocused,
focusHeader,
blurHeader,
registerOptIn
} = useContext(TabsContext);
let t0;
if ($[0] !== registerOptIn) {
t0 = [registerOptIn];
$[0] = registerOptIn;
$[1] = t0;
} else {
t0 = $[1];
}
useEffect(registerOptIn, t0);
let t1;
if ($[2] !== blurHeader || $[3] !== focusHeader || $[4] !== headerFocused) {
t1 = {
headerFocused,
focusHeader,
blurHeader
};
$[2] = blurHeader;
$[3] = focusHeader;
$[4] = headerFocused;
$[5] = t1;
} else {
t1 = $[5];
}
return t1;
export function useTabHeaderFocus(): {
headerFocused: boolean
focusHeader: () => void
blurHeader: () => void
} {
const { headerFocused, focusHeader, blurHeader, registerOptIn } =
useContext(TabsContext)
useEffect(registerOptIn, [registerOptIn])
return { headerFocused, focusHeader, blurHeader }
}