shieldcortex 4.31.2 → 4.32.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -2
- package/dashboard/.next/standalone/dashboard/.next/BUILD_ID +1 -1
- package/dashboard/.next/standalone/dashboard/.next/build-manifest.json +2 -2
- package/dashboard/.next/standalone/dashboard/.next/prerender-manifest.json +3 -3
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory/replay/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory/replay.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray/__PAGE__.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_full.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_head.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_index.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_tree.segment.rsc +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.json +1 -1
- package/dist/api/control.d.ts +2 -0
- package/dist/api/control.js +119 -2
- package/dist/api/routes/memories.js +19 -14
- package/dist/api/routes/system.js +2 -3
- package/dist/api/visualization-server.d.ts +13 -1
- package/dist/api/visualization-server.js +57 -1
- package/dist/audit/env-scanner.js +5 -2
- package/dist/audit/index.d.ts +4 -1
- package/dist/audit/index.js +2 -1
- package/dist/audit/mcp-config-scanner.d.ts +23 -0
- package/dist/audit/mcp-config-scanner.js +110 -0
- package/dist/audit/mcp-tools-scanner.d.ts +112 -0
- package/dist/audit/mcp-tools-scanner.js +299 -0
- package/dist/cli/audit.d.ts +1 -0
- package/dist/cli/audit.js +12 -1
- package/dist/cli/mcp.d.ts +13 -0
- package/dist/cli/mcp.js +0 -0
- package/dist/cli/remember.d.ts +75 -0
- package/dist/cli/remember.js +195 -0
- package/dist/cloud/config.d.ts +23 -1
- package/dist/cloud/config.js +453 -193
- package/dist/cloud/quarantine-sync.d.ts +12 -2
- package/dist/cloud/quarantine-sync.js +28 -6
- package/dist/cloud/sync-queue.d.ts +21 -2
- package/dist/cloud/sync-queue.js +124 -29
- package/dist/database/better-sqlite3-guard.d.ts +21 -2
- package/dist/database/better-sqlite3-guard.js +29 -5
- package/dist/database/init.js +68 -16
- package/dist/database/inline-schema.js +35 -1
- package/dist/database/migrations.js +104 -8
- package/dist/database/schema.sql +39 -1
- package/dist/defence/audit/queries.d.ts +10 -2
- package/dist/defence/audit/queries.js +30 -4
- package/dist/defence/audit/retention.d.ts +50 -0
- package/dist/defence/audit/retention.js +161 -0
- package/dist/defence/credential-leak/entropy.d.ts +11 -0
- package/dist/defence/credential-leak/entropy.js +27 -0
- package/dist/defence/credential-leak/index.js +27 -1
- package/dist/defence/credential-leak/patterns.d.ts +9 -0
- package/dist/defence/credential-leak/patterns.js +21 -0
- package/dist/defence/custom-patterns/store.js +8 -1
- package/dist/defence/custom-rules/store.d.ts +18 -0
- package/dist/defence/custom-rules/store.js +63 -0
- package/dist/defence/firewall/confusables.d.ts +30 -0
- package/dist/defence/firewall/confusables.js +87 -0
- package/dist/defence/firewall/encoding-detector.js +23 -9
- package/dist/defence/firewall/index.d.ts +11 -1
- package/dist/defence/firewall/index.js +34 -1
- package/dist/defence/firewall/instruction-detector.js +18 -7
- package/dist/defence/firewall/markdown-image-detector.d.ts +34 -0
- package/dist/defence/firewall/markdown-image-detector.js +83 -0
- package/dist/defence/fragmentation/entity-extractor.js +17 -6
- package/dist/defence/index.d.ts +5 -0
- package/dist/defence/index.js +8 -0
- package/dist/defence/iron-dome/index.js +7 -1
- package/dist/defence/pipeline.js +62 -10
- package/dist/defence/scan-windows.d.ts +41 -0
- package/dist/defence/scan-windows.js +61 -0
- package/dist/defence/semantic/attack-corpus.d.ts +22 -0
- package/dist/defence/semantic/attack-corpus.js +75 -0
- package/dist/defence/semantic/index.d.ts +67 -0
- package/dist/defence/semantic/index.js +138 -0
- package/dist/defence/skill-scanner/deep-scan.js +35 -15
- package/dist/defence/skill-scanner/patterns.d.ts +1 -1
- package/dist/defence/skill-scanner/patterns.js +8 -7
- package/dist/defence/tool-response-scanner.d.ts +21 -5
- package/dist/defence/tool-response-scanner.js +111 -22
- package/dist/defence/types.d.ts +11 -1
- package/dist/index.d.ts +29 -0
- package/dist/index.js +104 -20
- package/dist/memory/consolidate.js +1 -1
- package/dist/memory/decay.js +3 -1
- package/dist/memory/embedding.d.ts +18 -2
- package/dist/memory/embedding.js +32 -11
- package/dist/memory/expiry.js +1 -1
- package/dist/memory/search-recall.js +107 -49
- package/dist/memory/search.d.ts +19 -3
- package/dist/memory/search.js +25 -10
- package/dist/memory/store.d.ts +13 -2
- package/dist/memory/store.js +115 -11
- package/dist/scan-only.d.ts +64 -0
- package/dist/scan-only.js +173 -0
- package/dist/server.d.ts +5 -0
- package/dist/server.js +6 -4
- package/dist/setup/claude-md.js +39 -34
- package/dist/setup/codex.js +9 -2
- package/dist/setup/copilot.js +160 -47
- package/dist/setup/json-config.d.ts +99 -0
- package/dist/setup/json-config.js +167 -0
- package/dist/setup/migrate.js +1 -1
- package/dist/setup/settings-hooks.js +8 -13
- package/dist/setup/uninstall.js +1 -21
- package/dist/tools/context.d.ts +8 -8
- package/dist/tools/forget.d.ts +9 -8
- package/dist/tools/forget.js +17 -4
- package/dist/tools/recall.d.ts +13 -13
- package/dist/tools/remember.d.ts +16 -16
- package/dist/tools/remember.js +19 -8
- package/dist/worker/brain-worker.d.ts +1 -0
- package/dist/worker/brain-worker.js +79 -16
- package/dist/worker/types.d.ts +8 -0
- package/dist/worker/types.js +8 -0
- package/dist/xray/dir-scanner.d.ts +18 -0
- package/dist/xray/dir-scanner.js +23 -1
- package/dist/xray/file-scanner.js +16 -1
- package/dist/xray/findings-store.js +9 -1
- package/dist/xray/index.d.ts +2 -0
- package/dist/xray/index.js +10 -1
- package/dist/xray/npm-inspector.d.ts +31 -0
- package/dist/xray/npm-inspector.js +135 -29
- package/dist/xray/patterns.d.ts +1 -1
- package/dist/xray/patterns.js +20 -23
- package/dist/xray/sarif.d.ts +78 -0
- package/dist/xray/sarif.js +166 -0
- package/dist/xray/watch.d.ts +1 -0
- package/dist/xray/watch.js +10 -1
- package/hooks/openclaw/cortex-memory/handler.ts +122 -18
- package/hooks/openclaw/cortex-memory/runtime.mjs +10 -4
- package/package.json +10 -3
- package/dist/memory/embedding-cache.d.ts +0 -20
- package/dist/memory/embedding-cache.js +0 -91
- /package/dashboard/.next/standalone/dashboard/.next/static/{_j4TeMpss-w79QtNNWqZw → Ox9scglBehbbCk7DD8-Vn}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{_j4TeMpss-w79QtNNWqZw → Ox9scglBehbbCk7DD8-Vn}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{_j4TeMpss-w79QtNNWqZw → Ox9scglBehbbCk7DD8-Vn}/_ssgManifest.js +0 -0
package/dist/tools/context.d.ts
CHANGED
|
@@ -15,27 +15,27 @@ export declare const getContextSchema: z.ZodObject<{
|
|
|
15
15
|
type: z.ZodEnum<["user", "cli", "hook", "email", "web", "agent", "file", "api", "tool_response"]>;
|
|
16
16
|
identifier: z.ZodString;
|
|
17
17
|
}, "strip", z.ZodTypeAny, {
|
|
18
|
-
type: "user" | "cli" | "hook" | "
|
|
18
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
19
19
|
identifier: string;
|
|
20
20
|
}, {
|
|
21
|
-
type: "user" | "cli" | "hook" | "
|
|
21
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
22
22
|
identifier: string;
|
|
23
23
|
}>>;
|
|
24
24
|
}, "strip", z.ZodTypeAny, {
|
|
25
|
-
format: "summary" | "
|
|
25
|
+
format: "summary" | "raw" | "detailed";
|
|
26
26
|
source?: {
|
|
27
|
-
type: "user" | "cli" | "hook" | "
|
|
27
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
28
28
|
identifier: string;
|
|
29
29
|
} | undefined;
|
|
30
30
|
project?: string | undefined;
|
|
31
31
|
query?: string | undefined;
|
|
32
32
|
}, {
|
|
33
33
|
source?: {
|
|
34
|
-
type: "user" | "cli" | "hook" | "
|
|
34
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
35
35
|
identifier: string;
|
|
36
36
|
} | undefined;
|
|
37
37
|
project?: string | undefined;
|
|
38
|
-
format?: "summary" | "
|
|
38
|
+
format?: "summary" | "raw" | "detailed" | undefined;
|
|
39
39
|
query?: string | undefined;
|
|
40
40
|
}>;
|
|
41
41
|
export type GetContextInput = z.infer<typeof getContextSchema>;
|
|
@@ -86,11 +86,11 @@ export declare const consolidateSchema: z.ZodObject<{
|
|
|
86
86
|
force: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
87
87
|
dryRun: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
88
88
|
}, "strip", z.ZodTypeAny, {
|
|
89
|
-
dryRun: boolean;
|
|
90
89
|
force: boolean;
|
|
90
|
+
dryRun: boolean;
|
|
91
91
|
}, {
|
|
92
|
-
dryRun?: boolean | undefined;
|
|
93
92
|
force?: boolean | undefined;
|
|
93
|
+
dryRun?: boolean | undefined;
|
|
94
94
|
}>;
|
|
95
95
|
export declare function executeConsolidate(input: {
|
|
96
96
|
force?: boolean;
|
package/dist/tools/forget.d.ts
CHANGED
|
@@ -17,38 +17,38 @@ export declare const forgetSchema: z.ZodObject<{
|
|
|
17
17
|
type: z.ZodEnum<["user", "cli", "hook", "email", "web", "agent", "file", "api", "tool_response"]>;
|
|
18
18
|
identifier: z.ZodString;
|
|
19
19
|
}, "strip", z.ZodTypeAny, {
|
|
20
|
-
type: "user" | "cli" | "hook" | "
|
|
20
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
21
21
|
identifier: string;
|
|
22
22
|
}, {
|
|
23
|
-
type: "user" | "cli" | "hook" | "
|
|
23
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
24
24
|
identifier: string;
|
|
25
25
|
}>>;
|
|
26
26
|
}, "strip", z.ZodTypeAny, {
|
|
27
|
-
dryRun: boolean;
|
|
28
27
|
confirm: boolean;
|
|
28
|
+
dryRun: boolean;
|
|
29
29
|
source?: {
|
|
30
|
-
type: "user" | "cli" | "hook" | "
|
|
30
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
31
31
|
identifier: string;
|
|
32
32
|
} | undefined;
|
|
33
33
|
project?: string | undefined;
|
|
34
34
|
id?: number | undefined;
|
|
35
|
-
category?: "
|
|
35
|
+
category?: "context" | "pattern" | "architecture" | "preference" | "error" | "learning" | "todo" | "note" | "relationship" | "custom" | undefined;
|
|
36
36
|
query?: string | undefined;
|
|
37
37
|
olderThan?: number | undefined;
|
|
38
38
|
belowSalience?: number | undefined;
|
|
39
39
|
}, {
|
|
40
40
|
source?: {
|
|
41
|
-
type: "user" | "cli" | "hook" | "
|
|
41
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
42
42
|
identifier: string;
|
|
43
43
|
} | undefined;
|
|
44
44
|
project?: string | undefined;
|
|
45
45
|
id?: number | undefined;
|
|
46
|
-
category?: "
|
|
46
|
+
category?: "context" | "pattern" | "architecture" | "preference" | "error" | "learning" | "todo" | "note" | "relationship" | "custom" | undefined;
|
|
47
47
|
query?: string | undefined;
|
|
48
|
+
confirm?: boolean | undefined;
|
|
48
49
|
olderThan?: number | undefined;
|
|
49
50
|
belowSalience?: number | undefined;
|
|
50
51
|
dryRun?: boolean | undefined;
|
|
51
|
-
confirm?: boolean | undefined;
|
|
52
52
|
}>;
|
|
53
53
|
export type ForgetInput = z.infer<typeof forgetSchema>;
|
|
54
54
|
/**
|
|
@@ -57,6 +57,7 @@ export type ForgetInput = z.infer<typeof forgetSchema>;
|
|
|
57
57
|
export declare function executeForget(input: ForgetInput): Promise<{
|
|
58
58
|
success: boolean;
|
|
59
59
|
deleted?: number;
|
|
60
|
+
denied?: number;
|
|
60
61
|
wouldDelete?: number;
|
|
61
62
|
memories?: {
|
|
62
63
|
id: number;
|
package/dist/tools/forget.js
CHANGED
|
@@ -131,14 +131,27 @@ export async function executeForget(input) {
|
|
|
131
131
|
error: error.toUserMessage(),
|
|
132
132
|
};
|
|
133
133
|
}
|
|
134
|
-
// Execute deletion within a transaction for atomicity
|
|
134
|
+
// Execute deletion within a transaction for atomicity. Route every
|
|
135
|
+
// affected id through deleteMemory(id, source) — NOT a raw bulk DELETE —
|
|
136
|
+
// so each row gets the same enforcement as the single-ID path: delete-ACL
|
|
137
|
+
// check (+ access-denial audit on refusal), graph cleanup, cloud-sync
|
|
138
|
+
// delete, and the dashboard `memory_deleted` event. A low-trust / non-owner
|
|
139
|
+
// caller therefore can't mass-delete protected memories. better-sqlite3 is
|
|
140
|
+
// synchronous, so the per-row loop stays inside one transaction atomically.
|
|
141
|
+
const deletedMemories = [];
|
|
135
142
|
withTransaction(() => {
|
|
136
|
-
|
|
143
|
+
for (const memory of affected) {
|
|
144
|
+
if (deleteMemory(memory.id, source)) {
|
|
145
|
+
deletedMemories.push(memory);
|
|
146
|
+
}
|
|
147
|
+
}
|
|
137
148
|
});
|
|
149
|
+
const denied = affected.length - deletedMemories.length;
|
|
138
150
|
return {
|
|
139
151
|
success: true,
|
|
140
|
-
deleted:
|
|
141
|
-
|
|
152
|
+
deleted: deletedMemories.length,
|
|
153
|
+
...(denied > 0 ? { denied } : {}),
|
|
154
|
+
memories: deletedMemories,
|
|
142
155
|
};
|
|
143
156
|
}
|
|
144
157
|
catch (error) {
|
package/dist/tools/recall.d.ts
CHANGED
|
@@ -20,10 +20,10 @@ export declare const recallSchema: z.ZodObject<{
|
|
|
20
20
|
type: z.ZodEnum<["user", "cli", "hook", "email", "web", "agent", "file", "api", "tool_response"]>;
|
|
21
21
|
identifier: z.ZodString;
|
|
22
22
|
}, "strip", z.ZodTypeAny, {
|
|
23
|
-
type: "user" | "cli" | "hook" | "
|
|
23
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
24
24
|
identifier: string;
|
|
25
25
|
}, {
|
|
26
|
-
type: "user" | "cli" | "hook" | "
|
|
26
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
27
27
|
identifier: string;
|
|
28
28
|
}>>;
|
|
29
29
|
}, "strip", z.ZodTypeAny, {
|
|
@@ -31,26 +31,26 @@ export declare const recallSchema: z.ZodObject<{
|
|
|
31
31
|
limit: number;
|
|
32
32
|
includeDecayed: boolean;
|
|
33
33
|
includeGlobal: boolean;
|
|
34
|
+
type?: "short_term" | "long_term" | "episodic" | undefined;
|
|
34
35
|
source?: {
|
|
35
|
-
type: "user" | "cli" | "hook" | "
|
|
36
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
36
37
|
identifier: string;
|
|
37
38
|
} | undefined;
|
|
38
39
|
project?: string | undefined;
|
|
39
|
-
|
|
40
|
-
category?: "architecture" | "pattern" | "preference" | "error" | "context" | "learning" | "todo" | "note" | "relationship" | "custom" | undefined;
|
|
40
|
+
category?: "context" | "pattern" | "architecture" | "preference" | "error" | "learning" | "todo" | "note" | "relationship" | "custom" | undefined;
|
|
41
41
|
tags?: string[] | undefined;
|
|
42
42
|
query?: string | undefined;
|
|
43
43
|
}, {
|
|
44
|
+
type?: "short_term" | "long_term" | "episodic" | undefined;
|
|
44
45
|
source?: {
|
|
45
|
-
type: "user" | "cli" | "hook" | "
|
|
46
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
46
47
|
identifier: string;
|
|
47
48
|
} | undefined;
|
|
48
49
|
project?: string | undefined;
|
|
49
50
|
mode?: "search" | "important" | "recent" | undefined;
|
|
50
|
-
type?: "short_term" | "long_term" | "episodic" | undefined;
|
|
51
|
-
category?: "architecture" | "pattern" | "preference" | "error" | "context" | "learning" | "todo" | "note" | "relationship" | "custom" | undefined;
|
|
52
|
-
tags?: string[] | undefined;
|
|
53
51
|
limit?: number | undefined;
|
|
52
|
+
category?: "context" | "pattern" | "architecture" | "preference" | "error" | "learning" | "todo" | "note" | "relationship" | "custom" | undefined;
|
|
53
|
+
tags?: string[] | undefined;
|
|
54
54
|
query?: string | undefined;
|
|
55
55
|
includeDecayed?: boolean | undefined;
|
|
56
56
|
includeGlobal?: boolean | undefined;
|
|
@@ -87,22 +87,22 @@ export declare const getMemorySchema: z.ZodObject<{
|
|
|
87
87
|
type: z.ZodEnum<["user", "cli", "hook", "email", "web", "agent", "file", "api", "tool_response"]>;
|
|
88
88
|
identifier: z.ZodString;
|
|
89
89
|
}, "strip", z.ZodTypeAny, {
|
|
90
|
-
type: "user" | "cli" | "hook" | "
|
|
90
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
91
91
|
identifier: string;
|
|
92
92
|
}, {
|
|
93
|
-
type: "user" | "cli" | "hook" | "
|
|
93
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
94
94
|
identifier: string;
|
|
95
95
|
}>>;
|
|
96
96
|
}, "strip", z.ZodTypeAny, {
|
|
97
97
|
id: number;
|
|
98
98
|
source?: {
|
|
99
|
-
type: "user" | "cli" | "hook" | "
|
|
99
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
100
100
|
identifier: string;
|
|
101
101
|
} | undefined;
|
|
102
102
|
}, {
|
|
103
103
|
id: number;
|
|
104
104
|
source?: {
|
|
105
|
-
type: "user" | "cli" | "hook" | "
|
|
105
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
106
106
|
identifier: string;
|
|
107
107
|
} | undefined;
|
|
108
108
|
}>;
|
package/dist/tools/remember.d.ts
CHANGED
|
@@ -21,10 +21,10 @@ export declare const rememberSchema: z.ZodObject<{
|
|
|
21
21
|
type: z.ZodEnum<["user", "cli", "hook", "email", "web", "agent", "file", "api", "tool_response"]>;
|
|
22
22
|
identifier: z.ZodString;
|
|
23
23
|
}, "strip", z.ZodTypeAny, {
|
|
24
|
-
type: "user" | "cli" | "hook" | "
|
|
24
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
25
25
|
identifier: string;
|
|
26
26
|
}, {
|
|
27
|
-
type: "user" | "cli" | "hook" | "
|
|
27
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
28
28
|
identifier: string;
|
|
29
29
|
}>>;
|
|
30
30
|
sourceType: z.ZodOptional<z.ZodEnum<["user", "cli", "hook", "email", "web", "agent", "file", "api", "tool_response"]>>;
|
|
@@ -35,43 +35,43 @@ export declare const rememberSchema: z.ZodObject<{
|
|
|
35
35
|
}, "strip", z.ZodTypeAny, {
|
|
36
36
|
title: string;
|
|
37
37
|
content: string;
|
|
38
|
+
type?: "short_term" | "long_term" | "episodic" | undefined;
|
|
38
39
|
scope?: "project" | "global" | undefined;
|
|
39
40
|
transferable?: boolean | undefined;
|
|
40
41
|
source?: {
|
|
41
|
-
type: "user" | "cli" | "hook" | "
|
|
42
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
42
43
|
identifier: string;
|
|
43
44
|
} | undefined;
|
|
44
45
|
project?: string | undefined;
|
|
45
|
-
type?: "short_term" | "long_term" | "episodic" | undefined;
|
|
46
|
-
category?: "architecture" | "pattern" | "preference" | "error" | "context" | "learning" | "todo" | "note" | "relationship" | "custom" | undefined;
|
|
47
|
-
tags?: string[] | undefined;
|
|
48
46
|
sourceIdentifier?: string | undefined;
|
|
47
|
+
category?: "context" | "pattern" | "architecture" | "preference" | "error" | "learning" | "todo" | "note" | "relationship" | "custom" | undefined;
|
|
48
|
+
tags?: string[] | undefined;
|
|
49
|
+
sourceType?: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response" | undefined;
|
|
49
50
|
sessionId?: string | undefined;
|
|
50
|
-
|
|
51
|
-
memoryPurpose?: "project" | "user" | "feedback" | "reference" | undefined;
|
|
51
|
+
memoryPurpose?: "user" | "project" | "feedback" | "reference" | undefined;
|
|
52
52
|
memoryScope?: "private" | "team" | undefined;
|
|
53
|
-
importance?: "
|
|
53
|
+
importance?: "low" | "high" | "critical" | "normal" | undefined;
|
|
54
54
|
agentId?: string | undefined;
|
|
55
55
|
workspaceDir?: string | undefined;
|
|
56
56
|
}, {
|
|
57
57
|
title: string;
|
|
58
58
|
content: string;
|
|
59
|
+
type?: "short_term" | "long_term" | "episodic" | undefined;
|
|
59
60
|
scope?: "project" | "global" | undefined;
|
|
60
61
|
transferable?: boolean | undefined;
|
|
61
62
|
source?: {
|
|
62
|
-
type: "user" | "cli" | "hook" | "
|
|
63
|
+
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
63
64
|
identifier: string;
|
|
64
65
|
} | undefined;
|
|
65
66
|
project?: string | undefined;
|
|
66
|
-
type?: "short_term" | "long_term" | "episodic" | undefined;
|
|
67
|
-
category?: "architecture" | "pattern" | "preference" | "error" | "context" | "learning" | "todo" | "note" | "relationship" | "custom" | undefined;
|
|
68
|
-
tags?: string[] | undefined;
|
|
69
67
|
sourceIdentifier?: string | undefined;
|
|
68
|
+
category?: "context" | "pattern" | "architecture" | "preference" | "error" | "learning" | "todo" | "note" | "relationship" | "custom" | undefined;
|
|
69
|
+
tags?: string[] | undefined;
|
|
70
|
+
sourceType?: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response" | undefined;
|
|
70
71
|
sessionId?: string | undefined;
|
|
71
|
-
|
|
72
|
-
memoryPurpose?: "project" | "user" | "feedback" | "reference" | undefined;
|
|
72
|
+
memoryPurpose?: "user" | "project" | "feedback" | "reference" | undefined;
|
|
73
73
|
memoryScope?: "private" | "team" | undefined;
|
|
74
|
-
importance?: "
|
|
74
|
+
importance?: "low" | "high" | "critical" | "normal" | undefined;
|
|
75
75
|
agentId?: string | undefined;
|
|
76
76
|
workspaceDir?: string | undefined;
|
|
77
77
|
}>;
|
package/dist/tools/remember.js
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Store memories with automatic salience detection and categorization.
|
|
5
5
|
*/
|
|
6
6
|
import { z } from 'zod';
|
|
7
|
-
import { addMemory, searchMemories, detectRelationships, createMemoryLink, getLastTruncationInfo } from '../memory/store.js';
|
|
7
|
+
import { addMemory, updateMemory, searchMemories, detectRelationships, createMemoryLink, getLastTruncationInfo } from '../memory/store.js';
|
|
8
8
|
import { calculateSalience, analyzeSalienceFactors, explainSalience } from '../memory/salience.js';
|
|
9
9
|
import { formatErrorForMcp } from '../errors.js';
|
|
10
10
|
import { resolveProject } from '../context/project-context.js';
|
|
@@ -92,18 +92,29 @@ export async function executeRemember(input) {
|
|
|
92
92
|
project: resolvedProject ?? undefined,
|
|
93
93
|
limit: 3,
|
|
94
94
|
});
|
|
95
|
-
// If very similar memory exists,
|
|
95
|
+
// If a very similar memory exists, genuinely UPDATE it with the new
|
|
96
|
+
// content rather than silently discarding the new write. The previous
|
|
97
|
+
// behaviour reported "Updated existing similar memory" but never persisted
|
|
98
|
+
// anything — so a richer follow-up was lost while the report implied a
|
|
99
|
+
// successful update (Phase 17 A4).
|
|
96
100
|
if (existing.length > 0 && existing[0].relevanceScore > 0.9) {
|
|
97
101
|
const existingMemory = existing[0].memory;
|
|
102
|
+
const contentChanged = existingMemory.content !== content;
|
|
103
|
+
const updated = contentChanged
|
|
104
|
+
? updateMemory(existingMemory.id, { content, title })
|
|
105
|
+
: existingMemory;
|
|
106
|
+
const target = updated ?? existingMemory;
|
|
98
107
|
return {
|
|
99
108
|
success: true,
|
|
100
109
|
memory: {
|
|
101
|
-
id:
|
|
102
|
-
title:
|
|
103
|
-
salience:
|
|
104
|
-
type:
|
|
105
|
-
category:
|
|
106
|
-
reason:
|
|
110
|
+
id: target.id,
|
|
111
|
+
title: target.title,
|
|
112
|
+
salience: target.salience,
|
|
113
|
+
type: target.type,
|
|
114
|
+
category: target.category,
|
|
115
|
+
reason: contentChanged
|
|
116
|
+
? 'Updated existing similar memory with new content'
|
|
117
|
+
: 'Existing similar memory already up to date',
|
|
107
118
|
},
|
|
108
119
|
};
|
|
109
120
|
}
|
|
@@ -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, MCP_LIGHT_TICK_INTERVAL_MS, } from './types.js';
|
|
12
|
+
import { DEFAULT_WORKER_CONFIG, MCP_LIGHT_TICK_INTERVAL_MS, MCP_RETRY_QUEUE_BUDGET, } 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';
|
|
@@ -21,22 +21,51 @@ import { emitWorkerLightTick, emitWorkerMediumTick, emitPredictiveConsolidation,
|
|
|
21
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
|
+
import { purgeOldAuditEntries, purgeAuditUnderSizePressure } from '../defence/audit/retention.js';
|
|
24
25
|
import { isFeatureEnabled } from '../license/gate.js';
|
|
25
|
-
import { existsSync, mkdirSync, writeFileSync } from 'fs';
|
|
26
|
+
import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'fs';
|
|
26
27
|
import { join } from 'path';
|
|
27
28
|
import { homedir } from 'os';
|
|
28
29
|
const WORKER_STATE_DIR = join(homedir(), '.shieldcortex', 'state');
|
|
29
30
|
const WORKER_STATE_FILE = join(WORKER_STATE_DIR, 'worker.json');
|
|
30
|
-
|
|
31
|
+
// Audit retention runs in the light tick (which fires every 5–15 min) but is
|
|
32
|
+
// throttled to ~once per day — a daily purge is plenty to keep defence_audit
|
|
33
|
+
// bounded, and running it every tick would be wasteful.
|
|
34
|
+
const AUDIT_PURGE_INTERVAL_MS = 24 * 60 * 60 * 1000;
|
|
35
|
+
function persistWorkerState(profile, lastLightTick, lastAuditPurge) {
|
|
31
36
|
try {
|
|
32
37
|
if (!existsSync(WORKER_STATE_DIR))
|
|
33
38
|
mkdirSync(WORKER_STATE_DIR, { recursive: true });
|
|
34
|
-
writeFileSync(WORKER_STATE_FILE, JSON.stringify({
|
|
39
|
+
writeFileSync(WORKER_STATE_FILE, JSON.stringify({
|
|
40
|
+
pid: process.pid,
|
|
41
|
+
profile,
|
|
42
|
+
lastLightTick: lastLightTick.toISOString(),
|
|
43
|
+
lastAuditPurge: lastAuditPurge ? lastAuditPurge.toISOString() : null,
|
|
44
|
+
}, null, 2), 'utf-8');
|
|
35
45
|
}
|
|
36
46
|
catch {
|
|
37
47
|
// Best-effort: doctor will warn if the file is stale or missing
|
|
38
48
|
}
|
|
39
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Read the persisted lastAuditPurge timestamp so the 24h throttle survives
|
|
52
|
+
* process restarts — MCP servers restart frequently (one per Claude Code
|
|
53
|
+
* window), and without this every restart would trigger a fresh purge.
|
|
54
|
+
*/
|
|
55
|
+
function readPersistedAuditPurge() {
|
|
56
|
+
try {
|
|
57
|
+
const raw = JSON.parse(readFileSync(WORKER_STATE_FILE, 'utf-8'));
|
|
58
|
+
if (raw.lastAuditPurge) {
|
|
59
|
+
const d = new Date(raw.lastAuditPurge);
|
|
60
|
+
if (!Number.isNaN(d.getTime()))
|
|
61
|
+
return d;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// No prior state — treat as never purged.
|
|
66
|
+
}
|
|
67
|
+
return null;
|
|
68
|
+
}
|
|
40
69
|
/**
|
|
41
70
|
* Brain Worker Class
|
|
42
71
|
*
|
|
@@ -59,6 +88,9 @@ export class BrainWorker {
|
|
|
59
88
|
lastLightTick = null;
|
|
60
89
|
lastMediumTick = null;
|
|
61
90
|
lastConsolidation = null;
|
|
91
|
+
// Seeded from persisted state so the 24h audit-purge throttle survives
|
|
92
|
+
// frequent MCP-server restarts.
|
|
93
|
+
lastAuditPurge = readPersistedAuditPurge();
|
|
62
94
|
/**
|
|
63
95
|
* Create a new BrainWorker
|
|
64
96
|
*
|
|
@@ -181,20 +213,51 @@ export class BrainWorker {
|
|
|
181
213
|
result: result.predictiveConsolidation,
|
|
182
214
|
});
|
|
183
215
|
}
|
|
184
|
-
// 3
|
|
185
|
-
//
|
|
186
|
-
//
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
216
|
+
// 3. Audit retention — runs on BOTH profiles (MCP-only installs scan
|
|
217
|
+
// tool responses too, so their defence_audit also grows unbounded; the
|
|
218
|
+
// sync-queue purge being worker-only left an analogous gap we deliberately
|
|
219
|
+
// don't repeat here). The pressure valve is a cheap size check, so it runs
|
|
220
|
+
// every tick; the age-based purge is throttled to ~once per 24h.
|
|
221
|
+
try {
|
|
222
|
+
const pressurePurged = purgeAuditUnderSizePressure();
|
|
223
|
+
if (pressurePurged > 0) {
|
|
224
|
+
console.log(`[BrainWorker] Audit size-pressure valve purged ${pressurePurged} rows`);
|
|
225
|
+
}
|
|
226
|
+
const now = result.timestamp.getTime();
|
|
227
|
+
const dueForPurge = this.lastAuditPurge === null ||
|
|
228
|
+
now - this.lastAuditPurge.getTime() >= AUDIT_PURGE_INTERVAL_MS;
|
|
229
|
+
if (dueForPurge) {
|
|
230
|
+
const purged = purgeOldAuditEntries();
|
|
231
|
+
this.lastAuditPurge = result.timestamp;
|
|
232
|
+
if (purged > 0) {
|
|
233
|
+
console.log(`[BrainWorker] Audit retention purged ${purged} entries older than 90d`);
|
|
193
234
|
}
|
|
194
235
|
}
|
|
195
|
-
|
|
196
|
-
|
|
236
|
+
}
|
|
237
|
+
catch (auditErr) {
|
|
238
|
+
console.error('[BrainWorker] Audit retention failed:', auditErr);
|
|
239
|
+
}
|
|
240
|
+
// 4. Sync retry queue — drains on BOTH profiles. MCP-only installs have
|
|
241
|
+
// no full worker, so if this stayed full-only their queued audits/
|
|
242
|
+
// memories would age out unsent (the same gap we closed for audit
|
|
243
|
+
// retention above). The MCP path is BUDGETED (one process per Claude Code
|
|
244
|
+
// window) so it doesn't do unbounded network work each tick; full keeps
|
|
245
|
+
// its historical unbudgeted cadence. processRetryQueue itself no-ops
|
|
246
|
+
// cheaply when cloud is disabled (no API key), so this is safe to call
|
|
247
|
+
// unconditionally — no extra gate needed.
|
|
248
|
+
try {
|
|
249
|
+
const retryResult = await processRetryQueue(this.config.profile === 'mcp' ? { maxRows: MCP_RETRY_QUEUE_BUDGET } : {});
|
|
250
|
+
if (retryResult.processed > 0) {
|
|
251
|
+
console.log(`[BrainWorker] Sync retry queue: processed ${retryResult.processed} ` +
|
|
252
|
+
`(${retryResult.succeeded} ok, ${retryResult.failed} retry, ${retryResult.permanentlyFailed} failed)`);
|
|
197
253
|
}
|
|
254
|
+
}
|
|
255
|
+
catch (retryError) {
|
|
256
|
+
console.error('[BrainWorker] Sync retry queue failed:', retryError);
|
|
257
|
+
}
|
|
258
|
+
// 5-6: heartbeat + Iron Dome — full profile only. Skipped under MCP so we
|
|
259
|
+
// don't fan out N concurrent network calls from N open Claude Code windows.
|
|
260
|
+
if (this.config.profile === 'full') {
|
|
198
261
|
if (isFeatureEnabled('cloud_sync')) {
|
|
199
262
|
try {
|
|
200
263
|
sendHeartbeat();
|
|
@@ -216,7 +279,7 @@ export class BrainWorker {
|
|
|
216
279
|
this.lastLightTick = result.timestamp;
|
|
217
280
|
this.stats.lightTicks++;
|
|
218
281
|
// Persist worker freshness for `shieldcortex doctor` to detect stalls.
|
|
219
|
-
persistWorkerState(this.config.profile, result.timestamp);
|
|
282
|
+
persistWorkerState(this.config.profile, result.timestamp, this.lastAuditPurge);
|
|
220
283
|
// Emit light tick event
|
|
221
284
|
emitWorkerLightTick(result);
|
|
222
285
|
// Log summary
|
package/dist/worker/types.d.ts
CHANGED
|
@@ -51,6 +51,14 @@ export declare const DEFAULT_WORKER_CONFIG: WorkerConfig;
|
|
|
51
51
|
* background work in check across many windows.
|
|
52
52
|
*/
|
|
53
53
|
export declare const MCP_LIGHT_TICK_INTERVAL_MS: number;
|
|
54
|
+
/**
|
|
55
|
+
* Per-tick budget for the sync retry queue under the MCP profile. MCP-only
|
|
56
|
+
* installs have no full worker, so they MUST drain their own queue or queued
|
|
57
|
+
* audits/memories age out unsent — but one MCP process runs per Claude Code
|
|
58
|
+
* window, so we cap the network work each does per light tick. The full
|
|
59
|
+
* (dashboard) profile keeps its historical unbudgeted cadence.
|
|
60
|
+
*/
|
|
61
|
+
export declare const MCP_RETRY_QUEUE_BUDGET = 25;
|
|
54
62
|
/**
|
|
55
63
|
* Result of a light tick operation
|
|
56
64
|
*/
|
package/dist/worker/types.js
CHANGED
|
@@ -26,3 +26,11 @@ export const DEFAULT_WORKER_CONFIG = {
|
|
|
26
26
|
* background work in check across many windows.
|
|
27
27
|
*/
|
|
28
28
|
export const MCP_LIGHT_TICK_INTERVAL_MS = 15 * 60 * 1000;
|
|
29
|
+
/**
|
|
30
|
+
* Per-tick budget for the sync retry queue under the MCP profile. MCP-only
|
|
31
|
+
* installs have no full worker, so they MUST drain their own queue or queued
|
|
32
|
+
* audits/memories age out unsent — but one MCP process runs per Claude Code
|
|
33
|
+
* window, so we cap the network work each does per light tick. The full
|
|
34
|
+
* (dashboard) profile keeps its historical unbudgeted cadence.
|
|
35
|
+
*/
|
|
36
|
+
export const MCP_RETRY_QUEUE_BUDGET = 25;
|
|
@@ -5,6 +5,24 @@
|
|
|
5
5
|
* and aggregates findings into a single XRayResult.
|
|
6
6
|
*/
|
|
7
7
|
import type { XRayResult } from './types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Hidden directories worth scanning. These hold agent-instruction and CI
|
|
10
|
+
* surfaces (skills, slash commands, settings hooks, workflow YAML, editor
|
|
11
|
+
* tasks) — the primary prompt-injection / persistence vectors in an AI-agent
|
|
12
|
+
* codebase. By default `walkDir` skips ALL dot-directories; this allow-list
|
|
13
|
+
* carves out the ones X-Ray must inspect. `SKIP_DIRS` always wins, so `.git`
|
|
14
|
+
* et al. stay excluded even though they're hidden.
|
|
15
|
+
*
|
|
16
|
+
* Shared with watch mode (`watch.ts` imports this) so a scan and a watch agree
|
|
17
|
+
* on exactly which hidden dirs are in scope — one source of truth.
|
|
18
|
+
*/
|
|
19
|
+
export declare const ALLOW_HIDDEN_DIRS: Set<string>;
|
|
20
|
+
/**
|
|
21
|
+
* Whether to descend into a directory while walking. Recurse when it's not in
|
|
22
|
+
* the skip-list AND it's either not hidden or explicitly allow-listed. Exported
|
|
23
|
+
* so watch mode mirrors the identical rule.
|
|
24
|
+
*/
|
|
25
|
+
export declare function shouldWalkDir(name: string): boolean;
|
|
8
26
|
/**
|
|
9
27
|
* Scan an entire directory for X-Ray findings.
|
|
10
28
|
*
|
package/dist/xray/dir-scanner.js
CHANGED
|
@@ -15,6 +15,28 @@ const SKIP_DIRS = new Set([
|
|
|
15
15
|
'__pycache__', '.tox', '.venv', 'venv', '.cache', 'coverage',
|
|
16
16
|
'Caches', 'CacheStorage', 'IndexedDB', 'GPUCache',
|
|
17
17
|
]);
|
|
18
|
+
/**
|
|
19
|
+
* Hidden directories worth scanning. These hold agent-instruction and CI
|
|
20
|
+
* surfaces (skills, slash commands, settings hooks, workflow YAML, editor
|
|
21
|
+
* tasks) — the primary prompt-injection / persistence vectors in an AI-agent
|
|
22
|
+
* codebase. By default `walkDir` skips ALL dot-directories; this allow-list
|
|
23
|
+
* carves out the ones X-Ray must inspect. `SKIP_DIRS` always wins, so `.git`
|
|
24
|
+
* et al. stay excluded even though they're hidden.
|
|
25
|
+
*
|
|
26
|
+
* Shared with watch mode (`watch.ts` imports this) so a scan and a watch agree
|
|
27
|
+
* on exactly which hidden dirs are in scope — one source of truth.
|
|
28
|
+
*/
|
|
29
|
+
export const ALLOW_HIDDEN_DIRS = new Set([
|
|
30
|
+
'.github', '.claude', '.cursor', '.codex', '.vscode', '.agents', '.openclaw',
|
|
31
|
+
]);
|
|
32
|
+
/**
|
|
33
|
+
* Whether to descend into a directory while walking. Recurse when it's not in
|
|
34
|
+
* the skip-list AND it's either not hidden or explicitly allow-listed. Exported
|
|
35
|
+
* so watch mode mirrors the identical rule.
|
|
36
|
+
*/
|
|
37
|
+
export function shouldWalkDir(name) {
|
|
38
|
+
return !SKIP_DIRS.has(name) && (!name.startsWith('.') || ALLOW_HIDDEN_DIRS.has(name));
|
|
39
|
+
}
|
|
18
40
|
/** Absolute path prefixes to never scan — system/OS files that always produce false positives. */
|
|
19
41
|
const SKIP_PATH_PREFIXES = [
|
|
20
42
|
'/System/',
|
|
@@ -75,7 +97,7 @@ function walkDir(dirPath, files, depth = 0) {
|
|
|
75
97
|
break;
|
|
76
98
|
const fullPath = path.join(dirPath, entry.name);
|
|
77
99
|
if (entry.isDirectory()) {
|
|
78
|
-
if (
|
|
100
|
+
if (shouldWalkDir(entry.name)) {
|
|
79
101
|
walkDir(fullPath, files, depth + 1);
|
|
80
102
|
}
|
|
81
103
|
}
|