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

@@ -1,6 +1,6 @@
import figures from 'figures'
import React from 'react'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import type { AdvisorBlock } from '../../utils/advisor.js'
import { renderModelName } from '../../utils/model/model.js'
import { jsonStringify } from '../../utils/slowOperations.js'

View File

@@ -1,5 +1,5 @@
import React from 'react'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
type Props = {
addMargin: boolean

View File

@@ -3,7 +3,7 @@ import React, { useContext } from 'react'
import { ERROR_MESSAGE_USER_ABORT } from 'src/services/compact/compact.js'
import { isRateLimitErrorMessage } from 'src/services/rateLimitMessages.js'
import { BLACK_CIRCLE } from '../../constants/figures.js'
import { Box, NoSelect, Text } from '../../ink.js'
import { Box, NoSelect, Text } from '@anthropic/ink'
import {
API_ERROR_MESSAGE_PREFIX,
API_TIMEOUT_ERROR_MESSAGE,

View File

@@ -3,7 +3,7 @@ import type {
ThinkingBlockParam,
} from '@anthropic-ai/sdk/resources/index.mjs'
import React from 'react'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import { CtrlOToExpand } from '../CtrlOToExpand.js'
import { Markdown } from '../Markdown.js'

View File

@@ -4,8 +4,7 @@ import { useTerminalSize } from 'src/hooks/useTerminalSize.js'
import type { ThemeName } from 'src/utils/theme.js'
import type { Command } from '../../commands.js'
import { BLACK_CIRCLE } from '../../constants/figures.js'
import { stringWidth } from '../../ink/stringWidth.js'
import { Box, Text, useTheme } from '../../ink.js'
import { Box, Text, stringWidth, useTheme } from '@anthropic/ink'
import { useAppStateMaybeOutsideOfProvider } from '../../state/AppState.js'
import {
findToolByName,

View File

@@ -1,6 +1,8 @@
// biome-ignore-all assist/source/organizeImports: ANT-ONLY import markers must not be reordered
import React, { useMemo } from 'react'
import { Ansi, Box, Text } from '../../ink.js'
import { Ansi, Box, Text } from '@anthropic/ink'
import { FilePathLink } from '../FilePathLink.js'
import { toInkColor } from '../../utils/ink.js'
import type { Attachment } from 'src/utils/attachments.js'
import type { NullRenderingAttachmentType } from './nullRenderingAttachments.js'
import { useAppState } from '../../state/AppState.js'
@@ -13,7 +15,7 @@ import { DiagnosticsDisplay } from '../DiagnosticsDisplay.js'
import { getContentText } from 'src/utils/messages.js'
import type { Theme } from 'src/utils/theme.js'
import { UserImageMessage } from './UserImageMessage.js'
import { toInkColor } from '../../utils/ink.js'
import { jsonParse } from '../../utils/slowOperations.js'
import { plural } from '../../utils/stringUtils.js'
import { isEnvTruthy } from '../../utils/envUtils.js'
@@ -26,7 +28,7 @@ import { BLACK_CIRCLE } from '../../constants/figures.js'
import { TeammateMessageContent } from './UserTeammateMessage.js'
import { isShutdownApproved } from '../../utils/teammateMailbox.js'
import { CtrlOToExpand } from '../CtrlOToExpand.js'
import { FilePathLink } from '../FilePathLink.js'
import { feature } from 'bun:bundle'
import { useSelectedMessageBg } from '../messageActions.js'

View File

@@ -2,7 +2,7 @@ import { feature } from 'bun:bundle'
import { basename } from 'path'
import React, { useRef } from 'react'
import { useMinDisplayTime } from '../../hooks/useMinDisplayTime.js'
import { Ansi, Box, Text, useTheme } from '../../ink.js'
import { Ansi, Box, Text, useTheme } from '@anthropic/ink'
import { findToolByName, type Tools } from '../../Tool.js'
import { getReplPrimitiveTools } from '../../tools/REPLTool/primitiveTools.js'
import type {

View File

@@ -1,5 +1,5 @@
import * as React from 'react'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import { useShortcutDisplay } from '../../keybindings/useShortcutDisplay.js'
export function CompactBoundaryMessage(): React.ReactNode {

View File

@@ -2,7 +2,7 @@ import figures from 'figures'
import * as React from 'react'
import { useContext } from 'react'
import { useQueuedMessage } from '../../context/QueuedMessageContext.js'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import { formatBriefTimestamp } from '../../utils/formatBriefTimestamp.js'
import {
findThinkingTriggerPositions,

View File

@@ -1,7 +1,7 @@
import * as React from 'react'
import type { HookEvent } from 'src/entrypoints/agentSdkTypes.js'
import type { buildMessageLookups } from 'src/utils/messages.js'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import { MessageResponse } from '../MessageResponse.js'
type Props = {

View File

@@ -1,6 +1,6 @@
import * as React from 'react'
import { Markdown } from '../../components/Markdown.js'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import { jsonParse } from '../../utils/slowOperations.js'
import {
type IdleNotificationMessage,

View File

@@ -1,6 +1,6 @@
import React, { useEffect, useMemo, useState } from 'react'
import { extraUsage } from 'src/commands/extra-usage/index.js'
import { Box, Text } from 'src/ink.js'
import { Box, Text } from '@anthropic/ink'
import { useClaudeAiLimits } from 'src/services/claudeAiLimitsHook.js'
import { shouldProcessMockLimits } from 'src/services/rateLimitMocking.js' // Used for /mock-limits command
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 {
isShutdownApproved,
isShutdownRejected,

View File

@@ -1,6 +1,6 @@
import * as React from 'react'
import { useState } from 'react'
import { Box, Text } from 'src/ink.js'
import { Box, Text } from '@anthropic/ink'
import { formatAPIError } from 'src/services/api/errorUtils.js'
import type { SystemAPIErrorMessage } from 'src/types/message.js'
import { useInterval } from 'usehooks-ts'

View File

@@ -1,5 +1,6 @@
// biome-ignore-all assist/source/organizeImports: ANT-ONLY import markers must not be reordered
import { Box, Text, type TextProps } from '../../ink.js'
import { Box, Link, Text, type TextProps } from '@anthropic/ink'
import { FilePathLink } from '../FilePathLink.js'
import { feature } from 'bun:bundle'
import * as React from 'react'
import { useState } from 'react'
@@ -12,7 +13,7 @@ import {
import figures from 'figures'
import { basename } from 'path'
import { MessageResponse } from '../MessageResponse.js'
import { FilePathLink } from '../FilePathLink.js'
import { openPath } from '../../utils/browser.js'
/* eslint-disable @typescript-eslint/no-require-imports */
const teamMemSaved = feature('TEAMMEM')
@@ -36,7 +37,6 @@ import {
formatSecondsShort,
} from '../../utils/format.js'
import { getGlobalConfig } from '../../utils/config.js'
import Link from '../../ink/components/Link.js'
import ThemedText from '../design-system/ThemedText.js'
import { CtrlOToExpand } from '../CtrlOToExpand.js'
import { useAppStateStore } from '../../state/AppState.js'
@@ -108,7 +108,6 @@ export function SystemTextMessage({
return null
}
if (message.subtype === 'bridge_status') {
return <BridgeStatusMessage message={message} addMargin={addMargin} />
}

View File

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

View File

@@ -1,7 +1,7 @@
import type { TextBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'
import * as React from 'react'
import { BLACK_CIRCLE } from '../../constants/figures.js'
import { Box, Text, type TextProps } from '../../ink.js'
import { Box, Text, type TextProps } from '@anthropic/ink'
import { extractTag } from '../../utils/messages.js'
type Props = {

View File

@@ -1,6 +1,6 @@
import type { TextBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'
import * as React from 'react'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import { extractTag } from '../../utils/messages.js'
type Props = {

View File

@@ -2,7 +2,7 @@ import type { TextBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'
import * as React from 'react'
import { CHANNEL_ARROW } from '../../constants/figures.js'
import { CHANNEL_TAG } from '../../constants/xml.js'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import { truncateToWidth } from '../../utils/format.js'
type Props = {

View File

@@ -2,7 +2,7 @@ import type { TextBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'
import figures from 'figures'
import * as React from 'react'
import { COMMAND_MESSAGE_TAG } from '../../constants/xml.js'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import { extractTag } from '../../utils/messages.js'
type Props = {

View File

@@ -1,8 +1,6 @@
import * as React from 'react'
import { pathToFileURL } from 'url'
import Link from '../../ink/components/Link.js'
import { supportsHyperlinks } from '../../ink/supports-hyperlinks.js'
import { Box, Text } from '../../ink.js'
import { Box, Link, supportsHyperlinks, Text } from '@anthropic/ink'
import { getStoredImagePath } from '../../utils/imageStore.js'
import { MessageResponse } from '../MessageResponse.js'

View File

@@ -1,7 +1,7 @@
import * as React from 'react'
import { DIAMOND_FILLED, DIAMOND_OPEN } from '../../constants/figures.js'
import { NO_CONTENT_MESSAGE } from '../../constants/messages.js'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import { extractTag } from '../../utils/messages.js'
import { Markdown } from '../Markdown.js'
import { MessageResponse } from '../MessageResponse.js'

View File

@@ -1,7 +1,7 @@
import sample from 'lodash-es/sample.js'
import * as React from 'react'
import { useMemo } from 'react'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import { extractTag } from '../../utils/messages.js'
import { MessageResponse } from '../MessageResponse.js'

View File

@@ -1,5 +1,5 @@
import * as React from 'react'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
import { Markdown } from '../Markdown.js'
type Props = {

View File

@@ -2,7 +2,7 @@ import { feature } from 'bun:bundle'
import type { TextBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'
import React, { useContext, useMemo } from 'react'
import { getKairosActive, getUserMsgOptIn } from '../../bootstrap/state.js'
import { Box } from '../../ink.js'
import { Box } from '@anthropic/ink'
import { getFeatureValue_CACHED_MAY_BE_STALE } from '../../services/analytics/growthbook.js'
import { useAppState } from '../../state/AppState.js'
import { isEnvTruthy } from '../../utils/envUtils.js'

View File

@@ -1,7 +1,7 @@
import type { TextBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'
import * as React from 'react'
import { REFRESH_ARROW } from '../../constants/figures.js'
import { Box, Text } from '../../ink.js'
import { Box, Text } from '@anthropic/ink'
type Props = {
addMargin: boolean

View File

@@ -2,8 +2,9 @@ import type { TextBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'
import figures from 'figures'
import * as React from 'react'
import { TEAMMATE_MESSAGE_TAG } from '../../constants/xml.js'
import { Ansi, Box, Text, type TextProps } from '../../ink.js'
import { Ansi, Box, Text, type TextProps } from '@anthropic/ink'
import { toInkColor } from '../../utils/ink.js'
import { jsonParse } from '../../utils/slowOperations.js'
import { isShutdownApproved } from '../../utils/teammateMailbox.js'
import { MessageResponse } from '../MessageResponse.js'

View File

@@ -1,7 +1,7 @@
import * as React from 'react'
import { Markdown } from 'src/components/Markdown.js'
import { MessageResponse } from 'src/components/MessageResponse.js'
import { Box, Text } from '../../../ink.js'
import { Box, Text } from '@anthropic/ink'
type Props = {
plan: string

View File

@@ -1,5 +1,5 @@
import * as React from 'react'
import { Text } from '../../../ink.js'
import { Text } from '@anthropic/ink'
import { MessageResponse } from '../../MessageResponse.js'
export function RejectedToolUseMessage(): React.ReactNode {

View File

@@ -2,7 +2,7 @@ import { feature } from 'bun:bundle'
import type { ToolResultBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'
import * as React from 'react'
import { BULLET_OPERATOR } from '../../../constants/figures.js'
import { Text } from '../../../ink.js'
import { Text } from '@anthropic/ink'
import {
filterToolProgressMessages,
type Tool,

View File

@@ -1,6 +1,6 @@
import * as React from 'react'
import { useTerminalSize } from '../../../hooks/useTerminalSize.js'
import { useTheme } from '../../../ink.js'
import { useTheme } from '@anthropic/ink'
import {
filterToolProgressMessages,
type Tool,

View File

@@ -2,7 +2,7 @@ import { feature } from 'bun:bundle'
import figures from 'figures'
import * as React from 'react'
import { SentryErrorBoundary } from 'src/components/SentryErrorBoundary.js'
import { Box, Text, useTheme } from '../../../ink.js'
import { Box, Text, useTheme } from '@anthropic/ink'
import { useAppState } from '../../../state/AppState.js'
import {
filterToolProgressMessages,

View File

@@ -1,5 +1,5 @@
import React from 'react'
import { Text } from '../../ink.js'
import { Text } from '@anthropic/ink'
import type { CollapsedReadSearchGroup } from '../../types/message.js'
/**