/
aqa
/
claude-code
Обзор
Документация
Войти
/
aqa
/
claude-code
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
utils/statusNoticeDefinitions.tsx
198 строк
30 KB
kuberwastaken
new initial commit (history rewritten)
01 апр 2026, 14:57
01 апр 2026, 14:57
c1996f2
Код
Авторство
О чём код?
// biome-ignore-all assist/source/organizeImports: ANT-ONLY import markers must not be reordered import { Box, Text } from '../ink.js'; import * as React from 'react'; import { getLargeMemoryFiles, MAX_MEMORY_CHARACTER_COUNT, type MemoryFileInfo } from './claudemd.js'; import figures from 'figures'; import { getCwd } from './cwd.js'; import { relative } from 'path'; import { formatNumber } from './format.js'; import type { getGlobalConfig } from './config.js'; import { getAnthropicApiKeyWithSource, getApiKeyFromConfigOrMacOSKeychain, getAuthTokenSource, isClaudeAISubscriber } from './auth.js'; import type { AgentDefinitionsResult } from '../tools/AgentTool/loadAgentsDir.js'; import { getAgentDescriptionsTotalTokens, AGENT_DESCRIPTIONS_THRESHOLD } from './statusNoticeHelpers.js'; import { isSupportedJetBrainsTerminal, toIDEDisplayName, getTerminalIdeType } from './ide.js'; import { isJetBrainsPluginInstalledCachedSync } from './jetbrains.js'; // Types export type StatusNoticeType = 'warning' | 'info'; export type StatusNoticeContext = { config: ReturnType<typeof getGlobalConfig>; agentDefinitions?: AgentDefinitionsResult; memoryFiles: MemoryFileInfo[]; }; export type StatusNoticeDefinition = { id: string; type: StatusNoticeType; isActive: (context: StatusNoticeContext) => boolean; render: (context: StatusNoticeContext) => React.ReactNode; }; // Individual notice definitions const largeMemoryFilesNotice: StatusNoticeDefinition = { id: 'large-memory-files', type: 'warning', isActive: ctx => getLargeMemoryFiles(ctx.memoryFiles).length > 0, render: ctx => { const largeMemoryFiles = getLargeMemoryFiles(ctx.memoryFiles); return <> {largeMemoryFiles.map(file => { const displayPath = file.path.startsWith(getCwd()) ? relative(getCwd(), file.path) : file.path; return <Box key={file.path} flexDirection="row"> <Text color="warning">{figures.warning}</Text> <Text color="warning"> Large <Text bold>{displayPath}</Text> will impact performance ( {formatNumber(file.content.length)} chars >{' '} {formatNumber(MAX_MEMORY_CHARACTER_COUNT)}) <Text dimColor> · /memory to edit</Text> </Text> </Box>; })} </>; } }; const claudeAiSubscriberExternalTokenNotice: StatusNoticeDefinition = { id: 'claude-ai-external-token', type: 'warning', isActive: () => { const authTokenInfo = getAuthTokenSource(); return isClaudeAISubscriber() && (authTokenInfo.source === 'ANTHROPIC_AUTH_TOKEN' || authTokenInfo.source === 'apiKeyHelper'); }, render: () => { const authTokenInfo = getAuthTokenSource(); return <Box flexDirection="row" marginTop={1}> <Text color="warning">{figures.warning}</Text> <Text color="warning"> Auth conflict: Using {authTokenInfo.source} instead of Claude account subscription token. Either unset {authTokenInfo.source}, or run `claude /logout`. </Text> </Box>; } }; const apiKeyConflictNotice: StatusNoticeDefinition = { id: 'api-key-conflict', type: 'warning', isActive: () => { const { source: apiKeySource } = getAnthropicApiKeyWithSource({ skipRetrievingKeyFromApiKeyHelper: true }); return !!getApiKeyFromConfigOrMacOSKeychain() && (apiKeySource === 'ANTHROPIC_API_KEY' || apiKeySource === 'apiKeyHelper'); }, render: () => { const { source: apiKeySource } = getAnthropicApiKeyWithSource({ skipRetrievingKeyFromApiKeyHelper: true }); return <Box flexDirection="row" marginTop={1}> <Text color="warning">{figures.warning}</Text> <Text color="warning"> Auth conflict: Using {apiKeySource} instead of Anthropic Console key. Either unset {apiKeySource}, or run `claude /logout`. </Text> </Box>; } }; const bothAuthMethodsNotice: StatusNoticeDefinition = { id: 'both-auth-methods', type: 'warning', isActive: () => { const { source: apiKeySource } = getAnthropicApiKeyWithSource({ skipRetrievingKeyFromApiKeyHelper: true }); const authTokenInfo = getAuthTokenSource(); return apiKeySource !== 'none' && authTokenInfo.source !== 'none' && !(apiKeySource === 'apiKeyHelper' && authTokenInfo.source === 'apiKeyHelper'); }, render: () => { const { source: apiKeySource } = getAnthropicApiKeyWithSource({ skipRetrievingKeyFromApiKeyHelper: true }); const authTokenInfo = getAuthTokenSource(); return <Box flexDirection="column" marginTop={1}> <Box flexDirection="row"> <Text color="warning">{figures.warning}</Text> <Text color="warning"> Auth conflict: Both a token ({authTokenInfo.source}) and an API key ({apiKeySource}) are set. This may lead to unexpected behavior. </Text> </Box> <Box flexDirection="column" marginLeft={3}> <Text color="warning"> · Trying to use{' '} {authTokenInfo.source === 'claude.ai' ? 'claude.ai' : authTokenInfo.source} ?{' '} {apiKeySource === 'ANTHROPIC_API_KEY' ? 'Unset the ANTHROPIC_API_KEY environment variable, or claude /logout then say "No" to the API key approval before login.' : apiKeySource === 'apiKeyHelper' ? 'Unset the apiKeyHelper setting.' : 'claude /logout'} </Text> <Text color="warning"> · Trying to use {apiKeySource}?{' '} {authTokenInfo.source === 'claude.ai' ? 'claude /logout to sign out of claude.ai.' : `Unset the ${authTokenInfo.source} environment variable.`} </Text> </Box> </Box>; } }; const largeAgentDescriptionsNotice: StatusNoticeDefinition = { id: 'large-agent-descriptions', type: 'warning', isActive: context => { const totalTokens = getAgentDescriptionsTotalTokens(context.agentDefinitions); return totalTokens > AGENT_DESCRIPTIONS_THRESHOLD; }, render: context => { const totalTokens = getAgentDescriptionsTotalTokens(context.agentDefinitions); return <Box flexDirection="row"> <Text color="warning">{figures.warning}</Text> <Text color="warning"> Large cumulative agent descriptions will impact performance (~ {formatNumber(totalTokens)} tokens >{' '} {formatNumber(AGENT_DESCRIPTIONS_THRESHOLD)}) <Text dimColor> · /agents to manage</Text> </Text> </Box>; } }; const jetbrainsPluginNotice: StatusNoticeDefinition = { id: 'jetbrains-plugin-install', type: 'info', isActive: context => { // Only show if running in JetBrains built-in terminal if (!isSupportedJetBrainsTerminal()) { return false; } // Don't show if auto-install is disabled const shouldAutoInstall = context.config.autoInstallIdeExtension ?? true; if (!shouldAutoInstall) { return false; } // Check if plugin is already installed (cached to avoid repeated filesystem checks) const ideType = getTerminalIdeType(); return ideType !== null && !isJetBrainsPluginInstalledCachedSync(ideType); }, render: () => { const ideType = getTerminalIdeType(); const ideName = toIDEDisplayName(ideType); return <Box flexDirection="row" gap={1} marginLeft={1}> <Text color="ide">{figures.arrowUp}</Text> <Text> Install the <Text color="ide">{ideName}</Text> plugin from the JetBrains Marketplace:{' '} <Text bold>https://docs.claude.com/s/claude-code-jetbrains</Text> </Text> </Box>; } }; // All notice definitions export const statusNoticeDefinitions: StatusNoticeDefinition[] = [largeMemoryFilesNotice, largeAgentDescriptionsNotice, claudeAiSubscriberExternalTokenNotice, apiKeyConflictNotice, bothAuthMethodsNotice, jetbrainsPluginNotice]; // Helper functions for external use export function getActiveNotices(context: StatusNoticeContext): StatusNoticeDefinition[] { return statusNoticeDefinitions.filter(notice => notice.isActive(context)); } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJCb3giLCJUZXh0IiwiUmVhY3QiLCJnZXRMYXJnZU1lbW9yeUZpbGVzIiwiTUFYX01FTU9SWV9DSEFSQUNURVJfQ09VTlQiLCJNZW1vcnlG … [Строка слишком длинная. Вы можете скачать файл]