@dommaker/harness 0.18.0 → 1.0.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/CHANGELOG.md +23 -0
- package/bin/harness.js +136 -552
- package/dist/cli/commands/check.d.ts.map +1 -1
- package/dist/cli/commands/check.js +2 -13
- package/dist/cli/commands/check.js.map +1 -1
- package/dist/cli/commands/definitions.d.ts +90 -0
- package/dist/cli/commands/definitions.d.ts.map +1 -0
- package/dist/cli/commands/definitions.js +519 -0
- package/dist/cli/commands/definitions.js.map +1 -0
- package/dist/cli/commands/knowledge.js.map +1 -1
- package/dist/cli/commands/sync-docs/capabilities-syncer.d.ts +3 -25
- package/dist/cli/commands/sync-docs/capabilities-syncer.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/capabilities-syncer.js +3 -93
- package/dist/cli/commands/sync-docs/capabilities-syncer.js.map +1 -1
- package/dist/cli/commands/sync-docs/index.d.ts +1 -1
- package/dist/cli/commands/sync-docs/index.d.ts.map +1 -1
- package/dist/cli/commands/sync-docs/index.js +4 -4
- package/dist/cli/commands/sync-docs/index.js.map +1 -1
- package/dist/cli/commands/update-user-model.d.ts +1 -0
- package/dist/cli/commands/update-user-model.d.ts.map +1 -1
- package/dist/cli/commands/update-user-model.js +12 -5
- package/dist/cli/commands/update-user-model.js.map +1 -1
- package/dist/context/index.d.ts +1 -5
- package/dist/context/index.d.ts.map +1 -1
- package/dist/context/index.js +1 -5
- package/dist/context/index.js.map +1 -1
- package/dist/context/knowledge-injector.d.ts +3 -3
- package/dist/context/knowledge-injector.d.ts.map +1 -1
- package/dist/context/knowledge-injector.js +1 -1
- package/dist/context/session-manager.d.ts +1 -12
- package/dist/context/session-manager.d.ts.map +1 -1
- package/dist/context/session-manager.js +0 -63
- package/dist/context/session-manager.js.map +1 -1
- package/dist/context/types.d.ts +1 -39
- package/dist/context/types.d.ts.map +1 -1
- package/dist/context/types.js +2 -15
- package/dist/context/types.js.map +1 -1
- package/dist/core/constraints/agent-prompt-renderer.d.ts +32 -0
- package/dist/core/constraints/agent-prompt-renderer.d.ts.map +1 -0
- package/dist/core/constraints/agent-prompt-renderer.js +58 -0
- package/dist/core/constraints/agent-prompt-renderer.js.map +1 -0
- package/dist/core/constraints/capabilities-parser.d.ts +17 -2
- package/dist/core/constraints/capabilities-parser.d.ts.map +1 -1
- package/dist/core/constraints/capabilities-parser.js +84 -2
- package/dist/core/constraints/capabilities-parser.js.map +1 -1
- package/dist/core/constraints/check-cache.d.ts +48 -3
- package/dist/core/constraints/check-cache.d.ts.map +1 -1
- package/dist/core/constraints/check-cache.js +53 -5
- package/dist/core/constraints/check-cache.js.map +1 -1
- package/dist/core/constraints/checker.d.ts +3 -17
- package/dist/core/constraints/checker.d.ts.map +1 -1
- package/dist/core/constraints/checker.js +7 -47
- package/dist/core/constraints/checker.js.map +1 -1
- package/dist/core/constraints/definitions.d.ts +0 -7
- package/dist/core/constraints/definitions.d.ts.map +1 -1
- package/dist/core/constraints/definitions.js +1 -8
- package/dist/core/constraints/definitions.js.map +1 -1
- package/dist/core/constraints/doc-freshness/runner.d.ts +0 -2
- package/dist/core/constraints/doc-freshness/runner.d.ts.map +1 -1
- package/dist/core/constraints/doc-freshness/runner.js.map +1 -1
- package/dist/core/constraints/index.d.ts +5 -1
- package/dist/core/constraints/index.d.ts.map +1 -1
- package/dist/core/constraints/index.js +8 -3
- package/dist/core/constraints/index.js.map +1 -1
- package/dist/core/constraints/interceptor.d.ts.map +1 -1
- package/dist/core/constraints/interceptor.js +1 -5
- package/dist/core/constraints/interceptor.js.map +1 -1
- package/dist/core/effective-constraints.d.ts.map +1 -1
- package/dist/core/effective-constraints.js +0 -1
- package/dist/core/effective-constraints.js.map +1 -1
- package/dist/core/project-config-loader.d.ts.map +1 -1
- package/dist/core/project-config-loader.js +1 -8
- package/dist/core/project-config-loader.js.map +1 -1
- package/dist/dashboard/stats.d.ts.map +1 -1
- package/dist/dashboard/stats.js.map +1 -1
- package/dist/dashboard/types.d.ts +2 -2
- package/dist/dashboard/types.d.ts.map +1 -1
- package/dist/failure/constraint-handler.d.ts.map +1 -1
- package/dist/failure/constraint-handler.js +0 -2
- package/dist/failure/constraint-handler.js.map +1 -1
- package/dist/gates/acceptance.d.ts +9 -1
- package/dist/gates/acceptance.d.ts.map +1 -1
- package/dist/gates/acceptance.js +21 -0
- package/dist/gates/acceptance.js.map +1 -1
- package/dist/gates/checker-gate.d.ts +23 -0
- package/dist/gates/checker-gate.d.ts.map +1 -0
- package/dist/gates/checker-gate.js +53 -0
- package/dist/gates/checker-gate.js.map +1 -0
- package/dist/gates/command.d.ts +9 -2
- package/dist/gates/command.d.ts.map +1 -1
- package/dist/gates/command.js +10 -0
- package/dist/gates/command.js.map +1 -1
- package/dist/gates/contract.d.ts +8 -2
- package/dist/gates/contract.d.ts.map +1 -1
- package/dist/gates/contract.js +9 -0
- package/dist/gates/contract.js.map +1 -1
- package/dist/gates/decision.d.ts +17 -0
- package/dist/gates/decision.d.ts.map +1 -0
- package/dist/gates/decision.js +25 -0
- package/dist/gates/decision.js.map +1 -0
- package/dist/gates/definitions.d.ts +63 -0
- package/dist/gates/definitions.d.ts.map +1 -0
- package/dist/gates/definitions.js +160 -0
- package/dist/gates/definitions.js.map +1 -0
- package/dist/gates/effective-gates.d.ts +30 -0
- package/dist/gates/effective-gates.d.ts.map +1 -0
- package/dist/gates/effective-gates.js +85 -0
- package/dist/gates/effective-gates.js.map +1 -0
- package/dist/gates/index.d.ts +25 -1
- package/dist/gates/index.d.ts.map +1 -1
- package/dist/gates/index.js +37 -1
- package/dist/gates/index.js.map +1 -1
- package/dist/gates/performance.d.ts +8 -2
- package/dist/gates/performance.d.ts.map +1 -1
- package/dist/gates/performance.js +9 -0
- package/dist/gates/performance.js.map +1 -1
- package/dist/gates/registry.d.ts +32 -0
- package/dist/gates/registry.d.ts.map +1 -0
- package/dist/gates/registry.js +90 -0
- package/dist/gates/registry.js.map +1 -0
- package/dist/gates/review.d.ts +8 -2
- package/dist/gates/review.d.ts.map +1 -1
- package/dist/gates/review.js +9 -0
- package/dist/gates/review.js.map +1 -1
- package/dist/gates/runner.d.ts +30 -0
- package/dist/gates/runner.d.ts.map +1 -0
- package/dist/gates/runner.js +38 -0
- package/dist/gates/runner.js.map +1 -0
- package/dist/gates/security.d.ts +8 -2
- package/dist/gates/security.d.ts.map +1 -1
- package/dist/gates/security.js +9 -0
- package/dist/gates/security.js.map +1 -1
- package/dist/gates/types.d.ts +41 -1
- package/dist/gates/types.d.ts.map +1 -1
- package/dist/hooks/bootstrap.d.ts.map +1 -1
- package/dist/hooks/bootstrap.js +0 -2
- package/dist/hooks/bootstrap.js.map +1 -1
- package/dist/hooks/config.d.ts +26 -0
- package/dist/hooks/config.d.ts.map +1 -0
- package/dist/hooks/config.js +30 -0
- package/dist/hooks/config.js.map +1 -0
- package/dist/hooks/index.d.ts +2 -1
- package/dist/hooks/index.d.ts.map +1 -1
- package/dist/hooks/index.js +4 -1
- package/dist/hooks/index.js.map +1 -1
- package/dist/hooks/registry.d.ts +18 -1
- package/dist/hooks/registry.d.ts.map +1 -1
- package/dist/hooks/registry.js +45 -0
- package/dist/hooks/registry.js.map +1 -1
- package/dist/hooks/types.d.ts +20 -0
- package/dist/hooks/types.d.ts.map +1 -1
- package/dist/index.d.ts +8 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -21
- package/dist/index.js.map +1 -1
- package/dist/knowledge/import.d.ts +2 -2
- package/dist/knowledge/import.d.ts.map +1 -1
- package/dist/knowledge/ingest.js.map +1 -1
- package/dist/knowledge/lifecycle-hooks.d.ts +2 -2
- package/dist/knowledge/lifecycle-hooks.d.ts.map +1 -1
- package/dist/knowledge/types.d.ts +5 -7
- package/dist/knowledge/types.d.ts.map +1 -1
- package/dist/knowledge/types.js +1 -1
- package/dist/knowledge/types.js.map +1 -1
- package/dist/monitoring/constraint-doctor.d.ts +4 -22
- package/dist/monitoring/constraint-doctor.d.ts.map +1 -1
- package/dist/monitoring/constraint-doctor.js +7 -94
- package/dist/monitoring/constraint-doctor.js.map +1 -1
- package/dist/presets/standard.d.ts +1 -1
- package/dist/presets/standard.d.ts.map +1 -1
- package/dist/presets/standard.js +1 -2
- package/dist/presets/standard.js.map +1 -1
- package/dist/spec/annotation-checker.d.ts.map +1 -1
- package/dist/spec/annotation-checker.js +6 -26
- package/dist/spec/annotation-checker.js.map +1 -1
- package/dist/tools/index.d.ts +0 -4
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +0 -4
- package/dist/tools/index.js.map +1 -1
- package/dist/types/constraint.d.ts +1 -12
- package/dist/types/constraint.d.ts.map +1 -1
- package/dist/types/constraint.js +0 -3
- package/dist/types/constraint.js.map +1 -1
- package/dist/types/project-config.d.ts +0 -2
- package/dist/types/project-config.d.ts.map +1 -1
- package/dist/utils/file-walk.d.ts +2 -2
- package/dist/utils/file-walk.js +2 -2
- package/package.json +9 -4
- package/src/CONTEXT.md +14 -0
- package/src/__tests__/checker-extra.test.ts +2 -59
- package/src/__tests__/constraint-doctor.test.ts +1 -140
- package/src/__tests__/constraint-handler.test.ts +0 -4
- package/src/__tests__/project-config-loader-extra.test.ts +0 -20
- package/src/__tests__/project-config-loader.test.ts +0 -1
- package/src/cli/commands/CONTEXT.md +15 -7
- package/src/cli/commands/__tests__/analyze-sessions.test.ts +178 -0
- package/src/cli/commands/__tests__/check-drift.test.ts +0 -3
- package/src/cli/commands/__tests__/check-skip-output.test.ts +0 -5
- package/src/cli/commands/__tests__/check.test.ts +7 -75
- package/src/cli/commands/__tests__/registry.test.ts +201 -0
- package/src/cli/commands/__tests__/release.test.ts +162 -0
- package/src/cli/commands/__tests__/update-user-model.test.ts +205 -0
- package/src/cli/commands/check.ts +2 -14
- package/src/cli/commands/definitions.ts +593 -0
- package/src/cli/commands/knowledge.ts +3 -3
- package/src/cli/commands/sync-docs/capabilities-syncer.ts +4 -110
- package/src/cli/commands/sync-docs/index.ts +8 -5
- package/src/cli/commands/update-user-model.ts +15 -5
- package/src/context/CONTEXT.md +2 -7
- package/src/context/__tests__/session-manager.test.ts +0 -91
- package/src/context/index.ts +1 -5
- package/src/context/knowledge-injector.ts +3 -3
- package/src/context/session-manager.ts +0 -74
- package/src/context/types.ts +2 -63
- package/src/core/CONTEXT.md +1 -1
- package/src/core/constraints/__tests__/agent-prompt-renderer.test.ts +129 -0
- package/src/core/constraints/__tests__/check-cache.test.ts +227 -0
- package/src/core/constraints/__tests__/interceptor.test.ts +0 -2
- package/src/core/constraints/agent-prompt-renderer.ts +71 -0
- package/src/core/constraints/capabilities-parser.ts +95 -2
- package/src/core/constraints/check-cache.ts +75 -3
- package/src/core/constraints/checker.ts +8 -53
- package/src/core/constraints/definitions.ts +0 -8
- package/src/core/constraints/doc-freshness/runner.ts +1 -2
- package/src/core/constraints/index.ts +11 -2
- package/src/core/constraints/interceptor.ts +1 -6
- package/src/core/effective-constraints.ts +0 -1
- package/src/core/project-config-loader.ts +1 -7
- package/src/dashboard/stats.ts +2 -2
- package/src/dashboard/types.ts +2 -2
- package/src/failure/constraint-handler.ts +0 -2
- package/src/gates/CONTEXT.md +16 -13
- package/src/gates/__tests__/checker-gate.test.ts +45 -0
- package/src/gates/__tests__/contract.test.ts +73 -0
- package/src/gates/__tests__/effective-gates.test.ts +82 -0
- package/src/gates/__tests__/gate-interface.test.ts +202 -0
- package/src/gates/__tests__/registry.test.ts +87 -0
- package/src/gates/__tests__/runner.test.ts +81 -0
- package/src/gates/acceptance.ts +24 -1
- package/src/gates/checker-gate.ts +54 -0
- package/src/gates/command.ts +13 -2
- package/src/gates/contract.ts +12 -2
- package/src/gates/decision.ts +27 -0
- package/src/gates/definitions.ts +207 -0
- package/src/gates/effective-gates.ts +106 -0
- package/src/gates/index.ts +38 -0
- package/src/gates/performance.ts +12 -2
- package/src/gates/registry.ts +107 -0
- package/src/gates/review.ts +12 -2
- package/src/gates/runner.ts +57 -0
- package/src/gates/security.ts +12 -2
- package/src/gates/types.ts +48 -1
- package/src/hooks/CONTEXT.md +12 -2
- package/src/hooks/__tests__/bootstrap.test.ts +0 -1
- package/src/hooks/__tests__/config.test.ts +19 -0
- package/src/hooks/__tests__/pipeline.test.ts +79 -0
- package/src/hooks/__tests__/registry.test.ts +67 -0
- package/src/hooks/bootstrap.ts +0 -2
- package/src/hooks/config.ts +29 -0
- package/src/hooks/index.ts +2 -1
- package/src/hooks/registry.ts +60 -1
- package/src/hooks/types.ts +21 -0
- package/src/index.ts +13 -22
- package/src/knowledge/import.ts +3 -3
- package/src/knowledge/ingest.ts +4 -4
- package/src/knowledge/lifecycle-hooks.ts +3 -3
- package/src/knowledge/types.ts +5 -8
- package/src/monitoring/constraint-doctor.ts +7 -106
- package/src/presets/__tests__/standard.test.ts +0 -2
- package/src/presets/standard.ts +1 -2
- package/src/spec/__tests__/annotation-checker.test.ts +9 -3
- package/src/spec/annotation-checker.ts +7 -29
- package/src/tools/CONTEXT.md +7 -14
- package/src/tools/index.ts +0 -4
- package/src/types/constraint.ts +1 -14
- package/src/types/project-config.ts +0 -3
- package/src/utils/file-walk.ts +2 -2
- package/dist/architecture/constraint-engine.d.ts +0 -67
- package/dist/architecture/constraint-engine.d.ts.map +0 -1
- package/dist/architecture/constraint-engine.js +0 -295
- package/dist/architecture/constraint-engine.js.map +0 -1
- package/dist/architecture/cross-project-checker.d.ts +0 -54
- package/dist/architecture/cross-project-checker.d.ts.map +0 -1
- package/dist/architecture/cross-project-checker.js +0 -467
- package/dist/architecture/cross-project-checker.js.map +0 -1
- package/dist/cli/commands/index.d.ts +0 -30
- package/dist/cli/commands/index.d.ts.map +0 -1
- package/dist/cli/commands/index.js +0 -91
- package/dist/cli/commands/index.js.map +0 -1
- package/dist/context/file-budget.d.ts +0 -40
- package/dist/context/file-budget.d.ts.map +0 -1
- package/dist/context/file-budget.js +0 -147
- package/dist/context/file-budget.js.map +0 -1
- package/dist/context/progressive-loader.d.ts +0 -109
- package/dist/context/progressive-loader.d.ts.map +0 -1
- package/dist/context/progressive-loader.js +0 -166
- package/dist/context/progressive-loader.js.map +0 -1
- package/dist/context/token-pipeline.d.ts +0 -55
- package/dist/context/token-pipeline.d.ts.map +0 -1
- package/dist/context/token-pipeline.js +0 -220
- package/dist/context/token-pipeline.js.map +0 -1
- package/dist/context/tool-output-budget.d.ts +0 -59
- package/dist/context/tool-output-budget.d.ts.map +0 -1
- package/dist/context/tool-output-budget.js +0 -177
- package/dist/context/tool-output-budget.js.map +0 -1
- package/dist/core/constraints/default-executors.d.ts +0 -10
- package/dist/core/constraints/default-executors.d.ts.map +0 -1
- package/dist/core/constraints/default-executors.js +0 -120
- package/dist/core/constraints/default-executors.js.map +0 -1
- package/dist/llm/adapter.d.ts +0 -36
- package/dist/llm/adapter.d.ts.map +0 -1
- package/dist/llm/adapter.js +0 -118
- package/dist/llm/adapter.js.map +0 -1
- package/dist/llm/index.d.ts +0 -3
- package/dist/llm/index.d.ts.map +0 -1
- package/dist/llm/index.js +0 -19
- package/dist/llm/index.js.map +0 -1
- package/dist/llm/types.d.ts +0 -62
- package/dist/llm/types.d.ts.map +0 -1
- package/dist/llm/types.js +0 -8
- package/dist/llm/types.js.map +0 -1
- package/dist/tools/core/index.d.ts +0 -13
- package/dist/tools/core/index.d.ts.map +0 -1
- package/dist/tools/core/index.js +0 -198
- package/dist/tools/core/index.js.map +0 -1
- package/dist/tools/loader.d.ts +0 -21
- package/dist/tools/loader.d.ts.map +0 -1
- package/dist/tools/loader.js +0 -199
- package/dist/tools/loader.js.map +0 -1
- package/dist/tools/registry.d.ts +0 -59
- package/dist/tools/registry.d.ts.map +0 -1
- package/dist/tools/registry.js +0 -115
- package/dist/tools/registry.js.map +0 -1
- package/dist/tools/types.d.ts +0 -38
- package/dist/tools/types.d.ts.map +0 -1
- package/dist/tools/types.js +0 -6
- package/dist/tools/types.js.map +0 -1
- package/src/__tests__/architecture-engine.test.ts +0 -619
- package/src/__tests__/context/progressive-loader.test.ts +0 -131
- package/src/__tests__/cross-project-checker.test.ts +0 -318
- package/src/architecture/CONTEXT.md +0 -22
- package/src/architecture/constraint-engine.ts +0 -351
- package/src/architecture/cross-project-checker.ts +0 -545
- package/src/cli/commands/index.ts +0 -30
- package/src/context/__tests__/file-budget.test.ts +0 -142
- package/src/context/__tests__/progressive-loader.test.ts +0 -264
- package/src/context/__tests__/token-pipeline.test.ts +0 -178
- package/src/context/__tests__/tool-output-budget.test.ts +0 -95
- package/src/context/file-budget.ts +0 -142
- package/src/context/progressive-loader.ts +0 -260
- package/src/context/token-pipeline.ts +0 -265
- package/src/context/tool-output-budget.ts +0 -178
- package/src/core/constraints/__tests__/default-executors.test.ts +0 -57
- package/src/core/constraints/default-executors.ts +0 -92
- package/src/llm/CONTEXT.md +0 -21
- package/src/llm/__tests__/adapter.test.ts +0 -172
- package/src/llm/adapter.ts +0 -149
- package/src/llm/index.ts +0 -2
- package/src/llm/types.ts +0 -81
- package/src/tools/__tests__/loader.test.ts +0 -252
- package/src/tools/__tests__/registry.test.ts +0 -157
- package/src/tools/core/__tests__/core.test.ts +0 -122
- package/src/tools/core/index.ts +0 -201
- package/src/tools/loader.ts +0 -216
- package/src/tools/registry.ts +0 -128
- package/src/tools/types.ts +0 -46
|
@@ -1,545 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 跨工程接口契约检查
|
|
3
|
-
*
|
|
4
|
-
* 检测多工程开发时的接口不一致问题
|
|
5
|
-
*
|
|
6
|
-
* 可通过 CrossProjectConfig 自定义工程依赖关系和契约位置,
|
|
7
|
-
* 使此模块适用于任意多工程项目,而非仅限于 agent-studio 生态。
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
import { runCommand } from '../utils/exec';
|
|
11
|
-
import { findTsSourceFiles } from '../utils/file-walk';
|
|
12
|
-
import { existsSync, readFileSync } from 'fs';
|
|
13
|
-
import * as path from 'path';
|
|
14
|
-
|
|
15
|
-
export interface CrossProjectViolation {
|
|
16
|
-
type: 'api-mismatch' | 'doc-code-mismatch' | 'breaking-change' | 'missing-implementation';
|
|
17
|
-
severity: 'error' | 'warning';
|
|
18
|
-
message: string;
|
|
19
|
-
fromProject: string;
|
|
20
|
-
toProject: string;
|
|
21
|
-
details: {
|
|
22
|
-
interfaceName?: string;
|
|
23
|
-
fieldName?: string;
|
|
24
|
-
expectedType?: string;
|
|
25
|
-
actualType?: string;
|
|
26
|
-
location?: string;
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface CrossProjectContext {
|
|
31
|
-
baseBranch: string;
|
|
32
|
-
changedProjects: string[];
|
|
33
|
-
changedFiles: string[];
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* 跨工程检查配置
|
|
38
|
-
*
|
|
39
|
-
* 允许调用方自定义工程依赖关系和契约位置,
|
|
40
|
-
* 而非使用硬编码的默认值。
|
|
41
|
-
*/
|
|
42
|
-
export interface CrossProjectConfig {
|
|
43
|
-
/** 工程依赖关系图:project -> 它依赖的项目列表 */
|
|
44
|
-
dependencies: Record<string, string[]>;
|
|
45
|
-
/** 接口契约定义位置:pair name -> 文件路径列表 */
|
|
46
|
-
contractLocations: Record<string, string[]>;
|
|
47
|
-
/** 依赖过滤函数:筛选哪些包参与契约检查。默认不过滤(全部参与) */
|
|
48
|
-
dependencyFilter?: (depName: string) => boolean;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* 默认配置:从 monorepo 结构自动推断依赖关系
|
|
53
|
-
*/
|
|
54
|
-
function getDefaultConfig(): CrossProjectConfig {
|
|
55
|
-
const fs = require('fs');
|
|
56
|
-
const path = require('path');
|
|
57
|
-
const cwd = process.cwd();
|
|
58
|
-
|
|
59
|
-
// 扫描 packages/ 和 apps/ 下的 package.json 获取包名
|
|
60
|
-
const dependencies: Record<string, string[]> = {};
|
|
61
|
-
const contractLocations: Record<string, string[]> = {};
|
|
62
|
-
|
|
63
|
-
for (const dir of ['packages', 'apps']) {
|
|
64
|
-
const dirPath = path.join(cwd, dir);
|
|
65
|
-
if (!fs.existsSync(dirPath)) continue;
|
|
66
|
-
|
|
67
|
-
for (const entry of fs.readdirSync(dirPath)) {
|
|
68
|
-
const pkgJsonPath = path.join(dirPath, entry, 'package.json');
|
|
69
|
-
if (!fs.existsSync(pkgJsonPath)) continue;
|
|
70
|
-
|
|
71
|
-
try {
|
|
72
|
-
const pkgJson = JSON.parse(fs.readFileSync(pkgJsonPath, 'utf-8'));
|
|
73
|
-
const name = pkgJson.name || entry;
|
|
74
|
-
const deps = Object.keys({
|
|
75
|
-
...pkgJson.dependencies,
|
|
76
|
-
...pkgJson.peerDependencies,
|
|
77
|
-
});
|
|
78
|
-
// 默认不过滤,全部参与检查。调用方可通过 CrossProjectConfig.dependencyFilter 按需筛选
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
dependencies[name] = deps;
|
|
82
|
-
|
|
83
|
-
// 约定:src/api/ 或 src/index.ts 为接口契约位置
|
|
84
|
-
const srcDir = path.join(dirPath, entry, 'src');
|
|
85
|
-
if (fs.existsSync(srcDir)) {
|
|
86
|
-
contractLocations[name] = [path.join(dir, entry, 'src')];
|
|
87
|
-
}
|
|
88
|
-
} catch {
|
|
89
|
-
// package.json 解析失败,跳过
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return { dependencies, contractLocations };
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* 检查跨工程接口一致性
|
|
99
|
-
*
|
|
100
|
-
* @param context 跨工程上下文
|
|
101
|
-
* @param config 工程依赖关系和契约位置配置(可选,默认从 monorepo 自动推断)
|
|
102
|
-
*/
|
|
103
|
-
export async function checkCrossProjectContracts(
|
|
104
|
-
context: CrossProjectContext,
|
|
105
|
-
config?: CrossProjectConfig
|
|
106
|
-
): Promise<CrossProjectViolation[]> {
|
|
107
|
-
const violations: CrossProjectViolation[] = [];
|
|
108
|
-
const cfg = config || getDefaultConfig();
|
|
109
|
-
|
|
110
|
-
// 1. 检查 API 变更是否同步到调用方
|
|
111
|
-
violations.push(...await checkApiSync(context, cfg));
|
|
112
|
-
|
|
113
|
-
// 2. 检查类型定义一致性
|
|
114
|
-
violations.push(...await checkTypeConsistency(context, cfg));
|
|
115
|
-
|
|
116
|
-
// 3. 检查破坏性变更
|
|
117
|
-
violations.push(...await checkBreakingChanges(context, cfg));
|
|
118
|
-
|
|
119
|
-
return violations;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* 检查 API 变更同步
|
|
124
|
-
*/
|
|
125
|
-
async function checkApiSync(
|
|
126
|
-
context: CrossProjectContext,
|
|
127
|
-
config: CrossProjectConfig
|
|
128
|
-
): Promise<CrossProjectViolation[]> {
|
|
129
|
-
const violations: CrossProjectViolation[] = [];
|
|
130
|
-
|
|
131
|
-
for (const project of context.changedProjects) {
|
|
132
|
-
const dependents = getDependents(project, config);
|
|
133
|
-
const apiChanges = await getApiChanges(project, context.baseBranch);
|
|
134
|
-
|
|
135
|
-
for (const change of apiChanges) {
|
|
136
|
-
for (const dependent of dependents) {
|
|
137
|
-
const dependentUpdated = context.changedFiles.some(f =>
|
|
138
|
-
f.includes(`${dependent}/src/`)
|
|
139
|
-
);
|
|
140
|
-
|
|
141
|
-
if (!dependentUpdated && isPublicApi(change)) {
|
|
142
|
-
violations.push({
|
|
143
|
-
type: 'api-mismatch',
|
|
144
|
-
severity: 'error',
|
|
145
|
-
message: `'${project}' API '${change.name}' 变更未同步到 '${dependent}'`,
|
|
146
|
-
fromProject: project,
|
|
147
|
-
toProject: dependent,
|
|
148
|
-
details: {
|
|
149
|
-
interfaceName: change.name,
|
|
150
|
-
location: change.file,
|
|
151
|
-
},
|
|
152
|
-
});
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return violations;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* 检查类型定义一致性
|
|
163
|
-
*/
|
|
164
|
-
async function checkTypeConsistency(
|
|
165
|
-
context: CrossProjectContext,
|
|
166
|
-
config: CrossProjectConfig
|
|
167
|
-
): Promise<CrossProjectViolation[]> {
|
|
168
|
-
const violations: CrossProjectViolation[] = [];
|
|
169
|
-
|
|
170
|
-
for (const [pair] of Object.entries(config.contractLocations)) {
|
|
171
|
-
const [from, to] = pair.split('-');
|
|
172
|
-
if (!context.changedProjects.includes(from) && !context.changedProjects.includes(to)) {
|
|
173
|
-
continue;
|
|
174
|
-
}
|
|
175
|
-
|
|
176
|
-
const fromTypes = extractExportedTypes(from);
|
|
177
|
-
const toUsage = extractTypeUsage(to, fromTypes);
|
|
178
|
-
|
|
179
|
-
for (const [typeName, usage] of Object.entries(toUsage)) {
|
|
180
|
-
if (usage.hasMismatch) {
|
|
181
|
-
violations.push({
|
|
182
|
-
type: 'doc-code-mismatch',
|
|
183
|
-
severity: 'error',
|
|
184
|
-
message: `类型 '${typeName}' 在 ${to} 中的使用与 ${from} 定义不一致`,
|
|
185
|
-
fromProject: from,
|
|
186
|
-
toProject: to,
|
|
187
|
-
details: {
|
|
188
|
-
interfaceName: typeName,
|
|
189
|
-
expectedType: usage.expected,
|
|
190
|
-
actualType: usage.actual,
|
|
191
|
-
},
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
|
|
197
|
-
return violations;
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* 检查破坏性变更
|
|
202
|
-
*/
|
|
203
|
-
async function checkBreakingChanges(
|
|
204
|
-
context: CrossProjectContext,
|
|
205
|
-
config: CrossProjectConfig
|
|
206
|
-
): Promise<CrossProjectViolation[]> {
|
|
207
|
-
const violations: CrossProjectViolation[] = [];
|
|
208
|
-
|
|
209
|
-
for (const project of context.changedProjects) {
|
|
210
|
-
const dependents = getDependents(project, config);
|
|
211
|
-
|
|
212
|
-
for (const change of await getApiChanges(project, context.baseBranch)) {
|
|
213
|
-
if (isBreakingChange(change)) {
|
|
214
|
-
// 检查所有依赖方是否已适配
|
|
215
|
-
for (const dependent of dependents) {
|
|
216
|
-
const adapted = context.changedProjects.includes(dependent);
|
|
217
|
-
if (!adapted) {
|
|
218
|
-
violations.push({
|
|
219
|
-
type: 'breaking-change',
|
|
220
|
-
severity: 'error',
|
|
221
|
-
message: `破坏性变更 '${change.name}' 需要 ${dependent} 适配`,
|
|
222
|
-
fromProject: project,
|
|
223
|
-
toProject: dependent,
|
|
224
|
-
details: {
|
|
225
|
-
interfaceName: change.name,
|
|
226
|
-
location: change.file,
|
|
227
|
-
},
|
|
228
|
-
});
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
return violations;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/**
|
|
239
|
-
* 检查文档-代码一致性
|
|
240
|
-
* 场景:文档写了接口,代码没实现
|
|
241
|
-
*/
|
|
242
|
-
export async function checkDocCodeConsistency(
|
|
243
|
-
docPath: string,
|
|
244
|
-
projects: string[]
|
|
245
|
-
): Promise<CrossProjectViolation[]> {
|
|
246
|
-
const violations: CrossProjectViolation[] = [];
|
|
247
|
-
|
|
248
|
-
// 解析文档中的接口定义
|
|
249
|
-
const docInterfaces = parseDocInterfaces(docPath);
|
|
250
|
-
|
|
251
|
-
for (const [project, interfaces] of Object.entries(docInterfaces)) {
|
|
252
|
-
if (!projects.includes(project)) continue;
|
|
253
|
-
|
|
254
|
-
const actualExports = extractExportedApis(project);
|
|
255
|
-
|
|
256
|
-
for (const docInterface of interfaces) {
|
|
257
|
-
const implemented = actualExports.find(e => e.name === docInterface.name);
|
|
258
|
-
|
|
259
|
-
if (!implemented) {
|
|
260
|
-
violations.push({
|
|
261
|
-
type: 'missing-implementation',
|
|
262
|
-
severity: 'error',
|
|
263
|
-
message: `文档接口 '${docInterface.name}' 在 ${project} 中未实现`,
|
|
264
|
-
fromProject: 'documentation',
|
|
265
|
-
toProject: project,
|
|
266
|
-
details: {
|
|
267
|
-
interfaceName: docInterface.name,
|
|
268
|
-
location: docPath,
|
|
269
|
-
},
|
|
270
|
-
});
|
|
271
|
-
} else if (!isCompatible(docInterface, implemented)) {
|
|
272
|
-
violations.push({
|
|
273
|
-
type: 'doc-code-mismatch',
|
|
274
|
-
severity: 'warning',
|
|
275
|
-
message: `接口 '${docInterface.name}' 实现与文档不一致`,
|
|
276
|
-
fromProject: 'documentation',
|
|
277
|
-
toProject: project,
|
|
278
|
-
details: {
|
|
279
|
-
interfaceName: docInterface.name,
|
|
280
|
-
expectedType: JSON.stringify(docInterface.signature),
|
|
281
|
-
actualType: JSON.stringify(implemented.signature),
|
|
282
|
-
},
|
|
283
|
-
});
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
return violations;
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
// ============ 辅助函数 ============
|
|
292
|
-
|
|
293
|
-
async function getApiChanges(project: string, baseBranch: string): Promise<ApiChange[]> {
|
|
294
|
-
try {
|
|
295
|
-
const projectPath = resolveProjectPath(project);
|
|
296
|
-
|
|
297
|
-
const output = await runCommand(
|
|
298
|
-
`git diff ${baseBranch}...HEAD --name-only -- "${projectPath}/src/"`
|
|
299
|
-
);
|
|
300
|
-
|
|
301
|
-
const files = output.trim().split('\n').filter(f => f);
|
|
302
|
-
return Promise.all(files.map(async (f) => ({
|
|
303
|
-
file: f,
|
|
304
|
-
name: extractApiName(f),
|
|
305
|
-
changeType: await detectChangeType(f, baseBranch),
|
|
306
|
-
})));
|
|
307
|
-
} catch {
|
|
308
|
-
return [];
|
|
309
|
-
}
|
|
310
|
-
}
|
|
311
|
-
|
|
312
|
-
function isPublicApi(change: ApiChange): boolean {
|
|
313
|
-
// 检查是否为公开 API(导出、非内部)
|
|
314
|
-
return !change.name.startsWith('_') && !change.file.includes('/internal/');
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
function isBreakingChange(change: ApiChange): boolean {
|
|
318
|
-
// 检测是否为破坏性变更
|
|
319
|
-
return change.changeType === 'remove' ||
|
|
320
|
-
change.changeType === 'signature-change' ||
|
|
321
|
-
change.changeType === 'rename';
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
function getDependents(project: string, config: CrossProjectConfig): string[] {
|
|
325
|
-
return Object.entries(config.dependencies)
|
|
326
|
-
.filter(([, deps]) => deps.includes(project))
|
|
327
|
-
.map(([name]) => name);
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
interface ApiChange {
|
|
331
|
-
file: string;
|
|
332
|
-
name: string;
|
|
333
|
-
changeType: 'add' | 'remove' | 'modify' | 'rename' | 'signature-change';
|
|
334
|
-
}
|
|
335
|
-
|
|
336
|
-
// ============ 辅助函数实现 ============
|
|
337
|
-
|
|
338
|
-
function extractApiName(file: string): string {
|
|
339
|
-
return path.basename(file, '.ts');
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
async function detectChangeType(file: string, baseBranch: string): Promise<ApiChange['changeType']> {
|
|
343
|
-
try {
|
|
344
|
-
const statusOutput = await runCommand(
|
|
345
|
-
`git diff ${baseBranch}...HEAD --name-status -- "${file}"`
|
|
346
|
-
);
|
|
347
|
-
const statusLine = statusOutput.trim().split('\n')[0];
|
|
348
|
-
if (!statusLine) return 'modify';
|
|
349
|
-
|
|
350
|
-
const statusCode = statusLine.charAt(0);
|
|
351
|
-
if (statusCode === 'A') return 'add';
|
|
352
|
-
if (statusCode === 'D') return 'remove';
|
|
353
|
-
if (statusCode === 'R') return 'rename';
|
|
354
|
-
|
|
355
|
-
// M (modified) — check if export signatures changed
|
|
356
|
-
if (statusCode === 'M') {
|
|
357
|
-
const diff = await runCommand(`git diff ${baseBranch}...HEAD -- "${file}"`);
|
|
358
|
-
const signaturePattern = /^[+-]\s*export\s+(?:async\s+)?(?:function|interface|type|class|enum)\s+\w+/m;
|
|
359
|
-
if (signaturePattern.test(diff)) {
|
|
360
|
-
return 'signature-change';
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
|
|
364
|
-
return 'modify';
|
|
365
|
-
} catch {
|
|
366
|
-
return 'modify';
|
|
367
|
-
}
|
|
368
|
-
}
|
|
369
|
-
|
|
370
|
-
function extractExportedTypes(project: string): string[] {
|
|
371
|
-
const projectPath = resolveProjectPath(project);
|
|
372
|
-
const srcDir = path.join(projectPath, 'src');
|
|
373
|
-
const files = findTsSourceFiles(srcDir);
|
|
374
|
-
const types = new Set<string>();
|
|
375
|
-
|
|
376
|
-
for (const file of files) {
|
|
377
|
-
try {
|
|
378
|
-
const content = readFileSync(file, 'utf-8');
|
|
379
|
-
const regex = /export\s+(?:interface|type|enum)\s+(\w+)/g;
|
|
380
|
-
let match;
|
|
381
|
-
while ((match = regex.exec(content)) !== null) {
|
|
382
|
-
types.add(match[1]);
|
|
383
|
-
}
|
|
384
|
-
} catch {
|
|
385
|
-
// 文件读取失败,跳过
|
|
386
|
-
}
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
return [...types];
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
function extractTypeUsage(project: string, types: string[]): Record<string, { hasMismatch: boolean; expected?: string; actual?: string }> {
|
|
393
|
-
const projectPath = resolveProjectPath(project);
|
|
394
|
-
const srcDir = path.join(projectPath, 'src');
|
|
395
|
-
const files = findTsSourceFiles(srcDir);
|
|
396
|
-
const result: Record<string, { hasMismatch: boolean; expected?: string; actual?: string }> = {};
|
|
397
|
-
|
|
398
|
-
for (const typeName of types) {
|
|
399
|
-
let importedIn = false;
|
|
400
|
-
let usedIn = false;
|
|
401
|
-
|
|
402
|
-
for (const file of files) {
|
|
403
|
-
try {
|
|
404
|
-
const content = readFileSync(file, 'utf-8');
|
|
405
|
-
// 检查是否导入了该类型
|
|
406
|
-
const importRegex = new RegExp(`import\\s+(?:type\\s+)?\\{[^}]*\\b${typeName}\\b[^}]*\\}\\s+from`);
|
|
407
|
-
if (importRegex.test(content)) {
|
|
408
|
-
importedIn = true;
|
|
409
|
-
// 检查是否在 import 行之外使用了该类型
|
|
410
|
-
const lines = content.split('\n');
|
|
411
|
-
for (const line of lines) {
|
|
412
|
-
if (line.trim().startsWith('import ')) continue;
|
|
413
|
-
if (new RegExp(`\\b${typeName}\\b`).test(line)) {
|
|
414
|
-
usedIn = true;
|
|
415
|
-
break;
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
} catch {
|
|
420
|
-
// 文件读取失败,跳过
|
|
421
|
-
}
|
|
422
|
-
}
|
|
423
|
-
|
|
424
|
-
// 导入但未使用 → 可能是版本不一致
|
|
425
|
-
if (importedIn && !usedIn) {
|
|
426
|
-
result[typeName] = { hasMismatch: true, expected: typeName, actual: 'unused import' };
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
|
|
430
|
-
return result;
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
function parseDocInterfaces(docPath: string): Record<string, Array<{name: string, signature: string}>> {
|
|
434
|
-
if (!existsSync(docPath)) return {};
|
|
435
|
-
|
|
436
|
-
try {
|
|
437
|
-
const content = readFileSync(docPath, 'utf-8');
|
|
438
|
-
const lines = content.split('\n');
|
|
439
|
-
const result: Record<string, Array<{name: string, signature: string}>> = {};
|
|
440
|
-
let currentProject: string | null = null;
|
|
441
|
-
|
|
442
|
-
for (const line of lines) {
|
|
443
|
-
// 匹配 ## project-name
|
|
444
|
-
const headerMatch = line.match(/^##\s+(\S[\w-]*)/);
|
|
445
|
-
if (headerMatch) {
|
|
446
|
-
currentProject = headerMatch[1];
|
|
447
|
-
if (!result[currentProject]) result[currentProject] = [];
|
|
448
|
-
continue;
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
// 匹配 - `functionName(params): returnType`
|
|
452
|
-
if (currentProject) {
|
|
453
|
-
const sigMatch = line.match(/^-\s+`([^`]+)`/);
|
|
454
|
-
if (sigMatch) {
|
|
455
|
-
const signature = sigMatch[1];
|
|
456
|
-
const nameMatch = signature.match(/^(\w+)\s*\(/);
|
|
457
|
-
const name = nameMatch ? nameMatch[1] : signature;
|
|
458
|
-
result[currentProject].push({ name, signature });
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
return result;
|
|
464
|
-
} catch {
|
|
465
|
-
return {};
|
|
466
|
-
}
|
|
467
|
-
}
|
|
468
|
-
|
|
469
|
-
function extractExportedApis(project: string): Array<{name: string, signature: string}> {
|
|
470
|
-
const projectPath = resolveProjectPath(project);
|
|
471
|
-
const srcDir = path.join(projectPath, 'src');
|
|
472
|
-
const files = findTsSourceFiles(srcDir);
|
|
473
|
-
const apis: Array<{name: string, signature: string}> = [];
|
|
474
|
-
const seen = new Set<string>();
|
|
475
|
-
|
|
476
|
-
for (const file of files) {
|
|
477
|
-
try {
|
|
478
|
-
const content = readFileSync(file, 'utf-8');
|
|
479
|
-
|
|
480
|
-
// export function / export async function
|
|
481
|
-
const funcRegex = /export\s+(?:async\s+)?function\s+(\w+)\s*\(([^)]*)\)(?::\s*(\S+))?/g;
|
|
482
|
-
let match;
|
|
483
|
-
while ((match = funcRegex.exec(content)) !== null) {
|
|
484
|
-
const name = match[1];
|
|
485
|
-
if (seen.has(name)) continue;
|
|
486
|
-
seen.add(name);
|
|
487
|
-
const params = match[2] ? match[2].trim() : '';
|
|
488
|
-
const returnType = match[3] || 'void';
|
|
489
|
-
apis.push({ name, signature: `${name}(${params}): ${returnType}` });
|
|
490
|
-
}
|
|
491
|
-
|
|
492
|
-
// export class
|
|
493
|
-
const classRegex = /export\s+class\s+(\w+)/g;
|
|
494
|
-
while ((match = classRegex.exec(content)) !== null) {
|
|
495
|
-
const name = match[1];
|
|
496
|
-
if (!seen.has(name)) {
|
|
497
|
-
seen.add(name);
|
|
498
|
-
apis.push({ name, signature: name });
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
|
|
502
|
-
// export const arrow functions
|
|
503
|
-
const arrowRegex = /export\s+const\s+(\w+)\s*=\s*(?:async\s+)?\(/g;
|
|
504
|
-
while ((match = arrowRegex.exec(content)) !== null) {
|
|
505
|
-
const name = match[1];
|
|
506
|
-
if (!seen.has(name)) {
|
|
507
|
-
seen.add(name);
|
|
508
|
-
apis.push({ name, signature: name });
|
|
509
|
-
}
|
|
510
|
-
}
|
|
511
|
-
} catch {
|
|
512
|
-
// 文件读取失败,跳过
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
|
|
516
|
-
return apis;
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
function isCompatible(doc: any, actual: any): boolean {
|
|
520
|
-
return JSON.stringify(doc.signature) === JSON.stringify(actual.signature);
|
|
521
|
-
}
|
|
522
|
-
|
|
523
|
-
/**
|
|
524
|
-
* 解析项目在 monorepo 中的实际路径
|
|
525
|
-
* 支持 packages/xxx、apps/xxx、projects/xxx 三种常见结构
|
|
526
|
-
* 按优先级返回第一个存在的路径;都不存在时返回第一个候选(git 命令会优雅处理)
|
|
527
|
-
*/
|
|
528
|
-
function resolveProjectPath(project: string): string {
|
|
529
|
-
// 包名可能是 @scope/name 格式,取最后部分作为目录名
|
|
530
|
-
const dirName = project.includes('/') ? project.split('/').pop()! : project;
|
|
531
|
-
|
|
532
|
-
const candidates = [
|
|
533
|
-
path.join('packages', dirName),
|
|
534
|
-
path.join('apps', dirName),
|
|
535
|
-
path.join('projects', dirName),
|
|
536
|
-
path.join('packages', project), // 完整包名
|
|
537
|
-
];
|
|
538
|
-
|
|
539
|
-
for (const candidate of candidates) {
|
|
540
|
-
if (existsSync(candidate)) return candidate;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
// 都不存在时返回第一个候选(git 命令对不存在路径返回空,不会报错)
|
|
544
|
-
return candidates[0];
|
|
545
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* CLI 命令导出
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
export { check, listLaws, type CheckOptions } from './check';
|
|
6
|
-
export { validate, createExampleCheckpoint, DEFAULT_CHECKPOINTS, type ValidateOptions } from './validate';
|
|
7
|
-
export { runPassesGate, checkCoverage, type PassesGateOptions } from './passes-gate';
|
|
8
|
-
export { init, type InitOptions } from './init';
|
|
9
|
-
export { report, type ReportOptions } from './report';
|
|
10
|
-
export { status, type StatusOptions } from './status';
|
|
11
|
-
export { specValidate, listSpecTypes, type SpecValidateOptions } from './spec';
|
|
12
|
-
export { acceptance, listAcceptanceCriteria, type AcceptanceOptions } from './acceptance';
|
|
13
|
-
export { performance, type PerformanceOptions } from './performance';
|
|
14
|
-
export { security, auditDetails, type SecurityOptions } from './security';
|
|
15
|
-
export { contract, validateSchema, type ContractOptions } from './contract';
|
|
16
|
-
export { review, reviewStatus, type ReviewOptions } from './review';
|
|
17
|
-
export { executeCommand, type CommandCheckOptions } from './command';
|
|
18
|
-
export { syncDocs, type SyncDocsOptions } from './sync-docs';
|
|
19
|
-
export { knowledgeList, knowledgeSearch, knowledgeImport, knowledgeDecay, knowledgeStats, knowledgeUpsert, knowledgeSyncStatus, knowledgeSyncRag, knowledgeAudit, knowledgeSnapshot, knowledgeMigrate, knowledgeHealth, knowledgeIndex, type KnowledgeOptions, type KnowledgeUpsertOptions } from './knowledge';
|
|
20
|
-
export { failureList, failureStats, failureClear, type FailureOptions } from './failure';
|
|
21
|
-
export { postevalPlan, type PostEvalPlanOptions } from './posteval-plan';
|
|
22
|
-
export { release, type ReleaseOptions } from './release';
|
|
23
|
-
export { analyzeSessions, type AnalyzeSessionsOptions } from './analyze-sessions';
|
|
24
|
-
export { updateUserModel, type UpdateUserModelOptions } from './update-user-model';
|
|
25
|
-
export { constraints, getConstraintsMeta, type ConstraintsMeta } from './constraints';
|
|
26
|
-
export { constraintsReport, renderExportMarkdown, type ConstraintsReportOptions } from './constraints-report';
|
|
27
|
-
export { constraintsRetire, retireConstraint, runRetireInteractive, printRetireResult, type ConstraintsRetireOptions, type RetireResult, type RetireStatus } from './constraints-retire';
|
|
28
|
-
export { docFreshnessCheck, extractClaims, verifyClaims, type DocFreshnessCheckOptions, type ClaimResult, type ClaimType } from './doc-freshness-check';
|
|
29
|
-
export { specBaselineCheck, extractBaselineSection, type SpecBaselineCheckOptions, type PrerequisiteResult } from './spec-baseline-check';
|
|
30
|
-
export { sddIndex, type SDDOptions } from './sdd';
|