@feng0531/dsh-code-review 0.19.2 → 0.20.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 +5 -0
- package/README.md +3 -1
- package/index.mjs +1 -1
- package/package.json +1 -1
- package/src/service.mjs +3 -2
- package/src/snapshot.mjs +1 -0
- package/src/tracked-context.mjs +1 -1
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
|
|
5
5
|
## 当前状态
|
|
6
6
|
|
|
7
|
-
当前代码版本为 0.
|
|
7
|
+
当前代码版本为 0.20.0
|
|
8
|
+
|
|
9
|
+
可在预览传入 `autoContext: true`,显式选择有界Git直接import/include上下文捕获;默认关闭。候选、阻塞、截断及实际路径在预览可见,正文仅在确认后发送,执行重新验证快照。仅当前侧导航非历史/调用图,SVN暂不支持;不会自动引入未跟踪或排除变更。,包含有界覆盖预检、显式项目规则及候选证据与反证复核;发布状态以 npm 和 GitHub Release 为准。已通过真实临时 Git/SVN 仓库测试,以及隔离进程中的真实 DSH ToolRuntime 注册验证。当前开发会话的实际预览已返回0.6.0的plan/rules字段,空变更预览与默认关闭外发已验证;已进行经宿主审批的六次小规模真实试跑,累计12次模型调用;四组合成正负例与历史修复对照符合预期,历史引入方向检出候选但引用复核未完成(partial)。不是独立盲测或整体质量证明。详情见 [试跑结果](evaluation/PILOT-RESULTS.md)。
|
|
8
10
|
|
|
9
11
|
## 工作区下多个子仓库(0.11.0)
|
|
10
12
|
|
package/index.mjs
CHANGED
|
@@ -12,7 +12,7 @@ export function apply(ctx, config = {}) {
|
|
|
12
12
|
};
|
|
13
13
|
ctx.tools.register({
|
|
14
14
|
name: 'code_review_preview', description: 'Preview Git/SVN working-copy review scope and model destination without sending source to a model. repositoryPath selects an explicit child repository relative to session workspace; file paths are repository-relative. Preview each repository separately. Show the preview before execution.',
|
|
15
|
-
parameters: { type: 'object', additionalProperties: false, properties: { repositoryPath: { type: 'string', description: 'Workspace-relative explicit child Git/SVN repository root, forward slashes; omit for current repository.' }, selectedPaths: { type: 'array', items: { type: 'string' }, maxItems: 200 }, contextPaths: { type: 'array', items: { type: 'string' }, maxItems: 20 }, rulePaths: { type: 'array', items: { type: 'string' }, maxItems: 4 } } },
|
|
15
|
+
parameters: { type: 'object', additionalProperties: false, properties: { repositoryPath: { type: 'string', description: 'Workspace-relative explicit child Git/SVN repository root, forward slashes; omit for current repository.' }, selectedPaths: { type: 'array', items: { type: 'string' }, maxItems: 200 }, autoContext: { type: 'boolean', description: 'Opt in to bounded direct tracked Git import/include context captured and shown in preview; unsupported on SVN currently.' }, contextPaths: { type: 'array', items: { type: 'string' }, maxItems: 20 }, rulePaths: { type: 'array', items: { type: 'string' }, maxItems: 4 } } },
|
|
16
16
|
output,
|
|
17
17
|
async execute(args, exec) { const preview = await service.preview(args, exec); return { json: JSON.stringify(preview), markdown: '' }; },
|
|
18
18
|
});
|
package/package.json
CHANGED
package/src/service.mjs
CHANGED
|
@@ -26,7 +26,8 @@ export function createReviewService(llm, { capture = captureSnapshot, now = Date
|
|
|
26
26
|
exec = bind(exec);
|
|
27
27
|
exec.signal.throwIfAborted();
|
|
28
28
|
if (busy) throw new Error('Review service busy');
|
|
29
|
-
if (!args || Object.keys(args).some(k => !['repositoryPath', 'selectedPaths', 'contextPaths', 'rulePaths'].includes(k))) throw new Error('Unknown preview argument');
|
|
29
|
+
if (!args || Object.keys(args).some(k => !['repositoryPath', 'selectedPaths', 'contextPaths', 'rulePaths', 'autoContext'].includes(k))) throw new Error('Unknown preview argument');
|
|
30
|
+
if (args.autoContext !== undefined && typeof args.autoContext !== 'boolean') throw new Error('Invalid autoContext option');
|
|
30
31
|
for (const key of ['selectedPaths', 'contextPaths', 'rulePaths']) if (args[key] !== undefined && (!Array.isArray(args[key]) || args[key].length > (key === 'rulePaths' ? 4 : 200) || args[key].some(p => typeof p !== 'string'))) throw new Error('Invalid path list');
|
|
31
32
|
const current = owner(exec);
|
|
32
33
|
busy = true;
|
|
@@ -41,7 +42,7 @@ export function createReviewService(llm, { capture = captureSnapshot, now = Date
|
|
|
41
42
|
while (previews.size >= maxPreviews) previews.delete(previews.keys().next().value);
|
|
42
43
|
const previewId = randomUUID();
|
|
43
44
|
previews.set(previewId, { ...current, target, options, snapshotId: snapshot.id, expires: now() + ttlMs });
|
|
44
|
-
return { previewId, plan, snapshotId: snapshot.id, repositoryRoot: snapshot.root, vcs: snapshot.vcs, 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), rules: (snapshot.rules ?? []).map(({ path, hash }) => ({ path, hash })), notice: (enableRiskPlanning ? '执行先制定风险假设计划,再审查并复核;计划不是证据,所有阶段共享原预算。' : '') + '
|
|
45
|
+
return { previewId, plan, snapshotId: snapshot.id, repositoryRoot: snapshot.root, vcs: snapshot.vcs, 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不含后续检索/复核/动态业务综合;多文件可先进行业务分组,分组失败保留原组并记录限制,动态综合数执行前未知,实际预算可能不足。请先向用户展示范围,获得确认后执行。' };
|
|
45
46
|
} finally { busy = false; }
|
|
46
47
|
},
|
|
47
48
|
async execute(args, exec) {
|
package/src/snapshot.mjs
CHANGED
|
@@ -27,6 +27,7 @@ export async function captureSnapshot(cwd, options = {}) {
|
|
|
27
27
|
for (const value of [maxContextFiles, maxSnapshotBytes]) if (!Number.isSafeInteger(value) || value < 1) throw new Error('Invalid snapshot limit');
|
|
28
28
|
if (!Array.isArray(contextPaths) || contextPaths.length > maxContextFiles) throw new Error('Context file limit exceeded');
|
|
29
29
|
for (const name of contextPaths) relativePath(name);
|
|
30
|
+
if (options.autoContext !== undefined && typeof options.autoContext !== 'boolean') throw new Error('Invalid autoContext option');
|
|
30
31
|
const type = await detectVcs(cwd);
|
|
31
32
|
const capture = type === 'git' ? captureGit : captureSvn;
|
|
32
33
|
const snapshot = await capture(cwd, options);
|
package/src/tracked-context.mjs
CHANGED
|
@@ -7,7 +7,7 @@ export async function gitContextIndex(root, options = {}) {
|
|
|
7
7
|
if(records.length>10000)throw new Error('Tracked context index limit exceeded');
|
|
8
8
|
const entries=new Map();
|
|
9
9
|
for(const record of records){
|
|
10
|
-
const match=/^(\d{6}) ([a-f0-9]+) ([0-3])\t(
|
|
10
|
+
const match=/^(\d{6}) ([a-f0-9]+) ([0-3])\t([\s\S]+)$/.exec(record);if(!match)throw new Error('Invalid Git context index');
|
|
11
11
|
const name=relativePath(match[4]);const valid=match[3]==='0'&&['100644','100755'].includes(match[1]);
|
|
12
12
|
if(entries.has(name))entries.set(name,false);else entries.set(name,valid);
|
|
13
13
|
}
|