shieldcortex 4.31.1 → 4.32.0
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 +78 -2
- package/dashboard/.next/standalone/dashboard/.next/BUILD_ID +1 -1
- package/dashboard/.next/standalone/dashboard/.next/build-manifest.json +2 -2
- package/dashboard/.next/standalone/dashboard/.next/prerender-manifest.json +3 -3
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory/replay/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory/replay.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.json +1 -1
- package/dist/api/control.d.ts +2 -0
- package/dist/api/control.js +119 -2
- package/dist/api/routes/memories.js +19 -14
- package/dist/api/routes/system.js +2 -3
- package/dist/api/visualization-server.d.ts +13 -1
- package/dist/api/visualization-server.js +57 -1
- package/dist/audit/env-scanner.js +5 -2
- package/dist/audit/index.d.ts +4 -1
- package/dist/audit/index.js +2 -1
- package/dist/audit/mcp-config-scanner.d.ts +23 -0
- package/dist/audit/mcp-config-scanner.js +110 -0
- package/dist/audit/mcp-tools-scanner.d.ts +112 -0
- package/dist/audit/mcp-tools-scanner.js +299 -0
- package/dist/cli/audit.d.ts +1 -0
- package/dist/cli/audit.js +12 -1
- package/dist/cli/mcp.d.ts +13 -0
- package/dist/cli/mcp.js +0 -0
- package/dist/cli/remember.d.ts +75 -0
- package/dist/cli/remember.js +195 -0
- package/dist/cloud/config.d.ts +23 -1
- package/dist/cloud/config.js +453 -193
- package/dist/cloud/quarantine-sync.d.ts +12 -2
- package/dist/cloud/quarantine-sync.js +28 -6
- package/dist/cloud/sync-queue.d.ts +21 -2
- package/dist/cloud/sync-queue.js +124 -29
- package/dist/database/better-sqlite3-guard.d.ts +27 -2
- package/dist/database/better-sqlite3-guard.js +58 -5
- package/dist/database/init.js +85 -17
- package/dist/database/inline-schema.js +35 -1
- package/dist/database/migrations.js +104 -8
- package/dist/database/schema.sql +39 -1
- package/dist/defence/audit/queries.d.ts +10 -2
- package/dist/defence/audit/queries.js +30 -4
- package/dist/defence/audit/retention.d.ts +50 -0
- package/dist/defence/audit/retention.js +161 -0
- package/dist/defence/credential-leak/entropy.d.ts +11 -0
- package/dist/defence/credential-leak/entropy.js +27 -0
- package/dist/defence/credential-leak/index.js +27 -1
- package/dist/defence/credential-leak/patterns.d.ts +9 -0
- package/dist/defence/credential-leak/patterns.js +21 -0
- package/dist/defence/custom-patterns/store.js +8 -1
- package/dist/defence/custom-rules/store.d.ts +18 -0
- package/dist/defence/custom-rules/store.js +63 -0
- package/dist/defence/firewall/confusables.d.ts +30 -0
- package/dist/defence/firewall/confusables.js +87 -0
- package/dist/defence/firewall/encoding-detector.js +23 -9
- package/dist/defence/firewall/index.d.ts +11 -1
- package/dist/defence/firewall/index.js +34 -1
- package/dist/defence/firewall/instruction-detector.js +18 -7
- package/dist/defence/firewall/markdown-image-detector.d.ts +34 -0
- package/dist/defence/firewall/markdown-image-detector.js +83 -0
- package/dist/defence/fragmentation/entity-extractor.js +17 -6
- package/dist/defence/index.d.ts +5 -0
- package/dist/defence/index.js +8 -0
- package/dist/defence/iron-dome/index.js +7 -1
- package/dist/defence/pipeline.js +62 -10
- package/dist/defence/scan-windows.d.ts +41 -0
- package/dist/defence/scan-windows.js +61 -0
- package/dist/defence/semantic/attack-corpus.d.ts +22 -0
- package/dist/defence/semantic/attack-corpus.js +75 -0
- package/dist/defence/semantic/index.d.ts +67 -0
- package/dist/defence/semantic/index.js +138 -0
- package/dist/defence/skill-scanner/deep-scan.js +35 -15
- package/dist/defence/skill-scanner/patterns.d.ts +1 -1
- package/dist/defence/skill-scanner/patterns.js +8 -7
- package/dist/defence/tool-response-scanner.d.ts +21 -5
- package/dist/defence/tool-response-scanner.js +111 -22
- package/dist/defence/types.d.ts +11 -1
- package/dist/index.d.ts +29 -0
- package/dist/index.js +104 -20
- package/dist/memory/consolidate.js +1 -1
- package/dist/memory/decay.js +3 -1
- package/dist/memory/embedding.d.ts +18 -2
- package/dist/memory/embedding.js +32 -11
- package/dist/memory/expiry.js +1 -1
- package/dist/memory/search-recall.js +107 -49
- package/dist/memory/search.d.ts +19 -3
- package/dist/memory/search.js +25 -10
- package/dist/memory/store.d.ts +13 -2
- package/dist/memory/store.js +115 -11
- package/dist/scan-only.d.ts +64 -0
- package/dist/scan-only.js +173 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.js +6 -4
- package/dist/setup/claude-md.js +39 -34
- package/dist/setup/codex.js +9 -2
- package/dist/setup/copilot.js +160 -47
- package/dist/setup/json-config.d.ts +99 -0
- package/dist/setup/json-config.js +167 -0
- package/dist/setup/migrate.js +1 -1
- package/dist/setup/settings-hooks.js +8 -13
- package/dist/setup/uninstall.js +1 -21
- package/dist/tools/context.d.ts +8 -8
- package/dist/tools/forget.d.ts +9 -8
- package/dist/tools/forget.js +17 -4
- package/dist/tools/recall.d.ts +13 -13
- package/dist/tools/remember.d.ts +16 -16
- package/dist/tools/remember.js +19 -8
- package/dist/worker/brain-worker.d.ts +1 -0
- package/dist/worker/brain-worker.js +79 -16
- package/dist/worker/types.d.ts +8 -0
- package/dist/worker/types.js +8 -0
- package/dist/xray/dir-scanner.d.ts +18 -0
- package/dist/xray/dir-scanner.js +23 -1
- package/dist/xray/file-scanner.js +16 -1
- package/dist/xray/findings-store.js +9 -1
- package/dist/xray/index.d.ts +2 -0
- package/dist/xray/index.js +10 -1
- package/dist/xray/npm-inspector.d.ts +31 -0
- package/dist/xray/npm-inspector.js +135 -29
- package/dist/xray/patterns.d.ts +1 -1
- package/dist/xray/patterns.js +20 -23
- package/dist/xray/sarif.d.ts +78 -0
- package/dist/xray/sarif.js +166 -0
- package/dist/xray/watch.d.ts +1 -0
- package/dist/xray/watch.js +10 -1
- package/hooks/openclaw/cortex-memory/handler.ts +122 -18
- package/hooks/openclaw/cortex-memory/runtime.mjs +10 -4
- package/package.json +10 -3
- package/dist/memory/embedding-cache.d.ts +0 -20
- package/dist/memory/embedding-cache.js +0 -91
- /package/dashboard/.next/standalone/dashboard/.next/static/{T0hqc-Le01c8QVY0VrHnu → Ox9scglBehbbCk7DD8-Vn}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{T0hqc-Le01c8QVY0VrHnu → Ox9scglBehbbCk7DD8-Vn}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{T0hqc-Le01c8QVY0VrHnu → Ox9scglBehbbCk7DD8-Vn}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SARIF 2.1.0 output for ShieldCortex findings.
|
|
3
|
+
*
|
|
4
|
+
* Phase 15b — turns X-Ray / audit / mcp-scan findings into a SARIF 2.1.0
|
|
5
|
+
* document so they surface in GitHub Code Scanning (the Security tab).
|
|
6
|
+
*
|
|
7
|
+
* Lives in the xray layer (its `index.ts` already re-exports the other
|
|
8
|
+
* formatters) but is shape-agnostic: it accepts BOTH the xray `XRayFinding`
|
|
9
|
+
* and the audit `AuditFinding` via a single internal normaliser, so the SARIF
|
|
10
|
+
* builder never branches on the source shape.
|
|
11
|
+
*
|
|
12
|
+
* Spec: https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html
|
|
13
|
+
*/
|
|
14
|
+
import path from 'path';
|
|
15
|
+
import { createRequire } from 'module';
|
|
16
|
+
const INFORMATION_URI = 'https://shieldcortex.ai';
|
|
17
|
+
const SARIF_SCHEMA = 'https://json.schemastore.org/sarif-2.1.0.json';
|
|
18
|
+
// ── Helpers ────────────────────────────────────────────────────
|
|
19
|
+
/**
|
|
20
|
+
* Map a ShieldCortex severity onto a SARIF result level.
|
|
21
|
+
* critical / high → error
|
|
22
|
+
* medium → warning
|
|
23
|
+
* low / info → note
|
|
24
|
+
*/
|
|
25
|
+
function severityToLevel(severity) {
|
|
26
|
+
switch (severity) {
|
|
27
|
+
case 'critical':
|
|
28
|
+
case 'high':
|
|
29
|
+
return 'error';
|
|
30
|
+
case 'medium':
|
|
31
|
+
return 'warning';
|
|
32
|
+
case 'low':
|
|
33
|
+
case 'info':
|
|
34
|
+
default:
|
|
35
|
+
return 'note';
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Stable rule id from a category/scanner key + title. SARIF rule ids should be
|
|
40
|
+
* opaque, stable, and free of whitespace so they read well in the GitHub UI and
|
|
41
|
+
* dedupe deterministically across runs.
|
|
42
|
+
*/
|
|
43
|
+
function makeRuleId(prefix, title) {
|
|
44
|
+
const slug = `${prefix}/${title}`
|
|
45
|
+
.toLowerCase()
|
|
46
|
+
.replace(/[^a-z0-9]+/g, '-')
|
|
47
|
+
.replace(/^-+|-+$/g, '');
|
|
48
|
+
return `shieldcortex/${slug}`;
|
|
49
|
+
}
|
|
50
|
+
function isXRayFinding(f) {
|
|
51
|
+
// XRayFinding has `category`; AuditFinding has `scanner`. They are disjoint.
|
|
52
|
+
return f.category !== undefined;
|
|
53
|
+
}
|
|
54
|
+
/** Make a file path relative to baseDir + posix-separated for SARIF URIs. */
|
|
55
|
+
function toUri(file, baseDir) {
|
|
56
|
+
let rel = file;
|
|
57
|
+
if (path.isAbsolute(file)) {
|
|
58
|
+
rel = path.relative(baseDir, file);
|
|
59
|
+
// If the file is outside baseDir, relative() yields ../ — fall back to the
|
|
60
|
+
// absolute path rather than emitting a confusing climb-out URI.
|
|
61
|
+
if (rel.startsWith('..'))
|
|
62
|
+
rel = file;
|
|
63
|
+
}
|
|
64
|
+
return rel.split(path.sep).join('/');
|
|
65
|
+
}
|
|
66
|
+
function normalise(f) {
|
|
67
|
+
if (isXRayFinding(f)) {
|
|
68
|
+
const category = f.category;
|
|
69
|
+
return {
|
|
70
|
+
ruleId: makeRuleId(category, f.title),
|
|
71
|
+
ruleName: f.title,
|
|
72
|
+
level: severityToLevel(f.severity),
|
|
73
|
+
message: f.description,
|
|
74
|
+
file: f.file,
|
|
75
|
+
line: f.line,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// AuditFinding. May or may not have a filePath.
|
|
79
|
+
const audit = f;
|
|
80
|
+
const norm = {
|
|
81
|
+
ruleId: makeRuleId(audit.scanner, audit.title),
|
|
82
|
+
ruleName: audit.title,
|
|
83
|
+
level: severityToLevel(audit.severity),
|
|
84
|
+
message: audit.description,
|
|
85
|
+
helpUri: audit.learnMoreUrl,
|
|
86
|
+
};
|
|
87
|
+
if (audit.filePath) {
|
|
88
|
+
norm.file = audit.filePath;
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
// Fileless: synthesise a logical location from scanner + title so the
|
|
92
|
+
// result still carries a location and stays schema-valid without a
|
|
93
|
+
// physicalLocation.
|
|
94
|
+
norm.logicalName = `${audit.scanner}/${audit.title}`;
|
|
95
|
+
}
|
|
96
|
+
return norm;
|
|
97
|
+
}
|
|
98
|
+
// ── Builder ────────────────────────────────────────────────────
|
|
99
|
+
function resolveVersion() {
|
|
100
|
+
try {
|
|
101
|
+
const require = createRequire(import.meta.url);
|
|
102
|
+
const pkg = require('../../package.json');
|
|
103
|
+
return pkg.version ?? '0.0.0';
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return '0.0.0';
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Build a SARIF 2.1.0 log from a list of findings (either shape).
|
|
111
|
+
* Rules are deduped into `tool.driver.rules` by ruleId.
|
|
112
|
+
*/
|
|
113
|
+
export function toSarif(findings, options = {}) {
|
|
114
|
+
const version = options.version ?? resolveVersion();
|
|
115
|
+
const baseDir = options.baseDir ?? process.cwd();
|
|
116
|
+
const rulesById = new Map();
|
|
117
|
+
const results = [];
|
|
118
|
+
for (const finding of findings) {
|
|
119
|
+
const n = normalise(finding);
|
|
120
|
+
if (!rulesById.has(n.ruleId)) {
|
|
121
|
+
const rule = {
|
|
122
|
+
id: n.ruleId,
|
|
123
|
+
name: n.ruleName,
|
|
124
|
+
shortDescription: { text: n.ruleName },
|
|
125
|
+
};
|
|
126
|
+
if (n.helpUri)
|
|
127
|
+
rule.helpUri = n.helpUri;
|
|
128
|
+
rulesById.set(n.ruleId, rule);
|
|
129
|
+
}
|
|
130
|
+
const result = {
|
|
131
|
+
ruleId: n.ruleId,
|
|
132
|
+
level: n.level,
|
|
133
|
+
message: { text: n.message },
|
|
134
|
+
};
|
|
135
|
+
if (n.file) {
|
|
136
|
+
const physicalLocation = {
|
|
137
|
+
artifactLocation: { uri: toUri(n.file, baseDir) },
|
|
138
|
+
};
|
|
139
|
+
if (typeof n.line === 'number') {
|
|
140
|
+
physicalLocation.region = { startLine: n.line };
|
|
141
|
+
}
|
|
142
|
+
result.locations = [{ physicalLocation }];
|
|
143
|
+
}
|
|
144
|
+
else if (n.logicalName) {
|
|
145
|
+
result.locations = [{ logicalLocations: [{ fullyQualifiedName: n.logicalName }] }];
|
|
146
|
+
}
|
|
147
|
+
results.push(result);
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
$schema: SARIF_SCHEMA,
|
|
151
|
+
version: '2.1.0',
|
|
152
|
+
runs: [
|
|
153
|
+
{
|
|
154
|
+
tool: {
|
|
155
|
+
driver: {
|
|
156
|
+
name: 'ShieldCortex',
|
|
157
|
+
version,
|
|
158
|
+
informationUri: INFORMATION_URI,
|
|
159
|
+
rules: Array.from(rulesById.values()),
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
results,
|
|
163
|
+
},
|
|
164
|
+
],
|
|
165
|
+
};
|
|
166
|
+
}
|
package/dist/xray/watch.d.ts
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Watches a directory for file changes and incrementally re-scans
|
|
5
5
|
* only the changed files, printing new findings as they appear.
|
|
6
6
|
*/
|
|
7
|
+
export declare function shouldIgnore(filePath: string): boolean;
|
|
7
8
|
/**
|
|
8
9
|
* Watch a directory for changes and incrementally scan changed files.
|
|
9
10
|
*/
|
package/dist/xray/watch.js
CHANGED
|
@@ -10,6 +10,7 @@ import path from 'path';
|
|
|
10
10
|
import crypto from 'crypto';
|
|
11
11
|
import { scanFile } from './file-scanner.js';
|
|
12
12
|
import { calculateTrustScore } from './trust-score.js';
|
|
13
|
+
import { ALLOW_HIDDEN_DIRS } from './dir-scanner.js';
|
|
13
14
|
import { appendActivity, emitDetectionEvent, endWatchSession, heartbeatWatchSession, recordWatchSessionEvent, startWatchSession, } from './activity.js';
|
|
14
15
|
import { addFindings } from './findings-store.js';
|
|
15
16
|
// ── Constants ───────────────────────────────────────────────
|
|
@@ -34,10 +35,18 @@ const IGNORE_PATH_PATTERNS = [
|
|
|
34
35
|
'/tmp/com.apple.',
|
|
35
36
|
];
|
|
36
37
|
// ── Helpers ─────────────────────────────────────────────────
|
|
37
|
-
function shouldIgnore(filePath) {
|
|
38
|
+
export function shouldIgnore(filePath) {
|
|
38
39
|
const parts = filePath.split(path.sep);
|
|
39
40
|
if (parts.some(p => IGNORE_DIRS.has(p)))
|
|
40
41
|
return true;
|
|
42
|
+
// Security-relevant hidden dirs (.github/.claude/.cursor/.codex/.vscode/…)
|
|
43
|
+
// are explicitly in scope for watch mode — they hold the agent-instruction /
|
|
44
|
+
// CI surfaces X-Ray exists to protect. Shares ALLOW_HIDDEN_DIRS with the
|
|
45
|
+
// directory scanner so a scan and a watch agree on what's watched. `.git`,
|
|
46
|
+
// `node_modules`, `.venv` etc. are NOT in the allow-list and remain excluded
|
|
47
|
+
// via the IGNORE_DIRS check above (which runs first).
|
|
48
|
+
if (parts.some(p => ALLOW_HIDDEN_DIRS.has(p)))
|
|
49
|
+
return false;
|
|
41
50
|
// Resolve symlinks to check the real path
|
|
42
51
|
let abs;
|
|
43
52
|
try {
|
|
@@ -215,6 +215,84 @@ async function getSharedNoveltyGate() {
|
|
|
215
215
|
* Uses ShieldCortex's scanSkill via mcporter
|
|
216
216
|
* @returns {Promise<Array<{hookName: string, threat: string}>>}
|
|
217
217
|
*/
|
|
218
|
+
// Content-hash cache for hook scan_skill verdicts. Byte-identical
|
|
219
|
+
// HOOK.md/handler.js files produce the same sha256, so we skip the (cold MCP)
|
|
220
|
+
// scan_skill shell-out on a cache hit and reuse the stored verdict. Keyed by
|
|
221
|
+
// sha256(content) → "unsafe" | "clean". Persisted to ~/.shieldcortex so the
|
|
222
|
+
// cache survives gateway restarts. A file edit changes the hash and forces a
|
|
223
|
+
// fresh scan, so this never masks a newly-introduced threat.
|
|
224
|
+
const HOOK_SCAN_CACHE_FILE = path.join(homedir(), ".shieldcortex", "openclaw-hook-scan-cache.json");
|
|
225
|
+
|
|
226
|
+
async function loadHookScanCache() {
|
|
227
|
+
try {
|
|
228
|
+
const raw = JSON.parse(await fs.readFile(HOOK_SCAN_CACHE_FILE, "utf-8"));
|
|
229
|
+
if (raw && typeof raw === "object" && !Array.isArray(raw)) return raw;
|
|
230
|
+
} catch { /* no cache yet / unreadable */ }
|
|
231
|
+
return {};
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
async function saveHookScanCache(cache) {
|
|
235
|
+
try {
|
|
236
|
+
await fs.mkdir(path.dirname(HOOK_SCAN_CACHE_FILE), { recursive: true });
|
|
237
|
+
await fs.writeFile(HOOK_SCAN_CACHE_FILE, JSON.stringify(cache) + "\n", "utf-8");
|
|
238
|
+
} catch { /* best-effort — never block bootstrap on cache write */ }
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
function hashHookContent(content) {
|
|
242
|
+
return createHash("sha256").update(content).digest("hex");
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Parse the scan_skill verdict from its structured markdown output.
|
|
247
|
+
*
|
|
248
|
+
* The MCP `scan_skill` tool emits a fixed `**Safe:** Yes|No` field (see
|
|
249
|
+
* server.ts). We parse THAT exact field rather than substring-matching the
|
|
250
|
+
* whole report. The old `result.includes("unsafe")` was wrong twice over: the
|
|
251
|
+
* report never even prints the literal word "unsafe" (the verdict field is
|
|
252
|
+
* `**Safe:** No`), and any finding `description`/`matchedText` that merely
|
|
253
|
+
* mentions "unsafe" (e.g. "unsafe deserialization") would false-positive a
|
|
254
|
+
* clean file into a bootstrap security warning.
|
|
255
|
+
*
|
|
256
|
+
* Returns:
|
|
257
|
+
* true → definitively unsafe (`**Safe:** No`)
|
|
258
|
+
* false → definitively safe (`**Safe:** Yes`)
|
|
259
|
+
* null → verdict could not be parsed (treat as indeterminate; don't cache)
|
|
260
|
+
*
|
|
261
|
+
* @param {string} result
|
|
262
|
+
* @returns {boolean|null}
|
|
263
|
+
*/
|
|
264
|
+
function parseScanSkillUnsafe(result) {
|
|
265
|
+
if (typeof result !== "string") return null;
|
|
266
|
+
// Tolerate optional markdown bold markers and surrounding whitespace.
|
|
267
|
+
const m = result.match(/\*{0,2}Safe:\*{0,2}\s*(Yes|No)\b/i);
|
|
268
|
+
if (!m) return null;
|
|
269
|
+
return m[1].toLowerCase() === "no";
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* Scan one hook file, reusing a cached verdict when the content hash matches.
|
|
274
|
+
* Mutates `cache` in place and sets `dirty.changed` when a fresh scan runs.
|
|
275
|
+
* @returns {Promise<boolean>} true when the file is flagged unsafe
|
|
276
|
+
*/
|
|
277
|
+
async function scanHookFileCached(content, name, format, cache, dirty) {
|
|
278
|
+
const hash = hashHookContent(content);
|
|
279
|
+
const cached = cache[hash];
|
|
280
|
+
if (cached === "unsafe") return true;
|
|
281
|
+
if (cached === "clean") return false;
|
|
282
|
+
|
|
283
|
+
const result = await callCortex("scan_skill", { content, name, format });
|
|
284
|
+
// Only memoise a definitive verdict. A null/failed call is NOT cached, so a
|
|
285
|
+
// transient MCP failure doesn't get pinned as "clean" for an unscanned file.
|
|
286
|
+
if (result == null) return false;
|
|
287
|
+
const unsafe = parseScanSkillUnsafe(result);
|
|
288
|
+
// Indeterminate parse (null) → don't flag and don't cache, so the next scan
|
|
289
|
+
// retries rather than pinning a guessed verdict.
|
|
290
|
+
if (unsafe === null) return false;
|
|
291
|
+
cache[hash] = unsafe ? "unsafe" : "clean";
|
|
292
|
+
dirty.changed = true;
|
|
293
|
+
return unsafe;
|
|
294
|
+
}
|
|
295
|
+
|
|
218
296
|
async function scanInstalledHooks() {
|
|
219
297
|
const path = await import("node:path");
|
|
220
298
|
const { homedir } = await import("node:os");
|
|
@@ -224,6 +302,8 @@ async function scanInstalledHooks() {
|
|
|
224
302
|
|
|
225
303
|
try {
|
|
226
304
|
const entries = await fs.readdir(hooksDir, { withFileTypes: true });
|
|
305
|
+
const cache = await loadHookScanCache();
|
|
306
|
+
const dirty = { changed: false };
|
|
227
307
|
|
|
228
308
|
for (const entry of entries) {
|
|
229
309
|
if (!entry.isDirectory()) continue;
|
|
@@ -237,13 +317,7 @@ async function scanInstalledHooks() {
|
|
|
237
317
|
const hookMdPath = path.join(hookDir, "HOOK.md");
|
|
238
318
|
try {
|
|
239
319
|
const hookContent = await fs.readFile(hookMdPath, "utf-8");
|
|
240
|
-
|
|
241
|
-
content: hookContent,
|
|
242
|
-
name: entry.name,
|
|
243
|
-
format: "hook-md",
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
if (result && result.includes("unsafe")) {
|
|
320
|
+
if (await scanHookFileCached(hookContent, entry.name, "hook-md", cache, dirty)) {
|
|
247
321
|
threats.push({ hookName: entry.name, threat: `HOOK.md flagged as unsafe` });
|
|
248
322
|
}
|
|
249
323
|
} catch { /* No HOOK.md, skip */ }
|
|
@@ -252,17 +326,13 @@ async function scanInstalledHooks() {
|
|
|
252
326
|
const handlerPath = path.join(hookDir, "handler.js");
|
|
253
327
|
try {
|
|
254
328
|
const handlerContent = await fs.readFile(handlerPath, "utf-8");
|
|
255
|
-
|
|
256
|
-
content: handlerContent,
|
|
257
|
-
name: `${entry.name}/handler.js`,
|
|
258
|
-
format: "hook-js",
|
|
259
|
-
});
|
|
260
|
-
|
|
261
|
-
if (result && result.includes("unsafe")) {
|
|
329
|
+
if (await scanHookFileCached(handlerContent, `${entry.name}/handler.js`, "hook-js", cache, dirty)) {
|
|
262
330
|
threats.push({ hookName: entry.name, threat: `handler.js flagged as unsafe` });
|
|
263
331
|
}
|
|
264
332
|
} catch { /* No handler.js, skip */ }
|
|
265
333
|
}
|
|
334
|
+
|
|
335
|
+
if (dirty.changed) await saveHookScanCache(cache);
|
|
266
336
|
} catch {
|
|
267
337
|
// Hooks directory doesn't exist or is unreadable
|
|
268
338
|
}
|
|
@@ -303,10 +373,37 @@ function assistantConversationText(messages: string[]): string {
|
|
|
303
373
|
* @param {string} sessionFilePath
|
|
304
374
|
* @returns {Promise<string[]>} Array of "role: content" strings
|
|
305
375
|
*/
|
|
376
|
+
// Read only the tail of a (potentially large) JSONL transcript. We need the
|
|
377
|
+
// last 30 lines; reading the whole file just to discard the head wastes memory
|
|
378
|
+
// on long sessions. Read up to TAIL_BYTES from the end via a file descriptor.
|
|
379
|
+
// If the window started mid-file we drop its first (possibly partial) line so
|
|
380
|
+
// only complete lines are parsed — JSON.parse failures are skipped anyway, but
|
|
381
|
+
// dropping the fragment keeps the "last 30 complete lines" semantics exact.
|
|
382
|
+
const TAIL_BYTES = 64 * 1024;
|
|
383
|
+
|
|
384
|
+
async function readSessionTail(sessionFilePath) {
|
|
385
|
+
const fh = await fs.open(sessionFilePath, "r");
|
|
386
|
+
try {
|
|
387
|
+
const { size } = await fh.stat();
|
|
388
|
+
if (size <= TAIL_BYTES) {
|
|
389
|
+
// Small file — read it whole (identical to the original behaviour).
|
|
390
|
+
return { text: await fh.readFile("utf-8"), truncated: false };
|
|
391
|
+
}
|
|
392
|
+
const start = size - TAIL_BYTES;
|
|
393
|
+
const buf = Buffer.allocUnsafe(TAIL_BYTES);
|
|
394
|
+
const { bytesRead } = await fh.read(buf, 0, TAIL_BYTES, start);
|
|
395
|
+
return { text: buf.toString("utf-8", 0, bytesRead), truncated: true };
|
|
396
|
+
} finally {
|
|
397
|
+
await fh.close();
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
|
|
306
401
|
async function getRecentMessages(sessionFilePath) {
|
|
307
402
|
try {
|
|
308
|
-
const
|
|
309
|
-
|
|
403
|
+
const { text, truncated } = await readSessionTail(sessionFilePath);
|
|
404
|
+
let lines = text.trim().split("\n");
|
|
405
|
+
// Drop the leading partial line when we started reading mid-file.
|
|
406
|
+
if (truncated && lines.length > 1) lines = lines.slice(1);
|
|
310
407
|
const recentLines = lines.slice(-30);
|
|
311
408
|
|
|
312
409
|
const messages = [];
|
|
@@ -665,8 +762,15 @@ async function proactiveRecall(event) {
|
|
|
665
762
|
project: "*",
|
|
666
763
|
});
|
|
667
764
|
|
|
668
|
-
|
|
669
|
-
|
|
765
|
+
// Parse the structured `Found N memor(y|ies):` header (recall.ts) at the
|
|
766
|
+
// START of the result, rather than substring-matching "Found" anywhere —
|
|
767
|
+
// a recalled memory's own content can contain the word "Found" and the old
|
|
768
|
+
// `!result.includes("Found 0")` clause was dead (the empty result is
|
|
769
|
+
// "No memories found...", never "Found 0"). Surface only on N >= 1.
|
|
770
|
+
if (result && typeof result === "string") {
|
|
771
|
+
const m = result.match(/^Found\s+(\d+)\s+memor/m);
|
|
772
|
+
const count = m ? Number(m[1]) : 0;
|
|
773
|
+
if (count >= 1 && event.messages) {
|
|
670
774
|
event.messages.push(`🧠 ${result}`);
|
|
671
775
|
}
|
|
672
776
|
}
|
|
@@ -143,10 +143,16 @@ export function createOpenClawRuntime({
|
|
|
143
143
|
const serverCmd = await resolveServerCmd();
|
|
144
144
|
|
|
145
145
|
return new Promise((resolve) => {
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
146
|
+
// Pass arguments as a single `--args <json>` payload, NOT as per-key
|
|
147
|
+
// `key:value` flags. The old form did `String(value).replace(/'/g, "''")`
|
|
148
|
+
// — SQL-style apostrophe doubling — on each value, which mangled saved
|
|
149
|
+
// memory content (an apostrophe in "it's" became "it''s" and was stored
|
|
150
|
+
// literally; this is a key:value CLI flag, not a bound SQL param, so no
|
|
151
|
+
// such escaping should ever happen). A JSON payload also round-trips
|
|
152
|
+
// colons, spaces, and newlines in content without the `key:value`
|
|
153
|
+
// splitter misreading them. execFile passes argv elements directly (no
|
|
154
|
+
// shell), so the JSON string needs no further quoting/escaping.
|
|
155
|
+
const cmdArgs = ["mcporter", "call", "--stdio", serverCmd, tool, "--args", JSON.stringify(args)];
|
|
150
156
|
|
|
151
157
|
let attempts = 0;
|
|
152
158
|
const maxAttempts = (options.retries || 0) + 1;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shieldcortex",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.32.0",
|
|
4
4
|
"description": "Trustworthy memory and security for AI agents. Recall debugging, review queue, OpenClaw session capture, and memory poisoning defence for Claude Code, Codex, OpenClaw, LangChain, and MCP agents.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -30,6 +30,10 @@
|
|
|
30
30
|
"import": "./dist/defence/index.js",
|
|
31
31
|
"types": "./dist/defence/index.d.ts"
|
|
32
32
|
},
|
|
33
|
+
"./scan": {
|
|
34
|
+
"import": "./dist/scan-only.js",
|
|
35
|
+
"types": "./dist/scan-only.d.ts"
|
|
36
|
+
},
|
|
33
37
|
"./environment": {
|
|
34
38
|
"import": "./dist/environment/index.js",
|
|
35
39
|
"types": "./dist/environment/index.d.ts"
|
|
@@ -57,12 +61,13 @@
|
|
|
57
61
|
"test": "node scripts/run-jest.mjs",
|
|
58
62
|
"test:watch": "node scripts/run-jest.mjs --watch",
|
|
59
63
|
"test:coverage": "node scripts/run-jest.mjs --coverage",
|
|
64
|
+
"test:dist": "node scripts/check-no-bare-require.mjs",
|
|
60
65
|
"bench": "tsx benchmark/longmemeval/run.ts",
|
|
61
66
|
"bench:smoke": "SHIELDCORTEX_SKIP_EMBEDDINGS=1 tsx benchmark/longmemeval/run.ts --quiet",
|
|
62
67
|
"audit:security": "npm audit --audit-level=moderate",
|
|
63
68
|
"prepack": "node scripts/ensure-bin-executable.mjs",
|
|
64
69
|
"version": "node scripts/sync-plugin-version.mjs && git add plugins/openclaw/package.json plugins/openclaw/openclaw.plugin.json",
|
|
65
|
-
"prepublishOnly": "node scripts/sync-plugin-version.mjs --check && npm run build"
|
|
70
|
+
"prepublishOnly": "node scripts/sync-plugin-version.mjs --check && npm run build && npm run test:dist"
|
|
66
71
|
},
|
|
67
72
|
"keywords": [
|
|
68
73
|
"ai-memory",
|
|
@@ -112,7 +117,6 @@
|
|
|
112
117
|
"node": ">=20.0.0"
|
|
113
118
|
},
|
|
114
119
|
"dependencies": {
|
|
115
|
-
"@huggingface/transformers": "^3.7.2",
|
|
116
120
|
"@modelcontextprotocol/sdk": "^1.0.0",
|
|
117
121
|
"better-sqlite3": "^12.0.0",
|
|
118
122
|
"cors": "^2.8.5",
|
|
@@ -122,6 +126,9 @@
|
|
|
122
126
|
"ws": "^8.18.0",
|
|
123
127
|
"zod": "^3.23.0"
|
|
124
128
|
},
|
|
129
|
+
"optionalDependencies": {
|
|
130
|
+
"@huggingface/transformers": "^3.7.2"
|
|
131
|
+
},
|
|
125
132
|
"devDependencies": {
|
|
126
133
|
"@types/better-sqlite3": "^7.6.11",
|
|
127
134
|
"@types/cors": "^2.8.17",
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Embedding Cache
|
|
3
|
-
*
|
|
4
|
-
* Stores pre-computed embeddings in SQLite to avoid re-embedding on every recall.
|
|
5
|
-
* Self-migrating: creates the table on first use.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Get a cached embedding for a memory ID.
|
|
9
|
-
* Returns null if not cached or DB unavailable.
|
|
10
|
-
*/
|
|
11
|
-
export declare function getCachedEmbedding(memoryId: number): Float32Array | null;
|
|
12
|
-
/**
|
|
13
|
-
* Store a computed embedding in the cache.
|
|
14
|
-
*/
|
|
15
|
-
export declare function setCachedEmbedding(memoryId: number, embedding: Float32Array): void;
|
|
16
|
-
/**
|
|
17
|
-
* Get embedding from cache, or compute + store if missing.
|
|
18
|
-
* Returns null if both cache and computation fail.
|
|
19
|
-
*/
|
|
20
|
-
export declare function getOrComputeEmbedding(memoryId: number, text: string): Promise<Float32Array | null>;
|
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Embedding Cache
|
|
3
|
-
*
|
|
4
|
-
* Stores pre-computed embeddings in SQLite to avoid re-embedding on every recall.
|
|
5
|
-
* Self-migrating: creates the table on first use.
|
|
6
|
-
*/
|
|
7
|
-
import { getDatabase, isDatabaseInitialized } from '../database/init.js';
|
|
8
|
-
import { embedText } from './embedding.js';
|
|
9
|
-
const MODEL_VERSION = 'all-MiniLM-L6-v2';
|
|
10
|
-
let tableCreated = false;
|
|
11
|
-
/**
|
|
12
|
-
* Ensure the memory_embeddings table exists (self-migrating).
|
|
13
|
-
*/
|
|
14
|
-
function ensureTable() {
|
|
15
|
-
if (tableCreated)
|
|
16
|
-
return;
|
|
17
|
-
if (!isDatabaseInitialized())
|
|
18
|
-
return;
|
|
19
|
-
try {
|
|
20
|
-
const db = getDatabase();
|
|
21
|
-
db.exec(`
|
|
22
|
-
CREATE TABLE IF NOT EXISTS memory_embeddings (
|
|
23
|
-
memory_id INTEGER PRIMARY KEY,
|
|
24
|
-
embedding BLOB NOT NULL,
|
|
25
|
-
model_version TEXT NOT NULL,
|
|
26
|
-
created_at TEXT NOT NULL DEFAULT (datetime('now'))
|
|
27
|
-
)
|
|
28
|
-
`);
|
|
29
|
-
tableCreated = true;
|
|
30
|
-
}
|
|
31
|
-
catch (e) {
|
|
32
|
-
console.warn('[shieldcortex] Failed to create memory_embeddings table:', e.message);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
/**
|
|
36
|
-
* Get a cached embedding for a memory ID.
|
|
37
|
-
* Returns null if not cached or DB unavailable.
|
|
38
|
-
*/
|
|
39
|
-
export function getCachedEmbedding(memoryId) {
|
|
40
|
-
try {
|
|
41
|
-
ensureTable();
|
|
42
|
-
if (!isDatabaseInitialized())
|
|
43
|
-
return null;
|
|
44
|
-
const db = getDatabase();
|
|
45
|
-
const row = db.prepare('SELECT embedding FROM memory_embeddings WHERE memory_id = ? AND model_version = ?').get(memoryId, MODEL_VERSION);
|
|
46
|
-
if (!row)
|
|
47
|
-
return null;
|
|
48
|
-
const buf = row.embedding;
|
|
49
|
-
return new Float32Array(buf.buffer, buf.byteOffset, buf.byteLength / 4);
|
|
50
|
-
}
|
|
51
|
-
catch (e) {
|
|
52
|
-
console.warn('[shieldcortex] getCachedEmbedding error:', e.message);
|
|
53
|
-
return null;
|
|
54
|
-
}
|
|
55
|
-
}
|
|
56
|
-
/**
|
|
57
|
-
* Store a computed embedding in the cache.
|
|
58
|
-
*/
|
|
59
|
-
export function setCachedEmbedding(memoryId, embedding) {
|
|
60
|
-
try {
|
|
61
|
-
ensureTable();
|
|
62
|
-
if (!isDatabaseInitialized())
|
|
63
|
-
return;
|
|
64
|
-
const db = getDatabase();
|
|
65
|
-
const buffer = Buffer.from(embedding.buffer, embedding.byteOffset, embedding.byteLength);
|
|
66
|
-
db.prepare(`
|
|
67
|
-
INSERT OR REPLACE INTO memory_embeddings (memory_id, embedding, model_version, created_at)
|
|
68
|
-
VALUES (?, ?, ?, datetime('now'))
|
|
69
|
-
`).run(memoryId, buffer, MODEL_VERSION);
|
|
70
|
-
}
|
|
71
|
-
catch (e) {
|
|
72
|
-
console.warn('[shieldcortex] setCachedEmbedding error:', e.message);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
/**
|
|
76
|
-
* Get embedding from cache, or compute + store if missing.
|
|
77
|
-
* Returns null if both cache and computation fail.
|
|
78
|
-
*/
|
|
79
|
-
export async function getOrComputeEmbedding(memoryId, text) {
|
|
80
|
-
// Try cache first
|
|
81
|
-
const cached = getCachedEmbedding(memoryId);
|
|
82
|
-
if (cached)
|
|
83
|
-
return cached;
|
|
84
|
-
// Compute embedding
|
|
85
|
-
const embedding = await embedText(text);
|
|
86
|
-
if (!embedding)
|
|
87
|
-
return null;
|
|
88
|
-
// Store in cache (best-effort)
|
|
89
|
-
setCachedEmbedding(memoryId, embedding);
|
|
90
|
-
return embedding;
|
|
91
|
-
}
|
|
File without changes
|
|
File without changes
|