ethan-skill 1.5.7 → 1.5.9
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/autopilot.d.ts +2 -0
- package/dist/cli/autopilot.d.ts.map +1 -1
- package/dist/cli/autopilot.js +5 -2
- package/dist/cli/autopilot.js.map +1 -1
- package/dist/cli/index.js +118 -2
- package/dist/cli/index.js.map +1 -1
- package/dist/context/builder.d.ts +31 -0
- package/dist/context/builder.d.ts.map +1 -0
- package/dist/context/builder.js +230 -0
- package/dist/context/builder.js.map +1 -0
- package/dist/context/builder.test.d.ts +2 -0
- package/dist/context/builder.test.d.ts.map +1 -0
- package/dist/context/builder.test.js +138 -0
- package/dist/context/builder.test.js.map +1 -0
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +111 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/workflow/state.d.ts +1 -1
- package/dist/workflow/state.d.ts.map +1 -1
- package/dist/workflow/state.js +4 -1
- package/dist/workflow/state.js.map +1 -1
- package/package.json +1 -1
- package/rules/claude-code/CLAUDE.md +2 -2
- package/rules/cline/.clinerules +2 -2
- package/rules/codebuddy/CODEBUDDY.md +2 -2
- package/rules/continue/.continuerules +2 -2
- package/rules/copilot/copilot-instructions.md +2 -2
- package/rules/cursor/.cursorrules +2 -2
- package/rules/cursor/smart-flow.mdc +2 -2
- package/rules/jetbrains/smart-flow.md +2 -2
- package/rules/lingma/smart-flow.md +2 -2
- package/rules/windsurf/.windsurf/rules/smart-flow.md +2 -2
- package/rules/zed/smart-flow.rules +1 -1
package/dist/cli/autopilot.d.ts
CHANGED
|
@@ -4,9 +4,11 @@
|
|
|
4
4
|
* 粘贴到 AI 编辑器后,AI 自动链式执行所有步骤,无需手动推进
|
|
5
5
|
*/
|
|
6
6
|
import type { PipelineDefinition, SkillDefinition } from '../skills/types';
|
|
7
|
+
import type { ProjectSnapshot } from '../context/builder';
|
|
7
8
|
export interface AutopilotOptions {
|
|
8
9
|
context: string;
|
|
9
10
|
isEn?: boolean;
|
|
11
|
+
snapshot?: ProjectSnapshot;
|
|
10
12
|
}
|
|
11
13
|
/** 生成单条 Pipeline 的超级 prompt */
|
|
12
14
|
export declare function buildAutopilotPrompt(pipeline: PipelineDefinition, skills: SkillDefinition[], options: AutopilotOptions): string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autopilot.d.ts","sourceRoot":"","sources":["../../src/cli/autopilot.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"autopilot.d.ts","sourceRoot":"","sources":["../../src/cli/autopilot.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAC3E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAG1D,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,QAAQ,CAAC,EAAE,eAAe,CAAC;CAC5B;AAED,+BAA+B;AAC/B,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,kBAAkB,EAC5B,MAAM,EAAE,eAAe,EAAE,EACzB,OAAO,EAAE,gBAAgB,GACxB,MAAM,CAwHR;AAwCD,gDAAgD;AAChD,wBAAgB,gCAAgC,CAC9C,SAAS,EAAE,KAAK,CAAC;IAAE,QAAQ,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,eAAe,EAAE,CAAA;CAAE,CAAC,EAC7E,OAAO,EAAE,gBAAgB,GACxB,MAAM,CAeR"}
|
package/dist/cli/autopilot.js
CHANGED
|
@@ -7,6 +7,7 @@
|
|
|
7
7
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
8
8
|
exports.buildAutopilotPrompt = buildAutopilotPrompt;
|
|
9
9
|
exports.buildAllPipelinesAutopilotPrompt = buildAllPipelinesAutopilotPrompt;
|
|
10
|
+
const builder_1 = require("../context/builder");
|
|
10
11
|
/** 生成单条 Pipeline 的超级 prompt */
|
|
11
12
|
function buildAutopilotPrompt(pipeline, skills, options) {
|
|
12
13
|
const { context, isEn = false } = options;
|
|
@@ -60,7 +61,8 @@ ${stepsContent}
|
|
|
60
61
|
}).join('\n\n---\n\n');
|
|
61
62
|
const reportTemplate = buildReportTemplate(pipeline, skills, context, true);
|
|
62
63
|
const startCmd = `**Begin executing Step 1 now.**`;
|
|
63
|
-
|
|
64
|
+
const snapshotBlock = options.snapshot ? (0, builder_1.formatSnapshotForPrompt)(options.snapshot, true) : '';
|
|
65
|
+
return [header, snapshotBlock, '---', rules, '---', foldFormat, '---', `## Step Details`, stepsSection, '---', reportTemplate, startCmd].filter(Boolean).join('\n\n');
|
|
64
66
|
}
|
|
65
67
|
// 中文版
|
|
66
68
|
const header = `# Auto-Pilot 工作流指令
|
|
@@ -111,7 +113,8 @@ ${stepsContent}
|
|
|
111
113
|
}).join('\n\n---\n\n');
|
|
112
114
|
const reportTemplate = buildReportTemplate(pipeline, skills, context, false);
|
|
113
115
|
const startCmd = `**立即开始执行步骤 1。**`;
|
|
114
|
-
|
|
116
|
+
const snapshotBlock = options.snapshot ? (0, builder_1.formatSnapshotForPrompt)(options.snapshot, false) : '';
|
|
117
|
+
return [header, snapshotBlock, '---', rules, '---', foldFormat, '---', `## 步骤详情`, stepsSection, '---', reportTemplate, startCmd].filter(Boolean).join('\n\n');
|
|
115
118
|
}
|
|
116
119
|
/** 生成合并报告模板段落 */
|
|
117
120
|
function buildReportTemplate(pipeline, skills, context, isEn) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autopilot.js","sourceRoot":"","sources":["../../src/cli/autopilot.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;
|
|
1
|
+
{"version":3,"file":"autopilot.js","sourceRoot":"","sources":["../../src/cli/autopilot.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -1073,6 +1073,7 @@ workflowCmd
|
|
|
1073
1073
|
.command('done [summary]')
|
|
1074
1074
|
.description('完成当前步骤,自动推进到下一步(摘要可选)')
|
|
1075
1075
|
.option('-n, --name <name>', '具名会话名称')
|
|
1076
|
+
.option('-r, --rating <rating>', '评分本步 Skill 质量(1-5)')
|
|
1076
1077
|
.action(async (summary, options) => {
|
|
1077
1078
|
const { loadSession, markStepDone, buildStepPrompt, getCurrentStep, getCurrentStepIndex, calcProgress, } = await Promise.resolve().then(() => __importStar(require('../workflow/state')));
|
|
1078
1079
|
const { resolvePipeline } = await Promise.resolve().then(() => __importStar(require('../skills/pipeline')));
|
|
@@ -1096,6 +1097,23 @@ workflowCmd
|
|
|
1096
1097
|
const progress = calcProgress(session);
|
|
1097
1098
|
// 自动归档到 Skill Memory(T16)
|
|
1098
1099
|
archiveWorkflowToMemory(session.id, currentStep.skillId, session.pipelineName, stepSummary, process.cwd());
|
|
1100
|
+
// 记录 Skill 质量评分(--rating 1-5)
|
|
1101
|
+
if (options.rating !== undefined) {
|
|
1102
|
+
const ratingNum = parseInt(options.rating, 10);
|
|
1103
|
+
if (isNaN(ratingNum) || ratingNum < 1 || ratingNum > 5) {
|
|
1104
|
+
console.warn('⚠️ 评分无效,已忽略(必须为 1-5 的整数)');
|
|
1105
|
+
}
|
|
1106
|
+
else {
|
|
1107
|
+
const statsData = readStatsV2();
|
|
1108
|
+
if (!statsData.ratings)
|
|
1109
|
+
statsData.ratings = {};
|
|
1110
|
+
if (!statsData.ratings[currentStep.skillId])
|
|
1111
|
+
statsData.ratings[currentStep.skillId] = [];
|
|
1112
|
+
statsData.ratings[currentStep.skillId].push(ratingNum);
|
|
1113
|
+
writeStatsV2(statsData);
|
|
1114
|
+
console.log(`⭐ 已记录评分 ${ratingNum}/5 → ${currentStep.skillId}`);
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1099
1117
|
if (!nextStep) {
|
|
1100
1118
|
console.log('\n🎉 恭喜!工作流全部完成!');
|
|
1101
1119
|
console.log(` Pipeline: ${session.pipelineName}`);
|
|
@@ -2879,6 +2897,83 @@ function loadCustomPipelines(cwd) {
|
|
|
2879
2897
|
}
|
|
2880
2898
|
return results;
|
|
2881
2899
|
}
|
|
2900
|
+
// ─── context 命令组 ────────────────────────────────────────────────────────
|
|
2901
|
+
const contextCmd = program.command('context').description('采集并展示当前项目上下文快照(技术栈/git/目录树)');
|
|
2902
|
+
contextCmd
|
|
2903
|
+
.command('show')
|
|
2904
|
+
.description('显示项目上下文快照(使用缓存,TTL 30min)')
|
|
2905
|
+
.option('--refresh', '强制重新采集,忽略缓存')
|
|
2906
|
+
.option('--json', '以 JSON 格式输出')
|
|
2907
|
+
.action(async (options) => {
|
|
2908
|
+
const { buildProjectSnapshot, loadCachedSnapshot, saveSnapshotCache, formatSnapshotForPrompt } = await Promise.resolve().then(() => __importStar(require('../context/builder')));
|
|
2909
|
+
let snapshot = options.refresh ? null : loadCachedSnapshot(process.cwd());
|
|
2910
|
+
if (!snapshot) {
|
|
2911
|
+
console.log('🔍 正在采集项目上下文...');
|
|
2912
|
+
snapshot = buildProjectSnapshot(process.cwd());
|
|
2913
|
+
saveSnapshotCache(snapshot, process.cwd());
|
|
2914
|
+
}
|
|
2915
|
+
if (options.json) {
|
|
2916
|
+
console.log(JSON.stringify(snapshot, null, 2));
|
|
2917
|
+
}
|
|
2918
|
+
else {
|
|
2919
|
+
console.log('\n' + formatSnapshotForPrompt(snapshot, false) + '\n');
|
|
2920
|
+
console.log(`(缓存时间:${snapshot.generatedAt})\n`);
|
|
2921
|
+
}
|
|
2922
|
+
});
|
|
2923
|
+
contextCmd
|
|
2924
|
+
.command('refresh')
|
|
2925
|
+
.description('强制重新采集,更新 .ethan/context.json 缓存')
|
|
2926
|
+
.action(async () => {
|
|
2927
|
+
const { buildProjectSnapshot, saveSnapshotCache, formatSnapshotForPrompt } = await Promise.resolve().then(() => __importStar(require('../context/builder')));
|
|
2928
|
+
console.log('🔍 正在采集项目上下文...');
|
|
2929
|
+
const snapshot = buildProjectSnapshot(process.cwd());
|
|
2930
|
+
saveSnapshotCache(snapshot, process.cwd());
|
|
2931
|
+
console.log('\n' + formatSnapshotForPrompt(snapshot, false) + '\n');
|
|
2932
|
+
console.log('✅ 项目上下文已更新并缓存到 .ethan/context.json\n');
|
|
2933
|
+
});
|
|
2934
|
+
// ─── quality 命令组 ────────────────────────────────────────────────────────
|
|
2935
|
+
const qualityCmd = program.command('quality').description('Skill 质量评估报告(基于 workflow done --rating 的评分数据)');
|
|
2936
|
+
qualityCmd
|
|
2937
|
+
.command('report')
|
|
2938
|
+
.description('显示各 Skill 的质量评分报告(ASCII 条形图)')
|
|
2939
|
+
.option('--min-count <n>', '最少评分次数过滤(低于此数量的 Skill 不显示)', '1')
|
|
2940
|
+
.action((options) => {
|
|
2941
|
+
const minCount = parseInt(options.minCount, 10) || 1;
|
|
2942
|
+
const data = readStatsV2();
|
|
2943
|
+
const ratings = data.ratings || {};
|
|
2944
|
+
const entries = Object.entries(ratings)
|
|
2945
|
+
.map(([skillId, scores]) => ({
|
|
2946
|
+
skillId,
|
|
2947
|
+
scores,
|
|
2948
|
+
avg: scores.reduce((a, b) => a + b, 0) / scores.length,
|
|
2949
|
+
count: scores.length,
|
|
2950
|
+
}))
|
|
2951
|
+
.filter((e) => e.count >= minCount)
|
|
2952
|
+
.sort((a, b) => b.avg - a.avg);
|
|
2953
|
+
if (entries.length === 0) {
|
|
2954
|
+
console.log('\n📊 暂无评分数据。运行 ethan workflow done "摘要" --rating 4 记录评分。\n');
|
|
2955
|
+
return;
|
|
2956
|
+
}
|
|
2957
|
+
const globalAvg = entries.reduce((s, e) => s + e.avg, 0) / entries.length;
|
|
2958
|
+
console.log('\n📊 Skill 质量评估报告');
|
|
2959
|
+
console.log('─'.repeat(60));
|
|
2960
|
+
const BAR_MAX = 25;
|
|
2961
|
+
for (const e of entries) {
|
|
2962
|
+
const indicator = e.avg > 4 ? '🟢' : e.avg >= 3 ? '🟡' : '🔴';
|
|
2963
|
+
const bars = Math.round((e.avg / 5) * BAR_MAX);
|
|
2964
|
+
const bar = '█'.repeat(bars) + '░'.repeat(BAR_MAX - bars);
|
|
2965
|
+
const avgStr = e.avg.toFixed(1);
|
|
2966
|
+
console.log(`${indicator} ${e.skillId.padEnd(28)} ${bar} ${avgStr}/5 (n=${e.count})`);
|
|
2967
|
+
}
|
|
2968
|
+
console.log('─'.repeat(60));
|
|
2969
|
+
console.log(` 全局平均分:${globalAvg.toFixed(1)}/5 (${entries.length} 个 Skill,共 ${entries.reduce((s, e) => s + e.count, 0)} 条评分)`);
|
|
2970
|
+
const lowSkills = entries.filter((e) => e.avg < 3);
|
|
2971
|
+
if (lowSkills.length > 0) {
|
|
2972
|
+
console.log('\n⚠️ 低分 Skill(平均 < 3)需要关注:');
|
|
2973
|
+
lowSkills.forEach((e) => console.log(` 🔴 ${e.skillId} avg=${e.avg.toFixed(1)}`));
|
|
2974
|
+
}
|
|
2975
|
+
console.log('');
|
|
2976
|
+
});
|
|
2882
2977
|
// ─── autopilot 命令 ──────────────────────────────────────────────────────────
|
|
2883
2978
|
program
|
|
2884
2979
|
.command('autopilot [pipelineId]')
|
|
@@ -2886,12 +2981,33 @@ program
|
|
|
2886
2981
|
.option('-c, --context <context>', '任务上下文描述(如"实现用户登录功能")', '')
|
|
2887
2982
|
.option('--all', '生成全部 3 条 Pipeline 的超级 prompt')
|
|
2888
2983
|
.option('--lang <lang>', '输出语言:zh(默认)或 en', '')
|
|
2984
|
+
.option('--with-context', '自动采集项目上下文(技术栈/git 提交/目录树)注入到提示词')
|
|
2889
2985
|
.option('--no-copy', '不自动复制到剪贴板,直接打印到终端')
|
|
2890
2986
|
.action(async (pipelineId, options) => {
|
|
2891
2987
|
const { resolvePipeline, PIPELINES } = await Promise.resolve().then(() => __importStar(require('../skills/pipeline')));
|
|
2892
2988
|
const { buildAutopilotPrompt, buildAllPipelinesAutopilotPrompt } = await Promise.resolve().then(() => __importStar(require('./autopilot')));
|
|
2989
|
+
const { buildProjectSnapshot, loadCachedSnapshot, saveSnapshotCache } = await Promise.resolve().then(() => __importStar(require('../context/builder')));
|
|
2893
2990
|
const config = (0, config_1.readConfig)(process.cwd());
|
|
2894
2991
|
const isEn = (options.lang || config.lang || 'zh') === 'en';
|
|
2992
|
+
// 采集项目上下文快照(--with-context 或自动检测缓存)
|
|
2993
|
+
let snapshot = undefined;
|
|
2994
|
+
if (options.withContext) {
|
|
2995
|
+
const cached = loadCachedSnapshot(process.cwd());
|
|
2996
|
+
if (cached) {
|
|
2997
|
+
snapshot = cached;
|
|
2998
|
+
}
|
|
2999
|
+
else {
|
|
3000
|
+
console.log(isEn ? '🔍 Collecting project context...' : '🔍 正在采集项目上下文...');
|
|
3001
|
+
snapshot = buildProjectSnapshot(process.cwd());
|
|
3002
|
+
saveSnapshotCache(snapshot, process.cwd());
|
|
3003
|
+
}
|
|
3004
|
+
}
|
|
3005
|
+
else {
|
|
3006
|
+
// 静默注入:若缓存存在且未过期则自动使用
|
|
3007
|
+
const cached = loadCachedSnapshot(process.cwd());
|
|
3008
|
+
if (cached)
|
|
3009
|
+
snapshot = cached;
|
|
3010
|
+
}
|
|
2895
3011
|
// 获取任务上下文(--context 或交互式输入)
|
|
2896
3012
|
let context = (options.context || '').trim();
|
|
2897
3013
|
if (!context) {
|
|
@@ -2911,7 +3027,7 @@ program
|
|
|
2911
3027
|
if (options.all) {
|
|
2912
3028
|
// 生成全部 Pipeline 的超级 prompt
|
|
2913
3029
|
const allResolved = PIPELINES.map((p) => resolvePipeline(p.id)).filter(Boolean);
|
|
2914
|
-
prompt = buildAllPipelinesAutopilotPrompt(allResolved, { context, isEn });
|
|
3030
|
+
prompt = buildAllPipelinesAutopilotPrompt(allResolved, { context, isEn, snapshot });
|
|
2915
3031
|
console.log(isEn
|
|
2916
3032
|
? `\n🚀 Auto-Pilot prompt generated for all ${PIPELINES.length} pipelines`
|
|
2917
3033
|
: `\n🚀 已生成全部 ${PIPELINES.length} 条 Pipeline 的超级 prompt`);
|
|
@@ -2966,7 +3082,7 @@ program
|
|
|
2966
3082
|
process.exit(1);
|
|
2967
3083
|
}
|
|
2968
3084
|
const { pipeline, skills } = resolved;
|
|
2969
|
-
prompt = buildAutopilotPrompt(pipeline, skills, { context, isEn });
|
|
3085
|
+
prompt = buildAutopilotPrompt(pipeline, skills, { context, isEn, snapshot });
|
|
2970
3086
|
console.log(isEn
|
|
2971
3087
|
? `\n🚀 Auto-Pilot prompt generated: ${pipeline.name} (${skills.length} steps)`
|
|
2972
3088
|
: `\n🚀 超级 prompt 已生成:${pipeline.name}(${skills.length} 步)`);
|