feat: Phase4 命令系统与上下文增强

新增基础设施:
- TokenTracker: 真实Token使用量追踪和费用估算(按模型定价)
- SkillLoader: .claude/skills/ 扫描加载,支持YAML frontmatter元数据
- GitContext: Git分支/状态/最近提交收集,注入系统提示词

新增命令 (4个):
- /init: 项目CLAUDE.md初始化向导,自动检测项目类型(Maven/Gradle/Node/Python等)
- /status: 会话状态仪表板(模型、Token、内存、运行时间等)
- /context: 上下文概览(CLAUDE.md、Skills、Git、系统提示词大小)
- /config: 配置查看/设置(支持model快捷切换和API key显示)

增强命令 (3个):
- /cost: 从占位→真实Token统计,显示input/output/cache tokens和费用
- /model: 支持快捷名称切换(sonnet/opus/haiku),显示可用模型列表
- /compact: 增强显示压缩前后消息数和Token使用量

系统提示词增强:
- 集成Skills摘要和Git上下文到系统提示词
- 新增Shell环境信息和更详细的Guidelines

命令总数: 6 → 10, 工具总数: 11

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
liuzh
2026-04-01 20:59:22 +08:00
co-authored by Copilot
parent e09c3de91e
commit 7a6c2fcc02
13 changed files with 1043 additions and 37 deletions
@@ -3,12 +3,13 @@ package com.claudecode.command.impl;
import com.claudecode.command.CommandContext;
import com.claudecode.command.SlashCommand;
import com.claudecode.console.AnsiStyle;
import com.claudecode.core.TokenTracker;
/**
* /cost 命令 —— 显示 Token 使用量和费用估算。
* <p>
* 对应 claude-code/src/commands/cost.ts。
* 当前为占位实现,后续接入实际 Token 统计。
* 从 AgentLoop 的 TokenTracker 获取真实 Token 统计。
*/
public class CostCommand implements SlashCommand {
@@ -24,21 +25,40 @@ public class CostCommand implements SlashCommand {
@Override
public String execute(String args, CommandContext context) {
int msgCount = 0;
if (context.agentLoop() != null) {
msgCount = context.agentLoop().getMessageHistory().size();
}
TokenTracker tracker = context.agentLoop().getTokenTracker();
int msgCount = context.agentLoop().getMessageHistory().size();
StringBuilder sb = new StringBuilder();
sb.append("\n");
sb.append(AnsiStyle.bold(" Token Usage:\n\n"));
sb.append(" Messages: ").append(AnsiStyle.cyan(String.valueOf(msgCount))).append("\n");
sb.append(" Input tokens: ").append(AnsiStyle.dim("(tracking not yet implemented)")).append("\n");
sb.append(" Output tokens:").append(AnsiStyle.dim("(tracking not yet implemented)")).append("\n");
sb.append(" Est. cost: ").append(AnsiStyle.dim("(tracking not yet implemented)")).append("\n");
sb.append("\n");
sb.append(AnsiStyle.dim(" Token tracking will be added in a future update."));
sb.append(AnsiStyle.bold(" 💰 Token Usage & Cost\n"));
sb.append(" ").append("".repeat(40)).append("\n\n");
sb.append(" ").append(AnsiStyle.bold("Model: ")).append(AnsiStyle.cyan(tracker.getModelName())).append("\n");
sb.append(" ").append(AnsiStyle.bold("API Calls: ")).append(tracker.getApiCallCount()).append("\n");
sb.append(" ").append(AnsiStyle.bold("Messages: ")).append(msgCount).append("\n\n");
sb.append(" ").append(AnsiStyle.bold("Input tokens: ")).append(formatTokenLine(tracker.getInputTokens())).append("\n");
sb.append(" ").append(AnsiStyle.bold("Output tokens:")).append(formatTokenLine(tracker.getOutputTokens())).append("\n");
if (tracker.getCacheReadTokens() > 0) {
sb.append(" ").append(AnsiStyle.bold("Cache read: ")).append(formatTokenLine(tracker.getCacheReadTokens())).append("\n");
}
if (tracker.getCacheCreationTokens() > 0) {
sb.append(" ").append(AnsiStyle.bold("Cache create: ")).append(formatTokenLine(tracker.getCacheCreationTokens())).append("\n");
}
sb.append(" ").append("".repeat(30)).append("\n");
sb.append(" ").append(AnsiStyle.bold("Total: ")).append(TokenTracker.formatTokens(tracker.getTotalTokens())).append(" tokens\n");
sb.append(" ").append(AnsiStyle.bold("Est. Cost: ")).append(AnsiStyle.green("$" + String.format("%.4f", tracker.estimateCost()))).append("\n");
if (tracker.getApiCallCount() == 0) {
sb.append("\n").append(AnsiStyle.dim(" No API calls yet. Start a conversation to see usage."));
}
return sb.toString();
}
private String formatTokenLine(long tokens) {
return " " + TokenTracker.formatTokens(tokens) + AnsiStyle.dim(" (" + tokens + ")");
}
}