feat: skills delete — 交互式删除用户 Skill

新增 ias skills delete:
  扫描 skills/ 目录,列出所有用户 Skill
  MultiSelect TUI 选择要删除的 Skill
  确认后 remove_dir_all 物理删除
This commit is contained in:
2026-06-01 22:00:48 +08:00
parent cef8bee8ee
commit 438c52e79b
12 changed files with 1582 additions and 0 deletions
@@ -0,0 +1,99 @@
#!/usr/bin/env node
/**
* POI 搜索脚本
* 使用方法:
* node scripts/poi-search.js --keywords=肯德基 --city=北京
* 或设置环境变量: AMAP_KEY=your_key node scripts/poi-search.js --keywords=肯德基
*/
const { searchPOI } = require('../index');
// 解析命令行参数
function parseArgs() {
const args = {};
process.argv.slice(2).forEach(arg => {
if (arg.startsWith('--')) {
const [key, value] = arg.slice(2).split('=');
args[key] = value;
}
});
return args;
}
// 主函数
async function main() {
const args = parseArgs();
// 检查必需参数
if (!args.keywords) {
console.error('❌ 缺少必需参数: --keywords');
console.log('\n使用方法:');
console.log('node scripts/poi-search.js --keywords=关键词 [--city=城市] [--types=类型] [--page=页码] [--offset=每页数量]');
console.log('\n示例:');
console.log('node scripts/poi-search.js --keywords=肯德基 --city=北京 --page=1 --offset=20');
process.exit(1);
}
// 检查是否设置了 AMAP_KEY
if (!process.env.AMAP_KEY) {
console.error('❌ 请设置环境变量 AMAP_KEY');
console.log('\n示例:');
console.log('export AMAP_KEY=your_amap_key');
console.log('node scripts/poi-search.js --keywords=美食 --location=116.397428,39.90923 --radius=1000');
process.exit(1);
}
// 构建搜索参数
const params = {
keywords: args.keywords,
city: args.city || '',
types: args.types || '',
page: parseInt(args.page) || 1,
offset: parseInt(args.offset) || 10
};
// 可选参数
if (args.location) params.location = args.location;
if (args.radius) params.radius = parseInt(args.radius);
if (args.cityLimit !== undefined) params.cityLimit = args.cityLimit === 'true';
try {
const result = await searchPOI(params);
if (result && result.pois && result.pois.length > 0) {
console.log(`\n📍 共找到 ${result.count} 条结果,当前显示第 ${params.page} 页:\n`);
console.log('='.repeat(80));
result.pois.forEach((poi, index) => {
const num = (params.page - 1) * params.offset + index + 1;
console.log(`\n${num}. ${poi.name}`);
console.log(` 📍 地址: ${poi.address || '无'}`);
console.log(` 🏷️ 类型: ${poi.type}`);
console.log(` 📞 电话: ${poi.tel || '无'}`);
console.log(` 🗺️ 坐标: ${poi.location}`);
if (poi.distance) {
console.log(` 📏 距离: ${poi.distance}`);
}
});
console.log('\n' + '='.repeat(80));
// 输出分页信息
const totalPages = Math.ceil(result.count / params.offset);
console.log(`\n${params.page}/${totalPages}`);
if (params.page < totalPages) {
console.log(`\n💡 查看下一页: node scripts/poi-search.js --keywords=${params.keywords} --city=${params.city} --page=${params.page + 1}`);
}
} else {
console.log('\n❌ 未找到相关结果');
}
} catch (error) {
console.error('\n❌ 执行失败:', error.message);
process.exit(1);
}
}
// 执行主函数
main();
@@ -0,0 +1,179 @@
#!/usr/bin/env node
/**
* 路径规划脚本
* 使用方法:
* node scripts/route-planning.js --type=walking --origin=116.397428,39.90923 --destination=116.427281,39.903719
*/
const { walkingRoute, drivingRoute, ridingRoute, transitRoute, generateMapLink } = require('../index');
// 解析命令行参数
function parseArgs() {
const args = {};
process.argv.slice(2).forEach(arg => {
if (arg.startsWith('--')) {
const [key, value] = arg.slice(2).split('=');
args[key] = value;
}
});
return args;
}
// 主函数
async function main() {
const args = parseArgs();
// 检查必需参数
if (!args.type || !args.origin || !args.destination) {
console.error('❌ 缺少必需参数');
console.log('\n使用方法:');
console.log('node scripts/route-planning.js --type=路线类型 --origin=起点坐标 --destination=终点坐标 [其他参数]');
console.log('\n路线类型:');
console.log(' walking - 步行');
console.log(' driving - 驾车');
console.log(' riding - 骑行');
console.log(' transfer - 公交(需要额外提供 --city 参数)');
console.log('\n示例:');
console.log('# 步行路线');
console.log('node scripts/route-planning.js --type=walking --origin=116.397428,39.90923 --destination=116.427281,39.903719');
console.log('\n# 驾车路线(带途经点)');
console.log('node scripts/route-planning.js --type=driving --origin=116.397428,39.90923 --destination=116.427281,39.903719 --waypoints=116.410000,39.910000');
console.log('\n# 公交路线');
console.log('node scripts/route-planning.js --type=transfer --origin=116.397428,39.90923 --destination=116.427281,39.903719 --city=北京');
process.exit(1);
}
const { type, origin, destination } = args;
try {
let result = null;
let mapTaskData = [];
// 解析起点和终点坐标
const [originLng, originLat] = origin.split(',').map(Number);
const [destLng, destLat] = destination.split(',').map(Number);
// 根据类型调用不同的路径规划API
switch (type) {
case 'walking':
result = await walkingRoute({ origin, destination });
if (result && result.route) {
mapTaskData.push({
type: 'route',
routeType: 'walking',
start: [originLng, originLat],
end: [destLng, destLat],
remark: `步行路线,距离约 ${(result.route.paths[0].distance / 1000).toFixed(2)} 公里`
});
console.log('📊 路线信息:');
console.log(` 距离: ${(result.route.paths[0].distance / 1000).toFixed(2)} 公里`);
console.log(` 预计时间: ${Math.round(result.route.paths[0].duration / 60)} 分钟\n`);
}
break;
case 'driving':
const drivingParams = { origin, destination };
if (args.waypoints) {
drivingParams.waypoints = args.waypoints;
}
if (args.strategy) {
drivingParams.strategy = parseInt(args.strategy);
}
result = await drivingRoute(drivingParams);
if (result && result.route) {
const path = result.route.paths[0];
mapTaskData.push({
type: 'route',
routeType: 'driving',
start: [originLng, originLat],
end: [destLng, destLat],
remark: `驾车路线,距离约 ${(path.distance / 1000).toFixed(2)} 公里`
});
console.log('📊 路线信息:');
console.log(` 距离: ${(path.distance / 1000).toFixed(2)} 公里`);
console.log(` 预计时间: ${Math.round(path.duration / 60)} 分钟`);
console.log(` 过路费: ${path.tolls || 0}`);
console.log(` 红绿灯: ${path.traffic_lights || 0}\n`);
}
break;
case 'riding':
result = await ridingRoute({ origin, destination });
if (result && result.data) {
const path = result.data.paths[0];
mapTaskData.push({
type: 'route',
routeType: 'riding',
start: [originLng, originLat],
end: [destLng, destLat],
remark: `骑行路线,距离约 ${(path.distance / 1000).toFixed(2)} 公里`
});
console.log('📊 路线信息:');
console.log(` 距离: ${(path.distance / 1000).toFixed(2)} 公里`);
console.log(` 预计时间: ${Math.round(path.duration / 60)} 分钟\n`);
}
break;
case 'transfer':
if (!args.city) {
console.error('❌ 公交路线规划需要提供 --city 参数');
process.exit(1);
}
const transitParams = {
origin,
destination,
city: args.city,
strategy: args.strategy ? parseInt(args.strategy) : 0,
nightflag: args.nightflag === 'true'
};
result = await transitRoute(transitParams);
if (result && result.route) {
mapTaskData.push({
type: 'route',
routeType: 'transfer',
start: [originLng, originLat],
end: [destLng, destLat],
city: args.city,
remark: `公交路线,共 ${result.route.transits.length} 个方案`
});
console.log('📊 路线信息:');
console.log(` 方案数量: ${result.route.transits.length}`);
if (result.route.transits.length > 0) {
const transit = result.route.transits[0];
console.log(` 预计时间: ${Math.round(transit.duration / 60)} 分钟`);
console.log(` 费用: ${transit.cost}`);
console.log(` 步行距离: ${transit.walking_distance}\n`);
}
}
break;
default:
console.error(`❌ 不支持的路线类型: ${type}`);
process.exit(1);
}
if (result && mapTaskData.length > 0) {
// 生成地图链接
const mapLink = generateMapLink(mapTaskData);
console.log('🗺️ 地图可视化链接:');
console.log(mapLink);
console.log('\n💡 提示: 复制链接到浏览器打开即可查看路线详情\n');
} else {
console.log('\n❌ 路线规划失败,请检查参数是否正确');
}
} catch (error) {
console.error('\n❌ 执行失败:', error.message);
process.exit(1);
}
}
// 执行主函数
main();
@@ -0,0 +1,82 @@
#!/usr/bin/env node
/**
* 旅游规划脚本
* 使用方法:
* node scripts/travel-planner.js --city=北京 --interests=景点,美食,酒店 --routeType=walking
*/
const { travelPlanner } = require('../index');
// 解析命令行参数
function parseArgs() {
const args = {};
process.argv.slice(2).forEach(arg => {
if (arg.startsWith('--')) {
const [key, value] = arg.slice(2).split('=');
args[key] = value;
}
});
return args;
}
// 主函数
async function main() {
const args = parseArgs();
// 检查必需参数
if (!args.city) {
console.error('❌ 缺少必需参数: --city');
console.log('\n使用方法:');
console.log('node scripts/travel-planner.js --city=城市名 [--interests=兴趣点1,兴趣点2] [--routeType=路线类型]');
console.log('\n示例:');
console.log('node scripts/travel-planner.js --city=北京 --interests=景点,美食,酒店 --routeType=walking');
console.log('\n路线类型选项:');
console.log(' walking - 步行(默认)');
console.log(' driving - 驾车');
console.log(' riding - 骑行');
console.log(' transfer - 公交');
process.exit(1);
}
// 解析兴趣点
const interests = args.interests ? args.interests.split(',') : ['景点', '美食'];
const routeType = args.routeType || 'walking';
// 验证路线类型
const validRouteTypes = ['walking', 'driving', 'riding', 'transfer'];
if (!validRouteTypes.includes(routeType)) {
console.error(`❌ 无效的路线类型: ${routeType}`);
console.log('有效的路线类型:', validRouteTypes.join(', '));
process.exit(1);
}
try {
const result = await travelPlanner({
city: args.city,
interests: interests,
routeType: routeType
});
if (result && result.pois.length > 0) {
console.log('═'.repeat(80));
console.log('\n📊 规划数据统计:');
console.log(` 兴趣点数量: ${result.pois.length}`);
console.log(` 路线数量: ${result.mapTaskData.filter(item => item.type === 'route').length}`);
console.log(` 出行方式: ${routeType === 'walking' ? '步行' : routeType === 'driving' ? '驾车' : routeType === 'riding' ? '骑行' : '公交'}`);
console.log('\n' + '═'.repeat(80));
console.log('\n🎉 规划完成!\n');
console.log('📋 数据格式符合 MapTaskData 接口规范');
console.log(' - PoiTask: 兴趣点任务');
console.log(' - RouteTask: 路线规划任务\n');
} else {
console.log('\n❌ 未找到相关地点,请尝试更换关键词或城市。');
}
} catch (error) {
console.error('\n❌ 执行失败:', error.message);
process.exit(1);
}
}
// 执行主函数
main();