@dommaker/harness 0.5.0 → 0.6.1
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/README.md +92 -24
- package/bin/harness.js +59 -7
- package/dist/cli/commands/check.d.ts.map +1 -1
- package/dist/cli/commands/check.js +77 -0
- package/dist/cli/commands/check.js.map +1 -1
- package/dist/cli/commands/flow.d.ts +20 -0
- package/dist/cli/commands/flow.d.ts.map +1 -0
- package/dist/cli/commands/flow.js +239 -0
- package/dist/cli/commands/flow.js.map +1 -0
- package/dist/cli/commands/index.d.ts +2 -0
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +5 -1
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.d.ts +2 -0
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +99 -12
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/status.d.ts +20 -0
- package/dist/cli/commands/status.d.ts.map +1 -0
- package/dist/cli/commands/status.js +183 -0
- package/dist/cli/commands/status.js.map +1 -0
- package/dist/core/project-config-loader.d.ts +8 -0
- package/dist/core/project-config-loader.d.ts.map +1 -1
- package/dist/core/project-config-loader.js +69 -9
- package/dist/core/project-config-loader.js.map +1 -1
- package/dist/types/project-config.d.ts +11 -9
- package/dist/types/project-config.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* harness flow 命令
|
|
4
|
+
*
|
|
5
|
+
* 一键执行诊断 + 提案流程
|
|
6
|
+
*/
|
|
7
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
8
|
+
if (k2 === undefined) k2 = k;
|
|
9
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
10
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
11
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
12
|
+
}
|
|
13
|
+
Object.defineProperty(o, k2, desc);
|
|
14
|
+
}) : (function(o, m, k, k2) {
|
|
15
|
+
if (k2 === undefined) k2 = k;
|
|
16
|
+
o[k2] = m[k];
|
|
17
|
+
}));
|
|
18
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
19
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
20
|
+
}) : function(o, v) {
|
|
21
|
+
o["default"] = v;
|
|
22
|
+
});
|
|
23
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
24
|
+
var ownKeys = function(o) {
|
|
25
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
26
|
+
var ar = [];
|
|
27
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
28
|
+
return ar;
|
|
29
|
+
};
|
|
30
|
+
return ownKeys(o);
|
|
31
|
+
};
|
|
32
|
+
return function (mod) {
|
|
33
|
+
if (mod && mod.__esModule) return mod;
|
|
34
|
+
var result = {};
|
|
35
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
36
|
+
__setModuleDefault(result, mod);
|
|
37
|
+
return result;
|
|
38
|
+
};
|
|
39
|
+
})();
|
|
40
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
41
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
42
|
+
};
|
|
43
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
44
|
+
exports.flow = flow;
|
|
45
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
const path = __importStar(require("path"));
|
|
48
|
+
const readline = __importStar(require("readline"));
|
|
49
|
+
const traces_1 = require("../../monitoring/traces");
|
|
50
|
+
const trace_analyzer_1 = require("../../monitoring/trace-analyzer");
|
|
51
|
+
const constraint_doctor_1 = require("../../monitoring/constraint-doctor");
|
|
52
|
+
const constraint_evolver_1 = require("../../monitoring/constraint-evolver");
|
|
53
|
+
/**
|
|
54
|
+
* 创建 readline 接口
|
|
55
|
+
*/
|
|
56
|
+
function createReadlineInterface() {
|
|
57
|
+
return readline.createInterface({
|
|
58
|
+
input: process.stdin,
|
|
59
|
+
output: process.stdout,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* 询问用户
|
|
64
|
+
*/
|
|
65
|
+
function ask(rl, question) {
|
|
66
|
+
return new Promise(resolve => {
|
|
67
|
+
rl.question(question, answer => {
|
|
68
|
+
resolve(answer.trim().toLowerCase());
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* 执行流程
|
|
74
|
+
*/
|
|
75
|
+
async function flow(options) {
|
|
76
|
+
const projectPath = options.projectPath || process.cwd();
|
|
77
|
+
const harnessDir = path.join(projectPath, '.harness');
|
|
78
|
+
const tracesPath = path.join(harnessDir, 'traces', 'execution.log');
|
|
79
|
+
const diagnosesDir = path.join(harnessDir, 'diagnoses');
|
|
80
|
+
const proposalsDir = path.join(harnessDir, 'proposals');
|
|
81
|
+
console.log(chalk_1.default.blue('🔄 Harness 自动化流程'));
|
|
82
|
+
console.log();
|
|
83
|
+
// 检查前置条件
|
|
84
|
+
if (!fs.existsSync(tracesPath)) {
|
|
85
|
+
console.log(chalk_1.default.yellow('⚠️ 暂无 Trace 记录'));
|
|
86
|
+
console.log(chalk_1.default.gray('💡 运行 harness check 开始记录'));
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
// 读取 traces
|
|
90
|
+
const tracesContent = fs.readFileSync(tracesPath, 'utf-8');
|
|
91
|
+
const lines = tracesContent.trim().split('\n').filter(Boolean);
|
|
92
|
+
const traces = lines.map(line => {
|
|
93
|
+
try {
|
|
94
|
+
return JSON.parse(line);
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return null;
|
|
98
|
+
}
|
|
99
|
+
}).filter(Boolean);
|
|
100
|
+
// 创建收集器和分析器
|
|
101
|
+
const collector = new traces_1.TraceCollector({ traceFile: tracesPath });
|
|
102
|
+
const analyzer = new trace_analyzer_1.TraceAnalyzer(collector);
|
|
103
|
+
const summaries = analyzer.summarize(traces);
|
|
104
|
+
let anomalies = analyzer.detectAnomalies(summaries);
|
|
105
|
+
const rl = createReadlineInterface();
|
|
106
|
+
try {
|
|
107
|
+
// 步骤 1: 分析统计
|
|
108
|
+
if (!options.from || options.from === 'analyze') {
|
|
109
|
+
console.log(chalk_1.default.blue('📊 步骤 1/4: 分析统计'));
|
|
110
|
+
console.log(chalk_1.default.gray('────────────────────────────'));
|
|
111
|
+
console.log(chalk_1.default.gray(`约束统计: ${summaries.length} 条`));
|
|
112
|
+
console.log(chalk_1.default.gray(`检测异常: ${anomalies.length} 个`));
|
|
113
|
+
if (anomalies.length === 0) {
|
|
114
|
+
console.log(chalk_1.default.green('✅ 未发现异常'));
|
|
115
|
+
rl.close();
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
console.log(chalk_1.default.yellow('发现异常:'));
|
|
119
|
+
anomalies.forEach((a) => {
|
|
120
|
+
console.log(chalk_1.default.yellow(` - ${a.constraintId}: ${a.type}`));
|
|
121
|
+
});
|
|
122
|
+
console.log();
|
|
123
|
+
// 询问是否继续
|
|
124
|
+
const continue1 = await ask(rl, '是否继续运行诊断? [Y/n] ');
|
|
125
|
+
if (continue1 === 'n') {
|
|
126
|
+
console.log(chalk_1.default.gray('已取消'));
|
|
127
|
+
rl.close();
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
console.log();
|
|
131
|
+
}
|
|
132
|
+
// 步骤 2: 运行诊断
|
|
133
|
+
console.log(chalk_1.default.blue('🔍 步骤 2/4: 运行诊断'));
|
|
134
|
+
console.log(chalk_1.default.gray('────────────────────────────'));
|
|
135
|
+
const doctor = new constraint_doctor_1.ConstraintDoctor();
|
|
136
|
+
const diagnoses = [];
|
|
137
|
+
for (const anomaly of anomalies) {
|
|
138
|
+
try {
|
|
139
|
+
const diagnosis = await doctor.diagnose(anomaly);
|
|
140
|
+
diagnoses.push(diagnosis);
|
|
141
|
+
}
|
|
142
|
+
catch (e) {
|
|
143
|
+
console.log(chalk_1.default.yellow(` ⚠️ ${anomaly.constraintId} 诊断失败`));
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
console.log(chalk_1.default.gray(`诊断数量: ${diagnoses.length}`));
|
|
147
|
+
if (diagnoses.length > 0) {
|
|
148
|
+
console.log();
|
|
149
|
+
diagnoses.forEach((d) => {
|
|
150
|
+
console.log(chalk_1.default.yellow(` ${d.constraintId}`));
|
|
151
|
+
console.log(chalk_1.default.gray(` 根因: ${d.rootCause.primary}`));
|
|
152
|
+
console.log(chalk_1.default.gray(` 严重度: ${d.impact.severity}`));
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
// 保存诊断结果
|
|
156
|
+
if (diagnoses.length > 0) {
|
|
157
|
+
fs.mkdirSync(diagnosesDir, { recursive: true });
|
|
158
|
+
const diagnosisFile = path.join(diagnosesDir, `${new Date().toISOString().split('T')[0]}.json`);
|
|
159
|
+
fs.writeFileSync(diagnosisFile, JSON.stringify(diagnoses, null, 2));
|
|
160
|
+
console.log(chalk_1.default.green(`✅ 诊断已保存: ${diagnosisFile}`));
|
|
161
|
+
}
|
|
162
|
+
console.log();
|
|
163
|
+
// 询问是否继续
|
|
164
|
+
const continue2 = await ask(rl, '是否继续生成优化提案? [Y/n] ');
|
|
165
|
+
if (continue2 === 'n') {
|
|
166
|
+
console.log(chalk_1.default.gray('已取消'));
|
|
167
|
+
rl.close();
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
console.log();
|
|
171
|
+
// 步骤 3: 生成提案
|
|
172
|
+
console.log(chalk_1.default.blue('💡 步骤 3/4: 生成提案'));
|
|
173
|
+
console.log(chalk_1.default.gray('────────────────────────────'));
|
|
174
|
+
const evolver = new constraint_evolver_1.ConstraintEvolver();
|
|
175
|
+
const proposals = [];
|
|
176
|
+
for (const diagnosis of diagnoses) {
|
|
177
|
+
try {
|
|
178
|
+
const proposal = await evolver.propose(diagnosis);
|
|
179
|
+
if (proposal) {
|
|
180
|
+
proposals.push(proposal);
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
catch (e) {
|
|
184
|
+
console.log(chalk_1.default.yellow(` ⚠️ ${diagnosis.constraintId} 提案生成失败`));
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
console.log(chalk_1.default.gray(`提案数量: ${proposals.length}`));
|
|
188
|
+
if (proposals.length === 0) {
|
|
189
|
+
console.log(chalk_1.default.green('✅ 无需优化'));
|
|
190
|
+
rl.close();
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
console.log();
|
|
194
|
+
proposals.forEach((p, i) => {
|
|
195
|
+
console.log(chalk_1.default.yellow(`提案 ${i + 1}:`));
|
|
196
|
+
console.log(chalk_1.default.gray(` 约束: ${p.constraintId}`));
|
|
197
|
+
console.log(chalk_1.default.gray(` 操作: ${p.type}`));
|
|
198
|
+
console.log(chalk_1.default.gray(` 风险: ${p.risk.level}`));
|
|
199
|
+
console.log();
|
|
200
|
+
});
|
|
201
|
+
// 保存提案
|
|
202
|
+
fs.mkdirSync(proposalsDir, { recursive: true });
|
|
203
|
+
const proposalFile = path.join(proposalsDir, `${new Date().toISOString().split('T')[0]}.json`);
|
|
204
|
+
fs.writeFileSync(proposalFile, JSON.stringify({ proposals, timestamp: new Date().toISOString() }, null, 2));
|
|
205
|
+
console.log(chalk_1.default.green(`✅ 提案已保存: ${proposalFile}`));
|
|
206
|
+
console.log();
|
|
207
|
+
// 步骤 4: 审核提案
|
|
208
|
+
console.log(chalk_1.default.blue('📝 步骤 4/4: 审核提案'));
|
|
209
|
+
console.log(chalk_1.default.gray('────────────────────────────'));
|
|
210
|
+
for (let i = 0; i < proposals.length; i++) {
|
|
211
|
+
const p = proposals[i];
|
|
212
|
+
// 低风险 → 可自动应用
|
|
213
|
+
if (options.autoApply && p.risk.level === 'low') {
|
|
214
|
+
console.log(chalk_1.default.green(`✅ 自动应用提案 ${i + 1} (低风险)`));
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
// 需要人工审核
|
|
218
|
+
const answer = await ask(rl, `是否应用提案 ${i + 1}? [y/N] `);
|
|
219
|
+
if (answer === 'y') {
|
|
220
|
+
console.log(chalk_1.default.green(`✅ 提案 ${i + 1} 已标记为应用`));
|
|
221
|
+
console.log(chalk_1.default.gray(' 请手动更新约束配置'));
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
console.log(chalk_1.default.gray(`⏭️ 跳过提案 ${i + 1}`));
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
console.log();
|
|
228
|
+
console.log(chalk_1.default.green('✅ 流程完成!'));
|
|
229
|
+
console.log();
|
|
230
|
+
console.log(chalk_1.default.blue('💡 下一步:'));
|
|
231
|
+
console.log(chalk_1.default.gray(' 1. 查看提案文件确认变更'));
|
|
232
|
+
console.log(chalk_1.default.gray(' 2. 手动更新约束配置'));
|
|
233
|
+
console.log(chalk_1.default.gray(' 3. 运行 harness status 查看效果'));
|
|
234
|
+
}
|
|
235
|
+
finally {
|
|
236
|
+
rl.close();
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
//# sourceMappingURL=flow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow.js","sourceRoot":"","sources":["../../../src/cli/commands/flow.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,4 +9,6 @@ export { report, type ReportOptions } from './report';
|
|
|
9
9
|
export { tracesCommand } from './traces';
|
|
10
10
|
export { diagnoseCommand } from './diagnose';
|
|
11
11
|
export { proposeCommand } from './propose';
|
|
12
|
+
export { status, type StatusOptions } from './status';
|
|
13
|
+
export { flow, type FlowOptions } from './flow';
|
|
12
14
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,KAAK,YAAY,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,uBAAuB,EAAE,KAAK,eAAe,EAAE,MAAM,YAAY,CAAC;AACrF,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,KAAK,iBAAiB,EAAE,MAAM,eAAe,CAAC;AACrF,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,MAAM,EAAE,KAAK,aAAa,EAAE,MAAM,UAAU,CAAC;AACtD,OAAO,EAAE,IAAI,EAAE,KAAK,WAAW,EAAE,MAAM,QAAQ,CAAC"}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* CLI 命令导出
|
|
4
4
|
*/
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.proposeCommand = exports.diagnoseCommand = exports.tracesCommand = exports.report = exports.init = exports.checkCoverage = exports.runPassesGate = exports.createExampleCheckpoint = exports.validate = exports.listLaws = exports.check = void 0;
|
|
6
|
+
exports.flow = exports.status = exports.proposeCommand = exports.diagnoseCommand = exports.tracesCommand = exports.report = exports.init = exports.checkCoverage = exports.runPassesGate = exports.createExampleCheckpoint = exports.validate = exports.listLaws = exports.check = void 0;
|
|
7
7
|
var check_1 = require("./check");
|
|
8
8
|
Object.defineProperty(exports, "check", { enumerable: true, get: function () { return check_1.check; } });
|
|
9
9
|
Object.defineProperty(exports, "listLaws", { enumerable: true, get: function () { return check_1.listLaws; } });
|
|
@@ -23,4 +23,8 @@ var diagnose_1 = require("./diagnose");
|
|
|
23
23
|
Object.defineProperty(exports, "diagnoseCommand", { enumerable: true, get: function () { return diagnose_1.diagnoseCommand; } });
|
|
24
24
|
var propose_1 = require("./propose");
|
|
25
25
|
Object.defineProperty(exports, "proposeCommand", { enumerable: true, get: function () { return propose_1.proposeCommand; } });
|
|
26
|
+
var status_1 = require("./status");
|
|
27
|
+
Object.defineProperty(exports, "status", { enumerable: true, get: function () { return status_1.status; } });
|
|
28
|
+
var flow_1 = require("./flow");
|
|
29
|
+
Object.defineProperty(exports, "flow", { enumerable: true, get: function () { return flow_1.flow; } });
|
|
26
30
|
//# sourceMappingURL=index.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/commands/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,iCAA6D;AAApD,8FAAA,KAAK,OAAA;AAAE,iGAAA,QAAQ,OAAA;AACxB,uCAAqF;AAA5E,oGAAA,QAAQ,OAAA;AAAE,mHAAA,uBAAuB,OAAA;AAC1C,6CAAqF;AAA5E,4GAAA,aAAa,OAAA;AAAE,4GAAA,aAAa,OAAA;AACrC,+BAAgD;AAAvC,4FAAA,IAAI,OAAA;AACb,mCAAsD;AAA7C,gGAAA,MAAM,OAAA;AACf,mCAAyC;AAAhC,uGAAA,aAAa,OAAA;AACtB,uCAA6C;AAApC,2GAAA,eAAe,OAAA;AACxB,qCAA2C;AAAlC,yGAAA,cAAc,OAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/cli/commands/index.ts"],"names":[],"mappings":";AAAA;;GAEG;;;AAEH,iCAA6D;AAApD,8FAAA,KAAK,OAAA;AAAE,iGAAA,QAAQ,OAAA;AACxB,uCAAqF;AAA5E,oGAAA,QAAQ,OAAA;AAAE,mHAAA,uBAAuB,OAAA;AAC1C,6CAAqF;AAA5E,4GAAA,aAAa,OAAA;AAAE,4GAAA,aAAa,OAAA;AACrC,+BAAgD;AAAvC,4FAAA,IAAI,OAAA;AACb,mCAAsD;AAA7C,gGAAA,MAAM,OAAA;AACf,mCAAyC;AAAhC,uGAAA,aAAa,OAAA;AACtB,uCAA6C;AAApC,2GAAA,eAAe,OAAA;AACxB,qCAA2C;AAAlC,yGAAA,cAAc,OAAA;AACvB,mCAAsD;AAA7C,gGAAA,MAAM,OAAA;AACf,+BAAgD;AAAvC,4FAAA,IAAI,OAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,WAAW,WAAW;IAC1B,WAAW;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW;IACX,MAAM,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;IAC1C,WAAW;IACX,IAAI,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAC;IAC3D,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0BAA0B;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAkDD;;GAEG;AACH,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,WAAW,WAAW;IAC1B,WAAW;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW;IACX,MAAM,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;IAC1C,WAAW;IACX,IAAI,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,YAAY,GAAG,QAAQ,CAAC;IAC3D,qBAAqB;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0BAA0B;IAC1B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,oBAAoB;IACpB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAkDD;;GAEG;AACH,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAsF9D"}
|
|
@@ -97,6 +97,11 @@ const PRESETS = {
|
|
|
97
97
|
* 初始化项目
|
|
98
98
|
*/
|
|
99
99
|
async function init(options) {
|
|
100
|
+
// 只输出代码片段
|
|
101
|
+
if (options.printSnippets) {
|
|
102
|
+
printSnippets();
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
100
105
|
console.log(chalk_1.default.blue('🚀 初始化 harness 配置...'));
|
|
101
106
|
const projectPath = options.projectPath || process.cwd();
|
|
102
107
|
const configDir = path.join(projectPath, '.harness');
|
|
@@ -162,27 +167,81 @@ async function init(options) {
|
|
|
162
167
|
console.log();
|
|
163
168
|
console.log(chalk_1.default.gray('下一步:'));
|
|
164
169
|
console.log(chalk_1.default.gray(' 1. 编辑 .harness/config.yml 自定义配置'));
|
|
165
|
-
console.log(chalk_1.default.gray(' 2. 编辑 .harness/
|
|
166
|
-
console.log(chalk_1.default.gray(' 3.
|
|
167
|
-
console.log(chalk_1.default.gray(' 4. 运行
|
|
170
|
+
console.log(chalk_1.default.gray(' 2. 编辑 .harness/custom-constraints.yml 添加项目约束'));
|
|
171
|
+
console.log(chalk_1.default.gray(' 3. 正常开发,每次 git commit 会自动检查约束'));
|
|
172
|
+
console.log(chalk_1.default.gray(' 4. 运行 harness status 查看状态'));
|
|
173
|
+
console.log();
|
|
174
|
+
console.log(chalk_1.default.blue('💡 提示: 使用 harness init --print-snippets 查看配置代码片段'));
|
|
168
175
|
}
|
|
176
|
+
/**
|
|
177
|
+
* 输出代码片段
|
|
178
|
+
*/
|
|
179
|
+
function printSnippets() {
|
|
180
|
+
console.log(chalk_1.default.blue('📄 Harness 配置代码片段'));
|
|
181
|
+
console.log();
|
|
182
|
+
console.log(chalk_1.default.yellow('Git pre-commit hook:'));
|
|
183
|
+
console.log(chalk_1.default.gray('添加到 .git/hooks/pre-commit'));
|
|
184
|
+
console.log();
|
|
185
|
+
console.log(chalk_1.default.cyan(PRE_COMMIT_SNIPPET));
|
|
186
|
+
console.log(chalk_1.default.yellow('GitHub Actions:'));
|
|
187
|
+
console.log(chalk_1.default.gray('添加到 .github/workflows/*.yml 的 jobs 中'));
|
|
188
|
+
console.log();
|
|
189
|
+
console.log(chalk_1.default.cyan(GITHUB_ACTIONS_SNIPPET));
|
|
190
|
+
console.log(chalk_1.default.blue('💡 提示: 运行 harness init 自动创建配置文件'));
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Git pre-commit 代码片段
|
|
194
|
+
*/
|
|
195
|
+
const PRE_COMMIT_SNIPPET = `
|
|
196
|
+
# Harness 约束检查
|
|
197
|
+
npx harness check --staged
|
|
198
|
+
if [ $? -ne 0 ]; then
|
|
199
|
+
echo "❌ Iron law check failed"
|
|
200
|
+
exit 1
|
|
201
|
+
fi
|
|
202
|
+
`;
|
|
203
|
+
/**
|
|
204
|
+
* GitHub Actions 代码片段
|
|
205
|
+
*/
|
|
206
|
+
const GITHUB_ACTIONS_SNIPPET = `
|
|
207
|
+
harness-check:
|
|
208
|
+
runs-on: ubuntu-latest
|
|
209
|
+
steps:
|
|
210
|
+
- uses: actions/checkout@v4
|
|
211
|
+
- uses: actions/setup-node@v4
|
|
212
|
+
with:
|
|
213
|
+
node-version: '20'
|
|
214
|
+
- run: npm ci
|
|
215
|
+
- run: npx harness check
|
|
216
|
+
`;
|
|
169
217
|
/**
|
|
170
218
|
* 设置 Git hooks
|
|
171
219
|
*/
|
|
172
220
|
async function setupGitHooks(projectPath) {
|
|
173
221
|
const gitDir = path.join(projectPath, '.git');
|
|
174
222
|
const hooksDir = path.join(gitDir, 'hooks');
|
|
223
|
+
const preCommitPath = path.join(hooksDir, 'pre-commit');
|
|
175
224
|
try {
|
|
176
225
|
await fs.access(gitDir);
|
|
177
226
|
}
|
|
178
227
|
catch {
|
|
179
228
|
console.log(chalk_1.default.yellow('⚠️ 未检测到 Git 仓库,跳过 Git hooks'));
|
|
229
|
+
console.log(chalk_1.default.gray('💡 初始化 Git 后可运行 harness init --print-snippets 查看配置'));
|
|
180
230
|
return;
|
|
181
231
|
}
|
|
182
232
|
await fs.mkdir(hooksDir, { recursive: true });
|
|
183
|
-
// pre-commit
|
|
184
|
-
|
|
185
|
-
|
|
233
|
+
// 检查 pre-commit 是否已存在
|
|
234
|
+
try {
|
|
235
|
+
await fs.access(preCommitPath);
|
|
236
|
+
// 已存在,输出代码片段
|
|
237
|
+
console.log(chalk_1.default.yellow('⚠️ .git/hooks/pre-commit 已存在'));
|
|
238
|
+
console.log(chalk_1.default.gray('💡 请手动添加以下内容到文件末尾:'));
|
|
239
|
+
console.log();
|
|
240
|
+
console.log(chalk_1.default.cyan(PRE_COMMIT_SNIPPET));
|
|
241
|
+
}
|
|
242
|
+
catch {
|
|
243
|
+
// 不存在,创建文件
|
|
244
|
+
const preCommitContent = `#!/bin/sh
|
|
186
245
|
# Harness pre-commit hook
|
|
187
246
|
|
|
188
247
|
echo "🔍 Running harness checks..."
|
|
@@ -196,18 +255,32 @@ fi
|
|
|
196
255
|
|
|
197
256
|
echo "✅ All checks passed"
|
|
198
257
|
`;
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
258
|
+
await fs.writeFile(preCommitPath, preCommitContent, 'utf-8');
|
|
259
|
+
await fs.chmod(preCommitPath, 0o755);
|
|
260
|
+
console.log(chalk_1.default.green(`✅ 已创建 .git/hooks/pre-commit`));
|
|
261
|
+
}
|
|
202
262
|
}
|
|
203
263
|
/**
|
|
204
264
|
* 设置 GitHub Actions
|
|
205
265
|
*/
|
|
206
266
|
async function setupGitHubActions(projectPath, preset) {
|
|
207
267
|
const workflowsDir = path.join(projectPath, '.github', 'workflows');
|
|
208
|
-
await fs.mkdir(workflowsDir, { recursive: true });
|
|
209
|
-
// harness-check.yml
|
|
210
268
|
const workflowPath = path.join(workflowsDir, 'harness-check.yml');
|
|
269
|
+
// 检查是否已有 CI 配置
|
|
270
|
+
const existingFiles = await findCiWorkflows(workflowsDir);
|
|
271
|
+
if (existingFiles.length > 0) {
|
|
272
|
+
// 已有 CI 配置,输出代码片段
|
|
273
|
+
console.log(chalk_1.default.yellow('⚠️ 检测到已存在的 CI 配置:'));
|
|
274
|
+
existingFiles.forEach(f => {
|
|
275
|
+
console.log(chalk_1.default.gray(` - .github/workflows/${f}`));
|
|
276
|
+
});
|
|
277
|
+
console.log(chalk_1.default.gray('💡 请手动添加以下内容到 jobs 中:'));
|
|
278
|
+
console.log();
|
|
279
|
+
console.log(chalk_1.default.cyan(GITHUB_ACTIONS_SNIPPET));
|
|
280
|
+
return;
|
|
281
|
+
}
|
|
282
|
+
// 没有现有 CI 配置,创建文件
|
|
283
|
+
await fs.mkdir(workflowsDir, { recursive: true });
|
|
211
284
|
const workflowContent = `name: Harness Check
|
|
212
285
|
|
|
213
286
|
on:
|
|
@@ -241,7 +314,21 @@ jobs:
|
|
|
241
314
|
run: npx harness passes-gate
|
|
242
315
|
`;
|
|
243
316
|
await fs.writeFile(workflowPath, workflowContent, 'utf-8');
|
|
244
|
-
console.log(chalk_1.default.green(`✅ 已创建
|
|
317
|
+
console.log(chalk_1.default.green(`✅ 已创建 .github/workflows/harness-check.yml`));
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* 查找已存在的 CI 工作流文件
|
|
321
|
+
*/
|
|
322
|
+
async function findCiWorkflows(workflowsDir) {
|
|
323
|
+
try {
|
|
324
|
+
await fs.access(workflowsDir);
|
|
325
|
+
const files = await fs.readdir(workflowsDir);
|
|
326
|
+
// 过滤出可能是 CI 配置的文件
|
|
327
|
+
return files.filter(f => f.endsWith('.yml') || f.endsWith('.yaml'));
|
|
328
|
+
}
|
|
329
|
+
catch {
|
|
330
|
+
return [];
|
|
331
|
+
}
|
|
245
332
|
}
|
|
246
333
|
/**
|
|
247
334
|
* 创建自定义约束示例
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":";AAAA;;;;GAIG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* harness status 命令
|
|
3
|
+
*
|
|
4
|
+
* 显示 Harness 状态、统计、异常检测 + 智能建议
|
|
5
|
+
*/
|
|
6
|
+
export interface StatusOptions {
|
|
7
|
+
/** 项目路径 */
|
|
8
|
+
projectPath?: string;
|
|
9
|
+
/** 详细模式 */
|
|
10
|
+
detail?: boolean;
|
|
11
|
+
/** 只显示异常 */
|
|
12
|
+
anomalies?: boolean;
|
|
13
|
+
/** 时间范围(小时) */
|
|
14
|
+
hours?: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* 显示 Harness 状态
|
|
18
|
+
*/
|
|
19
|
+
export declare function status(options: StatusOptions): Promise<void>;
|
|
20
|
+
//# sourceMappingURL=status.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/status.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,WAAW,aAAa;IAC5B,WAAW;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW;IACX,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY;IACZ,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,eAAe;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;GAEG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CA8IlE"}
|