@feng0531/dsh-code-review 0.33.0 → 0.33.2

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 CHANGED
@@ -1,10 +1,20 @@
1
1
  # 变更记录
2
2
 
3
+ ## 0.33.2
4
+
5
+ - 接受唯一完整JSON的单一json/无语言Markdown围栏,不提取任意说明中的JSON、不修正文法/字段、不重试;后续原schema及证据校验不变。
6
+ - 不完整JSON返回MODEL_INVALID_JSON及字节/封装类型诊断,不泄露响应正文。317离线测试通过。实际碰撞审查原始响应未知,不能宣称复现其三处根因;超时与大文件范围缺口仍待定位。
7
+
8
+ ## 0.33.1
9
+
10
+ - 修正named import alias同一调用行再次出现别名(重赋值/逃逸/嵌套调用)仍产生绑定提示的误关联;保留字面导航而不证明真实绑定。
11
+ - 314离线测试、pack/隔离安装、固定标签四矩阵及原工件发布核验通过:npm/Release88082字节双hash一致;B3整体未完成。
12
+
3
13
  ## 0.33.0
4
14
 
5
15
  - 新增Git历史显式oldContextPaths,baseline对象只读捕获及版本/OID/hash身份;不伪造目标正文,不绕过所选变更边界。
6
16
  - reader与导入/C#关系消费者按侧分派;schema/service预览显示旧侧元数据,生成/综合/复核提示纳入共享输入预算。
7
- - 链接/submodule/凭据、重复及重叠路径、root无baseline、字节/槽/快照预算拒绝;真实Git零发送预览、工作树隔离、证据receipt验收。311离线测试通过;候选发布门禁待验证。
17
+ - 链接/submodule/凭据、重复及重叠路径、root无baseline、字节/槽/快照预算拒绝;真实Git零发送预览、工作树隔离、证据receipt验收。311离线测试通过;标签CI37904841884及发布37905053267成功,npm/正式Release原字节87754及SHA512/SHA256核验匹配。
8
18
 
9
19
  ## 0.32.0
10
20
 
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  ## 当前状态
6
6
 
7
- 当前代码版本为 0.33.0(候选版本,远端发布门禁待验证;已验收正式版本为0.32.0)
7
+ 当前正式版本为 0.33.1(固定标签四矩阵及npm/Release原工件字节双hash门禁通过);0.33.2为JSON封装兼容候选,尚未正式验收。
8
8
 
9
9
  Git历史预览新增oldContextPaths:最多20个显式仓库相对文件,与contextPaths/自动上下文共享20槽、256KiB每blob及4MiB快照。仅从baseline普通Git blob捕获,不checkout/fetch/读取工作树;根提交无baseline拒绝,working/SVN明确拒绝。旧侧条目携带oldRevision/oldBlobOid/oldHash,仅进入context-old;oldOnly表示仅批准旧侧,不证明target路径不存在。所选变更复用原changed-old,不重复上下文;excluded/blocked变更、链接/submodule、凭据路径不能重新进入。预览显示身份元数据、不显示正文,确认执行才按宿主正常权限发送。主审/综合/复核按侧提示,计入原输入预算,旧证据不能冒充新侧回归证明。
10
10
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@feng0531/dsh-code-review",
3
- "version": "0.33.0",
3
+ "version": "0.33.2",
4
4
  "private": false,
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "publishConfig": { "access": "public", "registry": "https://registry.npmjs.org/" },
package/src/dsh-model.mjs CHANGED
@@ -1,3 +1,4 @@
1
+ import { modelJson } from './model-json.mjs';
1
2
  /** One-shot host LLM call. No agent loop and no executable tools. */
2
3
  export function createDshModel(llm, route, { maxTokens = 4096, maxOutputBytes = 128 * 1024 } = {}) {
3
4
  if (!llm || typeof llm.stream !== 'function' || !route?.provider || !route?.model) throw new Error('DSH provider and model are required');
@@ -21,6 +22,6 @@ export function createDshModel(llm, route, { maxTokens = 4096, maxOutputBytes =
21
22
  }
22
23
  }
23
24
  if (!finished) throw new Error('Model stream ended without finish');
24
- return output;
25
+ return modelJson(output);
25
26
  };
26
27
  }
@@ -11,6 +11,10 @@ export function directImportBindings(lines, importLine, calls, targetText) {
11
11
  const token = new RegExp('(^|[^A-Za-z0-9_$])' + local.replaceAll('$', '\\$') + '([^A-Za-z0-9_$]|$)');
12
12
  const positions = calls.filter(c => c.local === local);
13
13
  if (!positions.length) continue;
14
+ // Arguments may mutate/escape the alias on the SAME indexed call line.
15
+ // Keep a hint only when the sole local token is the call callee.
16
+ const occurrences = new RegExp('(^|[^A-Za-z0-9_$])' + local.replaceAll('$', '\\$') + '(?=[^A-Za-z0-9_$]|$)', 'g');
17
+ if (positions.some(call => [...lines[call.line - 1].matchAll(occurrences)].length !== 1)) continue;
14
18
  // Every other occurrence may be declaration, parameter, mutation or escape.
15
19
  if (lines.some((line, i) => i + 1 !== importLine && !positions.some(c => c.line === i + 1) && token.test(line))) continue;
16
20
  const declarations = targets.map((line, i) => ({ line, number: i + 1 })).filter(item => /^\s*export\s+(?:async\s+)?function\s+([A-Za-z_$][A-Za-z0-9_$]*)\s*\(/.exec(item.line)?.[1] === imported);
@@ -0,0 +1,12 @@
1
+ // Accept one complete JSON value, optionally inside one exact Markdown fence.
2
+ export function modelJson(text) {
3
+ const bytes=Buffer.byteLength(text);
4
+ const trimmed=text.trim();
5
+ const fence=/^```(?:json)?\r?\n([\s\S]*)\r?\n```$/.exec(trimmed);
6
+ const body=fence?fence[1]:trimmed;
7
+ try { JSON.parse(body); } catch {
8
+ const error=new Error('Model response is not complete JSON (bytes='+bytes+', envelope='+(fence?'json-fence':'plain')+'); no repair or retry performed');
9
+ error.code='MODEL_INVALID_JSON';throw error;
10
+ }
11
+ return body;
12
+ }