@dommaker/harness 0.7.3 → 0.7.4
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 +239 -2
- package/dist/architecture/constraint-engine.d.ts +49 -0
- package/dist/architecture/constraint-engine.d.ts.map +1 -0
- package/dist/architecture/constraint-engine.js +207 -0
- package/dist/architecture/constraint-engine.js.map +1 -0
- package/dist/architecture/cross-project-checker.d.ts +34 -0
- package/dist/architecture/cross-project-checker.d.ts.map +1 -0
- package/dist/architecture/cross-project-checker.js +260 -0
- package/dist/architecture/cross-project-checker.js.map +1 -0
- package/dist/context/progressive-loader.d.ts +110 -0
- package/dist/context/progressive-loader.d.ts.map +1 -0
- package/dist/context/progressive-loader.js +183 -0
- package/dist/context/progressive-loader.js.map +1 -0
- package/dist/context/token-budget.d.ts +144 -0
- package/dist/context/token-budget.d.ts.map +1 -0
- package/dist/context/token-budget.js +264 -0
- package/dist/context/token-budget.js.map +1 -0
- package/dist/core/constraints/definitions.d.ts.map +1 -1
- package/dist/core/constraints/definitions.js +33 -0
- package/dist/core/constraints/definitions.js.map +1 -1
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -1
- package/dist/failure/classifier.d.ts +63 -0
- package/dist/failure/classifier.d.ts.map +1 -0
- package/dist/failure/classifier.js +123 -0
- package/dist/failure/classifier.js.map +1 -0
- package/dist/failure/index.d.ts +10 -0
- package/dist/failure/index.d.ts.map +1 -0
- package/dist/failure/index.js +36 -0
- package/dist/failure/index.js.map +1 -0
- package/dist/failure/recorder.d.ts +78 -0
- package/dist/failure/recorder.d.ts.map +1 -0
- package/dist/failure/recorder.js +193 -0
- package/dist/failure/recorder.js.map +1 -0
- package/dist/failure/types.d.ts +89 -0
- package/dist/failure/types.d.ts.map +1 -0
- package/dist/failure/types.js +121 -0
- package/dist/failure/types.js.map +1 -0
- package/dist/gates/acceptance.d.ts +159 -0
- package/dist/gates/acceptance.d.ts.map +1 -0
- package/dist/gates/acceptance.js +368 -0
- package/dist/gates/acceptance.js.map +1 -0
- package/dist/gates/index.d.ts +5 -2
- package/dist/gates/index.d.ts.map +1 -1
- package/dist/gates/index.js +8 -1
- package/dist/gates/index.js.map +1 -1
- package/dist/gates/types.d.ts +33 -0
- package/dist/gates/types.d.ts.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +18 -5
- package/dist/index.js.map +1 -1
- package/dist/monitoring/index.d.ts +6 -0
- package/dist/monitoring/index.d.ts.map +1 -1
- package/dist/monitoring/index.js +6 -0
- package/dist/monitoring/index.js.map +1 -1
- package/dist/monitoring/performance-analyzer.d.ts +104 -0
- package/dist/monitoring/performance-analyzer.d.ts.map +1 -0
- package/dist/monitoring/performance-analyzer.js +417 -0
- package/dist/monitoring/performance-analyzer.js.map +1 -0
- package/dist/monitoring/performance-collector.d.ts +111 -0
- package/dist/monitoring/performance-collector.d.ts.map +1 -0
- package/dist/monitoring/performance-collector.js +319 -0
- package/dist/monitoring/performance-collector.js.map +1 -0
- package/dist/monitoring/trace-analyzer.js +1 -1
- package/dist/monitoring/trace-analyzer.js.map +1 -1
- package/dist/monitoring/traces.js +1 -1
- package/dist/monitoring/traces.js.map +1 -1
- package/dist/presets/index.d.ts +0 -1
- package/dist/presets/index.d.ts.map +1 -1
- package/dist/presets/index.js +1 -6
- package/dist/presets/index.js.map +1 -1
- package/dist/spec/annotation-checker.d.ts +47 -0
- package/dist/spec/annotation-checker.d.ts.map +1 -0
- package/dist/spec/annotation-checker.js +299 -0
- package/dist/spec/annotation-checker.js.map +1 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js +9 -0
- package/dist/types/index.js.map +1 -1
- package/dist/types/performance.d.ts +204 -0
- package/dist/types/performance.d.ts.map +1 -0
- package/dist/types/performance.js +12 -0
- package/dist/types/performance.js.map +1 -0
- package/package.json +3 -1
- package/dist/extensions/long-running/constraints.d.ts +0 -38
- package/dist/extensions/long-running/constraints.d.ts.map +0 -1
- package/dist/extensions/long-running/constraints.js +0 -153
- package/dist/extensions/long-running/constraints.js.map +0 -1
- package/dist/extensions/long-running/index.d.ts +0 -30
- package/dist/extensions/long-running/index.d.ts.map +0 -1
- package/dist/extensions/long-running/index.js +0 -50
- package/dist/extensions/long-running/index.js.map +0 -1
- package/dist/extensions/long-running/types.d.ts +0 -154
- package/dist/extensions/long-running/types.d.ts.map +0 -1
- package/dist/extensions/long-running/types.js +0 -9
- package/dist/extensions/long-running/types.js.map +0 -1
- package/dist/presets/long-running.d.ts +0 -33
- package/dist/presets/long-running.d.ts.map +0 -1
- package/dist/presets/long-running.js +0 -52
- package/dist/presets/long-running.js.map +0 -1
package/README.md
CHANGED
|
@@ -11,12 +11,14 @@
|
|
|
11
11
|
| 功能 | 说明 |
|
|
12
12
|
|------|------|
|
|
13
13
|
| **铁律系统** | 16 条内置约束(4 Iron Laws + 10 Guidelines + 2 Tips) |
|
|
14
|
-
| **门禁系统** |
|
|
14
|
+
| **门禁系统** | 7 种门禁(测试、审查、安全、性能、契约、检查点、验收标准) |
|
|
15
15
|
| **检查点验证** | 验证工作流步骤的结果是否符合预期 |
|
|
16
16
|
| **拦截器** | 抽象拦截框架,自动执行 enforcement |
|
|
17
17
|
| **Session 管理** | 启动检查点 + 结束状态管理 |
|
|
18
18
|
| **预设系统** | 提供 strict/standard/relaxed 三种预设 |
|
|
19
19
|
| **Execution Trace** | 轻量记录约束检查,异常检测,诊断系统 |
|
|
20
|
+
| **Performance Trace** | 性能日志收集,统计分析,异常检测(🆕) |
|
|
21
|
+
| **Failure Classification** | 错误分类,失败记录,等级映射(🆕) |
|
|
20
22
|
| **Spec 验证** | 验证架构文档、模块定义、API 定义 |
|
|
21
23
|
| **项目级自定义约束** | 扩展/覆盖内置约束,无需 fork |
|
|
22
24
|
| **CLI 工具** | 命令行工具执行检查 |
|
|
@@ -183,6 +185,7 @@ harness 提供完整的门禁系统,支持多种门禁类型:
|
|
|
183
185
|
| 性能门禁 | `PerformanceGate` | 响应时间、覆盖率、打包大小检查 |
|
|
184
186
|
| 契约门禁 | `ContractGate` | OpenAPI 契约验证 |
|
|
185
187
|
| 检查点验证 | `CheckpointValidator` | 验证工作流步骤结果 |
|
|
188
|
+
| 验收标准门禁 | `SpecAcceptanceGate` | 验证任务是否满足验收标准 |
|
|
186
189
|
|
|
187
190
|
**使用门禁**:
|
|
188
191
|
|
|
@@ -194,6 +197,7 @@ import {
|
|
|
194
197
|
PerformanceGate,
|
|
195
198
|
ContractGate,
|
|
196
199
|
CheckpointValidator,
|
|
200
|
+
SpecAcceptanceGate,
|
|
197
201
|
} from '@dommaker/harness';
|
|
198
202
|
|
|
199
203
|
// 测试门控
|
|
@@ -519,6 +523,60 @@ class ContractGate {
|
|
|
519
523
|
}
|
|
520
524
|
```
|
|
521
525
|
|
|
526
|
+
### SpecAcceptanceGate
|
|
527
|
+
|
|
528
|
+
验收标准门禁,用于验证任务是否满足验收标准:
|
|
529
|
+
|
|
530
|
+
```typescript
|
|
531
|
+
import { SpecAcceptanceGate } from '@dommaker/harness';
|
|
532
|
+
|
|
533
|
+
// 创建验收门禁
|
|
534
|
+
const acceptanceGate = new SpecAcceptanceGate({
|
|
535
|
+
tasksPath: './tasks.yml',
|
|
536
|
+
checkAllTasks: false,
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
// 检查单个任务
|
|
540
|
+
const result = await acceptanceGate.check({
|
|
541
|
+
projectPath: '/path/to/project',
|
|
542
|
+
taskId: 'task-001',
|
|
543
|
+
tasksPath: './tasks.yml',
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
// 检查所有任务
|
|
547
|
+
const allResults = await acceptanceGate.check({
|
|
548
|
+
projectPath: '/path/to/project',
|
|
549
|
+
checkAllTasks: true,
|
|
550
|
+
});
|
|
551
|
+
|
|
552
|
+
// 自定义验收条件
|
|
553
|
+
const customGate = new SpecAcceptanceGate({
|
|
554
|
+
customAcceptanceCriteria: {
|
|
555
|
+
'has-tests': async (task) => {
|
|
556
|
+
// 自定义验证逻辑
|
|
557
|
+
return true;
|
|
558
|
+
},
|
|
559
|
+
},
|
|
560
|
+
});
|
|
561
|
+
```
|
|
562
|
+
|
|
563
|
+
**验收标准格式(tasks.yml)**:
|
|
564
|
+
|
|
565
|
+
```yaml
|
|
566
|
+
tasks:
|
|
567
|
+
- id: task-001
|
|
568
|
+
title: 实现用户登录
|
|
569
|
+
acceptance_criteria:
|
|
570
|
+
- id: ac-1
|
|
571
|
+
description: 用户可以使用邮箱登录
|
|
572
|
+
type: automated
|
|
573
|
+
required: true
|
|
574
|
+
- id: ac-2
|
|
575
|
+
description: 登录失败显示错误提示
|
|
576
|
+
type: manual
|
|
577
|
+
required: true
|
|
578
|
+
```
|
|
579
|
+
|
|
522
580
|
### SessionStartup
|
|
523
581
|
|
|
524
582
|
```typescript
|
|
@@ -682,4 +740,183 @@ harness propose implement --diagnosis <id>
|
|
|
682
740
|
| 异常检测 | 每日 | 0(未触发)~500(触发) |
|
|
683
741
|
| Agent 诊断 | 按需 | ~2000 |
|
|
684
742
|
|
|
685
|
-
**对比 Meta-Harness**:百万级 vs 5500/周,成本降低 **180 倍**。
|
|
743
|
+
**对比 Meta-Harness**:百万级 vs 5500/周,成本降低 **180 倍**。
|
|
744
|
+
|
|
745
|
+
---
|
|
746
|
+
|
|
747
|
+
## Performance Trace 系统(v0.4+)
|
|
748
|
+
|
|
749
|
+
### 概念
|
|
750
|
+
|
|
751
|
+
Performance Trace 是性能数据的轻量记录,用于:
|
|
752
|
+
- 监控关键操作耗时
|
|
753
|
+
- 检测性能异常(慢操作、超阈值)
|
|
754
|
+
- 统计 Token 使用和上下文大小
|
|
755
|
+
- 为性能优化提供数据基础
|
|
756
|
+
|
|
757
|
+
### 设计原则
|
|
758
|
+
|
|
759
|
+
| 原则 | 说明 |
|
|
760
|
+
|------|------|
|
|
761
|
+
| **零 Token 成本** | 记录和统计都不调用 LLM |
|
|
762
|
+
| **文件存储** | 追加写入,单行 JSON 格式 |
|
|
763
|
+
| **异步分析** | 统计每小时执行,异常检测每日执行 |
|
|
764
|
+
| **可配置阈值** | 按操作类型设置不同的性能阈值 |
|
|
765
|
+
|
|
766
|
+
### Trace 数据结构
|
|
767
|
+
|
|
768
|
+
```typescript
|
|
769
|
+
interface PerformanceTrace {
|
|
770
|
+
operation: string; // 操作名称
|
|
771
|
+
startTime: number; // 开始时间戳
|
|
772
|
+
duration: number; // 耗时(毫秒)
|
|
773
|
+
status: 'ok' | 'exceeded' | 'error';
|
|
774
|
+
threshold?: number; // 配置的阈值
|
|
775
|
+
metadata?: Record<string, unknown>;
|
|
776
|
+
}
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
### API 使用
|
|
780
|
+
|
|
781
|
+
```typescript
|
|
782
|
+
import { PerformanceCollector, PerformanceAnalyzer } from '@dommaker/harness';
|
|
783
|
+
|
|
784
|
+
// 创建收集器
|
|
785
|
+
const collector = new PerformanceCollector({
|
|
786
|
+
logFile: '.harness/logs/performance.log',
|
|
787
|
+
thresholds: {
|
|
788
|
+
extract: 1000, // 提取操作阈值 1s
|
|
789
|
+
transform: 500, // 转换操作阈值 500ms
|
|
790
|
+
invoke: 10000, // 调用操作阈值 10s
|
|
791
|
+
},
|
|
792
|
+
});
|
|
793
|
+
|
|
794
|
+
// 记录操作
|
|
795
|
+
await collector.recordOk('extract', 150, { contextSize: 5000 });
|
|
796
|
+
await collector.recordExceeded('invoke', 12000, 10000, { agent: 'skill-agent' });
|
|
797
|
+
|
|
798
|
+
// 分析统计
|
|
799
|
+
const analyzer = new PerformanceAnalyzer();
|
|
800
|
+
const summaries = analyzer.summarize(traces);
|
|
801
|
+
const anomalies = analyzer.detectAnomalies(traces);
|
|
802
|
+
|
|
803
|
+
// 生成报告
|
|
804
|
+
const report = analyzer.generateReport(summaries, anomalies);
|
|
805
|
+
```
|
|
806
|
+
|
|
807
|
+
### 文件位置
|
|
808
|
+
|
|
809
|
+
```
|
|
810
|
+
.harness/logs/
|
|
811
|
+
├── performance.log # 性能日志
|
|
812
|
+
├── performance-summary.json # 统计汇总
|
|
813
|
+
└── tokens.log # Token 使用日志
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
### 与 TraceCollector 对比
|
|
817
|
+
|
|
818
|
+
| 能力 | TraceCollector | PerformanceCollector |
|
|
819
|
+
|------|----------------|---------------------|
|
|
820
|
+
| **监控目标** | 约束检查结果 | 操作耗时 |
|
|
821
|
+
| **监控"什么"** | 对不对 | 快不快 |
|
|
822
|
+
| **异常类型** | 高绕过率、失败率上升 | 慢操作、超阈值 |
|
|
823
|
+
| **存储路径** | `.harness/logs/traces.log` | `.harness/logs/performance.log` |
|
|
824
|
+
|
|
825
|
+
---
|
|
826
|
+
|
|
827
|
+
## Failure Classification 系统(v0.4+)
|
|
828
|
+
|
|
829
|
+
### 概念
|
|
830
|
+
|
|
831
|
+
Failure Classification 提供通用的错误分类和记录能力,用于:
|
|
832
|
+
- 统一错误分类标准
|
|
833
|
+
- 分级处理失败(L1-L4)
|
|
834
|
+
- 记录失败历史供分析
|
|
835
|
+
|
|
836
|
+
### 设计原则
|
|
837
|
+
|
|
838
|
+
| 原则 | 说明 |
|
|
839
|
+
|------|------|
|
|
840
|
+
| **零业务逻辑** | 只提供类型 + 分类 + 记录能力 |
|
|
841
|
+
| **可扩展规则** | 支持自定义分类规则 |
|
|
842
|
+
| **文件存储** | 追加写入,单行 JSON 格式 |
|
|
843
|
+
|
|
844
|
+
### 错误类型
|
|
845
|
+
|
|
846
|
+
```typescript
|
|
847
|
+
enum ErrorType {
|
|
848
|
+
TEST_FAILED = 'TEST_FAILED', // 测试失败
|
|
849
|
+
GATE_FAILED = 'GATE_FAILED', // 门禁检查失败
|
|
850
|
+
DEPENDENCY_BLOCKED = 'DEPENDENCY_BLOCKED', // 依赖阻塞
|
|
851
|
+
CONTEXT_OVERFLOW = 'CONTEXT_OVERFLOW', // 上下文溢出
|
|
852
|
+
TIMEOUT = 'TIMEOUT', // 超时
|
|
853
|
+
NETWORK_ERROR = 'NETWORK_ERROR', // 网络错误
|
|
854
|
+
AGENT_ERROR = 'AGENT_ERROR', // Agent 错误
|
|
855
|
+
TOOL_ERROR = 'TOOL_ERROR', // 工具错误
|
|
856
|
+
VALIDATION_ERROR = 'VALIDATION_ERROR', // 验证错误
|
|
857
|
+
UNKNOWN = 'UNKNOWN', // 未知错误
|
|
858
|
+
}
|
|
859
|
+
```
|
|
860
|
+
|
|
861
|
+
### 失败等级
|
|
862
|
+
|
|
863
|
+
| 等级 | 说明 | 处理策略 |
|
|
864
|
+
|------|------|---------|
|
|
865
|
+
| L1 | 自动重试 | 重试、降级 |
|
|
866
|
+
| L2 | 需要干预 | 人工审核 |
|
|
867
|
+
| L3 | 严重问题 | 开会讨论 |
|
|
868
|
+
| L4 | 致命错误 | 回滚 |
|
|
869
|
+
|
|
870
|
+
### API 使用
|
|
871
|
+
|
|
872
|
+
```typescript
|
|
873
|
+
import {
|
|
874
|
+
ErrorClassifier,
|
|
875
|
+
FailureRecorder,
|
|
876
|
+
ErrorType,
|
|
877
|
+
FailureLevel,
|
|
878
|
+
classifyError,
|
|
879
|
+
} from '@dommaker/harness';
|
|
880
|
+
|
|
881
|
+
// 快速分类
|
|
882
|
+
const type = classifyError(new Error('test failed'));
|
|
883
|
+
// type === ErrorType.TEST_FAILED
|
|
884
|
+
|
|
885
|
+
// 完整分类器
|
|
886
|
+
const classifier = new ErrorClassifier({
|
|
887
|
+
rules: [
|
|
888
|
+
{
|
|
889
|
+
type: ErrorType.CUSTOM_ERROR,
|
|
890
|
+
keywords: ['custom', 'specific'],
|
|
891
|
+
level: FailureLevel.L2,
|
|
892
|
+
},
|
|
893
|
+
],
|
|
894
|
+
});
|
|
895
|
+
|
|
896
|
+
const result = classifier.classify(new Error('custom error'));
|
|
897
|
+
// result.type, result.level, result.matchedRule
|
|
898
|
+
|
|
899
|
+
// 失败记录
|
|
900
|
+
const recorder = new FailureRecorder({
|
|
901
|
+
logFile: '.harness/logs/failures.log',
|
|
902
|
+
});
|
|
903
|
+
|
|
904
|
+
await recorder.record({
|
|
905
|
+
type: ErrorType.TEST_FAILED,
|
|
906
|
+
level: FailureLevel.L1,
|
|
907
|
+
message: 'Test failed',
|
|
908
|
+
timestamp: Date.now(),
|
|
909
|
+
});
|
|
910
|
+
|
|
911
|
+
// 获取统计
|
|
912
|
+
const stats = await recorder.getStats();
|
|
913
|
+
// { total, byType, byLevel }
|
|
914
|
+
```
|
|
915
|
+
|
|
916
|
+
### 与 PerformanceCollector 对比
|
|
917
|
+
|
|
918
|
+
| 能力 | PerformanceCollector | FailureRecorder |
|
|
919
|
+
|------|---------------------|-----------------|
|
|
920
|
+
| **监控目标** | 操作耗时 | 错误分类 |
|
|
921
|
+
| **存储内容** | 性能指标 | 失败记录 |
|
|
922
|
+
| **分析维度** | 慢操作、超阈值 | 错误类型分布、失败等级 |
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 架构约束引擎
|
|
3
|
+
*
|
|
4
|
+
* 通用能力:加载规则、执行检查、生成报告
|
|
5
|
+
* 规则定义:由项目提供(.architect/rules.yml)
|
|
6
|
+
*/
|
|
7
|
+
export interface ArchitectureContext {
|
|
8
|
+
files: string[];
|
|
9
|
+
diff: string;
|
|
10
|
+
pr?: {
|
|
11
|
+
number: number;
|
|
12
|
+
changedFiles: number;
|
|
13
|
+
additions: number;
|
|
14
|
+
deletions: number;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export interface ArchitectureViolation {
|
|
18
|
+
ruleId: string;
|
|
19
|
+
message: string;
|
|
20
|
+
files?: string[];
|
|
21
|
+
severity: 'error' | 'warning';
|
|
22
|
+
}
|
|
23
|
+
export interface ArchitectureResult {
|
|
24
|
+
passed: boolean;
|
|
25
|
+
violations: ArchitectureViolation[];
|
|
26
|
+
}
|
|
27
|
+
export interface ArchitectureRule {
|
|
28
|
+
id: string;
|
|
29
|
+
type: 'forbidden-pattern' | 'file-count' | 'module-boundary' | 'custom';
|
|
30
|
+
severity?: 'error' | 'warning';
|
|
31
|
+
scope?: string;
|
|
32
|
+
message?: string;
|
|
33
|
+
patterns?: string[];
|
|
34
|
+
threshold?: number;
|
|
35
|
+
script?: string;
|
|
36
|
+
}
|
|
37
|
+
export declare class ArchitectureConstraintEngine {
|
|
38
|
+
private rules;
|
|
39
|
+
constructor(rules: ArchitectureRule[]);
|
|
40
|
+
check(context: ArchitectureContext): Promise<ArchitectureResult>;
|
|
41
|
+
private checkRule;
|
|
42
|
+
private checkForbiddenPattern;
|
|
43
|
+
private checkFileCount;
|
|
44
|
+
private checkModuleBoundary;
|
|
45
|
+
private matchGlob;
|
|
46
|
+
}
|
|
47
|
+
export declare function loadArchitectureRules(configPath: string): Promise<ArchitectureRule[]>;
|
|
48
|
+
export declare function runArchitectureCheck(configPath: string, context: ArchitectureContext): Promise<ArchitectureResult>;
|
|
49
|
+
//# sourceMappingURL=constraint-engine.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constraint-engine.d.ts","sourceRoot":"","sources":["../../src/architecture/constraint-engine.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE;QACH,MAAM,EAAE,MAAM,CAAC;QACf,YAAY,EAAE,MAAM,CAAC;QACrB,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,qBAAqB;IACpC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;CAC/B;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,OAAO,CAAC;IAChB,UAAU,EAAE,qBAAqB,EAAE,CAAC;CACrC;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,mBAAmB,GAAG,YAAY,GAAG,iBAAiB,GAAG,QAAQ,CAAC;IACxE,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IAE/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IAEpB,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,4BAA4B;IAC3B,OAAO,CAAC,KAAK;gBAAL,KAAK,EAAE,gBAAgB,EAAE;IAEvC,KAAK,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC;YAcxD,SAAS;IAgBvB,OAAO,CAAC,qBAAqB;IA6B7B,OAAO,CAAC,cAAc;IAkBtB,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,SAAS;CAkBlB;AAGD,wBAAsB,qBAAqB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAgB3F;AAiED,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,kBAAkB,CAAC,CAI7B"}
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* 架构约束引擎
|
|
4
|
+
*
|
|
5
|
+
* 通用能力:加载规则、执行检查、生成报告
|
|
6
|
+
* 规则定义:由项目提供(.architect/rules.yml)
|
|
7
|
+
*/
|
|
8
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
9
|
+
if (k2 === undefined) k2 = k;
|
|
10
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
11
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
12
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
13
|
+
}
|
|
14
|
+
Object.defineProperty(o, k2, desc);
|
|
15
|
+
}) : (function(o, m, k, k2) {
|
|
16
|
+
if (k2 === undefined) k2 = k;
|
|
17
|
+
o[k2] = m[k];
|
|
18
|
+
}));
|
|
19
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
20
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
21
|
+
}) : function(o, v) {
|
|
22
|
+
o["default"] = v;
|
|
23
|
+
});
|
|
24
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
25
|
+
var ownKeys = function(o) {
|
|
26
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
27
|
+
var ar = [];
|
|
28
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
29
|
+
return ar;
|
|
30
|
+
};
|
|
31
|
+
return ownKeys(o);
|
|
32
|
+
};
|
|
33
|
+
return function (mod) {
|
|
34
|
+
if (mod && mod.__esModule) return mod;
|
|
35
|
+
var result = {};
|
|
36
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
37
|
+
__setModuleDefault(result, mod);
|
|
38
|
+
return result;
|
|
39
|
+
};
|
|
40
|
+
})();
|
|
41
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
42
|
+
exports.ArchitectureConstraintEngine = void 0;
|
|
43
|
+
exports.loadArchitectureRules = loadArchitectureRules;
|
|
44
|
+
exports.runArchitectureCheck = runArchitectureCheck;
|
|
45
|
+
class ArchitectureConstraintEngine {
|
|
46
|
+
rules;
|
|
47
|
+
constructor(rules) {
|
|
48
|
+
this.rules = rules;
|
|
49
|
+
}
|
|
50
|
+
async check(context) {
|
|
51
|
+
const violations = [];
|
|
52
|
+
for (const rule of this.rules) {
|
|
53
|
+
const result = await this.checkRule(rule, context);
|
|
54
|
+
violations.push(...result);
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
passed: violations.filter(v => v.severity === 'error').length === 0,
|
|
58
|
+
violations,
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
async checkRule(rule, context) {
|
|
62
|
+
switch (rule.type) {
|
|
63
|
+
case 'forbidden-pattern':
|
|
64
|
+
return this.checkForbiddenPattern(rule, context);
|
|
65
|
+
case 'file-count':
|
|
66
|
+
return this.checkFileCount(rule, context);
|
|
67
|
+
case 'module-boundary':
|
|
68
|
+
return this.checkModuleBoundary(rule, context);
|
|
69
|
+
default:
|
|
70
|
+
return [];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
checkForbiddenPattern(rule, context) {
|
|
74
|
+
const violations = [];
|
|
75
|
+
const patterns = rule.patterns || [];
|
|
76
|
+
for (const file of context.files) {
|
|
77
|
+
// 检查文件路径是否匹配 scope
|
|
78
|
+
if (rule.scope && !this.matchGlob(file, rule.scope)) {
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
// 检查文件名是否包含禁止模式
|
|
82
|
+
for (const pattern of patterns) {
|
|
83
|
+
if (file.toLowerCase().includes(pattern.toLowerCase())) {
|
|
84
|
+
violations.push({
|
|
85
|
+
ruleId: rule.id,
|
|
86
|
+
message: rule.message || `File contains forbidden pattern: ${pattern}`,
|
|
87
|
+
files: [file],
|
|
88
|
+
severity: rule.severity || 'error',
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
return violations;
|
|
94
|
+
}
|
|
95
|
+
checkFileCount(rule, context) {
|
|
96
|
+
const threshold = rule.threshold || 3;
|
|
97
|
+
const count = context.files.length;
|
|
98
|
+
if (count > threshold) {
|
|
99
|
+
return [{
|
|
100
|
+
ruleId: rule.id,
|
|
101
|
+
message: rule.message || `Too many files changed (${count} > ${threshold}). Reuse check required.`,
|
|
102
|
+
severity: rule.severity || 'warning',
|
|
103
|
+
}];
|
|
104
|
+
}
|
|
105
|
+
return [];
|
|
106
|
+
}
|
|
107
|
+
checkModuleBoundary(rule, context) {
|
|
108
|
+
// TODO: 实现模块边界检查
|
|
109
|
+
return [];
|
|
110
|
+
}
|
|
111
|
+
matchGlob(file, pattern) {
|
|
112
|
+
// 简化的 glob 匹配
|
|
113
|
+
let regexPattern = pattern;
|
|
114
|
+
// 处理 **/ 开头(匹配任意前缀路径)
|
|
115
|
+
if (regexPattern.startsWith('**/')) {
|
|
116
|
+
regexPattern = '(?:.*/)?' + regexPattern.slice(3);
|
|
117
|
+
}
|
|
118
|
+
// 处理 /**/(匹配任意中间路径)和 **(匹配任意字符)
|
|
119
|
+
regexPattern = regexPattern
|
|
120
|
+
.replace(/\/\*\*\//g, '/(?:.*/)?') // /**/ -> /(?:.*/)?
|
|
121
|
+
.replace(/\*\*/g, '.*') // ** -> .*
|
|
122
|
+
.replace(/\*/g, '[^/]*'); // * -> [^/]*
|
|
123
|
+
const regex = new RegExp(regexPattern);
|
|
124
|
+
return regex.test(file);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
exports.ArchitectureConstraintEngine = ArchitectureConstraintEngine;
|
|
128
|
+
// 加载规则的工厂函数(支持 YAML 或 JSON)
|
|
129
|
+
async function loadArchitectureRules(configPath) {
|
|
130
|
+
const fs = await Promise.resolve().then(() => __importStar(require('fs/promises')));
|
|
131
|
+
const content = await fs.readFile(configPath, 'utf-8');
|
|
132
|
+
// 简单 YAML 解析(不依赖外部库)
|
|
133
|
+
let config;
|
|
134
|
+
if (configPath.endsWith('.json')) {
|
|
135
|
+
config = JSON.parse(content);
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
// 简单 YAML 解析:提取 rules 数组
|
|
139
|
+
config = parseSimpleYaml(content);
|
|
140
|
+
}
|
|
141
|
+
return config.rules || [];
|
|
142
|
+
}
|
|
143
|
+
// 简单的 YAML 子集解析器
|
|
144
|
+
function parseSimpleYaml(content) {
|
|
145
|
+
const lines = content.split('\n');
|
|
146
|
+
const result = { rules: [] };
|
|
147
|
+
let currentRule = null;
|
|
148
|
+
let currentArray = null;
|
|
149
|
+
let indentLevel = 0;
|
|
150
|
+
for (const line of lines) {
|
|
151
|
+
const trimmed = line.trim();
|
|
152
|
+
// 跳过注释和空行
|
|
153
|
+
if (!trimmed || trimmed.startsWith('#'))
|
|
154
|
+
continue;
|
|
155
|
+
// 检测缩进级别
|
|
156
|
+
const leadingSpace = line.length - line.trimStart().length;
|
|
157
|
+
// 新规则开始
|
|
158
|
+
if (trimmed.startsWith('- id:')) {
|
|
159
|
+
if (currentRule && result.rules) {
|
|
160
|
+
result.rules.push(currentRule);
|
|
161
|
+
}
|
|
162
|
+
currentRule = { id: trimmed.replace('- id:', '').trim() };
|
|
163
|
+
currentArray = null;
|
|
164
|
+
indentLevel = leadingSpace;
|
|
165
|
+
}
|
|
166
|
+
// 规则属性
|
|
167
|
+
else if (currentRule && trimmed.includes(':')) {
|
|
168
|
+
const colonIndex = trimmed.indexOf(':');
|
|
169
|
+
const key = trimmed.slice(0, colonIndex).trim();
|
|
170
|
+
const value = trimmed.slice(colonIndex + 1).trim();
|
|
171
|
+
if (key === 'patterns') {
|
|
172
|
+
currentArray = [];
|
|
173
|
+
currentRule[key] = currentArray;
|
|
174
|
+
}
|
|
175
|
+
else if (value) {
|
|
176
|
+
// 去除引号
|
|
177
|
+
const cleanValue = value.replace(/^["']|["']$/g, '');
|
|
178
|
+
if (key === 'threshold') {
|
|
179
|
+
currentRule[key] = parseInt(cleanValue, 10);
|
|
180
|
+
}
|
|
181
|
+
else if (key === 'severity') {
|
|
182
|
+
currentRule[key] = cleanValue;
|
|
183
|
+
}
|
|
184
|
+
else {
|
|
185
|
+
currentRule[key] = cleanValue;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// 数组元素
|
|
190
|
+
else if (currentArray && trimmed.startsWith('- ')) {
|
|
191
|
+
const value = trimmed.slice(2).trim().replace(/^["']|["']$/g, '');
|
|
192
|
+
currentArray.push(value);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// 添加最后一个规则
|
|
196
|
+
if (currentRule && result.rules) {
|
|
197
|
+
result.rules.push(currentRule);
|
|
198
|
+
}
|
|
199
|
+
return result;
|
|
200
|
+
}
|
|
201
|
+
// CLI 入口
|
|
202
|
+
async function runArchitectureCheck(configPath, context) {
|
|
203
|
+
const rules = await loadArchitectureRules(configPath);
|
|
204
|
+
const engine = new ArchitectureConstraintEngine(rules);
|
|
205
|
+
return engine.check(context);
|
|
206
|
+
}
|
|
207
|
+
//# sourceMappingURL=constraint-engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constraint-engine.js","sourceRoot":"","sources":["../../src/architecture/constraint-engine.ts"],"names":[],"mappings":";AAAA;;;;;GAKG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsJH,sDAgBC;AAiED,oDAOC;AArMD,MAAa,4BAA4B;IACnB;IAApB,YAAoB,KAAyB;QAAzB,UAAK,GAAL,KAAK,CAAoB;IAAG,CAAC;IAEjD,KAAK,CAAC,KAAK,CAAC,OAA4B;QACtC,MAAM,UAAU,GAA4B,EAAE,CAAC;QAE/C,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACnD,UAAU,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QAC7B,CAAC;QAED,OAAO;YACL,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC;YACnE,UAAU;SACX,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,SAAS,CACrB,IAAsB,EACtB,OAA4B;QAE5B,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;YAClB,KAAK,mBAAmB;gBACtB,OAAO,IAAI,CAAC,qBAAqB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACnD,KAAK,YAAY;gBACf,OAAO,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAC5C,KAAK,iBAAiB;gBACpB,OAAO,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YACjD;gBACE,OAAO,EAAE,CAAC;QACd,CAAC;IACH,CAAC;IAEO,qBAAqB,CAC3B,IAAsB,EACtB,OAA4B;QAE5B,MAAM,UAAU,GAA4B,EAAE,CAAC;QAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC;QAErC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;YACjC,mBAAmB;YACnB,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;gBACpD,SAAS;YACX,CAAC;YAED,gBAAgB;YAChB,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;gBAC/B,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;oBACvD,UAAU,CAAC,IAAI,CAAC;wBACd,MAAM,EAAE,IAAI,CAAC,EAAE;wBACf,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,oCAAoC,OAAO,EAAE;wBACtE,KAAK,EAAE,CAAC,IAAI,CAAC;wBACb,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,OAAO;qBACnC,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;IAEO,cAAc,CACpB,IAAsB,EACtB,OAA4B;QAE5B,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC;QAEnC,IAAI,KAAK,GAAG,SAAS,EAAE,CAAC;YACtB,OAAO,CAAC;oBACN,MAAM,EAAE,IAAI,CAAC,EAAE;oBACf,OAAO,EAAE,IAAI,CAAC,OAAO,IAAI,2BAA2B,KAAK,MAAM,SAAS,0BAA0B;oBAClG,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,SAAS;iBACrC,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,CAAC;IACZ,CAAC;IAEO,mBAAmB,CACzB,IAAsB,EACtB,OAA4B;QAE5B,iBAAiB;QACjB,OAAO,EAAE,CAAC;IACZ,CAAC;IAEO,SAAS,CAAC,IAAY,EAAE,OAAe;QAC7C,cAAc;QACd,IAAI,YAAY,GAAG,OAAO,CAAC;QAE3B,sBAAsB;QACtB,IAAI,YAAY,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YACnC,YAAY,GAAG,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;QACpD,CAAC;QAED,gCAAgC;QAChC,YAAY,GAAG,YAAY;aACxB,OAAO,CAAC,WAAW,EAAE,WAAW,CAAC,CAAE,oBAAoB;aACvD,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAc,WAAW;aAC/C,OAAO,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC,CAAY,aAAa;QAEpD,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,YAAY,CAAC,CAAC;QACvC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;CACF;AA1GD,oEA0GC;AAED,4BAA4B;AACrB,KAAK,UAAU,qBAAqB,CAAC,UAAkB;IAC5D,MAAM,EAAE,GAAG,wDAAa,aAAa,GAAC,CAAC;IAEvC,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IAEvD,qBAAqB;IACrB,IAAI,MAAsC,CAAC;IAE3C,IAAI,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QACjC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;SAAM,CAAC;QACN,yBAAyB;QACzB,MAAM,GAAG,eAAe,CAAC,OAAO,CAAC,CAAC;IACpC,CAAC;IAED,OAAO,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;AAC5B,CAAC;AAED,iBAAiB;AACjB,SAAS,eAAe,CAAC,OAAe;IACtC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,MAAM,GAAmC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAC7D,IAAI,WAAW,GAAqC,IAAI,CAAC;IACzD,IAAI,YAAY,GAAoB,IAAI,CAAC;IACzC,IAAI,WAAW,GAAG,CAAC,CAAC;IAEpB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAE5B,UAAU;QACV,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QAElD,SAAS;QACT,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,MAAM,CAAC;QAE3D,QAAQ;QACR,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAChC,IAAI,WAAW,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;gBAChC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAA+B,CAAC,CAAC;YACrD,CAAC;YACD,WAAW,GAAG,EAAE,EAAE,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC;YAC1D,YAAY,GAAG,IAAI,CAAC;YACpB,WAAW,GAAG,YAAY,CAAC;QAC7B,CAAC;QACD,OAAO;aACF,IAAI,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9C,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACxC,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,EAAE,CAAC;YAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAEnD,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;gBACvB,YAAY,GAAG,EAAE,CAAC;gBACjB,WAAwC,CAAC,GAAG,CAAC,GAAG,YAAY,CAAC;YAChE,CAAC;iBAAM,IAAI,KAAK,EAAE,CAAC;gBACjB,OAAO;gBACP,MAAM,UAAU,GAAG,KAAK,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;gBACrD,IAAI,GAAG,KAAK,WAAW,EAAE,CAAC;oBACvB,WAAsC,CAAC,GAAG,CAAC,GAAG,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;gBAC1E,CAAC;qBAAM,IAAI,GAAG,KAAK,UAAU,EAAE,CAAC;oBAC7B,WAAmD,CAAC,GAAG,CAAC,GAAG,UAAiC,CAAC;gBAChG,CAAC;qBAAM,CAAC;oBACL,WAAsC,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC;gBAC5D,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO;aACF,IAAI,YAAY,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAClD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;YAClE,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC3B,CAAC;IACH,CAAC;IAED,WAAW;IACX,IAAI,WAAW,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAChC,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,WAA+B,CAAC,CAAC;IACrD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,SAAS;AACF,KAAK,UAAU,oBAAoB,CACxC,UAAkB,EAClB,OAA4B;IAE5B,MAAM,KAAK,GAAG,MAAM,qBAAqB,CAAC,UAAU,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,IAAI,4BAA4B,CAAC,KAAK,CAAC,CAAC;IACvD,OAAO,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 跨工程接口契约检查
|
|
3
|
+
*
|
|
4
|
+
* 检测多工程开发时的接口不一致问题
|
|
5
|
+
*/
|
|
6
|
+
export interface CrossProjectViolation {
|
|
7
|
+
type: 'api-mismatch' | 'doc-code-mismatch' | 'breaking-change' | 'missing-implementation';
|
|
8
|
+
severity: 'error' | 'warning';
|
|
9
|
+
message: string;
|
|
10
|
+
fromProject: string;
|
|
11
|
+
toProject: string;
|
|
12
|
+
details: {
|
|
13
|
+
interfaceName?: string;
|
|
14
|
+
fieldName?: string;
|
|
15
|
+
expectedType?: string;
|
|
16
|
+
actualType?: string;
|
|
17
|
+
location?: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface CrossProjectContext {
|
|
21
|
+
baseBranch: string;
|
|
22
|
+
changedProjects: string[];
|
|
23
|
+
changedFiles: string[];
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* 检查跨工程接口一致性
|
|
27
|
+
*/
|
|
28
|
+
export declare function checkCrossProjectContracts(context: CrossProjectContext): Promise<CrossProjectViolation[]>;
|
|
29
|
+
/**
|
|
30
|
+
* 检查文档-代码一致性
|
|
31
|
+
* 场景:文档写了接口,代码没实现
|
|
32
|
+
*/
|
|
33
|
+
export declare function checkDocCodeConsistency(docPath: string, projects: string[]): Promise<CrossProjectViolation[]>;
|
|
34
|
+
//# sourceMappingURL=cross-project-checker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cross-project-checker.d.ts","sourceRoot":"","sources":["../../src/architecture/cross-project-checker.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAMH,MAAM,WAAW,qBAAqB;IACpC,IAAI,EAAE,cAAc,GAAG,mBAAmB,GAAG,iBAAiB,GAAG,wBAAwB,CAAC;IAC1F,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE;QACP,aAAa,CAAC,EAAE,MAAM,CAAC;QACvB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAsBD;;GAEG;AACH,wBAAsB,0BAA0B,CAC9C,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,qBAAqB,EAAE,CAAC,CAalC;AAyGD;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAAE,GACjB,OAAO,CAAC,qBAAqB,EAAE,CAAC,CA4ClC"}
|