@feng0531/dsh-code-review 0.31.0 → 0.31.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/README.md +3 -1
- package/package.json +1 -1
- package/src/review.mjs +4 -0
- package/src/service.mjs +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
package/package.json
CHANGED
package/src/review.mjs
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { correctAnchor } from './anchor-correction.mjs';
|
|
2
|
+
import { validateBusinessRequirement } from './business-requirement.mjs';
|
|
2
3
|
import { riskReadCoverage } from './risk-read-coverage.mjs';
|
|
3
4
|
import { BUSINESS_GROUP_INSTRUCTIONS, prepareBusinessGroups, validateBusinessGroups } from './business-groups.mjs';
|
|
4
5
|
import { RISK_PLAN_INSTRUCTIONS, validateRiskPlan } from './risk-plan.mjs';
|
|
@@ -90,6 +91,8 @@ export async function reviewSnapshot(snapshot, model, options = {}) {
|
|
|
90
91
|
if (options.enableVerification === true && options.enableRetrieval !== true) throw new Error('Verification requires approved retrieval scope');
|
|
91
92
|
const scope = options.enableRetrieval === true ? createRetrievalScope({ ...input, context: input.context ?? [] }, { signal }) : null;
|
|
92
93
|
const report = { schemaVersion: 1, snapshotId: input.id, vcs: input.vcs, status: 'completed', files: [], findings: [], limitations: [], modelCalls: 0 };
|
|
94
|
+
validateBusinessRequirement(input.businessRequirement);
|
|
95
|
+
if(input.businessRequirement!==undefined)report.businessRequirement={hash:hash(input.businessRequirement),bytes:Buffer.byteLength(input.businessRequirement),status:'untrusted-constraint'};
|
|
93
96
|
if (input.autoContext) {
|
|
94
97
|
report.autoContext = structuredClone(input.autoContext);
|
|
95
98
|
if (input.autoContext.truncated || input.autoContext.candidates.some(c => c.status === 'blocked')) report.limitations.push({ text: '自动上下文未完全捕获:存在截断或阻塞,仅实际捕获路径可用于证据。' });
|
|
@@ -265,6 +268,7 @@ const safe = text => Array.from(String(text ?? '')).map(c => {
|
|
|
265
268
|
}).join('');
|
|
266
269
|
export function markdownReport(report) {
|
|
267
270
|
const output = ['# Code Review 报告', '', '状态:' + report.status, '快照:' + report.snapshotId, '', '## 覆盖情况'];
|
|
271
|
+
if(report.businessRequirement)output.push('- 业务需求:SHA256 '+safe(report.businessRequirement.hash)+' · '+report.businessRequirement.bytes+' bytes;不可信约束,不是证据或权限,全文不在报告重复。');
|
|
268
272
|
for (const file of report.files) for (const correction of file.anchorCorrections ?? []) output.push('- 定位纠正:' + safe(correction.originalCandidate.fileId) + ' · ' + safe(correction.status) + ' · ' + safe(correction.reason) + ';原完整候选保留JSON,仅定位不证明因果');
|
|
269
273
|
if (report.history) output.push('- Git历史审查:' + safe(report.history.mode) + ' · ' + safe(report.history.base ?? 'empty') + ' → ' + safe(report.history.target) + ';精确端点树差异,重命名按增删,不含工作树');
|
|
270
274
|
if (report.businessGrouping) output.push('- 业务分组:' + safe(report.businessGrouping.status) + (report.businessGrouping.reason ? ' — ' + safe(report.businessGrouping.reason) : '') + ';仅调度假设,不证明依赖或覆盖');
|
package/src/service.mjs
CHANGED
|
@@ -45,7 +45,7 @@ export function createReviewService(llm, { capture = captureSnapshot, now = Date
|
|
|
45
45
|
while (previews.size >= maxPreviews) previews.delete(previews.keys().next().value);
|
|
46
46
|
const previewId = randomUUID();
|
|
47
47
|
previews.set(previewId, { ...current, target, options, snapshotId: snapshot.id, expires: now() + ttlMs });
|
|
48
|
-
return { ...(options.businessRequirement!==undefined?{businessRequirement:{text:options.businessRequirement,hash:hash(options.businessRequirement),bytes:Buffer.byteLength(options.businessRequirement)}}:{}), previewId, plan, snapshotId: snapshot.id, repositoryRoot: snapshot.root, vcs: snapshot.vcs, ...(snapshot.history ? { history: snapshot.history } : {}), model: current.route, modelSendingEnabled: allowModelSending, files: snapshot.files.map(f => ({ path: f.path, eligibility: f.eligibility, reason: f.reason })), contextPaths: snapshot.context.map(c => c.path), ...(snapshot.autoContext ? { autoContext: snapshot.autoContext } : {}), rules: (snapshot.rules ?? []).map(({ path, hash }) => ({ path, hash })), notice: (enableRiskPlanning ? '执行先制定风险假设计划,再审查并复核;计划不是证据,所有阶段共享原预算。' : '') + '
|
|
48
|
+
return { ...(options.businessRequirement!==undefined?{businessRequirement:{text:options.businessRequirement,hash:hash(options.businessRequirement),bytes:Buffer.byteLength(options.businessRequirement)}}:{}), previewId, plan, snapshotId: snapshot.id, repositoryRoot: snapshot.root, vcs: snapshot.vcs, ...(snapshot.history ? { history: snapshot.history } : {}), model: current.route, modelSendingEnabled: allowModelSending, files: snapshot.files.map(f => ({ path: f.path, eligibility: f.eligibility, reason: f.reason })), contextPaths: snapshot.context.map(c => c.path), ...(snapshot.autoContext ? { autoContext: snapshot.autoContext } : {}), rules: (snapshot.rules ?? []).map(({ path, hash }) => ({ path, hash })), notice: (enableRiskPlanning ? '执行先制定风险假设计划,再审查并复核;计划不是证据,所有阶段共享原预算。' : '') + '执行会向上述模型提供方发送可审查文件两侧内容、预览列出的显式/自动上下文、所选项目规则全文及预览业务需求文本。模型可在该快照范围内多轮只读检索,不读取范围外文件;候选生成后会进行证据与反证复核,两阶段各最多3轮检索,共享每文件120秒和总模型调用100次预算;复核不能证明缺陷成立。plan仅预检初始输入,ready不代表已审查;minimumCalls不含后续检索/复核/动态业务综合;多文件可先进行业务分组,分组失败保留原组并记录限制,动态综合数执行前未知,实际预算可能不足。请先向用户展示范围,获得确认后执行。' };
|
|
49
49
|
} finally { busy = false; }
|
|
50
50
|
},
|
|
51
51
|
async execute(args, exec) {
|