soloforge 1.3.2 → 1.3.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 +14 -0
- package/dist/adapters/claude_code/server.js +1 -1
- package/dist/adapters/claude_code/server.js.map +1 -1
- package/dist/adapters/claude_code/tools.d.ts.map +1 -1
- package/dist/adapters/claude_code/tools.js +385 -15
- package/dist/adapters/claude_code/tools.js.map +1 -1
- package/dist/adapters/shared/workflow_template.d.ts.map +1 -1
- package/dist/adapters/shared/workflow_template.js +3 -2
- package/dist/adapters/shared/workflow_template.js.map +1 -1
- package/dist/bin/soloforge.d.ts.map +1 -1
- package/dist/bin/soloforge.js +296 -1
- package/dist/bin/soloforge.js.map +1 -1
- package/dist/engine/asset_manifest.d.ts.map +1 -1
- package/dist/engine/asset_manifest.js +24 -0
- package/dist/engine/asset_manifest.js.map +1 -1
- package/dist/engine/backend_implementation_contract.d.ts +51 -0
- package/dist/engine/backend_implementation_contract.d.ts.map +1 -0
- package/dist/engine/backend_implementation_contract.js +142 -0
- package/dist/engine/backend_implementation_contract.js.map +1 -0
- package/dist/engine/code_maintainability_observability_contract.d.ts +74 -0
- package/dist/engine/code_maintainability_observability_contract.d.ts.map +1 -0
- package/dist/engine/code_maintainability_observability_contract.js +473 -0
- package/dist/engine/code_maintainability_observability_contract.js.map +1 -0
- package/dist/engine/config_write_boundary.d.ts +29 -0
- package/dist/engine/config_write_boundary.d.ts.map +1 -0
- package/dist/engine/config_write_boundary.js +69 -0
- package/dist/engine/config_write_boundary.js.map +1 -0
- package/dist/engine/consumable_asset_registry.d.ts.map +1 -1
- package/dist/engine/consumable_asset_registry.js +182 -1
- package/dist/engine/consumable_asset_registry.js.map +1 -1
- package/dist/engine/diagnostic_registry.d.ts +12 -0
- package/dist/engine/diagnostic_registry.d.ts.map +1 -1
- package/dist/engine/diagnostic_registry.js +62 -0
- package/dist/engine/diagnostic_registry.js.map +1 -1
- package/dist/engine/dual_layer_mechanism_registry.d.ts.map +1 -1
- package/dist/engine/dual_layer_mechanism_registry.js +318 -1
- package/dist/engine/dual_layer_mechanism_registry.js.map +1 -1
- package/dist/engine/explicit_asset_registry.d.ts.map +1 -1
- package/dist/engine/explicit_asset_registry.js +338 -0
- package/dist/engine/explicit_asset_registry.js.map +1 -1
- package/dist/engine/implementation_roadmap_registry.d.ts.map +1 -1
- package/dist/engine/implementation_roadmap_registry.js +112 -2
- package/dist/engine/implementation_roadmap_registry.js.map +1 -1
- package/dist/engine/knowledge_governance_gate.d.ts +38 -0
- package/dist/engine/knowledge_governance_gate.d.ts.map +1 -0
- package/dist/engine/knowledge_governance_gate.js +123 -0
- package/dist/engine/knowledge_governance_gate.js.map +1 -0
- package/dist/engine/log_governance.d.ts +25 -0
- package/dist/engine/log_governance.d.ts.map +1 -0
- package/dist/engine/log_governance.js +76 -0
- package/dist/engine/log_governance.js.map +1 -0
- package/dist/engine/mechanism_contract_registry.d.ts +1 -0
- package/dist/engine/mechanism_contract_registry.d.ts.map +1 -1
- package/dist/engine/mechanism_contract_registry.js +172 -0
- package/dist/engine/mechanism_contract_registry.js.map +1 -1
- package/dist/engine/mechanism_health_check.d.ts +23 -0
- package/dist/engine/mechanism_health_check.d.ts.map +1 -0
- package/dist/engine/mechanism_health_check.js +140 -0
- package/dist/engine/mechanism_health_check.js.map +1 -0
- package/dist/engine/next_action_planner.d.ts +19 -0
- package/dist/engine/next_action_planner.d.ts.map +1 -0
- package/dist/engine/next_action_planner.js +453 -0
- package/dist/engine/next_action_planner.js.map +1 -0
- package/dist/engine/observability.js +1 -1
- package/dist/engine/observability.js.map +1 -1
- package/dist/engine/ood_solid_contract.d.ts +51 -0
- package/dist/engine/ood_solid_contract.d.ts.map +1 -0
- package/dist/engine/ood_solid_contract.js +115 -0
- package/dist/engine/ood_solid_contract.js.map +1 -0
- package/dist/engine/project_stage_detector.d.ts +17 -0
- package/dist/engine/project_stage_detector.d.ts.map +1 -0
- package/dist/engine/project_stage_detector.js +185 -0
- package/dist/engine/project_stage_detector.js.map +1 -0
- package/dist/engine/release_issue_scenario_registry.d.ts.map +1 -1
- package/dist/engine/release_issue_scenario_registry.js +230 -1
- package/dist/engine/release_issue_scenario_registry.js.map +1 -1
- package/dist/engine/release_readiness_gate.d.ts +3 -0
- package/dist/engine/release_readiness_gate.d.ts.map +1 -1
- package/dist/engine/release_readiness_gate.js +407 -9
- package/dist/engine/release_readiness_gate.js.map +1 -1
- package/dist/engine/stale_current_task_detector.d.ts +30 -0
- package/dist/engine/stale_current_task_detector.d.ts.map +1 -0
- package/dist/engine/stale_current_task_detector.js +168 -0
- package/dist/engine/stale_current_task_detector.js.map +1 -0
- package/dist/engine/task_stage_detector.d.ts +19 -0
- package/dist/engine/task_stage_detector.d.ts.map +1 -0
- package/dist/engine/task_stage_detector.js +201 -0
- package/dist/engine/task_stage_detector.js.map +1 -0
- package/dist/engine/team_awareness.js +6 -6
- package/dist/engine/team_awareness.js.map +1 -1
- package/dist/engine/tool_invocation_contract_registry.d.ts.map +1 -1
- package/dist/engine/tool_invocation_contract_registry.js +10 -0
- package/dist/engine/tool_invocation_contract_registry.js.map +1 -1
- package/dist/engine/workflow_navigation_contract.d.ts +115 -0
- package/dist/engine/workflow_navigation_contract.d.ts.map +1 -0
- package/dist/engine/workflow_navigation_contract.js +39 -0
- package/dist/engine/workflow_navigation_contract.js.map +1 -0
- package/dist/types.d.ts +12 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/templates/knowledge/acceptance_templates/OOD/350/256/276/350/256/241/346/221/230/350/246/201/346/250/241/347/211/210.md +60 -0
- package/templates/knowledge/acceptance_templates//344/273/243/347/240/201/346/263/250/351/207/212/344/270/216/346/227/245/345/277/227/351/252/214/346/224/266/346/250/241/346/235/277.md +78 -0
- package/templates/knowledge/acceptance_templates//345/220/216/347/253/257/345/256/236/347/216/260/351/252/214/346/224/266/346/270/205/345/215/225.md +46 -0
- package/templates/knowledge/procedures/OOD/350/256/276/350/256/241/345/267/245/344/275/234/346/265/201.md +50 -0
- package/templates/knowledge/procedures//345/205/250/347/224/237/345/221/275/345/221/250/346/234/237/345/267/245/344/275/234/346/265/201/345/257/274/350/210/252.md +100 -0
- package/templates/knowledge/procedures//345/220/216/347/253/257/346/216/245/345/217/243/345/256/236/347/216/260/345/267/245/344/275/234/346/265/201.md +50 -0
- package/templates/knowledge/review//344/273/243/347/240/201/345/217/257/347/273/264/346/212/244/346/200/247/344/270/216/345/217/257/350/247/202/346/265/213/346/200/247/345/256/241/346/237/245.md +81 -0
- package/templates/knowledge/review_rules/SOLID/344/273/243/347/240/201/345/256/241/346/237/245/350/247/204/345/210/231.md +40 -0
- package/templates/knowledge/review_rules//345/220/216/347/253/257/345/256/236/347/216/260/345/267/245/347/250/213/345/256/241/346/237/245/350/247/204/345/210/231.md +38 -0
- package/templates/knowledge/rules/OOD/344/270/216SOLID/350/256/276/350/256/241/350/247/204/345/210/231.md +62 -0
- package/templates/knowledge/rules//344/273/243/347/240/201/346/263/250/351/207/212/344/270/216/346/227/245/345/277/227/345/245/221/347/272/246/350/247/204/345/210/231.md +121 -0
- package/templates/knowledge/rules//345/220/216/347/253/257/345/256/236/347/216/260/345/267/245/347/250/213/345/245/221/347/272/246/350/247/204/345/210/231.md +55 -0
- package/templates/knowledge/rules//345/267/245/344/275/234/346/265/201/345/257/274/350/210/252/345/245/221/347/272/246/350/247/204/345/210/231.md +113 -0
- package/templates/knowledge/rules//346/225/217/346/204/237/344/277/241/346/201/257/346/227/245/345/277/227/350/247/204/345/210/231.md +69 -0
- package/templates/knowledge/rules//346/227/245/345/277/227/346/262/273/347/220/206/350/247/204/345/210/231.md +49 -0
- package/templates/knowledge/rules//346/234/272/345/210/266/350/207/252/346/262/273/347/220/206/350/247/204/345/210/231.md +48 -0
- package/templates/knowledge/rules//346/240/207/345/207/206/350/265/204/344/272/247/350/246/206/347/233/226/350/247/204/345/210/231.md +43 -0
- package/templates/knowledge/rules//346/250/241/346/235/277/350/265/204/344/272/247/345/217/257/350/247/201/346/200/247/350/247/204/345/210/231.md +44 -0
- package/templates/knowledge/rules//347/237/245/350/257/206/346/262/273/347/220/206/350/247/204/345/210/231.md +50 -0
- package/templates/knowledge/rules//351/200/232/347/224/250/345/206/263/347/255/226/347/240/224/350/256/250/350/247/204/345/210/231.md +47 -0
- package/templates/knowledge/rules//351/205/215/347/275/256/350/220/275/347/233/230/350/276/271/347/225/214/350/247/204/345/210/231.md +47 -0
- package/templates/knowledge/rules//351/252/214/346/224/266/346/250/241/346/235/277/350/276/223/345/207/272/345/245/221/347/272/246/350/247/204/345/210/231.md +46 -0
- package/templates/patterns/SOLID/350/256/276/350/256/241/350/247/204/350/214/203.md +39 -0
- package/templates/patterns//345/220/216/347/253/257/345/256/236/347/216/260/345/267/245/347/250/213/350/247/204/350/214/203.md +39 -0
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 用户项目代码可维护性与可观测性契约。
|
|
3
|
+
*
|
|
4
|
+
* 治理对象是用户项目代码,不是 SoloForge 自身。
|
|
5
|
+
* 覆盖必要注释、结构化日志、错误日志、审计日志、
|
|
6
|
+
* 敏感信息脱敏和低风险跳过。
|
|
7
|
+
*/
|
|
8
|
+
/* ── 关键词 ─────────────────────────────────────── */
|
|
9
|
+
const OBSERVABILITY_KEYWORDS = /业务|支付|金额|账单|合同|入住|权限|登录|安全|通知|异步|状态机|审批|补贴|核销|外部系统|webhook|回调|异常处理|重试|补偿|事务|幂等|并发|数据修复|批处理|迁移|Controller|Service|UseCase|Domain|Repository|payment|billing|invoice|contract|permission|auth|security|state|workflow|migration|refund|charge|order/i;
|
|
10
|
+
const LOW_RISK_KEYWORDS = /错别字|拼写|文案|样式|css|颜色|README|配置值|测试数据|fixture|getter|setter|简单类型|类型定义|interface\s+\w+\s*\{|type\s+\w+\s*=/i;
|
|
11
|
+
const CRITICAL_LOG_KEYWORDS = /支付|账单|金额|退款|核销|补贴|缴费|payment|billing|refund|charge|invoice/i;
|
|
12
|
+
const SECURITY_LOG_KEYWORDS = /权限|登录|认证|越权|安全|role|auth|permission|security|access.?denied|forbidden/i;
|
|
13
|
+
const STATE_CHANGE_KEYWORDS = /状态|流转|status|state|transition|pending|approved|rejected|cancelled/i;
|
|
14
|
+
const EXTERNAL_CALL_KEYWORDS = /外部|第三方|API|调用|HTTP|RPC|webhook|callback|RestTemplate|WebClient|fetch|axios/i;
|
|
15
|
+
const MIGRATION_KEYWORDS = /迁移|修复|批处理|migration|batch|data.?fix|script/i;
|
|
16
|
+
const COMPLEX_RULE_KEYWORDS = /金额计算|计算逻辑|领域不变量|状态机|幂等|并发控制|分布式锁|算法|formula|invariant|idempoten|concurr/i;
|
|
17
|
+
const SENSITIVE_PATTERNS = [
|
|
18
|
+
{ pattern: /(?:password|passwd|pwd|secret|token|api[_-]?key|access[_-]?key|private[_-]?key)\s*[:=]\s*["'][^"']{4,}/i, name_zh: "明文密钥/令牌" },
|
|
19
|
+
{ pattern: /(?:cookie|session[_-]?id|set[_-]?cookie)\s*[:=]\s*["'][^"']{8,}/i, name_zh: "Cookie/会话" },
|
|
20
|
+
{ pattern: /(?:手机号|phone|mobile|cell)\s*[:=]\s*["']?\d{11}/i, name_zh: "手机号全量" },
|
|
21
|
+
{ pattern: /(?:身份证|id[_-]?card|id[_-]?number)\s*[:=]\s*["']?\d{15,18}/i, name_zh: "身份证全量" },
|
|
22
|
+
{ pattern: /(?:银行卡|bank[_-]?card|card[_-]?number|pan)\s*[:=]\s*["']?\d{13,19}/i, name_zh: "银行卡全量" },
|
|
23
|
+
{ pattern: /(?:健康|病历|诊断|处方|health|medical|diagnosis|prescription)/i, name_zh: "健康隐私" },
|
|
24
|
+
];
|
|
25
|
+
// 日志输出中的敏感信息 — 区分声明与输出
|
|
26
|
+
const LOG_OUTPUT_SENSITIVE_PATTERNS = [
|
|
27
|
+
// logger.info({ token }) / console 输出含 password 字段的对象
|
|
28
|
+
{ pattern: /(?:log|logger|LOG|console)\.(?:info|warn|error|debug|log|INFO|WARN|ERROR|DEBUG)\s*\(\s*\{[^}]*(?:password|passwd|pwd|secret|token|api[_-]?key|access[_-]?key|private[_-]?key|cookie|session[_-]?id)\b/i, name_zh: "日志对象含敏感字段" },
|
|
29
|
+
// console dot log 输出 user.password / log.info(data.secret)
|
|
30
|
+
{ pattern: /(?:log|logger|LOG|console)\.(?:info|warn|error|debug|log|INFO|WARN|ERROR|DEBUG)\s*\([^)]*\b\w+\.(?:password|passwd|pwd|secret|token|api[_-]?key|access[_-]?key|private[_-]?key|cookie|session[_-]?id)\b/i, name_zh: "日志输出敏感属性值" },
|
|
31
|
+
// logger.info("token={}", token) / log.info("password=" + pwd) / log.info("token: %s", t)
|
|
32
|
+
{ pattern: /(?:log|logger|LOG|console)\.(?:info|warn|error|debug|log|INFO|WARN|ERROR|DEBUG)\s*\(\s*["'][^"']*\b(?:password|passwd|pwd|secret|token|api[_-]?key|access[_-]?key|private[_-]?key|cookie|session[_-]?id)\s*[=::]\s*(?:["']?\s*\+|\{?\}|%[sd])/i, name_zh: "日志拼接/格式化敏感值" },
|
|
33
|
+
];
|
|
34
|
+
/* ── 触发判断 ─────────────────────────────────── */
|
|
35
|
+
export function requiresCodeObservabilityContract(intent, route, changedFiles = []) {
|
|
36
|
+
const text = `${intent} ${changedFiles.join(" ")}`;
|
|
37
|
+
if (LOW_RISK_KEYWORDS.test(text) && !OBSERVABILITY_KEYWORDS.test(text))
|
|
38
|
+
return false;
|
|
39
|
+
const relevantRoute = !route
|
|
40
|
+
|| ["code_change", "artifact_generation", "operation", "multi_stage_plan"].includes(route);
|
|
41
|
+
if (!relevantRoute)
|
|
42
|
+
return false;
|
|
43
|
+
if (!OBSERVABILITY_KEYWORDS.test(text))
|
|
44
|
+
return false;
|
|
45
|
+
// 简单修复/调试/查询不触发完整契约
|
|
46
|
+
if (/^(?:修复|调试|排查|查看|分析|解释|为什么|查一下|帮我看看|debug|fix\s+(?:a\s+)?(?:typo|lint|import|build))/i.test(intent.trim()))
|
|
47
|
+
return false;
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
/* ── 项目 logger 检测 ──────────────────────────── */
|
|
51
|
+
export function detectProjectLogger(fileContents) {
|
|
52
|
+
const allContent = Object.values(fileContents).join("\n");
|
|
53
|
+
if (/import\s+.*(?:LoggerFactory|@Slf4j|log\s*=.*Logger)/.test(allContent) || /log\.(info|warn|error|debug)\s*\(/.test(allContent)) {
|
|
54
|
+
return { type: "slf4j", import_pattern: "LoggerFactory.getLogger", call_pattern: "log.info/warn/error", confidence: "high" };
|
|
55
|
+
}
|
|
56
|
+
if (/import\s+.*(?:pino|from\s+['"]pino['"])/.test(allContent) || /(?:const|let)\s+\w*(?:logger|log)\s*=\s*pino/.test(allContent)) {
|
|
57
|
+
return { type: "pino", import_pattern: "import pino", call_pattern: "logger.info/warn/error", confidence: "high" };
|
|
58
|
+
}
|
|
59
|
+
if (/import\s+.*(?:winston|from\s+['"]winston['"])/.test(allContent) || /createLogger\s*\(/.test(allContent)) {
|
|
60
|
+
return { type: "winston", import_pattern: "import winston", call_pattern: "logger.info/warn/error", confidence: "high" };
|
|
61
|
+
}
|
|
62
|
+
if (/import\s+.*(?:@nestjs|NestJS|Logger\s*}\s*from\s+['"]@nestjs)/.test(allContent)) {
|
|
63
|
+
return { type: "nestjs_logger", import_pattern: "import { Logger } from '@nestjs/common'", call_pattern: "this.logger.log/warn/error", confidence: "high" };
|
|
64
|
+
}
|
|
65
|
+
const fileKeys = Object.keys(fileContents).join(" ");
|
|
66
|
+
const hasFrontendExt = /\.(?:vue|tsx|jsx|svelte)\b/.test(fileKeys);
|
|
67
|
+
const hasFrontendImport = /\.vue\s*['"]|\.tsx\s*['"]|\.jsx\s*['"]|react['"]|vue['"]/.test(allContent);
|
|
68
|
+
if (hasFrontendExt || hasFrontendImport) {
|
|
69
|
+
if (/(?:const|let)\s+\w*(?:logger|Logger)\s*=/.test(allContent)) {
|
|
70
|
+
return { type: "custom_logger", import_pattern: "项目封装 logger", call_pattern: "logger.info/warn/error", confidence: "medium" };
|
|
71
|
+
}
|
|
72
|
+
return { type: "frontend_project", import_pattern: "前端项目", call_pattern: "生产环境禁止 console", confidence: "medium" };
|
|
73
|
+
}
|
|
74
|
+
if (/(?:const|let)\s+\w*(?:logger|Logger)\s*=/.test(allContent)) {
|
|
75
|
+
return { type: "custom_logger", import_pattern: "项目封装 logger", call_pattern: "logger.info/warn/error", confidence: "medium" };
|
|
76
|
+
}
|
|
77
|
+
return { type: "none_detected", import_pattern: "无", call_pattern: "console.log", confidence: "low" };
|
|
78
|
+
}
|
|
79
|
+
/* ── 工作包创建 ───────────────────────────────── */
|
|
80
|
+
export function createCodeObservabilityWorkPackage(taskId, intent, loggerInfo) {
|
|
81
|
+
const text = intent;
|
|
82
|
+
const requiredLogs = [];
|
|
83
|
+
const sensitiveFields = [];
|
|
84
|
+
const requiredComments = [];
|
|
85
|
+
if (CRITICAL_LOG_KEYWORDS.test(text)) {
|
|
86
|
+
requiredLogs.push("支付/金额/退款/核销状态变更必须有业务日志,含对象 ID、操作人、前后状态");
|
|
87
|
+
sensitiveFields.push("payment_amount", "card_number", "bank_account");
|
|
88
|
+
}
|
|
89
|
+
if (SECURITY_LOG_KEYWORDS.test(text)) {
|
|
90
|
+
requiredLogs.push("权限拒绝/越权访问必须有安全日志,含操作人、目标资源、拒绝原因");
|
|
91
|
+
}
|
|
92
|
+
if (STATE_CHANGE_KEYWORDS.test(text)) {
|
|
93
|
+
requiredLogs.push("关键状态流转必须有日志,含流转前后状态和触发原因");
|
|
94
|
+
}
|
|
95
|
+
if (EXTERNAL_CALL_KEYWORDS.test(text)) {
|
|
96
|
+
requiredLogs.push("外部调用失败/超时/重试必须有日志,含目标、响应码/错误、重试次数");
|
|
97
|
+
}
|
|
98
|
+
if (MIGRATION_KEYWORDS.test(text)) {
|
|
99
|
+
requiredLogs.push("数据修复/迁移脚本必须有审计日志,含修复前值、修复后值、影响行数");
|
|
100
|
+
}
|
|
101
|
+
if (COMPLEX_RULE_KEYWORDS.test(text)) {
|
|
102
|
+
requiredComments.push("复杂业务规则必须有注释说明原因(为什么),不得只复述代码行为(做什么)");
|
|
103
|
+
}
|
|
104
|
+
if (/事务|幂等|并发|分布式锁/i.test(text)) {
|
|
105
|
+
requiredComments.push("事务边界、幂等策略、并发控制必须有注释说明设计意图");
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
task_id: taskId,
|
|
109
|
+
status: "required",
|
|
110
|
+
applicability_reason_zh: `该任务涉及业务编码,需确认代码可维护性与可观测性约束: ${intent}`,
|
|
111
|
+
required_logs: requiredLogs,
|
|
112
|
+
required_comments: requiredComments,
|
|
113
|
+
sensitive_fields: sensitiveFields,
|
|
114
|
+
detected_logger: loggerInfo,
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
function workPackageSatisfied(wp) {
|
|
118
|
+
return !!wp && wp.status === "satisfied";
|
|
119
|
+
}
|
|
120
|
+
/* ── Gate ─────────────────────────────────────── */
|
|
121
|
+
export function evaluateCodeObservabilityGate(input) {
|
|
122
|
+
if (!requiresCodeObservabilityContract(input.intent, input.route, input.changed_files)) {
|
|
123
|
+
return {
|
|
124
|
+
applicable: false,
|
|
125
|
+
allowed: true,
|
|
126
|
+
status: "not_applicable",
|
|
127
|
+
reason_zh: "低风险或非业务编码任务,不触发代码可维护性/可观测性工作包",
|
|
128
|
+
findings: [],
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
const loggerInfo = input.project_files
|
|
132
|
+
? detectProjectLogger(input.project_files)
|
|
133
|
+
: undefined;
|
|
134
|
+
const wp = input.work_package ?? createCodeObservabilityWorkPackage(input.task_id, input.intent, loggerInfo);
|
|
135
|
+
if (!workPackageSatisfied(wp)) {
|
|
136
|
+
return {
|
|
137
|
+
applicable: true,
|
|
138
|
+
allowed: false,
|
|
139
|
+
status: "blocked",
|
|
140
|
+
reason_zh: "业务编码任务缺少代码可维护性/可观测性工作包,不得开始实现",
|
|
141
|
+
work_package: { ...wp, detected_logger: loggerInfo },
|
|
142
|
+
findings: [],
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
applicable: true,
|
|
147
|
+
allowed: true,
|
|
148
|
+
status: "satisfied",
|
|
149
|
+
reason_zh: "代码可维护性/可观测性工作包已具备,可进入实现",
|
|
150
|
+
work_package: { ...wp, detected_logger: loggerInfo },
|
|
151
|
+
findings: [],
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
/* ── Review: 敏感信息检测 ─────────────────────── */
|
|
155
|
+
export function detectSensitiveLogs(fileContents) {
|
|
156
|
+
const findings = [];
|
|
157
|
+
for (const [file, content] of Object.entries(fileContents)) {
|
|
158
|
+
if (/\.(?:test|spec)\./.test(file))
|
|
159
|
+
continue;
|
|
160
|
+
for (const { pattern, name_zh } of SENSITIVE_PATTERNS) {
|
|
161
|
+
if (pattern.test(content)) {
|
|
162
|
+
findings.push({
|
|
163
|
+
category: "sensitive_log_leak",
|
|
164
|
+
severity: "hard_fail",
|
|
165
|
+
file,
|
|
166
|
+
evidence: `日志或输出可能包含敏感信息: ${name_zh}`,
|
|
167
|
+
suggestion_zh: `对 ${name_zh} 字段脱敏后再输出(如仅显示末四位或哈希值)。`,
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
for (const { pattern, name_zh } of LOG_OUTPUT_SENSITIVE_PATTERNS) {
|
|
172
|
+
if (pattern.test(content)) {
|
|
173
|
+
findings.push({
|
|
174
|
+
category: "sensitive_log_leak",
|
|
175
|
+
severity: "hard_fail",
|
|
176
|
+
file,
|
|
177
|
+
evidence: `日志输出包含敏感信息: ${name_zh}`,
|
|
178
|
+
suggestion_zh: `禁止在日志中输出敏感字段值,仅记录脱敏值或哈希。`,
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return findings;
|
|
184
|
+
}
|
|
185
|
+
/* ── Review: 缺失日志检测 ─────────────────────── */
|
|
186
|
+
export function reviewMissingLogs(fileContents) {
|
|
187
|
+
const findings = [];
|
|
188
|
+
for (const [file, content] of Object.entries(fileContents)) {
|
|
189
|
+
if (/\.(?:test|spec)\./.test(file))
|
|
190
|
+
continue;
|
|
191
|
+
const lowered = file.toLowerCase();
|
|
192
|
+
const hasLog = /(?:log\.(info|warn|error|debug)|logger\.(info|warn|error|debug|log)|LOG\.(INFO|WARN|ERROR)|console\.(log|error|warn))\s*\(/i.test(content);
|
|
193
|
+
if (CRITICAL_LOG_KEYWORDS.test(`${file} ${content}`)) {
|
|
194
|
+
const hasWriteOp = /\.(?:save|insert|update|delete|create|refund|charge|pay)\s*\(/i.test(content);
|
|
195
|
+
if (hasWriteOp && !/(?:log\.|logger\.|LOG\.)/i.test(content)) {
|
|
196
|
+
findings.push({
|
|
197
|
+
category: "missing_log_critical",
|
|
198
|
+
severity: "hard_fail",
|
|
199
|
+
file,
|
|
200
|
+
evidence: "支付/金额相关写操作缺少业务日志",
|
|
201
|
+
suggestion_zh: "补充包含对象 ID、操作人、金额前后值和操作结果的结构化日志。",
|
|
202
|
+
});
|
|
203
|
+
}
|
|
204
|
+
// 有日志但不可定位 — 支付/金额写操作的日志必须含对象ID或前后状态
|
|
205
|
+
// 事件词(退款/支付/changed/updated)不是可定位字段
|
|
206
|
+
if (hasWriteOp && /(?:log\.|logger\.|LOG\.)/i.test(content)) {
|
|
207
|
+
const logStmts = content.match(/(?:log\.|logger\.|LOG\.|console\.)\s*(?:info|warn|error|debug|log|INFO|WARN|ERROR|DEBUG)\s*\([^)]*\)/gi) ?? [];
|
|
208
|
+
const hasLocatableField = logStmts.some((stmt) => /\w+(?:Id|_id|ID|No|Number|Code)\b/i.test(stmt)
|
|
209
|
+
|| /\bid\s*[=::]/i.test(stmt)
|
|
210
|
+
|| /(?:before|after|prev|old|new|from|to)\s*[=::]/i.test(stmt)
|
|
211
|
+
|| /(?:操作人|操作者|operator|userId|user_id|adminId|staffId)\b/i.test(stmt)
|
|
212
|
+
|| /(?:resourceId|target|resource)\s*[=::]/i.test(stmt));
|
|
213
|
+
if (!hasLocatableField) {
|
|
214
|
+
findings.push({
|
|
215
|
+
category: "unlocatable_log",
|
|
216
|
+
severity: "hard_fail",
|
|
217
|
+
file,
|
|
218
|
+
evidence: "支付/金额写操作日志缺少可定位字段(对象ID、前后状态、操作人/目标资源)",
|
|
219
|
+
suggestion_zh: "日志必须包含对象 ID、前后状态或操作人+目标资源,事件词不是可定位字段。",
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (SECURITY_LOG_KEYWORDS.test(`${file} ${content}`)) {
|
|
225
|
+
const hasPermissionCheck = /(?:permission|auth|role|check|deny|reject|forbidden|authorize)/i.test(content);
|
|
226
|
+
if (hasPermissionCheck && !/(?:log\.|logger\.|LOG\.)/i.test(content)) {
|
|
227
|
+
findings.push({
|
|
228
|
+
category: "missing_log_critical",
|
|
229
|
+
severity: "hard_fail",
|
|
230
|
+
file,
|
|
231
|
+
evidence: "权限校验逻辑缺少安全日志",
|
|
232
|
+
suggestion_zh: "补充包含操作人、目标资源和拒绝原因的安全日志。",
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
const catchBlocks = content.match(/catch\s*\([^)]*\)\s*\{[^}]*\}/g) ?? [];
|
|
237
|
+
for (const block of catchBlocks) {
|
|
238
|
+
const hasLogInBlock = /(?:log\.|logger\.|LOG\.|console\.(error|warn))/i.test(block);
|
|
239
|
+
const onlyReturnOrRethrow = /^(?:\s*(?:return\s+(?:false|null|undefined|""|-1|0|[])|;?\s*\})+\s*$)/i.test(block.replace(/\s+/g, " ").trim());
|
|
240
|
+
if (!hasLogInBlock && (onlyReturnOrRethrow || /return\s+(?:false|null|""|-1|0)/i.test(block))) {
|
|
241
|
+
findings.push({
|
|
242
|
+
category: "catch_swallow",
|
|
243
|
+
severity: "hard_fail",
|
|
244
|
+
file,
|
|
245
|
+
evidence: `catch 块吞异常且无日志: ${block.slice(0, 80).replace(/\n/g, " ")}`,
|
|
246
|
+
suggestion_zh: "至少记录异常类型、消息和影响上下文,不得静默忽略。",
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
if (STATE_CHANGE_KEYWORDS.test(`${file} ${content}`)) {
|
|
251
|
+
const hasStateUpdate = /(?:status|state)\s*(?:=|\.set|\.update|transition|change)\s*/i.test(content);
|
|
252
|
+
if (hasStateUpdate && !/(?:log\.|logger\.|LOG\.)/i.test(content)) {
|
|
253
|
+
findings.push({
|
|
254
|
+
category: "missing_log_state_change",
|
|
255
|
+
severity: "warning",
|
|
256
|
+
file,
|
|
257
|
+
evidence: "状态变更逻辑缺少流转日志",
|
|
258
|
+
suggestion_zh: "补充状态流转日志,记录变更前后状态和触发原因。",
|
|
259
|
+
});
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
if (EXTERNAL_CALL_KEYWORDS.test(`${file} ${content}`)) {
|
|
263
|
+
const hasExternalCall = /(?:fetch|axios|RestTemplate|WebClient|Feign|http\.request|rpc|grpc)/i.test(content);
|
|
264
|
+
if (hasExternalCall && !/(?:log\.|logger\.|LOG\.)/i.test(content)) {
|
|
265
|
+
findings.push({
|
|
266
|
+
category: "missing_log_external",
|
|
267
|
+
severity: "warning",
|
|
268
|
+
file,
|
|
269
|
+
evidence: "外部调用缺少失败/超时日志",
|
|
270
|
+
suggestion_zh: "补充外部调用失败日志,含目标、响应码和重试信息。",
|
|
271
|
+
});
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
if (MIGRATION_KEYWORDS.test(`${file} ${content}`)) {
|
|
275
|
+
const hasDataModification = /(?:UPDATE|INSERT|DELETE|update\(|save\(|delete\(|remove\()/i.test(content);
|
|
276
|
+
if (hasDataModification && !/(?:log\.|logger\.|LOG\.|audit|审计)/i.test(content)) {
|
|
277
|
+
findings.push({
|
|
278
|
+
category: "missing_audit_log",
|
|
279
|
+
severity: "hard_fail",
|
|
280
|
+
file,
|
|
281
|
+
evidence: "数据修复/迁移脚本缺少审计日志",
|
|
282
|
+
suggestion_zh: "补充审计日志,记录修复前值、后值和影响行数。",
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
if (hasLog && /console\.(log|debug|info)\s*\(/i.test(content) && !/\.(?:test|spec)\./.test(file)) {
|
|
287
|
+
const isFrontendProd = /\.(?:vue|tsx|jsx|svelte)\b/.test(lowered);
|
|
288
|
+
findings.push({
|
|
289
|
+
category: "raw_console_log",
|
|
290
|
+
severity: isFrontendProd ? "hard_fail" : "warning",
|
|
291
|
+
file,
|
|
292
|
+
evidence: "生产代码使用裸 console.log/debug/info",
|
|
293
|
+
suggestion_zh: isFrontendProd
|
|
294
|
+
? "前端生产代码禁止裸 console 输出,使用项目封装 logger 或移除。"
|
|
295
|
+
: "使用项目 logger 替代 console.log,确保日志可追踪和可过滤。",
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
if (hasLog) {
|
|
299
|
+
const logLines = content.match(/(?:log\.info|logger\.info|LOG\.INFO|console\.log)\s*\(\s*["'](?:error|failed|success|done|ok|ok|完成|失败|错误)["']/gi) ?? [];
|
|
300
|
+
for (const _line of logLines) {
|
|
301
|
+
findings.push({
|
|
302
|
+
category: "unlocatable_log",
|
|
303
|
+
severity: "warning",
|
|
304
|
+
file,
|
|
305
|
+
evidence: "日志仅含通用状态词,无业务对象标识",
|
|
306
|
+
suggestion_zh: "日志必须包含事件名、业务对象 ID 和操作上下文,确保可定位。",
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
const loopLogPattern = /(?:for|while|forEach|map|flatMap|reduce)\s*\([^)]*\)\s*\{[^}]*(?:log\.|logger\.|console\.)/i;
|
|
311
|
+
if (loopLogPattern.test(content) && !/(?:batch|批量|each|every|per.?item)/i.test(content)) {
|
|
312
|
+
findings.push({
|
|
313
|
+
category: "noisy_log",
|
|
314
|
+
severity: "advisory",
|
|
315
|
+
file,
|
|
316
|
+
evidence: "循环内可能产生刷屏日志",
|
|
317
|
+
suggestion_zh: "在循环内使用 DEBUG 级别,或汇总后以单条日志输出。",
|
|
318
|
+
});
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return findings;
|
|
322
|
+
}
|
|
323
|
+
/* ── Review: 注释质量检测 ─────────────────────── */
|
|
324
|
+
export function reviewCommentQuality(fileContents) {
|
|
325
|
+
const findings = [];
|
|
326
|
+
for (const [file, content] of Object.entries(fileContents)) {
|
|
327
|
+
if (/\.(?:test|spec)\./.test(file))
|
|
328
|
+
continue;
|
|
329
|
+
if (COMPLEX_RULE_KEYWORDS.test(`${file} ${content}`)) {
|
|
330
|
+
const hasFunction = /(?:function\s+\w+|(?:const|let)\s+\w+\s*=\s*(?:async\s+)?\(|(?:public|private|protected)\s+(?:\w+\s+)+\w+\s*\(|def\s+\w+\s*\(|class\s+\w+)/i.test(content);
|
|
331
|
+
const hasComment = /(?:\/\/|\/\*|\*|<!--)/.test(content);
|
|
332
|
+
if (hasFunction && !hasComment) {
|
|
333
|
+
findings.push({
|
|
334
|
+
category: "missing_comment_complex",
|
|
335
|
+
severity: "warning",
|
|
336
|
+
file,
|
|
337
|
+
evidence: "复杂业务规则缺少注释",
|
|
338
|
+
suggestion_zh: "添加注释说明设计意图(为什么),不得只复述代码行为。",
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
const commentMatches = content.matchAll(/\/\/\s*(.+)|\/\*\s*([\s\S]*?)\s*\*\//g);
|
|
343
|
+
for (const match of commentMatches) {
|
|
344
|
+
const commentText = (match[1] ?? match[2] ?? "").trim();
|
|
345
|
+
if (!commentText)
|
|
346
|
+
continue;
|
|
347
|
+
const lineStart = match.index ?? 0;
|
|
348
|
+
const afterComment = content.slice(lineStart + match[0].length, lineStart + match[0].length + 200);
|
|
349
|
+
const nextCodeLine = afterComment.split("\n").find((l) => l.trim().length > 0 && !l.trim().startsWith("//") && !l.trim().startsWith("*"));
|
|
350
|
+
if (nextCodeLine) {
|
|
351
|
+
const codeStripped = nextCodeLine.replace(/[{}()\[\];,.]/g, "").trim();
|
|
352
|
+
const commentStripped = commentText.replace(/[{}()\[\];,.]/g, "").trim();
|
|
353
|
+
const codeLower = codeStripped.toLowerCase();
|
|
354
|
+
const commentLower = commentStripped.toLowerCase();
|
|
355
|
+
if (codeLower.length > 10 && commentLower.length > 10) {
|
|
356
|
+
const codeWords = new Set(codeLower.split(/\s+/));
|
|
357
|
+
const commentWords = new Set(commentLower.split(/\s+/));
|
|
358
|
+
let overlap = 0;
|
|
359
|
+
const total = Math.max(codeWords.size, commentWords.size);
|
|
360
|
+
for (const w of codeWords) {
|
|
361
|
+
if (commentWords.has(w) && w.length > 3)
|
|
362
|
+
overlap++;
|
|
363
|
+
}
|
|
364
|
+
if (total > 0 && overlap / total > 0.7) {
|
|
365
|
+
findings.push({
|
|
366
|
+
category: "verbose_comment",
|
|
367
|
+
severity: "advisory",
|
|
368
|
+
file,
|
|
369
|
+
evidence: `注释仅复述代码: "${commentText.slice(0, 60)}"`,
|
|
370
|
+
suggestion_zh: "删除废话注释;如需保留,改为说明设计意图或业务背景。",
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
return findings;
|
|
378
|
+
}
|
|
379
|
+
/* ── Review: 项目 logger 使用检查 ─────────────── */
|
|
380
|
+
export function reviewLoggerUsage(fileContents, loggerInfo) {
|
|
381
|
+
const findings = [];
|
|
382
|
+
if (loggerInfo.type === "frontend_project" || loggerInfo.type === "none_detected")
|
|
383
|
+
return findings;
|
|
384
|
+
for (const [file, content] of Object.entries(fileContents)) {
|
|
385
|
+
if (/\.(?:test|spec|d\.ts|\.types\.ts)\./.test(file))
|
|
386
|
+
continue;
|
|
387
|
+
const hasAnyLog = /(?:log\.|logger\.|LOG\.|console\.)/i.test(content);
|
|
388
|
+
if (!hasAnyLog)
|
|
389
|
+
continue;
|
|
390
|
+
const usesProjectLogger = new RegExp(loggerInfo.call_pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").replace(/\\\./g, "\\."), "i").test(content);
|
|
391
|
+
const usesConsoleDirectly = /console\.(log|debug|info|warn|error)\s*\(/i.test(content);
|
|
392
|
+
if (usesConsoleDirectly && !usesProjectLogger && loggerInfo.confidence === "high") {
|
|
393
|
+
findings.push({
|
|
394
|
+
category: "wrong_logger",
|
|
395
|
+
severity: "warning",
|
|
396
|
+
file,
|
|
397
|
+
evidence: `使用裸 console 而非项目 logger (${loggerInfo.type})`,
|
|
398
|
+
suggestion_zh: `使用项目 ${loggerInfo.type} logger 确保日志可追踪和可过滤。`,
|
|
399
|
+
});
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
return findings;
|
|
403
|
+
}
|
|
404
|
+
/* ── 综合审查入口 ─────────────────────────────── */
|
|
405
|
+
export function reviewCodeObservability(fileContents, loggerInfo) {
|
|
406
|
+
const findings = [];
|
|
407
|
+
findings.push(...detectSensitiveLogs(fileContents));
|
|
408
|
+
findings.push(...reviewMissingLogs(fileContents));
|
|
409
|
+
findings.push(...reviewCommentQuality(fileContents));
|
|
410
|
+
const resolvedLogger = loggerInfo ?? detectProjectLogger(fileContents);
|
|
411
|
+
findings.push(...reviewLoggerUsage(fileContents, resolvedLogger));
|
|
412
|
+
return findings;
|
|
413
|
+
}
|
|
414
|
+
/* ── 低风险跳过判断 ───────────────────────────── */
|
|
415
|
+
export function isLowRiskChange(intent, changedFiles = []) {
|
|
416
|
+
const text = `${intent} ${changedFiles.join(" ")}`;
|
|
417
|
+
if (/^(?:fix\s+)?(?:typo|错别字|拼写|文案|README|注释样式|格式化|lint|import\s*排序)/i.test(text.trim())) {
|
|
418
|
+
return { low_risk: true, reason_zh: "纯文案或格式修改,跳过可维护性/可观测性检查" };
|
|
419
|
+
}
|
|
420
|
+
if (/^(?:get|set|is|has|can)\w*\s*[\({]/i.test(text.trim()) && changedFiles.length <= 1) {
|
|
421
|
+
return { low_risk: true, reason_zh: "简单 getter/setter,跳过可维护性/可观测性检查" };
|
|
422
|
+
}
|
|
423
|
+
const allStyle = changedFiles.length > 0 && changedFiles.every((f) => /\.(?:css|scss|less|styl|style)$/i.test(f));
|
|
424
|
+
if (allStyle) {
|
|
425
|
+
return { low_risk: true, reason_zh: "纯样式修改,跳过可维护性/可观测性检查" };
|
|
426
|
+
}
|
|
427
|
+
const allTest = changedFiles.length > 0 && changedFiles.every((f) => /\.(?:test|spec)\./i.test(f));
|
|
428
|
+
if (allTest && !OBSERVABILITY_KEYWORDS.test(text)) {
|
|
429
|
+
return { low_risk: true, reason_zh: "纯测试文件修改,跳过可维护性/可观测性检查" };
|
|
430
|
+
}
|
|
431
|
+
return { low_risk: false, reason_zh: "" };
|
|
432
|
+
}
|
|
433
|
+
/* ── 阻断判断 ─────────────────────────────────── */
|
|
434
|
+
export function hasBlockingObservabilityFindings(findings) {
|
|
435
|
+
return findings.some((f) => f.severity === "hard_fail");
|
|
436
|
+
}
|
|
437
|
+
export function hasP1OrAboveFindings(findings) {
|
|
438
|
+
return findings.some((f) => f.severity === "hard_fail" || f.severity === "warning");
|
|
439
|
+
}
|
|
440
|
+
/* ── sf_verify changed_files 校验 ─────────────── */
|
|
441
|
+
export function verifyChangedFilesObservability(input) {
|
|
442
|
+
const filtered = {};
|
|
443
|
+
for (const [file, content] of Object.entries(input.file_contents)) {
|
|
444
|
+
if (/\.(?:test|spec|d\.ts|\.types\.ts|\.md|\.json|\.yaml|\.yml|\.lock|\.map)$/i.test(file))
|
|
445
|
+
continue;
|
|
446
|
+
if (input.changed_files.length > 0 && !input.changed_files.some((cf) => file.endsWith(cf) || cf.endsWith(file)))
|
|
447
|
+
continue;
|
|
448
|
+
filtered[file] = content;
|
|
449
|
+
}
|
|
450
|
+
if (Object.keys(filtered).length === 0) {
|
|
451
|
+
return [];
|
|
452
|
+
}
|
|
453
|
+
const lowRisk = isLowRiskChange(input.intent, input.changed_files);
|
|
454
|
+
if (lowRisk.low_risk) {
|
|
455
|
+
return [{ category: "low_risk_skip", severity: "info", file: "", evidence: lowRisk.reason_zh, suggestion_zh: "" }];
|
|
456
|
+
}
|
|
457
|
+
return reviewCodeObservability(filtered);
|
|
458
|
+
}
|
|
459
|
+
/* ── sf_deliver 交付阻断 ──────────────────────── */
|
|
460
|
+
export function evaluateDeliveryBlock(findings) {
|
|
461
|
+
const blocking = findings.filter((f) => f.severity === "hard_fail"
|
|
462
|
+
|| (f.severity === "warning" && f.category === "missing_comment_complex"));
|
|
463
|
+
if (blocking.length > 0) {
|
|
464
|
+
const reasons = blocking.map((f) => `[${f.category}] ${f.file}: ${f.evidence}`).join("\n");
|
|
465
|
+
return {
|
|
466
|
+
blocked: true,
|
|
467
|
+
reason_zh: `代码可维护性/可观测性存在 ${blocking.length} 项阻断:\n${reasons}`,
|
|
468
|
+
blocking_findings: blocking,
|
|
469
|
+
};
|
|
470
|
+
}
|
|
471
|
+
return { blocked: false, reason_zh: "", blocking_findings: [] };
|
|
472
|
+
}
|
|
473
|
+
//# sourceMappingURL=code_maintainability_observability_contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code_maintainability_observability_contract.js","sourceRoot":"","sources":["../../src/engine/code_maintainability_observability_contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 配置落盘边界。
|
|
3
|
+
*
|
|
4
|
+
* 区分空项目、已有项目和运行时推断,防止自动推断结果在未确认时写入用户工程。
|
|
5
|
+
*/
|
|
6
|
+
export type ConfigWriteContextKind = "greenfield" | "existing_project" | "runtime_inference";
|
|
7
|
+
export interface ConfigWriteContext {
|
|
8
|
+
kind: ConfigWriteContextKind;
|
|
9
|
+
project_path: string;
|
|
10
|
+
evidence: string[];
|
|
11
|
+
confirmed: boolean;
|
|
12
|
+
}
|
|
13
|
+
export interface ConfigWriteDecision {
|
|
14
|
+
allowed: boolean;
|
|
15
|
+
reason_zh: string;
|
|
16
|
+
requires_confirmation: boolean;
|
|
17
|
+
}
|
|
18
|
+
export interface WriteBoundaryViolation {
|
|
19
|
+
target_path: string;
|
|
20
|
+
reason_zh: string;
|
|
21
|
+
}
|
|
22
|
+
export declare function classifyConfigContext(projectDir: string, opts?: {
|
|
23
|
+
runtime_inference?: boolean;
|
|
24
|
+
confirmed?: boolean;
|
|
25
|
+
}): ConfigWriteContext;
|
|
26
|
+
export declare function isWriteAllowed(context: ConfigWriteContext, targetPath: string): ConfigWriteDecision;
|
|
27
|
+
export declare function getWriteConfirmationPrompt(context: ConfigWriteContext, targetPath: string): string;
|
|
28
|
+
export declare function validateWriteBoundary(context: ConfigWriteContext, writes: string[]): WriteBoundaryViolation[];
|
|
29
|
+
//# sourceMappingURL=config_write_boundary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config_write_boundary.d.ts","sourceRoot":"","sources":["../../src/engine/config_write_boundary.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,MAAM,MAAM,sBAAsB,GAAG,YAAY,GAAG,kBAAkB,GAAG,mBAAmB,CAAC;AAE7F,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,sBAAsB,CAAC;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,qBAAqB,EAAE,OAAO,CAAC;CAChC;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAaD,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE;IAAE,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,kBAAkB,CAYzI;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,GAAG,mBAAmB,CAsBnG;AAED,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,kBAAkB,EAAE,UAAU,EAAE,MAAM,GAAG,MAAM,CAIlG;AAED,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,sBAAsB,EAAE,CAS7G"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 配置落盘边界。
|
|
3
|
+
*
|
|
4
|
+
* 区分空项目、已有项目和运行时推断,防止自动推断结果在未确认时写入用户工程。
|
|
5
|
+
*/
|
|
6
|
+
import fs from "node:fs";
|
|
7
|
+
import path from "node:path";
|
|
8
|
+
const PROJECT_MARKERS = [
|
|
9
|
+
"package.json",
|
|
10
|
+
"pom.xml",
|
|
11
|
+
"build.gradle",
|
|
12
|
+
"settings.gradle",
|
|
13
|
+
"pyproject.toml",
|
|
14
|
+
"go.mod",
|
|
15
|
+
"Cargo.toml",
|
|
16
|
+
"src",
|
|
17
|
+
];
|
|
18
|
+
export function classifyConfigContext(projectDir, opts) {
|
|
19
|
+
if (opts?.runtime_inference) {
|
|
20
|
+
return { kind: "runtime_inference", project_path: projectDir, evidence: ["runtime_inference"], confirmed: opts.confirmed === true };
|
|
21
|
+
}
|
|
22
|
+
const evidence = PROJECT_MARKERS.filter((m) => fs.existsSync(path.join(projectDir, m)));
|
|
23
|
+
const hasSoloforgeState = fs.existsSync(path.join(projectDir, ".soloforge"))
|
|
24
|
+
|| fs.existsSync(path.join(projectDir, ".mcp.json"))
|
|
25
|
+
|| fs.existsSync(path.join(projectDir, "CLAUDE.md"));
|
|
26
|
+
if (evidence.length === 0 && !hasSoloforgeState) {
|
|
27
|
+
return { kind: "greenfield", project_path: projectDir, evidence: ["empty_project"], confirmed: opts?.confirmed === true };
|
|
28
|
+
}
|
|
29
|
+
return { kind: "existing_project", project_path: projectDir, evidence, confirmed: opts?.confirmed === true };
|
|
30
|
+
}
|
|
31
|
+
export function isWriteAllowed(context, targetPath) {
|
|
32
|
+
const normalized = targetPath.replace(/\\/g, "/");
|
|
33
|
+
const isSoloforgeManaged = normalized.includes(".soloforge/")
|
|
34
|
+
|| normalized.endsWith(".mcp.json")
|
|
35
|
+
|| normalized.endsWith("CLAUDE.md")
|
|
36
|
+
|| normalized.includes(".claude/");
|
|
37
|
+
if (context.kind === "runtime_inference") {
|
|
38
|
+
return {
|
|
39
|
+
allowed: false,
|
|
40
|
+
reason_zh: "运行时推断结果不得自动落盘,请使用 init --auto 或明确确认后写入。",
|
|
41
|
+
requires_confirmation: true,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (context.kind === "existing_project" && isSoloforgeManaged && !context.confirmed) {
|
|
45
|
+
return {
|
|
46
|
+
allowed: false,
|
|
47
|
+
reason_zh: "已有项目写入 SoloForge 管理文件需要用户确认。",
|
|
48
|
+
requires_confirmation: true,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
return { allowed: true, reason_zh: "写入边界允许", requires_confirmation: false };
|
|
52
|
+
}
|
|
53
|
+
export function getWriteConfirmationPrompt(context, targetPath) {
|
|
54
|
+
const decision = isWriteAllowed(context, targetPath);
|
|
55
|
+
if (decision.allowed)
|
|
56
|
+
return "无需额外确认。";
|
|
57
|
+
return `即将向 ${context.kind} 项目写入 ${targetPath}。${decision.reason_zh}`;
|
|
58
|
+
}
|
|
59
|
+
export function validateWriteBoundary(context, writes) {
|
|
60
|
+
const violations = [];
|
|
61
|
+
for (const target of writes) {
|
|
62
|
+
const decision = isWriteAllowed(context, target);
|
|
63
|
+
if (!decision.allowed) {
|
|
64
|
+
violations.push({ target_path: target, reason_zh: decision.reason_zh });
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return violations;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=config_write_boundary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config_write_boundary.js","sourceRoot":"","sources":["../../src/engine/config_write_boundary.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"consumable_asset_registry.d.ts","sourceRoot":"","sources":["../../src/engine/consumable_asset_registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,MAAM,eAAe,GACvB,UAAU,GACV,YAAY,GACZ,UAAU,GACV,kBAAkB,GAClB,WAAW,GACX,eAAe,GACf,YAAY,CAAC;AAEjB,MAAM,MAAM,SAAS,GACjB,qBAAqB,GACrB,oBAAoB,GACpB,mBAAmB,GACnB,0BAA0B,GAC1B,aAAa,GACb,gBAAgB,GAChB,aAAa,GACb,WAAW,GACX,iBAAiB,GACjB,mBAAmB,GACnB,gBAAgB,GAChB,2BAA2B,GAC3B,yBAAyB,CAAC;AAE9B,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,SAAS,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,eAAe,CAAC;IAClC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAmJD,eAAO,MAAM,yBAAyB,EAAE,kBAAkB,
|
|
1
|
+
{"version":3,"file":"consumable_asset_registry.d.ts","sourceRoot":"","sources":["../../src/engine/consumable_asset_registry.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,MAAM,MAAM,eAAe,GACvB,UAAU,GACV,YAAY,GACZ,UAAU,GACV,kBAAkB,GAClB,WAAW,GACX,eAAe,GACf,YAAY,CAAC;AAEjB,MAAM,MAAM,SAAS,GACjB,qBAAqB,GACrB,oBAAoB,GACpB,mBAAmB,GACnB,0BAA0B,GAC1B,aAAa,GACb,gBAAgB,GAChB,aAAa,GACb,WAAW,GACX,iBAAiB,GACjB,mBAAmB,GACnB,gBAAgB,GAChB,2BAA2B,GAC3B,yBAAyB,CAAC;AAE9B,MAAM,WAAW,kBAAkB;IACjC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,SAAS,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,gBAAgB,EAAE,eAAe,CAAC;IAClC,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAmJD,eAAO,MAAM,yBAAyB,EAAE,kBAAkB,EA0pCzD,CAAC;AAIF;;;GAGG;AACH;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,EAAE,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAEjF;AAED,wBAAgB,2BAA2B,IAAI,kBAAkB,EAAE,CAElE;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAEtF;AAED;;;;GAIG;AACH,wBAAgB,8BAA8B,CAAC,QAAQ,EAAE,MAAM,GAAG,kBAAkB,EAAE,CAErF;AAED;;;;GAIG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,eAAe,GAAG,kBAAkB,EAAE,CAEtF"}
|