@pwddd/skills-scanner 3.0.17 → 3.0.19

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
@@ -6,7 +6,7 @@ OpenClaw Skills 安全扫描插件,用于检测 Skills 中的潜在安全威
6
6
 
7
7
  - 🔍 **自动扫描**: 监听 Skills 目录,自动扫描新安装的 Skill
8
8
  - 🌐 **ClawHub 扫描**: 直接扫描 ClawHub 上的 Skill,无需手动下载
9
- - 📊 **定时日报**: 每天自动生成安全扫描报告
9
+ - 📊 **定时周报**: 每周一自动生成安全扫描报告
10
10
  - 🛡️ **多种策略**: 支持 strict/balanced/permissive 三种扫描策略
11
11
  - 🤖 **LLM 分析**: 可选的 LLM 语义分析
12
12
  - 🔒 **自动隔离**: 检测到不安全的 Skill 自动隔离或删除
@@ -168,7 +168,7 @@ skill-scanner-api
168
168
  2. **文件监控**: 监听配置的 Skills 目录
169
169
  3. **自动扫描**: 检测到新 Skill 时自动触发扫描
170
170
  4. **结果处理**: 根据配置隔离/删除/警告不安全的 Skill
171
- 5. **定时日报**: 每天 08:00 生成安全报告
171
+ 5. **定时周报**: 每周一 12:05 自动生成安全报告
172
172
 
173
173
  ## 故障排除
174
174
 
@@ -225,14 +225,16 @@ Windows 使用反斜杠 `\` 作为路径分隔符,但插件会自动处理。
225
225
 
226
226
  ### 定时任务未注册
227
227
 
228
+ 定时任务会在插件启动时自动注册。如果需要手动注册:
229
+
228
230
  ```bash
229
231
  # 手动注册定时任务
230
- /skills-scanner cron register
232
+ /skills-scanner cron setup
231
233
 
232
234
  # 或使用 CLI
233
235
  openclaw cron add \
234
- --name "skills-daily-report" \
235
- --cron "0 8 * * *" \
236
+ --name "skills-weekly-report" \
237
+ --cron "5 12 * * 1" \
236
238
  --tz "Asia/Shanghai" \
237
239
  --session isolated \
238
240
  --message "请执行 /skills-scanner scan --report 并把结果发送到此渠道" \
@@ -384,7 +386,7 @@ openclaw skills-scanner health
384
386
  3. **ClawHub 扫描**(聊天命令/CLI):直接扫描 ClawHub 上的 Skill
385
387
  4. **CLI 命令扫描**:通过命令行工具扫描
386
388
  5. **自动文件监控**:实时监控目录,自动扫描新 Skill
387
- 6. **定时任务扫描**:每天 08:00 自动生成日报
389
+ 6. **定时任务扫描**:每周一 12:05 自动生成周报
388
390
  7. **RPC 方法扫描**:供其他插件或程序调用
389
391
  8. **AI 主动扫描**:AI 在用户请求安装 Skills 时自动扫描(需启用 `injectSecurityGuidance`)
390
392
 
package/index.ts CHANGED
@@ -170,8 +170,9 @@ export default function register(api: OpenClawPluginApi) {
170
170
  api.logger.info("[skills-scanner] ⏭️ Pre-install scan disabled");
171
171
  }
172
172
 
173
- // Check if cron job needs setup
174
- checkCronJobStatus(api.logger);
173
+ // Auto-register cron job
174
+ api.logger.info("[skills-scanner] 🕐 Setting up weekly report cron job...");
175
+ await ensureCronJob(api.logger);
175
176
  },
176
177
  stop: () => {
177
178
  api.logger.info("[skills-scanner] 🛑 Service stopping...");
@@ -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.17",
5
+ "version": "3.0.19",
6
6
  "author": "pwddd",
7
7
  "skills": ["./skills"],
8
8
  "configSchema": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pwddd/skills-scanner",
3
- "version": "3.0.17",
3
+ "version": "3.0.19",
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",
package/src/commands.ts CHANGED
@@ -69,16 +69,7 @@ export function createCommandHandlers(
69
69
  const recursive = parts.includes("--recursive");
70
70
  const isReport = parts.includes("--report");
71
71
 
72
- if (!targetPath) {
73
- return { text: "⚠️ 请指定扫描路径" };
74
- }
75
-
76
- if (!existsSync(targetPath)) {
77
- return { text: `⚠️ 路径不存在: ${targetPath}` };
78
- }
79
-
80
- const isSingleSkill = existsSync(join(targetPath, "SKILL.md"));
81
-
72
+ // Report mode: use configured scanDirs
82
73
  if (isReport) {
83
74
  if (scanDirs.length === 0) {
84
75
  return { text: "⚠️ 未找到可扫描目录,请检查配置" };
@@ -94,7 +85,20 @@ export function createCommandHandlers(
94
85
  scanScript
95
86
  );
96
87
  return { text: report };
97
- } else if (isSingleSkill) {
88
+ }
89
+
90
+ // Regular scan mode: require path
91
+ if (!targetPath) {
92
+ return { text: "⚠️ 请指定扫描路径" };
93
+ }
94
+
95
+ if (!existsSync(targetPath)) {
96
+ return { text: `⚠️ 路径不存在: ${targetPath}` };
97
+ }
98
+
99
+ const isSingleSkill = existsSync(join(targetPath, "SKILL.md"));
100
+
101
+ if (isSingleSkill) {
98
102
  const res = await runScan(pythonCmd, scanScript, "scan", targetPath, {
99
103
  detailed,
100
104
  behavioral: useBehav,
package/src/cron.ts CHANGED
@@ -5,8 +5,8 @@
5
5
  import { execSync } from "node:child_process";
6
6
  import { loadState, saveState } from "./state.js";
7
7
 
8
- const CRON_JOB_NAME = "skills-daily-report";
9
- const CRON_SCHEDULE = "0 8 * * *";
8
+ const CRON_JOB_NAME = "skills-weekly-report";
9
+ const CRON_SCHEDULE = "5 12 * * 1"; // 每周一 12:05
10
10
  const CRON_TIMEZONE = "Asia/Shanghai";
11
11
 
12
12
  /**
@@ -181,7 +181,7 @@ async function ensureCronJobViaCLI(logger: any): Promise<void> {
181
181
  `--cron "${CRON_SCHEDULE}"`,
182
182
  `--tz "${CRON_TIMEZONE}"`,
183
183
  "--session isolated",
184
- '--message "Please run /skills-scanner scan --report and send results to this channel"',
184
+ '--message "/skills-scanner scan --report"',
185
185
  "--announce",
186
186
  "--channel last",
187
187
  ].join(" ");
@@ -200,7 +200,7 @@ async function ensureCronJobViaCLI(logger: any): Promise<void> {
200
200
  saveState({ ...state, cronJobId });
201
201
  logger.info(`[skills-scanner] ✅ Job created successfully: ${cronJobId}`);
202
202
  logger.info(
203
- `[skills-scanner] 📅 Schedule: Daily at ${CRON_SCHEDULE.split(" ")[1]}:${CRON_SCHEDULE.split(" ")[0]} (${CRON_TIMEZONE})`
203
+ `[skills-scanner] 📅 Schedule: Every Monday at 12:05 (${CRON_TIMEZONE})`
204
204
  );
205
205
  logger.info("[skills-scanner] 📬 Reports will be delivered to the last active channel");
206
206
  } else {
@@ -237,7 +237,7 @@ async function ensureCronJobViaCLI(logger: any): Promise<void> {
237
237
  logger.info(`[skills-scanner] --tz "${CRON_TIMEZONE}" \\`);
238
238
  logger.info("[skills-scanner] --session isolated \\");
239
239
  logger.info(
240
- '[skills-scanner] --message "Please run /skills-scanner scan --report and send results to this channel" \\'
240
+ '[skills-scanner] --message "/skills-scanner scan --report" \\'
241
241
  );
242
242
  logger.info("[skills-scanner] --announce \\");
243
243
  logger.info("[skills-scanner] --channel last");
@@ -259,11 +259,11 @@ export function checkCronJobStatus(logger: any): void {
259
259
 
260
260
  if (state.cronJobId) {
261
261
  logger.info(`[skills-scanner] ✅ Cron job registered: ${state.cronJobId}`);
262
- logger.info("[skills-scanner] 📅 Daily reports will be sent at 08:00 (Asia/Shanghai)");
262
+ logger.info("[skills-scanner] 📅 Weekly reports will be sent every Monday at 12:05 (Asia/Shanghai)");
263
263
  } else {
264
264
  logger.info("[skills-scanner] 💡 Cron job not configured yet");
265
265
  logger.info("[skills-scanner]");
266
- logger.info("[skills-scanner] To enable daily security reports, run:");
266
+ logger.info("[skills-scanner] To enable weekly security reports, run:");
267
267
  logger.info("[skills-scanner]");
268
268
  logger.info("[skills-scanner] npx openclaw cron add \\");
269
269
  logger.info(`[skills-scanner] --name "${CRON_JOB_NAME}" \\`);
@@ -271,7 +271,7 @@ export function checkCronJobStatus(logger: any): void {
271
271
  logger.info(`[skills-scanner] --tz "${CRON_TIMEZONE}" \\`);
272
272
  logger.info("[skills-scanner] --session isolated \\");
273
273
  logger.info(
274
- '[skills-scanner] --message "Please run /skills-scanner scan --report and send results to this channel" \\'
274
+ '[skills-scanner] --message "/skills-scanner scan --report" \\'
275
275
  );
276
276
  logger.info("[skills-scanner] --announce \\");
277
277
  logger.info("[skills-scanner] --channel last");