shieldcortex 4.31.2 → 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 +21 -2
- package/dist/database/better-sqlite3-guard.js +29 -5
- package/dist/database/init.js +68 -16
- 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/{_j4TeMpss-w79QtNNWqZw → Ox9scglBehbbCk7DD8-Vn}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{_j4TeMpss-w79QtNNWqZw → Ox9scglBehbbCk7DD8-Vn}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{_j4TeMpss-w79QtNNWqZw → Ox9scglBehbbCk7DD8-Vn}/_ssgManifest.js +0 -0
|
@@ -1,11 +1,25 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tool Response Scanner
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Defence scanner for MCP tool outputs (read-path). Tool output is the #1 MCP
|
|
5
|
+
* attack surface, so the read path shares the WRITE-path detection surface
|
|
6
|
+
* instead of running a thinner pattern set:
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* - scanForInjection — Iron Dome regex set (named-pattern reporting)
|
|
9
|
+
* - detectInstructions — write-path instruction detector; folds cross-script
|
|
10
|
+
* homoglyphs and scans in windows (catches `ignorе …`)
|
|
11
|
+
* - detectEncoding — write-path encoding detector; decodes base64/hex/url
|
|
12
|
+
* blobs so a BARE blob that decodes to an injection is
|
|
13
|
+
* re-scanned on the plaintext (decode-and-rescan)
|
|
14
|
+
* - detectMarkdownImageExfil — markdown image whose URL smuggles data out
|
|
15
|
+
* - scanForCredentials — credential leak scanning (retained)
|
|
16
|
+
*
|
|
17
|
+
* It deliberately does NOT pull in the write-path's trust scoring, anomaly,
|
|
18
|
+
* privilege, fragmentation or sensitivity layers — those are write concerns.
|
|
19
|
+
*
|
|
20
|
+
* Advisory by default: logs threats but never blocks tool responses. Only the
|
|
21
|
+
* audit/event firewall_result reflects enforce mode; the scan itself never hard
|
|
22
|
+
* blocks tool execution.
|
|
9
23
|
*/
|
|
10
24
|
import type { ToolResponseScanResult } from './types.js';
|
|
11
25
|
/**
|
|
@@ -16,7 +30,9 @@ export declare function shouldScanToolResponse(toolName: string): boolean;
|
|
|
16
30
|
/**
|
|
17
31
|
* Scan a tool response for threats.
|
|
18
32
|
*
|
|
19
|
-
*
|
|
33
|
+
* Shares the write-path detection surface: Iron Dome injection patterns,
|
|
34
|
+
* instruction detection (with homoglyph folding + windowed scanning), encoding
|
|
35
|
+
* decode-and-rescan, markdown-image exfiltration, and credential leak detection.
|
|
20
36
|
* In advisory mode, threats are logged but the response is never blocked.
|
|
21
37
|
*/
|
|
22
38
|
export declare function scanToolResponse(toolName: string, content: string, mode?: 'advisory' | 'enforce'): ToolResponseScanResult;
|
|
@@ -1,17 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Tool Response Scanner
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Defence scanner for MCP tool outputs (read-path). Tool output is the #1 MCP
|
|
5
|
+
* attack surface, so the read path shares the WRITE-path detection surface
|
|
6
|
+
* instead of running a thinner pattern set:
|
|
7
7
|
*
|
|
8
|
-
*
|
|
8
|
+
* - scanForInjection — Iron Dome regex set (named-pattern reporting)
|
|
9
|
+
* - detectInstructions — write-path instruction detector; folds cross-script
|
|
10
|
+
* homoglyphs and scans in windows (catches `ignorе …`)
|
|
11
|
+
* - detectEncoding — write-path encoding detector; decodes base64/hex/url
|
|
12
|
+
* blobs so a BARE blob that decodes to an injection is
|
|
13
|
+
* re-scanned on the plaintext (decode-and-rescan)
|
|
14
|
+
* - detectMarkdownImageExfil — markdown image whose URL smuggles data out
|
|
15
|
+
* - scanForCredentials — credential leak scanning (retained)
|
|
16
|
+
*
|
|
17
|
+
* It deliberately does NOT pull in the write-path's trust scoring, anomaly,
|
|
18
|
+
* privilege, fragmentation or sensitivity layers — those are write concerns.
|
|
19
|
+
*
|
|
20
|
+
* Advisory by default: logs threats but never blocks tool responses. Only the
|
|
21
|
+
* audit/event firewall_result reflects enforce mode; the scan itself never hard
|
|
22
|
+
* blocks tool execution.
|
|
9
23
|
*/
|
|
10
24
|
import { scanForInjection } from './iron-dome/injection-scanner.js';
|
|
11
25
|
import { scanForCredentials } from './credential-leak/index.js';
|
|
26
|
+
import { detectInstructions } from './firewall/instruction-detector.js';
|
|
27
|
+
import { detectEncoding } from './firewall/encoding-detector.js';
|
|
28
|
+
import { detectMarkdownImageExfil } from './firewall/markdown-image-detector.js';
|
|
12
29
|
import { logAudit } from './audit/logger.js';
|
|
13
30
|
import { isDatabaseInitialized } from '../database/init.js';
|
|
14
31
|
import { getToolResponseScanConfig } from '../cloud/config.js';
|
|
32
|
+
import { persistEvent } from '../api/events.js';
|
|
33
|
+
// ../api/events.js is imported statically. Safe at module-eval time: there is no
|
|
34
|
+
// import cycle on this edge — events imports only an EventEmitter, getDatabase
|
|
35
|
+
// and types, never back into this module — and it does no work at import (no
|
|
36
|
+
// server/ws stack). persistEvent is only called inside scanToolResponse. The
|
|
37
|
+
// try/catch below stays — dashboard event persistence is best-effort and must
|
|
38
|
+
// never affect tool-response delivery.
|
|
15
39
|
// Tools that return memory/knowledge content (worth scanning)
|
|
16
40
|
const HIGH_RISK_TOOLS = new Set([
|
|
17
41
|
'recall',
|
|
@@ -46,7 +70,9 @@ export function shouldScanToolResponse(toolName) {
|
|
|
46
70
|
/**
|
|
47
71
|
* Scan a tool response for threats.
|
|
48
72
|
*
|
|
49
|
-
*
|
|
73
|
+
* Shares the write-path detection surface: Iron Dome injection patterns,
|
|
74
|
+
* instruction detection (with homoglyph folding + windowed scanning), encoding
|
|
75
|
+
* decode-and-rescan, markdown-image exfiltration, and credential leak detection.
|
|
50
76
|
* In advisory mode, threats are logged but the response is never blocked.
|
|
51
77
|
*/
|
|
52
78
|
export function scanToolResponse(toolName, content, mode) {
|
|
@@ -66,28 +92,70 @@ export function scanToolResponse(toolName, content, mode) {
|
|
|
66
92
|
auditId: -1,
|
|
67
93
|
};
|
|
68
94
|
}
|
|
69
|
-
// 1. Injection scan (Iron Dome patterns
|
|
95
|
+
// 1. Injection scan (Iron Dome named patterns — drives the `injection` field
|
|
96
|
+
// of the result and the human-readable summary).
|
|
70
97
|
const injection = scanForInjection(content);
|
|
71
|
-
// 2.
|
|
98
|
+
// 2. Write-path detectors (parity). detectInstructions folds homoglyphs and
|
|
99
|
+
// scans in windows; detectEncoding decodes base64/hex/url blobs.
|
|
100
|
+
const instructions = detectInstructions(content);
|
|
101
|
+
const encoding = detectEncoding(content);
|
|
102
|
+
// 2b. Decode-and-rescan: re-run instruction + credential detection on each
|
|
103
|
+
// decoded snippet so a BARE base64/hex blob that decodes to an injection
|
|
104
|
+
// (the Iron Dome base64 rule only fires on literal framing words) is
|
|
105
|
+
// caught on its plaintext. Reuses the write-path detectors — no
|
|
106
|
+
// duplicated detection logic.
|
|
107
|
+
let decodedInjection = false;
|
|
108
|
+
let decodedCredentialLeak = false;
|
|
109
|
+
for (const snippet of encoding.decodedSnippets) {
|
|
110
|
+
if (!decodedInjection && detectInstructions(snippet).detected) {
|
|
111
|
+
decodedInjection = true;
|
|
112
|
+
}
|
|
113
|
+
if (!decodedCredentialLeak && scanForCredentials(snippet).leaked) {
|
|
114
|
+
decodedCredentialLeak = true;
|
|
115
|
+
}
|
|
116
|
+
if (decodedInjection && decodedCredentialLeak)
|
|
117
|
+
break;
|
|
118
|
+
}
|
|
119
|
+
// 3. Markdown-image exfiltration (rendered image URL smuggling data out).
|
|
120
|
+
const markdownImage = detectMarkdownImageExfil(content);
|
|
121
|
+
// 4. Credential leak scan (retained from the original 2-layer read path).
|
|
72
122
|
const credentials = scanForCredentials(content);
|
|
73
|
-
//
|
|
123
|
+
// 5. Collect threat indicators across every layer.
|
|
74
124
|
const threatIndicators = [];
|
|
125
|
+
const pushIndicator = (indicator) => {
|
|
126
|
+
if (!threatIndicators.includes(indicator))
|
|
127
|
+
threatIndicators.push(indicator);
|
|
128
|
+
};
|
|
129
|
+
if (instructions.detected || decodedInjection) {
|
|
130
|
+
pushIndicator('instruction_injection');
|
|
131
|
+
}
|
|
132
|
+
if (encoding.detected) {
|
|
133
|
+
pushIndicator('encoding_obfuscation');
|
|
134
|
+
}
|
|
75
135
|
if (!injection.clean) {
|
|
76
|
-
|
|
136
|
+
pushIndicator('instruction_injection');
|
|
77
137
|
const categories = new Set(injection.detections.map(d => d.category));
|
|
78
138
|
if (categories.has('credential_extraction')) {
|
|
79
|
-
|
|
139
|
+
pushIndicator('credential_leak');
|
|
80
140
|
}
|
|
81
141
|
if (categories.has('encoding_trick')) {
|
|
82
|
-
|
|
142
|
+
pushIndicator('encoding_obfuscation');
|
|
83
143
|
}
|
|
84
144
|
}
|
|
85
|
-
if (
|
|
86
|
-
|
|
145
|
+
if (markdownImage.detected) {
|
|
146
|
+
pushIndicator('external_url');
|
|
147
|
+
}
|
|
148
|
+
if (credentials.leaked || decodedCredentialLeak) {
|
|
149
|
+
pushIndicator('credential_leak');
|
|
87
150
|
}
|
|
88
|
-
const clean = injection.clean &&
|
|
151
|
+
const clean = injection.clean &&
|
|
152
|
+
!instructions.detected &&
|
|
153
|
+
!encoding.detected &&
|
|
154
|
+
!decodedInjection &&
|
|
155
|
+
!markdownImage.detected &&
|
|
156
|
+
!credentials.leaked;
|
|
89
157
|
const durationMs = Math.round(performance.now() - startTime);
|
|
90
|
-
//
|
|
158
|
+
// 6. Build summary
|
|
91
159
|
let summary;
|
|
92
160
|
if (clean) {
|
|
93
161
|
summary = `Tool response from "${toolName}" is clean (${durationMs}ms)`;
|
|
@@ -96,11 +164,33 @@ export function scanToolResponse(toolName, content, mode) {
|
|
|
96
164
|
const parts = [];
|
|
97
165
|
if (!injection.clean)
|
|
98
166
|
parts.push(`injection: ${injection.summary}`);
|
|
167
|
+
if (instructions.detected)
|
|
168
|
+
parts.push(`instructions: ${instructions.patterns.join(', ')}`);
|
|
169
|
+
if (decodedInjection)
|
|
170
|
+
parts.push('decoded payload contains injection');
|
|
171
|
+
if (encoding.detected)
|
|
172
|
+
parts.push(`encoding: ${encoding.encodingTypes.join(', ')}`);
|
|
173
|
+
if (markdownImage.detected)
|
|
174
|
+
parts.push(`markdown-image exfil: ${markdownImage.urls.length} URL(s)`);
|
|
99
175
|
if (credentials.leaked)
|
|
100
176
|
parts.push(`credentials: ${credentials.findings.length} finding(s)`);
|
|
177
|
+
else if (decodedCredentialLeak)
|
|
178
|
+
parts.push('decoded payload contains credentials');
|
|
101
179
|
summary = `THREAT in "${toolName}" response: ${parts.join('; ')} (${durationMs}ms)`;
|
|
102
180
|
}
|
|
103
|
-
//
|
|
181
|
+
// 7. Anomaly score: CRITICAL Iron Dome risk pins to 1.0; any other detection
|
|
182
|
+
// (homoglyph, decoded payload, markdown-image exfil, etc.) scores 0.7.
|
|
183
|
+
const anomalyScore = injection.riskLevel === 'CRITICAL' ? 1.0 : 0.7;
|
|
184
|
+
// Blocked patterns reported to the audit/dashboard — Iron Dome named patterns
|
|
185
|
+
// plus the parity detectors' own labels.
|
|
186
|
+
const blockedPatterns = [
|
|
187
|
+
...injection.detections.map(d => d.pattern),
|
|
188
|
+
...instructions.patterns,
|
|
189
|
+
...encoding.encodingTypes,
|
|
190
|
+
...(decodedInjection ? ['decoded_injection'] : []),
|
|
191
|
+
...(markdownImage.detected ? ['markdown_image_exfil'] : []),
|
|
192
|
+
];
|
|
193
|
+
// 8. Audit log (threats only)
|
|
104
194
|
let auditId = -1;
|
|
105
195
|
if (!clean && isDatabaseInitialized()) {
|
|
106
196
|
try {
|
|
@@ -111,11 +201,11 @@ export function scanToolResponse(toolName, content, mode) {
|
|
|
111
201
|
source_type: 'tool_response',
|
|
112
202
|
source_identifier: toolName,
|
|
113
203
|
trust_score: 0.5,
|
|
114
|
-
sensitivity_level: credentials.leaked ? 'CONFIDENTIAL' : 'PUBLIC',
|
|
204
|
+
sensitivity_level: (credentials.leaked || decodedCredentialLeak) ? 'CONFIDENTIAL' : 'PUBLIC',
|
|
115
205
|
firewall_result: resolvedMode === 'enforce' ? 'BLOCK' : 'ALLOW',
|
|
116
|
-
anomaly_score:
|
|
206
|
+
anomaly_score: anomalyScore,
|
|
117
207
|
threat_indicators: JSON.stringify(threatIndicators),
|
|
118
|
-
blocked_patterns: JSON.stringify(
|
|
208
|
+
blocked_patterns: JSON.stringify(blockedPatterns),
|
|
119
209
|
reason: summary,
|
|
120
210
|
fragmentation_score: null,
|
|
121
211
|
pipeline_duration_ms: durationMs,
|
|
@@ -124,15 +214,14 @@ export function scanToolResponse(toolName, content, mode) {
|
|
|
124
214
|
catch {
|
|
125
215
|
// Audit logging must never affect tool response delivery
|
|
126
216
|
}
|
|
127
|
-
//
|
|
217
|
+
// 9. Dashboard real-time event
|
|
128
218
|
try {
|
|
129
|
-
const { persistEvent } = require('../api/events.js');
|
|
130
219
|
persistEvent('defence_event', {
|
|
131
220
|
source_type: 'tool_response',
|
|
132
221
|
source_identifier: toolName,
|
|
133
222
|
firewall_result: resolvedMode === 'enforce' ? 'BLOCK' : 'ALLOW',
|
|
134
223
|
trust_score: 0.5,
|
|
135
|
-
anomaly_score:
|
|
224
|
+
anomaly_score: anomalyScore,
|
|
136
225
|
reason: summary,
|
|
137
226
|
threat_indicators: JSON.stringify(threatIndicators),
|
|
138
227
|
timestamp: new Date().toISOString(),
|
package/dist/defence/types.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
export type SensitivityLevel = 'PUBLIC' | 'INTERNAL' | 'CONFIDENTIAL' | 'RESTRICTED';
|
|
8
8
|
export type FirewallResult = 'ALLOW' | 'BLOCK' | 'QUARANTINE';
|
|
9
|
-
export type ThreatIndicator = 'instruction_injection' | 'privilege_escalation' | 'encoding_obfuscation' | 'credential_leak' | 'external_url' | 'fragmented_payload' | 'restricted_content' | 'pipeline_error' | 'custom_rule' | 'custom_pattern' | 'builtin_rule';
|
|
9
|
+
export type ThreatIndicator = 'instruction_injection' | 'privilege_escalation' | 'encoding_obfuscation' | 'credential_leak' | 'external_url' | 'fragmented_payload' | 'restricted_content' | 'pipeline_error' | 'semantic_similarity' | 'custom_rule' | 'custom_pattern' | 'builtin_rule';
|
|
10
10
|
export interface DefenceSource {
|
|
11
11
|
type: 'user' | 'cli' | 'hook' | 'email' | 'web' | 'agent' | 'file' | 'api' | 'tool_response';
|
|
12
12
|
identifier: string;
|
|
@@ -92,6 +92,16 @@ export interface DefencePipelineResultWithVerify extends DefencePipelineResult {
|
|
|
92
92
|
mode: 'advisory' | 'enforce';
|
|
93
93
|
originalFirewallResult?: FirewallResult;
|
|
94
94
|
};
|
|
95
|
+
/**
|
|
96
|
+
* Result of the async-path semantic-similarity layer (embedding vs curated
|
|
97
|
+
* attack corpus). Present only when the embedding model was available; absent
|
|
98
|
+
* when it degraded. For observability — the verdict escalation it may trigger
|
|
99
|
+
* is reflected in `firewall`.
|
|
100
|
+
*/
|
|
101
|
+
semanticSimilarity?: {
|
|
102
|
+
maxSimilarity: number;
|
|
103
|
+
matchedPhrase?: string;
|
|
104
|
+
};
|
|
95
105
|
}
|
|
96
106
|
export interface QuarantineEntry {
|
|
97
107
|
id: number;
|
package/dist/index.d.ts
CHANGED
|
@@ -63,4 +63,33 @@
|
|
|
63
63
|
* shieldcortex uninstall --confirm # Full uninstall (non-interactive)
|
|
64
64
|
* shieldcortex uninstall --keep-logs # Full uninstall but keep log files
|
|
65
65
|
*/
|
|
66
|
+
type ServerMode = 'mcp' | 'api' | 'both' | 'dashboard' | 'worker';
|
|
67
|
+
/**
|
|
68
|
+
* Should the interactive trial/stats banner print for this invocation?
|
|
69
|
+
*
|
|
70
|
+
* It must print for normal interactive CLI commands (status, scan, doctor,
|
|
71
|
+
* audit, setup, …) but NEVER for:
|
|
72
|
+
* - the MCP stdio server path (bare `shieldcortex`, `shieldcortex --db x`,
|
|
73
|
+
* or `shieldcortex --mode mcp`) — stdout there is the JSON-RPC channel and
|
|
74
|
+
* any banner bytes corrupt the protocol;
|
|
75
|
+
* - the per-prompt `hook` path (dispatched + returned before this is reached).
|
|
76
|
+
*
|
|
77
|
+
* The previous guard was `argv[2] && mode !== 'mcp'`. That was broken because
|
|
78
|
+
* `parseArgs()` defaults `mode` to `'mcp'` for EVERY command except the few
|
|
79
|
+
* server modes (dashboard/api/worker/--mode) — so `status`, `scan`, `doctor`,
|
|
80
|
+
* `audit` etc. all kept `mode === 'mcp'` and were silently excluded, and the
|
|
81
|
+
* banner never showed for any normal command (Phase 11 reordered this block but
|
|
82
|
+
* left the faulty condition).
|
|
83
|
+
*
|
|
84
|
+
* The reliable discriminator is a POSITIONAL command word: the MCP stdio launch
|
|
85
|
+
* is only ever reached with no positional command (flags only). So we show the
|
|
86
|
+
* banner when either (a) there's a positional first arg that isn't a flag, or
|
|
87
|
+
* (b) a non-mcp server mode was selected. `mcp` as an explicit positional
|
|
88
|
+
* subcommand IS an interactive CLI command (the MCP-config scanner) — it parses
|
|
89
|
+
* to mode 'mcp' but is not the stdio server, and prints normal stdout, so it's
|
|
90
|
+
* fine for it to show the banner.
|
|
91
|
+
*
|
|
92
|
+
* Exported for unit testing.
|
|
93
|
+
*/
|
|
94
|
+
export declare function shouldShowInteractiveBanner(argv: string[], mode: ServerMode): boolean;
|
|
66
95
|
export * from './lib.js';
|
package/dist/index.js
CHANGED
|
@@ -69,18 +69,14 @@ import { fileURLToPath } from 'url';
|
|
|
69
69
|
import http from 'http';
|
|
70
70
|
import path from 'path';
|
|
71
71
|
import fs from 'fs';
|
|
72
|
-
import { createServer } from './server.js';
|
|
73
|
-
import { startVisualizationServer } from './api/visualization-server.js';
|
|
74
|
-
import { handleServiceCommand } from './service/install.js';
|
|
75
|
-
import { setupClaudeMd } from './setup/claude-md.js';
|
|
76
|
-
import { handleHookCommand } from './setup/hooks.js';
|
|
77
|
-
import { handleOpenClawCommand } from './setup/openclaw.js';
|
|
78
|
-
import { handleCopilotCommand } from './setup/copilot.js';
|
|
79
|
-
import { handleCodexCommand } from './setup/codex.js';
|
|
80
72
|
import { createRequire } from 'module';
|
|
81
73
|
import { execSync } from 'child_process';
|
|
82
|
-
|
|
83
|
-
|
|
74
|
+
// Heavy modules (MCP server, visualization API + express/cors/ws, embedding
|
|
75
|
+
// model, brain worker, installer handlers) are loaded lazily via `await import`
|
|
76
|
+
// inside the dispatch branch that needs them — keeping per-prompt hook startup
|
|
77
|
+
// and lightweight CLI commands (--version, --help, status, doctor) fast. See
|
|
78
|
+
// Phase 11 of the hardening plan: the `hook` path must not eagerly pull in any
|
|
79
|
+
// of these, nor run the npx-staleness check.
|
|
84
80
|
const require = createRequire(import.meta.url);
|
|
85
81
|
const pkg = require('../package.json');
|
|
86
82
|
/**
|
|
@@ -111,6 +107,50 @@ function checkVersionStaleness() {
|
|
|
111
107
|
// Get the directory of this file for relative paths
|
|
112
108
|
const __filename = fileURLToPath(import.meta.url);
|
|
113
109
|
const __dirname = path.dirname(__filename);
|
|
110
|
+
/**
|
|
111
|
+
* Should the interactive trial/stats banner print for this invocation?
|
|
112
|
+
*
|
|
113
|
+
* It must print for normal interactive CLI commands (status, scan, doctor,
|
|
114
|
+
* audit, setup, …) but NEVER for:
|
|
115
|
+
* - the MCP stdio server path (bare `shieldcortex`, `shieldcortex --db x`,
|
|
116
|
+
* or `shieldcortex --mode mcp`) — stdout there is the JSON-RPC channel and
|
|
117
|
+
* any banner bytes corrupt the protocol;
|
|
118
|
+
* - the per-prompt `hook` path (dispatched + returned before this is reached).
|
|
119
|
+
*
|
|
120
|
+
* The previous guard was `argv[2] && mode !== 'mcp'`. That was broken because
|
|
121
|
+
* `parseArgs()` defaults `mode` to `'mcp'` for EVERY command except the few
|
|
122
|
+
* server modes (dashboard/api/worker/--mode) — so `status`, `scan`, `doctor`,
|
|
123
|
+
* `audit` etc. all kept `mode === 'mcp'` and were silently excluded, and the
|
|
124
|
+
* banner never showed for any normal command (Phase 11 reordered this block but
|
|
125
|
+
* left the faulty condition).
|
|
126
|
+
*
|
|
127
|
+
* The reliable discriminator is a POSITIONAL command word: the MCP stdio launch
|
|
128
|
+
* is only ever reached with no positional command (flags only). So we show the
|
|
129
|
+
* banner when either (a) there's a positional first arg that isn't a flag, or
|
|
130
|
+
* (b) a non-mcp server mode was selected. `mcp` as an explicit positional
|
|
131
|
+
* subcommand IS an interactive CLI command (the MCP-config scanner) — it parses
|
|
132
|
+
* to mode 'mcp' but is not the stdio server, and prints normal stdout, so it's
|
|
133
|
+
* fine for it to show the banner.
|
|
134
|
+
*
|
|
135
|
+
* Exported for unit testing.
|
|
136
|
+
*/
|
|
137
|
+
export function shouldShowInteractiveBanner(argv, mode) {
|
|
138
|
+
const first = argv[2];
|
|
139
|
+
if (!first)
|
|
140
|
+
return false; // bare invocation → MCP stdio server
|
|
141
|
+
// A positional (non-flag) first arg means a CLI subcommand was given.
|
|
142
|
+
const hasPositionalCommand = !first.startsWith('-');
|
|
143
|
+
if (hasPositionalCommand) {
|
|
144
|
+
// The only way a positional first arg lands on the stdio MCP server is the
|
|
145
|
+
// explicit server-mode words, which select a non-mcp mode anyway — so any
|
|
146
|
+
// positional command that resolves to mode 'mcp' is an interactive command
|
|
147
|
+
// (e.g. `mcp`, `scan`, `status`). Always show for positional commands.
|
|
148
|
+
return true;
|
|
149
|
+
}
|
|
150
|
+
// Flag-only invocation (e.g. `--db x`, `--mode mcp`, `--version`). Show only
|
|
151
|
+
// when a non-mcp server mode was explicitly requested (dashboard/api/worker).
|
|
152
|
+
return mode !== 'mcp';
|
|
153
|
+
}
|
|
114
154
|
// Parse command line arguments
|
|
115
155
|
function parseArgs() {
|
|
116
156
|
const args = process.argv.slice(2);
|
|
@@ -143,6 +183,11 @@ function parseArgs() {
|
|
|
143
183
|
* Start MCP server for Claude Code integration
|
|
144
184
|
*/
|
|
145
185
|
async function startMcpServer(dbPath) {
|
|
186
|
+
// Lazy-load heavy server/worker/embedding modules — only the actual MCP
|
|
187
|
+
// server path needs them, so they stay out of fast CLI/hook startup.
|
|
188
|
+
const { createServer } = await import('./server.js');
|
|
189
|
+
const { disposeModel, preloadModel } = await import('./embeddings/index.js');
|
|
190
|
+
const { startDefaultWorker, stopDefaultWorker } = await import('./worker/brain-worker.js');
|
|
146
191
|
// Create the MCP server
|
|
147
192
|
const server = createServer(dbPath);
|
|
148
193
|
const transport = new StdioServerTransport();
|
|
@@ -387,7 +432,7 @@ function startDashboard() {
|
|
|
387
432
|
}
|
|
388
433
|
async function startWorkerMode(dbPath) {
|
|
389
434
|
const { initDatabase } = await import('./database/init.js');
|
|
390
|
-
const { startDefaultWorker } = await import('./worker/brain-worker.js');
|
|
435
|
+
const { startDefaultWorker, stopDefaultWorker } = await import('./worker/brain-worker.js');
|
|
391
436
|
initDatabase(dbPath);
|
|
392
437
|
startDefaultWorker();
|
|
393
438
|
// Resilience handlers (v4.14.8). Without these, any throw outside a tick's
|
|
@@ -459,12 +504,25 @@ async function isLocalDashboardRunning() {
|
|
|
459
504
|
* Main entry point
|
|
460
505
|
*/
|
|
461
506
|
async function main() {
|
|
507
|
+
// Dispatch the "hook" subcommand FIRST — before checkVersionStaleness() and
|
|
508
|
+
// the trial/stats banner. Hooks fire on every UserPromptSubmit, so this path
|
|
509
|
+
// must be as cheap as possible: no `npm ls -g` staleness probe (hooks were
|
|
510
|
+
// migrated to the global binary, where the warning is meaningless) and no
|
|
511
|
+
// trial/stats banners. handleHookCommand is imported lazily so the rest of
|
|
512
|
+
// the installer surface stays out of hook startup.
|
|
513
|
+
if (process.argv[2] === 'hook') {
|
|
514
|
+
const { handleHookCommand } = await import('./setup/hooks.js');
|
|
515
|
+
await handleHookCommand(process.argv[3] || '');
|
|
516
|
+
return;
|
|
517
|
+
}
|
|
462
518
|
// Warn if npx is serving a stale cached version
|
|
463
519
|
checkVersionStaleness();
|
|
464
520
|
const parsedArgs = parseArgs();
|
|
465
521
|
// ── Trial welcome / expiry warning ──────────────────────
|
|
466
|
-
// Only show for interactive CLI commands
|
|
467
|
-
|
|
522
|
+
// Only show for interactive CLI commands. shouldShowInteractiveBanner gates
|
|
523
|
+
// out the MCP stdio server path (bare / --mode mcp / --db) where stdout is
|
|
524
|
+
// the JSON-RPC channel; the per-prompt `hook` path already returned above.
|
|
525
|
+
if (shouldShowInteractiveBanner(process.argv, parsedArgs.mode)) {
|
|
468
526
|
try {
|
|
469
527
|
const { existsSync } = await import('fs');
|
|
470
528
|
const { join } = await import('path');
|
|
@@ -534,6 +592,8 @@ ${bold}USAGE${reset}
|
|
|
534
592
|
shieldcortex [command] [options]
|
|
535
593
|
|
|
536
594
|
${bold}COMMANDS${reset}
|
|
595
|
+
${cyan}remember${reset} <title> Write a memory (via the defence pipeline)
|
|
596
|
+
--content <text> or pipe via stdin; --importance, --tags
|
|
537
597
|
${cyan}scan${reset} <text> Scan text through the defence pipeline
|
|
538
598
|
${cyan}scan-skill${reset} <path> Scan an agent instruction file for threats
|
|
539
599
|
${cyan}scan-skills${reset} Scan all installed skills/hooks
|
|
@@ -617,6 +677,7 @@ ${bold}DOCS${reset}
|
|
|
617
677
|
}
|
|
618
678
|
const stopHook = process.argv.includes('--with-stop-hook');
|
|
619
679
|
const sessionEnd = process.argv.includes('--with-session-end');
|
|
680
|
+
const { setupClaudeMd } = await import('./setup/claude-md.js');
|
|
620
681
|
await setupClaudeMd({ stopHook, sessionEnd });
|
|
621
682
|
return;
|
|
622
683
|
}
|
|
@@ -636,28 +697,30 @@ ${bold}DOCS${reset}
|
|
|
636
697
|
});
|
|
637
698
|
return;
|
|
638
699
|
}
|
|
639
|
-
//
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
return;
|
|
643
|
-
}
|
|
700
|
+
// NOTE: the "hook" subcommand is dispatched at the very top of main(),
|
|
701
|
+
// before checkVersionStaleness() and the trial/stats banner — it must stay
|
|
702
|
+
// fast (fires on every UserPromptSubmit) and never run `npm ls -g`.
|
|
644
703
|
// Handle "openclaw" subcommand (backward compat: "clawdbot" also accepted)
|
|
645
704
|
if (process.argv[2] === 'openclaw' || process.argv[2] === 'clawdbot') {
|
|
705
|
+
const { handleOpenClawCommand } = await import('./setup/openclaw.js');
|
|
646
706
|
await handleOpenClawCommand(process.argv[3] || '', process.argv.slice(4));
|
|
647
707
|
return;
|
|
648
708
|
}
|
|
649
709
|
// Handle "copilot" subcommand (VS Code + Cursor MCP setup)
|
|
650
710
|
if (process.argv[2] === 'copilot') {
|
|
711
|
+
const { handleCopilotCommand } = await import('./setup/copilot.js');
|
|
651
712
|
await handleCopilotCommand(process.argv[3] || '');
|
|
652
713
|
return;
|
|
653
714
|
}
|
|
654
715
|
// Handle "codex" subcommand (Codex CLI + VS Code MCP setup)
|
|
655
716
|
if (process.argv[2] === 'codex') {
|
|
717
|
+
const { handleCodexCommand } = await import('./setup/codex.js');
|
|
656
718
|
await handleCodexCommand(process.argv[3] || '');
|
|
657
719
|
return;
|
|
658
720
|
}
|
|
659
721
|
// Handle "service" subcommand before normal mode parsing
|
|
660
722
|
if (process.argv[2] === 'service') {
|
|
723
|
+
const { handleServiceCommand } = await import('./service/install.js');
|
|
661
724
|
await handleServiceCommand(process.argv[3] || '', process.argv.slice(4));
|
|
662
725
|
return;
|
|
663
726
|
}
|
|
@@ -685,6 +748,14 @@ ${bold}DOCS${reset}
|
|
|
685
748
|
await handleMemoriesCommand(process.argv.slice(3));
|
|
686
749
|
return;
|
|
687
750
|
}
|
|
751
|
+
// Handle "remember" subcommand (Phase 15c) — direct, non-hanging memory write
|
|
752
|
+
// through the same defence pipeline + project scoping the MCP tool uses.
|
|
753
|
+
// Content via --content or piped stdin; never blocks on a TTY (prints usage).
|
|
754
|
+
if (process.argv[2] === 'remember') {
|
|
755
|
+
const { handleRememberCommand } = await import('./cli/remember.js');
|
|
756
|
+
await handleRememberCommand(process.argv.slice(3));
|
|
757
|
+
return;
|
|
758
|
+
}
|
|
688
759
|
// Handle "import-jsonl" subcommand — import Claude Code session transcripts
|
|
689
760
|
// into session_events for dashboard replay.
|
|
690
761
|
if (process.argv[2] === 'import-jsonl') {
|
|
@@ -747,6 +818,13 @@ ${bold}DOCS${reset}
|
|
|
747
818
|
await handleAuditCommand(process.argv.slice(3));
|
|
748
819
|
return;
|
|
749
820
|
}
|
|
821
|
+
// Handle "mcp" subcommand (Phase 14) — scan configured MCP servers' tool
|
|
822
|
+
// descriptions for poisoning / line-jumping and rug-pull drift.
|
|
823
|
+
if (process.argv[2] === 'mcp') {
|
|
824
|
+
const { handleMcpCommand } = await import('./cli/mcp.js');
|
|
825
|
+
await handleMcpCommand(process.argv.slice(3));
|
|
826
|
+
return;
|
|
827
|
+
}
|
|
750
828
|
// Handle "memory" subcommand (v4.25.0) — show / downvote / list a single
|
|
751
829
|
// memory. Distinct from the existing "memories" (plural) command which
|
|
752
830
|
// routes to migrate-legacy.
|
|
@@ -972,9 +1050,9 @@ ${bold}DOCS${reset}
|
|
|
972
1050
|
const knownCommands = new Set([
|
|
973
1051
|
'doctor', 'quickstart', 'setup', 'install', 'migrate', 'uninstall', 'hook', 'update',
|
|
974
1052
|
'openclaw', 'clawdbot', 'copilot', 'codex', 'service', 'config', 'status',
|
|
975
|
-
'graph', 'license', 'licence', 'audit', 'iron-dome', 'scan', 'cloud', 'review-copilot',
|
|
1053
|
+
'graph', 'license', 'licence', 'audit', 'mcp', 'iron-dome', 'scan', 'cloud', 'review-copilot',
|
|
976
1054
|
'scan-skill', 'scan-skills', 'dashboard', 'api', 'worker', 'stats', 'cortex', 'consolidate', 'xray', 'xray-preinstall',
|
|
977
|
-
'memories', 'import-jsonl',
|
|
1055
|
+
'memories', 'import-jsonl', 'remember',
|
|
978
1056
|
]);
|
|
979
1057
|
const arg = process.argv[2];
|
|
980
1058
|
if (arg && !arg.startsWith('-') && !knownCommands.has(arg)) {
|
|
@@ -984,6 +1062,12 @@ ${bold}DOCS${reset}
|
|
|
984
1062
|
}
|
|
985
1063
|
const { dbPath, mode } = parsedArgs;
|
|
986
1064
|
let dashboardProcess = null;
|
|
1065
|
+
// Lazy-load the visualization server (pulls in express + cors + ws) only on
|
|
1066
|
+
// the modes that actually start it. mcp/worker never touch it.
|
|
1067
|
+
const needsVizServer = mode === 'api' || mode === 'dashboard' || mode === 'both';
|
|
1068
|
+
const startVisualizationServer = needsVizServer
|
|
1069
|
+
? (await import('./api/visualization-server.js')).startVisualizationServer
|
|
1070
|
+
: undefined;
|
|
987
1071
|
if (mode === 'api') {
|
|
988
1072
|
// API mode only - for dashboard visualization
|
|
989
1073
|
if (await isLocalApiRunning()) {
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
* - Merges similar memories to reduce redundancy
|
|
9
9
|
*/
|
|
10
10
|
import { getDatabase, withTransaction } from '../database/init.js';
|
|
11
|
+
import { expireQuarantineItems } from '../defence/quarantine/auto-expire.js';
|
|
11
12
|
import { DEFAULT_CONFIG, } from './types.js';
|
|
12
13
|
import { getMemoriesByType, getRecentMemories, promoteMemory, deleteMemory, searchMemories, getMemoryStats, updateDecayScores, addMemory, rowToMemory, } from './store.js';
|
|
13
14
|
import { processDecay, } from './decay.js';
|
|
@@ -895,7 +896,6 @@ export function fullCleanup(config = DEFAULT_CONFIG) {
|
|
|
895
896
|
// Expire old quarantine items
|
|
896
897
|
let quarantineExpired = 0;
|
|
897
898
|
try {
|
|
898
|
-
const { expireQuarantineItems } = require('../defence/quarantine/auto-expire.js');
|
|
899
899
|
quarantineExpired = expireQuarantineItems();
|
|
900
900
|
}
|
|
901
901
|
catch { /* defence module may not be available */ }
|
package/dist/memory/decay.js
CHANGED
|
@@ -150,7 +150,9 @@ export function processDecay(memories, config = DEFAULT_CONFIG) {
|
|
|
150
150
|
console.log(`[expiry] Deleted ${deleted} expired memories (${kept} protected)`);
|
|
151
151
|
}
|
|
152
152
|
}
|
|
153
|
-
catch {
|
|
153
|
+
catch (err) {
|
|
154
|
+
console.error('[expiry] applyExpiryRules failed:', err);
|
|
155
|
+
}
|
|
154
156
|
return { toDelete, toPromote, updated };
|
|
155
157
|
}
|
|
156
158
|
/**
|
|
@@ -27,8 +27,24 @@ export declare function cosineSimilarity(a: Float32Array, b: Float32Array): numb
|
|
|
27
27
|
export declare function getCachedQueryEmbedding(query: string): Promise<Float32Array | null>;
|
|
28
28
|
export declare function clearQueryEmbeddingCache(): void;
|
|
29
29
|
/**
|
|
30
|
-
* Embed the query, compute similarity against
|
|
31
|
-
* return top K (default 10) sorted by score desc.
|
|
30
|
+
* Embed the query, compute similarity against the candidate memories' PERSISTED
|
|
31
|
+
* embeddings, return top K (default 10) sorted by score desc.
|
|
32
|
+
*
|
|
33
|
+
* Candidate embeddings are read from the canonical `memories.embedding` column —
|
|
34
|
+
* the same vector addMemory persists on write and vectorSearch scores against —
|
|
35
|
+
* in ONE batched `WHERE id IN (...)` query, decoded with the shared
|
|
36
|
+
* `decodeEmbeddingBlob`. This is a reuse, not a recompute: previously every
|
|
37
|
+
* candidate was routed through `getOrComputeEmbedding`, which checked a SEPARATE,
|
|
38
|
+
* perpetually-cold `memory_embeddings` cache and re-embedded each candidate's text
|
|
39
|
+
* through the worker on the (near-universal) miss — up to 200 sequential worker
|
|
40
|
+
* round-trips per cold recall, all redundant.
|
|
41
|
+
*
|
|
42
|
+
* Candidates that genuinely lack a persisted embedding (rare — writes populate it;
|
|
43
|
+
* only possible when the model was unavailable at write time, or for legacy rows)
|
|
44
|
+
* are skipped, not re-embedded: re-embedding here would reintroduce exactly the
|
|
45
|
+
* per-candidate worker storm this change removed, and `addMemory` already
|
|
46
|
+
* (re)populates the column out of band. They simply don't contribute to the
|
|
47
|
+
* vector-similarity fallback this turn; FTS and the next write still cover them.
|
|
32
48
|
*
|
|
33
49
|
* Non-throwing: returns empty array on failure.
|
|
34
50
|
*/
|