ethan-skill 1.10.5 → 1.11.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.
- package/dist/cli/index.js +245 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/context/builder.d.ts +7 -0
- package/dist/context/builder.d.ts.map +1 -1
- package/dist/context/builder.js +31 -0
- package/dist/context/builder.js.map +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +212 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/skills/25-spec-proposal.d.ts +3 -0
- package/dist/skills/25-spec-proposal.d.ts.map +1 -0
- package/dist/skills/25-spec-proposal.js +157 -0
- package/dist/skills/25-spec-proposal.js.map +1 -0
- package/dist/skills/26-spec-review.d.ts +3 -0
- package/dist/skills/26-spec-review.d.ts.map +1 -0
- package/dist/skills/26-spec-review.js +126 -0
- package/dist/skills/26-spec-review.js.map +1 -0
- package/dist/skills/index.d.ts +2 -0
- package/dist/skills/index.d.ts.map +1 -1
- package/dist/skills/index.js +9 -1
- package/dist/skills/index.js.map +1 -1
- package/dist/skills/pipeline.d.ts.map +1 -1
- package/dist/skills/pipeline.js +12 -0
- package/dist/skills/pipeline.js.map +1 -1
- package/dist/spec/index.d.ts +57 -0
- package/dist/spec/index.d.ts.map +1 -0
- package/dist/spec/index.js +303 -0
- package/dist/spec/index.js.map +1 -0
- package/package.json +1 -1
- package/rules/claude-code/CLAUDE.md +246 -3
- package/rules/cline/.clinerules +216 -2
- package/rules/codebuddy/CODEBUDDY.md +236 -2
- package/rules/continue/.continuerules +216 -2
- package/rules/copilot/copilot-instructions.md +230 -2
- package/rules/cursor/.cursorrules +243 -2
- package/rules/cursor/smart-flow.mdc +243 -2
- package/rules/jetbrains/smart-flow.md +230 -2
- package/rules/lingma/smart-flow.md +235 -3
- package/rules/windsurf/.windsurf/rules/smart-flow.md +231 -3
- package/rules/zed/smart-flow.rules +213 -1
package/dist/cli/index.js
CHANGED
|
@@ -372,7 +372,7 @@ const WORKFLOW_SLASH_COMMANDS = [
|
|
|
372
372
|
description: '启动指定 Pipeline 的有状态工作流会话',
|
|
373
373
|
prompt: `# Ethan — 启动工作流\n\n` +
|
|
374
374
|
`我需要启动一个 Ethan 有状态工作流会话。请告诉我:\n\n` +
|
|
375
|
-
`1. 选择 Pipeline:dev-workflow | reporting | quality-workflow | full-dev-cycle | incident-response | new-feature\n` +
|
|
375
|
+
`1. 选择 Pipeline:dev-workflow | reporting | quality-workflow | full-dev-cycle | incident-response | new-feature | spec-workflow\n` +
|
|
376
376
|
`2. 描述任务上下文(如"实现用户登录功能")\n\n` +
|
|
377
377
|
`启动后,逐步执行每个 Skill 步骤,完成后用 \`ethan workflow done\` 推进。\n\n` +
|
|
378
378
|
`CLI 用法:\`ethan workflow start <pipeline> -c "任务描述"\``,
|
|
@@ -465,6 +465,54 @@ const WORKFLOW_SLASH_COMMANDS = [
|
|
|
465
465
|
`同时给出 T-shirt Size(XS/S/M/L/XL)和主要风险点。\n\n` +
|
|
466
466
|
`CLI 用法:\`ethan estimate --style hours|story-points|days\``,
|
|
467
467
|
},
|
|
468
|
+
// ── OpenSpec 集成 ────────────────────────────────────────────
|
|
469
|
+
{
|
|
470
|
+
id: 'spec-proposal',
|
|
471
|
+
name: 'Spec 变更提案',
|
|
472
|
+
category: 'OpenSpec',
|
|
473
|
+
description: '在编码前生成完整 OpenSpec 变更提案包(proposal + design + tasks + spec delta)',
|
|
474
|
+
prompt: `# Ethan — Spec Proposal\n\n` +
|
|
475
|
+
`请基于 OpenSpec 规范,为本次变更生成完整提案包。在开始编码之前,先对齐需求意图和实现范围。\n\n` +
|
|
476
|
+
`**请提供**:\n` +
|
|
477
|
+
`1. 变更描述(做什么、为什么)\n` +
|
|
478
|
+
`2. 涉及的功能模块(capability)\n\n` +
|
|
479
|
+
`**将生成文件**:\n` +
|
|
480
|
+
`- \`openspec/changes/[id]/proposal.md\`(变更提案)\n` +
|
|
481
|
+
`- \`openspec/changes/[id]/design.md\`(技术方案)\n` +
|
|
482
|
+
`- \`openspec/changes/[id]/tasks.md\`(分阶段任务)\n` +
|
|
483
|
+
`- \`openspec/changes/[id]/specs/[capability].md\`(spec delta)\n\n` +
|
|
484
|
+
`原则:**Review intent, not just code**\n\n` +
|
|
485
|
+
`CLI 用法:\`ethan spec proposal <capability> -c "变更描述"\``,
|
|
486
|
+
},
|
|
487
|
+
{
|
|
488
|
+
id: 'spec-review',
|
|
489
|
+
name: 'Spec 意图审查',
|
|
490
|
+
category: 'OpenSpec',
|
|
491
|
+
description: '对比 spec delta 与代码实现,执行意图级 Review,输出对齐矩阵和偏差报告',
|
|
492
|
+
prompt: `# Ethan — Spec Review(意图审查)\n\n` +
|
|
493
|
+
`请执行意图级 Spec Review,对照 openspec/changes/ 中的 spec delta 与代码变更:\n\n` +
|
|
494
|
+
`**审查维度**:\n` +
|
|
495
|
+
`1. 🗺️ **意图对齐矩阵**:每个 spec 需求/场景 → 对应代码位置 → ✅/⚠️/❌\n` +
|
|
496
|
+
`2. 🔴 **意图偏差(Critical)**:实现与 spec 意图相反或严重不符\n` +
|
|
497
|
+
`3. 🟡 **遗漏需求(Warning)**:spec 中有但代码未实现的场景\n` +
|
|
498
|
+
`4. 💡 **超范围实现(Info)**:代码实现了 spec 未定义的功能\n\n` +
|
|
499
|
+
`请先读取 openspec/changes/ 中最新的变更提案,再对照代码变更执行审查。\n\n` +
|
|
500
|
+
`CLI 用法:\`ethan spec review\``,
|
|
501
|
+
},
|
|
502
|
+
{
|
|
503
|
+
id: 'spec-validate',
|
|
504
|
+
name: 'Spec 规范校验',
|
|
505
|
+
category: 'OpenSpec',
|
|
506
|
+
description: '校验 openspec/ 目录结构完整性:Requirements 编号、GIVEN/WHEN/THEN 格式',
|
|
507
|
+
prompt: `# Ethan — Spec Validate\n\n` +
|
|
508
|
+
`请校验项目 openspec/ 目录的规范完整性,检查:\n\n` +
|
|
509
|
+
`- 每个 capability 是否包含 Purpose / Requirements / Scenarios 章节\n` +
|
|
510
|
+
`- Requirements 编号是否连续(REQ-001, REQ-002...)\n` +
|
|
511
|
+
`- Scenario 是否使用完整的 GIVEN/WHEN/THEN 格式\n` +
|
|
512
|
+
`- 是否存在空内容的占位模板\n\n` +
|
|
513
|
+
`输出:问题列表(按严重程度分级)+ 合格/不合格摘要\n\n` +
|
|
514
|
+
`CLI 用法:\`ethan spec validate [capability]\``,
|
|
515
|
+
},
|
|
468
516
|
];
|
|
469
517
|
program
|
|
470
518
|
.command('slash')
|
|
@@ -540,6 +588,9 @@ program
|
|
|
540
588
|
'explain': 'ethan explain $ARGUMENTS --no-copy',
|
|
541
589
|
'test-case': 'ethan test-case $ARGUMENTS --no-copy',
|
|
542
590
|
'estimate': 'ethan estimate --no-copy $ARGUMENTS',
|
|
591
|
+
'spec-proposal': 'ethan spec proposal --no-copy $ARGUMENTS',
|
|
592
|
+
'spec-review': 'ethan spec review --no-copy',
|
|
593
|
+
'spec-validate': 'ethan spec validate --no-copy $ARGUMENTS',
|
|
543
594
|
};
|
|
544
595
|
// 需要参数的命令:无参调用时显示用法说明(printf 内 \n 为换行)
|
|
545
596
|
const PIPELINE_LIST = 'dev-workflow: 需求理解->拆解->设计->实现\\n' +
|
|
@@ -547,7 +598,8 @@ program
|
|
|
547
598
|
'- new-feature: PRD->技术调研->接口->拆解->实现\\n' +
|
|
548
599
|
'- quality-workflow: 代码审查->故障排查\\n' +
|
|
549
600
|
'- reporting: 进度跟踪->任务报告->周报\\n' +
|
|
550
|
-
'- incident-response:
|
|
601
|
+
'- incident-response: 故障排查->技术调研->任务报告\\n' +
|
|
602
|
+
'- spec-workflow: Spec提案->方案设计->任务拆解->实现->意图审查';
|
|
551
603
|
const SLASH_USAGE_FALLBACKS = {
|
|
552
604
|
'auto': '## Ethan Auto-Pilot — 缺少参数\\n\\n' +
|
|
553
605
|
'用法: /ethan-auto <pipeline> [-c 任务描述]\\n\\n' +
|
|
@@ -3547,5 +3599,196 @@ skillIds:
|
|
|
3547
3599
|
console.log(`\n✅ 自定义 Pipeline 模板已生成:${filePath}`);
|
|
3548
3600
|
console.log(`\n💡 编辑后运行:ethan workflow start ${options.name} -c "任务描述"\n`);
|
|
3549
3601
|
});
|
|
3602
|
+
// ─── spec 命令组 ─────────────────────────────────────────────────────────────
|
|
3603
|
+
const specCmd = program.command('spec').description('OpenSpec 规范驱动开发工具集');
|
|
3604
|
+
specCmd
|
|
3605
|
+
.command('init <capability>')
|
|
3606
|
+
.description('初始化 openspec/specs/[capability]/spec.md 规范文件')
|
|
3607
|
+
.option('-d, --dir <dir>', '项目目录', process.cwd())
|
|
3608
|
+
.action(async (capability, options) => {
|
|
3609
|
+
const { writeSpecFile, specTemplate } = await Promise.resolve().then(() => __importStar(require('../spec/index')));
|
|
3610
|
+
const filePath = writeSpecFile(capability, specTemplate(capability), options.dir);
|
|
3611
|
+
console.log(`\n✅ Spec 文件已创建:${filePath}`);
|
|
3612
|
+
console.log(`\n💡 编辑文件填写需求和场景,再运行 ethan spec validate ${capability} 检查格式\n`);
|
|
3613
|
+
});
|
|
3614
|
+
specCmd
|
|
3615
|
+
.command('list')
|
|
3616
|
+
.description('列出所有 openspec/specs/ 下的 capability')
|
|
3617
|
+
.option('-d, --dir <dir>', '项目目录', process.cwd())
|
|
3618
|
+
.action(async (options) => {
|
|
3619
|
+
const { hasOpenSpec, listSpecs, listChanges } = await Promise.resolve().then(() => __importStar(require('../spec/index')));
|
|
3620
|
+
if (!hasOpenSpec(options.dir)) {
|
|
3621
|
+
console.log('\n⚠️ 当前项目未检测到 openspec/ 目录。');
|
|
3622
|
+
console.log('运行 ethan spec init <capability> 初始化第一个 spec 文件。\n');
|
|
3623
|
+
return;
|
|
3624
|
+
}
|
|
3625
|
+
const specs = listSpecs(options.dir);
|
|
3626
|
+
const changes = listChanges(options.dir);
|
|
3627
|
+
console.log('\n📋 OpenSpec 规范目录\n');
|
|
3628
|
+
if (specs.length === 0) {
|
|
3629
|
+
console.log(' (openspec/specs/ 暂无 spec 文件)');
|
|
3630
|
+
}
|
|
3631
|
+
else {
|
|
3632
|
+
for (const spec of specs) {
|
|
3633
|
+
const lines = spec.content.split('\n').filter(Boolean);
|
|
3634
|
+
const reqCount = (spec.content.match(/### REQ-/g) || []).length;
|
|
3635
|
+
const scenCount = (spec.content.match(/### Scenario/g) || []).length;
|
|
3636
|
+
console.log(` 📄 ${spec.capability} (${reqCount} 需求, ${scenCount} 场景)`);
|
|
3637
|
+
if (lines[0])
|
|
3638
|
+
console.log(` ${lines[0].replace(/^#+\s*/, '')}`);
|
|
3639
|
+
}
|
|
3640
|
+
}
|
|
3641
|
+
console.log(`\n📁 变更提案:${changes.length} 个`);
|
|
3642
|
+
for (const c of changes.slice(0, 5)) {
|
|
3643
|
+
const title = c.proposalContent?.split('\n').find((l) => l.startsWith('# '))?.replace('# ', '') || c.id;
|
|
3644
|
+
console.log(` 📝 ${c.id} ${title}`);
|
|
3645
|
+
}
|
|
3646
|
+
console.log('');
|
|
3647
|
+
});
|
|
3648
|
+
specCmd
|
|
3649
|
+
.command('show <capability>')
|
|
3650
|
+
.description('显示指定 capability 的 spec.md 内容')
|
|
3651
|
+
.option('-d, --dir <dir>', '项目目录', process.cwd())
|
|
3652
|
+
.action(async (capability, options) => {
|
|
3653
|
+
const { listSpecs } = await Promise.resolve().then(() => __importStar(require('../spec/index')));
|
|
3654
|
+
const specs = listSpecs(options.dir);
|
|
3655
|
+
const spec = specs.find((s) => s.capability === capability);
|
|
3656
|
+
if (!spec) {
|
|
3657
|
+
console.error(`\n❌ 未找到 capability: ${capability}`);
|
|
3658
|
+
console.error(`可用:${specs.map((s) => s.capability).join(', ') || '(无)'}\n`);
|
|
3659
|
+
process.exit(1);
|
|
3660
|
+
}
|
|
3661
|
+
console.log(`\n📄 ${capability}\n\n${spec.content}\n`);
|
|
3662
|
+
});
|
|
3663
|
+
specCmd
|
|
3664
|
+
.command('validate [capability]')
|
|
3665
|
+
.description('校验 openspec/ 规范完整性(Requirements 编号、GIVEN/WHEN/THEN 格式)')
|
|
3666
|
+
.option('-d, --dir <dir>', '项目目录', process.cwd())
|
|
3667
|
+
.option('--no-copy', '不复制到剪贴板', false)
|
|
3668
|
+
.action(async (capability, options) => {
|
|
3669
|
+
const { hasOpenSpec, listSpecs } = await Promise.resolve().then(() => __importStar(require('../spec/index')));
|
|
3670
|
+
if (!hasOpenSpec(options.dir)) {
|
|
3671
|
+
console.error('\n❌ 当前项目未检测到 openspec/ 目录。\n');
|
|
3672
|
+
process.exit(1);
|
|
3673
|
+
}
|
|
3674
|
+
const specs = listSpecs(options.dir);
|
|
3675
|
+
const filtered = capability ? specs.filter((s) => s.capability === capability) : specs;
|
|
3676
|
+
if (filtered.length === 0) {
|
|
3677
|
+
console.error(capability ? `\n❌ 未找到 capability: ${capability}\n` : '\n⚠️ openspec/specs/ 下没有任何 spec 文件\n');
|
|
3678
|
+
process.exit(1);
|
|
3679
|
+
}
|
|
3680
|
+
let totalIssues = 0;
|
|
3681
|
+
for (const spec of filtered) {
|
|
3682
|
+
const issues = [];
|
|
3683
|
+
const content = spec.content;
|
|
3684
|
+
if (!content.includes('## Purpose') && !content.includes('## 用途'))
|
|
3685
|
+
issues.push('缺少 ## Purpose 章节');
|
|
3686
|
+
if (!content.includes('## Requirements') && !content.includes('## 需求'))
|
|
3687
|
+
issues.push('缺少 ## Requirements 章节');
|
|
3688
|
+
if (!content.includes('## Scenarios') && !content.includes('## 场景'))
|
|
3689
|
+
issues.push('缺少 ## Scenarios 章节');
|
|
3690
|
+
const gwtRegex = /GIVEN[\s\S]*?WHEN[\s\S]*?THEN/i;
|
|
3691
|
+
if (content.includes('Scenario') && !gwtRegex.test(content))
|
|
3692
|
+
issues.push('存在 Scenario 但未使用 GIVEN/WHEN/THEN 格式');
|
|
3693
|
+
totalIssues += issues.length;
|
|
3694
|
+
const icon = issues.length === 0 ? '✅' : issues.length <= 2 ? '⚠️ ' : '❌';
|
|
3695
|
+
console.log(`\n${icon} ${spec.capability}`);
|
|
3696
|
+
if (issues.length === 0) {
|
|
3697
|
+
console.log(' 规范结构完整,无问题。');
|
|
3698
|
+
}
|
|
3699
|
+
else {
|
|
3700
|
+
issues.forEach((issue) => console.log(` - ${issue}`));
|
|
3701
|
+
}
|
|
3702
|
+
}
|
|
3703
|
+
console.log(`\n汇总:${filtered.length} 个 capability,发现 ${totalIssues} 个问题。${totalIssues === 0 ? ' 🎉 全部通过!' : ''}\n`);
|
|
3704
|
+
});
|
|
3705
|
+
specCmd
|
|
3706
|
+
.command('proposal <capability>')
|
|
3707
|
+
.description('生成 OpenSpec 变更提案包(proposal.md + design.md + tasks.md + spec delta)')
|
|
3708
|
+
.option('-c, --context <context>', '变更描述(如"新增用户邮箱二次验证")', '')
|
|
3709
|
+
.option('-d, --dir <dir>', '项目目录', process.cwd())
|
|
3710
|
+
.option('--no-copy', '不复制到剪贴板', false)
|
|
3711
|
+
.action(async (capability, options) => {
|
|
3712
|
+
const description = options.context || capability;
|
|
3713
|
+
const { listSpecs, generateChangeId, proposalTemplate, designTemplate, tasksTemplate, specDeltaTemplate, writeChangeFiles, hasOpenSpec, } = await Promise.resolve().then(() => __importStar(require('../spec/index')));
|
|
3714
|
+
if (!hasOpenSpec(options.dir)) {
|
|
3715
|
+
console.log('\n⚠️ 未检测到 openspec/ 目录,自动初始化...');
|
|
3716
|
+
const { writeSpecFile, specTemplate } = await Promise.resolve().then(() => __importStar(require('../spec/index')));
|
|
3717
|
+
writeSpecFile(capability, specTemplate(capability), options.dir);
|
|
3718
|
+
console.log(` 已创建 openspec/specs/${capability}/spec.md\n`);
|
|
3719
|
+
}
|
|
3720
|
+
const changeId = generateChangeId();
|
|
3721
|
+
const proposal = proposalTemplate(changeId, description);
|
|
3722
|
+
const design = designTemplate(description);
|
|
3723
|
+
const tasks = tasksTemplate(description);
|
|
3724
|
+
const specDelta = specDeltaTemplate(capability, description);
|
|
3725
|
+
const changeDir = writeChangeFiles(changeId, { proposal, design, tasks, specDeltas: [{ capability, content: specDelta }] }, options.dir);
|
|
3726
|
+
const specs = listSpecs(options.dir);
|
|
3727
|
+
console.log(`\n✅ 变更提案包已生成:${changeDir}`);
|
|
3728
|
+
console.log(` 📝 proposal.md — 填写变更描述和影响范围`);
|
|
3729
|
+
console.log(` 🏗️ design.md — 填写技术方案和架构决策`);
|
|
3730
|
+
console.log(` 📋 tasks.md — 填写分阶段任务列表`);
|
|
3731
|
+
console.log(` 📄 specs/${capability}.md — 填写需求变更 delta`);
|
|
3732
|
+
console.log(`\n💡 编辑完成后运行 ethan spec review 执行意图审查\n`);
|
|
3733
|
+
console.log(` Change ID: ${changeId}`);
|
|
3734
|
+
if (specs.length > 0) {
|
|
3735
|
+
console.log(` 已有 Capability: ${specs.map((s) => s.capability).join(', ')}`);
|
|
3736
|
+
}
|
|
3737
|
+
console.log('');
|
|
3738
|
+
});
|
|
3739
|
+
specCmd
|
|
3740
|
+
.command('review')
|
|
3741
|
+
.description('意图级 Spec Review:对比 spec delta 与代码变更,输出对齐矩阵和偏差报告')
|
|
3742
|
+
.option('--change-id <id>', '指定 Change ID(不填则取最新)', '')
|
|
3743
|
+
.option('-d, --dir <dir>', '项目目录', process.cwd())
|
|
3744
|
+
.option('--no-copy', '不复制到剪贴板', false)
|
|
3745
|
+
.action(async (options) => {
|
|
3746
|
+
const { hasOpenSpec, loadLatestChange, listChanges, truncateSpec } = await Promise.resolve().then(() => __importStar(require('../spec/index')));
|
|
3747
|
+
if (!hasOpenSpec(options.dir)) {
|
|
3748
|
+
console.error('\n❌ 当前项目未检测到 openspec/ 目录。先运行 ethan spec init <capability> 初始化。\n');
|
|
3749
|
+
process.exit(1);
|
|
3750
|
+
}
|
|
3751
|
+
const changes = listChanges(options.dir);
|
|
3752
|
+
if (changes.length === 0) {
|
|
3753
|
+
console.error('\n⚠️ 未找到任何变更提案(openspec/changes/ 为空)。先运行 ethan spec proposal <capability> 创建提案。\n');
|
|
3754
|
+
process.exit(1);
|
|
3755
|
+
}
|
|
3756
|
+
const change = options.changeId
|
|
3757
|
+
? (changes.find((c) => c.id === options.changeId) ?? loadLatestChange(options.dir))
|
|
3758
|
+
: loadLatestChange(options.dir);
|
|
3759
|
+
if (!change) {
|
|
3760
|
+
console.error(`\n❌ 未找到 Change ID: ${options.changeId}\n`);
|
|
3761
|
+
process.exit(1);
|
|
3762
|
+
}
|
|
3763
|
+
const gitDiff = (0, utils_1.isGitRepo)(options.dir) ? (0, utils_1.getBranchDiff)(options.dir) : '';
|
|
3764
|
+
const truncatedDiff = gitDiff ? (0, utils_1.truncateDiff)(gitDiff, 6000) : '(非 git 仓库或无代码变更)';
|
|
3765
|
+
let prompt = `# Spec Review — ${change.id}\n\n`;
|
|
3766
|
+
if (change.proposalContent) {
|
|
3767
|
+
prompt += `## 变更提案\n\n${truncateSpec(change.proposalContent, 800)}\n\n`;
|
|
3768
|
+
}
|
|
3769
|
+
if (change.specDeltas.length > 0) {
|
|
3770
|
+
prompt += `## Spec Delta(需求变更)\n\n`;
|
|
3771
|
+
for (const delta of change.specDeltas) {
|
|
3772
|
+
prompt += `### ${delta.capability}\n\n${truncateSpec(delta.content, 600)}\n\n`;
|
|
3773
|
+
}
|
|
3774
|
+
}
|
|
3775
|
+
prompt += `## 代码变更(Diff)\n\n\`\`\`diff\n${truncatedDiff}\n\`\`\`\n\n`;
|
|
3776
|
+
prompt += `---\n\n## 意图审查任务\n\n`;
|
|
3777
|
+
prompt += `请对照上方 spec delta 与代码 diff,执行意图级 Review:\n\n`;
|
|
3778
|
+
prompt += `1. **意图对齐矩阵**\n\n | Spec 需求/场景 | 代码位置 | 状态 | 说明 |\n |---|---|---|---|\n\n`;
|
|
3779
|
+
prompt += `2. **🔴 意图偏差(Critical)**:实现与 spec 意图严重不符,必须修复\n`;
|
|
3780
|
+
prompt += `3. **🟡 遗漏需求(Warning)**:spec 有但代码未实现\n`;
|
|
3781
|
+
prompt += `4. **💡 超范围实现(Info)**:代码实现了 spec 未定义的功能\n`;
|
|
3782
|
+
prompt += `5. **审查结论**:可合并 / 需要修复 / 需要更新 spec\n\n`;
|
|
3783
|
+
prompt += `> Review intent, not just code。`;
|
|
3784
|
+
if (options.copy !== false) {
|
|
3785
|
+
copyToClipboard(prompt);
|
|
3786
|
+
console.log(`\n✅ Spec Review 提示词已复制到剪贴板(Change: ${change.id})`);
|
|
3787
|
+
console.log(' 粘贴到 AI 编辑器执行意图审查。\n');
|
|
3788
|
+
}
|
|
3789
|
+
else {
|
|
3790
|
+
console.log(prompt);
|
|
3791
|
+
}
|
|
3792
|
+
});
|
|
3550
3793
|
program.parse(process.argv);
|
|
3551
3794
|
//# sourceMappingURL=index.js.map
|