shieldcortex 4.13.0 → 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 +16 -0
- package/dist/cli/doctor.js +329 -8
- package/dist/cli/migrate-legacy.d.ts +30 -0
- package/dist/cli/migrate-legacy.js +199 -0
- package/dist/cloud/config.d.ts +22 -0
- package/dist/cloud/config.js +38 -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 +37 -3
- 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 +22 -4
- 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 +88 -44
- /package/dashboard/.next/standalone/dashboard/.next/static/{kiA_iEHG_1wWOEYFsD0Tj → wrB1TUcOfBtV94V2I9t9N}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{kiA_iEHG_1wWOEYFsD0Tj → wrB1TUcOfBtV94V2I9t9N}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{kiA_iEHG_1wWOEYFsD0Tj → wrB1TUcOfBtV94V2I9t9N}/_ssgManifest.js +0 -0
package/dist/cli/doctor.js
CHANGED
|
@@ -338,6 +338,90 @@ async function checkHooks() {
|
|
|
338
338
|
return { label: 'Hooks', status: 'warn', message: `check failed — ${msg}` };
|
|
339
339
|
}
|
|
340
340
|
}
|
|
341
|
+
// ── Check 4b: Auto-memory hook gates ──────────────────────
|
|
342
|
+
/**
|
|
343
|
+
* Surfaces the resolved on/off state of the opt-in Stop and SessionEnd
|
|
344
|
+
* auto-memory hooks. Pre-v4.13.1 these were triple-gated (install flag,
|
|
345
|
+
* runtime config, sampling) with the runtime gate failing silently —
|
|
346
|
+
* users who wired the hook saw zero captures and zero feedback (#41).
|
|
347
|
+
*
|
|
348
|
+
* The check looks at both layers:
|
|
349
|
+
* - settings.json: is the hook wired so Claude Code will fire it?
|
|
350
|
+
* - autoMemory.enableStop / enableSessionEnd: will the hook actually run?
|
|
351
|
+
*
|
|
352
|
+
* Both layers must agree for the hook to do work. v4.13.1 onwards, the
|
|
353
|
+
* install flag flips both — if they disagree here, the user edited one
|
|
354
|
+
* side by hand and should re-run setup.
|
|
355
|
+
*/
|
|
356
|
+
export async function checkAutoMemoryHooks() {
|
|
357
|
+
const settingsPath = path.join(os.homedir(), '.claude', 'settings.json');
|
|
358
|
+
let wiredStop = false;
|
|
359
|
+
let wiredSessionEnd = false;
|
|
360
|
+
try {
|
|
361
|
+
if (fs.existsSync(settingsPath)) {
|
|
362
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
363
|
+
const hooks = settings?.hooks || {};
|
|
364
|
+
const isCortexWired = (entries) => Array.isArray(entries) && entries.some((entry) => Array.isArray(entry?.hooks) && entry.hooks.some((h) => typeof h?.command === 'string' && h.command.includes('shieldcortex')));
|
|
365
|
+
wiredStop = isCortexWired(hooks.Stop);
|
|
366
|
+
wiredSessionEnd = isCortexWired(hooks.SessionEnd);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
catch { /* fall through — both stay false, user gets a clean info row */ }
|
|
370
|
+
// Lazy-import to avoid pulling cloud/config into doctor's static graph
|
|
371
|
+
// when the user hasn't configured anything yet.
|
|
372
|
+
let gateStop = false;
|
|
373
|
+
let gateSessionEnd = false;
|
|
374
|
+
let samplingTurns = 10;
|
|
375
|
+
try {
|
|
376
|
+
const cfg = await import('../cloud/config.js');
|
|
377
|
+
const enable = cfg.getAutoMemoryEnableConfig();
|
|
378
|
+
gateStop = enable.enableStop;
|
|
379
|
+
gateSessionEnd = enable.enableSessionEnd;
|
|
380
|
+
const raw = cfg.readRawConfig();
|
|
381
|
+
const am = raw.autoMemory && typeof raw.autoMemory === 'object'
|
|
382
|
+
? raw.autoMemory
|
|
383
|
+
: {};
|
|
384
|
+
if (typeof am.stopHookSamplingTurns === 'number' && am.stopHookSamplingTurns > 0) {
|
|
385
|
+
samplingTurns = Math.floor(am.stopHookSamplingTurns);
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
catch { /* defaults already set */ }
|
|
389
|
+
const rowFor = (label, wired, gate, flag, extra) => {
|
|
390
|
+
if (!wired && !gate) {
|
|
391
|
+
return {
|
|
392
|
+
label,
|
|
393
|
+
status: 'info',
|
|
394
|
+
message: 'opt-in (not installed)',
|
|
395
|
+
};
|
|
396
|
+
}
|
|
397
|
+
if (wired && gate) {
|
|
398
|
+
return {
|
|
399
|
+
label,
|
|
400
|
+
status: 'pass',
|
|
401
|
+
message: extra ? `enabled (${extra})` : 'enabled',
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
if (wired && !gate) {
|
|
405
|
+
return {
|
|
406
|
+
label,
|
|
407
|
+
status: 'warn',
|
|
408
|
+
message: 'wired in settings.json but runtime gate is off — hook will exit silently every turn',
|
|
409
|
+
fix: `Run \`shieldcortex setup ${flag}\` to flip the gate, or set autoMemory.enableStop/enableSessionEnd=true in ~/.shieldcortex/config.json`,
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
// gate && !wired
|
|
413
|
+
return {
|
|
414
|
+
label,
|
|
415
|
+
status: 'warn',
|
|
416
|
+
message: 'runtime gate is on but hook is not wired in settings.json — hook will never fire',
|
|
417
|
+
fix: `Run \`shieldcortex setup ${flag}\` to wire the hook`,
|
|
418
|
+
};
|
|
419
|
+
};
|
|
420
|
+
return [
|
|
421
|
+
rowFor('Auto-memory: Stop hook', wiredStop, gateStop, '--with-stop-hook', `samples turn % ${samplingTurns} == 0`),
|
|
422
|
+
rowFor('Auto-memory: SessionEnd hook', wiredSessionEnd, gateSessionEnd, '--with-session-end'),
|
|
423
|
+
];
|
|
424
|
+
}
|
|
341
425
|
// ── Check 5: Process check ────────────────────────────────
|
|
342
426
|
async function checkProcesses() {
|
|
343
427
|
const results = [];
|
|
@@ -461,8 +545,12 @@ async function checkDiskUsage() {
|
|
|
461
545
|
}
|
|
462
546
|
}
|
|
463
547
|
// ── Check 7: Lock file ───────────────────────────────────
|
|
464
|
-
|
|
465
|
-
|
|
548
|
+
//
|
|
549
|
+
// A lock is stale only if its recorded PID is no longer running. Pure mtime age
|
|
550
|
+
// is unreliable: a long-running daemon (e.g. `shieldcortex dashboard` started
|
|
551
|
+
// at boot) holds the same lock for days, and flagging it stale tells the user
|
|
552
|
+
// to delete a file that is still in active use.
|
|
553
|
+
export async function checkLockFile(scDir = getShieldCortexDir()) {
|
|
466
554
|
if (!fs.existsSync(scDir)) {
|
|
467
555
|
return { label: 'Lock', status: 'pass', message: 'clean' };
|
|
468
556
|
}
|
|
@@ -477,18 +565,45 @@ async function checkLockFile() {
|
|
|
477
565
|
if (lockFiles.length === 0) {
|
|
478
566
|
return { label: 'Lock', status: 'pass', message: 'clean' };
|
|
479
567
|
}
|
|
480
|
-
// Check if lock files are stale (older than 1 hour)
|
|
481
568
|
const stale = [];
|
|
482
569
|
const active = [];
|
|
483
|
-
|
|
570
|
+
// Fallback only used when the lock file is unparseable or has no PID.
|
|
571
|
+
const oneDayAgo = Date.now() - 24 * 60 * 60 * 1000;
|
|
484
572
|
for (const lockFile of lockFiles) {
|
|
485
573
|
const lockPath = path.join(scDir, lockFile);
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
574
|
+
let pid = null;
|
|
575
|
+
try {
|
|
576
|
+
const parsed = JSON.parse(fs.readFileSync(lockPath, 'utf-8'));
|
|
577
|
+
if (typeof parsed.pid === 'number' && Number.isFinite(parsed.pid)) {
|
|
578
|
+
pid = parsed.pid;
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
catch {
|
|
582
|
+
// Unparseable lock — fall through to mtime fallback below.
|
|
583
|
+
}
|
|
584
|
+
if (pid !== null) {
|
|
585
|
+
try {
|
|
586
|
+
process.kill(pid, 0);
|
|
587
|
+
active.push(lockFile);
|
|
588
|
+
}
|
|
589
|
+
catch (err) {
|
|
590
|
+
if (err.code === 'ESRCH') {
|
|
591
|
+
stale.push(lockFile);
|
|
592
|
+
}
|
|
593
|
+
else {
|
|
594
|
+
// EPERM = process exists, owned by another user. Treat as active.
|
|
595
|
+
active.push(lockFile);
|
|
596
|
+
}
|
|
597
|
+
}
|
|
489
598
|
}
|
|
490
599
|
else {
|
|
491
|
-
|
|
600
|
+
const stat = fs.statSync(lockPath);
|
|
601
|
+
if (stat.mtimeMs < oneDayAgo) {
|
|
602
|
+
stale.push(lockFile);
|
|
603
|
+
}
|
|
604
|
+
else {
|
|
605
|
+
active.push(lockFile);
|
|
606
|
+
}
|
|
492
607
|
}
|
|
493
608
|
}
|
|
494
609
|
if (stale.length > 0) {
|
|
@@ -542,6 +657,207 @@ async function checkOpenClawResidue() {
|
|
|
542
657
|
return { label: 'OpenClaw residue', status: 'warn', message: `check failed — ${msg}` };
|
|
543
658
|
}
|
|
544
659
|
}
|
|
660
|
+
// ── Check 9: Auto-memory sampling rate (#44) ──────────────
|
|
661
|
+
/**
|
|
662
|
+
* Reports the resolved `autoMemory.stopHookSamplingTurns` and salience-bypass
|
|
663
|
+
* setting. Defaults dropped 10 → 5 (and salience bypass added) in v4.14.0;
|
|
664
|
+
* warn if a user pinned a sparser cadence likely to under-feed LTM.
|
|
665
|
+
*
|
|
666
|
+
* Reads the config file directly rather than importing the .mjs helper so
|
|
667
|
+
* doctor doesn't depend on path layout between dist/ and scripts/.
|
|
668
|
+
*/
|
|
669
|
+
async function checkAutoMemorySampling() {
|
|
670
|
+
try {
|
|
671
|
+
const configPath = path.join(getShieldCortexDir(), 'config.json');
|
|
672
|
+
let raw = {};
|
|
673
|
+
if (fs.existsSync(configPath)) {
|
|
674
|
+
try {
|
|
675
|
+
raw = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
|
|
676
|
+
}
|
|
677
|
+
catch {
|
|
678
|
+
/* fall through to defaults */
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
const overrides = raw.autoMemory ?? {};
|
|
682
|
+
const sampling = typeof overrides.stopHookSamplingTurns === 'number' &&
|
|
683
|
+
Number.isFinite(overrides.stopHookSamplingTurns) &&
|
|
684
|
+
overrides.stopHookSamplingTurns > 0
|
|
685
|
+
? Math.floor(overrides.stopHookSamplingTurns)
|
|
686
|
+
: 5; // default in auto-memory-config.mjs as of v4.14.0
|
|
687
|
+
const bypassEnabled = typeof overrides.stopHookSalienceBypass === 'boolean' ? overrides.stopHookSalienceBypass : true;
|
|
688
|
+
const bypass = bypassEnabled ? 'on' : 'off';
|
|
689
|
+
if (sampling <= 5) {
|
|
690
|
+
return {
|
|
691
|
+
label: 'Auto-memory sampling',
|
|
692
|
+
status: 'pass',
|
|
693
|
+
message: `every ${sampling} turn(s), salience-bypass ${bypass}`,
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
return {
|
|
697
|
+
label: 'Auto-memory sampling',
|
|
698
|
+
status: 'warn',
|
|
699
|
+
message: `every ${sampling} turn(s), salience-bypass ${bypass} — sparser than recommended`,
|
|
700
|
+
fix: 'Edit ~/.shieldcortex/config.json autoMemory.stopHookSamplingTurns (≤ 5 recommended)',
|
|
701
|
+
};
|
|
702
|
+
}
|
|
703
|
+
catch (err) {
|
|
704
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
705
|
+
return { label: 'Auto-memory sampling', status: 'info', message: `check skipped — ${msg}` };
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
// ── Check 10: Brain-worker freshness (#45) ────────────────
|
|
709
|
+
/**
|
|
710
|
+
* The MCP server starts a lite-profile brain worker on connect (v4.14.0).
|
|
711
|
+
* Each light tick writes to ~/.shieldcortex/state/worker.json. If the
|
|
712
|
+
* timestamp is missing or older than 30 min, consolidation has likely
|
|
713
|
+
* stalled — STM won't graduate to LTM.
|
|
714
|
+
*/
|
|
715
|
+
async function checkBrainWorker() {
|
|
716
|
+
if (process.env.SHIELDCORTEX_DISABLE_WORKER === '1') {
|
|
717
|
+
return {
|
|
718
|
+
label: 'Brain worker',
|
|
719
|
+
status: 'info',
|
|
720
|
+
message: 'disabled via SHIELDCORTEX_DISABLE_WORKER=1',
|
|
721
|
+
};
|
|
722
|
+
}
|
|
723
|
+
const statePath = path.join(getShieldCortexDir(), 'state', 'worker.json');
|
|
724
|
+
if (!fs.existsSync(statePath)) {
|
|
725
|
+
return {
|
|
726
|
+
label: 'Brain worker',
|
|
727
|
+
status: 'warn',
|
|
728
|
+
message: 'no worker.json — worker has not run yet',
|
|
729
|
+
fix: 'Start an MCP-bound session (Claude Code) or run `shieldcortex worker` to drive consolidation',
|
|
730
|
+
};
|
|
731
|
+
}
|
|
732
|
+
try {
|
|
733
|
+
const raw = JSON.parse(fs.readFileSync(statePath, 'utf-8'));
|
|
734
|
+
const last = raw.lastLightTick ? new Date(raw.lastLightTick) : null;
|
|
735
|
+
if (!last || Number.isNaN(last.getTime())) {
|
|
736
|
+
return {
|
|
737
|
+
label: 'Brain worker',
|
|
738
|
+
status: 'warn',
|
|
739
|
+
message: 'worker.json present but lastLightTick missing/invalid',
|
|
740
|
+
fix: 'Restart Claude Code to spawn a fresh MCP server',
|
|
741
|
+
};
|
|
742
|
+
}
|
|
743
|
+
const ageMs = Date.now() - last.getTime();
|
|
744
|
+
const ageMin = Math.round(ageMs / 60000);
|
|
745
|
+
if (ageMs > 30 * 60 * 1000) {
|
|
746
|
+
return {
|
|
747
|
+
label: 'Brain worker',
|
|
748
|
+
status: 'warn',
|
|
749
|
+
message: `last tick ${ageMin}m ago (profile=${raw.profile ?? '?'}, pid=${raw.pid ?? '?'})`,
|
|
750
|
+
fix: 'Restart Claude Code or run `shieldcortex worker` to resume consolidation',
|
|
751
|
+
};
|
|
752
|
+
}
|
|
753
|
+
return {
|
|
754
|
+
label: 'Brain worker',
|
|
755
|
+
status: 'pass',
|
|
756
|
+
message: `last tick ${ageMin}m ago (profile=${raw.profile ?? '?'}, pid=${raw.pid ?? '?'})`,
|
|
757
|
+
};
|
|
758
|
+
}
|
|
759
|
+
catch (err) {
|
|
760
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
761
|
+
return { label: 'Brain worker', status: 'warn', message: `check failed — ${msg}` };
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
// ── Check 11: Project-key consistency (#42) ───────────────
|
|
765
|
+
/**
|
|
766
|
+
* Detects rows tagged with both legacy basename keys and canonical
|
|
767
|
+
* owner-repo keys (the symptom of pre-v4.14.0 stop-hook writes). If any
|
|
768
|
+
* basename collides with a `<something>-<basename>` form already in the
|
|
769
|
+
* DB, point the user at `repair-project-keys`.
|
|
770
|
+
*/
|
|
771
|
+
async function checkProjectKeyConsistency() {
|
|
772
|
+
const dbPath = getDbPath();
|
|
773
|
+
if (!fs.existsSync(dbPath)) {
|
|
774
|
+
return { label: 'Project keys', status: 'info', message: 'skipped (no DB yet)' };
|
|
775
|
+
}
|
|
776
|
+
try {
|
|
777
|
+
const Database = require('better-sqlite3');
|
|
778
|
+
const db = new Database(dbPath, { readonly: true });
|
|
779
|
+
try {
|
|
780
|
+
const rows = db
|
|
781
|
+
.prepare("SELECT DISTINCT project FROM memories WHERE project IS NOT NULL AND project != ''")
|
|
782
|
+
.all();
|
|
783
|
+
const keys = rows.map((r) => r.project);
|
|
784
|
+
const collisions = [];
|
|
785
|
+
for (const candidate of keys) {
|
|
786
|
+
// A candidate is "legacy-looking" if it has no hyphen (cwd basename).
|
|
787
|
+
if (candidate.includes('-'))
|
|
788
|
+
continue;
|
|
789
|
+
const suffix = `-${candidate}`;
|
|
790
|
+
const matched = keys.find((k) => k !== candidate && k.endsWith(suffix));
|
|
791
|
+
if (matched)
|
|
792
|
+
collisions.push({ legacy: candidate, canonical: matched });
|
|
793
|
+
}
|
|
794
|
+
if (collisions.length === 0) {
|
|
795
|
+
return { label: 'Project keys', status: 'pass', message: `${keys.length} distinct, no legacy/canonical collisions` };
|
|
796
|
+
}
|
|
797
|
+
const example = collisions.slice(0, 3).map((c) => `${c.legacy} ↔ ${c.canonical}`).join('; ');
|
|
798
|
+
const more = collisions.length > 3 ? ` (+${collisions.length - 3} more)` : '';
|
|
799
|
+
return {
|
|
800
|
+
label: 'Project keys',
|
|
801
|
+
status: 'warn',
|
|
802
|
+
message: `${collisions.length} legacy/canonical collision(s): ${example}${more}`,
|
|
803
|
+
fix: 'Run `shieldcortex memories repair-project-keys --scan-paths <root>` (dry-run by default)',
|
|
804
|
+
};
|
|
805
|
+
}
|
|
806
|
+
finally {
|
|
807
|
+
db.close();
|
|
808
|
+
}
|
|
809
|
+
}
|
|
810
|
+
catch (err) {
|
|
811
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
812
|
+
return { label: 'Project keys', status: 'warn', message: `check failed — ${msg}` };
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
// ── Check 12: Hook timeouts (#43) ─────────────────────────
|
|
816
|
+
/**
|
|
817
|
+
* Compares each ShieldCortex hook's timeout in ~/.claude/settings.json
|
|
818
|
+
* against the canonical values written by `shieldcortex setup`. Catches
|
|
819
|
+
* the v4.13.x silent-recall failure mode where users on a hand-edited
|
|
820
|
+
* settings.json still ran with `UserPromptSubmit.timeout: 2`.
|
|
821
|
+
*/
|
|
822
|
+
async function checkHookTimeouts() {
|
|
823
|
+
const settingsPath = path.join(os.homedir(), '.claude', 'settings.json');
|
|
824
|
+
if (!fs.existsSync(settingsPath)) {
|
|
825
|
+
return { label: 'Hook timeouts', status: 'info', message: 'skipped (settings.json not found)' };
|
|
826
|
+
}
|
|
827
|
+
try {
|
|
828
|
+
const { CANONICAL_HOOK_TIMEOUTS } = await import('../setup/settings-hooks.js');
|
|
829
|
+
const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
|
|
830
|
+
const hooks = settings.hooks ?? {};
|
|
831
|
+
const drift = [];
|
|
832
|
+
for (const [name, expected] of Object.entries(CANONICAL_HOOK_TIMEOUTS)) {
|
|
833
|
+
const entries = hooks[name];
|
|
834
|
+
if (!Array.isArray(entries))
|
|
835
|
+
continue;
|
|
836
|
+
for (const entry of entries) {
|
|
837
|
+
for (const h of entry.hooks ?? []) {
|
|
838
|
+
if (typeof h.command !== 'string' || !h.command.includes('shieldcortex'))
|
|
839
|
+
continue;
|
|
840
|
+
if (typeof h.timeout === 'number' && h.timeout < expected) {
|
|
841
|
+
drift.push(`${name}=${h.timeout}s (canonical ${expected}s)`);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
if (drift.length === 0) {
|
|
847
|
+
return { label: 'Hook timeouts', status: 'pass', message: 'all canonical' };
|
|
848
|
+
}
|
|
849
|
+
return {
|
|
850
|
+
label: 'Hook timeouts',
|
|
851
|
+
status: 'warn',
|
|
852
|
+
message: `below canonical: ${drift.join(', ')}`,
|
|
853
|
+
fix: 'Re-run `shieldcortex install` to restore canonical timeouts',
|
|
854
|
+
};
|
|
855
|
+
}
|
|
856
|
+
catch (err) {
|
|
857
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
858
|
+
return { label: 'Hook timeouts', status: 'info', message: `check skipped — ${msg}` };
|
|
859
|
+
}
|
|
860
|
+
}
|
|
545
861
|
// ── Check 8: Model cache ─────────────────────────────────
|
|
546
862
|
async function checkModelCache() {
|
|
547
863
|
const cacheDir = path.join(os.homedir(), '.cache', 'shieldcortex', 'models', 'Xenova', 'all-MiniLM-L6-v2');
|
|
@@ -588,6 +904,11 @@ export async function runDoctor() {
|
|
|
588
904
|
checkWritePath, // Smoke test: real INSERT/SELECT/DELETE round-trip — catches silent schema drift
|
|
589
905
|
checkMemoryStats,
|
|
590
906
|
checkHooks,
|
|
907
|
+
checkHookTimeouts,
|
|
908
|
+
checkAutoMemoryHooks,
|
|
909
|
+
checkAutoMemorySampling,
|
|
910
|
+
checkBrainWorker,
|
|
911
|
+
checkProjectKeyConsistency,
|
|
591
912
|
checkProcesses,
|
|
592
913
|
checkDiskUsage,
|
|
593
914
|
checkLockFile,
|
|
@@ -25,4 +25,34 @@ interface MigrationReport {
|
|
|
25
25
|
}
|
|
26
26
|
export declare function migrateLegacy(options?: MigrateOptions): MigrationReport;
|
|
27
27
|
export declare function handleMemoriesCommand(args: string[]): Promise<void>;
|
|
28
|
+
interface RepairOptions {
|
|
29
|
+
/** Path to memories.db (defaults to ~/.shieldcortex/memories.db) */
|
|
30
|
+
dbPath?: string;
|
|
31
|
+
/** Walk these dev roots one level deep, propose mappings unambiguously */
|
|
32
|
+
scanPaths?: string[];
|
|
33
|
+
/** Explicit overrides; basename → canonical-key */
|
|
34
|
+
map?: Record<string, string>;
|
|
35
|
+
/** Limit the scan to a single legacy project key */
|
|
36
|
+
onlyProject?: string;
|
|
37
|
+
/** Include short-term rows (default: long-term + episodic only) */
|
|
38
|
+
includeStm?: boolean;
|
|
39
|
+
/** Default false — must be true to actually write */
|
|
40
|
+
execute?: boolean;
|
|
41
|
+
/** When true, never prompt (used by tests). Defaults to interactive. */
|
|
42
|
+
noConfirm?: boolean;
|
|
43
|
+
}
|
|
44
|
+
interface RepairProposal {
|
|
45
|
+
legacy: string;
|
|
46
|
+
canonical: string;
|
|
47
|
+
count: number;
|
|
48
|
+
source: 'map' | 'scan';
|
|
49
|
+
}
|
|
50
|
+
interface RepairReport {
|
|
51
|
+
dryRun: boolean;
|
|
52
|
+
proposals: RepairProposal[];
|
|
53
|
+
applied: number;
|
|
54
|
+
logPath?: string;
|
|
55
|
+
backupPath?: string;
|
|
56
|
+
}
|
|
57
|
+
export declare function repairProjectKeys(opts?: RepairOptions): Promise<RepairReport>;
|
|
28
58
|
export {};
|
|
@@ -2,7 +2,9 @@ import fs from 'fs';
|
|
|
2
2
|
import path from 'path';
|
|
3
3
|
import os from 'os';
|
|
4
4
|
import { randomUUID } from 'crypto';
|
|
5
|
+
import readline from 'readline';
|
|
5
6
|
import Database from 'better-sqlite3';
|
|
7
|
+
import { deriveProjectKey } from '../context/derive-project-key.js';
|
|
6
8
|
const DEFAULT_LEGACY_SOURCES = [
|
|
7
9
|
path.join(os.homedir(), '.claude-cortex', 'memories.db'),
|
|
8
10
|
path.join(os.homedir(), '.claude-memory', 'memories.db'),
|
|
@@ -265,6 +267,14 @@ function printUsage() {
|
|
|
265
267
|
console.log(' Cluster near-duplicate long-term memories and keep the highest-');
|
|
266
268
|
console.log(' salience representative. DRY-RUN BY DEFAULT — pass --execute.');
|
|
267
269
|
console.log(' Backup auto-saved before any merge.');
|
|
270
|
+
console.log('');
|
|
271
|
+
console.log(' repair-project-keys [--scan-paths <dir,dir,...>]');
|
|
272
|
+
console.log(' [--map basename=canonical] (repeatable)');
|
|
273
|
+
console.log(' [--project <key>] [--include-stm] [--execute]');
|
|
274
|
+
console.log(' Relabel memories tagged under a legacy basename project key');
|
|
275
|
+
console.log(' to their canonical owner-repo key (#42). DRY-RUN BY DEFAULT.');
|
|
276
|
+
console.log(' Backup auto-saved before any rewrite; per-rewrite log written');
|
|
277
|
+
console.log(' to ~/.shieldcortex/logs/project-key-repair-<ts>.json.');
|
|
268
278
|
}
|
|
269
279
|
export async function handleMemoriesCommand(args) {
|
|
270
280
|
const sub = args[0];
|
|
@@ -286,6 +296,195 @@ export async function handleMemoriesCommand(args) {
|
|
|
286
296
|
await runDedupe(args.slice(1));
|
|
287
297
|
return;
|
|
288
298
|
}
|
|
299
|
+
if (sub === 'repair-project-keys') {
|
|
300
|
+
await runRepairProjectKeys(args.slice(1));
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
289
303
|
printUsage();
|
|
290
304
|
process.exit(1);
|
|
291
305
|
}
|
|
306
|
+
function parseMapFlags(args) {
|
|
307
|
+
const map = {};
|
|
308
|
+
for (let i = 0; i < args.length; i++) {
|
|
309
|
+
if (args[i] === '--map' && args[i + 1]) {
|
|
310
|
+
const pair = args[i + 1];
|
|
311
|
+
const eq = pair.indexOf('=');
|
|
312
|
+
if (eq <= 0 || eq === pair.length - 1) {
|
|
313
|
+
throw new Error(`--map expects 'basename=canonical', got '${pair}'`);
|
|
314
|
+
}
|
|
315
|
+
const k = pair.slice(0, eq).trim();
|
|
316
|
+
const v = pair.slice(eq + 1).trim();
|
|
317
|
+
if (!k || !v)
|
|
318
|
+
throw new Error(`--map basename and canonical must be non-empty: '${pair}'`);
|
|
319
|
+
map[k] = v;
|
|
320
|
+
i++;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
return map;
|
|
324
|
+
}
|
|
325
|
+
function parseScanPaths(args) {
|
|
326
|
+
const v = flagValue(args, '--scan-paths');
|
|
327
|
+
if (!v)
|
|
328
|
+
return [];
|
|
329
|
+
return v
|
|
330
|
+
.split(',')
|
|
331
|
+
.map((s) => s.trim().replace(/^~(?=\/|$)/, os.homedir()))
|
|
332
|
+
.filter(Boolean);
|
|
333
|
+
}
|
|
334
|
+
async function confirmExecute(prompt) {
|
|
335
|
+
if (!process.stdin.isTTY)
|
|
336
|
+
return false;
|
|
337
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
338
|
+
try {
|
|
339
|
+
const answer = await new Promise((resolve) => rl.question(prompt, resolve));
|
|
340
|
+
return /^y(es)?$/i.test(answer.trim());
|
|
341
|
+
}
|
|
342
|
+
finally {
|
|
343
|
+
rl.close();
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
export async function repairProjectKeys(opts = {}) {
|
|
347
|
+
const dbPath = opts.dbPath ?? DEFAULT_TARGET;
|
|
348
|
+
if (!fs.existsSync(dbPath)) {
|
|
349
|
+
throw new Error(`memories DB not found at ${dbPath} — run \`shieldcortex setup\` first`);
|
|
350
|
+
}
|
|
351
|
+
const explicit = opts.map ?? {};
|
|
352
|
+
const scanPaths = opts.scanPaths ?? [];
|
|
353
|
+
const includeStm = opts.includeStm === true;
|
|
354
|
+
const dryRun = opts.execute !== true;
|
|
355
|
+
const db = new Database(dbPath);
|
|
356
|
+
db.pragma('busy_timeout = 10000');
|
|
357
|
+
let report;
|
|
358
|
+
try {
|
|
359
|
+
// 1. Distinct legacy project keys in the DB.
|
|
360
|
+
const typeFilter = includeStm ? '' : "AND type IN ('long_term', 'episodic')";
|
|
361
|
+
const distinct = db
|
|
362
|
+
.prepare(`SELECT DISTINCT project FROM memories WHERE project IS NOT NULL ${typeFilter}`)
|
|
363
|
+
.all();
|
|
364
|
+
const dbProjects = new Set(distinct.map((r) => r.project));
|
|
365
|
+
// 2. Build the proposal set.
|
|
366
|
+
const proposals = [];
|
|
367
|
+
const seen = new Set();
|
|
368
|
+
const addProposal = (legacy, canonical, source) => {
|
|
369
|
+
if (legacy === canonical)
|
|
370
|
+
return;
|
|
371
|
+
if (opts.onlyProject && legacy !== opts.onlyProject)
|
|
372
|
+
return;
|
|
373
|
+
if (!dbProjects.has(legacy))
|
|
374
|
+
return;
|
|
375
|
+
const key = `${legacy}${canonical}`;
|
|
376
|
+
if (seen.has(key))
|
|
377
|
+
return;
|
|
378
|
+
seen.add(key);
|
|
379
|
+
const countQ = db
|
|
380
|
+
.prepare(`SELECT COUNT(*) AS n FROM memories WHERE project = ? ${typeFilter}`)
|
|
381
|
+
.get(legacy);
|
|
382
|
+
proposals.push({ legacy, canonical, count: countQ.n, source });
|
|
383
|
+
};
|
|
384
|
+
// 2a. --map overrides win.
|
|
385
|
+
for (const [legacy, canonical] of Object.entries(explicit)) {
|
|
386
|
+
addProposal(legacy, canonical, 'map');
|
|
387
|
+
}
|
|
388
|
+
// 2b. --scan-paths: walk one level deep, run deriveProjectKey, match by basename.
|
|
389
|
+
for (const root of scanPaths) {
|
|
390
|
+
let entries = [];
|
|
391
|
+
try {
|
|
392
|
+
entries = fs.readdirSync(root);
|
|
393
|
+
}
|
|
394
|
+
catch {
|
|
395
|
+
continue;
|
|
396
|
+
}
|
|
397
|
+
for (const name of entries) {
|
|
398
|
+
const child = path.join(root, name);
|
|
399
|
+
let isDir = false;
|
|
400
|
+
try {
|
|
401
|
+
isDir = fs.statSync(child).isDirectory();
|
|
402
|
+
}
|
|
403
|
+
catch {
|
|
404
|
+
continue;
|
|
405
|
+
}
|
|
406
|
+
if (!isDir)
|
|
407
|
+
continue;
|
|
408
|
+
const canonical = deriveProjectKey(child);
|
|
409
|
+
if (!canonical || canonical === name)
|
|
410
|
+
continue;
|
|
411
|
+
addProposal(name, canonical, 'scan');
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
report = {
|
|
415
|
+
dryRun,
|
|
416
|
+
proposals,
|
|
417
|
+
applied: 0,
|
|
418
|
+
};
|
|
419
|
+
// 3. Print proposal table.
|
|
420
|
+
const banner = dryRun ? '[DRY RUN] ' : '';
|
|
421
|
+
console.log(`${banner}Project-key repair plan (${dbPath}):`);
|
|
422
|
+
if (proposals.length === 0) {
|
|
423
|
+
console.log(' No proposed rewrites — nothing to do.');
|
|
424
|
+
console.log('');
|
|
425
|
+
console.log('Tip: pass `--scan-paths ~/Development` (or `--map old=new`) so the');
|
|
426
|
+
console.log(' repair tool can match legacy basename keys against canonical');
|
|
427
|
+
console.log(' owner-repo keys derived from the git origin.');
|
|
428
|
+
return report;
|
|
429
|
+
}
|
|
430
|
+
for (const p of proposals) {
|
|
431
|
+
console.log(` ${p.legacy.padEnd(40)} → ${p.canonical.padEnd(48)} (${p.count} rows, source: ${p.source})`);
|
|
432
|
+
}
|
|
433
|
+
const totalRows = proposals.reduce((s, p) => s + p.count, 0);
|
|
434
|
+
console.log('');
|
|
435
|
+
console.log(`Total: ${totalRows} rows across ${proposals.length} project key(s).`);
|
|
436
|
+
if (dryRun) {
|
|
437
|
+
console.log('');
|
|
438
|
+
console.log('Re-run with --execute to apply. To undo later:');
|
|
439
|
+
console.log(' shieldcortex memories repair-project-keys \\');
|
|
440
|
+
console.log(' ' + proposals.map((p) => `--map ${p.canonical}=${p.legacy}`).join(' \\\n ') + ' --execute');
|
|
441
|
+
return report;
|
|
442
|
+
}
|
|
443
|
+
// 4. Confirm + backup + write.
|
|
444
|
+
if (!opts.noConfirm) {
|
|
445
|
+
const ok = await confirmExecute(`\nApply ${proposals.length} rewrite(s) to ${totalRows} rows? [y/N] `);
|
|
446
|
+
if (!ok) {
|
|
447
|
+
console.log('Aborted — no changes written.');
|
|
448
|
+
return report;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
const backupPath = `${dbPath}.bak.${new Date().toISOString().replace(/[:.]/g, '-')}`;
|
|
452
|
+
fs.copyFileSync(dbPath, backupPath);
|
|
453
|
+
report.backupPath = backupPath;
|
|
454
|
+
console.log(`Backup: ${backupPath}`);
|
|
455
|
+
const update = db.prepare(`UPDATE memories SET project = ? WHERE project = ? ${typeFilter}`);
|
|
456
|
+
const txn = db.transaction(() => {
|
|
457
|
+
for (const p of proposals) {
|
|
458
|
+
const r = update.run(p.canonical, p.legacy);
|
|
459
|
+
report.applied += r.changes;
|
|
460
|
+
}
|
|
461
|
+
});
|
|
462
|
+
txn();
|
|
463
|
+
// 5. Per-rewrite JSON log under ~/.shieldcortex/logs/.
|
|
464
|
+
const logsDir = path.join(os.homedir(), '.shieldcortex', 'logs');
|
|
465
|
+
fs.mkdirSync(logsDir, { recursive: true });
|
|
466
|
+
const logPath = path.join(logsDir, `project-key-repair-${new Date().toISOString().replace(/[:.]/g, '-')}.json`);
|
|
467
|
+
fs.writeFileSync(logPath, JSON.stringify({
|
|
468
|
+
dbPath,
|
|
469
|
+
backupPath,
|
|
470
|
+
appliedAt: new Date().toISOString(),
|
|
471
|
+
rewrites: proposals,
|
|
472
|
+
totalRowsAffected: report.applied,
|
|
473
|
+
}, null, 2), 'utf-8');
|
|
474
|
+
report.logPath = logPath;
|
|
475
|
+
console.log(`Applied: ${report.applied} rows`);
|
|
476
|
+
console.log(`Log: ${logPath}`);
|
|
477
|
+
}
|
|
478
|
+
finally {
|
|
479
|
+
db.close();
|
|
480
|
+
}
|
|
481
|
+
return report;
|
|
482
|
+
}
|
|
483
|
+
async function runRepairProjectKeys(args) {
|
|
484
|
+
const map = parseMapFlags(args);
|
|
485
|
+
const scanPaths = parseScanPaths(args);
|
|
486
|
+
const onlyProject = flagValue(args, '--project');
|
|
487
|
+
const includeStm = args.includes('--include-stm');
|
|
488
|
+
const execute = args.includes('--execute');
|
|
489
|
+
await repairProjectKeys({ map, scanPaths, onlyProject, includeStm, execute });
|
|
490
|
+
}
|
package/dist/cloud/config.d.ts
CHANGED
|
@@ -116,6 +116,28 @@ export declare function setProactiveRecall(enabled: boolean): void;
|
|
|
116
116
|
* so the flip is a one-command undo.
|
|
117
117
|
*/
|
|
118
118
|
export declare function restore410Defaults(): void;
|
|
119
|
+
export interface AutoMemoryEnableConfig {
|
|
120
|
+
enableStop: boolean;
|
|
121
|
+
enableSessionEnd: boolean;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Returns the resolved on/off state of the opt-in auto-memory hooks.
|
|
125
|
+
*
|
|
126
|
+
* Default is false for both — preserves the OpenClaw-safe default that
|
|
127
|
+
* shipped in v4.13.0. The install flags (`--with-stop-hook` /
|
|
128
|
+
* `--with-session-end`) flip these to true so that wiring the hook in
|
|
129
|
+
* settings.json and enabling the runtime gate are a single user action.
|
|
130
|
+
*/
|
|
131
|
+
export declare function getAutoMemoryEnableConfig(): AutoMemoryEnableConfig;
|
|
132
|
+
/**
|
|
133
|
+
* Persists the on/off state of the opt-in auto-memory hooks.
|
|
134
|
+
*
|
|
135
|
+
* Lives in `autoMemory.enableStop` / `autoMemory.enableSessionEnd` under
|
|
136
|
+
* `~/.shieldcortex/config.json` — the same namespace `auto-memory-config.mjs`
|
|
137
|
+
* reads from at hook fire time. Single source of truth: install flag +
|
|
138
|
+
* runtime gate cannot disagree.
|
|
139
|
+
*/
|
|
140
|
+
export declare function setAutoMemoryEnableConfig(updates: Partial<AutoMemoryEnableConfig>): void;
|
|
119
141
|
export interface ToolResponseScanConfig {
|
|
120
142
|
scanToolResponses: boolean;
|
|
121
143
|
toolResponseMode: 'advisory' | 'enforce';
|