refactor: 重构 provider、agents、status 及相关工具模块
This commit is contained in:
parent
3c41abe5ef
commit
88e2ce1e70
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -1,4 +1,4 @@
|
|||
#node_modules
|
||||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
coverage
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
{"t":0,"agent":"a9f2b75","agent_type":"general-purpose","event":"agent_start","parent_mode":"none"}
|
||||
{"t":0,"agent":"a9f2b75","agent_type":"general-purpose","event":"agent_stop","success":true,"duration_ms":268224}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
{
|
||||
"name": "@costrict/csc-beta",
|
||||
"name": "@costrict/csc",
|
||||
"version": "4.0.4",
|
||||
|
||||
"description": "Reverse-engineered Anthropic Claude Code CLI — interactive AI coding assistant in the terminal",
|
||||
|
|
|
|||
|
|
@ -2,27 +2,27 @@ import { feature } from 'bun:bundle'
|
|||
import { getIsNonInteractiveSession } from 'src/bootstrap/state.js'
|
||||
import { getFeatureValue_CACHED_MAY_BE_STALE } from 'src/services/analytics/growthbook.js'
|
||||
import { isEnvTruthy } from 'src/utils/envUtils.js'
|
||||
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 { 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'
|
||||
import { DESIGN_AGENT } from 'src/costrict/agents/designAgent.js'
|
||||
import { QUICK_EXPLORE_AGENT } from 'src/costrict/agents/quickExplore.js'
|
||||
import { REQUIREMENT_AGENT } from 'src/costrict/agents/requirement.js'
|
||||
import { STRICT_PLAN_AGENT } from 'src/costrict/agents/strictPlan.js'
|
||||
// import { STRICT_SPEC_AGENT } from 'src/costrict/agents/strictSpec.js'
|
||||
import { SUB_CODING_AGENT } from 'src/costrict/agents/subCoding.js'
|
||||
import { TASK_CHECK_AGENT } from 'src/costrict/agents/taskCheck.js'
|
||||
import { TASK_PLAN_AGENT } from 'src/costrict/agents/taskPlan.js'
|
||||
import { CLAUDE_CODE_GUIDE_AGENT } from './built-in/claudeCodeGuideAgent.js'
|
||||
import { EXPLORE_AGENT } from './built-in/exploreAgent.js'
|
||||
import { GENERAL_PURPOSE_AGENT } from './built-in/generalPurposeAgent.js'
|
||||
import { PLAN_AGENT } from './built-in/planAgent.js'
|
||||
import { WIKI_PROJECT_ANALYZE_AGENT } from '../../costrict/agents/wikiProjectAnalyze.js'
|
||||
import { WIKI_CATALOGUE_DESIGN_AGENT } from '../../costrict/agents/wikiCatalogueDesign.js'
|
||||
import { WIKI_DOCUMENT_GENERATE_AGENT } from '../../costrict/agents/wikiDocumentGenerate.js'
|
||||
import { WIKI_INDEX_GENERATION_AGENT } from '../../costrict/agents/wikiIndexGeneration.js'
|
||||
import { TDD_RUN_AND_FIX_AGENT } from '../../costrict/agents/tddRunAndFix.js'
|
||||
import { TDD_TEST_AND_FIX_AGENT } from '../../costrict/agents/tddTestAndFix.js'
|
||||
import { TDD_TEST_DESIGN_AGENT } from '../../costrict/agents/tddTestDesign.js'
|
||||
import { TDD_TEST_PREPARE_AGENT } from '../../costrict/agents/tddTestPrepare.js'
|
||||
import { TDD_AGENT } from '../../costrict/backup/tdd.js'
|
||||
import { WIKI_PROJECT_ANALYZE_AGENT } from 'src/costrict/agents/wikiProjectAnalyze.js'
|
||||
import { WIKI_CATALOGUE_DESIGN_AGENT } from 'src/costrict/agents/wikiCatalogueDesign.js'
|
||||
import { WIKI_DOCUMENT_GENERATE_AGENT } from 'src/costrict/agents/wikiDocumentGenerate.js'
|
||||
import { WIKI_INDEX_GENERATION_AGENT } from 'src/costrict/agents/wikiIndexGeneration.js'
|
||||
import { TDD_RUN_AND_FIX_AGENT } from 'src/costrict/agents/tddRunAndFix.js'
|
||||
import { TDD_TEST_AND_FIX_AGENT } from 'src/costrict/agents/tddTestAndFix.js'
|
||||
import { TDD_TEST_DESIGN_AGENT } from 'src/costrict/agents/tddTestDesign.js'
|
||||
import { TDD_TEST_PREPARE_AGENT } from 'src/costrict/agents/tddTestPrepare.js'
|
||||
import { TDD_AGENT } from 'src/costrict/backup/tdd.js'
|
||||
import { STATUSLINE_SETUP_AGENT } from './built-in/statuslineSetup.js'
|
||||
import { VERIFICATION_AGENT } from './built-in/verificationAgent.js'
|
||||
import type { AgentDefinition } from './loadAgentsDir.js'
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import React, { useCallback, useEffect, useRef, useState } from 'react';
|
||||
import type { Theme } from '@anthropic/ink';
|
||||
import {
|
||||
type AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
logEvent,
|
||||
|
|
@ -1251,7 +1252,7 @@ function OAuthStatusMessage({
|
|||
<Box flexDirection="column" gap={1}>
|
||||
<Text>Opening browser for CoStrict login. If it does not open automatically, copy and paste this URL:</Text>
|
||||
<Box marginY={1}>
|
||||
<Text color="cyan">{oauthStatus.url}</Text>
|
||||
<Text color={'cyan' as keyof Theme}>{oauthStatus.url}</Text>
|
||||
</Box>
|
||||
<Text dimColor>Waiting for authentication...</Text>
|
||||
</Box>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { EXIT_PLAN_MODE_TOOL_NAME } from 'src/tools/ExitPlanModeTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from 'src/tools/AgentTool/loadAgentsDir.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/ExitPlanModeTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getDesignAgentSystemPrompt(): string {
|
||||
return `你是 DesignAgent,一名专业软件开发团队中的资深软件架构师。
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { EXIT_PLAN_MODE_TOOL_NAME } from 'src/tools/ExitPlanModeTool/constants.js'
|
||||
import { FILE_EDIT_TOOL_NAME } from 'src/tools/FileEditTool/constants.js'
|
||||
import { FILE_WRITE_TOOL_NAME } from 'src/tools/FileWriteTool/prompt.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from 'src/tools/NotebookEditTool/constants.js'
|
||||
import { AGENT_TOOL_NAME } from '../../tools/AgentTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from 'src/tools/AgentTool/loadAgentsDir.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/ExitPlanModeTool/constants.js'
|
||||
import { FILE_EDIT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/FileEditTool/constants.js'
|
||||
import { FILE_WRITE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/FileWriteTool/prompt.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/NotebookEditTool/constants.js'
|
||||
import { AGENT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/AgentTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getQuickExploreSystemPrompt(): string {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { EXIT_PLAN_MODE_TOOL_NAME } from 'src/tools/ExitPlanModeTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from 'src/tools/AgentTool/loadAgentsDir.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/ExitPlanModeTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getRequirementSystemPrompt(): string {
|
||||
return `# 角色
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { EXIT_PLAN_MODE_TOOL_NAME } from 'src/tools/ExitPlanModeTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from 'src/tools/AgentTool/loadAgentsDir.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/ExitPlanModeTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getStrictPlanSystemPrompt(): string {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { EXIT_PLAN_MODE_TOOL_NAME } from 'src/tools/ExitPlanModeTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from 'src/tools/AgentTool/loadAgentsDir.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/ExitPlanModeTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getStrictSpecSystemPrompt(): string {
|
||||
return `你是工作流编排专家,负责将用户需求按照标准阶段分配到对应工作流Agent执行。
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { EXIT_PLAN_MODE_TOOL_NAME } from 'src/tools/ExitPlanModeTool/constants.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from 'src/tools/NotebookEditTool/constants.js'
|
||||
import { AGENT_TOOL_NAME } from '../../tools/AgentTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from '../../tools/AgentTool/loadAgentsDir.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/ExitPlanModeTool/constants.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/NotebookEditTool/constants.js'
|
||||
import { AGENT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/AgentTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getSubCodingSystemPrompt(): string {
|
||||
return `你是SubCodingAgent,一名专业软件开发团队中的开发人员。
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { EXIT_PLAN_MODE_TOOL_NAME } from 'src/tools/ExitPlanModeTool/constants.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from 'src/tools/NotebookEditTool/constants.js'
|
||||
import { AGENT_TOOL_NAME } from '../../tools/AgentTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from '../../tools/AgentTool/loadAgentsDir.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/ExitPlanModeTool/constants.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/NotebookEditTool/constants.js'
|
||||
import { AGENT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/AgentTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getTaskCheckSystemPrompt(): string {
|
||||
return `你是 TaskCheckAgent,一名专业的软件开发任务质量检查与修复专家。
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { EXIT_PLAN_MODE_TOOL_NAME } from 'src/tools/ExitPlanModeTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from 'src/tools/AgentTool/loadAgentsDir.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/ExitPlanModeTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getTaskPlanSystemPrompt(): string {
|
||||
return `# 核心职责
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { AGENT_TOOL_NAME } from '../../tools/AgentTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from '../../tools/AgentTool/loadAgentsDir.js'
|
||||
import { AGENT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/AgentTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getTddRunAndFixSystemPrompt(): string {
|
||||
return `<role>你是 RunAndFixAgent,一名可运行性验证与代码修复专家,擅长诊断和解决编译构建问题。</role>
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { BuiltInAgentDefinition } from '../../tools/AgentTool/loadAgentsDir.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getTddTestAndFixSystemPrompt(): string {
|
||||
return `<role>你是 TestAndFixAgent,一名测试执行与自动修复专家,擅长诊断和解决测试失败问题。</role>
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { BASH_TOOL_NAME } from '../../tools/BashTool/toolName.js'
|
||||
import type { BuiltInAgentDefinition } from '../../tools/AgentTool/loadAgentsDir.js'
|
||||
import { BASH_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/BashTool/toolName.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getTddTestDesignSystemPrompt(): string {
|
||||
return `<role>你是 TestDesignAgent,一名测试点设计与测试用例规划专家,精通测试自动化。</role>
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { AGENT_TOOL_NAME } from '../../tools/AgentTool/constants.js'
|
||||
import { BASH_TOOL_NAME } from '../../tools/BashTool/toolName.js'
|
||||
import type { BuiltInAgentDefinition } from '../../tools/AgentTool/loadAgentsDir.js'
|
||||
import { AGENT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/AgentTool/constants.js'
|
||||
import { BASH_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/BashTool/toolName.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getTddTestPrepareSystemPrompt(): string {
|
||||
return `<role>你是 TestPrepareAgent,一名测试配置检查与文档准备专家,专注于项目的测试执行和管理方法识别。</role>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { AGENT_TOOL_NAME } from '../../tools/AgentTool/constants.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '../../tools/ExitPlanModeTool/constants.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from '../../tools/NotebookEditTool/constants.js'
|
||||
import { SKILL_TOOL_NAME } from '../../tools/SkillTool/constants.js'
|
||||
import { WEB_FETCH_TOOL_NAME } from '../../tools/WebFetchTool/prompt.js'
|
||||
import type { BuiltInAgentDefinition } from '../../tools/AgentTool/loadAgentsDir.js'
|
||||
import { AGENT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/AgentTool/constants.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/ExitPlanModeTool/constants.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/NotebookEditTool/constants.js'
|
||||
import { SKILL_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/SkillTool/constants.js'
|
||||
import { WEB_FETCH_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/WebFetchTool/prompt.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getWikiCatalogueDesignSystemPrompt(): string {
|
||||
return `# 技术文档结构设计
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { AGENT_TOOL_NAME } from '../../tools/AgentTool/constants.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '../../tools/ExitPlanModeTool/constants.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from '../../tools/NotebookEditTool/constants.js'
|
||||
import { SKILL_TOOL_NAME } from '../../tools/SkillTool/constants.js'
|
||||
import { WEB_FETCH_TOOL_NAME } from '../../tools/WebFetchTool/prompt.js'
|
||||
import type { BuiltInAgentDefinition } from '../../tools/AgentTool/loadAgentsDir.js'
|
||||
import { AGENT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/AgentTool/constants.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/ExitPlanModeTool/constants.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/NotebookEditTool/constants.js'
|
||||
import { SKILL_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/SkillTool/constants.js'
|
||||
import { WEB_FETCH_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/WebFetchTool/prompt.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getWikiDocumentGenerateSystemPrompt(): string {
|
||||
return `# 技术文档生成
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { AGENT_TOOL_NAME } from '../../tools/AgentTool/constants.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '../../tools/ExitPlanModeTool/constants.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from '../../tools/NotebookEditTool/constants.js'
|
||||
import { SKILL_TOOL_NAME } from '../../tools/SkillTool/constants.js'
|
||||
import { WEB_FETCH_TOOL_NAME } from '../../tools/WebFetchTool/prompt.js'
|
||||
import type { BuiltInAgentDefinition } from '../../tools/AgentTool/loadAgentsDir.js'
|
||||
import { AGENT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/AgentTool/constants.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/ExitPlanModeTool/constants.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/NotebookEditTool/constants.js'
|
||||
import { SKILL_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/SkillTool/constants.js'
|
||||
import { WEB_FETCH_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/WebFetchTool/prompt.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getWikiIndexGenerationSystemPrompt(): string {
|
||||
return `# 索引文档生成
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
import { AGENT_TOOL_NAME } from '../../tools/AgentTool/constants.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '../../tools/ExitPlanModeTool/constants.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from '../../tools/NotebookEditTool/constants.js'
|
||||
import { SKILL_TOOL_NAME } from '../../tools/SkillTool/constants.js'
|
||||
import { WEB_FETCH_TOOL_NAME } from '../../tools/WebFetchTool/prompt.js'
|
||||
import type { BuiltInAgentDefinition } from '../../tools/AgentTool/loadAgentsDir.js'
|
||||
import { AGENT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/AgentTool/constants.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/ExitPlanModeTool/constants.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/NotebookEditTool/constants.js'
|
||||
import { SKILL_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/SkillTool/constants.js'
|
||||
import { WEB_FETCH_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/WebFetchTool/prompt.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getWikiProjectAnalyzeSystemPrompt(): string {
|
||||
return `# 项目基本分析
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { EXIT_PLAN_MODE_TOOL_NAME } from 'src/tools/ExitPlanModeTool/constants.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from 'src/tools/NotebookEditTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from 'src/tools/AgentTool/loadAgentsDir.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/ExitPlanModeTool/constants.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/NotebookEditTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getPlanApplySystemPrompt(): string {
|
||||
return `你是 CodingAgent,软件开发团队的项目管理者和技术架构师。
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
import { EXIT_PLAN_MODE_TOOL_NAME } from 'src/tools/ExitPlanModeTool/constants.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from 'src/tools/NotebookEditTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from 'src/tools/AgentTool/loadAgentsDir.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/ExitPlanModeTool/constants.js'
|
||||
import { NOTEBOOK_EDIT_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/NotebookEditTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getReviewAndFixSystemPrompt(): string {
|
||||
return `你是ReviewAndFix Agent,一名专业软件开发团队中的代码审查与修复专家。
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import type { BuiltInAgentDefinition } from 'src/tools/AgentTool/loadAgentsDir.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/ExitPlanModeTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getSpecPlanSystemPrompt(): string {
|
||||
return `你是 SpecPlan,软件开发团队的全流程实施协调者。
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { EXIT_PLAN_MODE_TOOL_NAME } from 'src/tools/ExitPlanModeTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from 'src/tools/AgentTool/loadAgentsDir.js'
|
||||
import { EXIT_PLAN_MODE_TOOL_NAME } from '@claude-code-best/builtin-tools/tools/ExitPlanModeTool/constants.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getStrictPlanSystemPrompt(): string {
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import type { BuiltInAgentDefinition } from 'src/tools/AgentTool/loadAgentsDir.js'
|
||||
import type { BuiltInAgentDefinition } from '@claude-code-best/builtin-tools/tools/AgentTool/loadAgentsDir.js'
|
||||
|
||||
function getTddSystemPrompt(): string {
|
||||
return `<role>你是 TestDrivenDevelopment Agent,负责执行全面的测试工作流程以确保代码质量。</role>
|
||||
|
|
|
|||
|
|
@ -19,7 +19,9 @@ import { createRequire } from 'module'
|
|||
function getVersion(): string {
|
||||
try {
|
||||
if (typeof MACRO !== 'undefined' && MACRO.VERSION) return MACRO.VERSION
|
||||
} catch { /* ignore */ }
|
||||
} catch {
|
||||
/* ignore */
|
||||
}
|
||||
try {
|
||||
const require = createRequire(import.meta.url)
|
||||
// eslint-disable-next-line @typescript-eslint/no-require-imports
|
||||
|
|
@ -41,8 +43,11 @@ const VERSION = getVersion()
|
|||
* 3. 注入 Authorization 和 CoStrict 特有 headers
|
||||
* 4. 反应性 401 错误恢复(自动重试一次)
|
||||
*/
|
||||
export function createCoStrictFetch(): typeof fetch {
|
||||
return async (input: RequestInfo | URL, init?: RequestInit) => {
|
||||
export function createCoStrictFetch() {
|
||||
const costrictFetch = async (
|
||||
input: RequestInfo | URL,
|
||||
init?: RequestInit,
|
||||
) => {
|
||||
// ========== 步骤 1: 动态读取凭证 ==========
|
||||
let creds = await loadCoStrictCredentials()
|
||||
|
||||
|
|
@ -119,4 +124,6 @@ export function createCoStrictFetch(): typeof fetch {
|
|||
|
||||
return response
|
||||
}
|
||||
costrictFetch.preconnect = fetch.preconnect.bind(fetch)
|
||||
return costrictFetch
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
import type { BetaToolUnion } from '@anthropic-ai/sdk/resources/beta/messages/messages.mjs'
|
||||
import type { SDKAssistantMessageError } from '../../entrypoints/agentSdkTypes.js'
|
||||
import type { SystemPrompt } from '../../utils/systemPromptType.js'
|
||||
import type {
|
||||
Message,
|
||||
|
|
@ -46,7 +47,10 @@ export async function* queryModelCoStrict(
|
|||
tools: Tools,
|
||||
signal: AbortSignal,
|
||||
options: Options,
|
||||
): AsyncGenerator<StreamEvent | AssistantMessage | SystemAPIErrorMessage, void> {
|
||||
): AsyncGenerator<
|
||||
StreamEvent | AssistantMessage | SystemAPIErrorMessage,
|
||||
void
|
||||
> {
|
||||
try {
|
||||
// 1. 解析模型名
|
||||
const costrictModel = resolveCoStrictModel(options.model)
|
||||
|
|
@ -73,7 +77,7 @@ export async function* queryModelCoStrict(
|
|||
)
|
||||
const standardTools = toolSchemas.filter(
|
||||
(t): t is BetaToolUnion & { type: string } => {
|
||||
const anyT = t as Record<string, unknown>
|
||||
const anyT = t as unknown as Record<string, unknown>
|
||||
return (
|
||||
anyT.type !== 'advisor_20260301' && anyT.type !== 'computer_20250124'
|
||||
)
|
||||
|
|
@ -81,7 +85,11 @@ export async function* queryModelCoStrict(
|
|||
)
|
||||
|
||||
// 5. 转换为 OpenAI 格式
|
||||
const openaiMessages = anthropicMessagesToOpenAI(messagesForAPI, systemPrompt, { enableThinking: true })
|
||||
const openaiMessages = anthropicMessagesToOpenAI(
|
||||
messagesForAPI,
|
||||
systemPrompt,
|
||||
{ enableThinking: true },
|
||||
)
|
||||
const openaiTools = anthropicToolsToOpenAI(standardTools)
|
||||
const openaiToolChoice = anthropicToolChoiceToOpenAI(options.toolChoice)
|
||||
|
||||
|
|
@ -93,7 +101,9 @@ export async function* queryModelCoStrict(
|
|||
maxRetries: 0,
|
||||
timeout: parseInt(process.env.API_TIMEOUT_MS || String(600 * 1000), 10),
|
||||
dangerouslyAllowBrowser: true,
|
||||
fetchOptions: getProxyFetchOptions({ forAnthropicAPI: false }) as RequestInit,
|
||||
fetchOptions: getProxyFetchOptions({
|
||||
forAnthropicAPI: false,
|
||||
}) as any,
|
||||
fetch: costrictFetch as any,
|
||||
})
|
||||
|
||||
|
|
@ -108,7 +118,10 @@ export async function* queryModelCoStrict(
|
|||
messages: openaiMessages,
|
||||
...(openaiTools.length > 0 && {
|
||||
tools: openaiTools,
|
||||
...(openaiToolChoice && { tool_choice: openaiToolChoice }),
|
||||
...(openaiToolChoice && {
|
||||
tool_choice:
|
||||
openaiToolChoice as OpenAI.Chat.Completions.ChatCompletionToolChoiceOption,
|
||||
}),
|
||||
}),
|
||||
stream: true,
|
||||
stream_options: { include_usage: true },
|
||||
|
|
@ -123,7 +136,7 @@ export async function* queryModelCoStrict(
|
|||
const adaptedStream = adaptOpenAIStreamToAnthropic(stream, costrictModel)
|
||||
|
||||
const contentBlocks: Record<number, any> = {}
|
||||
let partialMessage: any = undefined
|
||||
let partialMessage: any
|
||||
let usage = {
|
||||
input_tokens: 0,
|
||||
output_tokens: 0,
|
||||
|
|
@ -139,7 +152,7 @@ export async function* queryModelCoStrict(
|
|||
partialMessage = (event as any).message
|
||||
ttftMs = Date.now() - start
|
||||
if ((event as any).message?.usage) {
|
||||
usage = { ...usage, ...((event as any).message.usage) }
|
||||
usage = { ...usage, ...(event as any).message.usage }
|
||||
}
|
||||
break
|
||||
}
|
||||
|
|
@ -219,7 +232,10 @@ export async function* queryModelCoStrict(
|
|||
yield createAssistantAPIErrorMessage({
|
||||
content: `CoStrict API Error: ${errorMsg}`,
|
||||
apiError: 'api_error',
|
||||
error: error instanceof Error ? error : new Error(String(error)),
|
||||
error:
|
||||
error instanceof Error
|
||||
? (error as unknown as SDKAssistantMessageError)
|
||||
: undefined,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { registerBundledSkill } from '../../skills/bundledSkills.js'
|
||||
import { registerBundledSkill } from 'src/skills/bundledSkills.js'
|
||||
import { BUNDLED_SKILLS } from './builtin.js'
|
||||
|
||||
export function registerCodeReviewSecuritySkill(): void {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { getProjectRoot } from '../../bootstrap/state.js'
|
||||
import { registerBundledSkill } from '../../skills/bundledSkills.js'
|
||||
import { registerBundledSkill } from 'src/skills/bundledSkills.js'
|
||||
|
||||
// Orchestrator prompt for the /project-wiki skill.
|
||||
// Uses `Agent` tool (CSC equivalent of opencode's `task` tool) to delegate
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { registerBundledSkill } from '../../skills/bundledSkills.js'
|
||||
import { registerBundledSkill } from 'src/skills/bundledSkills.js'
|
||||
|
||||
export function registerStrictPlanSkill(): void {
|
||||
registerBundledSkill({
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { registerBundledSkill } from '../../skills/bundledSkills.js'
|
||||
import { registerBundledSkill } from 'src/skills/bundledSkills.js'
|
||||
|
||||
const TDD_PROMPT = `You are executing a comprehensive testing workflow to ensure code quality.
|
||||
|
||||
|
|
|
|||
|
|
@ -27,6 +27,8 @@ import { getModelBetas, modelSupportsStructuredOutputs } from './betas.js'
|
|||
import { computeFingerprint } from './fingerprint.js'
|
||||
import { normalizeModelStringForAPI } from './model/model.js'
|
||||
import { getAPIProvider } from './model/providers.js'
|
||||
import { asSystemPrompt } from './systemPromptType.js'
|
||||
import type { UserMessage, AssistantMessage } from '../types/message.js'
|
||||
|
||||
type MessageParam = Anthropic.MessageParam
|
||||
type TextBlockParam = Anthropic.TextBlockParam
|
||||
|
|
@ -257,7 +259,9 @@ async function sideQueryCoStrict(opts: SideQueryOptions): Promise<BetaMessage> {
|
|||
|
||||
// Build system prompt
|
||||
const systemContent = skipSystemPromptPrefix
|
||||
? (typeof system === 'string' ? system : '')
|
||||
? typeof system === 'string'
|
||||
? system
|
||||
: ''
|
||||
: `${getCLISyspromptPrefix({ isNonInteractive: false, hasAppendSystemPrompt: false })}
|
||||
${typeof system === 'string' ? system : ''}`
|
||||
|
||||
|
|
@ -275,18 +279,15 @@ ${typeof system === 'string' ? system : ''}`
|
|||
maxRetries: 0,
|
||||
timeout: parseInt(process.env.API_TIMEOUT_MS || String(600 * 1000), 10),
|
||||
dangerouslyAllowBrowser: true,
|
||||
fetchOptions: getProxyFetchOptions({ forAnthropicAPI: false }) as RequestInit,
|
||||
fetchOptions: getProxyFetchOptions({ forAnthropicAPI: false }) as any,
|
||||
fetch: costrictFetch as any,
|
||||
})
|
||||
|
||||
// Convert messages to OpenAI format
|
||||
const openaiMessages = anthropicMessagesToOpenAI(
|
||||
messages.map(m => ({
|
||||
...m,
|
||||
content: typeof m.content === 'string' ? m.content : m.content,
|
||||
})),
|
||||
systemContent,
|
||||
{ enableThinking: false }
|
||||
messages as unknown as (UserMessage | AssistantMessage)[],
|
||||
asSystemPrompt([systemContent]),
|
||||
{ enableThinking: false },
|
||||
)
|
||||
|
||||
// Build request
|
||||
|
|
@ -299,7 +300,7 @@ ${typeof system === 'string' ? system : ''}`
|
|||
|
||||
// Add response_format for JSON schema if specified
|
||||
if (output_format?.type === 'json_schema') {
|
||||
(requestBody as any).response_format = {
|
||||
;(requestBody as any).response_format = {
|
||||
type: 'json_schema',
|
||||
json_schema: {
|
||||
name: 'response',
|
||||
|
|
@ -333,15 +334,19 @@ ${typeof system === 'string' ? system : ''}`
|
|||
const now = Date.now()
|
||||
const lastCompletion = getLastApiCompletionTimestamp()
|
||||
logEvent('tengu_api_success', {
|
||||
requestId: response.id as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
querySource: opts.querySource as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
model: costrictModel as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
requestId:
|
||||
response.id as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
querySource:
|
||||
opts.querySource as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
model:
|
||||
costrictModel as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
inputTokens: response.usage?.prompt_tokens || 0,
|
||||
outputTokens: response.usage?.completion_tokens || 0,
|
||||
cachedInputTokens: 0,
|
||||
uncachedInputTokens: 0,
|
||||
durationMsIncludingRetries: now - start,
|
||||
timeSinceLastApiCallMs: lastCompletion !== null ? now - lastCompletion : undefined,
|
||||
timeSinceLastApiCallMs:
|
||||
lastCompletion !== null ? now - lastCompletion : undefined,
|
||||
})
|
||||
setLastApiCompletionTimestamp(now)
|
||||
|
||||
|
|
@ -365,7 +370,9 @@ async function sideQueryOpenAI(opts: SideQueryOptions): Promise<BetaMessage> {
|
|||
|
||||
// Build system prompt
|
||||
const systemContent = skipSystemPromptPrefix
|
||||
? (typeof system === 'string' ? system : '')
|
||||
? typeof system === 'string'
|
||||
? system
|
||||
: ''
|
||||
: `${getCLISyspromptPrefix({ isNonInteractive: false, hasAppendSystemPrompt: false })}
|
||||
${typeof system === 'string' ? system : ''}`
|
||||
|
||||
|
|
@ -377,12 +384,9 @@ ${typeof system === 'string' ? system : ''}`
|
|||
|
||||
// Convert messages to OpenAI format
|
||||
const openaiMessages = anthropicMessagesToOpenAI(
|
||||
messages.map(m => ({
|
||||
...m,
|
||||
content: typeof m.content === 'string' ? m.content : m.content,
|
||||
})),
|
||||
systemContent,
|
||||
{ enableThinking: false }
|
||||
messages as unknown as (UserMessage | AssistantMessage)[],
|
||||
asSystemPrompt([systemContent]),
|
||||
{ enableThinking: false },
|
||||
)
|
||||
|
||||
// Build request
|
||||
|
|
@ -395,7 +399,7 @@ ${typeof system === 'string' ? system : ''}`
|
|||
|
||||
// Add response_format for JSON schema if specified
|
||||
if (output_format?.type === 'json_schema') {
|
||||
(requestBody as any).response_format = {
|
||||
;(requestBody as any).response_format = {
|
||||
type: 'json_schema',
|
||||
json_schema: {
|
||||
name: 'response',
|
||||
|
|
@ -429,15 +433,19 @@ ${typeof system === 'string' ? system : ''}`
|
|||
const now = Date.now()
|
||||
const lastCompletion = getLastApiCompletionTimestamp()
|
||||
logEvent('tengu_api_success', {
|
||||
requestId: response.id as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
querySource: opts.querySource as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
model: openaiModel as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
requestId:
|
||||
response.id as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
querySource:
|
||||
opts.querySource as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
model:
|
||||
openaiModel as AnalyticsMetadata_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS,
|
||||
inputTokens: response.usage?.prompt_tokens || 0,
|
||||
outputTokens: response.usage?.completion_tokens || 0,
|
||||
cachedInputTokens: 0,
|
||||
uncachedInputTokens: 0,
|
||||
durationMsIncludingRetries: now - start,
|
||||
timeSinceLastApiCallMs: lastCompletion !== null ? now - lastCompletion : undefined,
|
||||
timeSinceLastApiCallMs:
|
||||
lastCompletion !== null ? now - lastCompletion : undefined,
|
||||
})
|
||||
setLastApiCompletionTimestamp(now)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,69 +1,46 @@
|
|||
import chalk from 'chalk'
|
||||
import figures from 'figures'
|
||||
import * as React from 'react'
|
||||
import { color, Text } from '@anthropic/ink'
|
||||
import type { MCPServerConnection } from '../services/mcp/types.js'
|
||||
import { getAccountInformation, isClaudeAISubscriber } from './auth.js'
|
||||
import {
|
||||
getLargeMemoryFiles,
|
||||
getMemoryFiles,
|
||||
MAX_MEMORY_CHARACTER_COUNT,
|
||||
} from './claudemd.js'
|
||||
import { getDoctorDiagnostic } from './doctorDiagnostic.js'
|
||||
import {
|
||||
getAWSRegion,
|
||||
getDefaultVertexRegion,
|
||||
isEnvTruthy,
|
||||
} from './envUtils.js'
|
||||
import { getDisplayPath } from './file.js'
|
||||
import { formatNumber } from './format.js'
|
||||
import {
|
||||
getIdeClientName,
|
||||
type IDEExtensionInstallationStatus,
|
||||
isJetBrainsIde,
|
||||
toIDEDisplayName,
|
||||
} from './ide.js'
|
||||
import {
|
||||
getClaudeAiUserDefaultModelDescription,
|
||||
modelDisplayString,
|
||||
} from './model/model.js'
|
||||
import { getAPIProvider } from './model/providers.js'
|
||||
import { getMTLSConfig } from './mtls.js'
|
||||
import { checkInstall } from './nativeInstaller/index.js'
|
||||
import { getProxyUrl } from './proxy.js'
|
||||
import { SandboxManager } from './sandbox/sandbox-adapter.js'
|
||||
import { getSettingsWithAllErrors } from './settings/allErrors.js'
|
||||
import {
|
||||
getEnabledSettingSources,
|
||||
getSettingSourceDisplayNameCapitalized,
|
||||
} from './settings/constants.js'
|
||||
import {
|
||||
getManagedFileSettingsPresence,
|
||||
getPolicySettingsOrigin,
|
||||
getSettingsForSource,
|
||||
} from './settings/settings.js'
|
||||
import type { ThemeName } from './theme.js'
|
||||
import chalk from 'chalk';
|
||||
import figures from 'figures';
|
||||
import * as React from 'react';
|
||||
import { color, Text } from '@anthropic/ink';
|
||||
import type { MCPServerConnection } from '../services/mcp/types.js';
|
||||
import { getAccountInformation, isClaudeAISubscriber } from './auth.js';
|
||||
import { getLargeMemoryFiles, getMemoryFiles, MAX_MEMORY_CHARACTER_COUNT } from './claudemd.js';
|
||||
import { getDoctorDiagnostic } from './doctorDiagnostic.js';
|
||||
import { getAWSRegion, getDefaultVertexRegion, isEnvTruthy } from './envUtils.js';
|
||||
import { getDisplayPath } from './file.js';
|
||||
import { formatNumber } from './format.js';
|
||||
import { getIdeClientName, type IDEExtensionInstallationStatus, isJetBrainsIde, toIDEDisplayName } from './ide.js';
|
||||
import { getClaudeAiUserDefaultModelDescription, modelDisplayString } from './model/model.js';
|
||||
import { getAPIProvider } from './model/providers.js';
|
||||
import { getMTLSConfig } from './mtls.js';
|
||||
import { checkInstall } from './nativeInstaller/index.js';
|
||||
import { getProxyUrl } from './proxy.js';
|
||||
import { SandboxManager } from './sandbox/sandbox-adapter.js';
|
||||
import { getSettingsWithAllErrors } from './settings/allErrors.js';
|
||||
import { getEnabledSettingSources, getSettingSourceDisplayNameCapitalized } from './settings/constants.js';
|
||||
import { getManagedFileSettingsPresence, getPolicySettingsOrigin, getSettingsForSource } from './settings/settings.js';
|
||||
import type { ThemeName } from './theme.js';
|
||||
|
||||
export type Property = {
|
||||
label?: string
|
||||
value: React.ReactNode | Array<string>
|
||||
}
|
||||
label?: string;
|
||||
value: React.ReactNode | Array<string>;
|
||||
};
|
||||
|
||||
export type Diagnostic = React.ReactNode
|
||||
export type Diagnostic = React.ReactNode;
|
||||
|
||||
export function buildSandboxProperties(): Property[] {
|
||||
if (process.env.USER_TYPE !== 'ant') {
|
||||
return []
|
||||
return [];
|
||||
}
|
||||
|
||||
const isSandboxed = SandboxManager.isSandboxingEnabled()
|
||||
const isSandboxed = SandboxManager.isSandboxingEnabled();
|
||||
|
||||
return [
|
||||
{
|
||||
label: 'Bash Sandbox',
|
||||
value: isSandboxed ? 'Enabled' : 'Disabled',
|
||||
},
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
export function buildIDEProperties(
|
||||
|
|
@ -71,13 +48,11 @@ export function buildIDEProperties(
|
|||
ideInstallationStatus: IDEExtensionInstallationStatus | null = null,
|
||||
theme: ThemeName,
|
||||
): Property[] {
|
||||
const ideClient = mcpClients?.find(client => client.name === 'ide')
|
||||
const ideClient = mcpClients?.find(client => client.name === 'ide');
|
||||
|
||||
if (ideInstallationStatus) {
|
||||
const ideName = toIDEDisplayName(ideInstallationStatus.ideType)
|
||||
const pluginOrExtension = isJetBrainsIde(ideInstallationStatus.ideType)
|
||||
? 'plugin'
|
||||
: 'extension'
|
||||
const ideName = toIDEDisplayName(ideInstallationStatus.ideType);
|
||||
const pluginOrExtension = isJetBrainsIde(ideInstallationStatus.ideType) ? 'plugin' : 'extension';
|
||||
|
||||
if (ideInstallationStatus.error) {
|
||||
return [
|
||||
|
|
@ -85,34 +60,31 @@ export function buildIDEProperties(
|
|||
label: 'IDE',
|
||||
value: (
|
||||
<Text>
|
||||
{color('error', theme)(figures.cross)} Error installing {ideName}{' '}
|
||||
{pluginOrExtension}: {ideInstallationStatus.error}
|
||||
{color('error', theme)(figures.cross)} Error installing {ideName} {pluginOrExtension}:{' '}
|
||||
{ideInstallationStatus.error}
|
||||
{'\n'}Please restart your IDE and try again.
|
||||
</Text>
|
||||
),
|
||||
},
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
if (ideInstallationStatus.installed) {
|
||||
if (ideClient && ideClient.type === 'connected') {
|
||||
if (
|
||||
ideInstallationStatus.installedVersion !==
|
||||
ideClient.serverInfo?.version
|
||||
) {
|
||||
if (ideInstallationStatus.installedVersion !== ideClient.serverInfo?.version) {
|
||||
return [
|
||||
{
|
||||
label: 'IDE',
|
||||
value: `Connected to ${ideName} ${pluginOrExtension} version ${ideInstallationStatus.installedVersion} (server version: ${ideClient.serverInfo?.version})`,
|
||||
},
|
||||
]
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
{
|
||||
label: 'IDE',
|
||||
value: `Connected to ${ideName} ${pluginOrExtension} version ${ideInstallationStatus.installedVersion}`,
|
||||
},
|
||||
]
|
||||
];
|
||||
}
|
||||
} else {
|
||||
return [
|
||||
|
|
@ -120,196 +92,183 @@ export function buildIDEProperties(
|
|||
label: 'IDE',
|
||||
value: `Installed ${ideName} ${pluginOrExtension}`,
|
||||
},
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
} else if (ideClient) {
|
||||
const ideName = getIdeClientName(ideClient) ?? 'IDE'
|
||||
const ideName = getIdeClientName(ideClient) ?? 'IDE';
|
||||
if (ideClient.type === 'connected') {
|
||||
return [
|
||||
{
|
||||
label: 'IDE',
|
||||
value: `Connected to ${ideName} extension`,
|
||||
},
|
||||
]
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
{
|
||||
label: 'IDE',
|
||||
value: `${color('error', theme)(figures.cross)} Not connected to ${ideName}`,
|
||||
},
|
||||
]
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
return []
|
||||
return [];
|
||||
}
|
||||
|
||||
export function buildMcpProperties(
|
||||
clients: MCPServerConnection[] = [],
|
||||
theme: ThemeName,
|
||||
): Property[] {
|
||||
const servers = clients.filter(client => client.name !== 'ide')
|
||||
export function buildMcpProperties(clients: MCPServerConnection[] = [], theme: ThemeName): Property[] {
|
||||
const servers = clients.filter(client => client.name !== 'ide');
|
||||
if (!servers.length) {
|
||||
return []
|
||||
return [];
|
||||
}
|
||||
|
||||
// Summary instead of a full server list — 20+ servers wrapped onto many
|
||||
// rows, dominating the Status pane. Show counts by state + /mcp hint.
|
||||
const byState = { connected: 0, pending: 0, needsAuth: 0, failed: 0 }
|
||||
const byState = { connected: 0, pending: 0, needsAuth: 0, failed: 0 };
|
||||
for (const s of servers) {
|
||||
if (s.type === 'connected') byState.connected++
|
||||
else if (s.type === 'pending') byState.pending++
|
||||
else if (s.type === 'needs-auth') byState.needsAuth++
|
||||
else byState.failed++
|
||||
if (s.type === 'connected') byState.connected++;
|
||||
else if (s.type === 'pending') byState.pending++;
|
||||
else if (s.type === 'needs-auth') byState.needsAuth++;
|
||||
else byState.failed++;
|
||||
}
|
||||
const parts: string[] = []
|
||||
if (byState.connected)
|
||||
parts.push(color('success', theme)(`${byState.connected} connected`))
|
||||
if (byState.needsAuth)
|
||||
parts.push(color('warning', theme)(`${byState.needsAuth} need auth`))
|
||||
if (byState.pending)
|
||||
parts.push(color('inactive', theme)(`${byState.pending} pending`))
|
||||
if (byState.failed)
|
||||
parts.push(color('error', theme)(`${byState.failed} failed`))
|
||||
const parts: string[] = [];
|
||||
if (byState.connected) parts.push(color('success', theme)(`${byState.connected} connected`));
|
||||
if (byState.needsAuth) parts.push(color('warning', theme)(`${byState.needsAuth} need auth`));
|
||||
if (byState.pending) parts.push(color('inactive', theme)(`${byState.pending} pending`));
|
||||
if (byState.failed) parts.push(color('error', theme)(`${byState.failed} failed`));
|
||||
|
||||
return [
|
||||
{
|
||||
label: 'MCP servers',
|
||||
value: `${parts.join(', ')} ${color('inactive', theme)('· /mcp')}`,
|
||||
},
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
export async function buildMemoryDiagnostics(): Promise<Diagnostic[]> {
|
||||
const files = await getMemoryFiles()
|
||||
const largeFiles = getLargeMemoryFiles(files)
|
||||
const files = await getMemoryFiles();
|
||||
const largeFiles = getLargeMemoryFiles(files);
|
||||
|
||||
const diagnostics: Diagnostic[] = []
|
||||
const diagnostics: Diagnostic[] = [];
|
||||
|
||||
largeFiles.forEach(file => {
|
||||
const displayPath = getDisplayPath(file.path)
|
||||
const displayPath = getDisplayPath(file.path);
|
||||
diagnostics.push(
|
||||
`Large ${displayPath} will impact performance (${formatNumber(file.content.length)} chars > ${formatNumber(MAX_MEMORY_CHARACTER_COUNT)})`,
|
||||
)
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
return diagnostics
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
export function buildSettingSourcesProperties(): Property[] {
|
||||
const enabledSources = getEnabledSettingSources()
|
||||
const enabledSources = getEnabledSettingSources();
|
||||
|
||||
// Filter to only sources that actually have settings loaded
|
||||
const sourcesWithSettings = enabledSources.filter(source => {
|
||||
const settings = getSettingsForSource(source)
|
||||
return settings !== null && Object.keys(settings).length > 0
|
||||
})
|
||||
const settings = getSettingsForSource(source);
|
||||
return settings !== null && Object.keys(settings).length > 0;
|
||||
});
|
||||
|
||||
// Map internal names to user-friendly names
|
||||
// For policySettings, distinguish between remote and local (or skip if neither exists)
|
||||
const sourceNames = sourcesWithSettings
|
||||
.map(source => {
|
||||
if (source === 'policySettings') {
|
||||
const origin = getPolicySettingsOrigin()
|
||||
const origin = getPolicySettingsOrigin();
|
||||
if (origin === null) {
|
||||
return null // Skip - no policy settings exist
|
||||
return null; // Skip - no policy settings exist
|
||||
}
|
||||
switch (origin) {
|
||||
case 'remote':
|
||||
return 'Enterprise managed settings (remote)'
|
||||
return 'Enterprise managed settings (remote)';
|
||||
case 'plist':
|
||||
return 'Enterprise managed settings (plist)'
|
||||
return 'Enterprise managed settings (plist)';
|
||||
case 'hklm':
|
||||
return 'Enterprise managed settings (HKLM)'
|
||||
return 'Enterprise managed settings (HKLM)';
|
||||
case 'file': {
|
||||
const { hasBase, hasDropIns } = getManagedFileSettingsPresence()
|
||||
const { hasBase, hasDropIns } = getManagedFileSettingsPresence();
|
||||
if (hasBase && hasDropIns) {
|
||||
return 'Enterprise managed settings (file + drop-ins)'
|
||||
return 'Enterprise managed settings (file + drop-ins)';
|
||||
}
|
||||
if (hasDropIns) {
|
||||
return 'Enterprise managed settings (drop-ins)'
|
||||
return 'Enterprise managed settings (drop-ins)';
|
||||
}
|
||||
return 'Enterprise managed settings (file)'
|
||||
return 'Enterprise managed settings (file)';
|
||||
}
|
||||
case 'hkcu':
|
||||
return 'Enterprise managed settings (HKCU)'
|
||||
return 'Enterprise managed settings (HKCU)';
|
||||
}
|
||||
}
|
||||
return getSettingSourceDisplayNameCapitalized(source)
|
||||
return getSettingSourceDisplayNameCapitalized(source);
|
||||
})
|
||||
.filter((name): name is string => name !== null)
|
||||
.filter((name): name is string => name !== null);
|
||||
|
||||
return [
|
||||
{
|
||||
label: 'Setting sources',
|
||||
value: sourceNames,
|
||||
},
|
||||
]
|
||||
];
|
||||
}
|
||||
|
||||
export async function buildInstallationDiagnostics(): Promise<Diagnostic[]> {
|
||||
const installWarnings = await checkInstall()
|
||||
return installWarnings.map(warning => warning.message)
|
||||
const installWarnings = await checkInstall();
|
||||
return installWarnings.map(warning => warning.message);
|
||||
}
|
||||
|
||||
export async function buildInstallationHealthDiagnostics(): Promise<
|
||||
Diagnostic[]
|
||||
> {
|
||||
const diagnostic = await getDoctorDiagnostic()
|
||||
const items: Diagnostic[] = []
|
||||
export async function buildInstallationHealthDiagnostics(): Promise<Diagnostic[]> {
|
||||
const diagnostic = await getDoctorDiagnostic();
|
||||
const items: Diagnostic[] = [];
|
||||
|
||||
const { errors: validationErrors } = getSettingsWithAllErrors()
|
||||
const { errors: validationErrors } = getSettingsWithAllErrors();
|
||||
if (validationErrors.length > 0) {
|
||||
const invalidFiles = Array.from(
|
||||
new Set(validationErrors.map(error => error.file)),
|
||||
)
|
||||
const fileList = invalidFiles.join(', ')
|
||||
const invalidFiles = Array.from(new Set(validationErrors.map(error => error.file)));
|
||||
const fileList = invalidFiles.join(', ');
|
||||
|
||||
items.push(
|
||||
`Found invalid settings files: ${fileList}. They will be ignored.`,
|
||||
)
|
||||
items.push(`Found invalid settings files: ${fileList}. They will be ignored.`);
|
||||
}
|
||||
|
||||
// Add warnings from doctor diagnostic (includes leftover installations, config mismatches, etc.)
|
||||
diagnostic.warnings.forEach(warning => {
|
||||
items.push(warning.issue)
|
||||
})
|
||||
items.push(warning.issue);
|
||||
});
|
||||
|
||||
if (diagnostic.hasUpdatePermissions === false) {
|
||||
items.push('No write permissions for auto-updates (requires sudo)')
|
||||
items.push('No write permissions for auto-updates (requires sudo)');
|
||||
}
|
||||
|
||||
return items
|
||||
return items;
|
||||
}
|
||||
|
||||
export function buildAccountProperties(): Property[] {
|
||||
const accountInfo = getAccountInformation()
|
||||
const accountInfo = getAccountInformation();
|
||||
if (!accountInfo) {
|
||||
return []
|
||||
return [];
|
||||
}
|
||||
|
||||
const properties: Property[] = []
|
||||
const properties: Property[] = [];
|
||||
|
||||
if (accountInfo.subscription) {
|
||||
properties.push({
|
||||
label: 'Login method',
|
||||
value: `${accountInfo.subscription} Account`,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
if (accountInfo.tokenSource) {
|
||||
properties.push({
|
||||
label: 'Auth token',
|
||||
value: accountInfo.tokenSource,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
if (accountInfo.apiKeySource) {
|
||||
properties.push({
|
||||
label: 'API key',
|
||||
value: accountInfo.apiKeySource,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
// Hide sensitive account info in demo mode
|
||||
|
|
@ -317,22 +276,22 @@ export function buildAccountProperties(): Property[] {
|
|||
properties.push({
|
||||
label: 'Organization',
|
||||
value: accountInfo.organization,
|
||||
})
|
||||
});
|
||||
}
|
||||
if (accountInfo.email && !process.env.IS_DEMO) {
|
||||
properties.push({
|
||||
label: 'Email',
|
||||
value: accountInfo.email,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
return properties
|
||||
return properties;
|
||||
}
|
||||
|
||||
export function buildAPIProviderProperties(): Property[] {
|
||||
const apiProvider = getAPIProvider()
|
||||
const apiProvider = getAPIProvider();
|
||||
|
||||
const properties: Property[] = []
|
||||
const properties: Property[] = [];
|
||||
|
||||
if (apiProvider !== 'firstParty') {
|
||||
const providerLabel = {
|
||||
|
|
@ -342,152 +301,152 @@ export function buildAPIProviderProperties(): Property[] {
|
|||
gemini: 'Gemini API',
|
||||
grok: 'Grok API',
|
||||
openai: 'OpenAI API',
|
||||
}[apiProvider]
|
||||
costrict: 'CoStrict API',
|
||||
}[apiProvider];
|
||||
properties.push({
|
||||
label: 'API provider',
|
||||
value: providerLabel,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
if (apiProvider === 'firstParty') {
|
||||
const anthropicBaseUrl = process.env.ANTHROPIC_BASE_URL
|
||||
const anthropicBaseUrl = process.env.ANTHROPIC_BASE_URL;
|
||||
if (anthropicBaseUrl) {
|
||||
properties.push({
|
||||
label: 'Anthropic base URL',
|
||||
value: anthropicBaseUrl,
|
||||
})
|
||||
});
|
||||
}
|
||||
} else if (apiProvider === 'bedrock') {
|
||||
const bedrockBaseUrl = process.env.BEDROCK_BASE_URL
|
||||
const bedrockBaseUrl = process.env.BEDROCK_BASE_URL;
|
||||
if (bedrockBaseUrl) {
|
||||
properties.push({
|
||||
label: 'Bedrock base URL',
|
||||
value: bedrockBaseUrl,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
properties.push({
|
||||
label: 'AWS region',
|
||||
value: getAWSRegion(),
|
||||
})
|
||||
});
|
||||
|
||||
if (isEnvTruthy(process.env.CLAUDE_CODE_SKIP_BEDROCK_AUTH)) {
|
||||
properties.push({
|
||||
value: 'AWS auth skipped',
|
||||
})
|
||||
});
|
||||
}
|
||||
} else if (apiProvider === 'vertex') {
|
||||
const vertexBaseUrl = process.env.VERTEX_BASE_URL
|
||||
const vertexBaseUrl = process.env.VERTEX_BASE_URL;
|
||||
if (vertexBaseUrl) {
|
||||
properties.push({
|
||||
label: 'Vertex base URL',
|
||||
value: vertexBaseUrl,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
const gcpProject = process.env.ANTHROPIC_VERTEX_PROJECT_ID
|
||||
const gcpProject = process.env.ANTHROPIC_VERTEX_PROJECT_ID;
|
||||
if (gcpProject) {
|
||||
properties.push({
|
||||
label: 'GCP project',
|
||||
value: gcpProject,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
properties.push({
|
||||
label: 'Default region',
|
||||
value: getDefaultVertexRegion(),
|
||||
})
|
||||
});
|
||||
|
||||
if (isEnvTruthy(process.env.CLAUDE_CODE_SKIP_VERTEX_AUTH)) {
|
||||
properties.push({
|
||||
value: 'GCP auth skipped',
|
||||
})
|
||||
});
|
||||
}
|
||||
} else if (apiProvider === 'foundry') {
|
||||
const foundryBaseUrl = process.env.ANTHROPIC_FOUNDRY_BASE_URL
|
||||
const foundryBaseUrl = process.env.ANTHROPIC_FOUNDRY_BASE_URL;
|
||||
if (foundryBaseUrl) {
|
||||
properties.push({
|
||||
label: 'Microsoft Foundry base URL',
|
||||
value: foundryBaseUrl,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
const foundryResource = process.env.ANTHROPIC_FOUNDRY_RESOURCE
|
||||
const foundryResource = process.env.ANTHROPIC_FOUNDRY_RESOURCE;
|
||||
if (foundryResource) {
|
||||
properties.push({
|
||||
label: 'Microsoft Foundry resource',
|
||||
value: foundryResource,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
if (isEnvTruthy(process.env.CLAUDE_CODE_SKIP_FOUNDRY_AUTH)) {
|
||||
properties.push({
|
||||
value: 'Microsoft Foundry auth skipped',
|
||||
})
|
||||
});
|
||||
}
|
||||
} else if (apiProvider === 'gemini') {
|
||||
const geminiBaseUrl =
|
||||
process.env.GEMINI_BASE_URL || 'https://generativelanguage.googleapis.com/v1beta'
|
||||
const geminiBaseUrl = process.env.GEMINI_BASE_URL || 'https://generativelanguage.googleapis.com/v1beta';
|
||||
properties.push({
|
||||
label: 'Gemini base URL',
|
||||
value: geminiBaseUrl,
|
||||
})
|
||||
});
|
||||
} else if (apiProvider === 'grok') {
|
||||
const grokBaseUrl = process.env.GROK_BASE_URL
|
||||
const grokBaseUrl = process.env.GROK_BASE_URL;
|
||||
properties.push({
|
||||
label: 'Grok base URL',
|
||||
value: grokBaseUrl,
|
||||
})
|
||||
});
|
||||
} else if (apiProvider === 'openai') {
|
||||
const openaiBaseUrl = process.env.OPENAI_BASE_URL
|
||||
const openaiBaseUrl = process.env.OPENAI_BASE_URL;
|
||||
properties.push({
|
||||
label: 'OpenAI base URL',
|
||||
value: openaiBaseUrl,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
const proxyUrl = getProxyUrl()
|
||||
const proxyUrl = getProxyUrl();
|
||||
if (proxyUrl) {
|
||||
properties.push({
|
||||
label: 'Proxy',
|
||||
value: proxyUrl,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
const mtlsConfig = getMTLSConfig()
|
||||
const mtlsConfig = getMTLSConfig();
|
||||
if (process.env.NODE_EXTRA_CA_CERTS) {
|
||||
properties.push({
|
||||
label: 'Additional CA cert(s)',
|
||||
value: process.env.NODE_EXTRA_CA_CERTS,
|
||||
})
|
||||
});
|
||||
}
|
||||
if (mtlsConfig) {
|
||||
if (mtlsConfig.cert && process.env.CLAUDE_CODE_CLIENT_CERT) {
|
||||
properties.push({
|
||||
label: 'mTLS client cert',
|
||||
value: process.env.CLAUDE_CODE_CLIENT_CERT,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
if (mtlsConfig.key && process.env.CLAUDE_CODE_CLIENT_KEY) {
|
||||
properties.push({
|
||||
label: 'mTLS client key',
|
||||
value: process.env.CLAUDE_CODE_CLIENT_KEY,
|
||||
})
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return properties
|
||||
return properties;
|
||||
}
|
||||
|
||||
export function getModelDisplayLabel(mainLoopModel: string | null): string {
|
||||
let modelLabel = modelDisplayString(mainLoopModel)
|
||||
let modelLabel = modelDisplayString(mainLoopModel);
|
||||
|
||||
if (mainLoopModel === null && isClaudeAISubscriber()) {
|
||||
const description = getClaudeAiUserDefaultModelDescription()
|
||||
const description = getClaudeAiUserDefaultModelDescription();
|
||||
|
||||
modelLabel = `${chalk.bold('Default')} ${description}`
|
||||
modelLabel = `${chalk.bold('Default')} ${description}`;
|
||||
}
|
||||
|
||||
return modelLabel
|
||||
return modelLabel;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user