- implements SlashCommand -> extends BaseSlashCommand (all 54 files) - Replace CommandUtils.parseArgs/args null checks -> args(args) - Replace agentLoop null checks -> requireAgentLoop(context)/noSession() - Replace context.agentLoop().getToolContext() -> toolCtx(context) - Replace CommandUtils.success/error/header/subtitle/warning/info -> instance methods - Remove unused CommandUtils/AnsiStyle imports where applicable - 87 tests passing, zero compilation errors Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>pull/1/head
parent
12a443c9a9
commit
9f4023bdf0
@ -0,0 +1,69 @@ |
|||||||
|
#!/usr/bin/env python3 |
||||||
|
""" |
||||||
|
简单的天气查询脚本 |
||||||
|
使用OpenWeatherMap API |
||||||
|
""" |
||||||
|
|
||||||
|
import requests |
||||||
|
import sys |
||||||
|
|
||||||
|
def get_weather(api_key, city="Beijing", units="metric"): |
||||||
|
""" |
||||||
|
获取指定城市的天气 |
||||||
|
""" |
||||||
|
url = "http://api.openweathermap.org/data/2.5/weather" |
||||||
|
|
||||||
|
params = { |
||||||
|
"q": city, |
||||||
|
"appid": api_key, |
||||||
|
"units": units, |
||||||
|
"lang": "zh_cn" |
||||||
|
} |
||||||
|
|
||||||
|
try: |
||||||
|
response = requests.get(url, params=params, timeout=10) |
||||||
|
data = response.json() |
||||||
|
|
||||||
|
if data.get("cod") != 200: |
||||||
|
print(f"错误: {data.get('message', '未知错误')}") |
||||||
|
return None |
||||||
|
|
||||||
|
return data |
||||||
|
except Exception as e: |
||||||
|
print(f"请求失败: {e}") |
||||||
|
return None |
||||||
|
|
||||||
|
def main(): |
||||||
|
# 请在这里输入您的API密钥 |
||||||
|
API_KEY = "YOUR_API_KEY_HERE" |
||||||
|
|
||||||
|
if API_KEY == "YOUR_API_KEY_HERE": |
||||||
|
print("请先获取OpenWeatherMap API密钥:") |
||||||
|
print("1. 访问 https://openweathermap.org/api") |
||||||
|
print("2. 注册免费账户") |
||||||
|
print("3. 获取API密钥并替换代码中的 'YOUR_API_KEY_HERE'") |
||||||
|
print("\n免费套餐:每天60次调用") |
||||||
|
return |
||||||
|
|
||||||
|
# 查询城市(可以修改为您所在的城市) |
||||||
|
city = input("请输入城市名称(英文,如 Beijing, Shanghai, New York): ").strip() |
||||||
|
if not city: |
||||||
|
city = "Beijing" |
||||||
|
|
||||||
|
print(f"\n正在查询 {city} 的天气...") |
||||||
|
|
||||||
|
weather_data = get_weather(API_KEY, city) |
||||||
|
|
||||||
|
if weather_data: |
||||||
|
print(f"\n=== {weather_data['name']} 天气 ===") |
||||||
|
print(f"温度: {weather_data['main']['temp']}°C") |
||||||
|
print(f"体感温度: {weather_data['main']['feels_like']}°C") |
||||||
|
print(f"天气: {weather_data['weather'][0]['description']}") |
||||||
|
print(f"湿度: {weather_data['main']['humidity']}%") |
||||||
|
print(f"风速: {weather_data['wind']['speed']} m/s") |
||||||
|
print(f"气压: {weather_data['main']['pressure']} hPa") |
||||||
|
else: |
||||||
|
print("无法获取天气数据") |
||||||
|
|
||||||
|
if __name__ == "__main__": |
||||||
|
main() |
||||||
@ -0,0 +1,110 @@ |
|||||||
|
package com.claudecode.command; |
||||||
|
|
||||||
|
import com.claudecode.core.AgentLoop; |
||||||
|
import com.claudecode.tool.ToolContext; |
||||||
|
|
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
/** |
||||||
|
* 命令抽象基类 —— 消除 54 个命令实现中的重复模式。 |
||||||
|
* <p> |
||||||
|
* 提供: |
||||||
|
* <ul> |
||||||
|
* <li>{@link #args(String)} — 安全解析参数</li> |
||||||
|
* <li>{@link #requireAgentLoop(CommandContext)} — null 检查并返回错误</li> |
||||||
|
* <li>{@link #toolCtx(CommandContext)} — 快速获取 ToolContext</li> |
||||||
|
* <li>{@link #success(String)}, {@link #error(String)}, {@link #warning(String)} — 格式化消息</li> |
||||||
|
* <li>默认 {@link #aliases()} 返回空列表</li> |
||||||
|
* </ul> |
||||||
|
* |
||||||
|
* 子类只需实现 {@link #name()}, {@link #description()}, {@link #execute(String, CommandContext)}。 |
||||||
|
* 可选覆盖 {@link #aliases()}。 |
||||||
|
*/ |
||||||
|
public abstract class BaseSlashCommand implements SlashCommand { |
||||||
|
|
||||||
|
@Override |
||||||
|
public List<String> aliases() { |
||||||
|
return List.of(); |
||||||
|
} |
||||||
|
|
||||||
|
// ==================== 参数解析 ====================
|
||||||
|
|
||||||
|
/** |
||||||
|
* 安全解析命令参数(null → 空字符串,去首尾空白)。 |
||||||
|
*/ |
||||||
|
protected String args(String raw) { |
||||||
|
return CommandUtils.parseArgs(raw); |
||||||
|
} |
||||||
|
|
||||||
|
// ==================== 上下文访问 ====================
|
||||||
|
|
||||||
|
/** |
||||||
|
* 检查 AgentLoop 是否可用。如果为 null,返回错误消息;否则返回 null。 |
||||||
|
* 典型用法: |
||||||
|
* <pre> |
||||||
|
* AgentLoop loop = requireAgentLoop(context); |
||||||
|
* if (loop == null) return noSession(); |
||||||
|
* </pre> |
||||||
|
*/ |
||||||
|
protected AgentLoop requireAgentLoop(CommandContext context) { |
||||||
|
return context.agentLoop(); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 标准 "无会话" 错误消息。 |
||||||
|
*/ |
||||||
|
protected String noSession() { |
||||||
|
return CommandUtils.error("No active session"); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 快速获取 ToolContext。如果 agentLoop 为 null 则返回 null。 |
||||||
|
*/ |
||||||
|
protected ToolContext toolCtx(CommandContext context) { |
||||||
|
return context.agentLoop() != null ? context.agentLoop().getToolContext() : null; |
||||||
|
} |
||||||
|
|
||||||
|
// ==================== 格式化输出 ====================
|
||||||
|
|
||||||
|
/** |
||||||
|
* 成功消息(绿色 ✓)。 |
||||||
|
*/ |
||||||
|
protected String success(String message) { |
||||||
|
return CommandUtils.success(message); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 错误消息(红色 ✗)。 |
||||||
|
*/ |
||||||
|
protected String error(String message) { |
||||||
|
return CommandUtils.error(message); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 警告消息(黄色 ⚠)。 |
||||||
|
*/ |
||||||
|
protected String warning(String message) { |
||||||
|
return CommandUtils.warning(message); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 信息消息(蓝色 ℹ)。 |
||||||
|
*/ |
||||||
|
protected String info(String message) { |
||||||
|
return CommandUtils.info(message); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 格式化标题行。 |
||||||
|
*/ |
||||||
|
protected String header(String emoji, String title) { |
||||||
|
return CommandUtils.header(emoji, title); |
||||||
|
} |
||||||
|
|
||||||
|
/** |
||||||
|
* 格式化子标题。 |
||||||
|
*/ |
||||||
|
protected String subtitle(String title) { |
||||||
|
return CommandUtils.subtitle(title); |
||||||
|
} |
||||||
|
} |
||||||
Loading…
Reference in new issue