shieldcortex 2.4.22 → 2.4.24

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.
Files changed (102) hide show
  1. package/dashboard/.next/standalone/dashboard/.next/BUILD_ID +1 -1
  2. package/dashboard/.next/standalone/dashboard/.next/build-manifest.json +2 -2
  3. package/dashboard/.next/standalone/dashboard/.next/prerender-manifest.json +3 -3
  4. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.html +2 -2
  5. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
  6. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  7. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  8. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  9. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  10. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  11. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  12. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +1 -1
  13. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +10 -10
  14. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +10 -10
  15. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +3 -3
  16. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +6 -6
  17. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +2 -2
  18. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +3 -3
  19. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  20. package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
  21. package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +5 -5
  22. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  23. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +5 -5
  24. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
  25. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +4 -4
  26. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  27. package/dashboard/.next/standalone/dashboard/.next/server/app/page/react-loadable-manifest.json +3 -3
  28. package/dashboard/.next/standalone/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
  29. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_25b1b286._.js +1 -1
  30. package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +1 -1
  31. package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
  32. package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.js +1 -1
  33. package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.json +1 -1
  34. package/dashboard/.next/standalone/dashboard/.next/static/chunks/0ba8a0e679bf5c40.js +842 -0
  35. package/dashboard/.next/standalone/dashboard/.next/static/chunks/17348ec48b354115.css +3 -0
  36. package/dashboard/.next/standalone/dashboard/.next/static/chunks/caa049bd46f24dd8.js +1 -0
  37. package/dashboard/.next/standalone/dashboard/.next/static/chunks/cb7d5bff58e77e2c.js +9 -0
  38. package/dashboard/.next/standalone/dashboard/.next/static/chunks/e007ff86847a4042.js +1 -0
  39. package/dist/api/visualization-server.d.ts.map +1 -1
  40. package/dist/api/visualization-server.js +154 -2
  41. package/dist/api/visualization-server.js.map +1 -1
  42. package/dist/cloud/sync.d.ts.map +1 -1
  43. package/dist/cloud/sync.js +7 -3
  44. package/dist/cloud/sync.js.map +1 -1
  45. package/dist/defence/index.d.ts +2 -0
  46. package/dist/defence/index.d.ts.map +1 -1
  47. package/dist/defence/index.js +2 -0
  48. package/dist/defence/index.js.map +1 -1
  49. package/dist/defence/skill-scanner/__tests__/skill-scanner.test.d.ts +12 -0
  50. package/dist/defence/skill-scanner/__tests__/skill-scanner.test.d.ts.map +1 -0
  51. package/dist/defence/skill-scanner/__tests__/skill-scanner.test.js +471 -0
  52. package/dist/defence/skill-scanner/__tests__/skill-scanner.test.js.map +1 -0
  53. package/dist/defence/skill-scanner/discover.d.ts +16 -0
  54. package/dist/defence/skill-scanner/discover.d.ts.map +1 -0
  55. package/dist/defence/skill-scanner/discover.js +85 -0
  56. package/dist/defence/skill-scanner/discover.js.map +1 -0
  57. package/dist/defence/skill-scanner/index.d.ts +20 -0
  58. package/dist/defence/skill-scanner/index.d.ts.map +1 -0
  59. package/dist/defence/skill-scanner/index.js +17 -0
  60. package/dist/defence/skill-scanner/index.js.map +1 -0
  61. package/dist/defence/skill-scanner/parser.d.ts +45 -0
  62. package/dist/defence/skill-scanner/parser.d.ts.map +1 -0
  63. package/dist/defence/skill-scanner/parser.js +373 -0
  64. package/dist/defence/skill-scanner/parser.js.map +1 -0
  65. package/dist/defence/skill-scanner/patterns.d.ts +37 -0
  66. package/dist/defence/skill-scanner/patterns.d.ts.map +1 -0
  67. package/dist/defence/skill-scanner/patterns.js +240 -0
  68. package/dist/defence/skill-scanner/patterns.js.map +1 -0
  69. package/dist/defence/skill-scanner/scan-skill.d.ts +75 -0
  70. package/dist/defence/skill-scanner/scan-skill.d.ts.map +1 -0
  71. package/dist/defence/skill-scanner/scan-skill.js +397 -0
  72. package/dist/defence/skill-scanner/scan-skill.js.map +1 -0
  73. package/dist/embeddings/generator.d.ts +5 -0
  74. package/dist/embeddings/generator.d.ts.map +1 -1
  75. package/dist/embeddings/generator.js +35 -5
  76. package/dist/embeddings/generator.js.map +1 -1
  77. package/dist/embeddings/index.d.ts +1 -1
  78. package/dist/embeddings/index.d.ts.map +1 -1
  79. package/dist/embeddings/index.js +1 -1
  80. package/dist/embeddings/index.js.map +1 -1
  81. package/dist/index.js +88 -0
  82. package/dist/index.js.map +1 -1
  83. package/dist/memory/contradiction.d.ts.map +1 -1
  84. package/dist/memory/contradiction.js +8 -2
  85. package/dist/memory/contradiction.js.map +1 -1
  86. package/dist/memory/store.d.ts.map +1 -1
  87. package/dist/memory/store.js +27 -0
  88. package/dist/memory/store.js.map +1 -1
  89. package/dist/server.d.ts.map +1 -1
  90. package/dist/server.js +35 -0
  91. package/dist/server.js.map +1 -1
  92. package/hooks/openclaw/cortex-memory/handler.js +75 -0
  93. package/package.json +1 -1
  94. package/scripts/session-start-hook.mjs +67 -1
  95. package/dashboard/.next/standalone/dashboard/.next/static/chunks/407e39ab7e5d1d65.js +0 -842
  96. package/dashboard/.next/standalone/dashboard/.next/static/chunks/411ad30d41e2dba1.js +0 -1
  97. package/dashboard/.next/standalone/dashboard/.next/static/chunks/5b58941ef74d514c.js +0 -9
  98. package/dashboard/.next/standalone/dashboard/.next/static/chunks/8455c2995c6bc094.css +0 -3
  99. package/dashboard/.next/standalone/dashboard/.next/static/chunks/877441708af3b745.js +0 -1
  100. /package/dashboard/.next/standalone/dashboard/.next/static/{wsdDa8QcyWWZyV1TsuGAo → G16ww7KrkUyZJT_fvjFk6}/_buildManifest.js +0 -0
  101. /package/dashboard/.next/standalone/dashboard/.next/static/{wsdDa8QcyWWZyV1TsuGAo → G16ww7KrkUyZJT_fvjFk6}/_clientMiddlewareManifest.json +0 -0
  102. /package/dashboard/.next/standalone/dashboard/.next/static/{wsdDa8QcyWWZyV1TsuGAo → G16ww7KrkUyZJT_fvjFk6}/_ssgManifest.js +0 -0
@@ -64,6 +64,65 @@ function callCortex(tool, args = {}, options = { retries: 1, timeout: 15000 }) {
64
64
  });
65
65
  }
66
66
 
67
+ // ==================== HOOK SCANNER ====================
68
+
69
+ /**
70
+ * Scan installed OpenClaw hooks for potential threats
71
+ * Uses ShieldCortex's scanSkill via mcporter
72
+ * @returns {Promise<Array<{hookName: string, threat: string}>>}
73
+ */
74
+ async function scanInstalledHooks() {
75
+ const path = await import("node:path");
76
+ const { homedir } = await import("node:os");
77
+
78
+ const hooksDir = path.join(homedir(), ".openclaw", "hooks");
79
+ const threats = [];
80
+
81
+ try {
82
+ const entries = await fs.readdir(hooksDir, { withFileTypes: true });
83
+
84
+ for (const entry of entries) {
85
+ if (!entry.isDirectory()) continue;
86
+
87
+ const hookDir = path.join(hooksDir, entry.name);
88
+
89
+ // Check for HOOK.md
90
+ const hookMdPath = path.join(hookDir, "HOOK.md");
91
+ try {
92
+ const hookContent = await fs.readFile(hookMdPath, "utf-8");
93
+ const result = await callCortex("scan_skill", {
94
+ content: hookContent,
95
+ name: entry.name,
96
+ format: "hook-md",
97
+ });
98
+
99
+ if (result && result.includes("unsafe")) {
100
+ threats.push({ hookName: entry.name, threat: `HOOK.md flagged as unsafe` });
101
+ }
102
+ } catch { /* No HOOK.md, skip */ }
103
+
104
+ // Check for handler.js
105
+ const handlerPath = path.join(hookDir, "handler.js");
106
+ try {
107
+ const handlerContent = await fs.readFile(handlerPath, "utf-8");
108
+ const result = await callCortex("scan_skill", {
109
+ content: handlerContent,
110
+ name: `${entry.name}/handler.js`,
111
+ format: "hook-js",
112
+ });
113
+
114
+ if (result && result.includes("unsafe")) {
115
+ threats.push({ hookName: entry.name, threat: `handler.js flagged as unsafe` });
116
+ }
117
+ } catch { /* No handler.js, skip */ }
118
+ }
119
+ } catch {
120
+ // Hooks directory doesn't exist or is unreadable
121
+ }
122
+
123
+ return threats;
124
+ }
125
+
67
126
  // ==================== CONTENT EXTRACTION ====================
68
127
 
69
128
  const PATTERNS = {
@@ -283,6 +342,22 @@ async function onBootstrap(event) {
283
342
  });
284
343
 
285
344
  console.log("[cortex-memory] Injected past context into bootstrap");
345
+
346
+ // Scan installed hooks for threats
347
+ try {
348
+ const threats = await scanInstalledHooks();
349
+ if (threats.length > 0) {
350
+ const warnings = threats.map(t => `- ${t.hookName}: ${t.threat}`).join("\n");
351
+ context.bootstrapFiles.push({
352
+ name: "SHIELDCORTEX_WARNINGS.md",
353
+ content: `# ShieldCortex Security Warning\n\nThe following installed hooks have been flagged as potentially unsafe:\n\n${warnings}\n\nConsider running: \`npx shieldcortex scan-skills\` for a detailed report.`,
354
+ });
355
+ console.log(`[cortex-memory] WARNING: ${threats.length} hook(s) flagged as potentially unsafe`);
356
+ }
357
+ } catch (scanErr) {
358
+ // Hook scanning is best-effort — never block bootstrap
359
+ console.warn("[cortex-memory] Hook scan failed:", scanErr.message);
360
+ }
286
361
  }
287
362
 
288
363
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shieldcortex",
3
- "version": "2.4.22",
3
+ "version": "2.4.24",
4
4
  "description": "Complete memory system + security layer for AI agents. Native OpenClaw integration. Persistent storage, semantic search, prompt injection firewall, credential protection, and audit trail. One package, full solution.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -11,7 +11,7 @@
11
11
  */
12
12
 
13
13
  import Database from 'better-sqlite3';
14
- import { existsSync } from 'fs';
14
+ import { existsSync, readdirSync, readFileSync } from 'fs';
15
15
  import { join } from 'path';
16
16
  import { homedir } from 'os';
17
17
 
@@ -140,6 +140,56 @@ function formatContext(memories, project) {
140
140
  return lines.join('\n');
141
141
  }
142
142
 
143
+ // ==================== SKILL FILE CHECK ====================
144
+
145
+ /**
146
+ * Quick check of project instruction files for obviously suspicious content.
147
+ * This is a lightweight inline check — for full scanning use `npx shieldcortex scan-skills`.
148
+ */
149
+ function checkProjectInstructionFiles(cwd) {
150
+ const warnings = [];
151
+
152
+ const filesToCheck = [
153
+ { path: '.cursorrules', name: '.cursorrules' },
154
+ { path: '.windsurfrules', name: '.windsurfrules' },
155
+ { path: '.clinerules', name: '.clinerules' },
156
+ { path: '.github/copilot-instructions.md', name: 'copilot-instructions.md' },
157
+ ];
158
+
159
+ // Suspicious patterns that indicate potential threats in instruction files
160
+ const suspiciousPatterns = [
161
+ { pattern: /ignore\s+(all\s+)?(safety|security|permission)/i, label: 'safety bypass' },
162
+ { pattern: /bypass\s+(the\s+)?(sandbox|permission|safety)/i, label: 'sandbox bypass' },
163
+ { pattern: /disable\s+(the\s+)?(firewall|security|protection)/i, label: 'security disable' },
164
+ { pattern: /curl\s+[\s\S]{0,100}-d\s+[\s\S]{0,100}https?:/i, label: 'data exfiltration' },
165
+ { pattern: /read\s+[\s\S]{0,50}~\/\.ssh/i, label: 'SSH key access' },
166
+ { pattern: /read\s+[\s\S]{0,50}~\/\.aws/i, label: 'AWS credential access' },
167
+ { pattern: /<!--[\s\S]{0,500}?(always|never|must|execute|run|send)[\s\S]{0,500}?-->/i, label: 'hidden HTML instruction' },
168
+ { pattern: /echo\s+[\s\S]{0,100}>\s*\//i, label: 'file write instruction' },
169
+ { pattern: /dangerouslyDisableSandbox/i, label: 'sandbox disable flag' },
170
+ ];
171
+
172
+ for (const file of filesToCheck) {
173
+ const fullPath = join(cwd, file.path);
174
+ if (!existsSync(fullPath)) continue;
175
+
176
+ try {
177
+ const content = readFileSync(fullPath, 'utf-8');
178
+
179
+ for (const { pattern, label } of suspiciousPatterns) {
180
+ if (pattern.test(content)) {
181
+ warnings.push(`${file.name}: suspicious pattern detected (${label})`);
182
+ break; // One warning per file is enough
183
+ }
184
+ }
185
+ } catch {
186
+ // File unreadable — skip
187
+ }
188
+ }
189
+
190
+ return warnings;
191
+ }
192
+
143
193
  // ==================== MAIN HOOK LOGIC ====================
144
194
 
145
195
  let input = '';
@@ -213,6 +263,22 @@ ${proactiveInstructions}
213
263
  console.error(`[shieldcortex] Session start: no memories found for "${project}"`);
214
264
  }
215
265
 
266
+ // Quick check for suspicious project instruction files
267
+ try {
268
+ const cwd = hookData.cwd || process.cwd();
269
+ const skillWarnings = checkProjectInstructionFiles(cwd);
270
+ if (skillWarnings.length > 0) {
271
+ console.log(`\n⚠️ ShieldCortex detected suspicious instruction files:`);
272
+ for (const w of skillWarnings) {
273
+ console.log(` - ${w}`);
274
+ }
275
+ console.log(`Run \`npx shieldcortex scan-skills\` for a full report.\n`);
276
+ console.error(`[shieldcortex] WARNING: ${skillWarnings.length} suspicious file(s) detected`);
277
+ }
278
+ } catch {
279
+ // Skill check is best-effort — never block session start
280
+ }
281
+
216
282
  process.exit(0);
217
283
  } catch (error) {
218
284
  console.error(`[session-start] Error: ${error.message}`);