@pwddd/skills-scanner 3.0.6 → 3.0.8

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.md CHANGED
@@ -116,29 +116,22 @@ openclaw skills-scanner health
116
116
 
117
117
  ## 前置要求
118
118
 
119
- ### 1. Python 3.10+(必需)
119
+ ### Python 3.10+(必需)
120
120
 
121
121
  ```bash
122
122
  # 检查 Python 版本
123
123
  python3 --version
124
- ```
125
-
126
- ### 2. 包管理器(二选一)
127
124
 
128
- **选项 A:uv(推荐,更快)**
125
+ # macOS
126
+ brew install python3
129
127
 
130
- ```bash
131
- # macOS/Linux
132
- curl -LsSf https://astral.sh/uv/install.sh | sh
128
+ # Linux
129
+ apt-get install python3 python3-pip
133
130
 
134
- # 或使用 Homebrew
135
- brew install uv
131
+ # Windows
132
+ # https://www.python.org/downloads/ 下载安装
136
133
  ```
137
134
 
138
- **选项 B:标准 pip(无需额外安装)**
139
-
140
- 如果没有 uv,插件会自动使用 Python 自带的 `pip`。
141
-
142
135
  ### 2. 启动扫描 API 服务
143
136
 
144
137
  插件需要连接到 skill-scanner-api 服务进行实际的安全扫描。
@@ -165,14 +158,7 @@ skill-scanner-api
165
158
  ```bash
166
159
  # 手动安装依赖
167
160
  cd extensions/skills-scanner/skills/skills-scanner
168
-
169
- # 使用 uv(推荐)
170
- uv venv .venv --python 3.10
171
- uv pip install --python .venv/bin/python requests>=2.31.0
172
-
173
- # 或使用标准 Python
174
- python3 -m venv .venv
175
- .venv/bin/python -m pip install requests>=2.31.0
161
+ python3 -m pip install --user "requests>=2.31.0"
176
162
  ```
177
163
 
178
164
  ### API 服务连接失败
@@ -216,8 +202,7 @@ extensions/skills-scanner/
216
202
  │ └── types.ts # 类型定义
217
203
  └── skills/
218
204
  └── skills-scanner/
219
- ├── scan.py # Python 扫描脚本
220
- └── .venv/ # Python 虚拟环境(自动创建)
205
+ └── scan.py # Python 扫描脚本
221
206
  ```
222
207
 
223
208
  ## 许可证
@@ -403,17 +388,13 @@ openclaw skills-scanner clawhub https://clawhub.ai/username/project --json resul
403
388
  ## 依赖要求
404
389
 
405
390
  - Python 3.10+
406
- - uv(Python 包管理器)
407
391
  - skill-scanner-api 服务(需要单独运行)
408
392
 
409
393
  ### 安装依赖
410
394
 
411
395
  ```bash
412
- # macOS
413
- brew install uv
414
-
415
- # Linux
416
- curl -LsSf https://astral.sh/uv/install.sh | sh
396
+ # 确保 Python 已安装
397
+ python3 --version
417
398
 
418
399
  # 启动 API 服务
419
400
  skill-scanner-api
@@ -426,8 +407,7 @@ skill-scanner-api
426
407
  ```bash
427
408
  # 手动安装依赖
428
409
  cd extensions/skills-scanner/skills/skills-scanner
429
- uv venv .venv --python 3.10
430
- uv pip install --python .venv/bin/python requests
410
+ python3 -m pip install --user "requests>=2.31.0"
431
411
  ```
432
412
 
433
413
  ### API 服务连接失败
package/index.ts CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  isFirstRun,
19
19
  markConfigReviewed,
20
20
  } from "./src/state.js";
21
- import { ensureDeps, isVenvReady } from "./src/deps.js";
21
+ import { ensureDeps, getPythonCommand, isPythonReady } from "./src/deps.js";
22
22
  import { runScan } from "./src/scanner.js";
23
23
  import { buildDailyReport } from "./src/report.js";
24
24
  import { ensureCronJob } from "./src/cron.js";
@@ -31,11 +31,12 @@ import { HIGH_RISK_OPERATION_GUARD } from "./src/high-risk-operation-guard.js";
31
31
  // Constants
32
32
  const PLUGIN_ROOT = process.env.OPENCLAW_PLUGIN_ROOT || __dirname;
33
33
  const SKILL_DIR = join(PLUGIN_ROOT, "skills", "skills-scanner");
34
- const VENV_PYTHON = join(SKILL_DIR, ".venv", "bin", "python");
35
34
  const SCAN_SCRIPT = join(SKILL_DIR, "scan.py");
36
35
  const STATE_DIR = join(os.homedir(), ".openclaw", "skills-scanner");
37
36
  const QUARANTINE_DIR = join(STATE_DIR, "quarantine");
38
37
 
38
+ const PYTHON_CMD = getPythonCommand();
39
+
39
40
  export default function register(api: OpenClawPluginApi) {
40
41
  const cfg: ScannerConfig =
41
42
  api.config?.plugins?.entries?.["skills-scanner"]?.config ?? {};
@@ -58,7 +59,7 @@ export default function register(api: OpenClawPluginApi) {
58
59
  api.logger.info(`[skills-scanner] API URL: ${apiUrl}`);
59
60
  api.logger.info(`[skills-scanner] Scan directories: ${scanDirs.join(", ")}`);
60
61
  api.logger.info(
61
- `[skills-scanner] Python dependencies: ${isVenvReady(VENV_PYTHON) ? "✅ Ready" : "❌ Not installed"}`
62
+ `[skills-scanner] Python dependencies: ${isPythonReady(PYTHON_CMD) ? "✅ Ready" : "❌ Not installed"}`
62
63
  );
63
64
 
64
65
  // Inject system prompt guidance (can be disabled via config)
@@ -110,9 +111,9 @@ export default function register(api: OpenClawPluginApi) {
110
111
  }
111
112
 
112
113
  // Install dependencies immediately
113
- if (!isVenvReady(VENV_PYTHON)) {
114
+ if (!isPythonReady(PYTHON_CMD)) {
114
115
  api.logger.info("[skills-scanner] Installing Python dependencies...");
115
- ensureDeps(SKILL_DIR, VENV_PYTHON, api.logger)
116
+ ensureDeps(PYTHON_CMD, api.logger)
116
117
  .then((success) => {
117
118
  if (success) {
118
119
  api.logger.info("[skills-scanner] ✅ Dependencies installed");
@@ -140,7 +141,7 @@ export default function register(api: OpenClawPluginApi) {
140
141
  start: async () => {
141
142
  api.logger.info("[skills-scanner] 🚀 Service starting...");
142
143
 
143
- const depsReady = await ensureDeps(SKILL_DIR, VENV_PYTHON, api.logger);
144
+ const depsReady = await ensureDeps(PYTHON_CMD, api.logger);
144
145
 
145
146
  if (!depsReady) {
146
147
  api.logger.error("[skills-scanner] ❌ Dependencies installation failed");
@@ -158,7 +159,7 @@ export default function register(api: OpenClawPluginApi) {
158
159
  policy,
159
160
  persistWatcherAlert,
160
161
  api.logger,
161
- VENV_PYTHON,
162
+ PYTHON_CMD,
162
163
  SCAN_SCRIPT,
163
164
  QUARANTINE_DIR
164
165
  );
@@ -192,7 +193,7 @@ export default function register(api: OpenClawPluginApi) {
192
193
  policy,
193
194
  preInstallScan,
194
195
  onUnsafe,
195
- VENV_PYTHON,
196
+ PYTHON_CMD,
196
197
  SCAN_SCRIPT,
197
198
  api.logger
198
199
  );
@@ -261,9 +262,9 @@ export default function register(api: OpenClawPluginApi) {
261
262
  api.registerGatewayMethod("skillsScanner.scan", async ({ respond, params }: any) => {
262
263
  const { path: p, mode = "scan", recursive = false, detailed = false } = params ?? {};
263
264
  if (!p) return respond(false, { error: "Missing path parameter" });
264
- if (!isVenvReady(VENV_PYTHON))
265
+ if (!isPythonReady(PYTHON_CMD))
265
266
  return respond(false, { error: "Python dependencies not ready" });
266
- const res = await runScan(VENV_PYTHON, SCAN_SCRIPT, mode === "batch" ? "batch" : "scan", expandPath(p), {
267
+ const res = await runScan(PYTHON_CMD, SCAN_SCRIPT, mode === "batch" ? "batch" : "scan", expandPath(p), {
267
268
  recursive,
268
269
  detailed,
269
270
  behavioral,
@@ -279,7 +280,7 @@ export default function register(api: OpenClawPluginApi) {
279
280
  });
280
281
 
281
282
  api.registerGatewayMethod("skillsScanner.report", async ({ respond }: any) => {
282
- if (!isVenvReady(VENV_PYTHON))
283
+ if (!isPythonReady(PYTHON_CMD))
283
284
  return respond(false, { error: "Python dependencies not ready" });
284
285
  if (scanDirs.length === 0) return respond(false, { error: "No scan directories found" });
285
286
  const report = await buildDailyReport(
@@ -289,7 +290,7 @@ export default function register(api: OpenClawPluginApi) {
289
290
  useLLM,
290
291
  policy,
291
292
  api.logger,
292
- VENV_PYTHON,
293
+ PYTHON_CMD,
293
294
  SCAN_SCRIPT
294
295
  );
295
296
  respond(true, { report, state: loadState() });
@@ -306,7 +307,7 @@ export default function register(api: OpenClawPluginApi) {
306
307
  .option("--detailed", "显示所有发现")
307
308
  .option("--behavioral", "启用行为分析")
308
309
  .action(async (p: string, opts: any) => {
309
- const res = await runScan(VENV_PYTHON, SCAN_SCRIPT, "scan", expandPath(p), {
310
+ const res = await runScan(PYTHON_CMD, SCAN_SCRIPT, "scan", expandPath(p), {
310
311
  ...opts,
311
312
  apiUrl,
312
313
  useLLM,
@@ -323,7 +324,7 @@ export default function register(api: OpenClawPluginApi) {
323
324
  .option("--detailed", "显示所有发现")
324
325
  .option("--behavioral", "启用行为分析")
325
326
  .action(async (d: string, opts: any) => {
326
- const res = await runScan(VENV_PYTHON, SCAN_SCRIPT, "batch", expandPath(d), {
327
+ const res = await runScan(PYTHON_CMD, SCAN_SCRIPT, "batch", expandPath(d), {
327
328
  ...opts,
328
329
  apiUrl,
329
330
  useLLM,
@@ -344,7 +345,7 @@ export default function register(api: OpenClawPluginApi) {
344
345
  useLLM,
345
346
  policy,
346
347
  console,
347
- VENV_PYTHON,
348
+ PYTHON_CMD,
348
349
  SCAN_SCRIPT
349
350
  );
350
351
  console.log(report);
@@ -354,7 +355,7 @@ export default function register(api: OpenClawPluginApi) {
354
355
  .command("health")
355
356
  .description("检查 API 服务健康状态")
356
357
  .action(async () => {
357
- if (!isVenvReady(VENV_PYTHON)) {
358
+ if (!isPythonReady(PYTHON_CMD)) {
358
359
  console.error("❌ Python 依赖未就绪");
359
360
  process.exit(1);
360
361
  }
@@ -364,7 +365,7 @@ export default function register(api: OpenClawPluginApi) {
364
365
  const { promisify } = await import("node:util");
365
366
  const execAsync = promisify(exec);
366
367
 
367
- const cmd = `"${VENV_PYTHON}" "${SCAN_SCRIPT}" --api-url "${apiUrl}" health`;
368
+ const cmd = `"${PYTHON_CMD}" "${SCAN_SCRIPT}" --api-url "${apiUrl}" health`;
368
369
  const env = { ...process.env };
369
370
  delete env.http_proxy;
370
371
  delete env.https_proxy;
@@ -395,3 +396,6 @@ export default function register(api: OpenClawPluginApi) {
395
396
 
396
397
  api.logger.info("[skills-scanner] ✅ Plugin registered");
397
398
  }
399
+
400
+
401
+
@@ -2,7 +2,7 @@
2
2
  "id": "skills-scanner",
3
3
  "name": "Skills Scanner",
4
4
  "description": "Security scanner for OpenClaw Skills to detect potential threats",
5
- "version": "3.0.6",
5
+ "version": "3.0.8",
6
6
  "author": "pwddd",
7
7
  "skills": ["./skills"],
8
8
  "configSchema": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
- "name": "@pwddd/skills-scanner",
3
- "version": "3.0.6",
2
+ "name": "@pwddd/skills-scanner",
3
+ "version": "3.0.8",
4
4
  "description": "OpenClaw Skills security scanner plugin - detect malicious code, data exfiltration, and prompt injection",
5
5
  "type": "module",
6
6
  "main": "./index.ts",