refactor: 重构现代化命令管理为基于配置文件的安全方案
🎯 解决问题: - 避免推荐用户系统中不存在的工具 - 防止因缺失工具导致的命令执行失败 - 提供更安全、更灵活的现代化命令管理 🔧 主要改进: - 新增 ai_shell/modern_commands.toml 配置文件 - 智能检测系统中已安装的现代化工具 - 只推荐实际可用的工具,安全回退到原始命令 - 完整的工具描述、分类和安装提示 📦 配置文件特性: - 28 个命令映射配置 - 20 个工具描述说明 - 8 个工具分类组织 - 6 个详细安装提示 🛠️ 新增管理工具: - scripts/manage_modern_commands.py 配置管理脚本 - 支持验证、列表、安装建议等功能 - 完整的配置状态检查和报告 🔍 用户体验优化: - ai --config 显示详细的工具状态 - 区分已启用、保持原样、未安装的工具 - 提供具体的安装命令和说明 - 支持环境变量和配置文件自定义 🛡️ 安全保障: - 绝不推荐不存在的工具 - 优雅降级到原始命令 - 保持完全向后兼容性 📋 技术实现: - 添加 tomli 依赖支持 TOML 解析 - 重构配置加载逻辑 - 智能工具检测和状态管理 - 完善的错误处理和回退机制
This commit is contained in:
200
scripts/manage_modern_commands.py
Executable file
200
scripts/manage_modern_commands.py
Executable file
@ -0,0 +1,200 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
现代化命令配置管理工具
|
||||
"""
|
||||
|
||||
import sys
|
||||
import os
|
||||
import shutil
|
||||
import argparse
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..'))
|
||||
|
||||
from ai_shell.config import (
|
||||
load_modern_commands_config,
|
||||
get_modern_commands,
|
||||
get_available_modern_commands,
|
||||
get_missing_modern_commands,
|
||||
get_installation_hint,
|
||||
get_command_description
|
||||
)
|
||||
|
||||
def list_commands():
|
||||
"""列出所有配置的现代化命令"""
|
||||
print("🔧 现代化命令配置状态\n")
|
||||
|
||||
available = get_available_modern_commands()
|
||||
missing = get_missing_modern_commands()
|
||||
|
||||
# 已启用的替代
|
||||
active_alternatives = {k: v for k, v in available.items() if k != v}
|
||||
if active_alternatives:
|
||||
print(f"✅ 已启用的替代 ({len(active_alternatives)} 个):")
|
||||
for old_cmd, new_cmd in sorted(active_alternatives.items()):
|
||||
desc = get_command_description(new_cmd)
|
||||
if desc:
|
||||
print(f" {old_cmd:8} → {new_cmd:12} ({desc})")
|
||||
else:
|
||||
print(f" {old_cmd:8} → {new_cmd}")
|
||||
print()
|
||||
|
||||
# 保持原样的命令
|
||||
unchanged = {k: v for k, v in available.items() if k == v}
|
||||
if unchanged:
|
||||
print(f"➡️ 保持原样的命令: {', '.join(sorted(unchanged.keys()))}\n")
|
||||
|
||||
# 未安装的工具
|
||||
if missing:
|
||||
print(f"⚠️ 可配置但未安装的工具 ({len(missing)} 个):")
|
||||
for old_cmd, new_cmd in sorted(missing.items()):
|
||||
desc = get_command_description(new_cmd)
|
||||
hint = get_installation_hint(new_cmd)
|
||||
|
||||
if desc:
|
||||
print(f" {old_cmd:8} → {new_cmd:12} ({desc})")
|
||||
else:
|
||||
print(f" {old_cmd:8} → {new_cmd}")
|
||||
|
||||
if hint:
|
||||
print(f" 安装: {hint.split('#')[0].strip()}")
|
||||
print()
|
||||
|
||||
def check_command(command):
|
||||
"""检查特定命令的状态"""
|
||||
config = load_modern_commands_config()
|
||||
commands = config.get("commands", {})
|
||||
|
||||
if command not in commands:
|
||||
print(f"❌ 命令 '{command}' 未在配置中找到")
|
||||
return
|
||||
|
||||
modern_cmd = commands[command]
|
||||
desc = get_command_description(modern_cmd)
|
||||
hint = get_installation_hint(modern_cmd)
|
||||
|
||||
print(f"🔍 命令 '{command}' 的配置:")
|
||||
print(f" 替代工具: {modern_cmd}")
|
||||
|
||||
if desc:
|
||||
print(f" 描述: {desc}")
|
||||
|
||||
# 检查是否安装
|
||||
if shutil.which(modern_cmd):
|
||||
print(f" 状态: ✅ 已安装")
|
||||
print(f" 路径: {shutil.which(modern_cmd)}")
|
||||
else:
|
||||
print(f" 状态: ❌ 未安装")
|
||||
if hint:
|
||||
print(f" 安装方法: {hint}")
|
||||
|
||||
def install_suggestions():
|
||||
"""显示安装建议"""
|
||||
missing = get_missing_modern_commands()
|
||||
|
||||
if not missing:
|
||||
print("✅ 所有配置的现代化工具都已安装!")
|
||||
return
|
||||
|
||||
print("📦 安装建议\n")
|
||||
|
||||
# 按类别分组显示
|
||||
config = load_modern_commands_config()
|
||||
categories = config.get("categories", {})
|
||||
|
||||
for category_name, commands in categories.items():
|
||||
category_missing = []
|
||||
for cmd in commands:
|
||||
if cmd in missing:
|
||||
category_missing.append((cmd, missing[cmd]))
|
||||
|
||||
if category_missing:
|
||||
display_name = category_name.replace("_", " ").title()
|
||||
print(f"**{display_name}:**")
|
||||
|
||||
for old_cmd, new_cmd in category_missing:
|
||||
hint = get_installation_hint(new_cmd)
|
||||
desc = get_command_description(new_cmd)
|
||||
|
||||
print(f" {new_cmd}:")
|
||||
if desc:
|
||||
print(f" 功能: {desc}")
|
||||
if hint:
|
||||
print(f" 安装: {hint}")
|
||||
print()
|
||||
|
||||
def validate_config():
|
||||
"""验证配置文件"""
|
||||
config_file = Path(__file__).parent.parent / "ai_shell" / "modern_commands.toml"
|
||||
|
||||
print(f"🔍 验证配置文件: {config_file}")
|
||||
|
||||
if not config_file.exists():
|
||||
print("❌ 配置文件不存在")
|
||||
return False
|
||||
|
||||
try:
|
||||
config = load_modern_commands_config()
|
||||
|
||||
# 检查必需的部分
|
||||
required_sections = ["commands", "descriptions", "categories", "installation_hints"]
|
||||
for section in required_sections:
|
||||
if section not in config:
|
||||
print(f"⚠️ 缺少配置部分: {section}")
|
||||
else:
|
||||
print(f"✅ 配置部分 '{section}': {len(config[section])} 项")
|
||||
|
||||
# 检查命令一致性
|
||||
commands = config.get("commands", {})
|
||||
descriptions = config.get("descriptions", {})
|
||||
installation_hints = config.get("installation_hints", {})
|
||||
|
||||
print(f"\n📊 配置统计:")
|
||||
print(f" 配置的命令: {len(commands)}")
|
||||
print(f" 有描述的工具: {len(descriptions)}")
|
||||
print(f" 有安装提示的工具: {len(installation_hints)}")
|
||||
|
||||
# 检查缺少描述的工具
|
||||
modern_tools = set(commands.values())
|
||||
missing_descriptions = modern_tools - set(descriptions.keys())
|
||||
if missing_descriptions:
|
||||
print(f" ⚠️ 缺少描述的工具: {', '.join(sorted(missing_descriptions))}")
|
||||
|
||||
return True
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ 配置文件解析错误: {e}")
|
||||
return False
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="现代化命令配置管理工具")
|
||||
subparsers = parser.add_subparsers(dest="command", help="可用命令")
|
||||
|
||||
# list 命令
|
||||
subparsers.add_parser("list", help="列出所有配置的现代化命令")
|
||||
|
||||
# check 命令
|
||||
check_parser = subparsers.add_parser("check", help="检查特定命令的状态")
|
||||
check_parser.add_argument("command", help="要检查的命令名")
|
||||
|
||||
# install 命令
|
||||
subparsers.add_parser("install", help="显示安装建议")
|
||||
|
||||
# validate 命令
|
||||
subparsers.add_parser("validate", help="验证配置文件")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.command == "list":
|
||||
list_commands()
|
||||
elif args.command == "check":
|
||||
check_command(args.command)
|
||||
elif args.command == "install":
|
||||
install_suggestions()
|
||||
elif args.command == "validate":
|
||||
validate_config()
|
||||
else:
|
||||
parser.print_help()
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Reference in New Issue
Block a user