(String[] args)
| 39 | */ |
| 40 | public class Main { |
| 41 | public static void main(String[] args) { |
| 42 | CliEnvironmentConfig.configureAwtForCli(); |
| 43 | if (CliRuntimeApiLauncher.isServeCommand(args)) { |
| 44 | CliEnvironmentConfig.configureLogging(); |
| 45 | CliRuntimeApiLauncher.startAndBlock(args); |
| 46 | return; |
| 47 | } |
| 48 | |
| 49 | CliEnvironmentConfig.configureLogging(); |
| 50 | |
| 51 | TCodeConfig config = TCodeConfig.load(); |
| 52 | LlmClient llmClient = LlmClientFactory.createFromConfig(config); |
| 53 | if (llmClient == null) { |
| 54 | System.err.println("❌ 错误: 未找到可用的 API Key"); |
| 55 | System.err.println("请在 .env 文件中添加 GLM_API_KEY、DEEPSEEK_API_KEY、STEP_API_KEY 或 KIMI_API_KEY"); |
| 56 | System.exit(1); |
| 57 | } |
| 58 | AtomicReference<LlmClient> llmClientRef = new AtomicReference<>(llmClient); |
| 59 | |
| 60 | try (Terminal terminal = TerminalBuilder.builder().system(true).dumb(true).build()) { |
| 61 | CliSessionInfrastructure infrastructure = CliSessionInfrastructure.create(Path.of(".")); |
| 62 | TerminalHitlHandler terminalHitlHandler = infrastructure.terminalHitlHandler(); |
| 63 | SwitchableHitlHandler hitlHandler = infrastructure.hitlHandler(); |
| 64 | HitlToolRegistry hitlToolRegistry = infrastructure.hitlToolRegistry(); |
| 65 | BrowserSession browserSession = infrastructure.browserSession(); |
| 66 | BrowserConnectivityCheck browserConnectivityCheck = infrastructure.browserConnectivityCheck(); |
| 67 | McpServerManager mcpServerManager = infrastructure.mcpServerManager(); |
| 68 | AtomicReference<SkillRegistry> skillRegistryRef = new AtomicReference<>(); |
| 69 | |
| 70 | LineReader lineReader = CliLineReaderFactory.create( |
| 71 | terminal, |
| 72 | mcpServerManager::resourceCandidates, |
| 73 | () -> skillRegistryRef.get() == null ? List.of() : skillRegistryRef.get().allSkills(), |
| 74 | Path.of(System.getProperty("user.home"))); |
| 75 | |
| 76 | // JLine-first:启动输出、命令输出、Agent 流式内容都走同一条 Renderer.stream() 通道。 |
| 77 | // inline 首屏要挂到 LineReader 首次初始化回调里,避免在 readLine 接管屏幕前用裸输出抢光标。 |
| 78 | CliRendererInfrastructure rendererInfrastructure = CliRendererInfrastructure.start( |
| 79 | terminal, lineReader, hitlHandler, |
| 80 | CliStartupStatus.statusInfo(llmClient, hitlHandler, "idle", mcpServerManager, null)); |
| 81 | Renderer renderer = rendererInfrastructure.renderer(); |
| 82 | PrintStream ui = rendererInfrastructure.ui(); |
| 83 | |
| 84 | Path home = Path.of(System.getProperty("user.home")); |
| 85 | CliMcpInfrastructure mcpInfrastructure = CliMcpInfrastructure.start( |
| 86 | home, Path.of("."), mcpServerManager, ui, CliStartupStatus.mcpStartupWait(), |
| 87 | Runtime.getRuntime()::addShutdownHook); |
| 88 | String startupNote = mcpInfrastructure.startupNote(); |
| 89 | AtMentionExpander mentionExpander = mcpInfrastructure.mentionExpander(); |
| 90 | LocalPathMentionExpander localPathMentionExpander = mcpInfrastructure.localPathMentionExpander(); |
| 91 | |
| 92 | // === Skill 系统初始化 === |
| 93 | CliSkillInfrastructure skillInfrastructure = CliSkillInfrastructure.create(home, Path.of(".")); |
| 94 | startupNote = CliStartupStatus.appendStartupNote(startupNote, skillInfrastructure.startupNote()); |
| 95 | SkillRegistry skillRegistry = skillInfrastructure.skillRegistry(); |
| 96 | com.tcode.skill.SkillStateStore skillStateStore = skillRegistry.stateStore(); |
| 97 | skillRegistryRef.set(skillRegistry); |
| 98 | com.tcode.skill.SkillContextBuffer skillContextBuffer = skillInfrastructure.skillContextBuffer(); |
nothing calls this directly
no test coverage detected