feat: 第一个可以用的 ink 组件抽象 (#158)

This commit is contained in:
claude-code-best
2026-04-06 23:56:45 +08:00
committed by GitHub
parent 3ea64eeb0f
commit c445f43f8d
645 changed files with 7255 additions and 1214 deletions

View File

@@ -12,8 +12,7 @@ import React, {
} from 'react'
import { useSettings } from '../../../hooks/useSettings.js'
import { useTerminalSize } from '../../../hooks/useTerminalSize.js'
import { stringWidth } from '../../../ink/stringWidth.js'
import { useTheme } from '../../../ink.js'
import { stringWidth, useTheme } from '@anthropic/ink'
import { useKeybindings } from '../../../keybindings/useKeybinding.js'
import {
type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,

View File

@@ -1,8 +1,7 @@
import React, { Suspense, use, useMemo } from 'react'
import { useSettings } from '../../../hooks/useSettings.js'
import { useTerminalSize } from '../../../hooks/useTerminalSize.js'
import { stringWidth } from '../../../ink/stringWidth.js'
import { Ansi, Box, Text, useTheme } from '../../../ink.js'
import { Ansi, Box, Text, stringWidth, useTheme } from '@anthropic/ink'
import {
type CliHighlight,
getCliHighlightPromise,

View File

@@ -1,8 +1,7 @@
import figures from 'figures'
import React, { useCallback, useMemo, useRef, useState } from 'react'
import { useTerminalSize } from '../../../hooks/useTerminalSize.js'
import type { KeyboardEvent } from '../../../ink/events/keyboard-event.js'
import { Box, Text } from '../../../ink.js'
import { type KeyboardEvent, Box, Text } from '@anthropic/ink'
import {
useKeybinding,
useKeybindings,
@@ -12,7 +11,7 @@ import type { Question } from '../../../tools/AskUserQuestionTool/AskUserQuestio
import { getExternalEditor } from '../../../utils/editor.js'
import { toIDEDisplayName } from '../../../utils/ide.js'
import { editPromptInEditor } from '../../../utils/promptEditor.js'
import { Divider } from '../../design-system/Divider.js'
import { Divider } from '@anthropic/ink'
import TextInput from '../../TextInput.js'
import { PermissionRequestTitle } from '../PermissionRequestTitle.js'
import { PreviewBox } from './PreviewBox.js'

View File

@@ -1,8 +1,7 @@
import figures from 'figures'
import React, { useMemo } from 'react'
import { useTerminalSize } from '../../../hooks/useTerminalSize.js'
import { stringWidth } from '../../../ink/stringWidth.js'
import { Box, Text } from '../../../ink.js'
import { Box, Text, stringWidth } from '@anthropic/ink'
import type { Question } from '../../../tools/AskUserQuestionTool/AskUserQuestionTool.js'
import { truncateToWidth } from '../../../utils/format.js'

View File

@@ -1,7 +1,6 @@
import figures from 'figures'
import React, { useCallback, useState } from 'react'
import type { KeyboardEvent } from '../../../ink/events/keyboard-event.js'
import { Box, Text } from '../../../ink.js'
import { type KeyboardEvent, Box, Text } from '@anthropic/ink'
import { useAppState } from '../../../state/AppState.js'
import type {
Question,
@@ -17,8 +16,9 @@ import {
Select,
SelectMulti,
} from '../../CustomSelect/index.js'
import { Divider } from '../../design-system/Divider.js'
import { Divider } from '@anthropic/ink'
import { FilePathLink } from '../../FilePathLink.js'
import { PermissionRequestTitle } from '../PermissionRequestTitle.js'
import { PreviewQuestionView } from './PreviewQuestionView.js'
import { QuestionNavigationBar } from './QuestionNavigationBar.js'

View File

@@ -1,10 +1,10 @@
import figures from 'figures'
import React from 'react'
import { Box, Text } from '../../../ink.js'
import { Box, Text } from '@anthropic/ink'
import type { Question } from '../../../tools/AskUserQuestionTool/AskUserQuestionTool.js'
import type { PermissionDecision } from '../../../utils/permissions/PermissionResult.js'
import { Select } from '../../CustomSelect/index.js'
import { Divider } from '../../design-system/Divider.js'
import { Divider } from '@anthropic/ink'
import { PermissionRequestTitle } from '../PermissionRequestTitle.js'
import { PermissionRuleExplanation } from '../PermissionRuleExplanation.js'
import { QuestionNavigationBar } from './QuestionNavigationBar.js'

View File

@@ -1,7 +1,7 @@
import { feature } from 'bun:bundle'
import figures from 'figures'
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { Box, Text, useTheme } from '../../../ink.js'
import { Box, Text, useTheme } from '@anthropic/ink'
import { useKeybinding } from '../../../keybindings/useKeybinding.js'
import { getFeatureValue_CACHED_MAY_BE_STALE } from '../../../services/analytics/growthbook.js'
import {

View File

@@ -7,12 +7,12 @@ import { DEFAULT_GRANT_FLAGS } from '@ant/computer-use-mcp/types'
import figures from 'figures'
import * as React from 'react'
import { useMemo, useState } from 'react'
import { Box, Text } from '../../../ink.js'
import { Box, Text } from '@anthropic/ink'
import { execFileNoThrow } from '../../../utils/execFileNoThrow.js'
import { plural } from '../../../utils/stringUtils.js'
import type { OptionWithDescription } from '../../CustomSelect/select.js'
import { Select } from '../../CustomSelect/select.js'
import { Dialog } from '../../design-system/Dialog.js'
import { Dialog } from '@anthropic/ink'
type ComputerUseApprovalProps = {
request: CuPermissionRequest

View File

@@ -1,6 +1,6 @@
import React from 'react'
import { handlePlanModeTransition } from '../../../bootstrap/state.js'
import { Box, Text } from '../../../ink.js'
import { Box, Text } from '@anthropic/ink'
import {
type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
logEvent,

View File

@@ -29,8 +29,7 @@ import {
} from '../../../bootstrap/state.js'
import { generateSessionName } from '../../../commands/rename/generateSessionName.js'
import { launchUltraplan } from '../../../commands/ultraplan.js'
import type { KeyboardEvent } from '../../../ink/events/keyboard-event.js'
import { Box, Text } from '../../../ink.js'
import { type KeyboardEvent, Box, Text } from '@anthropic/ink'
import type { AppState } from '../../../state/AppStateStore.js'
import { AGENT_TOOL_NAME } from '../../../tools/AgentTool/constants.js'
import { EXIT_PLAN_MODE_V2_TOOL_NAME } from '../../../tools/ExitPlanModeTool/constants.js'

View File

@@ -1,6 +1,6 @@
import React, { useCallback, useMemo } from 'react'
import { getOriginalCwd } from '../../bootstrap/state.js'
import { Box, Text, useTheme } from '../../ink.js'
import { Box, Text, useTheme } from '@anthropic/ink'
import { sanitizeToolNameForAnalytics } from '../../services/analytics/metadata.js'
import { env } from '../../utils/env.js'
import { shouldShowAlwaysAllowOptions } from '../../utils/permissions/permissionsLoader.js'

View File

@@ -3,7 +3,7 @@ import React from 'react'
import { FileEditToolDiff } from 'src/components/FileEditToolDiff.js'
import { getCwd } from 'src/utils/cwd.js'
import type { z } from 'zod/v4'
import { Text } from '../../../ink.js'
import { Text } from '@anthropic/ink'
import { FileEditTool } from '../../../tools/FileEditTool/FileEditTool.js'
import { FilePermissionDialog } from '../FilePermissionDialog/FilePermissionDialog.js'
import {

View File

@@ -1,7 +1,7 @@
import { relative } from 'path'
import React, { useMemo } from 'react'
import { useDiffInIDE } from '../../../hooks/useDiffInIDE.js'
import { Box, Text } from '../../../ink.js'
import { Box, Text } from '@anthropic/ink'
import type { ToolUseContext } from '../../../Tool.js'
import { getLanguageName } from '../../../utils/cliHighlight.js'
import { getCwd } from '../../../utils/cwd.js'

View File

@@ -2,7 +2,7 @@ import { homedir } from 'os'
import { basename, join, sep } from 'path'
import React, { type ReactNode } from 'react'
import { getOriginalCwd } from '../../../bootstrap/state.js'
import { Text } from '../../../ink.js'
import { Text } from '@anthropic/ink'
import { getShortcutDisplay } from '../../../keybindings/shortcutFormat.js'
import type { ToolPermissionContext } from '../../../Tool.js'
import { expandPath, getDirectoryForPath } from '../../../utils/path.js'

View File

@@ -1,7 +1,7 @@
import { basename, relative } from 'path'
import React, { useMemo } from 'react'
import type { z } from 'zod/v4'
import { Text } from '../../../ink.js'
import { Text } from '@anthropic/ink'
import { FileWriteTool } from '../../../tools/FileWriteTool/FileWriteTool.js'
import { getCwd } from '../../../utils/cwd.js'
import { isENOENT } from '../../../utils/errors.js'

View File

@@ -1,7 +1,7 @@
import * as React from 'react'
import { useMemo } from 'react'
import { useTerminalSize } from '../../../hooks/useTerminalSize.js'
import { Box, NoSelect, Text } from '../../../ink.js'
import { Box, NoSelect, Text } from '@anthropic/ink'
import { intersperse } from '../../../utils/array.js'
import { getPatchForDisplay } from '../../../utils/diff.js'
import { HighlightedCode } from '../../HighlightedCode.js'

View File

@@ -1,5 +1,5 @@
import React from 'react'
import { Box, Text, useTheme } from '../../../ink.js'
import { Box, Text, useTheme } from '@anthropic/ink'
import { FallbackPermissionRequest } from '../FallbackPermissionRequest.js'
import { FilePermissionDialog } from '../FilePermissionDialog/FilePermissionDialog.js'
import type { ToolInput } from '../FilePermissionDialog/useFilePermissionDialog.js'

View File

@@ -1,7 +1,7 @@
import { basename } from 'path'
import React from 'react'
import type { z } from 'zod/v4'
import { Text } from '../../../ink.js'
import { Text } from '@anthropic/ink'
import { NotebookEditTool } from '../../../tools/NotebookEditTool/NotebookEditTool.js'
import { logError } from '../../../utils/log.js'
import { FilePermissionDialog } from '../FilePermissionDialog/FilePermissionDialog.js'

View File

@@ -1,7 +1,7 @@
import { relative } from 'path'
import * as React from 'react'
import { Suspense, use, useMemo } from 'react'
import { Box, NoSelect, Text } from '../../../ink.js'
import { Box, NoSelect, Text } from '@anthropic/ink'
import type {
NotebookCellType,
NotebookContent,

View File

@@ -2,7 +2,7 @@ import { feature } from 'bun:bundle'
import chalk from 'chalk'
import figures from 'figures'
import React, { useMemo } from 'react'
import { Ansi, Box, color, Text, useTheme } from '../../ink.js'
import { Ansi, Box, color, Text, useTheme } from '@anthropic/ink'
import { useAppState } from '../../state/AppState.js'
import type { PermissionMode } from '../../utils/permissions/PermissionMode.js'
import { permissionModeTitle } from '../../utils/permissions/PermissionMode.js'

View File

@@ -1,5 +1,5 @@
import * as React from 'react'
import { Box } from '../../ink.js'
import { Box } from '@anthropic/ink'
import type { Theme } from '../../utils/theme.js'
import { PermissionRequestTitle } from './PermissionRequestTitle.js'
import type { WorkerBadgeProps } from './WorkerBadge.js'

View File

@@ -1,5 +1,5 @@
import React, { Suspense, use, useState } from 'react'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import { useKeybinding } from '../../keybindings/useKeybinding.js'
import { logEvent } from '../../services/analytics/index.js'
import type { Message } from '../../types/message.js'

View File

@@ -1,5 +1,5 @@
import React, { type ReactNode, useCallback, useMemo, useState } from 'react'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import type { KeybindingAction } from '../../keybindings/types.js'
import { useKeybindings } from '../../keybindings/useKeybinding.js'
import {

View File

@@ -1,5 +1,5 @@
import * as React from 'react'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import type { Theme } from '../../utils/theme.js'
import type { WorkerBadgeProps } from './WorkerBadge.js'

View File

@@ -1,7 +1,8 @@
import { feature } from 'bun:bundle'
import chalk from 'chalk'
import React from 'react'
import { Ansi, Box, Text } from '../../ink.js'
import { Ansi, Box, Text } from '@anthropic/ink'
import ThemedText from '../design-system/ThemedText.js'
import { useAppState } from '../../state/AppState.js'
import type {
PermissionDecision,
@@ -9,7 +10,6 @@ import type {
} from '../../utils/permissions/PermissionResult.js'
import { permissionRuleValueToString } from '../../utils/permissions/permissionRuleParser.js'
import type { Theme } from '../../utils/theme.js'
import ThemedText from '../design-system/ThemedText.js'
export type PermissionRuleExplanationProps = {
permissionResult: PermissionDecision

View File

@@ -1,5 +1,5 @@
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
import { Box, Text, useTheme } from '../../../ink.js'
import { Box, Text, useTheme } from '@anthropic/ink'
import { useKeybinding } from '../../../keybindings/useKeybinding.js'
import { getFeatureValue_CACHED_MAY_BE_STALE } from '../../../services/analytics/growthbook.js'
import {

View File

@@ -1,5 +1,5 @@
import * as React from 'react'
import { Box, Text } from 'src/ink.js'
import { Box, Text } from '@anthropic/ink'
import {
type NetworkHostPattern,
shouldAllowManagedSandboxDomainsOnly,

View File

@@ -5,7 +5,7 @@ import { getCwd } from 'src/utils/cwd.js'
import { isENOENT } from 'src/utils/errors.js'
import { detectEncodingForResolvedPath } from 'src/utils/fileRead.js'
import { getFsImplementation } from 'src/utils/fsOperations.js'
import { Text } from '../../../ink.js'
import { Text } from '@anthropic/ink'
import { BashTool } from '../../../tools/BashTool/BashTool.js'
import {
applySedSubstitution,

View File

@@ -1,7 +1,7 @@
import React, { useCallback, useMemo } from 'react'
import { logError } from 'src/utils/log.js'
import { getOriginalCwd } from '../../../bootstrap/state.js'
import { Box, Text } from '../../../ink.js'
import { Box, Text } from '@anthropic/ink'
import { sanitizeToolNameForAnalytics } from '../../../services/analytics/metadata.js'
import { SKILL_TOOL_NAME } from '../../../tools/SkillTool/constants.js'
import { SkillTool } from '../../../tools/SkillTool/SkillTool.js'

View File

@@ -1,5 +1,5 @@
import React, { useMemo } from 'react'
import { Box, Text, useTheme } from '../../../ink.js'
import { Box, Text, useTheme } from '@anthropic/ink'
import { WebFetchTool } from '../../../tools/WebFetchTool/WebFetchTool.js'
import { shouldShowAlwaysAllowOptions } from '../../../utils/permissions/permissionsLoader.js'
import {

View File

@@ -1,6 +1,6 @@
import * as React from 'react'
import { BLACK_CIRCLE } from '../../constants/figures.js'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import { toInkColor } from '../../utils/ink.js'
export type WorkerBadgeProps = {

View File

@@ -1,5 +1,5 @@
import * as React from 'react'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import {
getAgentName,
getTeammateColor,

View File

@@ -1,7 +1,7 @@
import * as React from 'react'
import { useCallback } from 'react'
import { Select } from '../../../components/CustomSelect/select.js'
import { Box, Text } from '../../../ink.js'
import { Box, Dialog, Text } from '@anthropic/ink'
import type { ToolPermissionContext } from '../../../Tool.js'
import type {
PermissionBehavior,
@@ -25,7 +25,6 @@ import {
import { getRelativeSettingsFilePathForSource } from '../../../utils/settings/settings.js'
import { plural } from '../../../utils/stringUtils.js'
import type { OptionWithDescription } from '../../CustomSelect/select.js'
import { Dialog } from '../../design-system/Dialog.js'
import { PermissionRuleDescription } from './PermissionRuleDescription.js'
export function optionForPermissionSaveDestination(

View File

@@ -7,16 +7,13 @@ import {
validateDirectoryForWorkspace,
} from '../../../commands/add-dir/validation.js'
import TextInput from '../../../components/TextInput.js'
import type { KeyboardEvent } from '../../../ink/events/keyboard-event.js'
import { Box, Text } from '../../../ink.js'
import { type KeyboardEvent, Box, Text } from '@anthropic/ink'
import { useKeybinding } from '../../../keybindings/useKeybinding.js'
import type { ToolPermissionContext } from '../../../Tool.js'
import { getDirectoryCompletions } from '../../../utils/suggestions/directoryCompletion.js'
import { ConfigurableShortcutHint } from '../../ConfigurableShortcutHint.js'
import { Select } from '../../CustomSelect/select.js'
import { Byline } from '../../design-system/Byline.js'
import { Dialog } from '../../design-system/Dialog.js'
import { KeyboardShortcutHint } from '../../design-system/KeyboardShortcutHint.js'
import { Byline, Dialog, KeyboardShortcutHint } from '@anthropic/ink'
import {
PromptInputFooterSuggestions,
type SuggestionItem,

View File

@@ -1,5 +1,5 @@
import * as React from 'react'
import { Text } from '../../../ink.js'
import { Text } from '@anthropic/ink'
import { BashTool } from '../../../tools/BashTool/BashTool.js'
import type { PermissionRuleValue } from '../../../utils/permissions/PermissionRule.js'

View File

@@ -4,7 +4,7 @@ import { useState } from 'react'
import TextInput from '../../../components/TextInput.js'
import { useExitOnCtrlCDWithKeybindings } from '../../../hooks/useExitOnCtrlCDWithKeybindings.js'
import { useTerminalSize } from '../../../hooks/useTerminalSize.js'
import { Box, Newline, Text } from '../../../ink.js'
import { Box, Newline, Text } from '@anthropic/ink'
import { useKeybinding } from '../../../keybindings/useKeybinding.js'
import { BashTool } from '../../../tools/BashTool/BashTool.js'
import { WebFetchTool } from '../../../tools/WebFetchTool/WebFetchTool.js'

View File

@@ -12,8 +12,7 @@ import type { CommandResultDisplay } from '../../../commands.js'
import { Select } from '../../../components/CustomSelect/select.js'
import { useExitOnCtrlCDWithKeybindings } from '../../../hooks/useExitOnCtrlCDWithKeybindings.js'
import { useSearchInput } from '../../../hooks/useSearchInput.js'
import type { KeyboardEvent } from '../../../ink/events/keyboard-event.js'
import { Box, Text, useTerminalFocus } from '../../../ink.js'
import { type KeyboardEvent, Box, Text, useTerminalFocus } from '@anthropic/ink'
import { useKeybinding } from '../../../keybindings/useKeybinding.js'
import {
type AutoModeDenial,
@@ -34,13 +33,8 @@ import {
} from '../../../utils/permissions/permissions.js'
import type { UnreachableRule } from '../../../utils/permissions/shadowedRuleDetection.js'
import { jsonStringify } from '../../../utils/slowOperations.js'
import { Pane } from '../../design-system/Pane.js'
import {
Tab,
Tabs,
useTabHeaderFocus,
useTabsWidth,
} from '../../design-system/Tabs.js'
import { Pane, Tabs } from '@anthropic/ink'
import { Tab, useTabHeaderFocus, useTabsWidth } from '../../design-system/Tabs.js'
import { SearchBox } from '../../SearchBox.js'
import type { Option } from '../../ui/option.js'
import { AddPermissionRules } from './AddPermissionRules.js'

View File

@@ -1,13 +1,13 @@
import * as React from 'react'
import { useCallback, useEffect, useState } from 'react'
// eslint-disable-next-line custom-rules/prefer-use-keybindings -- 'r' is a view-specific key, not a global keybinding
import { Box, Text, useInput } from '../../../ink.js'
import { Box, Text, useInput } from '@anthropic/ink'
import {
type AutoModeDenial,
getAutoModeDenials,
} from '../../../utils/autoModeDenials.js'
import { Select } from '../../CustomSelect/select.js'
import { StatusIcon } from '../../design-system/StatusIcon.js'
import { StatusIcon } from '@anthropic/ink'
import { useTabHeaderFocus } from '../../design-system/Tabs.js'
type Props = {

View File

@@ -1,10 +1,10 @@
import * as React from 'react'
import { useCallback } from 'react'
import { Select } from '../../../components/CustomSelect/select.js'
import { Box, Text } from '../../../ink.js'
import { Box, Text } from '@anthropic/ink'
import type { ToolPermissionContext } from '../../../Tool.js'
import { applyPermissionUpdate } from '../../../utils/permissions/PermissionUpdate.js'
import { Dialog } from '../../design-system/Dialog.js'
import { Dialog } from '@anthropic/ink'
type Props = {
directoryPath: string

View File

@@ -4,7 +4,7 @@ import { useCallback, useEffect } from 'react'
import { getOriginalCwd } from '../../../bootstrap/state.js'
import type { CommandResultDisplay } from '../../../commands.js'
import { Select } from '../../../components/CustomSelect/select.js'
import { Box, Text } from '../../../ink.js'
import { Box, Text } from '@anthropic/ink'
import type { ToolPermissionContext } from '../../../Tool.js'
import { useTabHeaderFocus } from '../../design-system/Tabs.js'

View File

@@ -1,7 +1,7 @@
import { basename, sep } from 'path'
import React, { type ReactNode } from 'react'
import { getOriginalCwd } from '../../bootstrap/state.js'
import { Text } from '../../ink.js'
import { Text } from '@anthropic/ink'
import type { PermissionUpdate } from '../../utils/permissions/PermissionUpdateSchema.js'
import { permissionRuleExtractPrefix } from '../../utils/permissions/shellRuleMatching.js'