fix: remove runtime helper as-any casts
This commit is contained in:
parent
ba36ca454d
commit
ac807aeb08
|
|
@ -10,7 +10,7 @@ import { getGlobalConfig } from '../utils/config.js'
|
|||
import { getClaudeAIOAuthTokens } from '../utils/auth.js'
|
||||
import { getOauthConfig } from '../constants/oauth.js'
|
||||
import { getUserAgent } from '../utils/http.js'
|
||||
import type { Message } from '../types/message.js'
|
||||
import type { ContentItem, Message } from '../types/message.js'
|
||||
|
||||
// ─── Rate limiting ──────────────────────────────────
|
||||
|
||||
|
|
@ -64,6 +64,15 @@ export function triggerCompanionReaction(
|
|||
|
||||
// ─── Helpers ────────────────────────────────────────
|
||||
|
||||
function getMessageContent(
|
||||
message: Message,
|
||||
): string | ContentItem[] | undefined {
|
||||
const content = message.message?.content
|
||||
return typeof content === 'string' || Array.isArray(content)
|
||||
? content
|
||||
: undefined
|
||||
}
|
||||
|
||||
function isAddressed(messages: Message[], name: string): boolean {
|
||||
const pattern = new RegExp(`\\b${escapeRegex(name)}\\b`, 'i')
|
||||
for (
|
||||
|
|
@ -73,7 +82,7 @@ function isAddressed(messages: Message[], name: string): boolean {
|
|||
) {
|
||||
const m = messages[i]
|
||||
if (m?.type !== 'user') continue
|
||||
const content = (m as any).message?.content
|
||||
const content = getMessageContent(m)
|
||||
if (typeof content === 'string' && pattern.test(content)) return true
|
||||
}
|
||||
return false
|
||||
|
|
@ -89,14 +98,17 @@ function buildTranscript(messages: Message[]): string {
|
|||
.filter(m => m.type === 'user' || m.type === 'assistant')
|
||||
.map(m => {
|
||||
const role = m.type === 'user' ? 'user' : 'claude'
|
||||
const content = (m as any).message?.content
|
||||
const content = getMessageContent(m)
|
||||
const text =
|
||||
typeof content === 'string'
|
||||
? content.slice(0, 300)
|
||||
: Array.isArray(content)
|
||||
? content
|
||||
.filter((b: any) => b?.type === 'text')
|
||||
.map((b: any) => b.text)
|
||||
.filter(
|
||||
(b): b is Extract<ContentItem, { type: 'text' }> =>
|
||||
b.type === 'text',
|
||||
)
|
||||
.map(b => b.text)
|
||||
.join(' ')
|
||||
.slice(0, 300)
|
||||
: ''
|
||||
|
|
|
|||
|
|
@ -185,8 +185,8 @@ export async function getOutputStyleConfig(): Promise<OutputStyleConfig | null>
|
|||
const forcedStyles = Object.values(allStyles).filter(
|
||||
(style): style is OutputStyleConfig =>
|
||||
style !== null &&
|
||||
(style as any).source === 'plugin' &&
|
||||
(style as any).forceForPlugin === true,
|
||||
style.source === 'plugin' &&
|
||||
style.forceForPlugin === true,
|
||||
)
|
||||
|
||||
const firstForcedStyle = forcedStyles[0]
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
import { describe, test, expect, mock, beforeEach } from 'bun:test'
|
||||
|
||||
// --- MACRO 全局注入 (编译时 define 在测试中不可用) ---
|
||||
;(globalThis as any).MACRO = {
|
||||
globalThis.MACRO = {
|
||||
VERSION: '2.1.888',
|
||||
BUILD_TIME: '2026-04-22T00:00:00Z',
|
||||
FEEDBACK_CHANNEL: '',
|
||||
|
|
@ -214,7 +214,7 @@ const standardTools: Tools = [
|
|||
{ name: 'Agent' },
|
||||
{ name: 'AskUserQuestion' },
|
||||
{ name: 'TaskCreate' },
|
||||
] as any
|
||||
] as unknown as Tools
|
||||
|
||||
async function getFullPrompt(
|
||||
tools: Tools = standardTools,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import { isEnvTruthy } from '../utils/envUtils.js';
|
|||
// Runtime fallback for MACRO.* when not injected by build/dev defines.
|
||||
// This happens when running cli.tsx directly (not via `bun run dev` or built dist/).
|
||||
if (typeof globalThis.MACRO === 'undefined') {
|
||||
(globalThis as any).MACRO = {
|
||||
globalThis.MACRO = {
|
||||
VERSION: process.env.CLAUDE_CODE_VERSION || '2.1.888',
|
||||
BUILD_TIME: new Date().toISOString(),
|
||||
FEEDBACK_CHANNEL: '',
|
||||
|
|
|
|||
|
|
@ -142,9 +142,9 @@ export async function startMCPServer(
|
|||
(args as never) ?? {},
|
||||
toolUseContext,
|
||||
)
|
||||
if (validationResult && !validationResult.result) {
|
||||
if (validationResult?.result === false) {
|
||||
throw new Error(
|
||||
`Tool ${name} input is invalid: ${(validationResult as any).message}`,
|
||||
`Tool ${name} input is invalid: ${validationResult.message}`,
|
||||
)
|
||||
}
|
||||
const finalResult = await tool.call(
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ async function isAppleTerminalBellDisabled(): Promise<boolean> {
|
|||
// Lazy-load plist (~280KB with xmlbuilder+@xmldom) — only hit on
|
||||
// Apple_Terminal with auto-channel, which is a small fraction of users.
|
||||
const plist = await import('plist')
|
||||
const parsed: Record<string, unknown> = plist.parse(defaultsOutput.stdout) as any
|
||||
const parsed = plist.parse(defaultsOutput.stdout) as Record<string, unknown>
|
||||
const windowSettings = parsed?.['Window Settings'] as
|
||||
| Record<string, unknown>
|
||||
| undefined
|
||||
|
|
|
|||
|
|
@ -241,7 +241,7 @@ export async function startSkillDiscoveryPrefetch(
|
|||
durationMs: Date.now() - startedAt,
|
||||
indexSize: index.length,
|
||||
method: 'tfidf',
|
||||
} as any
|
||||
}
|
||||
|
||||
logForDebugging(
|
||||
`[skill-search] prefetch found ${newResults.length} skills in ${signal.durationMs}ms`,
|
||||
|
|
@ -306,7 +306,7 @@ export async function getTurnZeroSkillDiscovery(
|
|||
durationMs: Date.now() - startedAt,
|
||||
indexSize: index.length,
|
||||
method: 'tfidf',
|
||||
} as any
|
||||
}
|
||||
|
||||
logForDebugging(
|
||||
`[skill-search] turn-zero found ${results.length} skills in ${signal.durationMs}ms`,
|
||||
|
|
|
|||
|
|
@ -1,9 +1,8 @@
|
|||
// STUB: 待补全 — 见 docs/devlog/02-tsc-stubs.md
|
||||
// Skill search signal types — used by skill search prefetch and attachment utilities.
|
||||
// DiscoverySignal represents the signal emitted when a skill is discovered during prefetch.
|
||||
|
||||
export type DiscoverySignal = {
|
||||
type: 'skill_discovery'
|
||||
skillId: string
|
||||
[key: string]: unknown
|
||||
trigger: 'assistant_turn' | 'user_input'
|
||||
queryText: string
|
||||
startedAt: number
|
||||
durationMs: number
|
||||
indexSize: number
|
||||
method: 'tfidf'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -479,7 +479,13 @@ function roughTokenCountEstimationForBlock(
|
|||
return 2000
|
||||
}
|
||||
if (block.type === 'tool_result') {
|
||||
return roughTokenCountEstimationForContent(block.content as any)
|
||||
return roughTokenCountEstimationForContent(
|
||||
block.content as
|
||||
| string
|
||||
| Array<Anthropic.ContentBlock>
|
||||
| Array<Anthropic.ContentBlockParam>
|
||||
| undefined,
|
||||
)
|
||||
}
|
||||
if (block.type === 'tool_use') {
|
||||
// input is the JSON the model generated — arbitrarily large (bash
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
import type { BetaContentBlock, BetaUsage } from '@anthropic-ai/sdk/resources/beta/messages/messages.mjs'
|
||||
import type {
|
||||
BetaContentBlock,
|
||||
BetaUsage,
|
||||
} from '@anthropic-ai/sdk/resources/beta/messages/messages.mjs'
|
||||
import { createHash, randomUUID, type UUID } from 'crypto'
|
||||
import { mkdir, readFile, writeFile } from 'fs/promises'
|
||||
import isPlainObject from 'lodash-es/isPlainObject.js'
|
||||
|
|
@ -9,6 +12,7 @@ import { calculateUSDCost } from 'src/utils/modelCost.js'
|
|||
import type {
|
||||
AssistantMessage,
|
||||
Message,
|
||||
MessageContent,
|
||||
StreamEvent,
|
||||
SystemAPIErrorMessage,
|
||||
UserMessage,
|
||||
|
|
@ -252,24 +256,27 @@ function mapAssistantMessage(
|
|||
message: {
|
||||
...message.message,
|
||||
content: (message.message.content as BetaContentBlock[])
|
||||
.map(_ => {
|
||||
switch (_.type) {
|
||||
.map(block => {
|
||||
switch (block.type) {
|
||||
case 'text':
|
||||
return {
|
||||
..._,
|
||||
text: f(_.text) as string,
|
||||
citations: _.citations || [],
|
||||
...block,
|
||||
text: f(block.text) as string,
|
||||
citations: block.citations || [],
|
||||
} // Ensure citations
|
||||
case 'tool_use':
|
||||
return {
|
||||
..._,
|
||||
input: mapValuesDeep(_.input as Record<string, unknown>, f),
|
||||
...block,
|
||||
input: mapValuesDeep(block.input as Record<string, unknown>, f),
|
||||
}
|
||||
default:
|
||||
return _ // Handle other block types unchanged
|
||||
return block // Handle other block types unchanged
|
||||
}
|
||||
})
|
||||
.filter(Boolean) as any,
|
||||
.filter(
|
||||
(block): block is NonNullable<typeof block> =>
|
||||
block !== null && block !== undefined,
|
||||
) as unknown as MessageContent,
|
||||
},
|
||||
type: 'assistant',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ type SetAppStateFn = (updater: (prev: AppState) => AppState) => void
|
|||
|
||||
export function killTask(taskId: string, setAppState: SetAppStateFn): void {
|
||||
updateTaskState(taskId, setAppState, task => {
|
||||
if ((task as any).status !== 'running' || !isLocalShellTask(task)) {
|
||||
if (!isLocalShellTask(task) || task.status !== 'running') {
|
||||
return task
|
||||
}
|
||||
|
||||
|
|
|
|||
39
src/types/global.d.ts
vendored
39
src/types/global.d.ts
vendored
|
|
@ -16,12 +16,28 @@ declare namespace MACRO {
|
|||
export const VERSION_CHANGELOG: string
|
||||
}
|
||||
|
||||
interface GlobalThis {
|
||||
MACRO:
|
||||
| {
|
||||
VERSION: string
|
||||
BUILD_TIME: string
|
||||
FEEDBACK_CHANNEL: string
|
||||
ISSUES_EXPLAINER: string
|
||||
NATIVE_PACKAGE_URL: string
|
||||
PACKAGE_URL: string
|
||||
VERSION_CHANGELOG: string
|
||||
}
|
||||
| undefined
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Internal Anthropic-only identifiers (dead-code eliminated in open-source)
|
||||
// These are referenced inside `MACRO(() => ...)` or `false && ...` blocks.
|
||||
|
||||
// Model resolution (internal)
|
||||
declare function resolveAntModel(model: string): import('../utils/model/antModels.js').AntModel | undefined
|
||||
declare function resolveAntModel(
|
||||
model: string,
|
||||
): import('../utils/model/antModels.js').AntModel | undefined
|
||||
declare function getAntModels(): import('../utils/model/antModels.js').AntModel[]
|
||||
declare function getAntModelOverrideConfig(): {
|
||||
defaultSystemPromptSuffix?: string
|
||||
|
|
@ -31,7 +47,13 @@ declare function getAntModelOverrideConfig(): {
|
|||
// Companion reactions handled by src/buddy/companionReact.ts (direct import)
|
||||
|
||||
// Metrics (internal)
|
||||
type ApiMetricEntry = { ttftMs: number; firstTokenTime: number; lastTokenTime: number; responseLengthBaseline: number; endResponseLength: number }
|
||||
type ApiMetricEntry = {
|
||||
ttftMs: number
|
||||
firstTokenTime: number
|
||||
lastTokenTime: number
|
||||
responseLengthBaseline: number
|
||||
endResponseLength: number
|
||||
}
|
||||
declare const apiMetricsRef: React.RefObject<ApiMetricEntry[]> | null
|
||||
declare function computeTtftText(metrics: ApiMetricEntry[]): string
|
||||
|
||||
|
|
@ -44,8 +66,12 @@ declare function ExperimentEnrollmentNotice(): JSX.Element | null
|
|||
declare const HOOK_TIMING_DISPLAY_THRESHOLD_MS: number
|
||||
|
||||
// Ultraplan (internal)
|
||||
declare function UltraplanChoiceDialog(props: Record<string, unknown>): JSX.Element | null
|
||||
declare function UltraplanLaunchDialog(props: Record<string, unknown>): JSX.Element | null
|
||||
declare function UltraplanChoiceDialog(
|
||||
props: Record<string, unknown>,
|
||||
): JSX.Element | null
|
||||
declare function UltraplanLaunchDialog(
|
||||
props: Record<string, unknown>,
|
||||
): JSX.Element | null
|
||||
declare function launchUltraplan(...args: unknown[]): Promise<string>
|
||||
|
||||
// T — Generic type parameter leaked from React compiler output
|
||||
|
|
@ -53,7 +79,10 @@ declare function launchUltraplan(...args: unknown[]): Promise<string>
|
|||
declare type T = unknown
|
||||
|
||||
// Tungsten (internal)
|
||||
declare function TungstenPill(props?: { key?: string; selected?: boolean }): JSX.Element | null
|
||||
declare function TungstenPill(props?: {
|
||||
key?: string
|
||||
selected?: boolean
|
||||
}): JSX.Element | null
|
||||
|
||||
// ============================================================================
|
||||
// Build-time constants BUILD_TARGET/BUILD_ENV/INTERFACE_TYPE — removed (zero runtime usage)
|
||||
|
|
|
|||
|
|
@ -117,8 +117,8 @@ export function isAnthropicAuthEnabled(): boolean {
|
|||
isEnvTruthy(process.env.CLAUDE_CODE_USE_BEDROCK) ||
|
||||
isEnvTruthy(process.env.CLAUDE_CODE_USE_VERTEX) ||
|
||||
isEnvTruthy(process.env.CLAUDE_CODE_USE_FOUNDRY) ||
|
||||
(settings as any).modelType === 'openai' ||
|
||||
(settings as any).modelType === 'gemini' ||
|
||||
settings.modelType === 'openai' ||
|
||||
settings.modelType === 'gemini' ||
|
||||
!!process.env.OPENAI_BASE_URL ||
|
||||
!!process.env.GEMINI_BASE_URL
|
||||
const apiKeyHelper = settings.apiKeyHelper
|
||||
|
|
|
|||
|
|
@ -56,7 +56,7 @@ import { TASK_LIST_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/TaskL
|
|||
import { TASK_UPDATE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/TaskUpdateTool/constants.js'
|
||||
import { TEAM_CREATE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/TeamCreateTool/constants.js'
|
||||
import { TEAM_DELETE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/TeamDeleteTool/constants.js'
|
||||
import type { Message } from '../../types/message.js'
|
||||
import type { ContentItem, Message } from '../../types/message.js'
|
||||
import type { PermissionDecision } from '../../types/permissions.js'
|
||||
import {
|
||||
createAssistantAPIErrorMessage,
|
||||
|
|
@ -1449,13 +1449,16 @@ export async function runInProcessTeammate(
|
|||
for (let i = allMessages.length - 1; i >= 0; i--) {
|
||||
const m = allMessages[i]!
|
||||
if (m.type === 'assistant') {
|
||||
const blocks = (m.message?.content ?? []) as any[]
|
||||
const content = m.message?.content
|
||||
const blocks: ContentItem[] = Array.isArray(content) ? content : []
|
||||
for (const b of blocks) {
|
||||
if (b?.type === 'tool_use') completionToolUseCount++
|
||||
if (b.type === 'tool_use') completionToolUseCount++
|
||||
}
|
||||
const textBlocks = blocks.filter((b: any) => b?.type === 'text')
|
||||
const textBlocks = blocks.filter(
|
||||
(b): b is Extract<ContentItem, { type: 'text' }> => b.type === 'text',
|
||||
)
|
||||
if (textBlocks.length > 0 && lastAssistantContent.length === 0) {
|
||||
lastAssistantContent = textBlocks.map((b: any) => ({
|
||||
lastAssistantContent = textBlocks.map(b => ({
|
||||
type: 'text' as const,
|
||||
text: b.text,
|
||||
}))
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user