@dommaker/harness 0.1.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.
Files changed (121) hide show
  1. package/README.md +188 -0
  2. package/bin/harness.js +104 -0
  3. package/dist/cli/commands/check.d.ts +25 -0
  4. package/dist/cli/commands/check.d.ts.map +1 -0
  5. package/dist/cli/commands/check.js +166 -0
  6. package/dist/cli/commands/check.js.map +1 -0
  7. package/dist/cli/commands/index.d.ts +9 -0
  8. package/dist/cli/commands/index.d.ts.map +1 -0
  9. package/dist/cli/commands/index.js +20 -0
  10. package/dist/cli/commands/index.js.map +1 -0
  11. package/dist/cli/commands/init.d.ts +22 -0
  12. package/dist/cli/commands/init.d.ts.map +1 -0
  13. package/dist/cli/commands/init.js +244 -0
  14. package/dist/cli/commands/init.js.map +1 -0
  15. package/dist/cli/commands/passes-gate.d.ts +24 -0
  16. package/dist/cli/commands/passes-gate.d.ts.map +1 -0
  17. package/dist/cli/commands/passes-gate.js +171 -0
  18. package/dist/cli/commands/passes-gate.js.map +1 -0
  19. package/dist/cli/commands/report.d.ts +18 -0
  20. package/dist/cli/commands/report.d.ts.map +1 -0
  21. package/dist/cli/commands/report.js +205 -0
  22. package/dist/cli/commands/report.js.map +1 -0
  23. package/dist/cli/commands/validate.d.ts +22 -0
  24. package/dist/cli/commands/validate.d.ts.map +1 -0
  25. package/dist/cli/commands/validate.js +175 -0
  26. package/dist/cli/commands/validate.js.map +1 -0
  27. package/dist/core/index.d.ts +7 -0
  28. package/dist/core/index.d.ts.map +1 -0
  29. package/dist/core/index.js +23 -0
  30. package/dist/core/index.js.map +1 -0
  31. package/dist/core/iron-laws/checker.d.ts +61 -0
  32. package/dist/core/iron-laws/checker.d.ts.map +1 -0
  33. package/dist/core/iron-laws/checker.js +175 -0
  34. package/dist/core/iron-laws/checker.js.map +1 -0
  35. package/dist/core/iron-laws/definitions.d.ts +28 -0
  36. package/dist/core/iron-laws/definitions.d.ts.map +1 -0
  37. package/dist/core/iron-laws/definitions.js +180 -0
  38. package/dist/core/iron-laws/definitions.js.map +1 -0
  39. package/dist/core/iron-laws/index.d.ts +6 -0
  40. package/dist/core/iron-laws/index.d.ts.map +1 -0
  41. package/dist/core/iron-laws/index.js +22 -0
  42. package/dist/core/iron-laws/index.js.map +1 -0
  43. package/dist/core/session/clean-state.d.ts +17 -0
  44. package/dist/core/session/clean-state.d.ts.map +1 -0
  45. package/dist/core/session/clean-state.js +190 -0
  46. package/dist/core/session/clean-state.js.map +1 -0
  47. package/dist/core/session/index.d.ts +6 -0
  48. package/dist/core/session/index.d.ts.map +1 -0
  49. package/dist/core/session/index.js +15 -0
  50. package/dist/core/session/index.js.map +1 -0
  51. package/dist/core/session/startup.d.ts +47 -0
  52. package/dist/core/session/startup.d.ts.map +1 -0
  53. package/dist/core/session/startup.js +266 -0
  54. package/dist/core/session/startup.js.map +1 -0
  55. package/dist/core/validators/checkpoint.d.ts +88 -0
  56. package/dist/core/validators/checkpoint.d.ts.map +1 -0
  57. package/dist/core/validators/checkpoint.js +451 -0
  58. package/dist/core/validators/checkpoint.js.map +1 -0
  59. package/dist/core/validators/cso.d.ts +47 -0
  60. package/dist/core/validators/cso.d.ts.map +1 -0
  61. package/dist/core/validators/cso.js +88 -0
  62. package/dist/core/validators/cso.js.map +1 -0
  63. package/dist/core/validators/index.d.ts +9 -0
  64. package/dist/core/validators/index.d.ts.map +1 -0
  65. package/dist/core/validators/index.js +13 -0
  66. package/dist/core/validators/index.js.map +1 -0
  67. package/dist/core/validators/passes-gate.d.ts +76 -0
  68. package/dist/core/validators/passes-gate.d.ts.map +1 -0
  69. package/dist/core/validators/passes-gate.js +418 -0
  70. package/dist/core/validators/passes-gate.js.map +1 -0
  71. package/dist/index.d.ts +18 -0
  72. package/dist/index.d.ts.map +1 -0
  73. package/dist/index.js +52 -0
  74. package/dist/index.js.map +1 -0
  75. package/dist/presets/index.d.ts +14 -0
  76. package/dist/presets/index.d.ts.map +1 -0
  77. package/dist/presets/index.js +25 -0
  78. package/dist/presets/index.js.map +1 -0
  79. package/dist/presets/relaxed.d.ts +8 -0
  80. package/dist/presets/relaxed.d.ts.map +1 -0
  81. package/dist/presets/relaxed.js +24 -0
  82. package/dist/presets/relaxed.js.map +1 -0
  83. package/dist/presets/standard.d.ts +8 -0
  84. package/dist/presets/standard.d.ts.map +1 -0
  85. package/dist/presets/standard.js +51 -0
  86. package/dist/presets/standard.js.map +1 -0
  87. package/dist/presets/strict.d.ts +8 -0
  88. package/dist/presets/strict.d.ts.map +1 -0
  89. package/dist/presets/strict.js +51 -0
  90. package/dist/presets/strict.js.map +1 -0
  91. package/dist/types/checkpoint.d.ts +120 -0
  92. package/dist/types/checkpoint.d.ts.map +1 -0
  93. package/dist/types/checkpoint.js +6 -0
  94. package/dist/types/checkpoint.js.map +1 -0
  95. package/dist/types/cso.d.ts +35 -0
  96. package/dist/types/cso.d.ts.map +1 -0
  97. package/dist/types/cso.js +6 -0
  98. package/dist/types/cso.js.map +1 -0
  99. package/dist/types/index.d.ts +10 -0
  100. package/dist/types/index.d.ts.map +1 -0
  101. package/dist/types/index.js +24 -0
  102. package/dist/types/index.js.map +1 -0
  103. package/dist/types/iron-law.d.ts +113 -0
  104. package/dist/types/iron-law.d.ts.map +1 -0
  105. package/dist/types/iron-law.js +21 -0
  106. package/dist/types/iron-law.js.map +1 -0
  107. package/dist/types/passes-gate.d.ts +72 -0
  108. package/dist/types/passes-gate.d.ts.map +1 -0
  109. package/dist/types/passes-gate.js +6 -0
  110. package/dist/types/passes-gate.js.map +1 -0
  111. package/dist/types/session.d.ts +105 -0
  112. package/dist/types/session.d.ts.map +1 -0
  113. package/dist/types/session.js +6 -0
  114. package/dist/types/session.js.map +1 -0
  115. package/package.json +74 -0
  116. package/templates/nextjs-app/.github/workflows/ci.yml +39 -0
  117. package/templates/node-api/.github/workflows/ci.yml +36 -0
  118. package/templates/node-api/package.json +23 -0
  119. package/templates/node-api/src/index.ts +2 -0
  120. package/templates/node-api/tsconfig.json +19 -0
  121. package/templates/python-api/.github/workflows/ci.yml +39 -0
@@ -0,0 +1,244 @@
1
+ "use strict";
2
+ /**
3
+ * harness init 命令
4
+ *
5
+ * 初始化项目的 harness 配置
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.init = init;
45
+ const chalk_1 = __importDefault(require("chalk"));
46
+ const fs = __importStar(require("fs/promises"));
47
+ const path = __importStar(require("path"));
48
+ const yaml = __importStar(require("js-yaml"));
49
+ const validate_1 = require("./validate");
50
+ /**
51
+ * 默认配置
52
+ */
53
+ const DEFAULT_CONFIG = {
54
+ preset: 'standard',
55
+ enabled: true,
56
+ ironLaws: {
57
+ enforceErrors: true,
58
+ warnWarnings: true,
59
+ },
60
+ validators: {
61
+ checkpoint: true,
62
+ passesGate: true,
63
+ cso: false,
64
+ },
65
+ };
66
+ /**
67
+ * 预设配置
68
+ */
69
+ const PRESETS = {
70
+ strict: {
71
+ ...DEFAULT_CONFIG,
72
+ preset: 'strict',
73
+ ironLaws: {
74
+ enforceErrors: true,
75
+ warnWarnings: true,
76
+ },
77
+ validators: {
78
+ checkpoint: true,
79
+ passesGate: true,
80
+ cso: true,
81
+ },
82
+ },
83
+ standard: {
84
+ ...DEFAULT_CONFIG,
85
+ preset: 'standard',
86
+ },
87
+ relaxed: {
88
+ ...DEFAULT_CONFIG,
89
+ preset: 'relaxed',
90
+ ironLaws: {
91
+ enforceErrors: true,
92
+ warnWarnings: false,
93
+ },
94
+ },
95
+ };
96
+ /**
97
+ * 初始化项目
98
+ */
99
+ async function init(options) {
100
+ console.log(chalk_1.default.blue('🚀 初始化 harness 配置...'));
101
+ const projectPath = options.projectPath || process.cwd();
102
+ const configDir = path.join(projectPath, '.harness');
103
+ // 创建配置目录
104
+ await fs.mkdir(configDir, { recursive: true });
105
+ console.log(chalk_1.default.gray(`配置目录: ${configDir}`));
106
+ // 选择预设
107
+ const preset = PRESETS[options.preset];
108
+ console.log(chalk_1.default.gray(`预设: ${options.preset}`));
109
+ // 写入配置文件
110
+ const configPath = path.join(configDir, 'config.yml');
111
+ const configContent = yaml.dump(preset, { indent: 2 });
112
+ await fs.writeFile(configPath, configContent, 'utf-8');
113
+ console.log(chalk_1.default.green(`✅ 已创建配置文件: ${configPath}`));
114
+ // 创建检查点示例
115
+ await (0, validate_1.createExampleCheckpoint)(projectPath);
116
+ // 创建 CAPABILITIES.md(如果不存在)
117
+ const capabilitiesPath = path.join(projectPath, 'CAPABILITIES.md');
118
+ try {
119
+ await fs.access(capabilitiesPath);
120
+ console.log(chalk_1.default.gray(`CAPABILITIES.md 已存在`));
121
+ }
122
+ catch {
123
+ const capabilitiesContent = `# CAPABILITIES.md
124
+
125
+ ## 功能清单
126
+
127
+ > 此文件由 harness 自动维护,记录项目的核心功能
128
+
129
+ ### 最后更新
130
+ - 时间: ${new Date().toISOString()}
131
+ - 触发: harness init
132
+
133
+ ---
134
+
135
+ ## 核心模块
136
+
137
+ <!-- 在此记录项目的核心模块 -->
138
+
139
+ ## API 能力
140
+
141
+ <!-- 在此记录项目的 API 能力 -->
142
+
143
+ ## 依赖关系
144
+
145
+ <!-- 在此记录模块间的依赖关系 -->
146
+ `;
147
+ await fs.writeFile(capabilitiesPath, capabilitiesContent, 'utf-8');
148
+ console.log(chalk_1.default.green(`✅ 已创建 CAPABILITIES.md`));
149
+ }
150
+ // 创建 Git hooks
151
+ if (options.gitHooks !== false) {
152
+ await setupGitHooks(projectPath);
153
+ }
154
+ // 创建 GitHub Actions
155
+ if (options.githubActions !== false) {
156
+ await setupGitHubActions(projectPath, options.preset);
157
+ }
158
+ console.log();
159
+ console.log(chalk_1.default.green('✅ harness 初始化完成!'));
160
+ console.log();
161
+ console.log(chalk_1.default.gray('下一步:'));
162
+ console.log(chalk_1.default.gray(' 1. 编辑 .harness/config.yml 自定义配置'));
163
+ console.log(chalk_1.default.gray(' 2. 编辑 .harness/checkpoints.yml 添加检查点'));
164
+ console.log(chalk_1.default.gray(' 3. 运行 `harness check` 检查铁律'));
165
+ console.log(chalk_1.default.gray(' 4. 运行 `harness validate` 验证检查点'));
166
+ }
167
+ /**
168
+ * 设置 Git hooks
169
+ */
170
+ async function setupGitHooks(projectPath) {
171
+ const gitDir = path.join(projectPath, '.git');
172
+ const hooksDir = path.join(gitDir, 'hooks');
173
+ try {
174
+ await fs.access(gitDir);
175
+ }
176
+ catch {
177
+ console.log(chalk_1.default.yellow('⚠️ 未检测到 Git 仓库,跳过 Git hooks'));
178
+ return;
179
+ }
180
+ await fs.mkdir(hooksDir, { recursive: true });
181
+ // pre-commit hook
182
+ const preCommitPath = path.join(hooksDir, 'pre-commit');
183
+ const preCommitContent = `#!/bin/sh
184
+ # Harness pre-commit hook
185
+
186
+ echo "🔍 Running harness checks..."
187
+
188
+ # 铁律检查
189
+ npx harness check --staged
190
+ if [ $? -ne 0 ]; then
191
+ echo "❌ Iron law check failed"
192
+ exit 1
193
+ fi
194
+
195
+ echo "✅ All checks passed"
196
+ `;
197
+ await fs.writeFile(preCommitPath, preCommitContent, 'utf-8');
198
+ await fs.chmod(preCommitPath, 0o755);
199
+ console.log(chalk_1.default.green(`✅ 已创建 pre-commit hook`));
200
+ }
201
+ /**
202
+ * 设置 GitHub Actions
203
+ */
204
+ async function setupGitHubActions(projectPath, preset) {
205
+ const workflowsDir = path.join(projectPath, '.github', 'workflows');
206
+ await fs.mkdir(workflowsDir, { recursive: true });
207
+ // harness-check.yml
208
+ const workflowPath = path.join(workflowsDir, 'harness-check.yml');
209
+ const workflowContent = `name: Harness Check
210
+
211
+ on:
212
+ push:
213
+ branches: [main, master]
214
+ pull_request:
215
+ branches: [main, master]
216
+
217
+ jobs:
218
+ harness-check:
219
+ runs-on: ubuntu-latest
220
+
221
+ steps:
222
+ - uses: actions/checkout@v4
223
+
224
+ - name: Setup Node.js
225
+ uses: actions/setup-node@v4
226
+ with:
227
+ node-version: '20'
228
+
229
+ - name: Install dependencies
230
+ run: npm ci
231
+
232
+ - name: Run harness check
233
+ run: npx harness check
234
+
235
+ - name: Run harness validate
236
+ run: npx harness validate
237
+
238
+ - name: Run harness passes-gate
239
+ run: npx harness passes-gate
240
+ `;
241
+ await fs.writeFile(workflowPath, workflowContent, 'utf-8');
242
+ console.log(chalk_1.default.green(`✅ 已创建 GitHub Action: harness-check.yml`));
243
+ }
244
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * harness passes-gate 命令
3
+ *
4
+ * 运行测试门控,确保测试通过
5
+ */
6
+ export interface PassesGateOptions {
7
+ /** 测试命令 */
8
+ testCommand?: string;
9
+ /** 项目路径 */
10
+ projectPath?: string;
11
+ /** 是否允许部分通过 */
12
+ allowPartial?: boolean;
13
+ /** 最大重试次数 */
14
+ maxRetries?: number;
15
+ }
16
+ /**
17
+ * 执行测试门控
18
+ */
19
+ export declare function runPassesGate(options: PassesGateOptions): Promise<void>;
20
+ /**
21
+ * 检查测试覆盖率
22
+ */
23
+ export declare function checkCoverage(projectPath: string, threshold?: number): Promise<boolean>;
24
+ //# sourceMappingURL=passes-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passes-gate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/passes-gate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAQH,MAAM,WAAW,iBAAiB;IAChC,WAAW;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe;IACf,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,aAAa;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAoCD;;GAEG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,IAAI,CAAC,CA8D7E;AAED;;GAEG;AACH,wBAAsB,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,GAAE,MAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAiCjG"}
@@ -0,0 +1,171 @@
1
+ "use strict";
2
+ /**
3
+ * harness passes-gate 命令
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.runPassesGate = runPassesGate;
45
+ exports.checkCoverage = checkCoverage;
46
+ const chalk_1 = __importDefault(require("chalk"));
47
+ const fs = __importStar(require("fs/promises"));
48
+ const path = __importStar(require("path"));
49
+ const passes_gate_1 = require("../../core/validators/passes-gate");
50
+ /**
51
+ * 检测项目的测试命令
52
+ */
53
+ async function detectTestCommand(projectPath) {
54
+ const packageJsonPath = path.join(projectPath, 'package.json');
55
+ try {
56
+ const content = await fs.readFile(packageJsonPath, 'utf-8');
57
+ const pkg = JSON.parse(content);
58
+ if (pkg.scripts?.test && pkg.scripts.test !== 'echo "Error: no test specified"') {
59
+ return 'npm test';
60
+ }
61
+ if (pkg.scripts?.['test:ci']) {
62
+ return 'npm run test:ci';
63
+ }
64
+ }
65
+ catch {
66
+ // 没有 package.json
67
+ }
68
+ // 检查其他项目类型
69
+ try {
70
+ await fs.access(path.join(projectPath, 'pytest.ini'));
71
+ return 'pytest';
72
+ }
73
+ catch { }
74
+ try {
75
+ await fs.access(path.join(projectPath, 'go.mod'));
76
+ return 'go test ./...';
77
+ }
78
+ catch { }
79
+ return undefined;
80
+ }
81
+ /**
82
+ * 执行测试门控
83
+ */
84
+ async function runPassesGate(options) {
85
+ console.log(chalk_1.default.blue('🚦 运行测试门控...'));
86
+ const projectPath = options.projectPath || process.cwd();
87
+ // 检测测试命令
88
+ let testCommand = options.testCommand;
89
+ if (!testCommand) {
90
+ testCommand = await detectTestCommand(projectPath);
91
+ }
92
+ if (!testCommand) {
93
+ console.log(chalk_1.default.yellow('⚠️ 未检测到测试命令,跳过测试门控'));
94
+ console.log(chalk_1.default.gray('提示: 使用 --test-command 指定测试命令'));
95
+ return;
96
+ }
97
+ console.log(chalk_1.default.gray(`测试命令: ${testCommand}`));
98
+ // 配置
99
+ const config = {
100
+ enabled: true,
101
+ testCommand,
102
+ requireEvidence: false,
103
+ allowPartialPass: options.allowPartial || false,
104
+ maxRetries: options.maxRetries || 2,
105
+ };
106
+ // 执行测试
107
+ const passesGate = new passes_gate_1.PassesGate(config);
108
+ try {
109
+ const result = await passesGate.runTests();
110
+ console.log();
111
+ console.log(chalk_1.default.gray('测试结果:'));
112
+ console.log(chalk_1.default.gray(` 通过: ${result.passedTests}/${result.totalTests}`));
113
+ console.log(chalk_1.default.gray(` 失败: ${result.failedTests}/${result.totalTests}`));
114
+ console.log(chalk_1.default.gray(` 耗时: ${result.duration}ms`));
115
+ if (result.passed) {
116
+ console.log();
117
+ console.log(chalk_1.default.green('✅ 测试门控通过'));
118
+ console.log(chalk_1.default.green(' task.passes = true (由测试结果设置)'));
119
+ }
120
+ else {
121
+ console.log();
122
+ console.log(chalk_1.default.red('❌ 测试门控未通过'));
123
+ console.log(chalk_1.default.red(' task.passes = false'));
124
+ if (result.failures && result.failures.length > 0) {
125
+ console.log(chalk_1.default.red('\n失败的测试:'));
126
+ result.failures.forEach(f => {
127
+ console.log(chalk_1.default.red(` - ${f.name}: ${f.message}`));
128
+ });
129
+ }
130
+ process.exit(1);
131
+ }
132
+ }
133
+ catch (error) {
134
+ console.log(chalk_1.default.red(`\n❌ 测试执行失败: ${error.message}`));
135
+ process.exit(1);
136
+ }
137
+ }
138
+ /**
139
+ * 检查测试覆盖率
140
+ */
141
+ async function checkCoverage(projectPath, threshold = 80) {
142
+ console.log(chalk_1.default.blue(`📊 检查测试覆盖率 (阈值: ${threshold}%)...`));
143
+ try {
144
+ const { exec } = await Promise.resolve().then(() => __importStar(require('child_process')));
145
+ const { promisify } = await Promise.resolve().then(() => __importStar(require('util')));
146
+ const execAsync = promisify(exec);
147
+ // 运行覆盖率检查
148
+ await execAsync('npm test -- --coverage --coverageReporters=json-summary', {
149
+ cwd: projectPath,
150
+ });
151
+ // 读取覆盖率报告
152
+ const coveragePath = path.join(projectPath, 'coverage', 'coverage-summary.json');
153
+ const content = await fs.readFile(coveragePath, 'utf-8');
154
+ const coverage = JSON.parse(content);
155
+ const totalCoverage = coverage.total?.lines?.pct || 0;
156
+ console.log(chalk_1.default.gray(`当前覆盖率: ${totalCoverage}%`));
157
+ if (totalCoverage >= threshold) {
158
+ console.log(chalk_1.default.green(`✅ 覆盖率达标 (${totalCoverage}% >= ${threshold}%)`));
159
+ return true;
160
+ }
161
+ else {
162
+ console.log(chalk_1.default.red(`❌ 覆盖率不足 (${totalCoverage}% < ${threshold}%)`));
163
+ return false;
164
+ }
165
+ }
166
+ catch (error) {
167
+ console.log(chalk_1.default.yellow(`⚠️ 无法获取覆盖率信息: ${error.message}`));
168
+ return true; // 无法获取时跳过检查
169
+ }
170
+ }
171
+ //# sourceMappingURL=passes-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passes-gate.js","sourceRoot":"","sources":["../../../src/cli/commands/passes-gate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * harness report 命令
3
+ *
4
+ * 生成检查报告
5
+ */
6
+ export interface ReportOptions {
7
+ /** 输出文件路径 */
8
+ output?: string;
9
+ /** 输出格式 */
10
+ format: 'json' | 'markdown' | 'html';
11
+ /** 项目路径 */
12
+ projectPath?: string;
13
+ }
14
+ /**
15
+ * 生成检查报告
16
+ */
17
+ export declare function report(options: ReportOptions): Promise<void>;
18
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/report.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,WAAW,aAAa;IAC5B,aAAa;IACb,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW;IACX,MAAM,EAAE,MAAM,GAAG,UAAU,GAAG,MAAM,CAAC;IACrC,WAAW;IACX,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAmCD;;GAEG;AACH,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAyDlE"}