@pwddd/skills-scanner 3.0.12 → 3.0.14

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/index.ts CHANGED
@@ -148,6 +148,8 @@ export default function register(api: OpenClawPluginApi) {
148
148
  return;
149
149
  }
150
150
 
151
+ api.logger.info("[skills-scanner] Python dependencies ready (requests installed)");
152
+
151
153
  if (preInstallScan === "on" && scanDirs.length > 0) {
152
154
  api.logger.info(`[skills-scanner] 📁 Starting file monitoring: ${scanDirs.length} directories`);
153
155
  stopWatcher = startWatcher(
@@ -168,14 +170,8 @@ export default function register(api: OpenClawPluginApi) {
168
170
  api.logger.info("[skills-scanner] ⏭️ Pre-install scan disabled");
169
171
  }
170
172
 
171
- // Register cron job (only in Gateway mode)
172
- const isGatewayMode = !!(api as any).runtime;
173
- if (isGatewayMode) {
174
- const runtime = (api as any).runtime;
175
- await ensureCronJob(api.logger, runtime);
176
- }
177
-
178
- api.logger.info("[skills-scanner] ─────────────────────────────────────");
173
+ // Setup cron job via CLI
174
+ await ensureCronJob(api.logger);
179
175
  },
180
176
  stop: () => {
181
177
  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.12",
5
+ "version": "3.0.14",
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.12",
3
+ "version": "3.0.14",
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/cron.ts CHANGED
@@ -57,70 +57,27 @@ function getOpenClawCommand(): string {
57
57
  }
58
58
 
59
59
  /**
60
- * Create cron job via Gateway API (most reliable)
60
+ * Create cron job via CLI
61
61
  */
62
- async function ensureCronJobViaAPI(runtime: any, logger: any): Promise<boolean> {
63
- if (!runtime?.cron) {
64
- logger.debug("[skills-scanner] Cron API not available");
65
- return false;
66
- }
62
+ async function ensureCronJobViaCLI(logger: any): Promise<void> {
63
+ const openclawCmd = getOpenClawCommand();
64
+ logger.info(`[skills-scanner] Using CLI command: ${openclawCmd}`);
67
65
 
66
+ // Test if command is available
68
67
  try {
69
- const state = loadState() as any;
70
-
71
- // Check if job already exists
72
- const jobs = await runtime.cron.list({ includeDisabled: true });
73
- const existing = jobs.find((j: any) => j.name === CRON_JOB_NAME);
74
-
75
- if (existing) {
76
- logger.info(`[skills-scanner] ✅ Job already exists: ${existing.id}`);
77
- if (state.cronJobId !== existing.id) {
78
- saveState({ ...state, cronJobId: existing.id });
79
- }
80
- return true;
81
- }
82
-
83
- // Create new job
84
- logger.info("[skills-scanner] 📝 Creating cron job via API...");
85
- const job = await runtime.cron.add({
86
- name: CRON_JOB_NAME,
87
- enabled: true,
88
- schedule: {
89
- kind: "cron",
90
- expr: CRON_SCHEDULE,
91
- tz: CRON_TIMEZONE
92
- },
93
- payload: {
94
- kind: "agentTurn",
95
- message: "Please run /skills-scanner scan --report and send results to this channel"
96
- },
97
- delivery: {
98
- mode: "announce",
99
- channel: "last"
100
- }
68
+ const testResult = execSync(`${openclawCmd} --version`, {
69
+ encoding: "utf-8",
70
+ timeout: 5000,
71
+ stdio: "pipe"
101
72
  });
102
-
103
- saveState({ ...state, cronJobId: job.id });
104
- logger.info(`[skills-scanner] Job created successfully via API: ${job.id}`);
105
- logger.info(
106
- `[skills-scanner] 📅 Schedule: Daily at ${CRON_SCHEDULE.split(" ")[1]}:${CRON_SCHEDULE.split(" ")[0]} (${CRON_TIMEZONE})`
107
- );
108
- logger.info("[skills-scanner] 📬 Reports will be delivered to the last active channel");
109
- return true;
110
- } catch (err: any) {
111
- logger.warn(`[skills-scanner] API creation failed: ${err.message}`);
112
- return false;
73
+ logger.info(`[skills-scanner] Command test successful: ${testResult.trim()}`);
74
+ } catch (testErr: any) {
75
+ logger.error(`[skills-scanner] Command not available: ${testErr.message}`);
76
+ logger.info(`[skills-scanner] 💡 Please ensure OpenClaw is installed and accessible`);
77
+ logger.info(`[skills-scanner] 💡 Try running: ${openclawCmd} --version`);
78
+ return;
113
79
  }
114
- }
115
-
116
- /**
117
- * Create cron job via CLI (fallback)
118
- */
119
- async function ensureCronJobViaCLI(logger: any): Promise<void> {
120
- const openclawCmd = getOpenClawCommand();
121
- logger.info(`[skills-scanner] Using CLI command: ${openclawCmd}`);
122
80
 
123
- const state = loadState() as any;
124
81
  const state = loadState() as any;
125
82
 
126
83
  try {
@@ -229,6 +186,8 @@ async function ensureCronJobViaCLI(logger: any): Promise<void> {
229
186
  "--channel last",
230
187
  ].join(" ");
231
188
 
189
+ logger.info(`[skills-scanner] Executing: ${cronCmd}`);
190
+
232
191
  const result = execSync(cronCmd, { encoding: "utf-8", timeout: 10000 });
233
192
 
234
193
  const jobIdMatch =
@@ -251,7 +210,15 @@ async function ensureCronJobViaCLI(logger: any): Promise<void> {
251
210
  }
252
211
  } catch (err: any) {
253
212
  logger.warn("[skills-scanner] ⚠️ Auto-registration failed");
254
- logger.debug(`[skills-scanner] Error details: ${err.message}`);
213
+ logger.warn(`[skills-scanner] Error: ${err.message || err}`);
214
+
215
+ // Log stderr if available
216
+ if (err.stderr) {
217
+ logger.warn(`[skills-scanner] stderr: ${err.stderr}`);
218
+ }
219
+ if (err.stdout) {
220
+ logger.warn(`[skills-scanner] stdout: ${err.stdout}`);
221
+ }
255
222
 
256
223
  if (err.message.includes("permission") || err.message.includes("EACCES")) {
257
224
  logger.error("[skills-scanner] ❌ Permission denied, please run with admin privileges");
@@ -260,6 +227,7 @@ async function ensureCronJobViaCLI(logger: any): Promise<void> {
260
227
  err.message.includes("ENOENT")
261
228
  ) {
262
229
  logger.error(`[skills-scanner] ❌ ${openclawCmd} command not found, please check installation`);
230
+ logger.info(`[skills-scanner] 💡 Current PATH: ${process.env.PATH}`);
263
231
  } else {
264
232
  logger.info("[skills-scanner] 💡 Please manually register cron job:");
265
233
  logger.info("[skills-scanner]");
@@ -282,22 +250,11 @@ async function ensureCronJobViaCLI(logger: any): Promise<void> {
282
250
  }
283
251
 
284
252
  /**
285
- * Ensure cron job exists (tries API first, falls back to CLI)
253
+ * Ensure cron job exists via CLI
286
254
  */
287
- export async function ensureCronJob(logger: any, runtime?: any): Promise<void> {
255
+ export async function ensureCronJob(logger: any): Promise<void> {
288
256
  logger.info("[skills-scanner] ─────────────────────────────────────");
289
257
  logger.info("[skills-scanner] 🕐 Checking cron job...");
290
258
 
291
- // Try API first (most reliable)
292
- if (runtime) {
293
- const success = await ensureCronJobViaAPI(runtime, logger);
294
- if (success) {
295
- logger.info("[skills-scanner] ✅ Cron job configured via API");
296
- return;
297
- }
298
- logger.info("[skills-scanner] Falling back to CLI method...");
299
- }
300
-
301
- // Fallback to CLI
302
259
  await ensureCronJobViaCLI(logger);
303
260
  }