diff --git a/src/main/java/com/claudecode/command/impl/CommitCommand.java b/src/main/java/com/claudecode/command/impl/CommitCommand.java index 23c90a1..8c9dd89 100644 --- a/src/main/java/com/claudecode/command/impl/CommitCommand.java +++ b/src/main/java/com/claudecode/command/impl/CommitCommand.java @@ -18,6 +18,8 @@ import java.util.concurrent.TimeUnit; *
* 对应 claude-code/src/commands/compact.ts。 - * 委托给 FullCompact 执行实际压缩逻辑。 + * 支持压缩级别和统计显示。 + *
+ * 对应 claude-code/src/commands/files.ts。
+ * 显示项目目录树(默认2层深度)。
+ */
+public class FilesCommand implements SlashCommand {
+
+ @Override
+ public String name() {
+ return "files";
+ }
+
+ @Override
+ public String description() {
+ return "List project files. Use /files [depth] to control depth (default: 2)";
+ }
+
+ @Override
+ public String execute(String args, CommandContext context) {
+ Path projectDir = Path.of(System.getProperty("user.dir"));
+ int maxDepth = 2;
+
+ if (args != null && !args.isBlank()) {
+ try {
+ maxDepth = Integer.parseInt(args.strip());
+ maxDepth = Math.max(1, Math.min(maxDepth, 5));
+ } catch (NumberFormatException ignored) {
+ // Treat as path filter
+ return listFiltered(projectDir, args.strip());
+ }
+ }
+
+ StringBuilder sb = new StringBuilder();
+ sb.append("\n ").append(AnsiStyle.bold("📁 " + projectDir.getFileName())).append("\n");
+ sb.append(" ").append("─".repeat(50)).append("\n");
+
+ try {
+ int[] counts = {0, 0}; // [files, dirs]
+ listDirectory(sb, projectDir, "", maxDepth, 0, counts);
+ sb.append(" ").append("─".repeat(50)).append("\n");
+ sb.append(" ").append(AnsiStyle.dim(counts[1] + " directories, " + counts[0] + " files")).append("\n");
+ } catch (IOException e) {
+ sb.append(" ").append(AnsiStyle.red("Error: " + e.getMessage())).append("\n");
+ }
+
+ return sb.toString();
+ }
+
+ private void listDirectory(StringBuilder sb, Path dir, String indent, int maxDepth, int depth, int[] counts) throws IOException {
+ if (depth >= maxDepth) return;
+
+ try (Stream
+ * 支持:
+ *
+ * 对应 claude-code/src/commands/permissions.ts。
+ * 显示当前权限模式和规则列表。
+ */
+public class PermissionsCommand implements SlashCommand {
+
+ private final PermissionSettings settings;
+
+ public PermissionsCommand(PermissionSettings settings) {
+ this.settings = settings;
+ }
+
+ @Override
+ public String name() {
+ return "permissions";
+ }
+
+ @Override
+ public String description() {
+ return "View and manage permission settings";
+ }
+
+ @Override
+ public String execute(String args, CommandContext context) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("\n ").append(AnsiStyle.bold("🔐 Permission Settings")).append("\n");
+ sb.append(" ").append("─".repeat(50)).append("\n");
+
+ // Current mode
+ PermissionTypes.PermissionMode mode = settings.getCurrentMode();
+ String modeStr = mode != null ? mode.name() : "DEFAULT";
+ String modeColor = switch (modeStr) {
+ case "AUTO_ALLOW" -> AnsiStyle.green(modeStr);
+ case "DENY_ALL" -> AnsiStyle.red(modeStr);
+ default -> AnsiStyle.yellow(modeStr);
+ };
+ sb.append(" Mode: ").append(modeColor).append("\n\n");
+
+ // All rules
+ List
+ * 对应 claude-code 中的任务管理 UI。
+ * 显示所有任务的状态、创建时间和结果摘要。
+ */
+public class TasksCommand implements SlashCommand {
+
+ private final TaskManager taskManager;
+
+ public TasksCommand(TaskManager taskManager) {
+ this.taskManager = taskManager;
+ }
+
+ @Override
+ public String name() {
+ return "tasks";
+ }
+
+ @Override
+ public String description() {
+ return "List all background tasks and their status";
+ }
+
+ @Override
+ public String execute(String args, CommandContext context) {
+ List
+ *
*/
public class HelpCommand implements SlashCommand {
@@ -18,7 +26,7 @@ public class HelpCommand implements SlashCommand {
@Override
public String description() {
- return "Show available commands";
+ return "Show available commands. Use /help [keyword] to search or /help [command] for details.";
}
@Override
@@ -28,13 +36,52 @@ public class HelpCommand implements SlashCommand {
@Override
public String execute(String args, CommandContext context) {
+ String query = (args == null) ? "" : args.strip();
+ var allCommands = context.commandRegistry().getCommands();
+
+ // If a specific command name is given, show details
+ if (!query.isEmpty()) {
+ String queryClean = query.startsWith("/") ? query.substring(1) : query;
+
+ // Exact match → show detail
+ var exactMatch = allCommands.stream()
+ .filter(cmd -> cmd.name().equalsIgnoreCase(queryClean)
+ || cmd.aliases().stream().anyMatch(a -> a.equalsIgnoreCase(queryClean)))
+ .findFirst();
+
+ if (exactMatch.isPresent()) {
+ return formatCommandDetail(exactMatch.get());
+ }
+
+ // Fuzzy search by keyword
+ String queryLower = queryClean.toLowerCase();
+ var matches = allCommands.stream()
+ .filter(cmd -> cmd.name().toLowerCase().contains(queryLower)
+ || cmd.description().toLowerCase().contains(queryLower))
+ .collect(Collectors.toList());
+
+ if (matches.isEmpty()) {
+ return AnsiStyle.yellow(" No commands matching \"" + query + "\"\n")
+ + AnsiStyle.dim(" Use /help to see all commands");
+ }
+
+ StringBuilder sb = new StringBuilder();
+ sb.append(AnsiStyle.bold("\n Commands matching \"" + query + "\":\n\n"));
+ appendCommandList(sb, matches);
+ return sb.toString();
+ }
+
+ // No args → show all
StringBuilder sb = new StringBuilder();
sb.append(AnsiStyle.bold("\n Available Commands:\n\n"));
+ appendCommandList(sb, allCommands);
+ sb.append("\n");
+ sb.append(AnsiStyle.dim(" 💡 Use /help [command] for details, /help [keyword] to search\n"));
+ sb.append(AnsiStyle.dim(" Shortcuts: Tab to autocomplete, ↑↓ to browse history, Ctrl+D to exit\n"));
+ return sb.toString();
+ }
- // 从 CommandRegistry 动态获取所有已注册命令
- var commands = context.commandRegistry().getCommands();
-
- // 计算最长命令名称用于对齐
+ private void appendCommandList(StringBuilder sb, List extends SlashCommand> commands) {
int maxNameLen = commands.stream()
.mapToInt(cmd -> cmd.name().length())
.max().orElse(12);
@@ -42,7 +89,6 @@ public class HelpCommand implements SlashCommand {
for (SlashCommand cmd : commands) {
String nameStr = "/" + cmd.name();
- // 如果有别名,附加显示
String aliasStr = "";
if (!cmd.aliases().isEmpty()) {
aliasStr = AnsiStyle.DIM + " (also: "
@@ -52,10 +98,17 @@ public class HelpCommand implements SlashCommand {
sb.append(String.format(" %s%-" + (maxNameLen + 2) + "s%s %s%s%n",
AnsiStyle.CYAN, nameStr, AnsiStyle.RESET, cmd.description(), aliasStr));
}
+ }
- sb.append("\n");
- sb.append(AnsiStyle.dim(" Shortcuts: Tab to autocomplete, ↑↓ to browse history, Ctrl+D to exit\n"));
-
+ private String formatCommandDetail(SlashCommand cmd) {
+ StringBuilder sb = new StringBuilder();
+ sb.append("\n ").append(AnsiStyle.bold("/" + cmd.name())).append("\n");
+ sb.append(" ").append("─".repeat(40)).append("\n");
+ sb.append(" ").append(cmd.description()).append("\n");
+ if (!cmd.aliases().isEmpty()) {
+ sb.append(" ").append(AnsiStyle.dim("Aliases: "
+ + cmd.aliases().stream().map(a -> "/" + a).collect(Collectors.joining(", ")))).append("\n");
+ }
return sb.toString();
}
}
diff --git a/src/main/java/com/claudecode/command/impl/PermissionsCommand.java b/src/main/java/com/claudecode/command/impl/PermissionsCommand.java
new file mode 100644
index 0000000..5245b53
--- /dev/null
+++ b/src/main/java/com/claudecode/command/impl/PermissionsCommand.java
@@ -0,0 +1,67 @@
+package com.claudecode.command.impl;
+
+import com.claudecode.command.CommandContext;
+import com.claudecode.command.SlashCommand;
+import com.claudecode.console.AnsiStyle;
+import com.claudecode.permission.PermissionSettings;
+import com.claudecode.permission.PermissionTypes;
+
+import java.util.List;
+
+/**
+ * /permissions 命令 —— 查看和管理权限设置。
+ *