shieldcortex 4.25.1 → 4.25.2
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/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/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/dist/cli/doctor.d.ts +27 -0
- package/dist/cli/doctor.js +97 -0
- package/package.json +1 -2
- package/plugins/openclaw/dist/cloud-sync.js +0 -19
- package/plugins/openclaw/dist/index.js +0 -703
- package/plugins/openclaw/dist/intercept-ingest.js +0 -18
- package/plugins/openclaw/dist/interceptor.js +0 -346
- package/plugins/openclaw/dist/openclaw.plugin.json +0 -205
- /package/dashboard/.next/standalone/dashboard/.next/static/{EItbSW_ccG_F0ufC_s7dD → Cl3bBJxPrtXsvyaKu3Y4x}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{EItbSW_ccG_F0ufC_s7dD → Cl3bBJxPrtXsvyaKu3Y4x}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{EItbSW_ccG_F0ufC_s7dD → Cl3bBJxPrtXsvyaKu3Y4x}/_ssgManifest.js +0 -0
|
@@ -1,703 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ShieldCortex Real-time Scanning Plugin for OpenClaw v2026.3.22+
|
|
3
|
-
*
|
|
4
|
-
* Uses explicit capability registration (registerHook + registerCommand)
|
|
5
|
-
* for llm_input/llm_output scanning and optional memory extraction.
|
|
6
|
-
* All scanning operations are fire-and-forget.
|
|
7
|
-
*/
|
|
8
|
-
import { createHash } from "node:crypto";
|
|
9
|
-
import fs from "node:fs/promises";
|
|
10
|
-
import { existsSync, readFileSync, realpathSync } from "node:fs";
|
|
11
|
-
import path from "node:path";
|
|
12
|
-
import { homedir } from "node:os";
|
|
13
|
-
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
14
|
-
import { createInterceptor, DEFAULT_CONFIG as DEFAULT_INTERCEPTOR_CONFIG } from './interceptor.js';
|
|
15
|
-
import { syncInterceptEvent } from './intercept-ingest.js';
|
|
16
|
-
import { cloudSync } from './cloud-sync.js';
|
|
17
|
-
let runtimePromise = null;
|
|
18
|
-
function addRuntimeCandidate(candidates, packageRoot) {
|
|
19
|
-
const runtimePath = path.join(packageRoot, "hooks", "openclaw", "cortex-memory", "runtime.mjs");
|
|
20
|
-
if (existsSync(runtimePath)) {
|
|
21
|
-
candidates.add(pathToFileURL(runtimePath).href);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
function addAncestorCandidates(candidates, startPath) {
|
|
25
|
-
let current = path.resolve(startPath);
|
|
26
|
-
let previous = "";
|
|
27
|
-
for (let i = 0; i < 6 && current !== previous; i++) {
|
|
28
|
-
addRuntimeCandidate(candidates, current);
|
|
29
|
-
previous = current;
|
|
30
|
-
current = path.dirname(current);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
function collectRuntimeCandidates() {
|
|
34
|
-
const candidates = new Set();
|
|
35
|
-
// 1. Relative path (works when running from within npm package tree)
|
|
36
|
-
candidates.add(new URL("../../hooks/openclaw/cortex-memory/runtime.mjs", import.meta.url).href);
|
|
37
|
-
// 2. Config file override (reads path from ~/.shieldcortex/config.json instead of env var)
|
|
38
|
-
try {
|
|
39
|
-
const cfgPath = path.join(homedir(), ".shieldcortex", "config.json");
|
|
40
|
-
if (existsSync(cfgPath)) {
|
|
41
|
-
const cfg = JSON.parse(readFileSync(cfgPath, "utf-8"));
|
|
42
|
-
if (cfg.installRoot)
|
|
43
|
-
addRuntimeCandidate(candidates, cfg.installRoot);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
catch { /* no config */ }
|
|
47
|
-
// 3. Walk up from current file location
|
|
48
|
-
addAncestorCandidates(candidates, path.dirname(fileURLToPath(import.meta.url)));
|
|
49
|
-
// 4. Resolve via common bin symlink paths (no child_process needed)
|
|
50
|
-
for (const binDir of ["/usr/local/bin", "/opt/homebrew/bin", path.join(homedir(), ".npm-global", "bin")]) {
|
|
51
|
-
const binPath = path.join(binDir, "shieldcortex");
|
|
52
|
-
try {
|
|
53
|
-
if (existsSync(binPath))
|
|
54
|
-
addAncestorCandidates(candidates, realpathSync(binPath));
|
|
55
|
-
}
|
|
56
|
-
catch { /* broken symlink */ }
|
|
57
|
-
}
|
|
58
|
-
// 5. Common global install paths (covers npm root -g results without spawning npm)
|
|
59
|
-
for (const root of [
|
|
60
|
-
"/usr/lib/node_modules/shieldcortex",
|
|
61
|
-
"/usr/local/lib/node_modules/shieldcortex",
|
|
62
|
-
"/opt/homebrew/lib/node_modules/shieldcortex",
|
|
63
|
-
path.join(homedir(), ".npm-global", "lib", "node_modules", "shieldcortex"),
|
|
64
|
-
path.join(homedir(), ".nvm", "versions", "node"), // nvm users
|
|
65
|
-
]) {
|
|
66
|
-
if (root.includes(".nvm")) {
|
|
67
|
-
// For nvm, check the current symlink
|
|
68
|
-
try {
|
|
69
|
-
const currentNode = path.join(homedir(), ".nvm", "current", "lib", "node_modules", "shieldcortex");
|
|
70
|
-
addRuntimeCandidate(candidates, currentNode);
|
|
71
|
-
}
|
|
72
|
-
catch { /* no nvm */ }
|
|
73
|
-
}
|
|
74
|
-
else {
|
|
75
|
-
addRuntimeCandidate(candidates, root);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
return [...candidates];
|
|
79
|
-
}
|
|
80
|
-
async function getRuntime() {
|
|
81
|
-
if (!runtimePromise) {
|
|
82
|
-
runtimePromise = (async () => {
|
|
83
|
-
const tried = [];
|
|
84
|
-
let lastError = null;
|
|
85
|
-
for (const candidate of collectRuntimeCandidates()) {
|
|
86
|
-
tried.push(candidate);
|
|
87
|
-
try {
|
|
88
|
-
const mod = await import(candidate);
|
|
89
|
-
if (typeof mod.createOpenClawRuntime === "function") {
|
|
90
|
-
return mod.createOpenClawRuntime({ logPrefix: "[shieldcortex]" });
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
catch (error) {
|
|
94
|
-
lastError = error;
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
const detail = lastError instanceof Error ? lastError.message : String(lastError ?? "unknown error");
|
|
98
|
-
throw new Error(`Could not load OpenClaw runtime. Tried: ${tried.join(", ")}. Last error: ${detail}`);
|
|
99
|
-
})();
|
|
100
|
-
}
|
|
101
|
-
return runtimePromise;
|
|
102
|
-
}
|
|
103
|
-
const PLUGIN_ID = "shieldcortex-realtime";
|
|
104
|
-
const PLUGIN_PACKAGE_NAME = "@drakon-systems/shieldcortex-realtime";
|
|
105
|
-
const PLUGIN_CONFIG_UI_HINTS = {
|
|
106
|
-
binaryPath: {
|
|
107
|
-
label: "ShieldCortex Binary Path",
|
|
108
|
-
help: "Optional absolute path to the shieldcortex CLI when it is not on PATH.",
|
|
109
|
-
placeholder: "/usr/local/bin/shieldcortex",
|
|
110
|
-
advanced: true,
|
|
111
|
-
},
|
|
112
|
-
cloudApiKey: {
|
|
113
|
-
label: "Cloud API Key",
|
|
114
|
-
help: "Optional ShieldCortex Cloud API key used for realtime threat forwarding.",
|
|
115
|
-
sensitive: true,
|
|
116
|
-
placeholder: "sc_...",
|
|
117
|
-
},
|
|
118
|
-
cloudBaseUrl: {
|
|
119
|
-
label: "Cloud Base URL",
|
|
120
|
-
help: "Override the ShieldCortex Cloud API base URL if you use a self-hosted or staging endpoint.",
|
|
121
|
-
placeholder: "https://api.shieldcortex.ai",
|
|
122
|
-
advanced: true,
|
|
123
|
-
},
|
|
124
|
-
openclawAutoMemory: {
|
|
125
|
-
label: "Auto Memory Extraction",
|
|
126
|
-
help: "Extract high-signal decisions and learnings from LLM output into ShieldCortex memory.",
|
|
127
|
-
},
|
|
128
|
-
openclawAutoMemoryDedupe: {
|
|
129
|
-
label: "Dedupe Auto Memory",
|
|
130
|
-
help: "Skip near-duplicate memories before they are written to ShieldCortex.",
|
|
131
|
-
advanced: true,
|
|
132
|
-
},
|
|
133
|
-
openclawAutoMemoryNoveltyThreshold: {
|
|
134
|
-
label: "Novelty Threshold",
|
|
135
|
-
help: "Similarity threshold for duplicate suppression. Higher values keep more memories.",
|
|
136
|
-
advanced: true,
|
|
137
|
-
},
|
|
138
|
-
openclawAutoMemoryMaxRecent: {
|
|
139
|
-
label: "Recent Memory Cache Size",
|
|
140
|
-
help: "How many recent extracted memories to keep in the dedupe cache.",
|
|
141
|
-
advanced: true,
|
|
142
|
-
},
|
|
143
|
-
};
|
|
144
|
-
const PLUGIN_CONFIG_JSON_SCHEMA = {
|
|
145
|
-
type: "object",
|
|
146
|
-
additionalProperties: false,
|
|
147
|
-
properties: {
|
|
148
|
-
enabled: { type: "boolean" },
|
|
149
|
-
binaryPath: { type: "string" },
|
|
150
|
-
cloudApiKey: { type: "string" },
|
|
151
|
-
cloudBaseUrl: { type: "string" },
|
|
152
|
-
openclawAutoMemory: { type: "boolean" },
|
|
153
|
-
openclawAutoMemoryDedupe: { type: "boolean" },
|
|
154
|
-
openclawAutoMemoryNoveltyThreshold: { type: "number", minimum: 0.6, maximum: 0.99 },
|
|
155
|
-
openclawAutoMemoryMaxRecent: { type: "integer", minimum: 50, maximum: 1000 },
|
|
156
|
-
},
|
|
157
|
-
};
|
|
158
|
-
let _config = null;
|
|
159
|
-
// Identity of the shield config we last merged from. The runtime's
|
|
160
|
-
// loadShieldConfig() returns the same parsed object until the file's mtime
|
|
161
|
-
// advances; using reference equality lets us re-merge precisely when the
|
|
162
|
-
// underlying config has actually changed (dashboard / CLI write).
|
|
163
|
-
let _lastShieldConfigRef = null;
|
|
164
|
-
let _configOverride = null;
|
|
165
|
-
let _version = "0.0.0";
|
|
166
|
-
try {
|
|
167
|
-
// Try package.json first, then openclaw.plugin.json (the manifest IS copied to extensions/)
|
|
168
|
-
for (const candidateUrl of [
|
|
169
|
-
new URL("./package.json", import.meta.url),
|
|
170
|
-
new URL("../../package.json", import.meta.url),
|
|
171
|
-
new URL("./openclaw.plugin.json", import.meta.url),
|
|
172
|
-
]) {
|
|
173
|
-
try {
|
|
174
|
-
const data = JSON.parse(readFileSync(candidateUrl, "utf-8"));
|
|
175
|
-
if (typeof data.version === "string" && data.version.trim()) {
|
|
176
|
-
_version = data.version;
|
|
177
|
-
break;
|
|
178
|
-
}
|
|
179
|
-
}
|
|
180
|
-
catch {
|
|
181
|
-
// try the next candidate
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
catch { /* fallback */ }
|
|
186
|
-
let _registered = false;
|
|
187
|
-
function normaliseConfig(raw) {
|
|
188
|
-
if (!raw || typeof raw !== "object" || Array.isArray(raw))
|
|
189
|
-
return {};
|
|
190
|
-
const value = raw;
|
|
191
|
-
const config = {};
|
|
192
|
-
if (typeof value.cloudApiKey === "string" && value.cloudApiKey.trim()) {
|
|
193
|
-
config.cloudApiKey = value.cloudApiKey.trim();
|
|
194
|
-
}
|
|
195
|
-
if (typeof value.cloudBaseUrl === "string" && value.cloudBaseUrl.trim()) {
|
|
196
|
-
config.cloudBaseUrl = value.cloudBaseUrl.trim();
|
|
197
|
-
}
|
|
198
|
-
if (typeof value.binaryPath === "string" && value.binaryPath.trim()) {
|
|
199
|
-
config.binaryPath = value.binaryPath.trim();
|
|
200
|
-
}
|
|
201
|
-
if (typeof value.openclawAutoMemory === "boolean") {
|
|
202
|
-
config.openclawAutoMemory = value.openclawAutoMemory;
|
|
203
|
-
}
|
|
204
|
-
if (typeof value.openclawAutoMemoryDedupe === "boolean") {
|
|
205
|
-
config.openclawAutoMemoryDedupe = value.openclawAutoMemoryDedupe;
|
|
206
|
-
}
|
|
207
|
-
if (typeof value.openclawAutoMemoryNoveltyThreshold === "number" && !Number.isNaN(value.openclawAutoMemoryNoveltyThreshold)) {
|
|
208
|
-
config.openclawAutoMemoryNoveltyThreshold = clamp(value.openclawAutoMemoryNoveltyThreshold, 0.6, 0.99);
|
|
209
|
-
}
|
|
210
|
-
if (typeof value.openclawAutoMemoryMaxRecent === "number" && !Number.isNaN(value.openclawAutoMemoryMaxRecent)) {
|
|
211
|
-
config.openclawAutoMemoryMaxRecent = Math.floor(clamp(value.openclawAutoMemoryMaxRecent, 50, 1000));
|
|
212
|
-
}
|
|
213
|
-
return config;
|
|
214
|
-
}
|
|
215
|
-
function extractPluginConfig(rootConfig) {
|
|
216
|
-
if (!rootConfig || typeof rootConfig !== "object" || Array.isArray(rootConfig))
|
|
217
|
-
return {};
|
|
218
|
-
const entries = rootConfig.plugins?.entries;
|
|
219
|
-
const pluginConfig = entries?.[PLUGIN_ID]?.config ??
|
|
220
|
-
entries?.[PLUGIN_PACKAGE_NAME]?.config;
|
|
221
|
-
return normaliseConfig(pluginConfig);
|
|
222
|
-
}
|
|
223
|
-
function applyPluginConfigOverride(api) {
|
|
224
|
-
const runtimeConfigApi = api.runtime?.config;
|
|
225
|
-
const runtimeConfig = typeof runtimeConfigApi?.current === "function"
|
|
226
|
-
? runtimeConfigApi.current()
|
|
227
|
-
: typeof runtimeConfigApi?.loadConfig === "function"
|
|
228
|
-
? runtimeConfigApi.loadConfig()
|
|
229
|
-
: api.config;
|
|
230
|
-
const pluginConfig = extractPluginConfig(runtimeConfig);
|
|
231
|
-
if (Object.keys(pluginConfig).length === 0)
|
|
232
|
-
return;
|
|
233
|
-
_configOverride = {
|
|
234
|
-
...(_configOverride ?? {}),
|
|
235
|
-
...pluginConfig,
|
|
236
|
-
};
|
|
237
|
-
// Override changed — invalidate so loadConfig() re-merges with new override.
|
|
238
|
-
_config = null;
|
|
239
|
-
_lastShieldConfigRef = null;
|
|
240
|
-
}
|
|
241
|
-
async function loadConfig() {
|
|
242
|
-
const shieldConfigRaw = await (await getRuntime()).loadShieldConfig();
|
|
243
|
-
if (_config && shieldConfigRaw === _lastShieldConfigRef)
|
|
244
|
-
return _config;
|
|
245
|
-
_lastShieldConfigRef = shieldConfigRaw;
|
|
246
|
-
_config = {
|
|
247
|
-
...normaliseConfig(shieldConfigRaw),
|
|
248
|
-
...(_configOverride ?? {}),
|
|
249
|
-
};
|
|
250
|
-
return _config;
|
|
251
|
-
}
|
|
252
|
-
function isAutoMemoryEnabled(config) {
|
|
253
|
-
return config.openclawAutoMemory === true;
|
|
254
|
-
}
|
|
255
|
-
function isAutoMemoryDedupeEnabled(config) {
|
|
256
|
-
return config.openclawAutoMemoryDedupe !== false;
|
|
257
|
-
}
|
|
258
|
-
async function callCortex(tool, args = {}) {
|
|
259
|
-
return (await getRuntime()).callCortex(tool, args);
|
|
260
|
-
}
|
|
261
|
-
// ==================== REMOTE SCANNING ====================
|
|
262
|
-
async function scanRealtimeContent(text) {
|
|
263
|
-
const response = await callCortex("scan_tool_response", {
|
|
264
|
-
toolName: "openclaw-realtime",
|
|
265
|
-
content: text,
|
|
266
|
-
mode: "advisory",
|
|
267
|
-
});
|
|
268
|
-
if (!response) {
|
|
269
|
-
return { clean: true, summary: "scan unavailable" };
|
|
270
|
-
}
|
|
271
|
-
const cleanMatch = response.match(/\*\*Clean:\*\*\s*(Yes|No)/i);
|
|
272
|
-
const riskMatch = response.match(/\*\*Risk Level:\*\*\s*([A-Za-z]+)/i);
|
|
273
|
-
const detectionsMatch = response.match(/\*\*Detections:\*\*\s*(\d+)/i);
|
|
274
|
-
const clean = cleanMatch ? /yes/i.test(cleanMatch[1]) : true;
|
|
275
|
-
const risk = riskMatch?.[1] ?? "unknown";
|
|
276
|
-
const detections = detectionsMatch?.[1];
|
|
277
|
-
const summary = detections ? `${risk} (${detections} detections)` : risk;
|
|
278
|
-
return { clean, summary };
|
|
279
|
-
}
|
|
280
|
-
// ==================== CONTENT PATTERNS ====================
|
|
281
|
-
const PATTERNS = {
|
|
282
|
-
architecture: [/\b(?:architecture|designed|structured)\b.*?(?:uses?|is|with)\b/i, /\b(?:decided?\s+to|going\s+with|chose)\b/i],
|
|
283
|
-
error: [/\b(?:fixed|resolved|solved)\s+(?:by|with|using)\b/i, /\b(?:solution|fix|root\s*cause)\s+(?:was|is)\b/i],
|
|
284
|
-
learning: [/\b(?:learned|discovered|turns?\s+out|figured\s+out|realized)\b/i],
|
|
285
|
-
preference: [
|
|
286
|
-
/\b(?:I|we|you\s+should)\s+(?:always|never)\b/i,
|
|
287
|
-
/\b(?:always\s+use|never\s+use|never\s+commit)\b/i,
|
|
288
|
-
/\bprefer(?:\s+to)?\s+\w+/i,
|
|
289
|
-
/\bshould\s+always\b/i,
|
|
290
|
-
],
|
|
291
|
-
note: [/\b(?:important|remember|key\s+point)\s*:/i],
|
|
292
|
-
};
|
|
293
|
-
function extractMemories(texts) {
|
|
294
|
-
const out = [];
|
|
295
|
-
const seen = new Set();
|
|
296
|
-
for (const text of texts) {
|
|
297
|
-
if (text.length < 30)
|
|
298
|
-
continue;
|
|
299
|
-
for (const [cat, pats] of Object.entries(PATTERNS)) {
|
|
300
|
-
if (pats.some(p => p.test(text))) {
|
|
301
|
-
const title = text.slice(0, 80).replace(/["\n]/g, " ").trim();
|
|
302
|
-
if (!seen.has(title)) {
|
|
303
|
-
seen.add(title);
|
|
304
|
-
out.push({ title, content: text.slice(0, 500), category: cat });
|
|
305
|
-
}
|
|
306
|
-
break;
|
|
307
|
-
}
|
|
308
|
-
if (out.length >= 3)
|
|
309
|
-
break;
|
|
310
|
-
}
|
|
311
|
-
if (out.length >= 3)
|
|
312
|
-
break;
|
|
313
|
-
}
|
|
314
|
-
return out;
|
|
315
|
-
}
|
|
316
|
-
// ==================== HELPERS ====================
|
|
317
|
-
function extractUserContent(msgs) {
|
|
318
|
-
const out = [];
|
|
319
|
-
for (const msg of msgs) {
|
|
320
|
-
if (!msg || typeof msg !== "object")
|
|
321
|
-
continue;
|
|
322
|
-
const m = msg;
|
|
323
|
-
if (m.role !== "user")
|
|
324
|
-
continue;
|
|
325
|
-
if (typeof m.content === "string")
|
|
326
|
-
out.push(m.content);
|
|
327
|
-
else if (Array.isArray(m.content))
|
|
328
|
-
for (const b of m.content)
|
|
329
|
-
if (b?.type === "text")
|
|
330
|
-
out.push(b.text);
|
|
331
|
-
}
|
|
332
|
-
return out;
|
|
333
|
-
}
|
|
334
|
-
const AUDIT_DIR = path.join(homedir(), ".shieldcortex", "audit");
|
|
335
|
-
const NOVELTY_CACHE_FILE = path.join(homedir(), ".shieldcortex", "openclaw-memory-cache.json");
|
|
336
|
-
const DEFAULT_NOVELTY_THRESHOLD = 0.88;
|
|
337
|
-
const DEFAULT_MAX_RECENT = 300;
|
|
338
|
-
const MIN_NOVELTY_CHARS = 40;
|
|
339
|
-
async function auditLog(entry) {
|
|
340
|
-
try {
|
|
341
|
-
await fs.mkdir(AUDIT_DIR, { recursive: true });
|
|
342
|
-
await fs.appendFile(path.join(AUDIT_DIR, `realtime-${new Date().toISOString().slice(0, 10)}.jsonl`), JSON.stringify(entry) + "\n");
|
|
343
|
-
}
|
|
344
|
-
catch { }
|
|
345
|
-
}
|
|
346
|
-
function normalizeMemoryText(text) {
|
|
347
|
-
return String(text || "")
|
|
348
|
-
.toLowerCase()
|
|
349
|
-
.replace(/[`"'\\]/g, " ")
|
|
350
|
-
.replace(/https?:\/\/\S+/g, " ")
|
|
351
|
-
.replace(/[^a-z0-9\s]/g, " ")
|
|
352
|
-
.replace(/\s+/g, " ")
|
|
353
|
-
.trim();
|
|
354
|
-
}
|
|
355
|
-
function hashToken(token) {
|
|
356
|
-
return createHash("sha1").update(token).digest("hex").slice(0, 12);
|
|
357
|
-
}
|
|
358
|
-
function buildTokenHashes(normalized) {
|
|
359
|
-
const words = normalized.split(" ").filter((w) => w.length >= 3);
|
|
360
|
-
const set = new Set();
|
|
361
|
-
for (let i = 0; i < words.length; i++) {
|
|
362
|
-
set.add(hashToken(words[i]));
|
|
363
|
-
if (i < words.length - 1)
|
|
364
|
-
set.add(hashToken(`${words[i]}_${words[i + 1]}`));
|
|
365
|
-
}
|
|
366
|
-
return Array.from(set).slice(0, 200);
|
|
367
|
-
}
|
|
368
|
-
function jaccardSimilarity(a, b) {
|
|
369
|
-
if (a.size === 0 || b.size === 0)
|
|
370
|
-
return 0;
|
|
371
|
-
let intersection = 0;
|
|
372
|
-
for (const item of a) {
|
|
373
|
-
if (b.has(item))
|
|
374
|
-
intersection++;
|
|
375
|
-
}
|
|
376
|
-
const union = a.size + b.size - intersection;
|
|
377
|
-
return union === 0 ? 0 : intersection / union;
|
|
378
|
-
}
|
|
379
|
-
function clamp(value, min, max) {
|
|
380
|
-
return Math.max(min, Math.min(max, value));
|
|
381
|
-
}
|
|
382
|
-
async function loadNoveltyCache(maxRecent) {
|
|
383
|
-
try {
|
|
384
|
-
const raw = JSON.parse(await fs.readFile(NOVELTY_CACHE_FILE, "utf-8"));
|
|
385
|
-
if (!Array.isArray(raw))
|
|
386
|
-
return [];
|
|
387
|
-
return raw
|
|
388
|
-
.filter((entry) => entry && typeof entry.hash === "string" && Array.isArray(entry.tokenHashes))
|
|
389
|
-
.slice(0, maxRecent);
|
|
390
|
-
}
|
|
391
|
-
catch {
|
|
392
|
-
return [];
|
|
393
|
-
}
|
|
394
|
-
}
|
|
395
|
-
async function saveNoveltyCache(entries) {
|
|
396
|
-
await fs.mkdir(path.dirname(NOVELTY_CACHE_FILE), { recursive: true });
|
|
397
|
-
await fs.writeFile(NOVELTY_CACHE_FILE, JSON.stringify(entries, null, 2) + "\n", "utf-8");
|
|
398
|
-
}
|
|
399
|
-
function inspectNovelty(content, entries, threshold) {
|
|
400
|
-
const normalized = normalizeMemoryText(content);
|
|
401
|
-
if (normalized.length < MIN_NOVELTY_CHARS) {
|
|
402
|
-
return { allow: true, contentHash: null, tokenHashes: [] };
|
|
403
|
-
}
|
|
404
|
-
const contentHash = createHash("sha256").update(normalized).digest("hex").slice(0, 24);
|
|
405
|
-
if (entries.some((entry) => entry.hash === contentHash)) {
|
|
406
|
-
return { allow: false, contentHash, tokenHashes: [], reason: "exact duplicate" };
|
|
407
|
-
}
|
|
408
|
-
const tokenHashes = buildTokenHashes(normalized);
|
|
409
|
-
const currentSet = new Set(tokenHashes);
|
|
410
|
-
for (const entry of entries) {
|
|
411
|
-
const score = jaccardSimilarity(currentSet, new Set(entry.tokenHashes || []));
|
|
412
|
-
if (score >= threshold) {
|
|
413
|
-
return {
|
|
414
|
-
allow: false,
|
|
415
|
-
contentHash,
|
|
416
|
-
tokenHashes,
|
|
417
|
-
reason: `near duplicate (similarity ${score.toFixed(2)})`,
|
|
418
|
-
};
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
return { allow: true, contentHash, tokenHashes };
|
|
422
|
-
}
|
|
423
|
-
async function createNoveltyGate(config) {
|
|
424
|
-
const thresholdRaw = Number(config.openclawAutoMemoryNoveltyThreshold);
|
|
425
|
-
const maxRecentRaw = Number(config.openclawAutoMemoryMaxRecent);
|
|
426
|
-
const threshold = Number.isFinite(thresholdRaw)
|
|
427
|
-
? clamp(thresholdRaw, 0.6, 0.99)
|
|
428
|
-
: DEFAULT_NOVELTY_THRESHOLD;
|
|
429
|
-
const maxRecent = Number.isFinite(maxRecentRaw)
|
|
430
|
-
? Math.floor(clamp(maxRecentRaw, 50, 1000))
|
|
431
|
-
: DEFAULT_MAX_RECENT;
|
|
432
|
-
const enabled = isAutoMemoryDedupeEnabled(config);
|
|
433
|
-
const entries = enabled ? await loadNoveltyCache(maxRecent) : [];
|
|
434
|
-
let dirty = false;
|
|
435
|
-
return {
|
|
436
|
-
inspect(content) {
|
|
437
|
-
if (!enabled)
|
|
438
|
-
return { allow: true, contentHash: null, tokenHashes: [] };
|
|
439
|
-
return inspectNovelty(content, entries, threshold);
|
|
440
|
-
},
|
|
441
|
-
remember(memory, novelty) {
|
|
442
|
-
if (!enabled || !novelty.contentHash || novelty.tokenHashes.length === 0)
|
|
443
|
-
return;
|
|
444
|
-
entries.unshift({
|
|
445
|
-
hash: novelty.contentHash,
|
|
446
|
-
tokenHashes: novelty.tokenHashes,
|
|
447
|
-
title: String(memory.title || "").slice(0, 120),
|
|
448
|
-
category: String(memory.category || "note"),
|
|
449
|
-
createdAt: new Date().toISOString(),
|
|
450
|
-
});
|
|
451
|
-
if (entries.length > maxRecent)
|
|
452
|
-
entries.length = maxRecent;
|
|
453
|
-
dirty = true;
|
|
454
|
-
},
|
|
455
|
-
async flush() {
|
|
456
|
-
if (!enabled || !dirty)
|
|
457
|
-
return;
|
|
458
|
-
await saveNoveltyCache(entries);
|
|
459
|
-
},
|
|
460
|
-
};
|
|
461
|
-
}
|
|
462
|
-
// ==================== HOOK HANDLERS ====================
|
|
463
|
-
// Skip scanning internal OpenClaw content (boot checks, system prompts, heartbeats)
|
|
464
|
-
const SKIP_PATTERNS = [
|
|
465
|
-
/^You are running a boot check/i,
|
|
466
|
-
/^Read HEARTBEAT\.md/i,
|
|
467
|
-
/^System:/,
|
|
468
|
-
/^\[System Message\]/,
|
|
469
|
-
/^HEARTBEAT_OK$/,
|
|
470
|
-
/^\[(?:Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s/, // Timestamped system events
|
|
471
|
-
/^A subagent task/i,
|
|
472
|
-
/subagent.*completed/i,
|
|
473
|
-
];
|
|
474
|
-
function isInternalContent(text) {
|
|
475
|
-
return SKIP_PATTERNS.some(p => p.test(text.trim()));
|
|
476
|
-
}
|
|
477
|
-
function handleLlmInput(event, ctx) {
|
|
478
|
-
// Fire and forget
|
|
479
|
-
(async () => {
|
|
480
|
-
try {
|
|
481
|
-
// Only scan user content, skip system/boot/heartbeat prompts
|
|
482
|
-
const userTexts = extractUserContent(event.historyMessages).slice(-5);
|
|
483
|
-
const texts = [event.prompt, ...userTexts].filter(t => t && !isInternalContent(t));
|
|
484
|
-
for (const text of texts) {
|
|
485
|
-
if (!text || text.length < 10)
|
|
486
|
-
continue;
|
|
487
|
-
const result = await scanRealtimeContent(text);
|
|
488
|
-
if (!result.clean) {
|
|
489
|
-
console.warn(`[shieldcortex] ⚠️ Threat in LLM input: ${result.summary}`);
|
|
490
|
-
const entry = {
|
|
491
|
-
type: "threat", hook: "llm_input", sessionId: event.sessionId,
|
|
492
|
-
model: event.model, reason: result.summary,
|
|
493
|
-
preview: text.slice(0, 100), ts: new Date().toISOString(),
|
|
494
|
-
};
|
|
495
|
-
auditLog(entry);
|
|
496
|
-
loadConfig()
|
|
497
|
-
.then(cfg => cloudSync({ ...entry, content: text.slice(0, 200) }, cfg))
|
|
498
|
-
.catch(() => { });
|
|
499
|
-
}
|
|
500
|
-
}
|
|
501
|
-
}
|
|
502
|
-
catch (e) {
|
|
503
|
-
console.error("[shieldcortex] llm_input error:", e instanceof Error ? e.message : String(e));
|
|
504
|
-
}
|
|
505
|
-
})();
|
|
506
|
-
}
|
|
507
|
-
// Skip text blocks that are ShieldCortex/OpenClaw tool-result pass-throughs
|
|
508
|
-
function isToolResultContent(text) {
|
|
509
|
-
// ShieldCortex recall returns "Found N memories:" header
|
|
510
|
-
if (/^Found \d+ memor(?:y|ies):/m.test(text))
|
|
511
|
-
return true;
|
|
512
|
-
// ShieldCortex get_context returns structured context blocks
|
|
513
|
-
if (/^## (?:Architecture|Patterns|Preferences|Errors|Context)/m.test(text))
|
|
514
|
-
return true;
|
|
515
|
-
// OpenClaw tool-result wrapper markers
|
|
516
|
-
if (/^\[tool_result\b/i.test(text.trim()))
|
|
517
|
-
return true;
|
|
518
|
-
if (/^<tool_result\b/i.test(text.trim()))
|
|
519
|
-
return true;
|
|
520
|
-
return false;
|
|
521
|
-
}
|
|
522
|
-
function handleLlmOutput(event, ctx) {
|
|
523
|
-
// Fire and forget
|
|
524
|
-
(async () => {
|
|
525
|
-
try {
|
|
526
|
-
const config = await loadConfig();
|
|
527
|
-
if (!isAutoMemoryEnabled(config))
|
|
528
|
-
return;
|
|
529
|
-
const texts = event.assistantTexts
|
|
530
|
-
.filter(t => t && t.length >= 30)
|
|
531
|
-
.filter(t => !isToolResultContent(t));
|
|
532
|
-
if (!texts.length)
|
|
533
|
-
return;
|
|
534
|
-
const memories = extractMemories(texts);
|
|
535
|
-
if (!memories.length)
|
|
536
|
-
return;
|
|
537
|
-
const noveltyGate = await createNoveltyGate(config);
|
|
538
|
-
let saved = 0;
|
|
539
|
-
let skipped = 0;
|
|
540
|
-
for (const mem of memories) {
|
|
541
|
-
const novelty = noveltyGate.inspect(mem.content);
|
|
542
|
-
if (!novelty.allow) {
|
|
543
|
-
skipped++;
|
|
544
|
-
continue;
|
|
545
|
-
}
|
|
546
|
-
const r = await callCortex("remember", {
|
|
547
|
-
title: mem.title, content: mem.content, category: mem.category,
|
|
548
|
-
project: ctx.agentId || "openclaw", scope: "global",
|
|
549
|
-
importance: "normal", tags: "auto-extracted,realtime-plugin,llm-output",
|
|
550
|
-
sourceType: "agent", sourceIdentifier: `openclaw-plugin:${event.sessionId}`,
|
|
551
|
-
sessionId: event.sessionId, agentId: ctx.agentId || "openclaw", workspaceDir: ctx.workspaceDir || "",
|
|
552
|
-
});
|
|
553
|
-
if (r) {
|
|
554
|
-
saved++;
|
|
555
|
-
noveltyGate.remember(mem, novelty);
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
await noveltyGate.flush();
|
|
559
|
-
if (saved) {
|
|
560
|
-
console.log(`[shieldcortex] Extracted ${saved} memor${saved === 1 ? "y" : "ies"} from LLM output (${skipped} duplicates skipped)`);
|
|
561
|
-
auditLog({ type: "memory", hook: "llm_output", sessionId: event.sessionId, count: saved, skipped, ts: new Date().toISOString() });
|
|
562
|
-
}
|
|
563
|
-
}
|
|
564
|
-
catch (e) {
|
|
565
|
-
console.error("[shieldcortex] llm_output error:", e instanceof Error ? e.message : String(e));
|
|
566
|
-
}
|
|
567
|
-
})();
|
|
568
|
-
}
|
|
569
|
-
// ==================== PLUGIN EXPORT ====================
|
|
570
|
-
export default {
|
|
571
|
-
id: PLUGIN_ID,
|
|
572
|
-
name: "ShieldCortex Real-time Scanner",
|
|
573
|
-
description: "Real-time defence scanning on LLM inputs with optional memory extraction from outputs",
|
|
574
|
-
version: _version,
|
|
575
|
-
configSchema: {
|
|
576
|
-
parse(value) {
|
|
577
|
-
return normaliseConfig(value);
|
|
578
|
-
},
|
|
579
|
-
uiHints: PLUGIN_CONFIG_UI_HINTS,
|
|
580
|
-
jsonSchema: PLUGIN_CONFIG_JSON_SCHEMA,
|
|
581
|
-
},
|
|
582
|
-
register(api) {
|
|
583
|
-
if (_registered)
|
|
584
|
-
return;
|
|
585
|
-
_registered = true;
|
|
586
|
-
try {
|
|
587
|
-
applyPluginConfigOverride(api);
|
|
588
|
-
// --- Interceptor (lazy init) ---
|
|
589
|
-
let interceptorReady = null;
|
|
590
|
-
let interceptorInitAttempted = false;
|
|
591
|
-
async function initInterceptor() {
|
|
592
|
-
if (interceptorInitAttempted)
|
|
593
|
-
return interceptorReady;
|
|
594
|
-
interceptorInitAttempted = true;
|
|
595
|
-
try {
|
|
596
|
-
const scConfig = await loadConfig();
|
|
597
|
-
const rawInterceptorConfig = scConfig.interceptor;
|
|
598
|
-
const interceptorConfig = {
|
|
599
|
-
...DEFAULT_INTERCEPTOR_CONFIG,
|
|
600
|
-
...(rawInterceptorConfig && typeof rawInterceptorConfig === 'object' ? {
|
|
601
|
-
enabled: rawInterceptorConfig.enabled ?? DEFAULT_INTERCEPTOR_CONFIG.enabled,
|
|
602
|
-
severityActions: { ...DEFAULT_INTERCEPTOR_CONFIG.severityActions, ...rawInterceptorConfig.severityActions },
|
|
603
|
-
failurePolicy: { ...DEFAULT_INTERCEPTOR_CONFIG.failurePolicy, ...rawInterceptorConfig.failurePolicy },
|
|
604
|
-
} : {}),
|
|
605
|
-
logger: { info: api.logger?.info ?? console.log, warn: api.logger?.warn ?? console.warn },
|
|
606
|
-
};
|
|
607
|
-
if (!interceptorConfig.enabled)
|
|
608
|
-
return null;
|
|
609
|
-
// Dynamic import with string variable to prevent TypeScript from resolving
|
|
610
|
-
// at compile time — 'shieldcortex/defence' only exists at runtime when the
|
|
611
|
-
// package is installed globally, not during CI builds of the plugin itself.
|
|
612
|
-
let defenceMod;
|
|
613
|
-
try {
|
|
614
|
-
const defenceModPath = 'shieldcortex' + '/defence';
|
|
615
|
-
defenceMod = await import(/* webpackIgnore: true */ defenceModPath);
|
|
616
|
-
}
|
|
617
|
-
catch (importErr) {
|
|
618
|
-
// Stack overflow or missing module — interceptor can't load
|
|
619
|
-
api.logger?.warn?.(`[shieldcortex] Cannot load defence module: ${importErr instanceof Error ? importErr.message : importErr}`);
|
|
620
|
-
return null;
|
|
621
|
-
}
|
|
622
|
-
if (typeof defenceMod.runDefencePipeline !== 'function')
|
|
623
|
-
return null;
|
|
624
|
-
interceptorReady = createInterceptor(interceptorConfig, defenceMod.runDefencePipeline, {
|
|
625
|
-
onAuditEntry: (entry) => syncInterceptEvent(entry, {
|
|
626
|
-
cloudApiKey: scConfig.cloudApiKey ?? '',
|
|
627
|
-
cloudBaseUrl: scConfig.cloudBaseUrl ?? 'https://api.shieldcortex.ai',
|
|
628
|
-
cloudEnabled: scConfig.cloudEnabled ?? false,
|
|
629
|
-
}),
|
|
630
|
-
});
|
|
631
|
-
api.logger?.info?.('[shieldcortex] Interceptor active — watching: remember, mcp__memory__remember');
|
|
632
|
-
return interceptorReady;
|
|
633
|
-
}
|
|
634
|
-
catch (err) {
|
|
635
|
-
api.logger?.warn?.(`[shieldcortex] Interceptor init failed: ${err instanceof Error ? err.message : err}`);
|
|
636
|
-
return null;
|
|
637
|
-
}
|
|
638
|
-
}
|
|
639
|
-
// Register before_tool_call with lazy-init wrapper
|
|
640
|
-
api.registerHook('before_tool_call', async (context) => {
|
|
641
|
-
const interceptor = await initInterceptor();
|
|
642
|
-
if (!interceptor)
|
|
643
|
-
return;
|
|
644
|
-
try {
|
|
645
|
-
await interceptor.handleToolCall(context);
|
|
646
|
-
}
|
|
647
|
-
catch (err) {
|
|
648
|
-
// Intentional blocks from the interceptor (ShieldCortex: ...) should propagate
|
|
649
|
-
if (err instanceof Error && err.message.startsWith('ShieldCortex:'))
|
|
650
|
-
throw err;
|
|
651
|
-
// Unexpected errors (DB crash, etc.) — log and allow the tool call through
|
|
652
|
-
api.logger?.warn?.(`[shieldcortex] Interceptor error (allowing tool call): ${err instanceof Error ? err.message : err}`);
|
|
653
|
-
}
|
|
654
|
-
}, {
|
|
655
|
-
name: 'shieldcortex-intercept-tool',
|
|
656
|
-
description: 'Active threat gating on tool calls',
|
|
657
|
-
});
|
|
658
|
-
// Try to register session_end for cache cleanup
|
|
659
|
-
try {
|
|
660
|
-
api.registerHook('session_end', () => { interceptorReady?.resetSession(); }, {
|
|
661
|
-
name: 'shieldcortex-session-cleanup',
|
|
662
|
-
description: 'Clear interceptor deny cache on session end',
|
|
663
|
-
});
|
|
664
|
-
}
|
|
665
|
-
catch {
|
|
666
|
-
// session_end may not be a supported hook — TTL safety net handles this
|
|
667
|
-
}
|
|
668
|
-
// Explicit capability registration (replaces legacy api.on)
|
|
669
|
-
api.registerHook("llm_input", handleLlmInput, {
|
|
670
|
-
name: "shieldcortex-scan-input",
|
|
671
|
-
description: "Real-time threat scanning on LLM input",
|
|
672
|
-
});
|
|
673
|
-
api.registerHook("llm_output", handleLlmOutput, {
|
|
674
|
-
name: "shieldcortex-scan-output",
|
|
675
|
-
description: "Memory extraction from LLM output",
|
|
676
|
-
});
|
|
677
|
-
// Register a lightweight status command so the plugin is not hook-only
|
|
678
|
-
api.registerCommand({
|
|
679
|
-
name: "shieldcortex-status",
|
|
680
|
-
description: "Show ShieldCortex real-time scanner status",
|
|
681
|
-
async handler() {
|
|
682
|
-
const cfg = await loadConfig();
|
|
683
|
-
const autoMemory = isAutoMemoryEnabled(cfg) ? "on" : "off";
|
|
684
|
-
const dedupe = isAutoMemoryDedupeEnabled(cfg) ? "on" : "off";
|
|
685
|
-
const cloud = cfg.cloudApiKey ? "configured" : "not configured";
|
|
686
|
-
return {
|
|
687
|
-
text: `ShieldCortex v${_version}\n` +
|
|
688
|
-
` Hooks: llm_input (scan), llm_output (memory)\n` +
|
|
689
|
-
` Auto memory: ${autoMemory} | Dedupe: ${dedupe}\n` +
|
|
690
|
-
` Cloud sync: ${cloud}`,
|
|
691
|
-
};
|
|
692
|
-
},
|
|
693
|
-
});
|
|
694
|
-
api.logger.info(`[shieldcortex] v${_version} registered (llm_input + llm_output + before_tool_call + /shieldcortex-status)`);
|
|
695
|
-
}
|
|
696
|
-
catch (err) {
|
|
697
|
-
// Plugin must never block channel startup — warn and bail gracefully
|
|
698
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
699
|
-
console.warn(`[shieldcortex] WARNING: Plugin failed to initialize: ${msg}`);
|
|
700
|
-
console.warn('[shieldcortex] Real-time scanning is disabled. Channels will start normally.');
|
|
701
|
-
}
|
|
702
|
-
},
|
|
703
|
-
};
|