dsh-code-security 0.3.4 → 0.3.6

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.en.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # dsh-code-security
2
2
 
3
- ## 0.3.4 update (2026-09-27)
3
+ ## 0.3.5 update (2026-09-28)
4
4
 
5
- Fixes scan output validation when no baseline exists. SARIF now uses workspace file URIs, relative locations and structured rule descriptions, including paths with spaces and Unicode.
5
+ Rejects unknown scan arguments and empty targets before scanning or replacing state, preventing misspelled scopes from expanding to the whole workspace. Fixes standard-mode output incorrectly displaying zero files and a failed verdict: counts, verdicts and findings now come from the actual scan result.
6
6
 
7
- Validation host: Harness 0.1.7-rc.2 built from official sources, retaining the local tool-scheduler fix. Build and automated checks pass; interactive coverage and external-service limits are recorded in this release round.
7
+ Validation host: Harness `0.2.0-rc.1` built from official sources (commit `407e65c8`) with Node `24.16.0` on 2026-09-28. All 31 plugin tests pass in an isolated environment; all 18 plugins mount together in one host registering 10 tools, with tool schemas and health-check contracts passing. No live ports or external services were exercised in this round.
8
8
 
9
9
  ![npm](https://img.shields.io/npm/v/dsh-code-security) ![downloads](https://img.shields.io/npm/dm/dsh-code-security) ![license](https://img.shields.io/github/license/STARDUSTLC666/dsh-code-security) ![stars](https://img.shields.io/github/stars/STARDUSTLC666/dsh-code-security?style=social)
10
10
 
package/README.md CHANGED
@@ -1,10 +1,10 @@
1
1
  # dsh-code-security
2
2
 
3
- ## 0.3.4 更新(2026-09-27)
3
+ ## 0.3.5 更新(2026-09-28)
4
4
 
5
- 修复未设置基线时扫描结果被新版 Harness 拒绝的问题。SARIF 正确使用工作区文件 URI、相对路径和规则描述对象,支持空格与中文文件名。
5
+ 扫描参数写错时明确报错,避免把 `paths`、`files` 或空目标误当成扫描整个工作区。修复标准模式中结果卡片误显示“0 个文件、未通过”的问题;文件数量、结论与问题列表现在使用实际扫描结果。
6
6
 
7
- 验证宿主:官方源码构建的 Harness 0.1.7-rc.2(保留本地工具调度器修复)。构建与自动测试通过;实际操作和外部服务限制见本轮验收记录。
7
+ 验证宿主:官方源码构建的 Harness `0.2.0-rc.1`(commit `407e65c8`)+ Node `24.16.0`(2026-09-28)。31 项插件测试在隔离环境全部通过;同一个宿主里 18 个插件共同加载,注册 10 个工具,工具 schema 与健康检查契约通过。本轮未启用真实端口与外部服务。
8
8
 
9
9
  ![npm](https://img.shields.io/npm/v/dsh-code-security) ![downloads](https://img.shields.io/npm/dm/dsh-code-security) ![license](https://img.shields.io/github/license/STARDUSTLC666/dsh-code-security) ![stars](https://img.shields.io/github/stars/STARDUSTLC666/dsh-code-security?style=social)
10
10
 
package/lib/tools.d.ts CHANGED
@@ -18,6 +18,7 @@ export interface SecureToolDefinition {
18
18
  type: 'object';
19
19
  properties: Record<string, unknown>;
20
20
  required?: string[];
21
+ additionalProperties?: boolean;
21
22
  };
22
23
  output: {
23
24
  schema: Record<string, unknown>;
package/lib/tools.js CHANGED
@@ -33,6 +33,21 @@ function compileParameters(spec) {
33
33
  }
34
34
  return { type: 'object', properties, ...(required.length > 0 ? { required } : {}) };
35
35
  }
36
+ /** Reject ambiguous scopes before reading files, running git, or replacing scan state. */
37
+ function scanArguments(raw, allowed = ['target']) {
38
+ if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
39
+ throw new Error('扫描参数必须是对象。请用 { target: "文件或目录" } 限定范围;扫描整个工作区请传 {}。');
40
+ }
41
+ const args = raw;
42
+ const unknown = Object.keys(args).filter(key => !allowed.includes(key));
43
+ if (unknown.length > 0) {
44
+ throw new Error('不支持的扫描参数:' + unknown.join('、') + '。请使用 target 指定一个文件或目录;仅省略 target 或使用 target: "." 才扫描整个工作区。');
45
+ }
46
+ if (Object.hasOwn(args, 'target') && (typeof args.target !== 'string' || args.target.trim() === '')) {
47
+ throw new Error('扫描参数 target 必须是非空的文件或目录字符串。扫描整个工作区请省略 target 或使用 "."。');
48
+ }
49
+ return args;
50
+ }
36
51
  const findingSchema = {
37
52
  type: 'object',
38
53
  properties: {
@@ -70,7 +85,7 @@ function baselineSummary(value) {
70
85
  accepted: Array.isArray(rec.acceptedFindings) ? rec.acceptedFindings : [],
71
86
  };
72
87
  }
73
- function renderFindings(value) {
88
+ function renderFindings(_args, value) {
74
89
  const rec = (value ?? {});
75
90
  const findings = Array.isArray(rec.findings) ? rec.findings : [];
76
91
  const counts = rec.counts;
@@ -88,13 +103,13 @@ export function buildSecureTools(cfg, cwd, runner) {
88
103
  const stateDir = cfg.stateDir;
89
104
  const secureScan = {
90
105
  name: 'secure_scan',
91
- description: '扫描工作区(或指定文件/目录),用确定性规则检测注入、弱加密、硬编码密钥、危险配置等问题。结果写入 .code-security 状态供 secure_fix_verify 对比。',
92
- parameters: compileParameters({
93
- target: { type: 'string', description: '要扫描的文件或目录(可选,缺省扫描整个工作区)。' },
94
- }),
106
+ description: '扫描工作区(或指定文件/目录),用确定性规则检测注入、弱加密、硬编码密钥、危险配置等问题。使用 target 字符串限定范围,不接受 paths/files 等参数;{} 表示整个工作区。结果写入 .code-security 状态供 secure_fix_verify 对比。',
107
+ parameters: { ...compileParameters({
108
+ target: { type: 'string', description: '要扫描的文件或目录(可选,缺省扫描整个工作区)。' },
109
+ }), additionalProperties: false },
95
110
  output: { schema: scanSchema, render: renderFindings },
96
111
  async execute(rawArgs) {
97
- const args = (rawArgs ?? {});
112
+ const args = scanArguments(rawArgs);
98
113
  const target = optionalString(args, 'target');
99
114
  const policy = await loadPolicy(cwd);
100
115
  const failOn = policy.failOn ?? cfg.failOn;
@@ -119,14 +134,14 @@ export function buildSecureTools(cfg, cwd, runner) {
119
134
  const secureDiff = {
120
135
  name: 'secure_diff',
121
136
  description: '只审查 git diff 的新增行(默认 HEAD,即未提交改动)。base 可用任意 git ref;staged=true 审查已暂存改动;target 可限定文件。结果同样写入状态。',
122
- parameters: compileParameters({
123
- base: { type: 'string', description: 'git 基线(默认 HEAD)。' },
124
- target: { type: 'string', description: '限定文件路径(可选)。' },
125
- staged: { type: 'boolean', description: '审查已暂存改动(git diff --cached,默认 false)。' },
126
- }),
137
+ parameters: { ...compileParameters({
138
+ base: { type: 'string', description: 'git 基线(默认 HEAD)。' },
139
+ target: { type: 'string', description: '限定文件路径(可选)。' },
140
+ staged: { type: 'boolean', description: '审查已暂存改动(git diff --cached,默认 false)。' },
141
+ }), additionalProperties: false },
127
142
  output: { schema: scanSchema, render: renderFindings },
128
143
  async execute(rawArgs) {
129
- const args = (rawArgs ?? {});
144
+ const args = scanArguments(rawArgs, ['base', 'target', 'staged']);
130
145
  const base = optionalString(args, 'base') ?? 'HEAD';
131
146
  const target = optionalString(args, 'target');
132
147
  const policy = await loadPolicy(cwd);
@@ -153,9 +168,9 @@ export function buildSecureTools(cfg, cwd, runner) {
153
168
  const secureFixVerify = {
154
169
  name: 'secure_fix_verify',
155
170
  description: '复扫并与上次扫描基线对比,输出已关闭、仍存在、新引入的问题指纹。用于修复后确认没有按下葫芦浮起瓢。',
156
- parameters: compileParameters({
157
- target: { type: 'string', description: '复扫文件或目录(可选,缺省扫描整个工作区)。' },
158
- }),
171
+ parameters: { ...compileParameters({
172
+ target: { type: 'string', description: '复扫文件或目录(可选,缺省扫描整个工作区)。' },
173
+ }), additionalProperties: false },
159
174
  output: {
160
175
  schema: {
161
176
  type: 'object',
@@ -173,7 +188,7 @@ export function buildSecureTools(cfg, cwd, runner) {
173
188
  },
174
189
  },
175
190
  async execute(rawArgs) {
176
- const args = (rawArgs ?? {});
191
+ const args = scanArguments(rawArgs);
177
192
  const target = optionalString(args, 'target');
178
193
  const policy = await loadPolicy(cwd);
179
194
  const state = await loadState(stateDir);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-code-security",
3
- "version": "0.3.4",
3
+ "version": "0.3.6",
4
4
  "description": "DSH 代码安全审查插件:40+ 确定性规则与密钥熵检测,支持 git diff/staged 审查、SARIF 导出、基线接受与 SBOM-lite。",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",