shieldcortex 4.13.1 → 4.14.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/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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- 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 +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
- package/dist/cli/doctor.d.ts +1 -0
- package/dist/cli/doctor.js +244 -8
- package/dist/cli/migrate-legacy.d.ts +30 -0
- package/dist/cli/migrate-legacy.js +199 -0
- package/dist/context/derive-project-key.d.ts +36 -0
- package/dist/context/derive-project-key.js +150 -0
- package/dist/context/project-context.d.ts +8 -5
- package/dist/context/project-context.js +16 -32
- package/dist/index.js +16 -1
- package/dist/setup/settings-hooks.d.ts +6 -0
- package/dist/setup/settings-hooks.js +14 -1
- package/dist/worker/brain-worker.d.ts +13 -5
- package/dist/worker/brain-worker.js +80 -40
- package/dist/worker/types.d.ts +19 -0
- package/dist/worker/types.js +7 -0
- package/package.json +1 -1
- package/plugins/openclaw/dist/openclaw.plugin.json +1 -1
- package/scripts/lib/auto-memory-config.mjs +11 -1
- package/scripts/lib/project-key.mjs +6 -0
- package/scripts/pre-compact-hook.mjs +2 -34
- package/scripts/session-end-hook.mjs +2 -24
- package/scripts/stop-hook.mjs +48 -43
- /package/dashboard/.next/standalone/dashboard/.next/static/{2JvJZkELhPQRzhTlgun1M → wrB1TUcOfBtV94V2I9t9N}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{2JvJZkELhPQRzhTlgun1M → wrB1TUcOfBtV94V2I9t9N}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{2JvJZkELhPQRzhTlgun1M → wrB1TUcOfBtV94V2I9t9N}/_ssgManifest.js +0 -0
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TypeScript port of scripts/lib/project-key.mjs.
|
|
3
|
+
*
|
|
4
|
+
* Both the MCP-server side (this module) and the hook scripts must agree on
|
|
5
|
+
* how a cwd maps to a project key — otherwise writes and reads fall under
|
|
6
|
+
* different scopes and recall silently misses (issue #42).
|
|
7
|
+
*
|
|
8
|
+
* Resolution order:
|
|
9
|
+
* 1. SHIELDCORTEX_PROJECT_KEY env override
|
|
10
|
+
* 2. CLAUDE_MEMORY_PROJECT env override (legacy alias for SC env var)
|
|
11
|
+
* 3. ~/.shieldcortex/config.json projectKey
|
|
12
|
+
* 4. ~/.shieldcortex/config.json projectAliases[basename]
|
|
13
|
+
* 5. Git origin owner-repo (walk up from cwd)
|
|
14
|
+
* 6. Cwd basename (legacy behaviour), skipping noise directories
|
|
15
|
+
*/
|
|
16
|
+
import { existsSync, readFileSync, statSync } from 'fs';
|
|
17
|
+
import { join, dirname } from 'path';
|
|
18
|
+
import { homedir } from 'os';
|
|
19
|
+
const SKIP_DIRECTORIES = [
|
|
20
|
+
'src', 'lib', 'dist', 'build', 'out',
|
|
21
|
+
'node_modules', '.git', '.next', '.cache',
|
|
22
|
+
'test', 'tests', '__tests__', 'spec',
|
|
23
|
+
'bin', 'scripts', 'config', 'public', 'static',
|
|
24
|
+
];
|
|
25
|
+
function resolveHome() {
|
|
26
|
+
return process.env.HOME || process.env.USERPROFILE || homedir();
|
|
27
|
+
}
|
|
28
|
+
function configPath() {
|
|
29
|
+
return join(resolveHome(), '.shieldcortex', 'config.json');
|
|
30
|
+
}
|
|
31
|
+
function loadConfig() {
|
|
32
|
+
try {
|
|
33
|
+
const p = configPath();
|
|
34
|
+
if (!existsSync(p))
|
|
35
|
+
return {};
|
|
36
|
+
return JSON.parse(readFileSync(p, 'utf-8'));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return {};
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function basenameFromCwd(path) {
|
|
43
|
+
if (!path)
|
|
44
|
+
return null;
|
|
45
|
+
const segments = path.split(/[/\\]/).filter(Boolean);
|
|
46
|
+
for (let i = segments.length - 1; i >= 0; i--) {
|
|
47
|
+
const segment = segments[i];
|
|
48
|
+
if (SKIP_DIRECTORIES.includes(segment.toLowerCase()))
|
|
49
|
+
continue;
|
|
50
|
+
if (segment.startsWith('.'))
|
|
51
|
+
continue;
|
|
52
|
+
return segment;
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
function findGitDir(startPath) {
|
|
57
|
+
let current = startPath;
|
|
58
|
+
const root = '/';
|
|
59
|
+
for (let i = 0; i < 40 && current && current !== root; i++) {
|
|
60
|
+
const candidate = join(current, '.git');
|
|
61
|
+
if (existsSync(candidate))
|
|
62
|
+
return candidate;
|
|
63
|
+
const parent = dirname(current);
|
|
64
|
+
if (parent === current)
|
|
65
|
+
break;
|
|
66
|
+
current = parent;
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
function parseOriginUrl(url) {
|
|
71
|
+
if (!url)
|
|
72
|
+
return null;
|
|
73
|
+
const trimmed = url.trim();
|
|
74
|
+
const sshMatch = trimmed.match(/^[^@]+@[^:]+:([^/]+)\/(.+?)(?:\.git)?$/);
|
|
75
|
+
if (sshMatch)
|
|
76
|
+
return { owner: sshMatch[1], repo: sshMatch[2] };
|
|
77
|
+
const urlMatch = trimmed.match(/^[a-z]+:\/\/[^/]+\/(.+?)\/([^/]+?)(?:\.git)?$/i);
|
|
78
|
+
if (urlMatch)
|
|
79
|
+
return { owner: urlMatch[1], repo: urlMatch[2] };
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
function readOriginFromGitConfig(gitPath) {
|
|
83
|
+
try {
|
|
84
|
+
let realGitDir = gitPath;
|
|
85
|
+
const stats = statSync(gitPath);
|
|
86
|
+
if (stats.isFile()) {
|
|
87
|
+
const content = readFileSync(gitPath, 'utf-8');
|
|
88
|
+
if (content.startsWith('gitdir:')) {
|
|
89
|
+
realGitDir = content.slice('gitdir:'.length).trim();
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
return null;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
const cfgPath = join(realGitDir, 'config');
|
|
96
|
+
if (!existsSync(cfgPath))
|
|
97
|
+
return null;
|
|
98
|
+
const content = readFileSync(cfgPath, 'utf-8');
|
|
99
|
+
const section = content.match(/\[remote\s+"origin"\][^[]*/);
|
|
100
|
+
if (!section)
|
|
101
|
+
return null;
|
|
102
|
+
const urlMatch = section[0].match(/\burl\s*=\s*(.+)/);
|
|
103
|
+
if (!urlMatch)
|
|
104
|
+
return null;
|
|
105
|
+
return parseOriginUrl(urlMatch[1]);
|
|
106
|
+
}
|
|
107
|
+
catch {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Derive the project key for a given working directory. Mirrors
|
|
113
|
+
* scripts/lib/project-key.mjs::deriveProjectKey so MCP-server-side and
|
|
114
|
+
* hook-side keys agree.
|
|
115
|
+
*/
|
|
116
|
+
export function deriveProjectKey(cwd) {
|
|
117
|
+
if (process.env.SHIELDCORTEX_PROJECT_KEY) {
|
|
118
|
+
return process.env.SHIELDCORTEX_PROJECT_KEY;
|
|
119
|
+
}
|
|
120
|
+
if (process.env.CLAUDE_MEMORY_PROJECT) {
|
|
121
|
+
const v = process.env.CLAUDE_MEMORY_PROJECT.trim();
|
|
122
|
+
if (v)
|
|
123
|
+
return v;
|
|
124
|
+
}
|
|
125
|
+
const config = loadConfig();
|
|
126
|
+
const projectKey = config.projectKey;
|
|
127
|
+
if (typeof projectKey === 'string' && projectKey.trim()) {
|
|
128
|
+
return projectKey.trim();
|
|
129
|
+
}
|
|
130
|
+
const basename = basenameFromCwd(cwd);
|
|
131
|
+
const aliases = config.projectAliases;
|
|
132
|
+
if (aliases && typeof aliases === 'object' && basename) {
|
|
133
|
+
const alias = aliases[basename];
|
|
134
|
+
if (typeof alias === 'string' && alias.trim())
|
|
135
|
+
return alias.trim();
|
|
136
|
+
}
|
|
137
|
+
const gitDir = cwd ? findGitDir(cwd) : null;
|
|
138
|
+
if (gitDir) {
|
|
139
|
+
const origin = readOriginFromGitConfig(gitDir);
|
|
140
|
+
if (origin?.owner && origin?.repo) {
|
|
141
|
+
return `${origin.owner}-${origin.repo}`;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
return basename;
|
|
145
|
+
}
|
|
146
|
+
export const __internal = {
|
|
147
|
+
parseOriginUrl,
|
|
148
|
+
basenameFromCwd,
|
|
149
|
+
readOriginFromGitConfig,
|
|
150
|
+
};
|
|
@@ -2,22 +2,25 @@
|
|
|
2
2
|
* Project Context Module
|
|
3
3
|
* Automatically detects and manages the active project scope for memory operations.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* 2. Extract from process.cwd() (working directory)
|
|
5
|
+
* Project key derivation is delegated to deriveProjectKey (mirroring
|
|
6
|
+
* scripts/lib/project-key.mjs) so reads and writes share one source of truth.
|
|
8
7
|
*
|
|
9
8
|
* The "*" sentinel means "global/all projects" (no filtering).
|
|
10
9
|
*/
|
|
11
10
|
/** Sentinel value meaning "all projects" - no project filtering */
|
|
12
11
|
export declare const GLOBAL_PROJECT_SENTINEL = "*";
|
|
13
12
|
/**
|
|
14
|
-
* Extract project name from a file path.
|
|
15
|
-
*
|
|
13
|
+
* Extract project name from a file path (basename only, with noise-dir skip).
|
|
14
|
+
* Retained for backwards compatibility with consumers that need just the
|
|
15
|
+
* basename component. New code should call deriveProjectKey instead.
|
|
16
16
|
*/
|
|
17
17
|
export declare function extractProjectFromPath(path: string): string | null;
|
|
18
18
|
/**
|
|
19
19
|
* Initialize project context from environment or working directory.
|
|
20
20
|
* Call this once at server startup.
|
|
21
|
+
*
|
|
22
|
+
* Uses the shared deriveProjectKey helper, so the resolved key is identical
|
|
23
|
+
* to whatever the .mjs hooks would resolve from the same cwd / env / config.
|
|
21
24
|
*/
|
|
22
25
|
export declare function initProjectContext(): void;
|
|
23
26
|
/**
|
|
@@ -2,54 +2,38 @@
|
|
|
2
2
|
* Project Context Module
|
|
3
3
|
* Automatically detects and manages the active project scope for memory operations.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* 2. Extract from process.cwd() (working directory)
|
|
5
|
+
* Project key derivation is delegated to deriveProjectKey (mirroring
|
|
6
|
+
* scripts/lib/project-key.mjs) so reads and writes share one source of truth.
|
|
8
7
|
*
|
|
9
8
|
* The "*" sentinel means "global/all projects" (no filtering).
|
|
10
9
|
*/
|
|
10
|
+
import { deriveProjectKey, basenameFromCwd } from './derive-project-key.js';
|
|
11
11
|
/** Sentinel value meaning "all projects" - no project filtering */
|
|
12
12
|
export const GLOBAL_PROJECT_SENTINEL = '*';
|
|
13
13
|
/** Currently active project (null = global/no filter) */
|
|
14
14
|
let activeProject = null;
|
|
15
15
|
/** How the project was detected */
|
|
16
16
|
let projectDetectionSource = 'none';
|
|
17
|
-
/** Directories to skip when extracting project name from path */
|
|
18
|
-
const SKIP_DIRECTORIES = [
|
|
19
|
-
'src', 'lib', 'dist', 'build', 'out',
|
|
20
|
-
'node_modules', '.git', '.next', '.cache',
|
|
21
|
-
'test', 'tests', '__tests__', 'spec',
|
|
22
|
-
'bin', 'scripts', 'config', 'public', 'static',
|
|
23
|
-
];
|
|
24
17
|
/**
|
|
25
|
-
* Extract project name from a file path.
|
|
26
|
-
*
|
|
18
|
+
* Extract project name from a file path (basename only, with noise-dir skip).
|
|
19
|
+
* Retained for backwards compatibility with consumers that need just the
|
|
20
|
+
* basename component. New code should call deriveProjectKey instead.
|
|
27
21
|
*/
|
|
28
22
|
export function extractProjectFromPath(path) {
|
|
29
|
-
|
|
30
|
-
return null;
|
|
31
|
-
const segments = path.split(/[/\\]/).filter(Boolean);
|
|
32
|
-
if (segments.length === 0)
|
|
33
|
-
return null;
|
|
34
|
-
// Start from the end and find first non-skipped segment
|
|
35
|
-
for (let i = segments.length - 1; i >= 0; i--) {
|
|
36
|
-
const segment = segments[i];
|
|
37
|
-
if (!SKIP_DIRECTORIES.includes(segment.toLowerCase())) {
|
|
38
|
-
// Skip hidden directories (starting with .)
|
|
39
|
-
if (segment.startsWith('.'))
|
|
40
|
-
continue;
|
|
41
|
-
return segment;
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
return null;
|
|
23
|
+
return basenameFromCwd(path);
|
|
45
24
|
}
|
|
46
25
|
/**
|
|
47
26
|
* Initialize project context from environment or working directory.
|
|
48
27
|
* Call this once at server startup.
|
|
28
|
+
*
|
|
29
|
+
* Uses the shared deriveProjectKey helper, so the resolved key is identical
|
|
30
|
+
* to whatever the .mjs hooks would resolve from the same cwd / env / config.
|
|
49
31
|
*/
|
|
50
32
|
export function initProjectContext() {
|
|
51
|
-
//
|
|
52
|
-
|
|
33
|
+
// Env overrides — match deriveProjectKey's order. We track these separately
|
|
34
|
+
// so projectDetectionSource keeps reporting 'env' when the user pinned the
|
|
35
|
+
// project explicitly (visible in get_project / dashboard).
|
|
36
|
+
const envProject = process.env.SHIELDCORTEX_PROJECT_KEY || process.env.CLAUDE_MEMORY_PROJECT;
|
|
53
37
|
if (envProject) {
|
|
54
38
|
const trimmed = envProject.trim();
|
|
55
39
|
if (trimmed === GLOBAL_PROJECT_SENTINEL) {
|
|
@@ -62,9 +46,9 @@ export function initProjectContext() {
|
|
|
62
46
|
}
|
|
63
47
|
return;
|
|
64
48
|
}
|
|
65
|
-
//
|
|
49
|
+
// Otherwise: config override → projectAliases → git origin → basename.
|
|
66
50
|
const cwd = process.cwd();
|
|
67
|
-
const detected =
|
|
51
|
+
const detected = deriveProjectKey(cwd);
|
|
68
52
|
if (detected) {
|
|
69
53
|
activeProject = detected;
|
|
70
54
|
projectDetectionSource = 'cwd';
|
package/dist/index.js
CHANGED
|
@@ -77,7 +77,7 @@ import { handleCodexCommand } from './setup/codex.js';
|
|
|
77
77
|
import { createRequire } from 'module';
|
|
78
78
|
import { execSync } from 'child_process';
|
|
79
79
|
import { disposeModel, preloadModel } from './embeddings/index.js';
|
|
80
|
-
import { stopDefaultWorker } from './worker/brain-worker.js';
|
|
80
|
+
import { startDefaultWorker, stopDefaultWorker } from './worker/brain-worker.js';
|
|
81
81
|
const require = createRequire(import.meta.url);
|
|
82
82
|
const pkg = require('../package.json');
|
|
83
83
|
/**
|
|
@@ -172,6 +172,21 @@ async function startMcpServer(dbPath) {
|
|
|
172
172
|
});
|
|
173
173
|
// Connect via stdio transport
|
|
174
174
|
await server.connect(transport);
|
|
175
|
+
// Start the brain worker in MCP-lite profile so STM→LTM consolidation runs
|
|
176
|
+
// even on hooks-only installs (no dashboard, no `service install`). Without
|
|
177
|
+
// this, MCP-only deployments accumulate STM forever and never promote (#45).
|
|
178
|
+
// The MCP profile uses a 15 min cadence and skips medium-tick + cloud-sync
|
|
179
|
+
// work to keep total background load bounded across many open windows.
|
|
180
|
+
// Disabled via SHIELDCORTEX_DISABLE_WORKER=1 for forensics / debugging.
|
|
181
|
+
if (process.env.SHIELDCORTEX_DISABLE_WORKER !== '1') {
|
|
182
|
+
try {
|
|
183
|
+
startDefaultWorker({ profile: 'mcp' });
|
|
184
|
+
}
|
|
185
|
+
catch (err) {
|
|
186
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
187
|
+
console.error('[shieldcortex] Brain worker autostart failed (continuing without):', msg);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
175
190
|
// Preload embedding model in background so first tool call doesn't hang.
|
|
176
191
|
// Fire-and-forget: failure is fine — searchMemories falls back to FTS-only.
|
|
177
192
|
if (process.env.SHIELDCORTEX_SKIP_EMBEDDINGS !== '1') {
|
|
@@ -7,6 +7,12 @@
|
|
|
7
7
|
* Keep this alongside CORTEX_HOOKS — drift between the two is what caused #23.
|
|
8
8
|
*/
|
|
9
9
|
export declare const REQUIRED_HOOK_NAMES: readonly string[];
|
|
10
|
+
/**
|
|
11
|
+
* Canonical timeout (seconds) for each ShieldCortex hook. Used by
|
|
12
|
+
* `shieldcortex doctor` to flag drift in hand-edited settings.json files —
|
|
13
|
+
* a too-tight UserPromptSubmit timeout silently dropped recall pre-#43.
|
|
14
|
+
*/
|
|
15
|
+
export declare const CANONICAL_HOOK_TIMEOUTS: Readonly<Record<string, number>>;
|
|
10
16
|
export declare function setupHooks(options?: {
|
|
11
17
|
stopHook?: boolean;
|
|
12
18
|
sessionEnd?: boolean;
|
|
@@ -17,7 +17,11 @@ const CORTEX_HOOKS = {
|
|
|
17
17
|
// agents when the session is already gone. PreCompact handles memory
|
|
18
18
|
// extraction. The cortex-memory hook handles session-end for OpenClaw.
|
|
19
19
|
UserPromptSubmit: {
|
|
20
|
-
|
|
20
|
+
// Cold-spawn floor for the recall hook is ~1.5 s (Node + better-sqlite3 +
|
|
21
|
+
// FTS query). The previous 2 s ceiling SIGKILLed the hook silently under
|
|
22
|
+
// any IO pressure, dropping recall context with no user-visible error
|
|
23
|
+
// (#43). 5 s leaves ~3 s headroom on a busy host.
|
|
24
|
+
hooks: [{ type: 'command', command: 'shieldcortex hook prompt-recall', timeout: 5 }],
|
|
21
25
|
},
|
|
22
26
|
};
|
|
23
27
|
/**
|
|
@@ -26,6 +30,15 @@ const CORTEX_HOOKS = {
|
|
|
26
30
|
* Keep this alongside CORTEX_HOOKS — drift between the two is what caused #23.
|
|
27
31
|
*/
|
|
28
32
|
export const REQUIRED_HOOK_NAMES = Object.freeze(Object.keys(CORTEX_HOOKS));
|
|
33
|
+
/**
|
|
34
|
+
* Canonical timeout (seconds) for each ShieldCortex hook. Used by
|
|
35
|
+
* `shieldcortex doctor` to flag drift in hand-edited settings.json files —
|
|
36
|
+
* a too-tight UserPromptSubmit timeout silently dropped recall pre-#43.
|
|
37
|
+
*/
|
|
38
|
+
export const CANONICAL_HOOK_TIMEOUTS = Object.freeze(Object.fromEntries(Object.entries(CORTEX_HOOKS).map(([name, entry]) => [
|
|
39
|
+
name,
|
|
40
|
+
entry.hooks?.[0]?.timeout ?? 0,
|
|
41
|
+
])));
|
|
29
42
|
const STOP_HOOK = {
|
|
30
43
|
hooks: [{ type: 'command', command: 'shieldcortex hook stop', timeout: 10 }],
|
|
31
44
|
};
|
|
@@ -29,7 +29,10 @@ export declare class BrainWorker {
|
|
|
29
29
|
/**
|
|
30
30
|
* Create a new BrainWorker
|
|
31
31
|
*
|
|
32
|
-
* @param config - Partial configuration to override defaults
|
|
32
|
+
* @param config - Partial configuration to override defaults. When `profile`
|
|
33
|
+
* is 'mcp' and no explicit `lightTickIntervalMs` is provided,
|
|
34
|
+
* the lite 15-minute cadence is applied so MCP-server-mode
|
|
35
|
+
* workers don't run as often as dashboard-mode ones.
|
|
33
36
|
*/
|
|
34
37
|
constructor(config?: Partial<WorkerConfig>);
|
|
35
38
|
/**
|
|
@@ -87,13 +90,18 @@ export declare class BrainWorker {
|
|
|
87
90
|
triggerMediumTick(): Promise<MediumTickResult>;
|
|
88
91
|
}
|
|
89
92
|
/**
|
|
90
|
-
* Get or create the default worker instance
|
|
93
|
+
* Get or create the default worker instance.
|
|
94
|
+
* The first call wins — subsequent calls return the existing singleton even
|
|
95
|
+
* if a different config is passed. That's intentional: it prevents accidental
|
|
96
|
+
* re-instantiation from creating two competing timer sets within one process.
|
|
91
97
|
*/
|
|
92
|
-
export declare function getDefaultWorker(): BrainWorker;
|
|
98
|
+
export declare function getDefaultWorker(config?: Partial<WorkerConfig>): BrainWorker;
|
|
93
99
|
/**
|
|
94
|
-
* Start the default worker if not already running
|
|
100
|
+
* Start the default worker if not already running. Forwards config to the
|
|
101
|
+
* underlying constructor on first call (used by MCP-server mode to start
|
|
102
|
+
* with `profile: 'mcp'`).
|
|
95
103
|
*/
|
|
96
|
-
export declare function startDefaultWorker(): BrainWorker;
|
|
104
|
+
export declare function startDefaultWorker(config?: Partial<WorkerConfig>): BrainWorker;
|
|
97
105
|
/**
|
|
98
106
|
* Stop the default worker
|
|
99
107
|
*/
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* This transforms the memory system from reactive to continuously organic.
|
|
11
11
|
*/
|
|
12
|
-
import { DEFAULT_WORKER_CONFIG, } from './types.js';
|
|
12
|
+
import { DEFAULT_WORKER_CONFIG, MCP_LIGHT_TICK_INTERVAL_MS, } from './types.js';
|
|
13
13
|
import { getDatabase } from '../database/init.js';
|
|
14
14
|
import { pruneActivationCache } from '../memory/activation.js';
|
|
15
15
|
import { getMemoryStats } from '../memory/store.js';
|
|
@@ -22,6 +22,21 @@ import { processRetryQueue, purgeOldEntries } from '../cloud/sync-queue.js';
|
|
|
22
22
|
import { sendHeartbeat } from '../cloud/sync.js';
|
|
23
23
|
import { refreshCloudIronDome, applyCachedCloudPatterns } from '../cloud/iron-dome-sync.js';
|
|
24
24
|
import { isFeatureEnabled } from '../license/gate.js';
|
|
25
|
+
import { existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
26
|
+
import { join } from 'path';
|
|
27
|
+
import { homedir } from 'os';
|
|
28
|
+
const WORKER_STATE_DIR = join(homedir(), '.shieldcortex', 'state');
|
|
29
|
+
const WORKER_STATE_FILE = join(WORKER_STATE_DIR, 'worker.json');
|
|
30
|
+
function persistWorkerState(profile, lastLightTick) {
|
|
31
|
+
try {
|
|
32
|
+
if (!existsSync(WORKER_STATE_DIR))
|
|
33
|
+
mkdirSync(WORKER_STATE_DIR, { recursive: true });
|
|
34
|
+
writeFileSync(WORKER_STATE_FILE, JSON.stringify({ pid: process.pid, profile, lastLightTick: lastLightTick.toISOString() }, null, 2), 'utf-8');
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Best-effort: doctor will warn if the file is stale or missing
|
|
38
|
+
}
|
|
39
|
+
}
|
|
25
40
|
/**
|
|
26
41
|
* Brain Worker Class
|
|
27
42
|
*
|
|
@@ -47,10 +62,17 @@ export class BrainWorker {
|
|
|
47
62
|
/**
|
|
48
63
|
* Create a new BrainWorker
|
|
49
64
|
*
|
|
50
|
-
* @param config - Partial configuration to override defaults
|
|
65
|
+
* @param config - Partial configuration to override defaults. When `profile`
|
|
66
|
+
* is 'mcp' and no explicit `lightTickIntervalMs` is provided,
|
|
67
|
+
* the lite 15-minute cadence is applied so MCP-server-mode
|
|
68
|
+
* workers don't run as often as dashboard-mode ones.
|
|
51
69
|
*/
|
|
52
70
|
constructor(config = {}) {
|
|
53
|
-
|
|
71
|
+
const merged = { ...DEFAULT_WORKER_CONFIG, ...config };
|
|
72
|
+
if (merged.profile === 'mcp' && config.lightTickIntervalMs === undefined) {
|
|
73
|
+
merged.lightTickIntervalMs = MCP_LIGHT_TICK_INTERVAL_MS;
|
|
74
|
+
}
|
|
75
|
+
this.config = merged;
|
|
54
76
|
}
|
|
55
77
|
/**
|
|
56
78
|
* Start the background worker
|
|
@@ -62,17 +84,26 @@ export class BrainWorker {
|
|
|
62
84
|
return;
|
|
63
85
|
}
|
|
64
86
|
this.isRunning = true;
|
|
65
|
-
console.log(
|
|
87
|
+
console.log(`[BrainWorker] Starting background worker (profile=${this.config.profile} pid=${process.pid})`);
|
|
66
88
|
console.log(`[BrainWorker] Light tick interval: ${this.config.lightTickIntervalMs / 1000}s`);
|
|
67
|
-
|
|
68
|
-
|
|
89
|
+
if (this.config.profile === 'full') {
|
|
90
|
+
console.log(`[BrainWorker] Medium tick interval: ${this.config.mediumTickIntervalMs / 1000}s`);
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
console.log('[BrainWorker] MCP profile — medium tick + cloud sync disabled');
|
|
94
|
+
}
|
|
95
|
+
// Light tick — every 5 min (full) or every 15 min (mcp)
|
|
69
96
|
this.lightTimer = setInterval(() => this.lightTick(), this.config.lightTickIntervalMs);
|
|
70
97
|
this.lightTimer.unref();
|
|
71
|
-
// Medium tick
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
98
|
+
// Medium tick — full profile only. mcp-mode skips link discovery,
|
|
99
|
+
// contradiction scans, graph maintenance, and sync-queue purging — those
|
|
100
|
+
// are dashboard concerns and shouldn't multiply across N MCP windows.
|
|
101
|
+
if (this.config.profile === 'full') {
|
|
102
|
+
this.mediumTimer = setInterval(() => this.mediumTick(), this.config.mediumTickIntervalMs);
|
|
103
|
+
this.mediumTimer.unref();
|
|
104
|
+
}
|
|
105
|
+
// Apply cached cloud Iron Dome patterns immediately on start (Pro+, full only)
|
|
106
|
+
if (this.config.profile === 'full' && isFeatureEnabled('custom_injection_patterns')) {
|
|
76
107
|
try {
|
|
77
108
|
applyCachedCloudPatterns();
|
|
78
109
|
}
|
|
@@ -150,38 +181,42 @@ export class BrainWorker {
|
|
|
150
181
|
result: result.predictiveConsolidation,
|
|
151
182
|
});
|
|
152
183
|
}
|
|
153
|
-
// 3
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
console.log(`[BrainWorker] Sync retry queue: processed ${retryResult.processed} ` +
|
|
158
|
-
`(${retryResult.succeeded} ok, ${retryResult.failed} retry, ${retryResult.permanentlyFailed} failed)`);
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
catch (retryError) {
|
|
162
|
-
console.error('[BrainWorker] Sync retry queue failed:', retryError);
|
|
163
|
-
}
|
|
164
|
-
// 4. Send cloud heartbeat (keeps device status "Online") — Team+ only
|
|
165
|
-
if (isFeatureEnabled('cloud_sync')) {
|
|
184
|
+
// 3-5: cloud sync (retry queue, heartbeat, Iron Dome) — full profile only.
|
|
185
|
+
// Skipped under MCP profile so we don't fan out N concurrent network calls
|
|
186
|
+
// from N open Claude Code windows.
|
|
187
|
+
if (this.config.profile === 'full') {
|
|
166
188
|
try {
|
|
167
|
-
|
|
189
|
+
const retryResult = await processRetryQueue();
|
|
190
|
+
if (retryResult.processed > 0) {
|
|
191
|
+
console.log(`[BrainWorker] Sync retry queue: processed ${retryResult.processed} ` +
|
|
192
|
+
`(${retryResult.succeeded} ok, ${retryResult.failed} retry, ${retryResult.permanentlyFailed} failed)`);
|
|
193
|
+
}
|
|
168
194
|
}
|
|
169
|
-
catch {
|
|
170
|
-
|
|
195
|
+
catch (retryError) {
|
|
196
|
+
console.error('[BrainWorker] Sync retry queue failed:', retryError);
|
|
171
197
|
}
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
198
|
+
if (isFeatureEnabled('cloud_sync')) {
|
|
199
|
+
try {
|
|
200
|
+
sendHeartbeat();
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
// Truly silent — heartbeat is best-effort
|
|
204
|
+
}
|
|
177
205
|
}
|
|
178
|
-
|
|
179
|
-
|
|
206
|
+
if (isFeatureEnabled('custom_injection_patterns')) {
|
|
207
|
+
try {
|
|
208
|
+
await refreshCloudIronDome();
|
|
209
|
+
}
|
|
210
|
+
catch {
|
|
211
|
+
// Non-critical — cloud Iron Dome sync is best-effort
|
|
212
|
+
}
|
|
180
213
|
}
|
|
181
214
|
}
|
|
182
215
|
// Update stats
|
|
183
216
|
this.lastLightTick = result.timestamp;
|
|
184
217
|
this.stats.lightTicks++;
|
|
218
|
+
// Persist worker freshness for `shieldcortex doctor` to detect stalls.
|
|
219
|
+
persistWorkerState(this.config.profile, result.timestamp);
|
|
185
220
|
// Emit light tick event
|
|
186
221
|
emitWorkerLightTick(result);
|
|
187
222
|
// Log summary
|
|
@@ -314,19 +349,24 @@ export class BrainWorker {
|
|
|
314
349
|
// Default singleton instance (optional - server can create its own)
|
|
315
350
|
let defaultWorker = null;
|
|
316
351
|
/**
|
|
317
|
-
* Get or create the default worker instance
|
|
352
|
+
* Get or create the default worker instance.
|
|
353
|
+
* The first call wins — subsequent calls return the existing singleton even
|
|
354
|
+
* if a different config is passed. That's intentional: it prevents accidental
|
|
355
|
+
* re-instantiation from creating two competing timer sets within one process.
|
|
318
356
|
*/
|
|
319
|
-
export function getDefaultWorker() {
|
|
357
|
+
export function getDefaultWorker(config) {
|
|
320
358
|
if (!defaultWorker) {
|
|
321
|
-
defaultWorker = new BrainWorker();
|
|
359
|
+
defaultWorker = new BrainWorker(config);
|
|
322
360
|
}
|
|
323
361
|
return defaultWorker;
|
|
324
362
|
}
|
|
325
363
|
/**
|
|
326
|
-
* Start the default worker if not already running
|
|
364
|
+
* Start the default worker if not already running. Forwards config to the
|
|
365
|
+
* underlying constructor on first call (used by MCP-server mode to start
|
|
366
|
+
* with `profile: 'mcp'`).
|
|
327
367
|
*/
|
|
328
|
-
export function startDefaultWorker() {
|
|
329
|
-
const worker = getDefaultWorker();
|
|
368
|
+
export function startDefaultWorker(config) {
|
|
369
|
+
const worker = getDefaultWorker(config);
|
|
330
370
|
if (!worker.isActive()) {
|
|
331
371
|
worker.start();
|
|
332
372
|
}
|
package/dist/worker/types.d.ts
CHANGED
|
@@ -7,6 +7,17 @@
|
|
|
7
7
|
* for the background brain worker.
|
|
8
8
|
*/
|
|
9
9
|
import { ConsolidationResult } from '../memory/types.js';
|
|
10
|
+
/**
|
|
11
|
+
* Worker profile.
|
|
12
|
+
* - 'full': dashboard / api / worker modes — runs medium tick, cloud sync,
|
|
13
|
+
* link discovery, the works.
|
|
14
|
+
* - 'mcp': default MCP-server mode (one process per Claude Code window) —
|
|
15
|
+
* keeps consolidation alive but skips heavy/networked work so we don't
|
|
16
|
+
* multiply background load by the number of open windows. Without this,
|
|
17
|
+
* hooks-only installs never run consolidation and STM never graduates
|
|
18
|
+
* to LTM (#45).
|
|
19
|
+
*/
|
|
20
|
+
export type WorkerProfile = 'full' | 'mcp';
|
|
10
21
|
/**
|
|
11
22
|
* Configuration for the brain worker
|
|
12
23
|
*/
|
|
@@ -27,11 +38,19 @@ export interface WorkerConfig {
|
|
|
27
38
|
contradictionScanLimit: number;
|
|
28
39
|
/** High activity threshold - memories created in 30 min (default: 5) */
|
|
29
40
|
highActivityThreshold: number;
|
|
41
|
+
/** Worker profile - 'full' (default) or 'mcp' (lite, see WorkerProfile docs) */
|
|
42
|
+
profile: WorkerProfile;
|
|
30
43
|
}
|
|
31
44
|
/**
|
|
32
45
|
* Default worker configuration
|
|
33
46
|
*/
|
|
34
47
|
export declare const DEFAULT_WORKER_CONFIG: WorkerConfig;
|
|
48
|
+
/**
|
|
49
|
+
* MCP-profile interval override. 15 min vs full's 5 min — one MCP server runs
|
|
50
|
+
* per Claude Code window, so we want lower per-window cadence to keep total
|
|
51
|
+
* background work in check across many windows.
|
|
52
|
+
*/
|
|
53
|
+
export declare const MCP_LIGHT_TICK_INTERVAL_MS: number;
|
|
35
54
|
/**
|
|
36
55
|
* Result of a light tick operation
|
|
37
56
|
*/
|
package/dist/worker/types.js
CHANGED
|
@@ -18,4 +18,11 @@ export const DEFAULT_WORKER_CONFIG = {
|
|
|
18
18
|
maxLinksPerCycle: 10,
|
|
19
19
|
contradictionScanLimit: 50,
|
|
20
20
|
highActivityThreshold: 5,
|
|
21
|
+
profile: 'full',
|
|
21
22
|
};
|
|
23
|
+
/**
|
|
24
|
+
* MCP-profile interval override. 15 min vs full's 5 min — one MCP server runs
|
|
25
|
+
* per Claude Code window, so we want lower per-window cadence to keep total
|
|
26
|
+
* background work in check across many windows.
|
|
27
|
+
*/
|
|
28
|
+
export const MCP_LIGHT_TICK_INTERVAL_MS = 15 * 60 * 1000;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shieldcortex",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.14.0",
|
|
4
4
|
"description": "Trustworthy memory and security for AI agents. Recall debugging, review queue, OpenClaw session capture, and memory poisoning defence for Claude Code, Codex, OpenClaw, LangChain, and MCP agents.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "shieldcortex-realtime",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.14.0",
|
|
4
4
|
"name": "ShieldCortex Real-time Scanner",
|
|
5
5
|
"description": "Real-time defence scanning on LLM input, memory extraction on LLM output, and active tool call interception with approval gating.",
|
|
6
6
|
"kind": null,
|
|
@@ -15,7 +15,14 @@ const DEFAULTS = Object.freeze({
|
|
|
15
15
|
maxTranscriptBytes: 1024 * 1024,
|
|
16
16
|
maxTranscriptLines: 5000,
|
|
17
17
|
keepSlashCommandProse: true,
|
|
18
|
-
|
|
18
|
+
// Lowered 10 → 5 in v4.14.0. At 1-in-10 the realistic capture rate over
|
|
19
|
+
// typical sessions was ~7%, which left LTM near-empty (#44). Salience
|
|
20
|
+
// bypass below catches high-signal turns at any cadence.
|
|
21
|
+
stopHookSamplingTurns: 5,
|
|
22
|
+
// Bypass the modulo gate when the last assistant turn carries a fenced
|
|
23
|
+
// code block or hits multiple keyword categories — those turns are
|
|
24
|
+
// disproportionately what we want to remember.
|
|
25
|
+
stopHookSalienceBypass: true,
|
|
19
26
|
stopHookWindowBytes: 256 * 1024,
|
|
20
27
|
enableSessionEnd: false,
|
|
21
28
|
enableStop: false,
|
|
@@ -39,6 +46,9 @@ export function getAutoMemoryConfig() {
|
|
|
39
46
|
? overrides.keepSlashCommandProse
|
|
40
47
|
: DEFAULTS.keepSlashCommandProse,
|
|
41
48
|
stopHookSamplingTurns: pickPositiveInt(overrides.stopHookSamplingTurns, DEFAULTS.stopHookSamplingTurns),
|
|
49
|
+
stopHookSalienceBypass: typeof overrides.stopHookSalienceBypass === 'boolean'
|
|
50
|
+
? overrides.stopHookSalienceBypass
|
|
51
|
+
: DEFAULTS.stopHookSalienceBypass,
|
|
42
52
|
stopHookWindowBytes: pickPositiveInt(overrides.stopHookWindowBytes, DEFAULTS.stopHookWindowBytes),
|
|
43
53
|
enableSessionEnd: overrides.enableSessionEnd === true,
|
|
44
54
|
enableStop: overrides.enableStop === true,
|