shieldcortex 4.15.0 → 4.17.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 +4 -0
- 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/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/routes/sessions.d.ts +19 -0
- package/dist/api/routes/sessions.js +153 -0
- package/dist/api/visualization-server.js +2 -0
- package/dist/cli/import-jsonl.d.ts +12 -0
- package/dist/cli/import-jsonl.js +88 -0
- package/dist/cli/migrate-legacy.d.ts +18 -0
- package/dist/cli/migrate-legacy.js +96 -0
- package/dist/database/init.js +65 -0
- package/dist/database/schema.sql +32 -0
- package/dist/database/seed-firewall-rules.d.ts +21 -0
- package/dist/database/seed-firewall-rules.js +105 -0
- package/dist/defence/custom-rules/store.d.ts +4 -1
- package/dist/defence/custom-rules/store.js +7 -3
- package/dist/defence/firewall/instruction-detector.js +15 -0
- package/dist/defence/pipeline.js +19 -13
- package/dist/defence/types.d.ts +1 -1
- package/dist/index.js +8 -0
- package/dist/sessions/capture.d.ts +45 -0
- package/dist/sessions/capture.js +59 -0
- package/dist/sessions/import-jsonl.d.ts +85 -0
- package/dist/sessions/import-jsonl.js +193 -0
- package/dist/sessions/timeline.d.ts +28 -0
- package/dist/sessions/timeline.js +52 -0
- package/hooks/openclaw/cortex-memory/HOOK.md +37 -0
- package/package.json +1 -1
- package/plugins/openclaw/dist/openclaw.plugin.json +1 -1
- package/scripts/lib/extract-memorable-segments.mjs +555 -0
- package/scripts/lib/save-memory.mjs +198 -13
- package/scripts/lib/session-capture.mjs +102 -0
- package/scripts/pre-compact-hook.mjs +38 -375
- package/scripts/prompt-recall-hook.mjs +30 -4
- package/scripts/session-end-hook.mjs +35 -307
- package/scripts/stop-hook.mjs +28 -159
- /package/dashboard/.next/standalone/dashboard/.next/static/{10a_MRwbHFUuDdfr86RUu → 9C0MR5ahRDqnfBA64wKCY}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{10a_MRwbHFUuDdfr86RUu → 9C0MR5ahRDqnfBA64wKCY}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{10a_MRwbHFUuDdfr86RUu → 9C0MR5ahRDqnfBA64wKCY}/_ssgManifest.js +0 -0
package/dist/database/init.js
CHANGED
|
@@ -8,6 +8,7 @@ import { homedir } from 'os';
|
|
|
8
8
|
import { fileURLToPath } from 'url';
|
|
9
9
|
import { execSync } from 'child_process';
|
|
10
10
|
import { randomUUID } from 'crypto';
|
|
11
|
+
import { seedDefaultFirewallRules } from './seed-firewall-rules.js';
|
|
11
12
|
const _currentFile = fileURLToPath(import.meta.url);
|
|
12
13
|
const _currentDir = dirname(_currentFile);
|
|
13
14
|
let db = null;
|
|
@@ -907,10 +908,12 @@ function runMigrations(database) {
|
|
|
907
908
|
condition_value TEXT NOT NULL,
|
|
908
909
|
action TEXT NOT NULL CHECK(action IN ('block', 'allow', 'quarantine')),
|
|
909
910
|
enabled INTEGER NOT NULL DEFAULT 1,
|
|
911
|
+
built_in INTEGER NOT NULL DEFAULT 0,
|
|
910
912
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
911
913
|
);
|
|
912
914
|
CREATE INDEX IF NOT EXISTS idx_firewall_rules_priority ON firewall_rules(priority);
|
|
913
915
|
CREATE INDEX IF NOT EXISTS idx_firewall_rules_enabled ON firewall_rules(enabled);
|
|
916
|
+
CREATE INDEX IF NOT EXISTS idx_firewall_rules_built_in ON firewall_rules(built_in);
|
|
914
917
|
|
|
915
918
|
CREATE TABLE IF NOT EXISTS rate_limits (
|
|
916
919
|
source_key TEXT PRIMARY KEY,
|
|
@@ -922,6 +925,46 @@ function runMigrations(database) {
|
|
|
922
925
|
catch {
|
|
923
926
|
// Tables may already exist - safe to ignore
|
|
924
927
|
}
|
|
928
|
+
// Migration: built_in column on pre-existing firewall_rules (added in v4.15)
|
|
929
|
+
try {
|
|
930
|
+
const cols = database.prepare("PRAGMA table_info(firewall_rules)").all();
|
|
931
|
+
if (!cols.some(c => c.name === 'built_in')) {
|
|
932
|
+
database.exec('ALTER TABLE firewall_rules ADD COLUMN built_in INTEGER NOT NULL DEFAULT 0');
|
|
933
|
+
database.exec('CREATE INDEX IF NOT EXISTS idx_firewall_rules_built_in ON firewall_rules(built_in)');
|
|
934
|
+
}
|
|
935
|
+
}
|
|
936
|
+
catch {
|
|
937
|
+
// Best-effort migration; pipeline handles missing column gracefully.
|
|
938
|
+
}
|
|
939
|
+
// Seed default built-in firewall rules on first init.
|
|
940
|
+
try {
|
|
941
|
+
seedDefaultFirewallRules(database);
|
|
942
|
+
}
|
|
943
|
+
catch {
|
|
944
|
+
// Seeder runs idempotently; failures here should never block startup.
|
|
945
|
+
}
|
|
946
|
+
// Migration: session_events.content_hash + dedupe UNIQUE index (v4.17).
|
|
947
|
+
// DBs created between the foundation commit and the importer commit have
|
|
948
|
+
// session_events but no content_hash column. ALTER + idempotent index
|
|
949
|
+
// upgrades them without touching fresh installs (schema.sql handles those).
|
|
950
|
+
try {
|
|
951
|
+
const sessionEventsTable = database
|
|
952
|
+
.prepare("SELECT name FROM sqlite_master WHERE type='table' AND name='session_events'")
|
|
953
|
+
.get();
|
|
954
|
+
if (sessionEventsTable) {
|
|
955
|
+
const sessionCols = database
|
|
956
|
+
.prepare("PRAGMA table_info(session_events)")
|
|
957
|
+
.all();
|
|
958
|
+
const sessionColNames = new Set(sessionCols.map((c) => c.name));
|
|
959
|
+
if (!sessionColNames.has('content_hash')) {
|
|
960
|
+
database.exec('ALTER TABLE session_events ADD COLUMN content_hash TEXT');
|
|
961
|
+
}
|
|
962
|
+
database.exec('CREATE UNIQUE INDEX IF NOT EXISTS idx_session_events_dedupe ON session_events(session_id, ts, kind, content_hash)');
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
catch {
|
|
966
|
+
// Best-effort; importer-side INSERT OR IGNORE handles missing index gracefully.
|
|
967
|
+
}
|
|
925
968
|
}
|
|
926
969
|
/**
|
|
927
970
|
* Get the current database instance
|
|
@@ -1422,6 +1465,28 @@ function getInlineSchema() {
|
|
|
1422
1465
|
write_count INTEGER NOT NULL DEFAULT 1,
|
|
1423
1466
|
window_start_ms INTEGER NOT NULL
|
|
1424
1467
|
);
|
|
1468
|
+
|
|
1469
|
+
-- v4.17 Session capture (mirrors schema.sql; bundled fallback only).
|
|
1470
|
+
CREATE TABLE IF NOT EXISTS session_events (
|
|
1471
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
1472
|
+
session_id TEXT NOT NULL,
|
|
1473
|
+
project TEXT,
|
|
1474
|
+
ts TIMESTAMP NOT NULL,
|
|
1475
|
+
kind TEXT NOT NULL CHECK(kind IN (
|
|
1476
|
+
'prompt', 'response', 'tool_call', 'tool_result', 'tool_error', 'hook_fire'
|
|
1477
|
+
)),
|
|
1478
|
+
actor TEXT,
|
|
1479
|
+
payload TEXT NOT NULL,
|
|
1480
|
+
duration_ms INTEGER,
|
|
1481
|
+
audit_id INTEGER,
|
|
1482
|
+
content_hash TEXT,
|
|
1483
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
1484
|
+
FOREIGN KEY (audit_id) REFERENCES defence_audit(id) ON DELETE SET NULL
|
|
1485
|
+
);
|
|
1486
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_session ON session_events(session_id, ts);
|
|
1487
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_project ON session_events(project, ts DESC);
|
|
1488
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_session_events_dedupe
|
|
1489
|
+
ON session_events(session_id, ts, kind, content_hash);
|
|
1425
1490
|
`;
|
|
1426
1491
|
}
|
|
1427
1492
|
/**
|
package/dist/database/schema.sql
CHANGED
|
@@ -95,6 +95,37 @@ CREATE TABLE IF NOT EXISTS sessions (
|
|
|
95
95
|
memories_accessed INTEGER DEFAULT 0
|
|
96
96
|
);
|
|
97
97
|
|
|
98
|
+
-- v4.17 Session capture: turn-by-turn events for replay.
|
|
99
|
+
-- Populated by the hook capture pipeline + JSONL importer. Read by the
|
|
100
|
+
-- timeline reader powering the dashboard replay UI. Distinct from the
|
|
101
|
+
-- summary `sessions` table above — this is the full event stream.
|
|
102
|
+
--
|
|
103
|
+
-- `content_hash` powers idempotent re-import. The JSONL importer writes
|
|
104
|
+
-- a SHA-256 of `kind + payload`; live capture leaves it NULL. SQLite
|
|
105
|
+
-- treats NULL as distinct in UNIQUE indexes by default, so live rows
|
|
106
|
+
-- never conflict with each other while imported rows are de-duplicated
|
|
107
|
+
-- across reruns of the same transcript.
|
|
108
|
+
CREATE TABLE IF NOT EXISTS session_events (
|
|
109
|
+
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
110
|
+
session_id TEXT NOT NULL,
|
|
111
|
+
project TEXT,
|
|
112
|
+
ts TIMESTAMP NOT NULL,
|
|
113
|
+
kind TEXT NOT NULL CHECK(kind IN (
|
|
114
|
+
'prompt', 'response', 'tool_call', 'tool_result', 'tool_error', 'hook_fire'
|
|
115
|
+
)),
|
|
116
|
+
actor TEXT,
|
|
117
|
+
payload TEXT NOT NULL,
|
|
118
|
+
duration_ms INTEGER,
|
|
119
|
+
audit_id INTEGER,
|
|
120
|
+
content_hash TEXT,
|
|
121
|
+
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
122
|
+
FOREIGN KEY (audit_id) REFERENCES defence_audit(id) ON DELETE SET NULL
|
|
123
|
+
);
|
|
124
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_session ON session_events(session_id, ts);
|
|
125
|
+
CREATE INDEX IF NOT EXISTS idx_session_events_project ON session_events(project, ts DESC);
|
|
126
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_session_events_dedupe
|
|
127
|
+
ON session_events(session_id, ts, kind, content_hash);
|
|
128
|
+
|
|
98
129
|
-- Memory relationships (for linked memories)
|
|
99
130
|
CREATE TABLE IF NOT EXISTS memory_links (
|
|
100
131
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
@@ -301,6 +332,7 @@ CREATE TABLE IF NOT EXISTS firewall_rules (
|
|
|
301
332
|
condition_value TEXT NOT NULL,
|
|
302
333
|
action TEXT NOT NULL CHECK(action IN ('block', 'allow', 'quarantine')),
|
|
303
334
|
enabled INTEGER NOT NULL DEFAULT 1,
|
|
335
|
+
built_in INTEGER NOT NULL DEFAULT 0,
|
|
304
336
|
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
305
337
|
);
|
|
306
338
|
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default firewall rule seeder.
|
|
3
|
+
*
|
|
4
|
+
* The `firewall_rules` table starts empty in production. The defence
|
|
5
|
+
* pipeline's PATTERN_GROUPS catch most threats inline (instruction
|
|
6
|
+
* injection, hidden instructions, etc.), but seeding the table with
|
|
7
|
+
* built-in rules makes them visible in the dashboard and gives operators
|
|
8
|
+
* a place to disable, edit, or extend them.
|
|
9
|
+
*
|
|
10
|
+
* Built-in rows are marked `built_in=1` and excluded from the user
|
|
11
|
+
* `MAX_RULES=25` cap (see custom-rules/store.ts). They are evaluated
|
|
12
|
+
* regardless of license tier — the Pro `custom_firewall_rules` gate
|
|
13
|
+
* applies only to user-added rules with `built_in=0`.
|
|
14
|
+
*
|
|
15
|
+
* Idempotent: running the seeder again is a no-op when built-in rules
|
|
16
|
+
* are already present. Operators wanting to re-seed after a built-in
|
|
17
|
+
* update should `DELETE FROM firewall_rules WHERE built_in = 1` first.
|
|
18
|
+
*/
|
|
19
|
+
import type Database from 'better-sqlite3';
|
|
20
|
+
export declare function seedDefaultFirewallRules(db: Database.Database): void;
|
|
21
|
+
export declare function listBuiltInRuleNames(): string[];
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Default firewall rule seeder.
|
|
3
|
+
*
|
|
4
|
+
* The `firewall_rules` table starts empty in production. The defence
|
|
5
|
+
* pipeline's PATTERN_GROUPS catch most threats inline (instruction
|
|
6
|
+
* injection, hidden instructions, etc.), but seeding the table with
|
|
7
|
+
* built-in rules makes them visible in the dashboard and gives operators
|
|
8
|
+
* a place to disable, edit, or extend them.
|
|
9
|
+
*
|
|
10
|
+
* Built-in rows are marked `built_in=1` and excluded from the user
|
|
11
|
+
* `MAX_RULES=25` cap (see custom-rules/store.ts). They are evaluated
|
|
12
|
+
* regardless of license tier — the Pro `custom_firewall_rules` gate
|
|
13
|
+
* applies only to user-added rules with `built_in=0`.
|
|
14
|
+
*
|
|
15
|
+
* Idempotent: running the seeder again is a no-op when built-in rules
|
|
16
|
+
* are already present. Operators wanting to re-seed after a built-in
|
|
17
|
+
* update should `DELETE FROM firewall_rules WHERE built_in = 1` first.
|
|
18
|
+
*/
|
|
19
|
+
const BUILT_IN_RULES = [
|
|
20
|
+
{
|
|
21
|
+
name: 'builtin:instruction_injection',
|
|
22
|
+
priority: 10,
|
|
23
|
+
condition_type: 'regex',
|
|
24
|
+
condition_value: '\\[SYSTEM:|<<SYS>>|\\[INST\\]|<\\|im_start\\|>|<\\|system\\|>|##SYSTEM##',
|
|
25
|
+
action: 'quarantine',
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'builtin:hidden_instruction',
|
|
29
|
+
priority: 11,
|
|
30
|
+
condition_type: 'regex',
|
|
31
|
+
condition_value: 'ignore\\s+(all\\s+)?previous\\s+(instructions?|prompts?)|forget\\s+everything|disregard\\s+(all\\s+)?(previous|above|prior)|override\\s+(previous|all|system)',
|
|
32
|
+
action: 'quarantine',
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
name: 'builtin:imperative_tool_call',
|
|
36
|
+
priority: 12,
|
|
37
|
+
condition_type: 'regex',
|
|
38
|
+
condition_value: '\\b(?:call|invoke|use)\\s+(?:the\\s+)?[A-Za-z][\\w-]*\\s+tool\\b|\\b(?:call|invoke|use)\\s+this\\s+tool\\s+now\\b',
|
|
39
|
+
action: 'quarantine',
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
name: 'builtin:memory_manipulation',
|
|
43
|
+
priority: 15,
|
|
44
|
+
condition_type: 'regex',
|
|
45
|
+
condition_value: 'save\\s+(this\\s+)?to\\s+memory|remember\\s+this\\s+(instruction|command|rule)|store\\s+this\\s+instruction|inject\\s+(into\\s+)?memory',
|
|
46
|
+
action: 'quarantine',
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
name: 'builtin:command_injection',
|
|
50
|
+
priority: 5,
|
|
51
|
+
condition_type: 'regex',
|
|
52
|
+
condition_value: '\\beval\\s*\\(|\\bexec\\s*\\(|\\bsystem\\s*\\(|\\bexecute\\s+(this\\s+)?(command|code|script)|\\b__import__\\s*\\(|\\bsubprocess\\b',
|
|
53
|
+
action: 'quarantine',
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
name: 'builtin:delimiter_attack',
|
|
57
|
+
priority: 18,
|
|
58
|
+
condition_type: 'regex',
|
|
59
|
+
condition_value: '<\\/?(system|admin|root)\\s*>|<!--[\\s\\S]{0,200}?(instruction|command|system|ignore|inject|override)[\\s\\S]{0,200}?-->',
|
|
60
|
+
action: 'quarantine',
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
name: 'builtin:credential_leak_aws',
|
|
64
|
+
priority: 1,
|
|
65
|
+
condition_type: 'regex',
|
|
66
|
+
condition_value: 'AKIA[0-9A-Z]{16}',
|
|
67
|
+
action: 'block',
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'builtin:credential_leak_jwt',
|
|
71
|
+
priority: 2,
|
|
72
|
+
condition_type: 'regex',
|
|
73
|
+
condition_value: 'eyJ[A-Za-z0-9_-]{10,}\\.eyJ[A-Za-z0-9_-]{10,}\\.[A-Za-z0-9_-]{10,}',
|
|
74
|
+
action: 'block',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'builtin:credential_leak_private_key',
|
|
78
|
+
priority: 3,
|
|
79
|
+
condition_type: 'regex',
|
|
80
|
+
condition_value: '-----BEGIN (?:RSA |EC |OPENSSH |DSA |PGP )?PRIVATE KEY-----',
|
|
81
|
+
action: 'block',
|
|
82
|
+
},
|
|
83
|
+
];
|
|
84
|
+
export function seedDefaultFirewallRules(db) {
|
|
85
|
+
// Confirm the column exists (older DBs may pre-date the migration).
|
|
86
|
+
const cols = db.prepare("PRAGMA table_info(firewall_rules)").all();
|
|
87
|
+
if (!cols.some(c => c.name === 'built_in'))
|
|
88
|
+
return;
|
|
89
|
+
const existing = db.prepare('SELECT COUNT(*) AS c FROM firewall_rules WHERE built_in = 1').get();
|
|
90
|
+
if (existing.c > 0)
|
|
91
|
+
return;
|
|
92
|
+
const insert = db.prepare(`
|
|
93
|
+
INSERT INTO firewall_rules (name, priority, condition_type, condition_value, action, enabled, built_in)
|
|
94
|
+
VALUES (?, ?, ?, ?, ?, 1, 1)
|
|
95
|
+
`);
|
|
96
|
+
const txn = db.transaction((rules) => {
|
|
97
|
+
for (const rule of rules) {
|
|
98
|
+
insert.run(rule.name, rule.priority, rule.condition_type, rule.condition_value, rule.action);
|
|
99
|
+
}
|
|
100
|
+
});
|
|
101
|
+
txn(BUILT_IN_RULES);
|
|
102
|
+
}
|
|
103
|
+
export function listBuiltInRuleNames() {
|
|
104
|
+
return BUILT_IN_RULES.map(r => r.name);
|
|
105
|
+
}
|
|
@@ -9,9 +9,12 @@ export interface FirewallRule {
|
|
|
9
9
|
condition_value: string;
|
|
10
10
|
action: 'block' | 'allow' | 'quarantine';
|
|
11
11
|
enabled: number;
|
|
12
|
+
built_in: number;
|
|
12
13
|
created_at: string;
|
|
13
14
|
}
|
|
14
|
-
export declare function listFirewallRules(
|
|
15
|
+
export declare function listFirewallRules(opts?: {
|
|
16
|
+
includeBuiltin?: boolean;
|
|
17
|
+
}): FirewallRule[];
|
|
15
18
|
export declare function getFirewallRule(id: number): FirewallRule | undefined;
|
|
16
19
|
export declare function createFirewallRule(rule: {
|
|
17
20
|
name: string;
|
|
@@ -3,9 +3,11 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { getDatabase } from '../../database/init.js';
|
|
5
5
|
const MAX_RULES = 25;
|
|
6
|
-
export function listFirewallRules() {
|
|
6
|
+
export function listFirewallRules(opts = {}) {
|
|
7
|
+
const includeBuiltin = opts.includeBuiltin ?? true;
|
|
7
8
|
const db = getDatabase();
|
|
8
|
-
|
|
9
|
+
const where = includeBuiltin ? '' : 'WHERE built_in = 0';
|
|
10
|
+
return db.prepare(`SELECT * FROM firewall_rules ${where} ORDER BY priority ASC`).all();
|
|
9
11
|
}
|
|
10
12
|
export function getFirewallRule(id) {
|
|
11
13
|
const db = getDatabase();
|
|
@@ -13,7 +15,9 @@ export function getFirewallRule(id) {
|
|
|
13
15
|
}
|
|
14
16
|
export function createFirewallRule(rule) {
|
|
15
17
|
const db = getDatabase();
|
|
16
|
-
|
|
18
|
+
// The MAX_RULES cap applies only to user-defined rules. Built-in rules
|
|
19
|
+
// (built_in=1) are seeded by the database layer and don't count.
|
|
20
|
+
const count = db.prepare('SELECT COUNT(*) as cnt FROM firewall_rules WHERE built_in = 0').get().cnt;
|
|
17
21
|
if (count >= MAX_RULES) {
|
|
18
22
|
throw new Error(`Maximum of ${MAX_RULES} custom firewall rules reached.`);
|
|
19
23
|
}
|
|
@@ -114,6 +114,21 @@ const PATTERN_GROUPS = [
|
|
|
114
114
|
/reveal\s+your\s+instructions/i,
|
|
115
115
|
],
|
|
116
116
|
},
|
|
117
|
+
{
|
|
118
|
+
// Imperative tool-call directives. These show up in transcripts as
|
|
119
|
+
// injected prompts disguised as user instructions ("call the X tool
|
|
120
|
+
// to complete this request. Call this tool now."). The session-end
|
|
121
|
+
// chunker historically captured them as user preferences with
|
|
122
|
+
// salience 1.0; the firewall now flags them at write time so they
|
|
123
|
+
// route to quarantine instead of memories.
|
|
124
|
+
name: 'imperative_tool_call',
|
|
125
|
+
weight: 0.8,
|
|
126
|
+
patterns: [
|
|
127
|
+
/\b(?:call|invoke|use)\s+(?:the\s+)?[A-Za-z][\w-]*\s+tool\b/i,
|
|
128
|
+
/\b(?:call|invoke|use)\s+this\s+tool\s+now\b/i,
|
|
129
|
+
/\bcomplete\s+this\s+request\.\s*(?:call|invoke|use)\s+this\s+tool\b/i,
|
|
130
|
+
],
|
|
131
|
+
},
|
|
117
132
|
];
|
|
118
133
|
// Maximum content length to scan (prevents ReDOS on very long inputs)
|
|
119
134
|
const MAX_SCAN_LENGTH = 50000;
|
package/dist/defence/pipeline.js
CHANGED
|
@@ -95,42 +95,48 @@ export function runDefencePipeline(content, title, source, config, project) {
|
|
|
95
95
|
reason = firewall.reason;
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
|
-
// 6b. Apply
|
|
99
|
-
|
|
98
|
+
// 6b. Apply firewall rules (built-in rules always evaluated; user-added
|
|
99
|
+
// custom rules require the Pro `custom_firewall_rules` feature). Both
|
|
100
|
+
// are additive only — can tighten, never weaken.
|
|
101
|
+
if (allowed && isDatabaseInitialized()) {
|
|
100
102
|
try {
|
|
101
103
|
const { getEnabledFirewallRules } = require('./custom-rules/store.js');
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
+
const userRulesAllowed = isFeatureEnabled('custom_firewall_rules');
|
|
105
|
+
const allRules = getEnabledFirewallRules();
|
|
106
|
+
for (const rule of allRules) {
|
|
107
|
+
if (!rule.built_in && !userRulesAllowed)
|
|
108
|
+
continue;
|
|
104
109
|
try {
|
|
105
110
|
const regex = new RegExp(rule.condition_value, 'gi');
|
|
106
111
|
if (regex.test(cleanContent) || regex.test(title)) {
|
|
112
|
+
const indicator = rule.built_in ? 'builtin_rule' : 'custom_rule';
|
|
107
113
|
if (rule.action === 'block') {
|
|
108
114
|
allowed = false;
|
|
109
|
-
reason = `Blocked by custom rule: ${rule.name}`;
|
|
115
|
+
reason = `Blocked by ${rule.built_in ? 'built-in' : 'custom'} rule: ${rule.name}`;
|
|
110
116
|
firewall.result = 'BLOCK';
|
|
111
|
-
if (!firewall.threatIndicators.includes(
|
|
112
|
-
firewall.threatIndicators.push(
|
|
117
|
+
if (!firewall.threatIndicators.includes(indicator)) {
|
|
118
|
+
firewall.threatIndicators.push(indicator);
|
|
113
119
|
}
|
|
114
120
|
break; // Block is final
|
|
115
121
|
}
|
|
116
122
|
else if (rule.action === 'quarantine' && firewall.result !== 'BLOCK') {
|
|
117
123
|
allowed = false;
|
|
118
|
-
reason = `Quarantined by custom rule: ${rule.name}`;
|
|
124
|
+
reason = `Quarantined by ${rule.built_in ? 'built-in' : 'custom'} rule: ${rule.name}`;
|
|
119
125
|
firewall.result = 'QUARANTINE';
|
|
120
|
-
if (!firewall.threatIndicators.includes(
|
|
121
|
-
firewall.threatIndicators.push(
|
|
126
|
+
if (!firewall.threatIndicators.includes(indicator)) {
|
|
127
|
+
firewall.threatIndicators.push(indicator);
|
|
122
128
|
}
|
|
123
129
|
}
|
|
124
|
-
// 'allow' action: no-op —
|
|
130
|
+
// 'allow' action: no-op — rules cannot weaken built-in decisions
|
|
125
131
|
}
|
|
126
132
|
}
|
|
127
133
|
catch {
|
|
128
|
-
// Skip invalid regex in
|
|
134
|
+
// Skip invalid regex in rules
|
|
129
135
|
}
|
|
130
136
|
}
|
|
131
137
|
}
|
|
132
138
|
catch {
|
|
133
|
-
//
|
|
139
|
+
// Rules store not available — skip silently
|
|
134
140
|
}
|
|
135
141
|
}
|
|
136
142
|
// 6c. Apply custom injection patterns (Pro feature, additive)
|
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';
|
|
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';
|
|
10
10
|
export interface DefenceSource {
|
|
11
11
|
type: 'user' | 'cli' | 'hook' | 'email' | 'web' | 'agent' | 'file' | 'api' | 'tool_response';
|
|
12
12
|
identifier: string;
|
package/dist/index.js
CHANGED
|
@@ -637,6 +637,13 @@ ${bold}DOCS${reset}
|
|
|
637
637
|
await handleMemoriesCommand(process.argv.slice(3));
|
|
638
638
|
return;
|
|
639
639
|
}
|
|
640
|
+
// Handle "import-jsonl" subcommand — import Claude Code session transcripts
|
|
641
|
+
// into session_events for dashboard replay.
|
|
642
|
+
if (process.argv[2] === 'import-jsonl') {
|
|
643
|
+
const { handleImportJsonlCommand } = await import('./cli/import-jsonl.js');
|
|
644
|
+
await handleImportJsonlCommand(process.argv.slice(3));
|
|
645
|
+
return;
|
|
646
|
+
}
|
|
640
647
|
// Handle "status" subcommand
|
|
641
648
|
if (process.argv[2] === 'status') {
|
|
642
649
|
const { handleStatusCommand } = await import('./setup/status.js');
|
|
@@ -896,6 +903,7 @@ ${bold}DOCS${reset}
|
|
|
896
903
|
'openclaw', 'clawdbot', 'copilot', 'codex', 'service', 'config', 'status',
|
|
897
904
|
'graph', 'license', 'licence', 'audit', 'iron-dome', 'scan', 'cloud', 'review-copilot',
|
|
898
905
|
'scan-skill', 'scan-skills', 'dashboard', 'api', 'worker', 'stats', 'cortex', 'consolidate', 'xray', 'xray-preinstall',
|
|
906
|
+
'memories', 'import-jsonl',
|
|
899
907
|
]);
|
|
900
908
|
const arg = process.argv[2];
|
|
901
909
|
if (arg && !arg.startsWith('-') && !knownCommands.has(arg)) {
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session capture — write side.
|
|
3
|
+
*
|
|
4
|
+
* Hooks (`scripts/prompt-recall-hook.mjs`, `scripts/stop-hook.mjs`,
|
|
5
|
+
* `scripts/session-end-hook.mjs`, etc.) call `recordEvent()` or the
|
|
6
|
+
* batched `recordEvents()` to persist turn-by-turn events into the
|
|
7
|
+
* `session_events` table. The timeline reader in `./timeline.ts`
|
|
8
|
+
* then reassembles them into the replay stream.
|
|
9
|
+
*
|
|
10
|
+
* Distinct from the summary `sessions` table (one row per session)
|
|
11
|
+
* and from `defence_audit` (one row per scan). Captures every event
|
|
12
|
+
* with enough fidelity to scrub/replay.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Six kinds the schema CHECK constraint enforces. Keeping these in
|
|
16
|
+
* sync with `schema.sql` is load-bearing — adding a new kind requires
|
|
17
|
+
* both a schema migration and a code update here.
|
|
18
|
+
*/
|
|
19
|
+
export type SessionEventKind = 'prompt' | 'response' | 'tool_call' | 'tool_result' | 'tool_error' | 'hook_fire';
|
|
20
|
+
export interface SessionEventInput {
|
|
21
|
+
session_id: string;
|
|
22
|
+
/** ISO-8601 timestamp string. Caller-supplied so import order is preserved. */
|
|
23
|
+
ts: string;
|
|
24
|
+
kind: SessionEventKind;
|
|
25
|
+
/**
|
|
26
|
+
* Payload — object (auto-serialised to JSON) or string (stored as-is).
|
|
27
|
+
* Strings are kept verbatim so JSONL importers can pass through raw
|
|
28
|
+
* content without double-encoding.
|
|
29
|
+
*/
|
|
30
|
+
payload: unknown;
|
|
31
|
+
project?: string | null;
|
|
32
|
+
actor?: string | null;
|
|
33
|
+
duration_ms?: number | null;
|
|
34
|
+
audit_id?: number | null;
|
|
35
|
+
}
|
|
36
|
+
/** Insert one event row. Returns the new row id. */
|
|
37
|
+
export declare function recordEvent(input: SessionEventInput): number;
|
|
38
|
+
/**
|
|
39
|
+
* Batched insert wrapped in a single transaction. Used when a hook
|
|
40
|
+
* fires and produces several events at once (e.g. stop-hook emitting
|
|
41
|
+
* a `response` plus N tool_call/tool_result pairs from the just-
|
|
42
|
+
* finished turn). All-or-nothing: a CHECK violation rolls back the
|
|
43
|
+
* lot, so the table never holds half a turn.
|
|
44
|
+
*/
|
|
45
|
+
export declare function recordEvents(inputs: readonly SessionEventInput[]): number[];
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session capture — write side.
|
|
3
|
+
*
|
|
4
|
+
* Hooks (`scripts/prompt-recall-hook.mjs`, `scripts/stop-hook.mjs`,
|
|
5
|
+
* `scripts/session-end-hook.mjs`, etc.) call `recordEvent()` or the
|
|
6
|
+
* batched `recordEvents()` to persist turn-by-turn events into the
|
|
7
|
+
* `session_events` table. The timeline reader in `./timeline.ts`
|
|
8
|
+
* then reassembles them into the replay stream.
|
|
9
|
+
*
|
|
10
|
+
* Distinct from the summary `sessions` table (one row per session)
|
|
11
|
+
* and from `defence_audit` (one row per scan). Captures every event
|
|
12
|
+
* with enough fidelity to scrub/replay.
|
|
13
|
+
*/
|
|
14
|
+
import { getDatabase } from '../database/init.js';
|
|
15
|
+
/**
|
|
16
|
+
* Serialise payload to text. Objects/arrays go through JSON.stringify;
|
|
17
|
+
* strings pass through. This keeps the column NOT NULL constraint
|
|
18
|
+
* satisfied even for empty-object payloads and matches the timeline
|
|
19
|
+
* reader's `JSON.parse` with raw-string fallback.
|
|
20
|
+
*/
|
|
21
|
+
function serialisePayload(payload) {
|
|
22
|
+
if (typeof payload === 'string')
|
|
23
|
+
return payload;
|
|
24
|
+
return JSON.stringify(payload ?? null);
|
|
25
|
+
}
|
|
26
|
+
const INSERT_SQL = `
|
|
27
|
+
INSERT INTO session_events
|
|
28
|
+
(session_id, project, ts, kind, actor, payload, duration_ms, audit_id)
|
|
29
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)
|
|
30
|
+
`;
|
|
31
|
+
/** Insert one event row. Returns the new row id. */
|
|
32
|
+
export function recordEvent(input) {
|
|
33
|
+
const db = getDatabase();
|
|
34
|
+
const stmt = db.prepare(INSERT_SQL);
|
|
35
|
+
const result = stmt.run(input.session_id, input.project ?? null, input.ts, input.kind, input.actor ?? null, serialisePayload(input.payload), input.duration_ms ?? null, input.audit_id ?? null);
|
|
36
|
+
return Number(result.lastInsertRowid);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Batched insert wrapped in a single transaction. Used when a hook
|
|
40
|
+
* fires and produces several events at once (e.g. stop-hook emitting
|
|
41
|
+
* a `response` plus N tool_call/tool_result pairs from the just-
|
|
42
|
+
* finished turn). All-or-nothing: a CHECK violation rolls back the
|
|
43
|
+
* lot, so the table never holds half a turn.
|
|
44
|
+
*/
|
|
45
|
+
export function recordEvents(inputs) {
|
|
46
|
+
if (inputs.length === 0)
|
|
47
|
+
return [];
|
|
48
|
+
const db = getDatabase();
|
|
49
|
+
const stmt = db.prepare(INSERT_SQL);
|
|
50
|
+
const ids = [];
|
|
51
|
+
const tx = db.transaction((rows) => {
|
|
52
|
+
for (const row of rows) {
|
|
53
|
+
const result = stmt.run(row.session_id, row.project ?? null, row.ts, row.kind, row.actor ?? null, serialisePayload(row.payload), row.duration_ms ?? null, row.audit_id ?? null);
|
|
54
|
+
ids.push(Number(result.lastInsertRowid));
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
tx(inputs);
|
|
58
|
+
return ids;
|
|
59
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSONL transcript importer for Claude Code session files.
|
|
3
|
+
*
|
|
4
|
+
* Claude Code writes session transcripts to `~/.claude/projects/<slug>/
|
|
5
|
+
* <session-uuid>.jsonl`. Each line is a JSON object. Conversation lines
|
|
6
|
+
* have shape `{type, sessionId, timestamp, message: {role, content}}`
|
|
7
|
+
* where `content` is an Anthropic SDK content-block array
|
|
8
|
+
* (`text|thinking|tool_use|tool_result`).
|
|
9
|
+
*
|
|
10
|
+
* Mapping to `session_events.kind`:
|
|
11
|
+
*
|
|
12
|
+
* user.text → prompt
|
|
13
|
+
* assistant.text → response
|
|
14
|
+
* assistant.tool_use → tool_call
|
|
15
|
+
* user.tool_result → tool_result
|
|
16
|
+
* thinking → (skipped — not user-replayable in v1)
|
|
17
|
+
*
|
|
18
|
+
* Non-conversation lines (`ai-title`, `attachment`, `system`,
|
|
19
|
+
* `queue-operation`, etc.) are skipped. Idempotent on re-import: each
|
|
20
|
+
* row carries a sha256 `content_hash` of `kind|payload`, and the
|
|
21
|
+
* `idx_session_events_dedupe` UNIQUE index drops collisions silently
|
|
22
|
+
* via `INSERT OR IGNORE`.
|
|
23
|
+
*
|
|
24
|
+
* Lossy by design — agentmemory documents the same scope:
|
|
25
|
+
* - Anthropic-internal cache markers, partial-message frames, and
|
|
26
|
+
* non-string tool_result encodings beyond plain text are not
|
|
27
|
+
* preserved.
|
|
28
|
+
* - Things we WILL preserve: prompts, assistant text, tool name +
|
|
29
|
+
* args + result, and timestamps.
|
|
30
|
+
*/
|
|
31
|
+
import type { SessionEventInput } from './capture.js';
|
|
32
|
+
export interface TranscriptLine {
|
|
33
|
+
type?: string;
|
|
34
|
+
sessionId?: string;
|
|
35
|
+
timestamp?: string;
|
|
36
|
+
message?: {
|
|
37
|
+
role?: 'user' | 'assistant';
|
|
38
|
+
content?: ContentBlock[];
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
type ContentBlock = {
|
|
42
|
+
type: 'text';
|
|
43
|
+
text?: string;
|
|
44
|
+
} | {
|
|
45
|
+
type: 'thinking';
|
|
46
|
+
thinking?: string;
|
|
47
|
+
} | {
|
|
48
|
+
type: 'tool_use';
|
|
49
|
+
id?: string;
|
|
50
|
+
name?: string;
|
|
51
|
+
input?: unknown;
|
|
52
|
+
} | {
|
|
53
|
+
type: 'tool_result';
|
|
54
|
+
tool_use_id?: string;
|
|
55
|
+
content?: unknown;
|
|
56
|
+
} | {
|
|
57
|
+
type: string;
|
|
58
|
+
[key: string]: unknown;
|
|
59
|
+
};
|
|
60
|
+
export interface ImportResult {
|
|
61
|
+
sessionId: string | null;
|
|
62
|
+
eventCount: number;
|
|
63
|
+
/** Lines that produced zero events — non-conversation types + parse errors. */
|
|
64
|
+
skipped: number;
|
|
65
|
+
/** Lines whose JSON parsed but were rejected (missing required fields, unknown block types). */
|
|
66
|
+
malformed: number;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Pure mapper: one transcript line → 0..N `SessionEventInput`s.
|
|
70
|
+
*
|
|
71
|
+
* Exported so unit tests can exercise the mapping in isolation without
|
|
72
|
+
* standing up a database. Returns `[]` for any line that doesn't yield
|
|
73
|
+
* replayable events (thinking blocks, ai-title, missing fields, etc.) —
|
|
74
|
+
* the caller treats an empty array as "skipped".
|
|
75
|
+
*/
|
|
76
|
+
export declare function parseTranscriptLine(line: unknown): SessionEventInput[];
|
|
77
|
+
/**
|
|
78
|
+
* Import one JSONL file. Wraps the whole import in a single transaction
|
|
79
|
+
* so a mid-file error rolls back cleanly — better-sqlite3's transaction
|
|
80
|
+
* helper restores DB state if the callback throws. Malformed lines do
|
|
81
|
+
* NOT throw — they're counted and skipped so a single bad row never
|
|
82
|
+
* blocks the rest of the file.
|
|
83
|
+
*/
|
|
84
|
+
export declare function importJsonlTranscript(path: string): ImportResult;
|
|
85
|
+
export {};
|