This commit is contained in:
y574444354 2026-04-11 12:48:57 +08:00
commit 48d64ccd23
14 changed files with 101 additions and 39 deletions

View File

@ -7,7 +7,7 @@ import { useAppState } from '../../state/AppState.js';
import { getEffortSuffix } from '../../utils/effort.js';
import { truncate } from '../../utils/format.js';
import { isFullscreenEnvEnabled } from '../../utils/fullscreen.js';
import { formatModelAndBilling, getLogoDisplayData, truncatePath } from '../../utils/logoV2Utils.js';
import { formatModelAndBilling, getLogoDisplayData, isNotLoggedIn, truncatePath } from '../../utils/logoV2Utils.js';
import { renderModelSetting } from '../../utils/model/model.js';
import { OffscreenFreeze } from '../OffscreenFreeze.js';
import { AnimatedClawd } from './AnimatedClawd.js';
@ -23,7 +23,10 @@ export function CondensedLogo(): ReactNode {
const { columns } = useTerminalSize();
const agent = useAppState(s => s.agent);
const effortValue = useAppState(s => s.effortValue);
// Subscribe to authVersion to re-render after login/logout
useAppState(s => s.authVersion);
const model = useMainLoopModel();
const notLoggedIn = isNotLoggedIn();
const modelDisplayName = renderModelSetting(model);
const { version, cwd, billingType, agentName: agentNameFromSettings } = getLogoDisplayData();
@ -92,7 +95,9 @@ export function CondensedLogo(): ReactNode {
</Text>{' '}
<Text dimColor>v{truncatedVersion}</Text>
</Text>
{shouldSplit ? (
{notLoggedIn ? (
<Text dimColor>Not logged in</Text>
) : shouldSplit ? (
<>
<Text dimColor>{truncatedModel}</Text>
<Text dimColor>{truncatedBilling}</Text>

View File

@ -11,6 +11,7 @@ import {
getRecentActivitySync,
getRecentReleaseNotesSync,
getLogoDisplayData,
isNotLoggedIn,
} from '../../utils/logoV2Utils.js';
import { truncate } from '../../utils/format.js';
import { getDisplayPath } from '../../utils/file.js';
@ -82,6 +83,8 @@ export function LogoV2(): React.ReactNode {
const showOverageCreditUpsell = useShowOverageCreditUpsell();
const agent = useAppState(s => s.agent);
const effortValue = useAppState(s => s.effortValue);
// Subscribe to authVersion to re-render after login/logout
useAppState(s => s.authVersion);
const config = getGlobalConfig();
@ -136,6 +139,7 @@ export function LogoV2(): React.ReactNode {
}, [showOverageCreditUpsell, showOnboarding, showGuestPassesUpsell, isCondensedMode]);
const model = useMainLoopModel();
const notLoggedIn = isNotLoggedIn();
const fullModelDisplayName = renderModelSetting(model);
const { version, cwd, billingType, agentName: agentNameFromSettings } = getLogoDisplayData();
// Prefer AppState.agent (set from --agent CLI flag) over settings
@ -247,8 +251,8 @@ export function LogoV2(): React.ReactNode {
<Box marginY={1}>
<Clawd />
</Box>
<Text dimColor>{modelDisplayName}</Text>
<Text dimColor>{billingType}</Text>
<Text dimColor>{notLoggedIn ? 'Not logged in' : modelDisplayName}</Text>
{!notLoggedIn && <Text dimColor>{billingType}</Text>}
<Text dimColor>{agentName ? `@${agentName} · ${truncatedCwd}` : truncatedCwd}</Text>
</Box>
</OffscreenFreeze>
@ -269,8 +273,9 @@ export function LogoV2(): React.ReactNode {
}
const welcomeMessage = formatWelcomeMessage(username);
const modelLine =
!process.env.IS_DEMO && config.oauthAccount?.organizationName
const modelLine = notLoggedIn
? 'Not logged in'
: !process.env.IS_DEMO && config.oauthAccount?.organizationName
? `${modelDisplayName} · ${billingType} · ${config.oauthAccount.organizationName}`
: `${modelDisplayName} · ${billingType}`;
// Calculate cwd width accounting for agent name if present

View File

@ -573,10 +573,10 @@ function getRequirementSystemPrompt(): string {
---
# 使
1. 使 read
2. 使 write
3. 使 edit
4. 使 bash
1. 使 Read
2. 使 Write
3. 使 Edit
4. 使 Bash
#

View File

@ -53,7 +53,7 @@ function getStrictPlanSystemPrompt(): string {
(2) //
(3)
- **SubAgent产出要求**SubAgent必须提供可操作的技术决策依据
- **Agent调用**\`task\`工具,并行启动 1~3 个QuickExplore SubAgent高效完成项目探索工作
- **Agent调用**\`Agent\`工具,并行启动 1~3 个QuickExplore SubAgent高效完成项目探索工作
- 3 使 1
- SubAgent适用场景
- SubAgent适用场景
@ -124,18 +124,18 @@ SubCodingAgent 只需理解与其任务直接相关的内容。分发任务时
#####
使 \`todowrite\` 工具列出 task.md 中的任务清单,作为待办事项跟踪。
使 \`TodoWrite\` 工具列出 task.md 中的任务清单,作为待办事项跟踪。
****
1. **** \`task\` 工具启动 SubCodingAgent 分发任务
1. **** \`Agent\` 工具启动 SubCodingAgent 分发任务
2. ****
- SubCodingAgent的任务完成情况
- SubCodingAgent
-
- ** task.md**使 \`edit\` 更新 task.md 文件,将刚完成的任务标记为已完成(\`- [x]\`
- ** todos **使 \`todowrite\` 工具将当前任务标记为完成
- ** task.md**使 \`Edit\` 更新 task.md 文件,将刚完成的任务标记为已完成(\`- [x]\`
- ** todos **使 \`TodoWrite\` 工具将当前任务标记为完成
- ****** task.md todos**
3. ****

View File

@ -16,7 +16,7 @@ function getSubCodingSystemPrompt(): string {
-
-
\`read\` 命令读取代码片段)。
\`Read\` 工具读取代码片段)。
###
- /

View File

@ -50,7 +50,7 @@ function getTaskCheckSystemPrompt(): string {
### 3
issues
1. //
2. \`question\` 工具
2. \`AskUserQuestion\` 工具
3. continue 2
###

View File

@ -99,7 +99,7 @@ Phase 6修复编码问题
****
- ********
- ****使 \`question\` 工具请求用户许可
- ****使 \`AskUserQuestion\` 工具请求用户许可
- "在 [文件名] 中发现错误:[错误描述]。该文件最近未修改,允许我修复吗?"
-
-
@ -214,7 +214,7 @@ Phase 9完成验证
****
-
- 使 \`question\` 工具请求许可
- 使 \`AskUserQuestion\` 工具请求许可
-
-

View File

@ -24,8 +24,8 @@ function getTddTestPrepareSystemPrompt(): string {
4. ****
- TEST_GUIDE.md 使
- 使 \`question\` 工具向用户确认后才能使用
- / question
- 使 \`AskUserQuestion\` 工具向用户确认后才能使用
- / AskUserQuestion
- ** TEST_GUIDE.md TODO **
5. **退**
@ -36,15 +36,15 @@ function getTddTestPrepareSystemPrompt(): string {
<workflow>
**使 todowrite **
**使 TodoWrite **
使 \`todowrite\` 工具创建任务列表:
使 \`TodoWrite\` 工具创建任务列表:
1. Check TEST_GUIDE.md completeness
2. Ask user if auto-search needed
3. Identify runnability verification commands
4. Identify test case management methods
5. Identify test execution methods
6. Confirm with user (question tool)
6. Confirm with user (AskUserQuestion tool)
7. Update TEST_GUIDE.md
phase
@ -63,7 +63,7 @@ Phase 1检查 TEST_GUIDE.md 完整性并解析指引文档
5. Phase 1.5
Phase 1.5
- 使 \`question\` 工具询问用户是否需要自动搜索项目文件
- 使 \`AskUserQuestion\` 工具询问用户是否需要自动搜索项目文件
- header: "搜索方式"
- question: "TEST_GUIDE.md 内容不完整,是否自动搜索项目文件以分析测试命令?(支持在后续确认时自定义输入)"
- options: [
@ -93,7 +93,7 @@ Phase 2搜索项目文件仅当用户选择"自动搜索"时执行,使
- 2CI/CD .github/workflows.gitlab-ci.yml
- 3jestpytestgo testnpm testbun test
Phase 3使 \`question\` 工具,三个问题作为独立数组提交)
Phase 3使 \`AskUserQuestion\` 工具,三个问题作为独立数组提交)
**1**
- header: "可运行性"

View File

@ -21,7 +21,7 @@ function getWikiCatalogueDesignSystemPrompt(): string {
JSON文档结构
##
- ****: \`read\` 工具读取 \`.costrict/wiki/.staging/basic_analyze.json\`
- ****: \`Read\` 工具读取 \`.costrict/wiki/.staging/basic_analyze.json\`
- ****:
##

View File

@ -104,7 +104,7 @@ function getWikiDocumentGenerateSystemPrompt(): string {
### 3 -
1. ****: 使 \`read\` 工具读取每个关键文件
1. ****: 使 \`Read\` 工具读取每个关键文件
2. ****
- MVC
@ -162,7 +162,7 @@ function getWikiDocumentGenerateSystemPrompt(): string {
- 优先级4: 环境变量配置
****
- 使 \`read\` 工具按优先级批量读取关键代码文件
- 使 \`Read\` 工具按优先级批量读取关键代码文件
-
-
-

View File

@ -19,7 +19,7 @@ function getWikiProjectAnalyzeSystemPrompt(): string {
###
- ****: README.mdpackage.jsonrequirements.txtCargo.toml等核心配置
- ****: tsconfig.jsonpyproject.tomlDockerfileCI/CD配置等
- ****: \`list\` 工具获取的项目全貌
- ****: \`Bash\` 工具获取的项目全貌
##
@ -108,8 +108,8 @@ function getWikiProjectAnalyzeSystemPrompt(): string {
##
### 1
- 使 \`list\` 工具获取完整项目结构
- 使 \`read\` 工具解析关键配置文件
- 使 \`Bash\` 工具获取完整项目结构
- 使 \`Read\` 工具解析关键配置文件
-
### 2

View File

@ -6,7 +6,7 @@ import { DESIGN_AGENT } from '../../costrict/agents/designAgent.js'
import { QUICK_EXPLORE_AGENT } from '../../costrict/agents/quickExplore.js'
import { REQUIREMENT_AGENT } from '../../costrict/agents/requirement.js'
import { STRICT_PLAN_AGENT } from '../../costrict/agents/strictPlan.js'
import { STRICT_SPEC_AGENT } from '../../costrict/agents/strictSpec.js'
// import { STRICT_SPEC_AGENT } from '../../costrict/agents/strictSpec.js'
import { SUB_CODING_AGENT } from '../../costrict/agents/subCoding.js'
import { TASK_CHECK_AGENT } from '../../costrict/agents/taskCheck.js'
import { TASK_PLAN_AGENT } from '../../costrict/agents/taskPlan.js'
@ -64,7 +64,7 @@ export function getBuiltInAgents(): AgentDefinition[] {
STATUSLINE_SETUP_AGENT,
PLAN_AGENT,
// StrictSpec workflow: 4-stage pipeline (Requirement → DesignAgent → TaskPlan → SubCoding)
STRICT_SPEC_AGENT,
// STRICT_SPEC_AGENT,
REQUIREMENT_AGENT,
DESIGN_AGENT,
TASK_PLAN_AGENT,

View File

@ -1,7 +1,8 @@
import { getDirectConnectServerUrl, getSessionId } from '../bootstrap/state.js'
import { stringWidth } from '@anthropic/ink'
import type { LogOption } from '../types/logs.js'
import { getSubscriptionName, isClaudeAISubscriber } from './auth.js'
import { getAnthropicApiKey } from './auth.js'
import { hasCoStrictCredentialsSync } from '../costrict/provider/credentials.js'
import { getCwd } from './cwd.js'
import { getDisplayPath } from './file.js'
import {
@ -9,6 +10,7 @@ import {
truncateToWidth,
truncateToWidthNoEllipsis,
} from './format.js'
import { getAPIProvider, getProviderDisplayName } from './model/providers.js'
import { getStoredChangelogFromMemory, parseChangelog } from './releaseNotes.js'
import { gt } from './semver.js'
import { loadMessageLogs } from './sessionStorage.js'
@ -237,12 +239,33 @@ export function formatReleaseNoteForDisplay(
}
/**
* Gets the common logo display data used by both LogoV2 and CondensedLogo
* Check if user is not logged in
* User is considered logged in if they have CoStrict credentials or API key
*/
export function isNotLoggedIn(): boolean {
// 1. CoStrict login (credentials file exists)
if (hasCoStrictCredentialsSync()) return false
const settings = getInitialSettings()
// 2. Any provider configured via modelType (包括 anthropic/openai/bedrock 等)
// 用户通过 /login 选择 provider 后会设置 modelType
if (settings.modelType) {
return false
}
// 3. Anthropic API Key configured (legacy way without modelType)
if (getAnthropicApiKey() !== null) return false
// None of the above - not logged in
return true
}
export function getLogoDisplayData(): {
version: string
cwd: string
billingType: string
isLoggedIn: boolean
agentName: string | undefined
} {
const version = process.env.DEMO_VERSION ?? MACRO.VERSION
@ -253,15 +276,18 @@ export function getLogoDisplayData(): {
const cwd = serverUrl
? `${displayPath} in ${serverUrl.replace(/^https?:\/\//, '')}`
: displayPath
const billingType = isClaudeAISubscriber()
? getSubscriptionName()
: 'API Usage Billing'
const loggedIn = !isNotLoggedIn()
const provider = getAPIProvider()
const providerName = getProviderDisplayName(provider)
const billingType = loggedIn ? providerName : 'Not logged in'
const agentName = getInitialSettings().agent
return {
version,
cwd,
billingType,
isLoggedIn: loggedIn,
agentName,
}
}

View File

@ -35,6 +35,32 @@ export function getAPIProviderForStatsig(): AnalyticsMetadata_I_VERIFIED_THIS_IS
return getAPIProvider() as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS
}
/**
* Get a human-readable display name for the current API provider
*/
export function getProviderDisplayName(provider: APIProvider): string {
switch (provider) {
case 'firstParty':
return 'Anthropic'
case 'bedrock':
return 'AWS Bedrock'
case 'vertex':
return 'Google Vertex'
case 'foundry':
return 'Foundry'
case 'openai':
return 'OpenAI'
case 'gemini':
return 'Google Gemini'
case 'grok':
return 'xAI Grok'
case 'costrict':
return 'CoStrict'
default:
return provider
}
}
/**
* Check if ANTHROPIC_BASE_URL is a first-party Anthropic API URL.
* Returns true if not set (default API) or points to api.anthropic.com