|
|
|
@ -5,7 +5,7 @@ import java.io.PrintStream; |
|
|
|
/** |
|
|
|
/** |
|
|
|
* 工具调用状态渲染器 —— 对应 claude-code/src/components/ToolStatus.tsx。 |
|
|
|
* 工具调用状态渲染器 —— 对应 claude-code/src/components/ToolStatus.tsx。 |
|
|
|
* <p> |
|
|
|
* <p> |
|
|
|
* 在终端中显示工具调用的进度和结果。 |
|
|
|
* 使用彩色 ● 圆点标识工具调用状态,配合 ⎿ 显示结果(参考 Claude Code 样式)。 |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public class ToolStatusRenderer { |
|
|
|
public class ToolStatusRenderer { |
|
|
|
|
|
|
|
|
|
|
|
@ -17,16 +17,17 @@ public class ToolStatusRenderer { |
|
|
|
|
|
|
|
|
|
|
|
/** 渲染工具调用开始 */ |
|
|
|
/** 渲染工具调用开始 */ |
|
|
|
public void renderStart(String toolName, String args) { |
|
|
|
public void renderStart(String toolName, String args) { |
|
|
|
out.println(AnsiStyle.dim(" ─────────────────────────────────────────")); |
|
|
|
out.println(); |
|
|
|
out.print(AnsiStyle.YELLOW + " ⚙ " + AnsiStyle.BOLD + toolName + AnsiStyle.RESET); |
|
|
|
out.print(AnsiStyle.BRIGHT_BLUE + " ● " + AnsiStyle.BOLD + toolName + AnsiStyle.RESET); |
|
|
|
out.println(AnsiStyle.dim(" running...")); |
|
|
|
|
|
|
|
// 如果有简短参数,显示
|
|
|
|
// 提取并显示简短参数
|
|
|
|
if (args != null && !args.isBlank()) { |
|
|
|
if (args != null && !args.isBlank()) { |
|
|
|
String summary = extractSummary(toolName, args); |
|
|
|
String summary = extractSummary(toolName, args); |
|
|
|
if (summary != null) { |
|
|
|
if (summary != null) { |
|
|
|
out.println(AnsiStyle.dim(" " + summary)); |
|
|
|
out.print(AnsiStyle.dim("(" + summary + ")")); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
out.println(AnsiStyle.dim(" running...")); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** 渲染工具调用完成 */ |
|
|
|
/** 渲染工具调用完成 */ |
|
|
|
@ -37,36 +38,40 @@ public class ToolStatusRenderer { |
|
|
|
display = display.substring(0, 497) + "..."; |
|
|
|
display = display.substring(0, 497) + "..."; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
out.println(AnsiStyle.GREEN + " ✓ " + AnsiStyle.BOLD + toolName + AnsiStyle.RESET |
|
|
|
out.println(AnsiStyle.GREEN + " ● " + AnsiStyle.BOLD + toolName + AnsiStyle.RESET |
|
|
|
+ AnsiStyle.dim(" done")); |
|
|
|
+ AnsiStyle.dim(" done")); |
|
|
|
|
|
|
|
|
|
|
|
if (display != null && !display.isBlank()) { |
|
|
|
if (display != null && !display.isBlank()) { |
|
|
|
// 缩进输出每一行
|
|
|
|
// 使用 ⎿ 前缀显示结果(Claude Code 风格)
|
|
|
|
for (String line : display.lines().toList()) { |
|
|
|
String[] lines = display.lines().toArray(String[]::new); |
|
|
|
out.println(AnsiStyle.dim(" " + line)); |
|
|
|
for (int i = 0; i < lines.length; i++) { |
|
|
|
|
|
|
|
if (i == 0) { |
|
|
|
|
|
|
|
out.println(AnsiStyle.DIM + " ⎿ " + lines[i] + AnsiStyle.RESET); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
out.println(AnsiStyle.DIM + " " + lines[i] + AnsiStyle.RESET); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
out.println(AnsiStyle.dim(" ─────────────────────────────────────────")); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** 渲染工具错误 */ |
|
|
|
/** 渲染工具错误 */ |
|
|
|
public void renderError(String toolName, String error) { |
|
|
|
public void renderError(String toolName, String error) { |
|
|
|
out.println(AnsiStyle.RED + " ✗ " + AnsiStyle.BOLD + toolName + AnsiStyle.RESET |
|
|
|
out.println(AnsiStyle.RED + " ● " + AnsiStyle.BOLD + toolName + AnsiStyle.RESET |
|
|
|
+ AnsiStyle.red(" error")); |
|
|
|
+ AnsiStyle.red(" error")); |
|
|
|
if (error != null) { |
|
|
|
if (error != null) { |
|
|
|
out.println(AnsiStyle.red(" " + error)); |
|
|
|
out.println(AnsiStyle.DIM + " ⎿ " + AnsiStyle.RED + error + AnsiStyle.RESET); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** 从 JSON 参数中提取人类可读的摘要 */ |
|
|
|
/** 从 JSON 参数中提取人类可读的摘要 */ |
|
|
|
private String extractSummary(String toolName, String args) { |
|
|
|
private String extractSummary(String toolName, String args) { |
|
|
|
try { |
|
|
|
try { |
|
|
|
// 简单提取关键字段
|
|
|
|
|
|
|
|
if (args.contains("\"command\"")) { |
|
|
|
if (args.contains("\"command\"")) { |
|
|
|
int start = args.indexOf("\"command\""); |
|
|
|
int start = args.indexOf("\"command\""); |
|
|
|
int valStart = args.indexOf("\"", start + 10) + 1; |
|
|
|
int valStart = args.indexOf("\"", start + 10) + 1; |
|
|
|
int valEnd = args.indexOf("\"", valStart); |
|
|
|
int valEnd = args.indexOf("\"", valStart); |
|
|
|
if (valStart > 0 && valEnd > valStart) { |
|
|
|
if (valStart > 0 && valEnd > valStart) { |
|
|
|
String cmd = args.substring(valStart, Math.min(valEnd, valStart + 80)); |
|
|
|
String cmd = args.substring(valStart, Math.min(valEnd, valStart + 60)); |
|
|
|
return "$ " + cmd; |
|
|
|
return "$ " + cmd; |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -86,6 +91,14 @@ public class ToolStatusRenderer { |
|
|
|
return "pattern: " + args.substring(valStart, valEnd); |
|
|
|
return "pattern: " + args.substring(valStart, valEnd); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
if (args.contains("\"query\"")) { |
|
|
|
|
|
|
|
int start = args.indexOf("\"query\""); |
|
|
|
|
|
|
|
int valStart = args.indexOf("\"", start + 8) + 1; |
|
|
|
|
|
|
|
int valEnd = args.indexOf("\"", valStart); |
|
|
|
|
|
|
|
if (valStart > 0 && valEnd > valStart) { |
|
|
|
|
|
|
|
return "\"" + args.substring(valStart, Math.min(valEnd, valStart + 60)) + "\""; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} catch (Exception e) { |
|
|
|
} catch (Exception e) { |
|
|
|
// 忽略解析错误
|
|
|
|
// 忽略解析错误
|
|
|
|
} |
|
|
|
} |
|
|
|
|