@feng0531/dsh-code-review 0.25.2 → 0.26.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 +10 -0
- package/README.md +1 -1
- package/package.json +1 -1
- package/src/context-candidates.mjs +1 -1
- package/src/csharp-context.mjs +3 -2
- package/src/defect-guidance.mjs +2 -1
- package/src/primary-input.mjs +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# 变更记录
|
|
2
2
|
|
|
3
|
+
## 0.26.0
|
|
4
|
+
|
|
5
|
+
- Shader/HLSL/GLSL/cginc/hlsli/compute直接字面include纳入有界自动上下文,不宏/条件展开,不编译搜索路径。
|
|
6
|
+
- 专用坐标空间、精度/NaN、采样/资源绑定/pass变体缺陷指引;270测试通过,不保证编译或绑定。
|
|
7
|
+
|
|
8
|
+
## 0.25.3
|
|
9
|
+
|
|
10
|
+
- 历史C#方法语法提示按侧使用明确捕获的oldText/目标text,标记contextSide/contextVersion;缺oldText不回退新定义。
|
|
11
|
+
- 268测试通过,线索不作为语义绑定或因果证明,不额外读取。
|
|
12
|
+
|
|
3
13
|
## 0.25.2
|
|
4
14
|
|
|
5
15
|
- 修预览已知跨文件minimumCalls计入风险规划,动态业务交互maximumAdditionalInitialCalls同样计入规划阶段。
|
package/README.md
CHANGED
package/package.json
CHANGED
|
@@ -10,7 +10,7 @@ export function contextCandidates(files, trackedPaths, {maxCandidates=20,onProbe
|
|
|
10
10
|
relativePath(f.path);if(f.eligibility!=='reviewable'||f.rightExists===false)continue;
|
|
11
11
|
const text=f.right?.text;if(typeof text!=='string'||Buffer.byteLength(text)>256*1024)continue;
|
|
12
12
|
if(text.includes('/*')||text.includes(String.fromCharCode(96))||text.includes('R"')||/\\\r?\n/.test(text))continue;
|
|
13
|
-
const cpp=/\.(c|cc|cpp|cxx|h|hh|hpp|hxx)$/i.test(f.path),js=/\.(mjs|cjs|js|jsx|ts|tsx)$/i.test(f.path);
|
|
13
|
+
const cpp=/\.(c|cc|cpp|cxx|h|hh|hpp|hxx|shader|hlsl|glsl|cginc|hlsli|compute)$/i.test(f.path),js=/\.(mjs|cjs|js|jsx|ts|tsx)$/i.test(f.path);
|
|
14
14
|
if(cpp&&/^\s*#\s*(if|ifdef|ifndef|elif|else|define|undef)\b/m.test(text))continue;
|
|
15
15
|
for(const line of text.split('\n')){
|
|
16
16
|
const match=cpp?/^\s*#\s*include\s*"([^"\\]+)"\s*(?:\/\/.*)?$/.exec(line):js?/^\s*(?:import\s+(?:(?:[^'";]+)\s+from\s+)?|export\s+(?:[^'";]+)\s+from\s+)(['"])([^'"\\]+)\1\s*;?\s*(?:\/\/.*)?$/.exec(line):null;
|
package/src/csharp-context.mjs
CHANGED
|
@@ -3,9 +3,10 @@ const safe = text => typeof text === 'string' && Buffer.byteLength(text) <= 256
|
|
|
3
3
|
const namespaceOf = text => { const matches = [...text.matchAll(/^\s*namespace\s+([A-Za-z_][A-Za-z0-9_.]*)\s*;\s*$/gm)]; return matches.length === 1 ? matches[0][1] : null; };
|
|
4
4
|
export function inferCsharpContext(input, primary) {
|
|
5
5
|
if (!primary.path.endsWith('.cs')) return [];
|
|
6
|
-
const
|
|
6
|
+
const approvedContexts = (input.context ?? []).filter(c => c.path.endsWith('.cs') && !input.files.some(f => f.path === c.path));
|
|
7
7
|
const result = [];
|
|
8
8
|
for (const side of ['old', 'new']) {
|
|
9
|
+
const contexts = input.history ? approvedContexts.map(c=>({...c,text:side==='old'?c.oldText:c.text})) : approvedContexts;
|
|
9
10
|
const source = (side === 'old' ? primary.left : primary.right)?.text;
|
|
10
11
|
if (!safe(source) || /\busing\b|\bdynamic\b/.test(source)) continue;
|
|
11
12
|
const ns = namespaceOf(source); if (!ns) continue;
|
|
@@ -38,7 +39,7 @@ export function inferCsharpContext(input, primary) {
|
|
|
38
39
|
if (malformed || depth !== 0 || typeDepth !== 0 || methodDepth !== 1 || methods[0]?.number <= classes[0].number) continue;
|
|
39
40
|
if (occurrences.length === 1 && methods.length === 1) declarations.push({ contextPath:context.path, typeLine:classes[0].number, declarationLine:methods[0].number });
|
|
40
41
|
}
|
|
41
|
-
if (declarations.length === 1) result.push({ primaryPath:primary.path, side, contextVersion:'approved-current-not-historical', callLine:i+1, namespace:ns, type, method, ...declarations[0], confidence:'conservative-syntax-only' });
|
|
42
|
+
if (declarations.length === 1) result.push({ primaryPath:primary.path, side, contextVersion:input.history ? (side==='old'?input.history.base:input.history.target) : 'approved-current-not-historical', ...(input.history ? {contextSide:side} : {}), callLine:i+1, namespace:ns, type, method, ...declarations[0], confidence:'conservative-syntax-only' });
|
|
42
43
|
if (result.length >= 20) return result;
|
|
43
44
|
}
|
|
44
45
|
}
|
package/src/defect-guidance.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Original defect checklists, not executable rules or proof of a defect.
|
|
2
2
|
const common = ['Only report a concrete defect with trigger, impact and changed-code evidence.', 'Check before/after behavior and counterexamples; absent context means uncertainty, not an invented contract.'];
|
|
3
3
|
const checklists = {
|
|
4
|
+
shader: ['Check coordinate spaces, matrix/vector order, normal transforms, UV units and screen/projection conventions against captured pipeline evidence.', 'Check division/normalization and precision near zero, NaN propagation, sampling/LOD behavior and bounds for changed input domains.', 'Check resource bindings, pass/keyword variants, depth/blend state and synchronization against actual consumers; do not invent platform/compiler behavior or include search paths.'],
|
|
4
5
|
objc: ['Check ARC/manual ownership, retain cycles, weak/unowned callbacks and Objective-C++ lifetime crossings against captured contracts.', 'Check observer/block cancellation and queue affinity before teardown; message to nil is not proof that required work completed.'],
|
|
5
6
|
swift: ['Check optional force unwraps and unowned captures against actual object lifetime and failure paths.', 'Check actor isolation, task cancellation, continuation completion exactly once and resources surviving asynchronous work.'],
|
|
6
7
|
matlab: ['Check matrix dimensions, elementwise versus matrix operations and indexing against captured input contracts.', 'Check empty/NaN values, numeric precision, resource cleanup and changed output shapes with actual consumers.'],
|
|
@@ -19,7 +20,7 @@ export function defectGuidance(filePath, sourceText = '') {
|
|
|
19
20
|
const lower = filePath.toLowerCase();
|
|
20
21
|
const first = typeof sourceText === 'string' ? sourceText.slice(0,8192).split('\n').map(s=>s.trim()).find(Boolean) ?? '' : '';
|
|
21
22
|
const sniffed = lower.endsWith('.m') ? (/^(?:#(?:import|include|pragma|if|define)\b|@(?:import|interface|implementation|class|protocol)\b|\/\/|\/\*)/.test(first) ? 'objc' : 'matlab') : null;
|
|
22
|
-
const specialized = sniffed ?? (/\.mm$/.test(lower) ? 'objc' : /\.swift$/.test(lower) ? 'swift' : null) ?? (/\.java$/.test(lower) ? 'java' : /\.go$/.test(lower) ? 'go' : /\.(py|pyi)$/.test(lower) ? 'python' : /\.rs$/.test(lower) ? 'rust' : /\.(kt|kts)$/.test(lower) ? 'kotlin' : /\.(php|phtml)$/.test(lower) ? 'php' : null);
|
|
23
|
+
const specialized = /\.(shader|hlsl|glsl|cginc|hlsli|compute)$/.test(lower) ? 'shader' : sniffed ?? (/\.mm$/.test(lower) ? 'objc' : /\.swift$/.test(lower) ? 'swift' : null) ?? (/\.java$/.test(lower) ? 'java' : /\.go$/.test(lower) ? 'go' : /\.(py|pyi)$/.test(lower) ? 'python' : /\.rs$/.test(lower) ? 'rust' : /\.(kt|kts)$/.test(lower) ? 'kotlin' : /\.(php|phtml)$/.test(lower) ? 'php' : null);
|
|
23
24
|
const language = specialized ?? (/\.(c|cc|cpp|cxx|h|hh|hpp|hxx)$/.test(lower) ? 'cpp' : lower.endsWith('.cs') ? 'csharp' : /\.(js|jsx|mjs|cjs|ts|tsx)$/.test(lower) ? 'javascript' : /\.(json|yaml|yml|toml|ini|xml|properties)$/.test(lower) ? 'configuration' : 'generic');
|
|
24
25
|
const fileType = /^\.github\/workflows\/.+\.(yaml|yml)$/.test(lower) ? 'github-workflow' : /(?:^|\/)(package\.json|cargo\.toml|pom\.xml|build\.gradle|composer\.json)$/.test(lower) ? 'dependency-manifest' : undefined;
|
|
25
26
|
const purpose = fileType ?? (/\.(ftl|ftlh|ftlx|hbs|mustache|jinja2|j2|pug|astro)$/.test(lower) ? 'template' : /\.(tf|hcl|tfvars|bicep|nix)$/.test(lower) ? 'infrastructure' : /\.(proto|thrift|capnp|graphql|gql|prisma)$/.test(lower) ? 'protocol-schema' : undefined);
|
package/src/primary-input.mjs
CHANGED
|
@@ -23,7 +23,7 @@ export function preparePrimaryInput(input, file, { instructions, scope, grouping
|
|
|
23
23
|
if (calls.length) { base.cppCallSites = calls; base.cppCallNotice = '最多20条零参语法位置/侧,仅导航子集;不表示全部调用覆盖,不证明宏展开、重载选择、动态分派或执行顺序。其他源码须在批准范围内读取。'; }
|
|
24
24
|
}
|
|
25
25
|
const csharpHints = inferCsharpContext(input, file);
|
|
26
|
-
if (csharpHints.length) { base.csharpContextHints = csharpHints; base.csharpContextNotice = '
|
|
26
|
+
if (csharpHints.length) { base.csharpContextHints = csharpHints; base.csharpContextNotice = '仅批准context的C#静态类型/方法语法位置;历史输入按contextSide/contextVersion区分正文,无旧正文不回退目标侧。不证明语义绑定或执行可达。歧义不推定,线索不增加审查覆盖。'; }
|
|
27
27
|
let payload = JSON.stringify(base);
|
|
28
28
|
const measure = value => initialInputBudget({ instructions, input: value }, scope, maxInputBytes);
|
|
29
29
|
const metadata = {};
|