Skip to content

Commit 9e77d6d

Browse files
committed
feat(scan): 扫描透明度(耗时+规则数) + 修境外厂商重复 (v0.7.3)
- 报告显示扫描耗时+检测规则数,让"秒出"可验证(正则匹配本就毫秒级,快≠假) - 修数据出境控制项同一厂商列两次(端点+SDK依赖去重,不区分大小写) - 回应用户"还是秒出?"的信任质疑
1 parent c1f4db4 commit 9e77d6d

6 files changed

Lines changed: 15 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/),
66
and this project adheres to [Semantic Versioning](https://semver.org/).
77

8+
## [0.7.3] - 2026-06-20
9+
10+
### Added — 扫描透明度("秒出=干活了吗"的证据)
11+
- 报告显示**扫描耗时 + 应用的检测规则数**(如"已扫描 150 个文件 · 耗时 28ms · 应用 53 条检测规则")——让"快"可被验证:正则匹配文本本就是毫秒级,快≠假
12+
### Fixed
13+
- 数据出境控制项不再把同一厂商列两次(端点命中 + SDK 依赖命中去重,不区分大小写)
14+
815
## [0.7.2] - 2026-06-20
916

1017
### Changed — 诚实度与真实覆盖(用户反馈"上传就出结果太假"后修正)

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "shellward",
3-
"version": "0.7.2",
3+
"version": "0.7.3",
44
"mcpName": "io.github.jnMetaCode/shellward",
55
"description": "AI agent security & MCP security middleware — prompt injection detection, AI firewall, runtime guardrails & data-loss prevention for LLM tool calls. 8-layer defense against data exfiltration & dangerous commands. Zero dependencies. SDK + OpenClaw plugin. Supports LangChain, AutoGPT, Claude Code, Cursor, OpenAI Agents, Hermes Agent.",
66
"keywords": [

src/compliance/audit.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,10 +171,11 @@ export function runProjectComplianceAudit(config: ShellWardConfig, root: string)
171171

172172
// 把文件中实测到的境外端点/依赖并入 facts(按 endpointId 或 provider 去重),
173173
// 使数据出境项基于真实证据(含 SDK 依赖通道)
174-
const seen = new Set(env.overseas.map(o => o.endpointId || o.provider_en))
174+
const seen = new Set(env.overseas.map(o => (o.endpointId || o.provider_en || '').toLowerCase()))
175175
for (const f of scan.findings) {
176176
if (f.kind !== 'overseas') continue
177-
const key = f.endpointId || f.provider_en || ''
177+
// 按厂商去重(不区分大小写),避免"端点命中"与"SDK依赖命中"把同一厂商列两次
178+
const key = (f.provider_en || f.endpointId || '').toLowerCase()
178179
if (!key || seen.has(key)) continue
179180
seen.add(key)
180181
env.overseas.push({

src/compliance/html-report.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,8 @@ export function renderHtmlReport(
9696

9797
// ===== 项目实测风险 =====
9898
S.push(sectionHead('🔍', t('项目实测风险', 'Project Scan Findings'),
99-
t(`已扫描 ${scan.filesScanned} 个文件${scan.truncated ? '(已达上限)' : ''}`,
100-
`Scanned ${scan.filesScanned} files${scan.truncated ? ' (limit reached)' : ''}`)))
99+
t(`已扫描 ${scan.filesScanned} 个文件${scan.truncated ? '(已达上限)' : ''} · 耗时 ${scan.durationMs ?? '?'}ms · 应用 ${scan.rulesChecked ?? '?'} 条检测规则`,
100+
`Scanned ${scan.filesScanned} files${scan.truncated ? ' (limit reached)' : ''} · ${scan.durationMs ?? '?'}ms · ${scan.rulesChecked ?? '?'} detection rules`)))
101101

102102
if (scan.findings.length === 0) {
103103
S.push(`<div class="empty">🟢 ${t('未在项目文件中发现硬编码密钥、个人信息暴露或境外端点。',

src/compliance/project-scan.ts

466 Bytes
Binary file not shown.

src/compliance/report.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -141,8 +141,8 @@ export function renderProjectFindings(scan: ProjectScanResult, locale: 'zh' | 'e
141141
L.push(zh ? '## 🔍 项目实测风险' : '## 🔍 Project Scan Findings')
142142
L.push('')
143143
L.push(zh
144-
? `> 已扫描 ${scan.filesScanned} 个文件${scan.truncated ? '(已达上限,部分未扫)' : ''}`
145-
: `> Scanned ${scan.filesScanned} files${scan.truncated ? ' (limit reached, partial)' : ''}`)
144+
? `> 已扫描 ${scan.filesScanned} 个文件${scan.truncated ? '(已达上限)' : ''} · 耗时 ${scan.durationMs ?? '?'}ms · 应用 ${scan.rulesChecked ?? '?'} 条检测规则`
145+
: `> Scanned ${scan.filesScanned} files${scan.truncated ? ' (limit reached)' : ''} · ${scan.durationMs ?? '?'}ms · ${scan.rulesChecked ?? '?'} detection rules`)
146146
L.push('')
147147

148148
if (scan.findings.length === 0) {

0 commit comments

Comments
 (0)