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 +3 -3
- package/README.md +3 -3
- package/lib/tools.d.ts +1 -0
- package/lib/tools.js +31 -16
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# dsh-code-security
|
|
2
2
|
|
|
3
|
-
## 0.3.
|
|
3
|
+
## 0.3.5 update (2026-09-28)
|
|
4
4
|
|
|
5
|
-
|
|
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.
|
|
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
|
   
|
|
10
10
|
|
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# dsh-code-security
|
|
2
2
|
|
|
3
|
-
## 0.3.
|
|
3
|
+
## 0.3.5 更新(2026-09-28)
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
扫描参数写错时明确报错,避免把 `paths`、`files` 或空目标误当成扫描整个工作区。修复标准模式中结果卡片误显示“0 个文件、未通过”的问题;文件数量、结论与问题列表现在使用实际扫描结果。
|
|
6
6
|
|
|
7
|
-
验证宿主:官方源码构建的 Harness 0.
|
|
7
|
+
验证宿主:官方源码构建的 Harness `0.2.0-rc.1`(commit `407e65c8`)+ Node `24.16.0`(2026-09-28)。31 项插件测试在隔离环境全部通过;同一个宿主里 18 个插件共同加载,注册 10 个工具,工具 schema 与健康检查契约通过。本轮未启用真实端口与外部服务。
|
|
8
8
|
|
|
9
9
|
   
|
|
10
10
|
|
package/lib/tools.d.ts
CHANGED
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: '
|
|
92
|
-
parameters: compileParameters({
|
|
93
|
-
|
|
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
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
|
|
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);
|