feat: 大规模清理 claude 的类型问题及依赖

This commit is contained in:
claude-code-best
2026-03-31 22:21:35 +08:00
parent 2c759fe6fa
commit 4c0a655a1c
38 changed files with 1154 additions and 718 deletions

View File

@@ -52,7 +52,7 @@ import type { JumpHandle } from './VirtualMessageList.js';
// and pegs CPU at 100%. Memo on agentDefinitions so a new messages array
// doesn't invalidate the logo subtree. LogoV2/StatusNotices internally
// subscribe to useAppState/useSettings for their own updates.
const LogoHeader = React.memo(function LogoHeader(t0) {
const LogoHeader = React.memo(function LogoHeader(t0: { agentDefinitions: AgentDefinitionsResult }) {
const $ = _c(3);
const {
agentDefinitions
@@ -400,7 +400,7 @@ const MessagesImpl = ({
for (let i = normalizedMessages.length - 1; i >= 0; i--) {
const msg = normalizedMessages[i];
if (msg?.type === 'assistant') {
const content = msg.message.content;
const content = msg.message.content as Array<{ type: string }>;
// Find the last thinking block in this message
for (let j = content.length - 1; j >= 0; j--) {
if (content[j]?.type === 'thinking') {
@@ -408,7 +408,7 @@ const MessagesImpl = ({
}
}
} else if (msg?.type === 'user') {
const hasToolResult = msg.message.content.some(block => block.type === 'tool_result');
const hasToolResult = (msg.message.content as Array<{ type: string }>).some(block => block.type === 'tool_result');
if (!hasToolResult) {
// Reached a previous user turn so don't show stale thinking from before
return 'no-thinking';
@@ -425,11 +425,11 @@ const MessagesImpl = ({
for (let i_0 = normalizedMessages.length - 1; i_0 >= 0; i_0--) {
const msg_0 = normalizedMessages[i_0];
if (msg_0?.type === 'user') {
const content_0 = msg_0.message.content;
const content_0 = msg_0.message.content as Array<{ type: string; text?: string }>;
// Check if any text content is bash output
for (const block_0 of content_0) {
if (block_0.type === 'text') {
const text = block_0.text;
const text = block_0.text!;
if (text.startsWith('<bash-stdout') || text.startsWith('<bash-stderr')) {
return msg_0.uuid;
}

View File

@@ -220,7 +220,7 @@ function SpinnerWithVerbInner({
// doesn't trigger re-renders; we pick up updates on the parent's ~25x/turn
// re-render cadence, same as the old ApiMetricsLine did.
let ttftText: string | null = null;
if ("external" === 'ant' && apiMetricsRef?.current && apiMetricsRef.current.length > 0) {
if (("external" as string) === 'ant' && apiMetricsRef?.current && apiMetricsRef.current.length > 0) {
ttftText = computeTtftText(apiMetricsRef.current);
}

View File

@@ -124,18 +124,18 @@ function StatsContent(t0) {
allTimePromise,
onClose
} = t0;
const allTimeResult = use(allTimePromise);
const [dateRange, setDateRange] = useState("all");
const allTimeResult = use(allTimePromise) as StatsResult;
const [dateRange, setDateRange] = useState<StatsDateRange>("all");
let t1;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
t1 = {};
t1 = {} as Record<string, ClaudeCodeStats>;
$[0] = t1;
} else {
t1 = $[0];
t1 = $[0] as Record<string, ClaudeCodeStats>;
}
const [statsCache, setStatsCache] = useState(t1);
const [statsCache, setStatsCache] = useState<Record<string, ClaudeCodeStats>>(t1);
const [isLoadingFiltered, setIsLoadingFiltered] = useState(false);
const [activeTab, setActiveTab] = useState("Overview");
const [activeTab, setActiveTab] = useState<"Overview" | "Models">("Overview");
const [copyStatus, setCopyStatus] = useState(null);
let t2;
let t3;
@@ -512,7 +512,7 @@ function OverviewTab({
</Box>
{/* Speculation time saved (ant-only) */}
{"external" === 'ant' && stats.totalSpeculationTimeSavedMs > 0 && <Box flexDirection="row" gap={4}>
{("external" as string) === 'ant' && stats.totalSpeculationTimeSavedMs > 0 && <Box flexDirection="row" gap={4}>
<Box flexDirection="column" width={28}>
<Text wrap="truncate">
Speculation saved:{' '}
@@ -1151,7 +1151,7 @@ function renderOverviewToAnsi(stats: ClaudeCodeStats): string[] {
lines.push(row('Active days', activeDaysVal, 'Peak hour', peakHourVal));
// Speculation time saved (ant-only)
if ("external" === 'ant' && stats.totalSpeculationTimeSavedMs > 0) {
if (("external" as string) === 'ant' && stats.totalSpeculationTimeSavedMs > 0) {
const label = 'Speculation saved:'.padEnd(COL1_LABEL_WIDTH);
lines.push(label + h(formatDuration(stats.totalSpeculationTimeSavedMs)));
}

View File

@@ -5,7 +5,7 @@ import React, { useCallback, useMemo, useRef } from 'react';
import { Box, Text } from '../ink.js';
import { useKeybindings } from '../keybindings/useKeybinding.js';
import { logEvent } from '../services/analytics/index.js';
import type { NormalizedUserMessage, RenderableMessage } from '../types/message.js';
import type { ContentItem, NormalizedUserMessage, RenderableMessage } from '../types/message.js';
import { isEmptyMessageText, SYNTHETIC_MESSAGES } from '../utils/messages.js';
const NAVIGABLE_TYPES = ['user', 'assistant', 'grouped_tool_use', 'collapsed_read_search', 'system', 'attachment'] as const;
export type NavigableType = (typeof NAVIGABLE_TYPES)[number];
@@ -19,7 +19,7 @@ export function isNavigableMessage(msg: NavigableMessage): boolean {
switch (msg.type) {
case 'assistant':
{
const b = msg.message.content[0];
const b = msg.message.content[0] as ContentItem | undefined;
// Text responses (minus AssistantTextMessage's return-null cases — tier-1
// misses unmeasured virtual items), or tool calls with extractable input.
return b?.type === 'text' && !isEmptyMessageText(b.text) && !SYNTHETIC_MESSAGES.has(b.text) || b?.type === 'tool_use' && b.name in PRIMARY_INPUT;
@@ -27,7 +27,7 @@ export function isNavigableMessage(msg: NavigableMessage): boolean {
case 'user':
{
if (msg.isMeta || msg.isCompactSummary) return false;
const b = msg.message.content[0];
const b = msg.message.content[0] as ContentItem | undefined;
if (b?.type !== 'text') return false;
// Interrupt etc. — synthetic, not user-authored.
if (SYNTHETIC_MESSAGES.has(b.text)) return false;
@@ -124,14 +124,14 @@ export function toolCallOf(msg: NavigableMessage): {
input: Record<string, unknown>;
} | undefined {
if (msg.type === 'assistant') {
const b = msg.message.content[0];
const b = msg.message.content[0] as ContentItem | undefined;
if (b?.type === 'tool_use') return {
name: b.name,
input: b.input as Record<string, unknown>
};
}
if (msg.type === 'grouped_tool_use') {
const b = msg.messages[0]?.message.content[0];
const b = msg.messages[0]?.message.content[0] as ContentItem | undefined;
if (b?.type === 'tool_use') return {
name: msg.toolName,
input: b.input as Record<string, unknown>
@@ -410,12 +410,12 @@ export function copyTextOf(msg: NavigableMessage): string {
switch (msg.type) {
case 'user':
{
const b = msg.message.content[0];
const b = msg.message.content[0] as ContentItem | undefined;
return b?.type === 'text' ? stripSystemReminders(b.text) : '';
}
case 'assistant':
{
const b = msg.message.content[0];
const b = msg.message.content[0] as ContentItem | undefined;
if (b?.type === 'text') return b.text;
const tc = toolCallOf(msg);
return tc ? PRIMARY_INPUT[tc.name]?.extract(tc.input) ?? '' : '';
@@ -425,14 +425,14 @@ export function copyTextOf(msg: NavigableMessage): string {
case 'collapsed_read_search':
return msg.messages.flatMap(m => m.type === 'user' ? [toolResultText(m)] : m.type === 'grouped_tool_use' ? m.results.map(toolResultText) : []).filter(Boolean).join('\n\n');
case 'system':
if ('content' in msg) return msg.content;
if ('content' in msg) return msg.content as string;
if ('error' in msg) return String(msg.error);
return msg.subtype;
return msg.subtype as string;
case 'attachment':
{
const a = msg.attachment;
if (a.type === 'queued_command') {
const p = a.prompt;
const p = a.prompt as string | ContentItem[];
return typeof p === 'string' ? p : p.flatMap(b => b.type === 'text' ? [b.text] : []).join('\n');
}
return `[${a.type}]`;
@@ -440,7 +440,7 @@ export function copyTextOf(msg: NavigableMessage): string {
}
}
function toolResultText(r: NormalizedUserMessage): string {
const b = r.message.content[0];
const b = r.message.content[0] as ContentItem | undefined;
if (b?.type !== 'tool_result') return '';
const c = b.content;
if (typeof c === 'string') return c;

View File

@@ -204,7 +204,7 @@ export function CollapsedReadSearchContent({
if (isActiveGroup) {
for (const id_0 of toolUseIds) {
if (!inProgressToolUseIDs.has(id_0)) continue;
const latest = lookups.progressMessagesByToolUseID.get(id_0)?.at(-1)?.data;
const latest = lookups.progressMessagesByToolUseID.get(id_0)?.at(-1)?.data as { type?: string; phase?: string; toolInput?: unknown; toolName?: string } | undefined;
if (latest?.type === 'repl_tool_call' && latest.phase === 'start') {
const input = latest.toolInput as {
command?: string;
@@ -276,13 +276,13 @@ export function CollapsedReadSearchContent({
let lines = 0;
for (const id_1 of toolUseIds) {
if (!inProgressToolUseIDs.has(id_1)) continue;
const data = lookups.progressMessagesByToolUseID.get(id_1)?.at(-1)?.data;
const data = lookups.progressMessagesByToolUseID.get(id_1)?.at(-1)?.data as { type?: string; elapsedTimeSeconds?: number; totalLines?: number } | undefined;
if (data?.type !== 'bash_progress' && data?.type !== 'powershell_progress') {
continue;
}
if (elapsed === undefined || data.elapsedTimeSeconds > elapsed) {
elapsed = data.elapsedTimeSeconds;
lines = data.totalLines;
if (elapsed === undefined || (data.elapsedTimeSeconds ?? 0) > elapsed) {
elapsed = data.elapsedTimeSeconds ?? 0;
lines = data.totalLines ?? 0;
}
}
if (elapsed !== undefined && elapsed >= 2) {

View File

@@ -158,7 +158,7 @@ function ExplanationResult(t0) {
const {
promise
} = t0;
const explanation = use(promise);
const explanation = use(promise) as PermissionExplanationType | null;
if (!explanation) {
let t1;
if ($[0] === Symbol.for("react.memo_cache_sentinel")) {

View File

@@ -1,4 +1,3 @@
// Auto-generated type stub — replace with real implementation
export type RemoteAgentTaskState = any;
export type RemoteAgentTask = any;
export type RemoteAgentTaskState = any;