shieldcortex 4.28.1 → 4.29.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/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/cli/doctor.d.ts +17 -0
- package/dist/cli/doctor.js +44 -0
- package/dist/cli/memory.d.ts +23 -0
- package/dist/cli/memory.js +101 -0
- package/dist/database/init.d.ts +9 -0
- package/dist/database/init.js +32 -4
- package/dist/database/migrations.js +126 -0
- package/dist/memory/consolidate.d.ts +82 -6
- package/dist/memory/consolidate.js +287 -117
- package/dist/setup/openclaw.d.ts +26 -0
- package/dist/setup/openclaw.js +61 -0
- package/dist/tools/remember.js +24 -3
- package/hooks/openclaw/cortex-memory/handler.ts +223 -171
- package/hooks/openclaw/cortex-memory/runtime.mjs +64 -0
- package/package.json +1 -1
- package/scripts/lib/dedup.mjs +99 -0
- package/scripts/lib/openclaw-extract.mjs +129 -0
- package/scripts/lib/recall-log.mjs +16 -1
- package/scripts/lib/recall-relevance.mjs +191 -0
- package/scripts/lib/salience.mjs +8 -3
- package/scripts/lib/save-memory.mjs +62 -6
- package/scripts/lib/session-context.mjs +30 -0
- package/scripts/postinstall.mjs +29 -10
- package/scripts/prompt-recall-hook.mjs +118 -15
- package/scripts/session-start-hook.mjs +17 -6
- /package/dashboard/.next/standalone/dashboard/.next/static/{N9XiRuuRX4eTtiJFa43tY → 0HpUm8SRvm9fnWVO0OBB2}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{N9XiRuuRX4eTtiJFa43tY → 0HpUm8SRvm9fnWVO0OBB2}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{N9XiRuuRX4eTtiJFa43tY → 0HpUm8SRvm9fnWVO0OBB2}/_ssgManifest.js +0 -0
package/dist/setup/openclaw.js
CHANGED
|
@@ -209,6 +209,67 @@ function legacyHookDirs(hooksDir) {
|
|
|
209
209
|
function hasRequiredHookFiles(dir) {
|
|
210
210
|
return HOOK_FILES.every(file => fs.existsSync(path.join(dir, file)));
|
|
211
211
|
}
|
|
212
|
+
/**
|
|
213
|
+
* The standard installed-hook destination: `~/.openclaw/hooks/cortex-memory`.
|
|
214
|
+
* Resolves the real user's home (sudo-aware) so doctor/postinstall agree with
|
|
215
|
+
* the install path.
|
|
216
|
+
*/
|
|
217
|
+
export function defaultHookDestDir() {
|
|
218
|
+
return path.join(resolveUserHome(), '.openclaw', 'hooks', HOOK_NAME);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Single source of truth for "the installed hook copy is out of date".
|
|
222
|
+
*
|
|
223
|
+
* The cortex-memory hook is installed by FILE COPY (see `copyHookFiles`) into
|
|
224
|
+
* `~/.openclaw/hooks/cortex-memory/`. A package update does NOT automatically
|
|
225
|
+
* re-copy it, so the installed `handler.ts` / `runtime.mjs` can drift behind
|
|
226
|
+
* the package's `HOOK_SOURCE` version. This compares every HOOK_FILE in
|
|
227
|
+
* `destDir` against the packaged source by content.
|
|
228
|
+
*
|
|
229
|
+
* Pure + synchronous (fs reads only, no writes, no side effects). Returns
|
|
230
|
+
* `true` if any required file is missing from `destDir` OR differs byte-for-byte
|
|
231
|
+
* from the packaged source. Returns `false` only when every file is present and
|
|
232
|
+
* identical. On any unexpected read error it returns `true` (fail toward
|
|
233
|
+
* "refresh needed") so a half-readable install is never reported as current.
|
|
234
|
+
*
|
|
235
|
+
* If the package's own `HOOK_SOURCE` is missing (corrupt/partial package), the
|
|
236
|
+
* comparison is impossible, so this returns `false` — we can't claim the
|
|
237
|
+
* install is stale relative to a source we can't read.
|
|
238
|
+
*/
|
|
239
|
+
export function hookFilesStale(destDir = defaultHookDestDir()) {
|
|
240
|
+
// No installed copy at all → definitely needs (re)install.
|
|
241
|
+
if (!fs.existsSync(destDir))
|
|
242
|
+
return true;
|
|
243
|
+
// No packaged source to compare against → can't prove staleness.
|
|
244
|
+
if (!fs.existsSync(HOOK_SOURCE))
|
|
245
|
+
return false;
|
|
246
|
+
for (const file of HOOK_FILES) {
|
|
247
|
+
const srcPath = path.join(HOOK_SOURCE, file);
|
|
248
|
+
const destPath = path.join(destDir, file);
|
|
249
|
+
try {
|
|
250
|
+
if (!fs.existsSync(srcPath)) {
|
|
251
|
+
// Packaged source is missing this file — can't compare it; skip.
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
if (!fs.existsSync(destPath))
|
|
255
|
+
return true; // installed copy missing a file
|
|
256
|
+
const srcBuf = fs.readFileSync(srcPath);
|
|
257
|
+
const destBuf = fs.readFileSync(destPath);
|
|
258
|
+
if (!srcBuf.equals(destBuf))
|
|
259
|
+
return true; // content differs → stale
|
|
260
|
+
}
|
|
261
|
+
catch {
|
|
262
|
+
// Unreadable file on either side — treat as stale so the user re-copies.
|
|
263
|
+
// DELIBERATE ASYMMETRY with the inline staleness loop in
|
|
264
|
+
// hooks/openclaw/cortex-memory/handler.ts (selfCheckAndHeal), which does
|
|
265
|
+
// NOT flip `stale` on a read error: that runs in the long-lived gateway
|
|
266
|
+
// and must stay quiet on transient errors. This path backs `doctor`, which
|
|
267
|
+
// SHOULD nag on a half-readable install. Keep them divergent.
|
|
268
|
+
return true;
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
return false;
|
|
272
|
+
}
|
|
212
273
|
function copyHookFiles(sourceDir, destDir) {
|
|
213
274
|
fs.mkdirSync(destDir, { recursive: true });
|
|
214
275
|
for (const file of HOOK_FILES) {
|
package/dist/tools/remember.js
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
import { z } from 'zod';
|
|
7
7
|
import { addMemory, searchMemories, detectRelationships, createMemoryLink, getLastTruncationInfo } from '../memory/store.js';
|
|
8
|
-
import { analyzeSalienceFactors, explainSalience } from '../memory/salience.js';
|
|
8
|
+
import { calculateSalience, analyzeSalienceFactors, explainSalience } from '../memory/salience.js';
|
|
9
9
|
import { formatErrorForMcp } from '../errors.js';
|
|
10
10
|
import { resolveProject } from '../context/project-context.js';
|
|
11
11
|
import { shouldFilterMemory } from '../memory/save-filter.js';
|
|
@@ -116,7 +116,7 @@ export async function executeRemember(input) {
|
|
|
116
116
|
error: `Memory filtered: ${filterResult.reason}${filterResult.warning ? ' — ' + filterResult.warning : ''}`,
|
|
117
117
|
};
|
|
118
118
|
}
|
|
119
|
-
const
|
|
119
|
+
const memoryInput = {
|
|
120
120
|
title,
|
|
121
121
|
content,
|
|
122
122
|
category: input.category,
|
|
@@ -129,7 +129,28 @@ export async function executeRemember(input) {
|
|
|
129
129
|
metadata: Object.keys(metadata).length > 0 ? metadata : undefined,
|
|
130
130
|
memoryPurpose: input.memoryPurpose,
|
|
131
131
|
memoryScope: input.memoryScope,
|
|
132
|
-
}
|
|
132
|
+
};
|
|
133
|
+
// Defence-in-depth against the "salience wall": automated/hook callers
|
|
134
|
+
// (e.g. the OpenClaw hook, which shells out `remember` with importance:"high"
|
|
135
|
+
// /"critical" and sourceType:"hook") must not mint 0.8/1.0-salience memories
|
|
136
|
+
// the way a human deliberately saving something can. Cap the FINAL resolved
|
|
137
|
+
// salience — covering BOTH the importance-derived override and the
|
|
138
|
+
// calculateSalience fall-through — at the same 0.6 the dedicated auto-extract
|
|
139
|
+
// writer enforces, so even a stale/un-refactored hook can't exceed it by ANY
|
|
140
|
+
// path. Interactive remembers (no source, or a user/cli/agent source) stay
|
|
141
|
+
// uncapped — deliberate intent is honoured. Resolve salience exactly as
|
|
142
|
+
// addMemory does, from the SAME memoryInput object, so there is no input-shape
|
|
143
|
+
// drift, then clamp and pass it verbatim.
|
|
144
|
+
//
|
|
145
|
+
// Canonical constant: scripts/lib/extract-memorable-segments.mjs:24
|
|
146
|
+
// (AUTO_EXTRACT_SALIENCE_CAP = 0.6). It lives in a build-script .mjs outside
|
|
147
|
+
// the compiled src/ surface, so the value is mirrored here.
|
|
148
|
+
if (derivedSource?.type === 'hook') {
|
|
149
|
+
const AUTO_EXTRACT_SALIENCE_CAP = 0.6;
|
|
150
|
+
const effective = memoryInput.salience ?? calculateSalience(memoryInput);
|
|
151
|
+
memoryInput.salience = Math.min(effective, AUTO_EXTRACT_SALIENCE_CAP);
|
|
152
|
+
}
|
|
153
|
+
const memory = addMemory(memoryInput, undefined, derivedSource ?? { type: 'cli', identifier: 'mcp' });
|
|
133
154
|
// Auto-detect and create relationships with existing memories
|
|
134
155
|
let linksCreated = 0;
|
|
135
156
|
try {
|
|
@@ -10,14 +10,34 @@ import { createHash } from "node:crypto";
|
|
|
10
10
|
import fs from "node:fs/promises";
|
|
11
11
|
import { homedir } from "node:os";
|
|
12
12
|
import path from "node:path";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
13
14
|
import { createOpenClawRuntime } from "./runtime.mjs";
|
|
14
15
|
|
|
15
16
|
// ==================== SERVER COMMAND RESOLUTION ====================
|
|
16
17
|
|
|
18
|
+
// Transcript line format shared by the producer (getRecentMessages builds
|
|
19
|
+
// `${role}: ${text}`) and the consumer (assistantConversationText filters on
|
|
20
|
+
// this prefix). Centralised so a format change can't silently break the filter.
|
|
21
|
+
const ASSISTANT_PREFIX = "assistant:";
|
|
22
|
+
|
|
23
|
+
// Process-global by design: these one-shot notice flags and the load-null
|
|
24
|
+
// cache live for the lifetime of the long-lived gateway process. A gateway
|
|
25
|
+
// restart is the intended upgrade boundary that resets them.
|
|
17
26
|
let _autoMemoryNoticeShown = false;
|
|
27
|
+
let _noExtractNoticeShown = false;
|
|
18
28
|
const runtime = createOpenClawRuntime({ logPrefix: "[cortex-memory]" });
|
|
19
29
|
const loadShieldConfig = runtime.loadShieldConfig;
|
|
20
30
|
const callCortex = runtime.callCortex;
|
|
31
|
+
// Pure chunker wrapper loader (resolves the local install's hardened
|
|
32
|
+
// extractor). Returns null when no local install is resolvable — in which
|
|
33
|
+
// case auto-capture is simply skipped (we do NOT regrow the old high-salience
|
|
34
|
+
// bespoke-extractor path). The wrapper imports nothing native; persistence
|
|
35
|
+
// still flows only through callCortex's mcporter shell-out.
|
|
36
|
+
const loadOpenClawExtract = runtime.loadOpenClawExtract;
|
|
37
|
+
// Resolves the ShieldCortex package root from the resolved server binary (no
|
|
38
|
+
// DB access). Used by selfCheckAndHeal to compare the running hook against the
|
|
39
|
+
// packaged source for staleness — warn-only, never re-copies from the gateway.
|
|
40
|
+
const resolvePackageRoot = runtime.resolvePackageRoot;
|
|
21
41
|
|
|
22
42
|
async function isOpenClawAutoMemoryEnabled() {
|
|
23
43
|
const config = await loadShieldConfig();
|
|
@@ -251,67 +271,29 @@ async function scanInstalledHooks() {
|
|
|
251
271
|
}
|
|
252
272
|
|
|
253
273
|
// ==================== CONTENT EXTRACTION ====================
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
/\b(?:fixed|resolved|solved)\s+(?:by|with|using)\b/i,
|
|
263
|
-
/\b(?:the\s+)?(?:solution|fix|root\s*cause|bug)\s+(?:was|is)\b/i,
|
|
264
|
-
],
|
|
265
|
-
learning: [
|
|
266
|
-
/\b(?:learned|discovered|turns?\s+out|figured\s+out|realized)\b/i,
|
|
267
|
-
/\b(?:TIL|today\s+I\s+learned)\b/i,
|
|
268
|
-
],
|
|
269
|
-
preference: [
|
|
270
|
-
/\b(?:I|we|you\s+should)\s+(?:always|never)\b/i,
|
|
271
|
-
/\b(?:always\s+use|never\s+use|never\s+commit)\b/i,
|
|
272
|
-
/\bprefer(?:\s+to)?\s+\w+/i,
|
|
273
|
-
/\bshould\s+always\b/i,
|
|
274
|
-
],
|
|
275
|
-
note: [
|
|
276
|
-
/\b(?:important|remember|key\s+point|crucial|note)\s*:/i,
|
|
277
|
-
],
|
|
278
|
-
};
|
|
274
|
+
//
|
|
275
|
+
// Extraction is delegated to the hardened centralized chunker via the pure
|
|
276
|
+
// `openclaw-extract` wrapper (resolved through runtime.loadOpenClawExtract).
|
|
277
|
+
// The old bespoke regex extractor lived here and mislabelled categories,
|
|
278
|
+
// produced clause fragments, and minted high/critical-salience memories (the
|
|
279
|
+
// "salience wall"). It is intentionally gone — the chunker is now the single
|
|
280
|
+
// source of truth for extraction quality and taxonomy. Persistence below is
|
|
281
|
+
// uniformly importance:"normal" (0.5, capped well under the wall).
|
|
279
282
|
|
|
280
283
|
/**
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
*
|
|
284
|
+
* Join transcript lines into conversation text, keeping ONLY assistant-authored
|
|
285
|
+
* lines. getRecentMessages returns "role: content" strings for both user and
|
|
286
|
+
* assistant turns; for the first ship we extract from assistant text only
|
|
287
|
+
* (lowest-risk: don't mine user-typed prose). Returns "" if nothing qualifies.
|
|
284
288
|
*/
|
|
285
|
-
function
|
|
286
|
-
const
|
|
287
|
-
const seen = new Set();
|
|
288
|
-
|
|
289
|
+
function assistantConversationText(messages: string[]): string {
|
|
290
|
+
const parts: string[] = [];
|
|
289
291
|
for (const msg of messages) {
|
|
290
|
-
if (!msg.startsWith(
|
|
291
|
-
const text = msg.slice(
|
|
292
|
-
if (text.length
|
|
293
|
-
|
|
294
|
-
for (const [category, patterns] of Object.entries(PATTERNS)) {
|
|
295
|
-
for (const pattern of patterns) {
|
|
296
|
-
if (pattern.test(text)) {
|
|
297
|
-
const title = text.slice(0, 80).replace(/["\n]/g, " ").trim();
|
|
298
|
-
if (seen.has(title)) break;
|
|
299
|
-
seen.add(title);
|
|
300
|
-
|
|
301
|
-
extracted.push({
|
|
302
|
-
title,
|
|
303
|
-
content: text.slice(0, 500),
|
|
304
|
-
category,
|
|
305
|
-
});
|
|
306
|
-
break;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
if (extracted.length >= 5) break;
|
|
310
|
-
}
|
|
311
|
-
if (extracted.length >= 5) break;
|
|
292
|
+
if (typeof msg !== "string" || !msg.startsWith(ASSISTANT_PREFIX)) continue;
|
|
293
|
+
const text = msg.slice(ASSISTANT_PREFIX.length).trim();
|
|
294
|
+
if (text.length > 0) parts.push(text);
|
|
312
295
|
}
|
|
313
|
-
|
|
314
|
-
return extracted;
|
|
296
|
+
return parts.join("\n");
|
|
315
297
|
}
|
|
316
298
|
|
|
317
299
|
// ==================== SESSION FILE READER ====================
|
|
@@ -338,7 +320,11 @@ async function getRecentMessages(sessionFilePath) {
|
|
|
338
320
|
? msg.content.find((c) => c.type === "text")?.text
|
|
339
321
|
: msg.content;
|
|
340
322
|
if (text && !text.startsWith("/")) {
|
|
341
|
-
|
|
323
|
+
// Producer side of the transcript line format. The assistant
|
|
324
|
+
// prefix is tied to ASSISTANT_PREFIX so the consumer
|
|
325
|
+
// (assistantConversationText) filter can't silently drift.
|
|
326
|
+
const prefix = msg.role === "assistant" ? ASSISTANT_PREFIX : `${msg.role}:`;
|
|
327
|
+
messages.push(`${prefix} ${text}`);
|
|
342
328
|
}
|
|
343
329
|
}
|
|
344
330
|
}
|
|
@@ -355,9 +341,16 @@ async function getRecentMessages(sessionFilePath) {
|
|
|
355
341
|
// ==================== EVENT HANDLERS ====================
|
|
356
342
|
|
|
357
343
|
/**
|
|
358
|
-
*
|
|
344
|
+
* Shared session-extraction routine for both /new (onSessionEnd) and
|
|
345
|
+
* /stop|/clear|/exit (onSessionStop). They were ~95% identical; the only
|
|
346
|
+
* differences are which sessionEntry to read, the persisted tags +
|
|
347
|
+
* source-identifier, and the user-facing "done" message. Behaviour is
|
|
348
|
+
* otherwise identical — gateway-safe persistence via callCortex only.
|
|
349
|
+
*
|
|
350
|
+
* @param {object} event
|
|
351
|
+
* @param {{ sessionEntry: object, tags: string, sourceIdentifier: string, doneMessage: (n: number) => string }} opts
|
|
359
352
|
*/
|
|
360
|
-
async function
|
|
353
|
+
async function runSessionExtraction(event, { sessionEntry, tags, sourceIdentifier, doneMessage }) {
|
|
361
354
|
if (!(await isOpenClawAutoMemoryEnabled())) {
|
|
362
355
|
if (!_autoMemoryNoticeShown) {
|
|
363
356
|
console.log("[cortex-memory] Auto memory extraction disabled (set openclawAutoMemory=true to enable)");
|
|
@@ -367,7 +360,6 @@ async function onSessionEnd(event) {
|
|
|
367
360
|
}
|
|
368
361
|
|
|
369
362
|
const context = event.context || {};
|
|
370
|
-
const sessionEntry = context.previousSessionEntry || context.sessionEntry || {};
|
|
371
363
|
const sessionFile = sessionEntry.sessionFile;
|
|
372
364
|
|
|
373
365
|
if (!sessionFile) {
|
|
@@ -381,7 +373,22 @@ async function onSessionEnd(event) {
|
|
|
381
373
|
return;
|
|
382
374
|
}
|
|
383
375
|
|
|
384
|
-
const
|
|
376
|
+
const conversationText = assistantConversationText(messages);
|
|
377
|
+
if (conversationText.length === 0) {
|
|
378
|
+
console.log("[cortex-memory] No assistant content to extract");
|
|
379
|
+
return;
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
const extract = await loadOpenClawExtract();
|
|
383
|
+
if (!extract) {
|
|
384
|
+
if (!_noExtractNoticeShown) {
|
|
385
|
+
console.log("[cortex-memory] No resolvable local install — skipping auto-extraction (no fallback)");
|
|
386
|
+
_noExtractNoticeShown = true;
|
|
387
|
+
}
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
const memories = extract.extractSessionMemories(conversationText);
|
|
385
392
|
if (memories.length === 0) {
|
|
386
393
|
console.log("[cortex-memory] No high-salience content found");
|
|
387
394
|
return;
|
|
@@ -401,12 +408,13 @@ async function onSessionEnd(event) {
|
|
|
401
408
|
title: mem.title,
|
|
402
409
|
content: mem.content,
|
|
403
410
|
category: mem.category,
|
|
411
|
+
memoryPurpose: mem.memoryPurpose,
|
|
404
412
|
project: "openclaw",
|
|
405
413
|
scope: "global",
|
|
406
|
-
importance: "
|
|
407
|
-
tags
|
|
414
|
+
importance: "normal",
|
|
415
|
+
tags,
|
|
408
416
|
sourceType: "hook",
|
|
409
|
-
sourceIdentifier
|
|
417
|
+
sourceIdentifier,
|
|
410
418
|
workspaceDir: context.workspaceDir || "",
|
|
411
419
|
});
|
|
412
420
|
if (result) {
|
|
@@ -420,79 +428,37 @@ async function onSessionEnd(event) {
|
|
|
420
428
|
|
|
421
429
|
// Provide visible feedback to user
|
|
422
430
|
if (saved > 0 && event.messages) {
|
|
423
|
-
event.messages.push(
|
|
431
|
+
event.messages.push(doneMessage(saved));
|
|
424
432
|
}
|
|
425
433
|
}
|
|
426
434
|
|
|
435
|
+
/**
|
|
436
|
+
* Handle command:new — extract memories from ending session
|
|
437
|
+
*/
|
|
438
|
+
async function onSessionEnd(event) {
|
|
439
|
+
const context = event.context || {};
|
|
440
|
+
await runSessionExtraction(event, {
|
|
441
|
+
sessionEntry: context.previousSessionEntry || context.sessionEntry || {},
|
|
442
|
+
tags: "auto-extracted,openclaw-hook",
|
|
443
|
+
sourceIdentifier: "openclaw-session-end",
|
|
444
|
+
doneMessage: (n) =>
|
|
445
|
+
`🧠 ShieldCortex: Saved ${n} memor${n === 1 ? "y" : "ies"} from this session`,
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
|
|
427
449
|
/**
|
|
428
450
|
* Handle command:stop — extract memories before session ends
|
|
429
451
|
* This fires when user explicitly calls /stop
|
|
430
452
|
*/
|
|
431
453
|
async function onSessionStop(event) {
|
|
432
|
-
if (!(await isOpenClawAutoMemoryEnabled())) {
|
|
433
|
-
if (!_autoMemoryNoticeShown) {
|
|
434
|
-
console.log("[cortex-memory] Auto memory extraction disabled (set openclawAutoMemory=true to enable)");
|
|
435
|
-
_autoMemoryNoticeShown = true;
|
|
436
|
-
}
|
|
437
|
-
return;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
454
|
const context = event.context || {};
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
const messages = await getRecentMessages(sessionFile);
|
|
450
|
-
if (messages.length === 0) {
|
|
451
|
-
console.log("[cortex-memory] No messages to extract on stop");
|
|
452
|
-
return;
|
|
453
|
-
}
|
|
454
|
-
|
|
455
|
-
const memories = extractMemories(messages);
|
|
456
|
-
if (memories.length === 0) {
|
|
457
|
-
console.log("[cortex-memory] No high-salience content found on stop");
|
|
458
|
-
return;
|
|
459
|
-
}
|
|
460
|
-
|
|
461
|
-
const noveltyGate = await getSharedNoveltyGate();
|
|
462
|
-
let saved = 0;
|
|
463
|
-
let skipped = 0;
|
|
464
|
-
for (const mem of memories) {
|
|
465
|
-
const novelty = noveltyGate.inspect(mem.content);
|
|
466
|
-
if (!novelty.allow) {
|
|
467
|
-
skipped++;
|
|
468
|
-
continue;
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
const result = await callCortex("remember", {
|
|
472
|
-
title: mem.title,
|
|
473
|
-
content: mem.content,
|
|
474
|
-
category: mem.category,
|
|
475
|
-
project: "openclaw",
|
|
476
|
-
scope: "global",
|
|
477
|
-
importance: "high",
|
|
478
|
-
tags: "auto-extracted,openclaw-hook,session-stop",
|
|
479
|
-
sourceType: "hook",
|
|
480
|
-
sourceIdentifier: "openclaw-session-stop",
|
|
481
|
-
workspaceDir: context.workspaceDir || "",
|
|
482
|
-
});
|
|
483
|
-
if (result) {
|
|
484
|
-
saved++;
|
|
485
|
-
noveltyGate.remember(mem, novelty);
|
|
486
|
-
}
|
|
487
|
-
}
|
|
488
|
-
await noveltyGate.flush();
|
|
489
|
-
|
|
490
|
-
console.log(`[cortex-memory] Saved ${saved}/${memories.length} memories on session stop (${skipped} skipped as duplicates)`);
|
|
491
|
-
|
|
492
|
-
// Provide visible feedback to user
|
|
493
|
-
if (saved > 0 && event.messages) {
|
|
494
|
-
event.messages.push(`🧠 ShieldCortex: Saved ${saved} memor${saved === 1 ? 'y' : 'ies'} before session end`);
|
|
495
|
-
}
|
|
455
|
+
await runSessionExtraction(event, {
|
|
456
|
+
sessionEntry: context.sessionEntry || {},
|
|
457
|
+
tags: "auto-extracted,openclaw-hook,session-stop",
|
|
458
|
+
sourceIdentifier: "openclaw-session-stop",
|
|
459
|
+
doneMessage: (n) =>
|
|
460
|
+
`🧠 ShieldCortex: Saved ${n} memor${n === 1 ? "y" : "ies"} before session end`,
|
|
461
|
+
});
|
|
496
462
|
}
|
|
497
463
|
|
|
498
464
|
/**
|
|
@@ -531,43 +497,54 @@ async function onBootstrap(event) {
|
|
|
531
497
|
}
|
|
532
498
|
|
|
533
499
|
/**
|
|
534
|
-
* Keyword
|
|
535
|
-
*
|
|
500
|
+
* Keyword trigger phrases. Order matters: more specific triggers should come
|
|
501
|
+
* first (the first match wins). Each entry carries the AUTHORITATIVE chunker
|
|
502
|
+
* extractorType for its phrase — the trigger phrase is the classification
|
|
503
|
+
* signal ("the fix was" → error-fix, "i prefer" → preference), so we pass it
|
|
504
|
+
* straight into extractKeywordMemory rather than re-guessing from content
|
|
505
|
+
* (which collapsed everything to `note`). Salience stays uniform across all
|
|
506
|
+
* triggers (importance:"normal" → 0.5, capped well under the wall); the old
|
|
507
|
+
* per-trigger category/importance fields are gone — they minted high/critical
|
|
508
|
+
* salience and mislabelled categories.
|
|
509
|
+
*
|
|
510
|
+
* extractorType must be one of the chunker's keys (EXTRACTOR_TO_CATEGORY /
|
|
511
|
+
* EXTRACTOR_TO_PURPOSE in extract-memorable-segments.mjs):
|
|
512
|
+
* decision | error-fix | learning | architecture | preference | important-note
|
|
536
513
|
*/
|
|
537
514
|
const KEYWORD_TRIGGERS = [
|
|
538
515
|
// Learning triggers
|
|
539
|
-
{ phrase: "lesson learned",
|
|
540
|
-
{ phrase: "i learned",
|
|
541
|
-
{ phrase: "til:",
|
|
542
|
-
{ phrase: "today i learned",
|
|
543
|
-
|
|
516
|
+
{ phrase: "lesson learned", extractorType: "learning" },
|
|
517
|
+
{ phrase: "i learned", extractorType: "learning" },
|
|
518
|
+
{ phrase: "til:", extractorType: "learning" },
|
|
519
|
+
{ phrase: "today i learned", extractorType: "learning" },
|
|
520
|
+
|
|
544
521
|
// Error/prevention triggers
|
|
545
|
-
{ phrase: "never again",
|
|
546
|
-
{ phrase: "root cause was",
|
|
547
|
-
{ phrase: "the fix was",
|
|
548
|
-
|
|
522
|
+
{ phrase: "never again", extractorType: "error-fix" },
|
|
523
|
+
{ phrase: "root cause was", extractorType: "error-fix" },
|
|
524
|
+
{ phrase: "the fix was", extractorType: "error-fix" },
|
|
525
|
+
|
|
549
526
|
// Preference triggers
|
|
550
|
-
{ phrase: "always do",
|
|
551
|
-
{ phrase: "never do",
|
|
552
|
-
{ phrase: "i prefer",
|
|
553
|
-
{ phrase: "we should always",
|
|
554
|
-
|
|
527
|
+
{ phrase: "always do", extractorType: "preference" },
|
|
528
|
+
{ phrase: "never do", extractorType: "preference" },
|
|
529
|
+
{ phrase: "i prefer", extractorType: "preference" },
|
|
530
|
+
{ phrase: "we should always", extractorType: "preference" },
|
|
531
|
+
|
|
555
532
|
// Architecture/decision triggers
|
|
556
|
-
{ phrase: "we decided",
|
|
557
|
-
{ phrase: "decision made",
|
|
558
|
-
{ phrase: "going with",
|
|
559
|
-
|
|
560
|
-
// Explicit memory triggers (
|
|
561
|
-
{ phrase: "remember this",
|
|
562
|
-
{ phrase: "don't forget",
|
|
563
|
-
{ phrase: "dont forget",
|
|
564
|
-
{ phrase: "this is important",
|
|
565
|
-
{ phrase: "make a note",
|
|
566
|
-
{ phrase: "for the record",
|
|
567
|
-
{ phrase: "note to self",
|
|
568
|
-
{ phrase: "important:",
|
|
569
|
-
{ phrase: "key point:",
|
|
570
|
-
{ phrase: "crucial:",
|
|
533
|
+
{ phrase: "we decided", extractorType: "decision" },
|
|
534
|
+
{ phrase: "decision made", extractorType: "decision" },
|
|
535
|
+
{ phrase: "going with", extractorType: "decision" },
|
|
536
|
+
|
|
537
|
+
// Explicit memory triggers (generic — important-note)
|
|
538
|
+
{ phrase: "remember this", extractorType: "important-note" },
|
|
539
|
+
{ phrase: "don't forget", extractorType: "important-note" },
|
|
540
|
+
{ phrase: "dont forget", extractorType: "important-note" },
|
|
541
|
+
{ phrase: "this is important", extractorType: "important-note" },
|
|
542
|
+
{ phrase: "make a note", extractorType: "important-note" },
|
|
543
|
+
{ phrase: "for the record", extractorType: "important-note" },
|
|
544
|
+
{ phrase: "note to self", extractorType: "important-note" },
|
|
545
|
+
{ phrase: "important:", extractorType: "important-note" },
|
|
546
|
+
{ phrase: "key point:", extractorType: "important-note" },
|
|
547
|
+
{ phrase: "crucial:", extractorType: "important-note" },
|
|
571
548
|
];
|
|
572
549
|
|
|
573
550
|
/**
|
|
@@ -604,35 +581,62 @@ async function checkAndSaveKeywordTrigger(messageText, event) {
|
|
|
604
581
|
content = messageText;
|
|
605
582
|
}
|
|
606
583
|
|
|
607
|
-
|
|
584
|
+
// Route through the chunker wrapper: applies the rejection corpus (drops true
|
|
585
|
+
// malformations) and derives category + memory_purpose from the chunker's
|
|
586
|
+
// taxonomy. Explicit keyword intent BYPASSES the salience threshold (B8) —
|
|
587
|
+
// the wrapper returns a memory for any non-malformed content.
|
|
588
|
+
const extract = await loadOpenClawExtract();
|
|
589
|
+
if (!extract) {
|
|
590
|
+
if (!_noExtractNoticeShown) {
|
|
591
|
+
console.log("[cortex-memory] No resolvable local install — skipping keyword capture (no fallback)");
|
|
592
|
+
_noExtractNoticeShown = true;
|
|
593
|
+
}
|
|
594
|
+
return false;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
// The trigger phrase carries the authoritative classification — pass its
|
|
598
|
+
// extractorType so the wrapper pins category/purpose instead of re-guessing
|
|
599
|
+
// from content (which collapsed typed triggers to `note`).
|
|
600
|
+
const candidates = extract.extractKeywordMemory(content, matchedTrigger.extractorType);
|
|
601
|
+
if (candidates.length === 0) {
|
|
602
|
+
console.log(`[cortex-memory] Keyword trigger skipped (rejected as malformed): "${matchedTrigger.phrase}"`);
|
|
603
|
+
return false;
|
|
604
|
+
}
|
|
605
|
+
const mem = candidates[0];
|
|
608
606
|
|
|
609
607
|
// Deduplicate via shared novelty gate (same gate used by session-end/stop extraction)
|
|
610
608
|
const noveltyGate = await getSharedNoveltyGate();
|
|
611
|
-
const novelty = noveltyGate.inspect(content
|
|
609
|
+
const novelty = noveltyGate.inspect(mem.content);
|
|
612
610
|
if (!novelty.allow) {
|
|
613
|
-
console.log(`[cortex-memory] Keyword trigger skipped (duplicate): "${title}"`);
|
|
611
|
+
console.log(`[cortex-memory] Keyword trigger skipped (duplicate): "${mem.title}"`);
|
|
612
|
+
// M2: an EXPLICIT "remember this" must never be silently dropped — make the
|
|
613
|
+
// dedup decision visible even though we skip the duplicate store.
|
|
614
|
+
if (event.messages) {
|
|
615
|
+
event.messages.push(`🧠 Already remembered.`);
|
|
616
|
+
}
|
|
614
617
|
return false;
|
|
615
618
|
}
|
|
616
619
|
|
|
617
620
|
const result = await callCortex("remember", {
|
|
618
|
-
title,
|
|
619
|
-
content: content
|
|
620
|
-
category:
|
|
621
|
+
title: mem.title,
|
|
622
|
+
content: mem.content,
|
|
623
|
+
category: mem.category,
|
|
624
|
+
memoryPurpose: mem.memoryPurpose,
|
|
621
625
|
project: "openclaw",
|
|
622
626
|
scope: "global",
|
|
623
|
-
importance:
|
|
627
|
+
importance: "normal",
|
|
624
628
|
tags: `keyword-trigger,openclaw-hook,trigger:${matchedTrigger.phrase.replace(/\s+/g, "-")}`,
|
|
625
629
|
sourceType: "hook",
|
|
626
630
|
sourceIdentifier: `openclaw-keyword:${matchedTrigger.phrase.replace(/\s+/g, "-")}`,
|
|
627
631
|
});
|
|
628
632
|
|
|
629
633
|
if (result) {
|
|
630
|
-
noveltyGate.remember({ content: content
|
|
634
|
+
noveltyGate.remember({ content: mem.content, title: mem.title, category: mem.category }, novelty);
|
|
631
635
|
await noveltyGate.flush();
|
|
632
636
|
if (event.messages) {
|
|
633
|
-
event.messages.push(`✅ Saved to Cortex memory (${
|
|
637
|
+
event.messages.push(`✅ Saved to Cortex memory (${mem.category}): "${mem.title}"`);
|
|
634
638
|
}
|
|
635
|
-
console.log(`[cortex-memory] Keyword trigger "${matchedTrigger.phrase}" saved: ${title}`);
|
|
639
|
+
console.log(`[cortex-memory] Keyword trigger "${matchedTrigger.phrase}" saved: ${mem.title}`);
|
|
636
640
|
return true;
|
|
637
641
|
}
|
|
638
642
|
return false;
|
|
@@ -724,8 +728,11 @@ async function selfCheckAndHeal(event) {
|
|
|
724
728
|
const { homedir } = await import("node:os");
|
|
725
729
|
const home = homedir();
|
|
726
730
|
|
|
727
|
-
// Where am I running from?
|
|
728
|
-
|
|
731
|
+
// Where am I running from? Use fileURLToPath, not URL.pathname — the latter
|
|
732
|
+
// does NOT decode percent-encoding, so an install path with spaces/special
|
|
733
|
+
// chars would yield a path that fails every downstream fs read (staleness
|
|
734
|
+
// comparison + self-heal copy below).
|
|
735
|
+
const myDir = path.dirname(fileURLToPath(import.meta.url));
|
|
729
736
|
|
|
730
737
|
// Expected locations (newest first)
|
|
731
738
|
const expectedDirs = [
|
|
@@ -761,6 +768,51 @@ async function selfCheckAndHeal(event) {
|
|
|
761
768
|
}
|
|
762
769
|
}
|
|
763
770
|
|
|
771
|
+
// Task 6b: staleness signal. The hook is installed by file-copy, so a
|
|
772
|
+
// package update can leave THIS running copy behind the packaged source
|
|
773
|
+
// (e.g. an OpenClaw version-lag where the global package is newer than
|
|
774
|
+
// the hook last copied into ~/.openclaw). Compare our running files
|
|
775
|
+
// against the package's hooks/openclaw/cortex-memory source by content.
|
|
776
|
+
//
|
|
777
|
+
// WARN-ONLY by design — we do NOT re-copy from inside the long-lived
|
|
778
|
+
// gateway. Re-copying would overwrite the very files this process is
|
|
779
|
+
// executing from, racing any concurrently-bootstrapping agent's jiti
|
|
780
|
+
// load. The real auto-refresh happens in the npm postinstall; the
|
|
781
|
+
// user-invoked repair is `shieldcortex openclaw install` (also surfaced
|
|
782
|
+
// by `shieldcortex doctor`). No DB, no persistence — pure fs reads.
|
|
783
|
+
try {
|
|
784
|
+
const root = await resolvePackageRoot();
|
|
785
|
+
if (root) {
|
|
786
|
+
const sourceDir = path.join(root, "hooks", "openclaw", "cortex-memory");
|
|
787
|
+
const hookFiles = ["HOOK.md", "handler.ts", "runtime.mjs"];
|
|
788
|
+
let stale = false;
|
|
789
|
+
for (const file of hookFiles) {
|
|
790
|
+
const srcPath = path.join(sourceDir, file);
|
|
791
|
+
const minePath = path.join(myDir, file);
|
|
792
|
+
try {
|
|
793
|
+
const srcBuf = await fs.readFile(srcPath);
|
|
794
|
+
const mineBuf = await fs.readFile(minePath);
|
|
795
|
+
if (!srcBuf.equals(mineBuf)) { stale = true; break; }
|
|
796
|
+
} catch {
|
|
797
|
+
// Source file missing/unreadable (can't prove staleness for it)
|
|
798
|
+
// or our own file unreadable — don't flip `stale` on a read error.
|
|
799
|
+
// DELIBERATE ASYMMETRY with src/setup/openclaw.ts `hookFilesStale`,
|
|
800
|
+
// which returns `true` (stale) on a read error so the doctor nags
|
|
801
|
+
// on a broken install. Here we stay quiet: this runs inside the
|
|
802
|
+
// long-lived gateway, where a transient read error must not emit a
|
|
803
|
+
// spurious bootstrap "out of date" warning. Keep them divergent.
|
|
804
|
+
}
|
|
805
|
+
}
|
|
806
|
+
if (stale) {
|
|
807
|
+
console.warn(
|
|
808
|
+
"[cortex-memory] Installed hook is OUT OF DATE — it differs from the " +
|
|
809
|
+
"packaged version. Run `shieldcortex openclaw install` to refresh it " +
|
|
810
|
+
"(then restart the gateway) so memory capture uses the latest logic."
|
|
811
|
+
);
|
|
812
|
+
}
|
|
813
|
+
}
|
|
814
|
+
} catch { /* staleness check is best-effort — never blocks bootstrap */ }
|
|
815
|
+
|
|
764
816
|
return; // All good
|
|
765
817
|
}
|
|
766
818
|
|