From 88e2ce1e70c0da521944f3fd491997b6eef614c2 Mon Sep 17 00:00:00 2001 From: Ubuntu Date: Tue, 14 Apr 2026 14:19:27 +0000 Subject: [PATCH] =?UTF-8?q?refactor:=20=E9=87=8D=E6=9E=84=20provider?= =?UTF-8?q?=E3=80=81agents=E3=80=81status=20=E5=8F=8A=E7=9B=B8=E5=85=B3?= =?UTF-8?q?=E5=B7=A5=E5=85=B7=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 +- ...0375b005-04be-4064-90ad-ac7b5bdf56df.jsonl | 2 - package.json | 2 +- .../src/tools/AgentTool/builtInAgents.ts | 34 +- src/components/ConsoleOAuthFlow.tsx | 3 +- src/costrict/agents/designAgent.ts | 4 +- src/costrict/agents/quickExplore.ts | 12 +- src/costrict/agents/requirement.ts | 4 +- src/costrict/agents/strictPlan.ts | 4 +- src/costrict/agents/strictSpec.ts | 4 +- src/costrict/agents/subCoding.ts | 8 +- src/costrict/agents/taskCheck.ts | 8 +- src/costrict/agents/taskPlan.ts | 4 +- src/costrict/agents/tddRunAndFix.ts | 4 +- src/costrict/agents/tddTestAndFix.ts | 2 +- src/costrict/agents/tddTestDesign.ts | 4 +- src/costrict/agents/tddTestPrepare.ts | 6 +- src/costrict/agents/wikiCatalogueDesign.ts | 12 +- src/costrict/agents/wikiDocumentGenerate.ts | 12 +- src/costrict/agents/wikiIndexGeneration.ts | 12 +- src/costrict/agents/wikiProjectAnalyze.ts | 12 +- src/costrict/backup/planApply.ts | 6 +- src/costrict/backup/reviewAndFix.ts | 6 +- src/costrict/backup/specPlan.ts | 3 +- src/costrict/backup/strictPlan.ts | 4 +- src/costrict/backup/tdd.ts | 2 +- src/costrict/provider/fetch.ts | 13 +- src/costrict/provider/index.ts | 32 +- src/costrict/skill/codeReviewSecurity.ts | 2 +- src/costrict/skill/projectWiki.ts | 2 +- src/costrict/skill/strictPlan.ts | 2 +- src/costrict/skill/tdd.ts | 2 +- src/utils/sideQuery.ts | 58 ++-- src/utils/status.tsx | 325 ++++++++---------- 34 files changed, 301 insertions(+), 311 deletions(-) delete mode 100644 .omc/state/agent-replay-0375b005-04be-4064-90ad-ac7b5bdf56df.jsonl diff --git a/.gitignore b/.gitignore index 0debb4976..468dd0c70 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -#node_modules +node_modules .DS_Store dist coverage diff --git a/.omc/state/agent-replay-0375b005-04be-4064-90ad-ac7b5bdf56df.jsonl b/.omc/state/agent-replay-0375b005-04be-4064-90ad-ac7b5bdf56df.jsonl deleted file mode 100644 index 874852afc..000000000 --- a/.omc/state/agent-replay-0375b005-04be-4064-90ad-ac7b5bdf56df.jsonl +++ /dev/null @@ -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} diff --git a/package.json b/package.json index 3b8b20db7..5459d9014 100644 --- a/package.json +++ b/package.json @@ -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", diff --git a/packages/builtin-tools/src/tools/AgentTool/builtInAgents.ts b/packages/builtin-tools/src/tools/AgentTool/builtInAgents.ts index d3f4150bd..750e0d9a1 100644 --- a/packages/builtin-tools/src/tools/AgentTool/builtInAgents.ts +++ b/packages/builtin-tools/src/tools/AgentTool/builtInAgents.ts @@ -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' diff --git a/src/components/ConsoleOAuthFlow.tsx b/src/components/ConsoleOAuthFlow.tsx index 609d061c4..73ba8d0a5 100644 --- a/src/components/ConsoleOAuthFlow.tsx +++ b/src/components/ConsoleOAuthFlow.tsx @@ -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({ Opening browser for CoStrict login. If it does not open automatically, copy and paste this URL: - {oauthStatus.url} + {oauthStatus.url} Waiting for authentication... diff --git a/src/costrict/agents/designAgent.ts b/src/costrict/agents/designAgent.ts index 993739d02..9dc36e5e8 100644 --- a/src/costrict/agents/designAgent.ts +++ b/src/costrict/agents/designAgent.ts @@ -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,一名专业软件开发团队中的资深软件架构师。 diff --git a/src/costrict/agents/quickExplore.ts b/src/costrict/agents/quickExplore.ts index 7ed94ddf1..b25788a62 100644 --- a/src/costrict/agents/quickExplore.ts +++ b/src/costrict/agents/quickExplore.ts @@ -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 { diff --git a/src/costrict/agents/requirement.ts b/src/costrict/agents/requirement.ts index 518f453a0..d81d61ef2 100644 --- a/src/costrict/agents/requirement.ts +++ b/src/costrict/agents/requirement.ts @@ -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 `# 角色 diff --git a/src/costrict/agents/strictPlan.ts b/src/costrict/agents/strictPlan.ts index dbd4cf1cc..7ed8d6a65 100644 --- a/src/costrict/agents/strictPlan.ts +++ b/src/costrict/agents/strictPlan.ts @@ -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 { diff --git a/src/costrict/agents/strictSpec.ts b/src/costrict/agents/strictSpec.ts index f304df742..cb39956f3 100644 --- a/src/costrict/agents/strictSpec.ts +++ b/src/costrict/agents/strictSpec.ts @@ -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执行。 diff --git a/src/costrict/agents/subCoding.ts b/src/costrict/agents/subCoding.ts index 8c979788b..504ba2646 100644 --- a/src/costrict/agents/subCoding.ts +++ b/src/costrict/agents/subCoding.ts @@ -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,一名专业软件开发团队中的开发人员。 diff --git a/src/costrict/agents/taskCheck.ts b/src/costrict/agents/taskCheck.ts index 9af765f16..03e6943ed 100644 --- a/src/costrict/agents/taskCheck.ts +++ b/src/costrict/agents/taskCheck.ts @@ -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,一名专业的软件开发任务质量检查与修复专家。 diff --git a/src/costrict/agents/taskPlan.ts b/src/costrict/agents/taskPlan.ts index 5068e43b2..a5be800b9 100644 --- a/src/costrict/agents/taskPlan.ts +++ b/src/costrict/agents/taskPlan.ts @@ -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 `# 核心职责 diff --git a/src/costrict/agents/tddRunAndFix.ts b/src/costrict/agents/tddRunAndFix.ts index 11860942d..352442ff0 100644 --- a/src/costrict/agents/tddRunAndFix.ts +++ b/src/costrict/agents/tddRunAndFix.ts @@ -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 `你是 RunAndFixAgent,一名可运行性验证与代码修复专家,擅长诊断和解决编译构建问题。 diff --git a/src/costrict/agents/tddTestAndFix.ts b/src/costrict/agents/tddTestAndFix.ts index 714eb9a19..f8e528380 100644 --- a/src/costrict/agents/tddTestAndFix.ts +++ b/src/costrict/agents/tddTestAndFix.ts @@ -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 `你是 TestAndFixAgent,一名测试执行与自动修复专家,擅长诊断和解决测试失败问题。 diff --git a/src/costrict/agents/tddTestDesign.ts b/src/costrict/agents/tddTestDesign.ts index 996364b4d..89b9a450f 100644 --- a/src/costrict/agents/tddTestDesign.ts +++ b/src/costrict/agents/tddTestDesign.ts @@ -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 `你是 TestDesignAgent,一名测试点设计与测试用例规划专家,精通测试自动化。 diff --git a/src/costrict/agents/tddTestPrepare.ts b/src/costrict/agents/tddTestPrepare.ts index 1c825d011..02ff0f987 100644 --- a/src/costrict/agents/tddTestPrepare.ts +++ b/src/costrict/agents/tddTestPrepare.ts @@ -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 `你是 TestPrepareAgent,一名测试配置检查与文档准备专家,专注于项目的测试执行和管理方法识别。 diff --git a/src/costrict/agents/wikiCatalogueDesign.ts b/src/costrict/agents/wikiCatalogueDesign.ts index 7134699af..dfdb5a920 100644 --- a/src/costrict/agents/wikiCatalogueDesign.ts +++ b/src/costrict/agents/wikiCatalogueDesign.ts @@ -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 `# 技术文档结构设计 diff --git a/src/costrict/agents/wikiDocumentGenerate.ts b/src/costrict/agents/wikiDocumentGenerate.ts index 2b612aa97..865bf8fad 100644 --- a/src/costrict/agents/wikiDocumentGenerate.ts +++ b/src/costrict/agents/wikiDocumentGenerate.ts @@ -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 `# 技术文档生成 diff --git a/src/costrict/agents/wikiIndexGeneration.ts b/src/costrict/agents/wikiIndexGeneration.ts index cc07ce2af..9e6999045 100644 --- a/src/costrict/agents/wikiIndexGeneration.ts +++ b/src/costrict/agents/wikiIndexGeneration.ts @@ -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 `# 索引文档生成 diff --git a/src/costrict/agents/wikiProjectAnalyze.ts b/src/costrict/agents/wikiProjectAnalyze.ts index 30a6b739b..4e7f8c896 100644 --- a/src/costrict/agents/wikiProjectAnalyze.ts +++ b/src/costrict/agents/wikiProjectAnalyze.ts @@ -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 `# 项目基本分析 diff --git a/src/costrict/backup/planApply.ts b/src/costrict/backup/planApply.ts index 20ec60dbd..0f6587771 100644 --- a/src/costrict/backup/planApply.ts +++ b/src/costrict/backup/planApply.ts @@ -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,软件开发团队的项目管理者和技术架构师。 diff --git a/src/costrict/backup/reviewAndFix.ts b/src/costrict/backup/reviewAndFix.ts index 4953120f2..248852a93 100644 --- a/src/costrict/backup/reviewAndFix.ts +++ b/src/costrict/backup/reviewAndFix.ts @@ -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,一名专业软件开发团队中的代码审查与修复专家。 diff --git a/src/costrict/backup/specPlan.ts b/src/costrict/backup/specPlan.ts index 8bb918453..9935517f9 100644 --- a/src/costrict/backup/specPlan.ts +++ b/src/costrict/backup/specPlan.ts @@ -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,软件开发团队的全流程实施协调者。 diff --git a/src/costrict/backup/strictPlan.ts b/src/costrict/backup/strictPlan.ts index 87a815d7a..0bb728fc9 100644 --- a/src/costrict/backup/strictPlan.ts +++ b/src/costrict/backup/strictPlan.ts @@ -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 { diff --git a/src/costrict/backup/tdd.ts b/src/costrict/backup/tdd.ts index d66d95620..48f4f0d03 100644 --- a/src/costrict/backup/tdd.ts +++ b/src/costrict/backup/tdd.ts @@ -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 `你是 TestDrivenDevelopment Agent,负责执行全面的测试工作流程以确保代码质量。 diff --git a/src/costrict/provider/fetch.ts b/src/costrict/provider/fetch.ts index 73cfd7f1a..ecda30171 100644 --- a/src/costrict/provider/fetch.ts +++ b/src/costrict/provider/fetch.ts @@ -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 } diff --git a/src/costrict/provider/index.ts b/src/costrict/provider/index.ts index 1da455fdf..00bfdda81 100644 --- a/src/costrict/provider/index.ts +++ b/src/costrict/provider/index.ts @@ -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 { +): 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 + const anyT = t as unknown as Record 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 = {} - 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, }) } } diff --git a/src/costrict/skill/codeReviewSecurity.ts b/src/costrict/skill/codeReviewSecurity.ts index 6a569f77f..f69444afc 100644 --- a/src/costrict/skill/codeReviewSecurity.ts +++ b/src/costrict/skill/codeReviewSecurity.ts @@ -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 { diff --git a/src/costrict/skill/projectWiki.ts b/src/costrict/skill/projectWiki.ts index f768aa6c4..81d3c5edd 100644 --- a/src/costrict/skill/projectWiki.ts +++ b/src/costrict/skill/projectWiki.ts @@ -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 diff --git a/src/costrict/skill/strictPlan.ts b/src/costrict/skill/strictPlan.ts index 41208c855..dea9bfccc 100644 --- a/src/costrict/skill/strictPlan.ts +++ b/src/costrict/skill/strictPlan.ts @@ -1,4 +1,4 @@ -import { registerBundledSkill } from '../../skills/bundledSkills.js' +import { registerBundledSkill } from 'src/skills/bundledSkills.js' export function registerStrictPlanSkill(): void { registerBundledSkill({ diff --git a/src/costrict/skill/tdd.ts b/src/costrict/skill/tdd.ts index 3d08ddbd6..8644fb7fc 100644 --- a/src/costrict/skill/tdd.ts +++ b/src/costrict/skill/tdd.ts @@ -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. diff --git a/src/utils/sideQuery.ts b/src/utils/sideQuery.ts index 0c3c70a3d..2f510dc50 100644 --- a/src/utils/sideQuery.ts +++ b/src/utils/sideQuery.ts @@ -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 { // 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 { // 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) diff --git a/src/utils/status.tsx b/src/utils/status.tsx index b4cb087c2..dc7772138 100644 --- a/src/utils/status.tsx +++ b/src/utils/status.tsx @@ -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 -} + label?: string; + value: React.ReactNode | Array; +}; -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: ( - {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. ), }, - ] + ]; } 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 { - 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 { - 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 { + 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; }