ethan-skill 1.13.0 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"presets.js","sourceRoot":"","sources":["../../src/agents/presets.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"presets.js","sourceRoot":"","sources":["../../src/agents/presets.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,8 @@ export interface AgentDefinition {
16
16
  /** 此 Agent 可执行的 Skill ID 列表 */
17
17
  skillIds: string[];
18
18
  }
19
+ /** Agent 协作模式 */
20
+ export type AgentCollaborationMode = 'sequential' | 'parallel' | 'review-loop' | 'consensus';
19
21
  export interface AgentOrchestrationOptions {
20
22
  /** 任务背景描述 */
21
23
  context: string;
@@ -25,5 +27,7 @@ export interface AgentOrchestrationOptions {
25
27
  withContext?: boolean;
26
28
  /** ProjectSnapshot 的格式化字符串(已渲染) */
27
29
  snapshot?: string;
30
+ /** Agent 协作模式,默认 sequential */
31
+ mode?: AgentCollaborationMode;
28
32
  }
29
33
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agents/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,YAAY;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW;IACX,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,yBAAyB;IACxC,aAAa;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB;IACjB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,2BAA2B;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agents/types.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,YAAY;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,mCAAmC;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,WAAW;IACX,MAAM,EAAE,MAAM,CAAC;IACf,uBAAuB;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,uCAAuC;IACvC,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,iBAAiB;AACjB,MAAM,MAAM,sBAAsB,GAC9B,YAAY,GACZ,UAAU,GACV,aAAa,GACb,WAAW,CAAC;AAEhB,MAAM,WAAW,yBAAyB;IACxC,aAAa;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,iBAAiB;IACjB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,2BAA2B;IAC3B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,mCAAmC;IACnC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+BAA+B;IAC/B,IAAI,CAAC,EAAE,sBAAsB,CAAC;CAC/B"}
package/dist/cli/index.js CHANGED
@@ -4853,6 +4853,7 @@ agentCmd
4853
4853
  .description('生成 Multi-Agent 编排 Prompt,粘贴到 AI 编辑器执行')
4854
4854
  .option('-c, --context <context>', '任务背景描述(如"实现用户登录功能")', '')
4855
4855
  .option('--lang <lang>', '输出语言:zh(默认)或 en', '')
4856
+ .option('--mode <mode>', '协作模式:sequential(默认)/ parallel / review-loop / consensus', 'sequential')
4856
4857
  .option('--with-context', '自动采集项目上下文注入到提示词')
4857
4858
  .option('--no-copy', '不复制到剪贴板,直接打印到终端')
4858
4859
  .action(async (pipelineId, options) => {
@@ -4863,6 +4864,7 @@ agentCmd
4863
4864
  const lang = (options.lang || config.lang || 'zh');
4864
4865
  const isEn = lang === 'en';
4865
4866
  const agents = getActiveAgents(process.cwd());
4867
+ const mode = (options.mode || 'sequential');
4866
4868
  // 采集项目上下文快照
4867
4869
  let snapshotBlock;
4868
4870
  if (options.withContext) {
@@ -4930,14 +4932,21 @@ agentCmd
4930
4932
  process.exit(1);
4931
4933
  }
4932
4934
  const { pipeline, skills } = resolved;
4935
+ const modeLabels = {
4936
+ sequential: isEn ? 'Sequential' : '顺序执行',
4937
+ parallel: isEn ? 'Parallel' : '并行分析',
4938
+ 'review-loop': isEn ? 'Review-Loop' : '迭代审查',
4939
+ consensus: isEn ? 'Consensus' : '共识决策',
4940
+ };
4933
4941
  const prompt = buildMultiAgentPrompt(pipeline, skills, agents, {
4934
4942
  context,
4935
4943
  lang,
4936
4944
  snapshot: snapshotBlock,
4945
+ mode,
4937
4946
  });
4938
4947
  console.log(isEn
4939
- ? `\n🤖 Multi-Agent prompt generated: ${pipeline.name} (${skills.length} steps, ${agents.length} agents)`
4940
- : `\n🤖 Multi-Agent 编排 Prompt 已生成:${pipeline.name}(${skills.length} 步,${agents.length} 个 Agent)`);
4948
+ ? `\n🤖 Multi-Agent prompt generated: ${pipeline.name} (${skills.length} steps, ${agents.length} agents, mode: ${modeLabels[mode] ?? mode})`
4949
+ : `\n🤖 Multi-Agent 编排 Prompt 已生成:${pipeline.name}(${skills.length} 步,${agents.length} 个 Agent,模式:${modeLabels[mode] ?? mode})`);
4941
4950
  console.log('─'.repeat(60));
4942
4951
  if (options.copy !== false) {
4943
4952
  if (copyToClipboard(prompt)) {
@@ -4957,5 +4966,102 @@ agentCmd
4957
4966
  : '\n💡 每个 Agent 负责执行分配给自己的步骤,通过 Handoff 摘要将产出传递给下一个 Agent。\n');
4958
4967
  trackUsageWithStreak(`agent-run-${pipeline.id}`);
4959
4968
  });
4969
+ agentCmd
4970
+ .command('new [agentId]')
4971
+ .description('交互式创建自定义 Agent,生成 .ethan/agents/<id>.yaml')
4972
+ .action(async (agentIdArg) => {
4973
+ const fs = await Promise.resolve().then(() => __importStar(require('fs')));
4974
+ const path = await Promise.resolve().then(() => __importStar(require('path')));
4975
+ const readline = await Promise.resolve().then(() => __importStar(require('readline')));
4976
+ const { getActiveAgents } = await Promise.resolve().then(() => __importStar(require('../agents/index')));
4977
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
4978
+ const ask = (q) => new Promise((resolve) => rl.question(q, (a) => resolve(a.trim())));
4979
+ console.log('\n🤖 创建自定义 Agent\n');
4980
+ console.log('─'.repeat(50));
4981
+ // 1. Agent ID
4982
+ let agentId = agentIdArg || '';
4983
+ if (!agentId) {
4984
+ agentId = await ask('Agent ID(唯一标识符,如 frontend-expert):\n> ');
4985
+ }
4986
+ if (!agentId || !/^[a-z0-9-]+$/.test(agentId)) {
4987
+ console.error('\n❌ Agent ID 只能包含小写字母、数字和连字符\n');
4988
+ rl.close();
4989
+ process.exit(1);
4990
+ }
4991
+ // 检查是否已存在同名 Agent
4992
+ const existingAgents = getActiveAgents(process.cwd());
4993
+ if (existingAgents.find((a) => a.id === agentId)) {
4994
+ const overwrite = await ask(`⚠️ Agent "${agentId}" 已存在。覆盖?(y/N):\n> `);
4995
+ if (overwrite.toLowerCase() !== 'y') {
4996
+ console.log('\n已取消。\n');
4997
+ rl.close();
4998
+ return;
4999
+ }
5000
+ }
5001
+ // 2. 中文名称
5002
+ const name = await ask('Agent 名称(中文,如 "前端专家 Agent"):\n> ') || `${agentId} Agent`;
5003
+ // 3. 英文名称
5004
+ const nameEn = await ask(`英文名称(如 "${agentId}-agent",默认 ${agentId}-agent):\n> `) || `${agentId}-agent`;
5005
+ // 4. Emoji
5006
+ const emoji = await ask('角色 Emoji(默认 🤖):\n> ') || '🤖';
5007
+ // 5. 职责描述
5008
+ const role = await ask('角色职责描述(一句话):\n> ') || `负责 ${agentId} 相关任务`;
5009
+ // 6. Skills 选择
5010
+ const allSkills = await getActiveSkills();
5011
+ console.log('\n可用 Skill ID 列表(共 ' + allSkills.length + ' 个):');
5012
+ const skillCols = Math.ceil(allSkills.length / 3);
5013
+ for (let i = 0; i < skillCols; i++) {
5014
+ const row = [0, 1, 2].map((col) => {
5015
+ const skill = allSkills[i + col * skillCols];
5016
+ return skill ? ` ${String(i + col * skillCols + 1).padStart(2, ' ')}. ${skill.id.padEnd(28, ' ')}` : '';
5017
+ }).join('');
5018
+ console.log(row);
5019
+ }
5020
+ const skillInput = await ask('\n输入 Skill ID(逗号分隔,或序号):\n> ');
5021
+ const skillIds = skillInput.split(',').map((s) => s.trim()).filter(Boolean).map((s) => {
5022
+ const num = parseInt(s, 10);
5023
+ if (!isNaN(num) && num >= 1 && num <= allSkills.length)
5024
+ return allSkills[num - 1].id;
5025
+ return s;
5026
+ });
5027
+ // 校验 skillIds
5028
+ const validIds = new Set(allSkills.map((s) => s.id));
5029
+ const invalid = skillIds.filter((id) => !validIds.has(id));
5030
+ if (invalid.length > 0) {
5031
+ console.error(`\n❌ 无效的 Skill ID:${invalid.join(', ')}\n`);
5032
+ rl.close();
5033
+ process.exit(1);
5034
+ }
5035
+ if (skillIds.length === 0) {
5036
+ console.error('\n❌ 至少需要指定一个 Skill ID\n');
5037
+ rl.close();
5038
+ process.exit(1);
5039
+ }
5040
+ rl.close();
5041
+ // 生成 YAML 内容
5042
+ const yaml = [
5043
+ `# Ethan 自定义 Agent — ${name}`,
5044
+ `id: ${agentId}`,
5045
+ `name: ${name}`,
5046
+ `nameEn: ${nameEn}`,
5047
+ `emoji: ${emoji}`,
5048
+ `role: ${role}`,
5049
+ `skillIds:`,
5050
+ ...skillIds.map((id) => ` - ${id}`),
5051
+ '',
5052
+ ].join('\n');
5053
+ // 写入文件
5054
+ const agentsDir = path.join(process.cwd(), '.ethan', 'agents');
5055
+ if (!fs.existsSync(agentsDir)) {
5056
+ fs.mkdirSync(agentsDir, { recursive: true });
5057
+ }
5058
+ const outPath = path.join(agentsDir, `${agentId}.yaml`);
5059
+ fs.writeFileSync(outPath, yaml, 'utf-8');
5060
+ console.log(`\n✅ 自定义 Agent 已创建:${outPath}`);
5061
+ console.log('\n后续用法:');
5062
+ console.log(` ethan agent show ${agentId} # 查看 Agent 详情`);
5063
+ console.log(` ethan agent run --context "任务" # 在编排中使用此 Agent`);
5064
+ console.log('');
5065
+ });
4960
5066
  program.parse(process.argv);
4961
5067
  //# sourceMappingURL=index.js.map