ethan-skill 1.14.0 → 1.15.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.
@@ -61,7 +61,7 @@ const mockPipeline = {
61
61
  (0, vitest_1.expect)(prompt).toContain('Agent 阵容');
62
62
  (0, vitest_1.expect)(prompt).toContain('Architect Agent');
63
63
  (0, vitest_1.expect)(prompt).toContain('Code Agent');
64
- (0, vitest_1.expect)(prompt).toContain('Review Agent');
64
+ // dev-workflow uses architect+coder+pm (no reviewer/qa in this pipeline)
65
65
  });
66
66
  (0, vitest_1.it)('contains collaboration protocol', () => {
67
67
  (0, vitest_1.expect)(prompt).toContain('协作协议');
@@ -70,7 +70,6 @@ const mockPipeline = {
70
70
  (0, vitest_1.it)('contains step headings with agent names', () => {
71
71
  (0, vitest_1.expect)(prompt).toContain('🏗️ Architect Agent');
72
72
  (0, vitest_1.expect)(prompt).toContain('💻 Code Agent');
73
- (0, vitest_1.expect)(prompt).toContain('🔍 Review Agent');
74
73
  });
75
74
  (0, vitest_1.it)('contains handoff markers between different agents', () => {
76
75
  (0, vitest_1.expect)(prompt).toContain('Handoff →');
@@ -97,8 +96,8 @@ const mockPipeline = {
97
96
  });
98
97
  });
99
98
  (0, vitest_1.describe)('BUILT_IN_AGENTS', () => {
100
- (0, vitest_1.it)('has 5 agents', () => {
101
- (0, vitest_1.expect)(presets_1.BUILT_IN_AGENTS).toHaveLength(5);
99
+ (0, vitest_1.it)('has 8 agents', () => {
100
+ (0, vitest_1.expect)(presets_1.BUILT_IN_AGENTS).toHaveLength(8);
102
101
  });
103
102
  (0, vitest_1.it)('all agents have required fields', () => {
104
103
  for (const agent of presets_1.BUILT_IN_AGENTS) {
@@ -130,7 +129,7 @@ const mockPipeline = {
130
129
  const routing = (0, presets_1.buildSkillRouting)(presets_1.BUILT_IN_AGENTS);
131
130
  (0, vitest_1.expect)(routing['requirement-understanding']).toBe('architect');
132
131
  (0, vitest_1.expect)(routing['implementation']).toBe('coder');
133
- (0, vitest_1.expect)(routing['code-review']).toBe('reviewer');
132
+ (0, vitest_1.expect)(routing['code-review']).toBe('qa'); // qa overrides reviewer (last-writer-wins)
134
133
  (0, vitest_1.expect)(routing['deployment']).toBe('devops');
135
134
  (0, vitest_1.expect)(routing['debug']).toBe('pm');
136
135
  });
@@ -139,7 +138,7 @@ const mockPipeline = {
139
138
  (0, vitest_1.it)('returns only agents participating in the pipeline', () => {
140
139
  const routing = (0, presets_1.buildSkillRouting)(presets_1.BUILT_IN_AGENTS);
141
140
  const agents = (0, presets_1.getAgentsForPipeline)(['requirement-understanding', 'implementation', 'code-review'], presets_1.BUILT_IN_AGENTS, routing);
142
- (0, vitest_1.expect)(agents.map((a) => a.id)).toEqual(['architect', 'coder', 'reviewer']);
141
+ (0, vitest_1.expect)(agents.map((a) => a.id)).toEqual(['architect', 'coder', 'qa']);
143
142
  });
144
143
  (0, vitest_1.it)('deduplicates consecutive same-agent steps', () => {
145
144
  const routing = (0, presets_1.buildSkillRouting)(presets_1.BUILT_IN_AGENTS);
@@ -1 +1 @@
1
- {"version":3,"file":"orchestrator.test.js","sourceRoot":"","sources":["../../src/agents/orchestrator.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"orchestrator.test.js","sourceRoot":"","sources":["../../src/agents/orchestrator.test.ts"],"names":[],"mappings":"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"}
package/dist/cli/index.js CHANGED
@@ -752,6 +752,32 @@ program
752
752
  console.log(` ✅ claude-code → 工作流: ${cmdDir}/ethan-{cmd}.md × ${WORKFLOW_SLASH_COMMANDS.length}`);
753
753
  console.log(` 使用方式:在 Claude Code 聊天中输入 /ethan-commit、/ethan-auto 等`);
754
754
  console.log(` ⚡ 动态注入:提示词自动注入对话,无需复制粘贴`);
755
+ // ── Agent 命令(Claude Code 专属:每个 Agent 一个 .md 文件)─────────────
756
+ const { getActiveAgents } = await Promise.resolve().then(() => __importStar(require('../agents/index')));
757
+ const agents = getActiveAgents(dir);
758
+ // ethan-agent-list.md
759
+ const agentListContent = `---\ndescription: "Ethan — 查看所有可用 Agent 及其 Skill 分配"\n---\n\n` +
760
+ `$(ethan agent list 2>/dev/null)\n`;
761
+ fs.writeFileSync(path.join(outDir, 'ethan-agent-list.md'), agentListContent, 'utf-8');
762
+ // ethan-agent-run.md
763
+ const agentRunContent = `---\ndescription: "Ethan — Multi-Agent 编排:将任务分配给多个专业 Agent 协作执行"\n---\n\n` +
764
+ `$(![ -n "$ARGUMENTS" ] && ethan agent run $ARGUMENTS --no-copy 2>/dev/null || printf "## Ethan Multi-Agent 编排\\n\\n用法: /ethan-agent-run <pipeline> -c \\"任务描述\\"\\n\\n示例:\\n /ethan-agent-run dev-workflow -c \\"实现用户登录功能\\"\\n\\n可用模式: sequential / parallel / review-loop / consensus")\n`;
765
+ fs.writeFileSync(path.join(outDir, 'ethan-agent-run.md'), agentRunContent, 'utf-8');
766
+ // ethan-agent-new.md
767
+ const agentNewContent = `---\ndescription: "Ethan — 创建自定义 Agent,生成 .ethan/agents/<id>.yaml"\n---\n\n` +
768
+ `$(ethan agent new $ARGUMENTS 2>/dev/null)\n`;
769
+ fs.writeFileSync(path.join(outDir, 'ethan-agent-new.md'), agentNewContent, 'utf-8');
770
+ // 每个内置 Agent 生成独立快捷命令
771
+ let agentFileCount = 3;
772
+ for (const agent of agents) {
773
+ const agentSkillList = agent.skillIds.slice(0, 8).join('、') + (agent.skillIds.length > 8 ? '...' : '');
774
+ const agentContent = `---\ndescription: "Ethan — ${agent.emoji} ${agent.name}:${agent.role}"\n---\n\n` +
775
+ `$(![ -n "$ARGUMENTS" ] && ethan agent run --no-copy -c "$ARGUMENTS" 2>/dev/null || printf "## ${agent.emoji} ${agent.name}\\n\\n**职责**: ${agent.role}\\n\\n**负责 Skill**: ${agentSkillList}\\n\\n用法: /ethan-agent-${agent.id} <任务描述>")\n`;
776
+ fs.writeFileSync(path.join(outDir, `ethan-agent-${agent.id}.md`), agentContent, 'utf-8');
777
+ agentFileCount++;
778
+ total++;
779
+ }
780
+ console.log(` ✅ claude-code → Agents: ${cmdDir}/ethan-agent-*.md × ${agentFileCount}(含 ${agents.length} 个 Agent 快捷键)`);
755
781
  }
756
782
  else {
757
783
  // CodeBuddy:静态提示词(各 /ethan-xxx 命令文件)
@@ -797,14 +823,28 @@ program
797
823
  continue: 'Continue(@ethan 触发)',
798
824
  lingma: '灵码(@ethan 触发)',
799
825
  };
826
+ // ── Agent 速查表章节 ─────────────────────────────────────────────────
827
+ const { getActiveAgents: getAgentsForOther } = await Promise.resolve().then(() => __importStar(require('../agents/index')));
828
+ const otherAgents = getAgentsForOther(dir);
829
+ const agentRows = otherAgents
830
+ .map((a) => `| \`/ethan-agent-${a.id}\` | \`@ethan agent ${a.id}\` | ${a.emoji} ${a.name} | Agent | ${a.role} |`)
831
+ .join('\n');
832
+ const agentSection = `## Multi-Agent 命令\n\n` +
833
+ `| Slash 命令 | @ethan 形式 | Agent | 类型 | 职责 |\n` +
834
+ `|-----------|------------|-------|------|------|\n` +
835
+ `| \`/ethan-agent-list\` | \`@ethan agent list\` | — | Agent | 查看所有可用 Agent |\n` +
836
+ `| \`/ethan-agent-run\` | \`@ethan agent run\` | — | Agent | Multi-Agent 编排执行 |\n` +
837
+ `| \`/ethan-agent-new\` | \`@ethan agent new\` | — | Agent | 创建自定义 Agent |\n` +
838
+ `${agentRows}\n`;
800
839
  const content = `# Ethan Slash 命令速查表 — ${platformLabel[p] ?? p}\n\n` +
801
840
  `> 生成时间:${new Date().toISOString()}\n\n` +
802
- `## Skills 命令(24 个)\n\n` +
841
+ `## Skills 命令(${skills.length} 个)\n\n` +
803
842
  `| Slash 命令 | @ethan 形式 | Skill 名称 | 类型 | 说明 |\n` +
804
843
  `|-----------|------------|-----------|------|------|\n` +
805
844
  `${skillRows}\n\n` +
806
845
  `## 工作流命令\n\n` +
807
846
  `${wfSections}\n\n` +
847
+ `${agentSection}\n` +
808
848
  `## 快速示例\n\n` +
809
849
  `\`\`\`\n` +
810
850
  `/ethan-code-review # Skill:代码审查\n` +
@@ -812,7 +852,8 @@ program
812
852
  `/ethan-commit # 工作流:生成提交信息\n` +
813
853
  `/ethan-review # 工作流:Code Review\n` +
814
854
  `/ethan-auto # 工作流:Auto-Pilot 超级 Prompt\n` +
815
- `/ethan-workflow-start # 工作流:启动有状态工作流\n` +
855
+ `/ethan-agent-run # Agent:Multi-Agent 协作编排\n` +
856
+ `/ethan-agent-architect # Agent:架构师 Agent 直接对话\n` +
816
857
  `\`\`\`\n`;
817
858
  const destFile = path.join(outDir, 'ethan-commands.md');
818
859
  fs.writeFileSync(destFile, content, 'utf-8');
@@ -1267,7 +1308,27 @@ program
1267
1308
  const nodeOk = nodeMajor >= 18;
1268
1309
  console.log(`\n[环境检查]`);
1269
1310
  console.log(` Node.js: v${nodeVersion} ${nodeOk ? '✅' : '❌ (需要 Node.js >= 18)'}`);
1270
- // 2. MCP SDK check
1311
+ // 2. Windows 专项检查
1312
+ if (process.platform === 'win32') {
1313
+ console.log('\n[Windows 环境检查]');
1314
+ // 检查 PowerShell 执行策略
1315
+ try {
1316
+ const psPolicy = (0, child_process_1.spawnSync)('powershell', ['-Command', 'Get-ExecutionPolicy'], { encoding: 'utf-8' });
1317
+ const policy = (psPolicy.stdout ?? '').trim();
1318
+ const policyOk = !['Restricted', 'AllSigned'].includes(policy);
1319
+ console.log(` PowerShell 执行策略: ${policy} ${policyOk ? '✅' : '⚠️ 需设置(Set-ExecutionPolicy RemoteSigned -Scope CurrentUser)'}`);
1320
+ }
1321
+ catch { /* PowerShell not available */ }
1322
+ // 检查 npm 全局路径是否在 PATH 中
1323
+ const npmGlobal = (0, child_process_1.spawnSync)('npm', ['config', 'get', 'prefix'], { encoding: 'utf-8', shell: true });
1324
+ const npmPrefix = (npmGlobal.stdout ?? '').trim();
1325
+ if (npmPrefix) {
1326
+ const inPath = (process.env.PATH ?? '').includes(npmPrefix);
1327
+ console.log(` npm global prefix: ${npmPrefix} ${inPath ? '✅ (在 PATH 中)' : '⚠️ 不在 PATH 中(需手动添加)'}`);
1328
+ }
1329
+ console.log(` UTF-8 编码: ${process.env.CHCP === '65001' || process.env.LC_ALL?.includes('UTF') ? '✅' : '⚠️ 建议 chcp 65001'}`);
1330
+ }
1331
+ // 3. MCP SDK check
1271
1332
  const sdkOk = fs.existsSync(path.join(__dirname, '../../node_modules/@modelcontextprotocol/sdk'));
1272
1333
  console.log(` @modelcontextprotocol/sdk: ${sdkOk ? '✅ 已安装' : '❌ 未安装'}`);
1273
1334
  // 3. Rules files status
@@ -1471,6 +1532,166 @@ program
1471
1532
  console.log(`\n文件路径:${configPath}`);
1472
1533
  console.log('\n💡 提示:现在运行 ethan install --platform <platform> 将使用此配置\n');
1473
1534
  });
1535
+ // ─── setup 命令(零门槛一键安装向导) ────────────────────────────────────────
1536
+ // 面向产品、测试等非技术用户,自动检测环境,提供最简安装体验
1537
+ program
1538
+ .command('setup')
1539
+ .description('一键安装向导:自动检测编辑器,为非技术用户提供最简配置体验')
1540
+ .option('--role <role>', '用户角色:dev(开发)/ pm(产品)/ qa(测试)/ design(设计)')
1541
+ .option('--platform <platform>', '强制指定平台(跳过自动检测)')
1542
+ .option('--lang <lang>', '界面语言:zh(默认)/ en')
1543
+ .option('-y, --yes', '跳过所有确认,使用推荐配置')
1544
+ .action(async (options) => {
1545
+ const readline = await Promise.resolve().then(() => __importStar(require('readline')));
1546
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
1547
+ const ask = (q, def) => new Promise((resolve) => rl.question(def !== undefined ? `${q} [${def}]: ` : `${q}: `, (a) => resolve(a.trim() || def || '')));
1548
+ const isEn = options.lang === 'en';
1549
+ const isAuto = !!options.yes;
1550
+ const t = {
1551
+ title: isEn ? 'Ethan Setup Wizard' : 'Ethan 快速安装向导',
1552
+ welcome: isEn
1553
+ ? 'This wizard will configure Ethan for your editor in 3 steps.'
1554
+ : '3 步完成配置,无需任何编程知识。',
1555
+ step1: isEn ? '[1/3] Detecting your editor...' : '[1/3] 检测你的编辑器...',
1556
+ step2: isEn ? '[2/3] Configuring your role...' : '[2/3] 配置你的角色...',
1557
+ step3: isEn ? '[3/3] Generating slash commands...' : '[3/3] 生成编辑器快捷指令...',
1558
+ done: isEn ? 'Setup complete!' : '安装完成!',
1559
+ };
1560
+ console.log(`\n${'═'.repeat(52)}`);
1561
+ console.log(` ${t.title}`);
1562
+ console.log(` ${t.welcome}`);
1563
+ console.log(`${'═'.repeat(52)}\n`);
1564
+ // ── 步骤 1:自动检测编辑器 ─────────────────────────────────────────────
1565
+ console.log(t.step1);
1566
+ // 检测逻辑:查找 .cursor / .vscode / .windsurf 等目录
1567
+ const detectedPlatforms = [];
1568
+ const checkDir = (d) => fs.existsSync(path.join(process.cwd(), d));
1569
+ if (checkDir('.cursor'))
1570
+ detectedPlatforms.push('cursor');
1571
+ if (checkDir('.vscode') || checkDir('.github'))
1572
+ detectedPlatforms.push('copilot');
1573
+ if (checkDir('.windsurf'))
1574
+ detectedPlatforms.push('windsurf');
1575
+ if (checkDir('.codebuddy'))
1576
+ detectedPlatforms.push('codebuddy');
1577
+ if (checkDir('.claude'))
1578
+ detectedPlatforms.push('claude-code');
1579
+ if (checkDir('.continue'))
1580
+ detectedPlatforms.push('continue');
1581
+ // 如果没有检测到任何编辑器,给出选项列表
1582
+ const ALL_PLATFORMS_SETUP = ['claude-code', 'cursor', 'copilot', 'codebuddy', 'windsurf', 'zed', 'jetbrains', 'continue', 'cline', 'lingma'];
1583
+ let chosenPlatform = options.platform ?? '';
1584
+ if (!chosenPlatform) {
1585
+ if (detectedPlatforms.length === 1 && isAuto) {
1586
+ chosenPlatform = detectedPlatforms[0];
1587
+ console.log(` ✅ 检测到 ${chosenPlatform},将自动配置`);
1588
+ }
1589
+ else if (detectedPlatforms.length > 0) {
1590
+ console.log(` 检测到以下编辑器:${detectedPlatforms.join(', ')}`);
1591
+ const detected = detectedPlatforms.join('/');
1592
+ if (isAuto) {
1593
+ chosenPlatform = detectedPlatforms[0];
1594
+ }
1595
+ else {
1596
+ const choice = await ask(isEn
1597
+ ? ` Which editor? (${ALL_PLATFORMS_SETUP.join('|')}|all)`
1598
+ : ` 选择编辑器(${ALL_PLATFORMS_SETUP.join('|')}|all)`, detectedPlatforms[0]);
1599
+ chosenPlatform = choice || detectedPlatforms[0];
1600
+ }
1601
+ }
1602
+ else {
1603
+ if (isAuto) {
1604
+ chosenPlatform = 'claude-code';
1605
+ }
1606
+ else {
1607
+ console.log(isEn ? ' No editor auto-detected. Common options:' : ' 未检测到编辑器,请选择:');
1608
+ ALL_PLATFORMS_SETUP.forEach((p, i) => console.log(` ${i + 1}. ${p}`));
1609
+ const choice = await ask(isEn ? ' Enter number or name' : ' 输入序号或名称', '1');
1610
+ const num = parseInt(choice, 10);
1611
+ chosenPlatform = (!isNaN(num) && num >= 1 && num <= ALL_PLATFORMS_SETUP.length)
1612
+ ? ALL_PLATFORMS_SETUP[num - 1]
1613
+ : (choice || 'claude-code');
1614
+ }
1615
+ }
1616
+ }
1617
+ console.log(` → 目标平台:${chosenPlatform}\n`);
1618
+ // ── 步骤 2:角色配置 ──────────────────────────────────────────────────
1619
+ console.log(t.step2);
1620
+ const ROLE_PRESETS = {
1621
+ pm: { lang: 'zh', disabledSkills: ['unit-testing', 'docker', 'cicd', 'observability', 'data-pipeline', 'ml-experiment'] },
1622
+ qa: { lang: 'zh', disabledSkills: ['docker', 'cicd', 'ml-experiment', 'green-code', 'api-mock'] },
1623
+ design: { lang: 'zh', disabledSkills: ['unit-testing', 'docker', 'cicd', 'database-optimize', 'data-pipeline', 'ml-experiment', 'observability'] },
1624
+ dev: { lang: 'zh', disabledSkills: [] },
1625
+ };
1626
+ let chosenRole = options.role ?? '';
1627
+ if (!chosenRole && !isAuto) {
1628
+ console.log(isEn ? ' Your role:' : ' 你的角色:');
1629
+ console.log(' 1. dev - 开发工程师(启用所有 36 个 Skill)');
1630
+ console.log(' 2. qa - 测试工程师(测试、审查相关 Skill)');
1631
+ console.log(' 3. pm - 产品经理(需求、设计、周报相关 Skill)');
1632
+ console.log(' 4. design - 设计师(流程、文档类 Skill)');
1633
+ const roleChoice = await ask(isEn ? ' Select (1-4)' : ' 选择(1-4)', '1');
1634
+ const roleMap = { '1': 'dev', '2': 'qa', '3': 'pm', '4': 'design' };
1635
+ chosenRole = roleMap[roleChoice] ?? roleChoice ?? 'dev';
1636
+ }
1637
+ chosenRole = chosenRole || 'dev';
1638
+ console.log(` → 角色:${chosenRole}\n`);
1639
+ const preset = ROLE_PRESETS[chosenRole] ?? ROLE_PRESETS.dev;
1640
+ // 语言选择
1641
+ let chosenLang = preset.lang;
1642
+ if (!isAuto && !options.lang) {
1643
+ const langChoice = await ask(isEn ? ' Output language (zh/en)' : ' 输出语言(zh/en)', 'zh');
1644
+ chosenLang = langChoice === 'en' ? 'en' : 'zh';
1645
+ }
1646
+ rl.close();
1647
+ // 写入 .ethanrc.json
1648
+ const existingConfig = (0, config_1.readConfig)(process.cwd());
1649
+ const newConfig = {
1650
+ ...existingConfig,
1651
+ lang: chosenLang,
1652
+ ...(preset.disabledSkills.length > 0 ? { disabledSkills: preset.disabledSkills } : {}),
1653
+ setup: { role: chosenRole, platform: chosenPlatform, setupAt: new Date().toISOString() },
1654
+ };
1655
+ (0, config_1.writeConfig)(newConfig, process.cwd());
1656
+ console.log(` ✅ .ethanrc.json 已生成(角色:${chosenRole},语言:${chosenLang})`);
1657
+ // ── 步骤 3:生成编辑器快捷指令 ───────────────────────────────────────
1658
+ console.log(`\n${t.step3}`);
1659
+ const slashPlatforms = chosenPlatform === 'all' ? 'all' : chosenPlatform;
1660
+ // 动态调用 slash 命令逻辑(通过 execSync,保持 tty)
1661
+ const { execSync } = await Promise.resolve().then(() => __importStar(require('child_process')));
1662
+ try {
1663
+ execSync(`ethan slash --platform ${slashPlatforms} --dir "${process.cwd()}"`, { stdio: 'inherit' });
1664
+ }
1665
+ catch {
1666
+ // 如果 ethan 还未在全局安装(开发模式),尝试直接调用 ts-node
1667
+ console.log(isEn ? ' Note: Run "ethan slash" manually if above failed.' : ' 提示:如以上失败,请手动运行 ethan slash。');
1668
+ }
1669
+ // ── 完成 ─────────────────────────────────────────────────────────────
1670
+ console.log(`\n${'═'.repeat(52)}`);
1671
+ console.log(` ${t.done}`);
1672
+ console.log('═'.repeat(52));
1673
+ console.log(isEn ? '\nNext steps:' : '\n下一步:');
1674
+ if (chosenPlatform === 'claude-code') {
1675
+ console.log(isEn
1676
+ ? ' 1. Restart Claude Code editor'
1677
+ : ' 1. 重启 Claude Code 编辑器');
1678
+ console.log(isEn
1679
+ ? ' 2. Type /ethan- in chat to see all commands'
1680
+ : ' 2. 在聊天中输入 /ethan- 即可看到所有快捷指令');
1681
+ }
1682
+ else {
1683
+ console.log(isEn
1684
+ ? ` 1. Open ethan-commands.md in your ${chosenPlatform} context`
1685
+ : ` 1. 将 ethan-commands.md 加入你的 ${chosenPlatform} 上下文`);
1686
+ console.log(isEn
1687
+ ? ' 2. Type /ethan-code-review or @ethan code-review to start'
1688
+ : ' 2. 输入 /ethan-code-review 或 @ethan code-review 开始使用');
1689
+ }
1690
+ console.log(isEn
1691
+ ? ' 3. Run "ethan agent run" for multi-agent collaboration'
1692
+ : ' 3. 运行 ethan agent run 体验多 Agent 协作');
1693
+ console.log('');
1694
+ });
1474
1695
  // ─── workflow 命令(有状态一键工作流) ──────────────────────────────────────
1475
1696
  const workflowCmd = program.command('workflow').description('有状态工作流执行:一键推进各阶段任务');
1476
1697
  workflowCmd
@@ -3014,36 +3235,34 @@ memoryCmd
3014
3235
  });
3015
3236
  memoryCmd
3016
3237
  .command('search <keyword>')
3017
- .description('在记忆库中搜索关键词(标题 + 内容 + 标签)')
3238
+ .description('在记忆库中全文检索(加权评分 + 片段高亮)')
3018
3239
  .option('--global', '搜索全局记忆库')
3019
- .option('--tag <tag>', '按标签过滤')
3240
+ .option('--tag <tag>', '按标签过滤(AND 语义)')
3241
+ .option('--type <type>', '按类型过滤:workflow|skill|manual|decision|knowledge')
3020
3242
  .option('-n, --limit <n>', '最多显示 N 条', '10')
3021
- .action((keyword, options) => {
3022
- const dir = getMemoryDir(!!options.global);
3023
- const entries = loadMemoryEntries(dir);
3024
- const kw = keyword.toLowerCase();
3025
- const limit = parseInt(options.limit, 10) || 10;
3026
- let results = entries.filter((e) => {
3027
- const matchKw = e.title.toLowerCase().includes(kw) ||
3028
- e.content.toLowerCase().includes(kw) ||
3029
- e.tags.some((t) => t.toLowerCase().includes(kw));
3030
- const matchTag = options.tag ? e.tags.includes(options.tag) : true;
3031
- return matchKw && matchTag;
3243
+ .action(async (keyword, options) => {
3244
+ const { searchMemory, getMemoryDir: getMemDir } = await Promise.resolve().then(() => __importStar(require('../memory/index')));
3245
+ const dir = getMemDir(!!options.global);
3246
+ const limit = parseInt(options.limit ?? '10', 10) || 10;
3247
+ const results = searchMemory(keyword, dir, {
3248
+ tags: options.tag ? [options.tag] : undefined,
3249
+ type: options.type,
3250
+ limit,
3032
3251
  });
3033
- results = results.slice(0, limit);
3034
3252
  if (results.length === 0) {
3035
3253
  console.log(`\n🔍 未找到匹配 "${keyword}" 的记忆\n`);
3254
+ console.log(' 💡 尝试更宽泛的关键词,或用 ethan memory list 查看所有记忆\n');
3036
3255
  return;
3037
3256
  }
3038
3257
  console.log(`\n🔍 找到 ${results.length} 条记忆(关键词:"${keyword}")\n`);
3039
- console.log('─'.repeat(60));
3040
- for (const e of results) {
3041
- const preview = e.content.length > 100 ? e.content.slice(0, 100) + '…' : e.content;
3042
- console.log(`\n 📌 ${e.title}`);
3043
- console.log(` ID: ${e.id} | ${e.createdAt.slice(0, 10)} | 标签:${e.tags.join(', ') || '无'}`);
3044
- console.log(` ${preview}`);
3258
+ console.log('─'.repeat(70));
3259
+ for (const { entry: e, score, matchedFields, snippet } of results) {
3260
+ console.log(`\n 📌 [${e.type}] ${e.title}`);
3261
+ console.log(` ID: ${e.id} | ${e.createdAt.slice(0, 10)} | 相关度: ${score} | 命中: ${matchedFields.join(', ')}`);
3262
+ console.log(` 标签:${e.tags.join(', ') || '无'}`);
3263
+ console.log(` 摘要:${snippet}`);
3045
3264
  }
3046
- console.log('\n' + '─'.repeat(60));
3265
+ console.log('\n' + '─'.repeat(70));
3047
3266
  console.log(`\n💡 用 ethan memory show <id> 查看完整内容\n`);
3048
3267
  });
3049
3268
  memoryCmd
@@ -5063,5 +5282,67 @@ agentCmd
5063
5282
  console.log(` ethan agent run --context "任务" # 在编排中使用此 Agent`);
5064
5283
  console.log('');
5065
5284
  });
5285
+ // ─── extension 命令(事件钩子 + Webhook 扩展)─────────────────────────────────
5286
+ const extCmd = program
5287
+ .command('extension')
5288
+ .alias('ext')
5289
+ .description('扩展管理:事件钩子、Webhook 集成、Extension SDK');
5290
+ extCmd
5291
+ .command('list')
5292
+ .description('查看当前项目的钩子和 Webhook 配置')
5293
+ .action(async () => {
5294
+ const { readExtensionsConfig } = await Promise.resolve().then(() => __importStar(require('../extension/index')));
5295
+ const cfg = readExtensionsConfig(process.cwd());
5296
+ console.log('\n🔌 Ethan 扩展配置\n');
5297
+ console.log('─'.repeat(50));
5298
+ console.log(`\n钩子文件(${cfg.hooks.length} 个):`);
5299
+ if (cfg.hooks.length === 0)
5300
+ console.log(' (无)');
5301
+ cfg.hooks.forEach((h) => console.log(` ${h.enabled ? '✅' : '⏸️ '} ${h.file}`));
5302
+ console.log(`\nWebhook(${cfg.webhooks.length} 个):`);
5303
+ if (cfg.webhooks.length === 0)
5304
+ console.log(' (无)');
5305
+ cfg.webhooks.forEach((w) => console.log(` ${w.enabled ? '✅' : '⏸️ '} ${w.url} [${w.events.join(', ')}]`));
5306
+ console.log('');
5307
+ });
5308
+ extCmd
5309
+ .command('hook-init [name]')
5310
+ .description('在 .ethan/hooks/ 生成示例钩子文件')
5311
+ .action(async (name) => {
5312
+ const { generateHookTemplate } = await Promise.resolve().then(() => __importStar(require('../extension/index')));
5313
+ const hookName = name || 'my-hook';
5314
+ const file = generateHookTemplate(process.cwd(), hookName);
5315
+ console.log(`\n✅ 钩子文件已生成:${file}`);
5316
+ console.log('\n支持的事件:before:skill | after:skill | before:pipeline | after:pipeline | workflow:done | memory:save\n');
5317
+ });
5318
+ extCmd
5319
+ .command('webhook-add <url>')
5320
+ .description('添加 Webhook(在工作流事件后推送通知)')
5321
+ .option('--events <events>', '监听事件(逗号分隔)', 'after:skill,workflow:done')
5322
+ .option('--secret <secret>', 'HMAC 签名密钥(可选)')
5323
+ .action(async (url, opts) => {
5324
+ const { readExtensionsConfig, writeExtensionsConfig } = await Promise.resolve().then(() => __importStar(require('../extension/index')));
5325
+ const cfg = readExtensionsConfig(process.cwd());
5326
+ const events = opts.events.split(',').map((e) => e.trim());
5327
+ cfg.webhooks.push({ url, events, secret: opts.secret, enabled: true, headers: {} });
5328
+ writeExtensionsConfig(cfg, process.cwd());
5329
+ console.log(`\n✅ Webhook 已添加:${url}`);
5330
+ console.log(` 监听事件:${events.join(', ')}\n`);
5331
+ });
5332
+ extCmd
5333
+ .command('webhook-remove <url>')
5334
+ .description('移除 Webhook')
5335
+ .action(async (url) => {
5336
+ const { readExtensionsConfig, writeExtensionsConfig } = await Promise.resolve().then(() => __importStar(require('../extension/index')));
5337
+ const cfg = readExtensionsConfig(process.cwd());
5338
+ const before = cfg.webhooks.length;
5339
+ cfg.webhooks = cfg.webhooks.filter((w) => w.url !== url);
5340
+ if (cfg.webhooks.length === before) {
5341
+ console.error(`\n❌ 未找到 Webhook: ${url}\n`);
5342
+ process.exit(1);
5343
+ }
5344
+ writeExtensionsConfig(cfg, process.cwd());
5345
+ console.log(`\n✅ Webhook 已移除:${url}\n`);
5346
+ });
5066
5347
  program.parse(process.argv);
5067
5348
  //# sourceMappingURL=index.js.map