7.8 KiB
7.8 KiB
核心模块设计 — 命令系统
所属项目: free-code .NET 10 重写 原始代码来源:
../../src/commands.ts,../../src/commands/原始设计意图: 定义并注册所有斜杠命令(/command),提供会话管理、配置变更、认证操作等用户可交互的命令集合 上级文档: 核心模块设计总览
概述
命令系统管理用户在 REPL 中输入的斜杠命令(如 /clear、/model、/help)。它与工具系统平行,但面向的是用户直接操作而非 Agent 的自主调用。
原始 TypeScript 实现在 commands.ts 中以数组形式注册约 80 个命令对象,每个对象实现固定的接口字段。.NET 重写引入 ICommand 接口和 CommandRegistry 注册表,通过 DI 容器管理命令生命周期,并支持基于认证状态和 feature flag 的动态可用性控制。
8.1 ICommand 接口
public interface ICommand
{
string Name { get; }
string[]? Aliases { get; }
string Description { get; }
CommandCategory Category { get; } // Prompt, Local, LocalDialog
CommandAvailability Availability { get; } // Always, RequiresAuth, ClaudeAiOnly, InternalOnly
bool IsEnabled();
Task<CommandResult> ExecuteAsync(
CommandContext context, string? args = null, CancellationToken ct = default);
}
public enum CommandCategory { Prompt, Local, LocalDialog }
public enum CommandAvailability { Always, RequiresAuth, ClaudeAiOnly, InternalOnly }
public record CommandResult(bool Success, string? Output = null);
命令分类说明
CommandCategory 决定命令的执行方式:
| 类别 | 说明 |
|---|---|
Prompt |
命令内容作为 prompt 发送给 LLM(如 /commit 生成提交信息) |
Local |
在本地直接执行,不经过 LLM(如 /clear 清空历史) |
LocalDialog |
在本地执行并打开对话框(如 /config 弹出配置界面) |
CommandAvailability 控制命令的可见性:
| 可用性 | 显示条件 |
|---|---|
Always |
始终可用 |
RequiresAuth |
需要已登录任意账号 |
ClaudeAiOnly |
仅 Claude.ai 账号用户可见 |
InternalOnly |
仅 Anthropic 内部用户可见 |
8.2 CommandRegistry 命令注册表
CommandRegistry 完整注册 70+ 个命令,并提供基于认证状态的过滤能力。
public class CommandRegistry : ICommandRegistry
{
private readonly IServiceProvider _services;
private readonly IFeatureFlagService _features;
private readonly IAuthService _authService;
private List<ICommand>? _cachedCommands;
public async Task<IReadOnlyList<ICommand>> GetCommandsAsync()
{
if (_cachedCommands != null) return _cachedCommands;
_cachedCommands = new List<ICommand>();
// === 核心命令 (~65个) ===
// 会话管理
Add<SessionCommand>(); Add<ResumeCommand>(); Add<RenameCommand>();
Add<ClearCommand>(); Add<ExportCommand>();
// 配置
Add<ConfigCommand>(); Add<ModelCommand>(); Add<ThemeCommand>();
Add<ColorCommand>(); Add<OutputStyleCommand>(); Add<KeybindingsCommand>();
// 认证
Add<LoginCommand>(); Add<LogoutCommand>();
// 状态与统计
Add<StatusCommand>(); Add<CostCommand>(); Add<StatsCommand>(); Add<ExtraUsageCommand>();
// 工具与诊断
Add<DiffCommand>(); Add<CopyCommand>(); Add<DoctorCommand>();
Add<MemoryCommand>(); Add<AgentsCommand>();
// Git 集成
Add<CommitCommand>(); Add<CommitPushPrCommand>(); Add<BranchCommand>();
// MCP / LSP / Hooks
Add<McpCommand>(); Add<HooksCommand>(); Add<FilesCommand>();
// 扩展系统
Add<SkillsCommand>(); Add<PluginCommand>();
// 杂项
Add<HelpCommand>(); Add<ExitCommand>(); Add<VersionCommand>();
Add<AddDirCommand>(); Add<VimCommand>(); Add<FastCommand>();
Add<UpgradeCommand>(); Add<FeedbackCommand>(); Add<TagCommand>();
Add<CompactCommand>(); Add<ContextCommand>();
Add<PermissionsCommand>(); Add<EffortCommand>();
Add<TasksCommand>(); Add<TeleportCommand>(); Add<RewindCommand>();
Add<TerminalSetupCommand>(); Add<DesktopCommand>(); Add<MobileCommand>();
Add<ChromeCommand>(); Add<PrivacySettingsCommand>();
Add<AssistantCommand>(); Add<SandboxToggleCommand>();
Add<RemoteEnvCommand>(); Add<RateLimitOptionsCommand>();
Add<PassesCommand>(); Add<BreakCacheCommand>(); Add<SummaryCommand>();
Add<ShareCommand>(); Add<ReleaseNotesCommand>(); Add<StatusLineCommand>();
Add<PrCommentsCommand>(); Add<ReviewCommand>(); Add<UltrareviewCommand>();
Add<InstallGitHubAppCommand>(); Add<InstallSlackAppCommand>();
// === 条件命令 ===
if (_features.IsEnabled(FeatureFlags.Buddy))
Add<BtwCommand>();
if (_features.IsEnabled(FeatureFlags.Ultraplan))
Add<UltraplanCommand>();
Add<ThinkbackCommand>(); Add<ThinkbackPlayCommand>();
// === 内部命令 (~15个) ===
Add<HeapdumpCommand>(); Add<MockLimitsCommand>();
Add<BridgeKickCommand>(); Add<AntTraceCommand>();
Add<PerfIssueCommand>(); Add<DebugToolCallCommand>();
Add<OnboardingCommand>(); Add<BughunterCommand>();
Add<GoodClaudeCommand>(); Add<IssueCommand>();
Add<AdvisorCommand>(); Add<InsightsCommand>();
Add<ResetLimitsCommand>(); Add<CtxVizCommand>();
Add<OauthRefreshCommand>();
return _cachedCommands;
}
public async Task<IReadOnlyList<ICommand>> GetEnabledCommandsAsync()
{
var all = await GetCommandsAsync();
return all.Where(c => c.IsEnabled() && MeetsAvailability(c)).ToList();
}
private bool MeetsAvailability(ICommand cmd) => cmd.Availability switch
{
CommandAvailability.Always => true,
CommandAvailability.RequiresAuth => _authService.IsAuthenticated,
CommandAvailability.ClaudeAiOnly => _authService.IsClaudeAiUser,
CommandAvailability.InternalOnly => _authService.IsInternalUser,
_ => false
};
private void Add<T>() where T : ICommand =>
_cachedCommands!.Add(_services.GetRequiredService<T>());
}
8.3 命令分组统计
| 分组 | 命令数量 | 说明 |
|---|---|---|
| 会话管理 | 5 | session、resume、rename、clear、export |
| 配置 | 6 | config、model、theme、color、output-style、keybindings |
| 认证 | 2 | login、logout |
| 状态与统计 | 4 | status、cost、stats、extra-usage |
| 工具与诊断 | 5 | diff、copy、doctor、memory、agents |
| Git 集成 | 3 | commit、commit-push-pr、branch |
| MCP/LSP/Hooks | 3 | mcp、hooks、files |
| 扩展系统 | 2 | skills、plugin |
| 杂项(核心) | ~30 | help、exit、version、add-dir 等 |
| 条件命令 | 2-4 | btw(BUDDY)、ultraplan(ULTRAPLAN)、thinkback |
| 内部命令 | 15 | heapdump、mock-limits、bughunter 等 |
8.4 与工具系统的区别
命令系统和工具系统都是 free-code 的扩展点,但职责不同:
| 维度 | 命令系统 | 工具系统 |
|---|---|---|
| 触发方 | 用户(输入 /command) |
Agent 自主决策 |
| 输入格式 | 斜杠 + 可选文本参数 | 结构化 JSON(JSON Schema 验证) |
| 出现在 System Prompt | 是(命令描述段) | 是(工具描述段) |
| 权限控制粒度 | CommandAvailability 枚举 |
PermissionEngine + ToolPermissionContext |
| 执行上下文 | CommandContext |
ToolExecutionContext |