@pwddd/skills-scanner 1.0.0-beta.2 → 1.0.0-beta.21

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
@@ -4,10 +4,9 @@ OpenClaw Skills 安全扫描插件,用于检测 Skills 中的潜在安全威
4
4
 
5
5
  ## 功能特性
6
6
 
7
- - 🔍 **自动扫描**: 监听 Skills 目录,自动扫描新安装的 Skill
7
+ - 🔍 **手动扫描**: 支持扫描指定路径的 Skill
8
8
  - 🛡️ **安装前拦截**: 使用 before_install hook 在安装前强制拦截不安全的 Skills
9
9
  - 🌐 **ClawHub 扫描**: 直接扫描 ClawHub 上的 Skill,无需手动下载
10
- - 📊 **定时周报**: 每周一自动生成安全扫描报告
11
10
  - 🛡️ **多种策略**: 支持 strict/balanced/permissive 三种扫描策略
12
11
  - 🤖 **LLM 分析**: 可选的 LLM 语义分析
13
12
  - 🔒 **自动隔离**: 检测到不安全的 Skill 自动隔离或删除
@@ -34,11 +33,9 @@ openclaw plugins install @pwddd/skills-scanner
34
33
  "enabled": true,
35
34
  "config": {
36
35
  "apiUrl": "https://110.vemic.com/skills-scanner",
37
- "scanDirs": ["~/.openclaw/skills", "~/.openclaw/workspace/skills"],
38
36
  "behavioral": false,
39
37
  "useLLM": false,
40
38
  "policy": "balanced",
41
- "preInstallScan": "on",
42
39
  "onUnsafe": "warn",
43
40
  "enableBeforeInstallHook": true
44
41
  }
@@ -51,16 +48,12 @@ openclaw plugins install @pwddd/skills-scanner
51
48
  ### 配置说明
52
49
 
53
50
  - `apiUrl`: 扫描 API 服务地址
54
- - `scanDirs`: 要监控的 Skills 目录列表
55
51
  - `behavioral`: 是否启用行为分析(深度扫描,较慢)
56
52
  - `useLLM`: 是否使用 LLM 进行语义分析
57
53
  - `policy`: 扫描策略
58
54
  - `strict`: 严格模式,发现任何可疑行为都标记为不安全
59
55
  - `balanced`: 平衡模式(推荐)
60
56
  - `permissive`: 宽松模式,只标记明确的威胁
61
- - `preInstallScan`: 是否启用文件监控(安装后扫描)
62
- - `on`: 启用
63
- - `off`: 禁用
64
57
  - `onUnsafe`: 发现不安全 Skill 的处理方式
65
58
  - `warn`: 仅警告,不处理(推荐)
66
59
  - `quarantine`: 移入隔离目录
@@ -88,7 +81,6 @@ openclaw config reload
88
81
 
89
82
  配置变更会自动:
90
83
  - 更新 API URL
91
- - 重启文件监控器(如果扫描目录变更)
92
84
  - 应用新的扫描策略
93
85
 
94
86
  #### 调试模式
@@ -108,7 +100,6 @@ SKILLS_SCANNER_DEBUG=1 openclaw gateway start
108
100
  - 完整的配置信息
109
101
  - 详细的扫描过程
110
102
  - API 请求和响应
111
- - 文件监控事件
112
103
 
113
104
  #### 健康检查端点
114
105
 
@@ -130,11 +121,6 @@ curl http://localhost:3000/health/skills-scanner
130
121
  "url": "https://110.vemic.com/skills-scanner",
131
122
  "status": "available"
132
123
  },
133
- "watcher": {
134
- "enabled": true,
135
- "running": true,
136
- "directories": 2
137
- },
138
124
  "metrics": {
139
125
  "totalScans": 42,
140
126
  "successRate": "95.24%",
@@ -152,7 +138,6 @@ curl http://localhost:3000/health/skills-scanner
152
138
  /skills-scanner scan clawhub <URL> [选项] # 扫描 ClawHub Skill
153
139
  /skills-scanner health # 健康检查
154
140
  /skills-scanner config [操作] # 配置管理
155
- /skills-scanner cron [操作] # 定时任务管理
156
141
  /skills-scanner help # 帮助信息
157
142
  ```
158
143
 
@@ -161,14 +146,12 @@ curl http://localhost:3000/health/skills-scanner
161
146
  - `--detailed`: 显示详细的安全发现
162
147
  - `--behavioral`: 启用行为分析
163
148
  - `--recursive`: 递归扫描子目录
164
- - `--report`: 生成日报格式
165
149
 
166
150
  #### 示例
167
151
 
168
152
  ```
169
153
  /skills-scanner scan ~/.openclaw/skills/my-skill
170
154
  /skills-scanner scan ~/.openclaw/skills --recursive
171
- /skills-scanner scan ~/.openclaw/skills --report
172
155
  /skills-scanner scan clawhub https://clawhub.ai/username/project
173
156
  /skills-scanner scan clawhub https://clawhub.ai/Asleep123/caldav-calendar --detailed
174
157
  /skills-scanner health
@@ -186,9 +169,6 @@ openclaw skills-scanner clawhub <url> [--detailed] [--behavioral]
186
169
  # 批量扫描目录
187
170
  openclaw skills-scanner batch <directory> [--recursive] [--detailed]
188
171
 
189
- # 生成日报
190
- openclaw skills-scanner report
191
-
192
172
  # 检查 API 服务健康状态
193
173
  openclaw skills-scanner health
194
174
  ```
@@ -196,10 +176,8 @@ openclaw skills-scanner health
196
176
  ## 工作流程
197
177
 
198
178
  1. **插件启动**: 自动初始化并连接 API 服务
199
- 2. **文件监控**: 监听配置的 Skills 目录
200
- 3. **自动扫描**: 检测到新 Skill 时自动触发扫描
201
- 4. **结果处理**: 根据配置隔离/删除/警告不安全的 Skill
202
- 5. **定时周报**: 每周一 12:05 自动生成安全报告
179
+ 2. **手动扫描**: 使用命令扫描指定的 Skill 或目录
180
+ 3. **结果处理**: 根据配置隔离/删除/警告不安全的 Skill
203
181
 
204
182
  ## 故障排除
205
183
 
@@ -209,24 +187,6 @@ openclaw skills-scanner health
209
187
  2. 运行健康检查:`/skills-scanner health`
210
188
  3. 检查网络连接
211
189
 
212
- ### 定时任务未注册
213
-
214
- 定时任务会在插件启动时自动注册。如果需要手动注册:
215
-
216
- ```bash
217
- # 手动注册定时任务
218
- /skills-scanner cron setup
219
-
220
- # 或使用 CLI
221
- openclaw cron add \
222
- --name "skills-weekly-report" \
223
- --cron "5 12 * * 1" \
224
- --tz "Asia/Shanghai" \
225
- --session isolated \
226
- --message "请执行 /skills-scanner scan --report 并把结果发送到此渠道" \
227
- --announce
228
- ```
229
-
230
190
  ## 开发
231
191
 
232
192
  ### 目录结构
@@ -241,8 +201,6 @@ extensions/skills-scanner/
241
201
  │ ├── api-client.ts # HTTP API 客户端
242
202
  │ ├── config.ts # 配置管理
243
203
  │ ├── scanner.ts # 扫描逻辑
244
- │ ├── watcher.ts # 文件监控
245
- │ ├── cron.ts # 定时任务
246
204
  │ ├── commands.ts # 命令处理
247
205
  │ └── types.ts # 类型定义
248
206
  └── skills/
package/index.ts CHANGED
@@ -6,27 +6,20 @@
6
6
 
7
7
  import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
8
8
  import { join } from "node:path";
9
- import os from "node:os";
10
- import { existsSync } from "node:fs";
11
9
  import type { ScannerConfig } from "./src/types.js";
12
10
  import { skillsScannerConfigSchema, generateConfigGuide } from "./src/config.js";
13
11
  import {
14
12
  loadState,
15
13
  saveState,
16
14
  expandPath,
17
- defaultScanDirs,
18
15
  isFirstRun,
19
16
  markConfigReviewed,
20
17
  getStateDir,
21
18
  } from "./src/state.js";
22
19
  import { runScan } from "./src/scanner.js";
23
- import { buildDailyReport } from "./src/report.js";
24
- import { ensureCronJobViaGateway, checkCronJobStatus } from "./src/cron-manager.js";
25
- import { startWatcher } from "./src/watcher.js";
20
+ import { ensureCronJob } from "./src/cron-manager.js";
26
21
  import { createCommandHandlers } from "./src/commands.js";
27
22
  import { SKILLS_SECURITY_GUIDANCE } from "./src/prompt-guidance.js";
28
- import { PROMPT_INJECTION_GUARD } from "./src/prompt-injection-guard.js";
29
- import { HIGH_RISK_OPERATION_GUARD } from "./src/high-risk-operation-guard.js";
30
23
  import { handleBeforeInstall } from "./src/before-install-hook.js";
31
24
  import type { BeforeInstallEvent } from "./src/before-install-hook.js";
32
25
  import { validateConfig } from "./src/config-validator.js";
@@ -57,24 +50,16 @@ export default definePluginEntry({
57
50
  }
58
51
 
59
52
  const apiUrl = cfg.apiUrl ?? "https://110.vemic.com/skills-scanner";
60
- const scanDirs =
61
- (cfg.scanDirs?.map(expandPath) ?? []).filter(existsSync).length > 0
62
- ? cfg.scanDirs!.map(expandPath)
63
- : defaultScanDirs();
64
53
  const behavioral = cfg.behavioral ?? false;
65
54
  const useLLM = cfg.useLLM ?? false;
66
55
  const policy = cfg.policy ?? "balanced";
67
- const preInstallScan = cfg.preInstallScan ?? "on";
68
56
  const onUnsafe = cfg.onUnsafe ?? "warn";
69
57
  const injectSecurityGuidance = cfg.injectSecurityGuidance ?? true;
70
- const enablePromptInjectionGuard = cfg.enablePromptInjectionGuard ?? false;
71
- const enableHighRiskOperationGuard = cfg.enableHighRiskOperationGuard ?? false;
72
58
  const enableBeforeInstallHook = cfg.enableBeforeInstallHook ?? true;
73
59
 
74
60
  api.logger.info("[skills-scanner] ═══════════════════════════════════════");
75
61
  api.logger.info("[skills-scanner] Plugin loading...");
76
62
  api.logger.info(`[skills-scanner] API URL: ${apiUrl}`);
77
- api.logger.info(`[skills-scanner] Scan directories: ${scanDirs.join(", ")}`);
78
63
  api.logger.info(`[skills-scanner] Before-install hook: ${enableBeforeInstallHook ? "✅ ENABLED" : "❌ DISABLED"}`);
79
64
 
80
65
  if (isDebugMode()) {
@@ -84,30 +69,11 @@ export default definePluginEntry({
84
69
 
85
70
  // Inject system prompt guidance (can be disabled via config)
86
71
  if (injectSecurityGuidance) {
87
- // Build combined guidance
88
- const guidanceParts = [SKILLS_SECURITY_GUIDANCE];
89
-
90
- if (enablePromptInjectionGuard) {
91
- guidanceParts.push(PROMPT_INJECTION_GUARD);
92
- }
93
-
94
- if (enableHighRiskOperationGuard) {
95
- guidanceParts.push(HIGH_RISK_OPERATION_GUARD);
96
- }
97
-
98
- const combinedGuidance = guidanceParts.join("\n\n");
99
-
100
72
  api.on("before_prompt_build", async () => ({
101
- prependSystemContext: combinedGuidance,
73
+ prependSystemContext: SKILLS_SECURITY_GUIDANCE,
102
74
  }));
103
75
 
104
76
  api.logger.info("[skills-scanner] ✅ Security guidance injected into system prompt");
105
- if (enablePromptInjectionGuard) {
106
- api.logger.info("[skills-scanner] - Prompt injection guard enabled");
107
- }
108
- if (enableHighRiskOperationGuard) {
109
- api.logger.info("[skills-scanner] - High-risk operation guard enabled");
110
- }
111
77
  } else {
112
78
  api.logger.info("[skills-scanner] ⏭️ Security guidance injection disabled");
113
79
  }
@@ -129,7 +95,9 @@ export default definePluginEntry({
129
95
  api.logger.error("[skills-scanner] ❌ before_install hook error", {
130
96
  error: err.message,
131
97
  stack: err.stack,
132
- skillPath: event.skillPath,
98
+ sourcePath: event.sourcePath,
99
+ targetType: event.targetType,
100
+ targetName: event.targetName,
133
101
  });
134
102
  // Return safe default on error - allow installation but log the failure
135
103
  return { block: false };
@@ -141,80 +109,20 @@ export default definePluginEntry({
141
109
  api.logger.warn("[skills-scanner] ⚠️ before_install hook DISABLED - installations will NOT be intercepted!");
142
110
  }
143
111
 
144
- // Register gateway_start hook for automatic cron job registration
145
- api.on("gateway_start", async () => {
112
+ // 在插件启动时设置系统 crontab 清理任务
113
+ (async () => {
146
114
  try {
147
- api.logger.info("[skills-scanner] 🚀 Gateway started, checking cron job...");
148
- await ensureCronJobViaGateway({
115
+ await ensureCronJob({
149
116
  logger: api.logger,
150
- callGateway: async (method: string, params: any) => {
151
- return await api.callGateway(method, params);
152
- },
153
- });
154
- api.logger.info("[skills-scanner] ✅ Cron job check completed");
155
- } catch (err: any) {
156
- api.logger.error("[skills-scanner] ❌ Cron job registration failed", {
157
- error: err.message,
158
- stack: err.stack,
117
+ config: api.config,
159
118
  });
160
- // Don't throw - avoid blocking gateway startup
161
- }
162
- });
163
-
164
- // Register plugin_uninstall hook for cleanup
165
- api.on("plugin_uninstall", async () => {
166
- api.logger.info("[skills-scanner] 🗑️ Plugin uninstalling, cleaning up...");
167
-
168
- try {
169
- // 1. Stop file watcher
170
- if (stopWatcher) {
171
- api.logger.debug("[skills-scanner] Stopping file watcher...");
172
- stopWatcher();
173
- stopWatcher = null;
174
- api.logger.debug("[skills-scanner] ✅ File watcher stopped");
175
- }
176
-
177
- // 2. Remove cron jobs
178
- try {
179
- const listResult = await api.callGateway("cron.list", {});
180
- const jobs = listResult?.jobs || [];
181
- const ourJobs = jobs.filter((j: any) => j.name === "skills-weekly-report");
182
-
183
- for (const job of ourJobs) {
184
- const jobId = job.jobId || job.id;
185
- await api.callGateway("cron.remove", { jobId });
186
- api.logger.info("[skills-scanner] Removed cron job", { jobId });
187
- }
188
-
189
- if (ourJobs.length > 0) {
190
- api.logger.info(`[skills-scanner] ✅ Removed ${ourJobs.length} cron job(s)`);
191
- }
192
- } catch (err: any) {
193
- api.logger.warn("[skills-scanner] Failed to remove cron jobs", {
194
- error: err.message,
195
- });
196
- }
197
-
198
- // 3. Save final state
199
- try {
200
- const finalState = loadState(api.runtime);
201
- finalState.lastUninstallAt = new Date().toISOString();
202
- saveState(finalState, api.runtime);
203
- api.logger.debug("[skills-scanner] ✅ Final state saved");
204
- } catch (err: any) {
205
- api.logger.warn("[skills-scanner] Failed to save final state", {
206
- error: err.message,
207
- });
208
- }
209
-
210
- api.logger.info("[skills-scanner] ✅ Cleanup completed successfully");
119
+ api.logger.info("[skills-scanner] System crontab cleanup task ensured");
211
120
  } catch (err: any) {
212
- api.logger.error("[skills-scanner] Cleanup failed", {
121
+ api.logger.warn("[skills-scanner] ⚠️ Failed to setup system crontab", {
213
122
  error: err.message,
214
- stack: err.stack,
215
123
  });
216
124
  }
217
- });
125
+ })();
218
126
 
219
127
  // Register config_changed hook for hot reload
220
128
  api.on("config_changed", async (newConfig: any) => {
@@ -233,8 +141,6 @@ export default definePluginEntry({
233
141
 
234
142
  // Check what changed
235
143
  const apiUrlChanged = newCfg.apiUrl !== cfg.apiUrl;
236
- const scanDirsChanged = JSON.stringify(newCfg.scanDirs) !== JSON.stringify(cfg.scanDirs);
237
- const preInstallScanChanged = newCfg.preInstallScan !== cfg.preInstallScan;
238
144
 
239
145
  if (apiUrlChanged) {
240
146
  api.logger.info("[skills-scanner] API URL updated", {
@@ -245,42 +151,6 @@ export default definePluginEntry({
245
151
  Object.assign(cfg, { apiUrl: newCfg.apiUrl });
246
152
  }
247
153
 
248
- if (scanDirsChanged || preInstallScanChanged) {
249
- api.logger.info("[skills-scanner] Scan configuration updated, restarting watcher...");
250
-
251
- // Stop old watcher
252
- if (stopWatcher) {
253
- stopWatcher();
254
- stopWatcher = null;
255
- }
256
-
257
- // Start new watcher with updated config
258
- const newScanDirs =
259
- (newCfg.scanDirs?.map(expandPath) ?? []).filter(existsSync).length > 0
260
- ? newCfg.scanDirs!.map(expandPath)
261
- : defaultScanDirs();
262
-
263
- if (newCfg.preInstallScan === "on" && newScanDirs.length > 0) {
264
- stopWatcher = startWatcher(
265
- newScanDirs,
266
- newCfg.onUnsafe ?? "warn",
267
- newCfg.behavioral ?? false,
268
- newCfg.apiUrl ?? apiUrl,
269
- newCfg.useLLM ?? false,
270
- newCfg.policy ?? "balanced",
271
- persistWatcherAlert,
272
- api.logger,
273
- QUARANTINE_DIR
274
- );
275
- api.logger.info("[skills-scanner] ✅ Watcher restarted with new configuration");
276
- } else {
277
- api.logger.info("[skills-scanner] ⏭️ Watcher disabled by new configuration");
278
- }
279
-
280
- // Update global config
281
- Object.assign(cfg, newCfg);
282
- }
283
-
284
154
  api.logger.info("[skills-scanner] ✅ Configuration reload completed");
285
155
  } catch (err: any) {
286
156
  api.logger.error("[skills-scanner] ❌ Configuration reload failed", {
@@ -297,93 +167,15 @@ export default definePluginEntry({
297
167
  const configGuide = generateConfigGuide(
298
168
  cfg,
299
169
  apiUrl,
300
- scanDirs,
301
170
  behavioral,
302
171
  useLLM,
303
172
  policy,
304
- preInstallScan,
305
173
  onUnsafe
306
174
  );
307
175
  console.log(configGuide);
308
176
  markConfigReviewed(api.runtime);
309
177
  }
310
178
 
311
- // Helper for watcher alerts
312
- function persistWatcherAlert(msg: string): void {
313
- const state = loadState(api.runtime);
314
- const alerts: string[] = (state as any).pendingAlerts ?? [];
315
- alerts.push(`[${new Date().toLocaleString("en-US")}] ${msg}`);
316
- saveState({ ...state, pendingAlerts: alerts } as any, api.runtime);
317
- api.logger.warn(`[skills-scanner] ${msg}`);
318
- }
319
-
320
- // Service: start watcher
321
- let stopWatcher: (() => void) | null = null;
322
-
323
- api.registerService({
324
- id: "skills-scanner-setup",
325
- start: async () => {
326
- api.logger.info("[skills-scanner] 🚀 Service starting...");
327
-
328
- if (preInstallScan === "on" && scanDirs.length > 0) {
329
- api.logger.info(`[skills-scanner] 📁 Starting file monitoring: ${scanDirs.length} directories`);
330
- stopWatcher = startWatcher(
331
- scanDirs,
332
- onUnsafe,
333
- behavioral,
334
- apiUrl,
335
- useLLM,
336
- policy,
337
- persistWatcherAlert,
338
- api.logger,
339
- QUARANTINE_DIR
340
- );
341
- api.logger.info("[skills-scanner] ✅ File monitoring started");
342
- } else {
343
- api.logger.info("[skills-scanner] ⏭️ Pre-install scan disabled");
344
- }
345
- },
346
- stop: async () => {
347
- api.logger.info("[skills-scanner] 🛑 Service stopping...");
348
-
349
- try {
350
- // 1. Stop file watcher
351
- if (stopWatcher) {
352
- api.logger.debug("[skills-scanner] Stopping file watcher...");
353
- stopWatcher();
354
- stopWatcher = null;
355
- api.logger.debug("[skills-scanner] ✅ File watcher stopped");
356
- }
357
-
358
- // 2. Save final state
359
- try {
360
- const finalState = loadState(api.runtime);
361
- finalState.lastShutdownAt = new Date().toISOString();
362
- saveState(finalState, api.runtime);
363
- api.logger.debug("[skills-scanner] ✅ Final state saved");
364
- } catch (err: any) {
365
- api.logger.warn("[skills-scanner] Failed to save final state", {
366
- error: err.message,
367
- });
368
- }
369
-
370
- // 3. Clear pending alerts (optional - keep for next run)
371
- // This is intentionally commented out to preserve alerts
372
- // const state = loadState(api.runtime);
373
- // if ((state as any).pendingAlerts?.length > 0) {
374
- // saveState({ ...state, pendingAlerts: [] } as any, api.runtime);
375
- // }
376
-
377
- api.logger.info("[skills-scanner] ✅ Service stopped cleanly");
378
- } catch (err: any) {
379
- api.logger.error("[skills-scanner] ❌ Error during shutdown", {
380
- error: err.message,
381
- stack: err.stack,
382
- });
383
- }
384
- },
385
- });
386
-
387
179
  // Health check endpoint
388
180
  api.registerHttpRoute({
389
181
  method: "GET",
@@ -417,11 +209,6 @@ export default definePluginEntry({
417
209
  url: apiUrl,
418
210
  status: apiStatus,
419
211
  },
420
- watcher: {
421
- enabled: preInstallScan === "on",
422
- running: stopWatcher !== null,
423
- directories: scanDirs.length,
424
- },
425
212
  state: {
426
213
  lastScanAt: state.lastScanAt || null,
427
214
  lastShutdownAt: state.lastShutdownAt || null,
@@ -461,16 +248,12 @@ export default definePluginEntry({
461
248
  const handlers = createCommandHandlers(
462
249
  cfg,
463
250
  apiUrl,
464
- scanDirs,
465
251
  behavioral,
466
252
  useLLM,
467
253
  policy,
468
- preInstallScan,
469
254
  onUnsafe,
470
255
  api.logger,
471
- async (method: string, params: any) => {
472
- return await api.callGateway(method, params);
473
- }
256
+ api.config
474
257
  );
475
258
 
476
259
  // Chat command: /skills-scanner
@@ -492,13 +275,11 @@ export default definePluginEntry({
492
275
  "• `/skills-scanner scan clawhub <URL> [选项]` - 扫描 ClawHub Skill",
493
276
  "• `/skills-scanner health` - 健康检查",
494
277
  "• `/skills-scanner config [操作]` - 配置管理",
495
- "• `/skills-scanner cron [操作]` - 定时任务管理",
496
278
  "",
497
279
  "扫描选项:",
498
280
  "• `--detailed` - 显示详细发现",
499
281
  "• `--behavioral` - 启用行为分析",
500
282
  "• `--recursive` - 递归扫描子目录",
501
- "• `--report` - 生成日报格式",
502
283
  "",
503
284
  "示例:",
504
285
  "```",
@@ -523,8 +304,6 @@ export default definePluginEntry({
523
304
  return await handlers.handleHealthCommand();
524
305
  } else if (subCommand === "config") {
525
306
  return await handlers.handleConfigCommand(subArgs);
526
- } else if (subCommand === "cron") {
527
- return await handlers.handleCronCommand(subArgs);
528
307
  } else if (subCommand === "help" || subCommand === "--help" || subCommand === "-h") {
529
308
  return { text: handlers.getHelpText() };
530
309
  } else {
@@ -560,23 +339,6 @@ export default definePluginEntry({
560
339
  }
561
340
  });
562
341
 
563
- api.registerGatewayMethod("skillsScanner.report", async ({ respond }: any) => {
564
- if (scanDirs.length === 0) return respond(false, { error: "No scan directories found" });
565
- try {
566
- const report = await buildDailyReport(
567
- scanDirs,
568
- behavioral,
569
- apiUrl,
570
- useLLM,
571
- policy,
572
- api.logger
573
- );
574
- respond(true, { report, state: loadState() });
575
- } catch (err: any) {
576
- respond(false, { error: err.message });
577
- }
578
- });
579
-
580
342
  // CLI commands
581
343
  api.registerCli(
582
344
  ({ program }: any) => {
@@ -615,21 +377,6 @@ export default definePluginEntry({
615
377
  process.exit(res.exitCode);
616
378
  });
617
379
 
618
- cmd
619
- .command("report")
620
- .description("生成日报")
621
- .action(async () => {
622
- const report = await buildDailyReport(
623
- scanDirs,
624
- behavioral,
625
- apiUrl,
626
- useLLM,
627
- policy,
628
- console
629
- );
630
- console.log(report);
631
- });
632
-
633
380
  cmd
634
381
  .command("health")
635
382
  .description("检查 API 服务健康状态")
@@ -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": "1.0.0-beta.2",
5
+ "version": "1.0.0-beta.21",
6
6
  "author": "pwddd",
7
7
  "skills": ["./skills"],
8
8
  "uiHints": {
@@ -27,10 +27,6 @@
27
27
  "label": "扫描策略",
28
28
  "help": "strict=严格 / balanced=平衡(推荐)/ permissive=宽松"
29
29
  },
30
- "preInstallScan": {
31
- "label": "安装前扫描",
32
- "help": "监听新 Skill 并自动扫描"
33
- },
34
30
  "onUnsafe": {
35
31
  "label": "不安全处理",
36
32
  "help": "warn=仅警告(推荐)/ quarantine=隔离 / delete=删除"
@@ -85,12 +81,6 @@
85
81
  "description": "Scanning policy: strict (more false positives) / balanced (recommended) / permissive (may miss threats)",
86
82
  "default": "balanced"
87
83
  },
88
- "preInstallScan": {
89
- "type": "string",
90
- "enum": ["on", "off"],
91
- "description": "Enable pre-installation scanning (monitors directories for new Skills)",
92
- "default": "on"
93
- },
94
84
  "onUnsafe": {
95
85
  "type": "string",
96
86
  "enum": ["quarantine", "delete", "warn"],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pwddd/skills-scanner",
3
- "version": "1.0.0-beta.2",
3
+ "version": "1.0.0-beta.21",
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",