shieldcortex 4.39.0 → 4.41.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/(dashboard)/admin/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/cloud/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/capture/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/graph/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/page/react-loadable-manifest.json +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/recall/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/replay/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/review/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/timeline/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/overview/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/audit/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/intercepts/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/iron-dome/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/policies/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/quarantine/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/supply-chain/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/supply-chain/xray/page_client-reference-manifest.js +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/xray/page_client-reference-manifest.js +1 -1
- 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/page_client-reference-manifest.js +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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.rsc +3 -3
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory/__PAGE__.segment.rsc +2 -2
- 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 +3 -3
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/page_client-reference-manifest.js +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 +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_tree.segment.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.rsc +2 -2
- 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 +2 -2
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.html +1 -1
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.rsc +3 -3
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray/__PAGE__.segment.rsc +2 -2
- 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 +3 -3
- 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 +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_tree.segment.rsc +2 -2
- package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_c219bf07._.js +4 -4
- package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_src_components_xray_XRayOverview_tsx_ceba698e._.js +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/dashboard/.next/standalone/dashboard/.next/static/chunks/6dddc4bf46b08fb2.css +1 -0
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/90baaf667600b429.js +1 -0
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/{e8884e7f3b85fd0b.js → 9305fb02787779da.js} +1 -1
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/9b02aba35b7ce4b7.js +15 -0
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/e18095d552836b96.js +1 -0
- package/dist/api/events.js +2 -0
- package/dist/api/redact-response.d.ts +15 -0
- package/dist/api/redact-response.js +19 -0
- package/dist/api/routes/memories.js +86 -21
- package/dist/api/visualization-server.js +15 -4
- package/dist/cloud/cli.js +13 -1
- package/dist/cloud/config.d.ts +10 -0
- package/dist/cloud/config.js +15 -0
- package/dist/defence/audit/queries.d.ts +1 -1
- package/dist/defence/trust/access-control.d.ts +1 -4
- package/dist/defence/trust/access-control.js +32 -0
- package/dist/defence/trust/read-guard.d.ts +42 -0
- package/dist/defence/trust/read-guard.js +120 -0
- package/dist/defence/types.d.ts +1 -1
- package/dist/memory/store.d.ts +4 -2
- package/dist/memory/store.js +9 -7
- package/dist/server.js +9 -1
- package/dist/tools/forget.d.ts +3 -0
- package/dist/tools/forget.js +53 -1
- package/package.json +1 -1
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/1600063be806f47c.js +0 -1
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/61aaa0c660c32b96.js +0 -1
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/98ae91e0a6f5d317.css +0 -1
- package/dashboard/.next/standalone/dashboard/.next/static/chunks/cfbc41857d998b74.js +0 -15
- /package/dashboard/.next/standalone/dashboard/.next/static/{LfTY3B6uX3j7zNwqqgvPG → QyU8uJKG3JL56w9hEtgrx}/_buildManifest.js +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{LfTY3B6uX3j7zNwqqgvPG → QyU8uJKG3JL56w9hEtgrx}/_clientMiddlewareManifest.json +0 -0
- /package/dashboard/.next/standalone/dashboard/.next/static/{LfTY3B6uX3j7zNwqqgvPG → QyU8uJKG3JL56w9hEtgrx}/_ssgManifest.js +0 -0
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
* resolves a source via resolveToolSource before calling the read tools.
|
|
20
20
|
*/
|
|
21
21
|
import { checkAccess } from './access-control.js';
|
|
22
|
+
import { redactContent } from '../sensitivity/redaction.js';
|
|
22
23
|
/**
|
|
23
24
|
* Core read decision, shared by the camelCase (Memory) and snake_case (raw row)
|
|
24
25
|
* guards so the policy lives in exactly one place.
|
|
@@ -74,3 +75,122 @@ export function guardReadMemory(memory, source) {
|
|
|
74
75
|
return null;
|
|
75
76
|
return guardReadMemories([memory], source)[0] ?? null;
|
|
76
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Dashboard / HTTP visualization-API read guard.
|
|
80
|
+
*
|
|
81
|
+
* The dashboard is the OWNER's surface, but it renders in a BROWSER — so raw
|
|
82
|
+
* RESTRICTED (credential-class) content there is a leak vector (screenshots,
|
|
83
|
+
* screen-shares, the browser's disk cache). Policy (REDACT, don't drop):
|
|
84
|
+
*
|
|
85
|
+
* - RESTRICTED rows are KEPT (so the owner sees the memory exists and can
|
|
86
|
+
* review/delete it) but their `content` is replaced with a placeholder;
|
|
87
|
+
* - because sensitivity is classified on TITLE + CONTENT together, a secret can
|
|
88
|
+
* also live in the title or metadata — so credential SPANS in those fields are
|
|
89
|
+
* masked too (a benign label like "AWS deploy key" is left intact);
|
|
90
|
+
* - low-trust / trust-0 rows are NOT dropped: the dashboard is a management
|
|
91
|
+
* surface (its Review queue exists to triage exactly these), so the owner must
|
|
92
|
+
* see them. Only RESTRICTED *content* is withheld, never whole rows.
|
|
93
|
+
*
|
|
94
|
+
* RESTRICTED full content remains available via the CLI (`recall`/`get_memory`),
|
|
95
|
+
* which is not a browser-render surface. Dropping quarantined rows is the MCP
|
|
96
|
+
* read-boundary's job (a subagent caller), not the owner's dashboard.
|
|
97
|
+
*/
|
|
98
|
+
export const RESTRICTED_CONTENT_PLACEHOLDER = '🔒 [RESTRICTED content withheld — view via CLI]';
|
|
99
|
+
/** Mask credential spans in a string (no-op if it carries no secret); pass-through for non-strings. */
|
|
100
|
+
function scrubSecretSpans(value) {
|
|
101
|
+
return typeof value === 'string' ? redactContent(value) : value;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Redact a single RESTRICTED memory for display: withhold `content`, mask
|
|
105
|
+
* credential spans in `title` and string `metadata` values. Returns a fresh copy
|
|
106
|
+
* (never mutates the input — rows may be live cache objects). Non-RESTRICTED rows
|
|
107
|
+
* pass through unchanged.
|
|
108
|
+
*/
|
|
109
|
+
function redactRestrictedMemory(m) {
|
|
110
|
+
// Always mask credential spans in the title (benign titles are untouched —
|
|
111
|
+
// redactContent only rewrites known credential patterns). A secret can be
|
|
112
|
+
// classified RESTRICTED via the title alone, and titles are shown for
|
|
113
|
+
// manageability, so this closes the secret-in-title leak without hiding labels.
|
|
114
|
+
const title = redactContent(m.title);
|
|
115
|
+
if (m.sensitivityLevel !== 'RESTRICTED') {
|
|
116
|
+
return title === m.title ? m : { ...m, title };
|
|
117
|
+
}
|
|
118
|
+
const metadata = m.metadata && typeof m.metadata === 'object' && !Array.isArray(m.metadata)
|
|
119
|
+
? Object.fromEntries(Object.entries(m.metadata).map(([k, v]) => [k, scrubSecretSpans(v)]))
|
|
120
|
+
: m.metadata;
|
|
121
|
+
return {
|
|
122
|
+
...m,
|
|
123
|
+
content: RESTRICTED_CONTENT_PLACEHOLDER,
|
|
124
|
+
title,
|
|
125
|
+
metadata: metadata,
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
/** Redact RESTRICTED memories for display (content withheld; title/metadata secret-scrubbed). */
|
|
129
|
+
export function redactRestrictedForDisplay(memories) {
|
|
130
|
+
return memories.map(redactRestrictedMemory);
|
|
131
|
+
}
|
|
132
|
+
/** Apply the dashboard redaction to every memory list in a context summary (used before formatting). */
|
|
133
|
+
export function guardDashboardContextSummary(summary) {
|
|
134
|
+
return {
|
|
135
|
+
...summary,
|
|
136
|
+
recentMemories: redactRestrictedForDisplay(summary.recentMemories),
|
|
137
|
+
keyDecisions: redactRestrictedForDisplay(summary.keyDecisions),
|
|
138
|
+
activePatterns: redactRestrictedForDisplay(summary.activePatterns),
|
|
139
|
+
pendingItems: redactRestrictedForDisplay(summary.pendingItems),
|
|
140
|
+
};
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Returns true for a serialized-memory object — one carrying a sensitivity label
|
|
144
|
+
* and a content field, in either camelCase (Memory) or snake_case (raw DB row).
|
|
145
|
+
*/
|
|
146
|
+
function isRedactableMemoryObject(o) {
|
|
147
|
+
const level = (o.sensitivityLevel ?? o.sensitivity_level);
|
|
148
|
+
return level === 'RESTRICTED' && typeof o.content === 'string';
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* Deep-walk an arbitrary HTTP-response payload and redact every RESTRICTED memory
|
|
152
|
+
* object it contains (withhold `content`; mask credential spans in `title` and
|
|
153
|
+
* string `metadata`), returning a redacted COPY (the input is never mutated —
|
|
154
|
+
* payloads often reference the live row cache).
|
|
155
|
+
*
|
|
156
|
+
* This is the comprehensive backstop for the visualization API: memories surface
|
|
157
|
+
* at many different nesting depths (`{ memories: [...] }`, recall
|
|
158
|
+
* `results[].memory`, openclaw `sessions[].memories[]`, review-queue
|
|
159
|
+
* `sections.stale[]`, `contradictions[].memoryA`), so guarding each route by hand
|
|
160
|
+
* would inevitably miss one. A single response interceptor that walks the whole
|
|
161
|
+
* tree cannot. It does NOT reach content already baked into a pre-rendered string
|
|
162
|
+
* (e.g. `/api/context`'s `formatted`) or bare title fields stripped of their
|
|
163
|
+
* sensitivity label (the contradictions endpoints, the `memory_deleted` event) —
|
|
164
|
+
* those are scrubbed at their own surface.
|
|
165
|
+
*/
|
|
166
|
+
export function deepRedactRestrictedContent(value, seen = new WeakSet()) {
|
|
167
|
+
if (value === null || typeof value !== 'object')
|
|
168
|
+
return value;
|
|
169
|
+
if (seen.has(value))
|
|
170
|
+
return value; // cycle guard
|
|
171
|
+
seen.add(value);
|
|
172
|
+
if (Array.isArray(value)) {
|
|
173
|
+
return value.map((item) => deepRedactRestrictedContent(item, seen));
|
|
174
|
+
}
|
|
175
|
+
const obj = value;
|
|
176
|
+
const copy = {};
|
|
177
|
+
for (const key of Object.keys(obj)) {
|
|
178
|
+
copy[key] = deepRedactRestrictedContent(obj[key], seen);
|
|
179
|
+
// Mask credential spans in any title-bearing string field, wherever it sits —
|
|
180
|
+
// titles are emitted bare (no sensitivity label) on recall/graph/contradictions
|
|
181
|
+
// /memory_deleted surfaces, so this closes those leaks centrally. redactContent
|
|
182
|
+
// only rewrites known credential patterns, so benign titles pass through.
|
|
183
|
+
if (/title/i.test(key) && typeof copy[key] === 'string') {
|
|
184
|
+
copy[key] = redactContent(copy[key]);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
if (isRedactableMemoryObject(copy)) {
|
|
188
|
+
copy.content = RESTRICTED_CONTENT_PLACEHOLDER;
|
|
189
|
+
if (copy.metadata && typeof copy.metadata === 'object' && !Array.isArray(copy.metadata)) {
|
|
190
|
+
const md = copy.metadata;
|
|
191
|
+
for (const k of Object.keys(md))
|
|
192
|
+
md[k] = scrubSecretSpans(md[k]);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
return copy;
|
|
196
|
+
}
|
package/dist/defence/types.d.ts
CHANGED
|
@@ -130,7 +130,7 @@ export interface QuarantineEntry {
|
|
|
130
130
|
audit_id: number | null;
|
|
131
131
|
}
|
|
132
132
|
/** Operation that produced an audit row (provenance ledger discriminator). */
|
|
133
|
-
export type AuditOperation = 'write' | 'read' | 'delete' | 'update';
|
|
133
|
+
export type AuditOperation = 'write' | 'read' | 'delete' | 'update' | 'revoke';
|
|
134
134
|
export interface AuditEntry {
|
|
135
135
|
id: number;
|
|
136
136
|
memory_id: number | null;
|
package/dist/memory/store.d.ts
CHANGED
|
@@ -34,7 +34,7 @@ export declare function logAllowedRead(source: DefenceSource, tool: string, memo
|
|
|
34
34
|
* audit.memory_id FK is ON DELETE SET NULL, so a live reference can't survive.
|
|
35
35
|
* The deleted id is preserved in `reason` + `blocked_patterns` for forensics.
|
|
36
36
|
*/
|
|
37
|
-
export declare function logAllowedDelete(memoryId: number, source: DefenceSource, project?: string | null): void;
|
|
37
|
+
export declare function logAllowedDelete(memoryId: number, source: DefenceSource, project?: string | null, operation?: AuditOperation): void;
|
|
38
38
|
/**
|
|
39
39
|
* Error thrown when memory creation is paused
|
|
40
40
|
*/
|
|
@@ -65,7 +65,9 @@ export declare function mergeMemories(keptId: number, removedId: number, options
|
|
|
65
65
|
/**
|
|
66
66
|
* Delete a memory
|
|
67
67
|
*/
|
|
68
|
-
export declare function deleteMemory(id: number, source?: DefenceSource
|
|
68
|
+
export declare function deleteMemory(id: number, source?: DefenceSource, opts?: {
|
|
69
|
+
mode?: 'delete' | 'revoke';
|
|
70
|
+
}): boolean;
|
|
69
71
|
/**
|
|
70
72
|
* Get all memories for a project
|
|
71
73
|
*/
|
package/dist/memory/store.js
CHANGED
|
@@ -283,7 +283,7 @@ export function logAllowedRead(source, tool, memoryIds, project) {
|
|
|
283
283
|
* audit.memory_id FK is ON DELETE SET NULL, so a live reference can't survive.
|
|
284
284
|
* The deleted id is preserved in `reason` + `blocked_patterns` for forensics.
|
|
285
285
|
*/
|
|
286
|
-
export function logAllowedDelete(memoryId, source, project) {
|
|
286
|
+
export function logAllowedDelete(memoryId, source, project, operation = 'delete') {
|
|
287
287
|
logAudit({
|
|
288
288
|
memory_id: null,
|
|
289
289
|
project: project ?? null,
|
|
@@ -293,7 +293,7 @@ export function logAllowedDelete(memoryId, source, project) {
|
|
|
293
293
|
trust_score: scoreSource(source).score,
|
|
294
294
|
sensitivity_level: 'INTERNAL',
|
|
295
295
|
firewall_result: 'ALLOW',
|
|
296
|
-
operation
|
|
296
|
+
operation,
|
|
297
297
|
anomaly_score: 0,
|
|
298
298
|
threat_indicators: '[]',
|
|
299
299
|
blocked_patterns: JSON.stringify([memoryId]),
|
|
@@ -936,15 +936,17 @@ export function mergeMemories(keptId, removedId, options, source = { type: 'cli'
|
|
|
936
936
|
/**
|
|
937
937
|
* Delete a memory
|
|
938
938
|
*/
|
|
939
|
-
export function deleteMemory(id, source) {
|
|
939
|
+
export function deleteMemory(id, source, opts) {
|
|
940
940
|
const db = getDatabase();
|
|
941
|
-
|
|
941
|
+
const aclOp = opts?.mode ?? 'delete';
|
|
942
|
+
// ACCESS CONTROL: Check delete permission. mode 'revoke' uses the
|
|
943
|
+
// trust-hierarchy rule (own OR outrank); 'delete' (default) stays own-only.
|
|
942
944
|
if (source) {
|
|
943
945
|
const row = db.prepare('SELECT id, source, sensitivity_level FROM memories WHERE id = ?').get(id);
|
|
944
946
|
if (row) {
|
|
945
|
-
const policy = checkAccess({ id: row.id, source: row.source, sensitivity_level: row.sensitivity_level }, source,
|
|
947
|
+
const policy = checkAccess({ id: row.id, source: row.source, sensitivity_level: row.sensitivity_level }, source, aclOp);
|
|
946
948
|
if (!policy.canDelete) {
|
|
947
|
-
logAccessDenial(id, source, policy.reason,
|
|
949
|
+
logAccessDenial(id, source, policy.reason, aclOp);
|
|
948
950
|
return false;
|
|
949
951
|
}
|
|
950
952
|
}
|
|
@@ -966,7 +968,7 @@ export function deleteMemory(id, source) {
|
|
|
966
968
|
// caller is attributed. Internal source-less deletes (merge/consolidation)
|
|
967
969
|
// are machinery, not user actions, so they're not audited here.
|
|
968
970
|
if (source) {
|
|
969
|
-
logAllowedDelete(id, source, memory.project ?? null);
|
|
971
|
+
logAllowedDelete(id, source, memory.project ?? null, aclOp);
|
|
970
972
|
}
|
|
971
973
|
if (isFeatureEnabled('cloud_sync')) {
|
|
972
974
|
syncMemoryDeleteToCloud(memory);
|
package/dist/server.js
CHANGED
|
@@ -23,6 +23,7 @@ import { checkDatabaseSize } from './database/init.js';
|
|
|
23
23
|
import { queryAuditLogs, getAuditStats, getLifetimeStats } from './defence/audit/index.js';
|
|
24
24
|
import { scanExistingMemories } from './defence/scanner/index.js';
|
|
25
25
|
import { resolveToolSource as resolveToolSourceImpl } from './defence/trust/resolve-tool-source.js';
|
|
26
|
+
import { inferSourceFromEnvironment } from './defence/trust/env-detector.js';
|
|
26
27
|
import { scanToolResponse, shouldScanToolResponse } from './defence/tool-response-scanner.js';
|
|
27
28
|
import { UNTRUSTED_TOOL_TAG } from './defence/tool-response-enforce.js';
|
|
28
29
|
import { guardReadBySensitivity, guardContextSummary } from './defence/trust/read-guard.js';
|
|
@@ -287,8 +288,15 @@ Modes: search (query-based), recent (by time), important (by salience)`, {
|
|
|
287
288
|
confirm: z.boolean().optional().default(false)
|
|
288
289
|
.describe('Confirm bulk delete'),
|
|
289
290
|
source: sourceParam,
|
|
291
|
+
fromSource: z.string().optional()
|
|
292
|
+
.describe('Revoke-by-source: delete all memories written by this source ("type:identifier", or "type:*" for a whole type). Authorised by the trust-hierarchy revoke ACL (own the source or outrank it). Use project:"*" to revoke across all projects.'),
|
|
290
293
|
}, { title: 'Delete Memories', readOnlyHint: false, destructiveHint: true, idempotentHint: false }, withKillSwitchGuard('memory_write', async (args) => {
|
|
291
|
-
|
|
294
|
+
// Delete is destructive, and revoke-by-source grants cross-identity power,
|
|
295
|
+
// so the caller identity MUST be the unspoofable runtime identity — derive
|
|
296
|
+
// it from the environment, NOT the MCP-declared `source` param. Honouring a
|
|
297
|
+
// declared identity would let a caller claim ownership of any peer source's
|
|
298
|
+
// memories (the clamp only caps trust SCORE, not identity).
|
|
299
|
+
const source = inferSourceFromEnvironment().source;
|
|
292
300
|
const result = await executeForget({ ...args, source });
|
|
293
301
|
return {
|
|
294
302
|
content: [{ type: 'text', text: formatForgetResult(result) }],
|
package/dist/tools/forget.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export declare const forgetSchema: z.ZodObject<{
|
|
|
23
23
|
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
24
24
|
identifier: string;
|
|
25
25
|
}>>;
|
|
26
|
+
fromSource: z.ZodOptional<z.ZodString>;
|
|
26
27
|
}, "strip", z.ZodTypeAny, {
|
|
27
28
|
confirm: boolean;
|
|
28
29
|
dryRun: boolean;
|
|
@@ -36,6 +37,7 @@ export declare const forgetSchema: z.ZodObject<{
|
|
|
36
37
|
query?: string | undefined;
|
|
37
38
|
olderThan?: number | undefined;
|
|
38
39
|
belowSalience?: number | undefined;
|
|
40
|
+
fromSource?: string | undefined;
|
|
39
41
|
}, {
|
|
40
42
|
source?: {
|
|
41
43
|
type: "user" | "cli" | "hook" | "email" | "web" | "agent" | "file" | "api" | "tool_response";
|
|
@@ -49,6 +51,7 @@ export declare const forgetSchema: z.ZodObject<{
|
|
|
49
51
|
olderThan?: number | undefined;
|
|
50
52
|
belowSalience?: number | undefined;
|
|
51
53
|
dryRun?: boolean | undefined;
|
|
54
|
+
fromSource?: string | undefined;
|
|
52
55
|
}>;
|
|
53
56
|
export type ForgetInput = z.infer<typeof forgetSchema>;
|
|
54
57
|
/**
|
package/dist/tools/forget.js
CHANGED
|
@@ -8,6 +8,13 @@ import { deleteMemory, searchMemories, getMemoryById } from '../memory/store.js'
|
|
|
8
8
|
import { getDatabase, withTransaction } from '../database/init.js';
|
|
9
9
|
import { MemoryNotFoundError, BulkDeleteSafetyError, formatErrorForMcp, } from '../errors.js';
|
|
10
10
|
import { resolveProject } from '../context/project-context.js';
|
|
11
|
+
import { isRevokeBySourceEnabled } from '../cloud/config.js';
|
|
12
|
+
/**
|
|
13
|
+
* Upper bound on rows a single revoke-by-source call may delete. Caps the blast
|
|
14
|
+
* radius of the mass-delete primitive — a larger match must be narrowed (by
|
|
15
|
+
* project/category/etc.) or paged.
|
|
16
|
+
*/
|
|
17
|
+
const MAX_REVOKE_ROWS = 500;
|
|
11
18
|
// Input schema for the forget tool
|
|
12
19
|
export const forgetSchema = z.object({
|
|
13
20
|
id: z.number().optional().describe('Specific memory ID to delete'),
|
|
@@ -28,6 +35,8 @@ export const forgetSchema = z.object({
|
|
|
28
35
|
type: z.enum(['user', 'cli', 'hook', 'email', 'web', 'agent', 'file', 'api', 'tool_response']),
|
|
29
36
|
identifier: z.string(),
|
|
30
37
|
}).optional().describe('Caller identity for access control'),
|
|
38
|
+
fromSource: z.string().optional()
|
|
39
|
+
.describe('Revoke-by-source: delete all memories written by this source. Exact "type:identifier", or a "type:*" / "type:" prefix to revoke a whole source type. Authorised by the trust-hierarchy revoke ACL (you must own the source or outrank it). Distinct from `source` (the caller).'),
|
|
31
40
|
});
|
|
32
41
|
/**
|
|
33
42
|
* Execute the forget tool
|
|
@@ -35,6 +44,15 @@ export const forgetSchema = z.object({
|
|
|
35
44
|
export async function executeForget(input) {
|
|
36
45
|
try {
|
|
37
46
|
const db = getDatabase();
|
|
47
|
+
// Revoke-by-source gate: a destructive mass-delete primitive that a hijacked
|
|
48
|
+
// agent must not be able to invoke. OFF by default; only an out-of-band human
|
|
49
|
+
// action (`shieldcortex config --allow-revoke-by-source`) enables it.
|
|
50
|
+
if (input.fromSource !== undefined && !isRevokeBySourceEnabled()) {
|
|
51
|
+
return {
|
|
52
|
+
success: false,
|
|
53
|
+
error: 'revoke-by-source is disabled. Enable it deliberately with `shieldcortex config --allow-revoke-by-source` (an out-of-band action), then re-run.',
|
|
54
|
+
};
|
|
55
|
+
}
|
|
38
56
|
// Resolve project (auto-detect if not provided)
|
|
39
57
|
const resolvedProject = resolveProject(input.project);
|
|
40
58
|
const source = input.source;
|
|
@@ -101,6 +119,28 @@ export async function executeForget(input) {
|
|
|
101
119
|
conditions.push('salience < ?');
|
|
102
120
|
params.push(input.belowSalience);
|
|
103
121
|
}
|
|
122
|
+
// Revoke-by-source: target every memory written by a given source. Exact
|
|
123
|
+
// "type:identifier", or a "type:*" / "type:" prefix for a whole source type.
|
|
124
|
+
// Per-row authorisation is the trust-hierarchy revoke ACL (in deleteMemory
|
|
125
|
+
// via mode:'revoke') — this clause only SELECTS the candidates. Project scope
|
|
126
|
+
// still applies; pass project:"*" to revoke a source across all projects.
|
|
127
|
+
if (input.fromSource !== undefined) {
|
|
128
|
+
const fs = input.fromSource.trim();
|
|
129
|
+
if (!fs || fs === '*' || fs === ':' || fs === ':*') {
|
|
130
|
+
return {
|
|
131
|
+
success: false,
|
|
132
|
+
error: 'fromSource must name a source (e.g. "agent:agent-spawned" or "agent:*"), not a blanket wildcard.',
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (fs.endsWith(':*') || fs.endsWith(':')) {
|
|
136
|
+
conditions.push('source LIKE ?');
|
|
137
|
+
params.push(`${fs.replace(/:\*?$/, '')}:%`);
|
|
138
|
+
}
|
|
139
|
+
else {
|
|
140
|
+
conditions.push('source = ?');
|
|
141
|
+
params.push(fs);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
104
144
|
if (conditions.length === 0) {
|
|
105
145
|
return {
|
|
106
146
|
success: false,
|
|
@@ -113,6 +153,15 @@ export async function executeForget(input) {
|
|
|
113
153
|
if (affected.length === 0) {
|
|
114
154
|
return { success: true, deleted: 0, memories: [] };
|
|
115
155
|
}
|
|
156
|
+
// Blast-radius cap on revoke-by-source: refuse a single call that would
|
|
157
|
+
// delete more than MAX_REVOKE_ROWS — narrow it (by project/category/etc.).
|
|
158
|
+
if (input.fromSource !== undefined && affected.length > MAX_REVOKE_ROWS) {
|
|
159
|
+
return {
|
|
160
|
+
success: false,
|
|
161
|
+
wouldDelete: affected.length,
|
|
162
|
+
error: `revoke-by-source matched ${affected.length} memories (cap ${MAX_REVOKE_ROWS}). Narrow the scope (project/category/query) and re-run.`,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
116
165
|
// Dry run - just show what would be deleted
|
|
117
166
|
if (input.dryRun) {
|
|
118
167
|
return {
|
|
@@ -138,10 +187,13 @@ export async function executeForget(input) {
|
|
|
138
187
|
// delete, and the dashboard `memory_deleted` event. A low-trust / non-owner
|
|
139
188
|
// caller therefore can't mass-delete protected memories. better-sqlite3 is
|
|
140
189
|
// synchronous, so the per-row loop stays inside one transaction atomically.
|
|
190
|
+
// revoke-by-source uses the trust-hierarchy revoke ACL (own OR outrank);
|
|
191
|
+
// every other bulk forget stays own-only.
|
|
192
|
+
const deleteMode = input.fromSource !== undefined ? 'revoke' : 'delete';
|
|
141
193
|
const deletedMemories = [];
|
|
142
194
|
withTransaction(() => {
|
|
143
195
|
for (const memory of affected) {
|
|
144
|
-
if (deleteMemory(memory.id, source)) {
|
|
196
|
+
if (deleteMemory(memory.id, source, { mode: deleteMode })) {
|
|
145
197
|
deletedMemories.push(memory);
|
|
146
198
|
}
|
|
147
199
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "shieldcortex",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.41.0",
|
|
4
4
|
"description": "Trustworthy memory and security for AI agents. Recall debugging, review queue, OpenClaw session capture, and memory poisoning defence for Claude Code, Codex, OpenClaw, LangChain, and MCP agents.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,27918,e=>{"use strict";var t=e.i(27493),a=e.i(4),s=e.i(45434),r=e.i(36062),i=e.i(71259),n=e.i(24929);let c=(0,n.default)("file-search",[["path",{d:"M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z",key:"1oefj6"}],["path",{d:"M14 2v5a1 1 0 0 0 1 1h5",key:"wfsgrz"}],["circle",{cx:"11.5",cy:"14.5",r:"2.5",key:"1bq0ko"}],["path",{d:"M13.3 16.3 15 18",key:"2quom7"}]]),l=(0,n.default)("folder-search",[["path",{d:"M10.7 20H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h3.9a2 2 0 0 1 1.69.9l.81 1.2a2 2 0 0 0 1.67.9H20a2 2 0 0 1 2 2v4.1",key:"1bw5m7"}],["path",{d:"m21 21-1.9-1.9",key:"1g2n9r"}],["circle",{cx:"17",cy:"17",r:"3",key:"18b49y"}]]);var d=e.i(66949);let o=(0,n.default)("radar",[["path",{d:"M19.07 4.93A10 10 0 0 0 6.99 3.34",key:"z3du51"}],["path",{d:"M4 6h.01",key:"oypzma"}],["path",{d:"M2.29 9.62A10 10 0 1 0 21.31 8.35",key:"qzzz0"}],["path",{d:"M16.24 7.76A6 6 0 1 0 8.23 16.67",key:"1yjesh"}],["path",{d:"M12 18h.01",key:"mhygvu"}],["path",{d:"M17.99 11.66A6 6 0 0 1 15.77 16.67",key:"1u2y91"}],["circle",{cx:"12",cy:"12",r:"2",key:"1c9p78"}],["path",{d:"m13.41 10.59 5.66-5.66",key:"mhq4k0"}]]);var x=e.i(76344),m=e.i(48615),v=e.i(88969),u=e.i(35372),h=e.i(16467),p=e.i(95659),g=e.i(81523),y=e.i(40950),f=e.i(46194);function j({score:e,size:a=160,label:s}){let r=2*Math.PI*42,i=e/100*r,n=e<=50?"var(--sc-coral)":e<=75?"var(--sc-amber)":"var(--sc-cyan)",c=e<=50?"var(--sc-glow-coral)":e<=75?"rgba(245, 158, 11, 0.15)":"var(--sc-glow-cyan)";return(0,t.jsxs)("div",{className:"flex flex-col items-center gap-2",children:[(0,t.jsxs)("div",{className:"relative",style:{width:a,height:a},children:[(0,t.jsxs)("svg",{viewBox:"0 0 100 100",className:"h-full w-full -rotate-90",style:{filter:`drop-shadow(0 0 12px ${c})`},children:[(0,t.jsx)("circle",{cx:"50",cy:"50",r:42,fill:"none",stroke:"var(--sc-bg-elevated)",strokeWidth:"7"}),(0,t.jsx)("circle",{cx:"50",cy:"50",r:42,fill:"none",stroke:n,strokeWidth:"7",strokeDasharray:`${i} ${r}`,strokeLinecap:"round",className:"transition-all duration-1000 ease-out"})]}),(0,t.jsxs)("div",{className:"absolute inset-0 flex flex-col items-center justify-center",children:[(0,t.jsx)("span",{className:"text-3xl font-bold",style:{color:n},children:e}),(0,t.jsx)("span",{className:"text-[11px] text-[var(--sc-text-muted)]",children:"trust"})]})]}),s&&(0,t.jsx)("span",{className:"text-xs font-medium text-[var(--sc-text-secondary)]",children:s})]})}var b=e.i(16511);let N=(0,n.default)("eye-off",[["path",{d:"M10.733 5.076a10.744 10.744 0 0 1 11.205 6.575 1 1 0 0 1 0 .696 10.747 10.747 0 0 1-1.444 2.49",key:"ct8e1f"}],["path",{d:"M14.084 14.158a3 3 0 0 1-4.242-4.242",key:"151rxh"}],["path",{d:"M17.479 17.499a10.75 10.75 0 0 1-15.417-5.151 1 1 0 0 1 0-.696 10.75 10.75 0 0 1 4.446-5.143",key:"13bj9a"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]]);var k=e.i(27528),w=e.i(77744),S=e.i(22534),C=e.i(45688),B=e.i(71921),E=e.i(1235);let F=S.default.env.NEXT_PUBLIC_API_URL||"http://localhost:3001";function $(e){return(0,C.useQuery)({queryKey:["xray-findings",e],queryFn:async()=>{let t=new URLSearchParams;e?.status&&t.set("status",e.status),e?.severity&&t.set("severity",e.severity),e?.target&&t.set("target",e.target),e?.limit&&t.set("limit",String(e.limit));let a=t.toString()?`?${t}`:"",s=await (0,v.gatedFetch)(`${F}/api/xray/findings${a}`);if(!s.ok)throw Error(await (0,v.readApiError)(s,"Failed to fetch findings"));return s.json()},refetchInterval:15e3})}function z(){let e=(0,E.useQueryClient)();return(0,B.useMutation)({mutationFn:async({id:e,status:t,note:a})=>{let s=await (0,v.gatedFetch)(`${F}/api/xray/findings/${e}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify({status:t,note:a})});if(!s.ok)throw Error(await (0,v.readApiError)(s,"Failed to update finding"));return s.json()},onSuccess:()=>{e.invalidateQueries({queryKey:["xray-findings"]}),e.invalidateQueries({queryKey:["xray-findings-stats"]})}})}function A(){let e=(0,E.useQueryClient)();return(0,B.useMutation)({mutationFn:async({id:e,note:t})=>{let a=await (0,v.gatedFetch)(`${F}/api/xray/findings/${e}/quarantine`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({note:t})});if(!a.ok)throw Error(await (0,v.readApiError)(a,"Failed to quarantine file"));return a.json()},onSuccess:()=>{e.invalidateQueries({queryKey:["xray-findings"]}),e.invalidateQueries({queryKey:["xray-findings-stats"]})}})}function R({findingId:e,status:s,hasFile:r,compact:n=!1}){let c,[l,d]=(0,a.useState)(!1),[o,x]=(0,a.useState)(""),[u,h]=(0,a.useState)(!1),p=z(),y=A(),f=(c=(0,E.useQueryClient)(),(0,B.useMutation)({mutationFn:async e=>{let t=await (0,v.gatedFetch)(`${F}/api/xray/findings/${e}`,{method:"DELETE"});if(!t.ok)throw Error(await (0,v.readApiError)(t,"Failed to delete finding"));return t.json()},onSuccess:()=>{c.invalidateQueries({queryKey:["xray-findings"]}),c.invalidateQueries({queryKey:["xray-findings-stats"]})}})),j=t=>{switch(t){case"reviewed":p.mutate({id:e,status:"reviewed"},{onSuccess:()=>m.toast.success("Marked as reviewed"),onError:e=>m.toast.error(`Failed to update: ${e.message}`)});break;case"ignored":p.mutate({id:e,status:"ignored",note:o},{onSuccess:()=>{m.toast.info("Finding ignored — removed from active list"),d(!1),x(""),h(!0)},onError:e=>m.toast.error(`Failed to ignore: ${e.message}`)});break;case"resolved":p.mutate({id:e,status:"resolved",note:o},{onSuccess:()=>{m.toast.success("Finding resolved — removed from active list"),d(!1),x(""),h(!0)},onError:e=>m.toast.error(`Failed to resolve: ${e.message}`)});break;case"quarantine":y.mutate({id:e,note:o},{onSuccess:e=>{m.toast.warning(e.moved?"File quarantined and moved":"Marked quarantined (file not found)"),h(!0)},onError:e=>m.toast.error(`Quarantine failed: ${e.message}`)});break;case"delete":f.mutate(e,{onSuccess:()=>{m.toast.success("Finding deleted"),h(!0)},onError:e=>m.toast.error(`Failed to delete: ${e.message}`)})}};if(u)return(0,t.jsxs)("span",{className:"inline-flex items-center gap-1.5 text-xs text-[var(--sc-cyan)] italic animate-pulse",children:[(0,t.jsx)(b.Check,{size:12})," Done — removing from list..."]});if("resolved"===s)return(0,t.jsxs)("span",{className:"inline-flex items-center gap-1.5 text-xs text-[var(--sc-cyan)]",children:[(0,t.jsx)(b.Check,{size:12})," Resolved"]});if("quarantined"===s)return(0,t.jsxs)("span",{className:"inline-flex items-center gap-1.5 text-xs text-[var(--sc-amber)]",children:[(0,t.jsx)(k.Shield,{size:12})," Quarantined"]});if("ignored"===s)return(0,t.jsxs)("span",{className:"inline-flex items-center gap-1.5 text-xs text-[var(--sc-text-muted)]",children:[(0,t.jsx)(N,{size:12})," Ignored"]});let S=n?"sm":"md",C=p.isPending||y.isPending||f.isPending;return(0,t.jsxs)("div",{className:"space-y-2",children:[(0,t.jsxs)("div",{className:"flex flex-wrap gap-1.5",children:["new"===s&&(0,t.jsxs)(g.Button,{variant:"ghost",size:S,onClick:()=>j("reviewed"),disabled:C,children:[(0,t.jsx)(i.Eye,{size:12})," Mark reviewed"]}),(0,t.jsxs)(g.Button,{variant:"cyan",size:S,onClick:()=>d(!l),disabled:C,children:[(0,t.jsx)(b.Check,{size:12})," Resolve"]}),(0,t.jsxs)(g.Button,{variant:"ghost",size:S,onClick:()=>j("ignored"),disabled:C,children:[(0,t.jsx)(N,{size:12})," Safe to ignore"]}),r&&(0,t.jsxs)(g.Button,{variant:"coral",size:S,onClick:()=>j("quarantine"),disabled:C,children:[(0,t.jsx)(k.Shield,{size:12})," Quarantine file"]}),(0,t.jsx)(g.Button,{variant:"ghost",size:S,onClick:()=>j("delete"),disabled:C,children:(0,t.jsx)(w.Trash2,{size:12})})]}),l&&(0,t.jsxs)("div",{className:"flex gap-2",children:[(0,t.jsx)("input",{value:o,onChange:e=>x(e.target.value),placeholder:"What did you do about it? (optional)",className:"flex-1 rounded-lg border border-[var(--sc-border)] bg-[var(--sc-bg-elevated)] px-3 py-1.5 text-xs text-[var(--sc-text-primary)] placeholder:text-[var(--sc-text-muted)] focus-ring-cyan","aria-label":"Resolution note",onKeyDown:e=>{"Enter"===e.key&&j("resolved")}}),(0,t.jsx)(g.Button,{variant:"cyan",size:"sm",onClick:()=>j("resolved"),disabled:C,children:"Done"})]})]})}var P=e.i(45256),L=e.i(51069),M=e.i(44758);let q=(0,n.default)("shield-x",[["path",{d:"M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z",key:"oel41y"}],["path",{d:"m14.5 9.5-5 5",key:"17q4r4"}],["path",{d:"m9.5 9.5 5 5",key:"18nt4w"}]]);var D=e.i(13808),W=e.i(76624),T=e.i(23457),G=e.i(44250);function I(e,t,a,s){return`${e}|${t}|${a??""}|${s??""}`}function Q({finding:e,target:s}){let r=(0,T.useLocalAiExplain)(),i=z(),n=A(),[c,l]=(0,a.useState)(new Set),d=e=>l(t=>{let a=new Set(t);return a.add(e),a}),o=!e.id&&!!s&&!!r.data,x=$(o?{target:s,limit:200}:void 0),v=(()=>{if(e.id)return e.id;if(!x.data?.findings)return;let t=I(e.category,e.title,e.file,e.line),a=x.data.findings.find(e=>I(e.category,e.title,e.file,e.line)===t);return a?.id})();return(0,t.jsxs)("div",{className:"mt-3 space-y-3",children:[(0,t.jsxs)(g.Button,{variant:"outline",size:"sm",onClick:()=>{r.mutate({kind:"xray_finding",title:e.title,content:[`Title: ${e.title}`,`Description: ${e.description}`,e.file?`File: ${e.line?`${e.file}:${e.line}`:e.file}`:"",e.evidence?`Evidence: ${e.evidence}`:"",e.guidance?.whatItMeans?`Scanner meaning: ${e.guidance.whatItMeans}`:"",e.guidance?.whatToDo?`Scanner guidance: ${e.guidance.whatToDo}`:"",e.guidance?.falsePositiveNote?`False positive note: ${e.guidance.falsePositiveNote}`:""].filter(Boolean).join("\n"),source:e.file?`xray:${e.file}`:"xray",signals:[e.severity,e.category,e.status??"",e.guidance?.urgency??"",e.systemFile?"system-file":""].filter(Boolean),metadata:{id:e.id,file:e.file,line:e.line,severity:e.severity,category:e.category,status:e.status,detectedAt:e.detectedAt,systemFile:e.systemFile,guidance:e.guidance}},{onSuccess:e=>{m.toast.success(e.explanation.synthetic?"Fallback explanation generated":"Local explanation generated")},onError:e=>m.toast.error(e instanceof Error?e.message:"Local explanation failed")})},disabled:r.isPending,pulse:r.isPending,children:[(0,t.jsx)(D.Sparkles,{size:13}),r.isPending?"Explaining":"Explain"]}),r.data?.explanation&&(0,t.jsx)(W.LocalAiExplanationPanel,{explanation:r.data.explanation,actions:(()=>{let a=[];if(e.file){let s=(0,G.buildEditorUrl)(e.file,e.line);a.push({key:"open",label:"Open in editor",icon:(0,t.jsx)(P.ExternalLink,{size:13}),variant:"outline",onClick:()=>{s&&(window.location.href=s)}})}if(!v)return o&&x.isLoading&&a.push({key:"lookup",label:"Loading actions",variant:"outline",disabled:!0,pending:!0,onClick:()=>void 0}),a;let s=i.isPending||n.isPending,r=c.has("reviewed");a.push({key:"reviewed",label:r?"Reviewed":"Mark reviewed",icon:r?(0,t.jsx)(b.Check,{size:13}):(0,t.jsx)(M.ShieldCheck,{size:13}),variant:r?"cyan":"outline",pending:i.isPending&&i.variables?.status==="reviewed",disabled:s||r,onClick:()=>{i.mutate({id:v,status:"reviewed"},{onSuccess:()=>{d("reviewed"),m.toast.success("Marked as reviewed")},onError:e=>m.toast.error(e instanceof Error?e.message:"Failed to mark reviewed")})}});let l=c.has("dismiss");a.push({key:"dismiss",label:l?"Dismissed":"Dismiss",icon:l?(0,t.jsx)(b.Check,{size:13}):(0,t.jsx)(q,{size:13}),variant:l?"cyan":"ghost",pending:i.isPending&&i.variables?.status==="ignored",disabled:s||l,onClick:()=>{i.mutate({id:v,status:"ignored"},{onSuccess:()=>{d("dismiss"),m.toast.success("Finding dismissed")},onError:e=>m.toast.error(e instanceof Error?e.message:"Failed to dismiss")})}});let u=c.has("quarantine");return a.push({key:"quarantine",label:u?"Quarantined":"Quarantine file",icon:u?(0,t.jsx)(b.Check,{size:13}):(0,t.jsx)(L.ShieldAlert,{size:13}),variant:u?"cyan":"coral",pending:n.isPending,disabled:s||u,onClick:()=>{n.mutate({id:v},{onSuccess:()=>{d("quarantine"),m.toast.success("File quarantined")},onError:e=>m.toast.error(e instanceof Error?e.message:"Failed to quarantine")})}}),a})()}),r.error&&(0,t.jsx)("div",{className:"rounded-lg border border-[var(--sc-coral)]/30 bg-[var(--sc-coral)]/10 p-3 text-sm text-[var(--sc-coral)]",children:r.error instanceof Error?r.error.message:"Local explanation failed"})]})}var H=e.i(31309);function X(e){return e?new Date(e).toLocaleString():"—"}function K(){let[e,n]=(0,a.useState)("scanner"),[b,N]=(0,a.useState)(""),[k,w]=(0,a.useState)(!1),[S,B]=(0,a.useState)(null),[E,z]=(0,a.useState)("ALL"),[A,P]=(0,a.useState)("all"),[L,M]=(0,a.useState)("all"),[q,D]=(0,a.useState)(""),[W,T]=(0,a.useState)("all"),[G,I]=(0,a.useState)("all"),[K,O]=(0,a.useState)(""),[V,U]=(0,a.useState)(!1),[_,J]=(0,a.useState)("new"),{data:Y}=(0,H.useXRayHistory)({risk:E,targetType:A,deep:L,search:q}),{data:Z}=(0,H.useXRayActivity)(8,{kind:W}),{data:ee}=(0,H.useXRayWatchSessions)(8,{state:G}),{data:et}=(0,H.useXRayStatus)(),{data:ea}=(0,C.useQuery)({queryKey:["xray-findings-stats"],queryFn:async()=>{let e=await (0,v.gatedFetch)(`${F}/api/xray/findings/stats`);if(!e.ok)throw Error(await (0,v.readApiError)(e,"Failed to fetch finding stats"));return e.json()},refetchInterval:15e3}),{data:es}=$({status:"all"===_?void 0:_}),er=(0,a.useMemo)(()=>Y?.entries??[],[Y?.entries]),ei=Z?.entries??[],en=ee?.entries??[],ec=(0,H.useXRayScan)(),el=(0,H.usePickXRayTarget)(),ed=S??(er.length>0?er[0].id:null),eo=(0,H.useXRayHistoryEntry)(ed),{data:ex}=(0,H.useActiveWatchers)(),em=(0,H.useStartWatch)(),ev=(0,H.useStopWatch)(),eu=ex?.watchers??[],eh=ec.data?.result,ep=ec.data?.persistedFindings??[],eg=ec.error,ey=eg instanceof v.FeatureLockedError;(0,u.useWebSocketEvent)(e=>{if("xray_detection"===e.type){let t=e.data;m.toast.warning(t.summary||"X-Ray detection",{description:`Risk: ${t.riskLevel||"unknown"}`,duration:8e3})}});let ef=eo.data?.entry??er.find(e=>e.id===ed)??null,ej=eh??ef?.result??null,eb=(0,a.useMemo)(()=>({total:er.length,avgScore:er.length?Math.round(er.reduce((e,t)=>e+t.trustScore,0)/er.length):null}),[er]),eN=et?.capabilities,ek=et?.summary,ew=[{id:"scanner",label:"Scanner",icon:(0,t.jsx)(x.ScanSearch,{size:14})},{id:"history",label:"History",count:eb.total},{id:"watch",label:"Watch",count:ek?.activeWatchRoots??0},{id:"activity",label:"Activity"},{id:"findings",label:"Findings",count:ea?.new??0}];return(0,t.jsx)("div",{className:"h-full overflow-y-auto",children:(0,t.jsxs)("div",{className:"mx-auto max-w-7xl space-y-6 p-6",children:[(0,t.jsx)(y.PageHeader,{eyebrow:"Supply Chain Security",title:"X-Ray Scanner",subtitle:"Scan packages, files, and directories for hidden risk signals.",tabs:ew,activeTab:e,onTabChange:e=>n(e),actions:(0,t.jsx)("div",{className:"flex items-center gap-3",children:(0,t.jsxs)(p.Badge,{variant:eN?.deepScan?"cyan":"muted",dot:!0,children:["Deep scan ",eN?.deepScan?"enabled":"gated"]})})}),(0,t.jsxs)("div",{className:"grid grid-cols-2 gap-4 lg:grid-cols-4",children:[(0,t.jsx)(f.StatCard,{label:"Total Scans",value:ek?.scans??0,icon:x.ScanSearch,accent:"cyan"}),(0,t.jsx)(f.StatCard,{label:"High Risk",value:ek?.highRiskScans??0,icon:s.Activity,accent:"coral"}),(0,t.jsx)(f.StatCard,{label:"Watch Roots",value:ek?.activeWatchRoots??0,icon:i.Eye,accent:"cyan"}),(0,t.jsx)(f.StatCard,{label:"Avg Trust",value:eb.avgScore??"—",icon:c,accent:eb.avgScore&&eb.avgScore>=70?"cyan":"amber"})]}),"scanner"===e&&(0,t.jsxs)("div",{className:"grid gap-6 xl:grid-cols-[1.2fr_0.8fr]",children:[(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)(h.GlassCard,{strong:!0,className:"p-6",children:[(0,t.jsxs)("form",{onSubmit:e=>{e.preventDefault(),b.trim()&&ec.mutate({target:b.trim(),deep:k})},children:[(0,t.jsx)("label",{className:"text-sm font-semibold text-[var(--sc-text-primary)]",children:"What do you want to scan?"}),(0,t.jsx)("input",{value:b,onChange:e=>N(e.target.value),placeholder:"Package name, file path, or directory...",className:"mt-3 w-full rounded-xl border border-[var(--sc-border)] bg-[var(--sc-bg-elevated)] px-4 py-3 text-sm text-[var(--sc-text-primary)] placeholder:text-[var(--sc-text-muted)] focus-ring-cyan"}),(0,t.jsxs)("div",{className:"mt-4 flex flex-wrap items-center gap-3",children:[(0,t.jsxs)("button",{type:"button",onClick:()=>el.mutate("file",{onSuccess:e=>{e.path&&N(e.path)}}),className:"inline-flex items-center gap-2 rounded-xl border border-[var(--sc-border)] bg-[var(--sc-surface-interactive)] px-4 py-2.5 text-sm font-medium text-[var(--sc-text-secondary)] transition-all hover:bg-[var(--sc-surface-interactive-hover)] hover:text-[var(--sc-text-primary)]",children:[(0,t.jsx)(c,{size:14})," Browse file"]}),(0,t.jsxs)("button",{type:"button",onClick:()=>el.mutate("folder",{onSuccess:e=>{e.path&&N(e.path)}}),className:"inline-flex items-center gap-2 rounded-xl border border-[var(--sc-border)] bg-[var(--sc-surface-interactive)] px-4 py-2.5 text-sm font-medium text-[var(--sc-text-secondary)] transition-all hover:bg-[var(--sc-surface-interactive-hover)] hover:text-[var(--sc-text-primary)]",children:[(0,t.jsx)(l,{size:14})," Browse folder"]}),(0,t.jsxs)("label",{className:"inline-flex items-center gap-2 rounded-xl border border-[var(--sc-border)] bg-[var(--sc-surface-interactive)] px-3 py-2.5 text-sm text-[var(--sc-text-secondary)]",children:[(0,t.jsx)("input",{type:"checkbox",checked:k,onChange:e=>w(e.target.checked),className:"h-4 w-4 rounded border-[var(--sc-border)] accent-[var(--sc-cyan)]"}),"Deep scan",!eN?.deepScan&&(0,t.jsx)(d.Lock,{size:12,className:"text-[var(--sc-coral)]"})]}),(0,t.jsxs)(g.Button,{type:"submit",variant:"coral",glow:!0,disabled:ec.isPending||!b.trim(),children:[ec.isPending?"Scanning…":"Run Scan",(0,t.jsx)(r.ArrowRight,{size:14})]})]}),(0,t.jsx)("p",{className:"mt-3 text-xs text-[var(--sc-text-muted)]",children:"Native macOS picker via local API, or paste a path / package name directly."})]}),el.isError&&(0,t.jsx)("div",{className:"mt-3 rounded-xl border border-[var(--sc-coral)]/20 bg-[var(--sc-coral)]/5 px-4 py-3 text-sm text-[var(--sc-coral)]",children:el.error instanceof Error?el.error.message:"Failed to open native picker"}),eg&&(0,t.jsx)("div",{className:`mt-4 rounded-xl px-4 py-3 text-sm ${ey?"border border-[var(--sc-amber)]/20 bg-[var(--sc-amber)]/5 text-[var(--sc-amber)]":"border border-[var(--sc-coral)]/20 bg-[var(--sc-coral)]/5 text-[var(--sc-coral)]"}`,children:eg.message})]}),(0,t.jsxs)(h.GlassCard,{className:`p-6 ${ec.isPending?"scan-sweep":""}`,children:[(0,t.jsxs)("div",{className:"flex items-center justify-between gap-3",children:[(0,t.jsx)("h3",{className:"text-lg font-semibold text-[var(--sc-text-primary)]",children:"Scan Result"}),(0,t.jsxs)("div",{className:"flex gap-2",children:[(0,t.jsxs)(p.Badge,{variant:"muted",children:[eb.total," scans"]}),(0,t.jsxs)(p.Badge,{variant:"muted",children:["Avg ",eb.avgScore??"—"]})]})]}),ej?(0,t.jsxs)("div",{className:"mt-5 space-y-4",children:[(0,t.jsxs)("div",{className:"flex items-start gap-6",children:[(0,t.jsx)(j,{score:ej.trustScore,size:120}),(0,t.jsxs)("div",{className:"flex-1",children:[(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-3",children:[(0,t.jsx)("h4",{className:"text-lg font-semibold text-[var(--sc-text-primary)]",children:ej.target}),(0,t.jsx)(p.Badge,{variant:(0,p.riskVariant)(ej.riskLevel),children:ej.riskLevel})]}),(0,t.jsxs)("div",{className:"mt-2 flex flex-wrap gap-2",children:[(0,t.jsxs)(p.Badge,{variant:"muted",children:[ej.filesScanned," files"]}),(0,t.jsx)(p.Badge,{variant:"muted",children:ej.deepScan?"Deep":"Standard"}),(0,t.jsx)(p.Badge,{variant:"muted",children:X(ej.scannedAt)})]})]})]}),(0,t.jsx)("div",{className:"space-y-3",children:0===ej.findings.length?(0,t.jsx)("div",{className:"rounded-xl border border-[var(--sc-cyan)]/20 bg-[var(--sc-cyan)]/5 px-4 py-4 text-sm text-[var(--sc-cyan)]",children:"No findings detected. This target looks clean."}):ej.findings.map((e,a)=>(0,t.jsxs)(h.GlassCard,{severity:e.severity,className:"p-4",children:[(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,t.jsx)(p.Badge,{variant:(0,p.riskVariant)(e.severity),children:e.severity}),(0,t.jsx)(p.Badge,{variant:"muted",children:e.category})]}),(0,t.jsx)("p",{className:"mt-2 text-sm font-semibold text-[var(--sc-text-primary)]",children:e.title}),(0,t.jsx)("p",{className:"mt-1 text-sm text-[var(--sc-text-secondary)]",children:e.description}),(e.file||e.evidence)&&(0,t.jsxs)("div",{className:"mt-2 space-y-0.5 font-mono text-xs text-[var(--sc-text-muted)]",children:[e.file&&(0,t.jsxs)("div",{children:["File: ",e.line?`${e.file}:${e.line}`:e.file]}),e.evidence&&(0,t.jsxs)("div",{children:["Evidence: ",e.evidence]})]}),(0,t.jsx)(Q,{finding:{...e,id:ep[a]?.id,status:ep[a]?.status},target:ej.target}),ep[a]&&(0,t.jsx)("div",{className:"mt-3 border-t border-[var(--sc-border)] pt-3",children:(0,t.jsx)(R,{findingId:ep[a].id,status:ep[a].status,hasFile:!!e.file,compact:!0})})]},`${e.title}-${a}`))})]}):(0,t.jsx)("div",{className:"mt-5 rounded-xl bg-[var(--sc-bg-elevated)] px-5 py-8 text-center text-sm text-[var(--sc-text-muted)]",children:"Run a scan or select one from history to see results here."})]})]}),(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)(h.GlassCard,{strong:!0,className:"p-5",children:[(0,t.jsx)("h4",{className:"text-xs font-semibold uppercase tracking-[0.18em] text-[var(--sc-text-muted)]",children:"Capabilities"}),(0,t.jsx)("div",{className:"mt-4 space-y-3",children:[{label:"Local scan",enabled:eN?.localScan??!0},{label:"Watch mode",enabled:eN?.watchMode??!0},{label:"Preinstall hook",enabled:eN?.preinstallHook??!1},{label:"npm inspection",enabled:eN?.npmInspection??!1},{label:"Deep scan",enabled:eN?.deepScan??!1}].map(e=>(0,t.jsxs)("div",{className:"flex items-center justify-between rounded-lg bg-[var(--sc-bg-elevated)] px-3 py-2",children:[(0,t.jsx)("span",{className:"text-sm text-[var(--sc-text-secondary)]",children:e.label}),(0,t.jsx)(p.Badge,{variant:e.enabled?"cyan":"muted",dot:!0,children:e.enabled?"On":"Off"})]},e.label))})]}),(0,t.jsxs)(h.GlassCard,{strong:!0,className:"p-5",children:[(0,t.jsx)("h4",{className:"text-xs font-semibold uppercase tracking-[0.18em] text-[var(--sc-text-muted)]",children:"Quick stats"}),(0,t.jsxs)("div",{className:"mt-4 space-y-3",children:[(0,t.jsxs)("div",{className:"flex items-center justify-between rounded-lg bg-[var(--sc-bg-elevated)] px-3 py-2",children:[(0,t.jsx)("span",{className:"text-sm text-[var(--sc-text-secondary)]",children:"Watch roots"}),(0,t.jsxs)("span",{className:"text-sm font-semibold text-[var(--sc-text-primary)]",children:[ek?.activeWatchRoots??0," active"]})]}),(0,t.jsxs)("div",{className:"flex items-center justify-between rounded-lg bg-[var(--sc-bg-elevated)] px-3 py-2",children:[(0,t.jsx)("span",{className:"text-sm text-[var(--sc-text-secondary)]",children:"Stale roots"}),(0,t.jsx)("span",{className:"text-sm font-semibold text-[var(--sc-amber)]",children:ek?.staleWatchRoots??0})]}),(0,t.jsxs)("div",{className:"flex items-center justify-between rounded-lg bg-[var(--sc-bg-elevated)] px-3 py-2",children:[(0,t.jsx)("span",{className:"text-sm text-[var(--sc-text-secondary)]",children:"Blocked events"}),(0,t.jsx)("span",{className:"text-sm font-semibold text-[var(--sc-coral)]",children:ek?.blockedEvents??0})]})]})]})]})]}),"history"===e&&(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsxs)(h.GlassCard,{className:"p-4",children:[(0,t.jsxs)("div",{className:"grid gap-3 lg:grid-cols-[1fr_auto_auto]",children:[(0,t.jsx)("input",{value:q,onChange:e=>D(e.target.value),placeholder:"Filter by file, folder, or package...",className:"rounded-xl border border-[var(--sc-border)] bg-[var(--sc-bg-elevated)] px-4 py-2.5 text-sm text-[var(--sc-text-primary)] placeholder:text-[var(--sc-text-muted)] focus-ring-cyan"}),(0,t.jsxs)("select",{value:E,onChange:e=>z(e.target.value),className:"rounded-xl border border-[var(--sc-border)] bg-[var(--sc-bg-elevated)] px-4 py-2.5 text-sm text-[var(--sc-text-primary)]",children:[(0,t.jsx)("option",{value:"ALL",children:"All risk"}),(0,t.jsx)("option",{value:"CRITICAL",children:"Critical"}),(0,t.jsx)("option",{value:"HIGH",children:"High"}),(0,t.jsx)("option",{value:"MEDIUM",children:"Medium"}),(0,t.jsx)("option",{value:"LOW",children:"Low"}),(0,t.jsx)("option",{value:"SAFE",children:"Safe"})]}),(0,t.jsxs)("select",{value:A,onChange:e=>P(e.target.value),className:"rounded-xl border border-[var(--sc-border)] bg-[var(--sc-bg-elevated)] px-4 py-2.5 text-sm text-[var(--sc-text-primary)]",children:[(0,t.jsx)("option",{value:"all",children:"All targets"}),(0,t.jsx)("option",{value:"file",children:"Files"}),(0,t.jsx)("option",{value:"dir",children:"Directories"}),(0,t.jsx)("option",{value:"npm",children:"Packages"})]})]}),(0,t.jsx)("div",{className:"mt-3 flex gap-2",children:["all","true","false"].map(e=>(0,t.jsx)("button",{onClick:()=>M(e),className:`rounded-lg px-3 py-1.5 text-xs font-medium transition-all ${L===e?"bg-[var(--sc-coral)] text-white":"bg-[var(--sc-surface-interactive)] text-[var(--sc-text-muted)] hover:text-[var(--sc-text-secondary)]"}`,children:"all"===e?"All scans":"true"===e?"Deep only":"Standard only"},e))})]}),(0,t.jsxs)("div",{className:"grid gap-6 xl:grid-cols-[0.45fr_0.55fr]",children:[(0,t.jsx)("div",{className:"space-y-3",children:0===er.length?(0,t.jsx)(h.GlassCard,{className:"p-5 text-center text-sm text-[var(--sc-text-muted)]",children:"No matching scan history yet."}):er.map(e=>(0,t.jsxs)(h.GlassCard,{hover:!0,selected:ed===e.id,onClick:()=>{B(e.id),N(e.target),w(e.deepScan)},className:"p-4",children:[(0,t.jsx)("div",{className:"truncate text-sm font-semibold text-[var(--sc-text-primary)]",children:e.target}),(0,t.jsx)("div",{className:"mt-1 text-xs text-[var(--sc-text-muted)]",children:X(e.scannedAt)}),(0,t.jsxs)("div",{className:"mt-2 flex flex-wrap gap-2",children:[(0,t.jsx)(p.Badge,{variant:(0,p.riskVariant)(e.riskLevel),children:e.riskLevel}),(0,t.jsxs)(p.Badge,{variant:"muted",children:["Score ",e.trustScore]}),(0,t.jsxs)(p.Badge,{variant:"muted",children:[e.findingCount," findings"]})]})]},e.id))}),ej?(0,t.jsxs)(h.GlassCard,{strong:!0,className:"p-6",children:[(0,t.jsxs)("div",{className:"flex items-start gap-5",children:[(0,t.jsx)(j,{score:ej.trustScore,size:100}),(0,t.jsxs)("div",{className:"flex-1",children:[(0,t.jsx)("h4",{className:"text-lg font-semibold text-[var(--sc-text-primary)]",children:ej.target}),(0,t.jsxs)("div",{className:"mt-2 flex flex-wrap gap-2",children:[(0,t.jsx)(p.Badge,{variant:(0,p.riskVariant)(ej.riskLevel),children:ej.riskLevel}),(0,t.jsxs)(p.Badge,{variant:"muted",children:[ej.filesScanned," files"]}),(0,t.jsx)(p.Badge,{variant:"muted",children:ej.deepScan?"Deep":"Standard"})]})]})]}),(0,t.jsx)("div",{className:"mt-5 space-y-3",children:0===ej.findings.length?(0,t.jsx)("div",{className:"rounded-xl border border-[var(--sc-cyan)]/20 bg-[var(--sc-cyan)]/5 px-4 py-3 text-sm text-[var(--sc-cyan)]",children:"Clean — no findings."}):ej.findings.map((e,a)=>(0,t.jsxs)(h.GlassCard,{severity:e.severity,className:"p-3",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(p.Badge,{variant:(0,p.riskVariant)(e.severity),children:e.severity}),(0,t.jsx)("span",{className:"text-sm font-medium text-[var(--sc-text-primary)]",children:e.title})]}),(0,t.jsx)("p",{className:"mt-1 text-xs text-[var(--sc-text-secondary)]",children:e.description}),(0,t.jsx)(Q,{finding:e,target:ej.target})]},`${e.title}-${a}`))})]}):(0,t.jsx)(h.GlassCard,{className:"flex items-center justify-center p-8 text-sm text-[var(--sc-text-muted)]",children:"Select a scan from the list to view details."})]})]}),"watch"===e&&(0,t.jsxs)("div",{className:"space-y-6",children:[(0,t.jsxs)(h.GlassCard,{strong:!0,className:"p-6",children:[(0,t.jsx)("h3",{className:"text-lg font-semibold text-[var(--sc-text-primary)]",children:"Start Watching"}),(0,t.jsx)("p",{className:"mt-1 text-sm text-[var(--sc-text-muted)]",children:"Monitor a directory for file changes and automatically scan for threats in real-time."}),(0,t.jsxs)("form",{className:"mt-4 flex flex-wrap items-end gap-3",onSubmit:e=>{e.preventDefault(),K.trim()&&em.mutate({target:K.trim(),deep:V})},children:[(0,t.jsx)("div",{className:"flex-1",children:(0,t.jsx)("input",{value:K,onChange:e=>O(e.target.value),placeholder:"Directory path, e.g. /Users/michael/Development/project",className:"w-full rounded-xl border border-[var(--sc-border)] bg-[var(--sc-bg-elevated)] px-4 py-3 text-sm text-[var(--sc-text-primary)] placeholder:text-[var(--sc-text-muted)] focus-ring-cyan"})}),(0,t.jsxs)("button",{type:"button",onClick:()=>el.mutate("folder",{onSuccess:e=>{e.path&&O(e.path)}}),className:"inline-flex items-center gap-2 rounded-xl border border-[var(--sc-border)] bg-[var(--sc-surface-interactive)] px-4 py-3 text-sm font-medium text-[var(--sc-text-secondary)] transition-all hover:bg-[var(--sc-surface-interactive-hover)] hover:text-[var(--sc-text-primary)]",children:[(0,t.jsx)(l,{size:14})," Browse"]}),(0,t.jsxs)("label",{className:"inline-flex items-center gap-2 rounded-xl border border-[var(--sc-border)] bg-[var(--sc-surface-interactive)] px-3 py-3 text-sm text-[var(--sc-text-secondary)]",children:[(0,t.jsx)("input",{type:"checkbox",checked:V,onChange:e=>U(e.target.checked),className:"h-4 w-4 rounded accent-[var(--sc-cyan)]"}),"Deep"]}),(0,t.jsxs)(g.Button,{type:"submit",variant:"cyan",disabled:em.isPending||!K.trim(),children:[em.isPending?"Starting…":"Start Watch",(0,t.jsx)(i.Eye,{size:14})]})]}),em.isSuccess&&(0,t.jsxs)("p",{className:"mt-3 text-sm text-[var(--sc-cyan)]",children:["Watching ",em.data.root]}),em.isError&&(0,t.jsx)("p",{className:"mt-3 text-sm text-[var(--sc-coral)]",children:em.error instanceof Error?em.error.message:"Failed to start watch"})]}),eu.length>0&&(0,t.jsxs)("div",{children:[(0,t.jsx)("h4",{className:"mb-3 text-sm font-semibold uppercase tracking-wider text-[var(--sc-text-muted)]",children:"Active Watchers (This Session)"}),(0,t.jsx)("div",{className:"grid gap-3 lg:grid-cols-2",children:eu.map(e=>(0,t.jsxs)(h.GlassCard,{className:"flex items-center justify-between p-4",children:[(0,t.jsxs)("div",{className:"min-w-0",children:[(0,t.jsx)("p",{className:"truncate text-sm font-semibold text-[var(--sc-text-primary)]",children:e.root}),(0,t.jsxs)("p",{className:"text-xs text-[var(--sc-text-muted)]",children:["PID ",e.pid]})]}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(p.Badge,{variant:"cyan",dot:!0,pulse:!0,children:"Watching"}),(0,t.jsx)(g.Button,{variant:"outline",size:"sm",onClick:()=>ev.mutate(e.root),disabled:ev.isPending,children:"Stop"})]})]},e.root))})]}),(0,t.jsxs)("div",{className:"flex items-center justify-between gap-3",children:[(0,t.jsx)("h4",{className:"text-sm font-semibold uppercase tracking-wider text-[var(--sc-text-muted)]",children:"Session History"}),(0,t.jsx)("div",{className:"flex gap-2",children:["all","active","stale","ended"].map(e=>(0,t.jsx)("button",{onClick:()=>I(e),className:`rounded-lg px-3 py-1.5 text-xs font-medium capitalize transition-all ${G===e?"bg-[var(--sc-coral)] text-white":"bg-[var(--sc-surface-interactive)] text-[var(--sc-text-muted)] hover:text-[var(--sc-text-secondary)]"}`,children:e},e))})]}),0===en.length?(0,t.jsxs)(h.GlassCard,{className:"p-8 text-center text-sm text-[var(--sc-text-muted)]",children:["No watch sessions recorded yet. Start a watcher above or use ",(0,t.jsx)("code",{className:"font-mono text-[var(--sc-cyan)]",children:"shieldcortex xray --watch ./src"})," from the CLI."]}):(0,t.jsx)("div",{className:"grid gap-4 lg:grid-cols-2",children:en.map(e=>(0,t.jsxs)(h.GlassCard,{className:"p-5",children:[(0,t.jsxs)("div",{className:"flex items-start justify-between gap-3",children:[(0,t.jsxs)("div",{className:"min-w-0",children:[(0,t.jsx)("p",{className:"truncate text-sm font-semibold text-[var(--sc-text-primary)]",children:e.root}),(0,t.jsxs)("p",{className:"mt-1 text-xs text-[var(--sc-text-muted)]",children:["Started ",X(e.startedAt)]})]}),(0,t.jsx)(p.Badge,{variant:"active"===e.state?"cyan":"stale"===e.state?"amber":"muted",dot:!0,pulse:"active"===e.state,children:e.state})]}),(0,t.jsx)("p",{className:"mt-2 text-sm text-[var(--sc-text-secondary)]",children:e.lastEventSummary??"No detections yet"}),(0,t.jsxs)("div",{className:"mt-3 flex flex-wrap gap-2",children:[(0,t.jsxs)(p.Badge,{variant:"muted",children:[e.changesDetected," changes"]}),(0,t.jsxs)(p.Badge,{variant:"muted",children:[e.findingsDetected," findings"]}),(0,t.jsx)(p.Badge,{variant:(0,p.riskVariant)(e.highestRiskLevel),children:e.highestRiskLevel})]})]},e.id))})]}),"activity"===e&&(0,t.jsxs)("div",{className:"space-y-4",children:[(0,t.jsx)("div",{className:"flex gap-2",children:["all","scan","watch","preinstall"].map(e=>(0,t.jsx)("button",{onClick:()=>T(e),className:`rounded-lg px-3 py-1.5 text-xs font-medium capitalize transition-all ${W===e?"bg-[var(--sc-coral)] text-white":"bg-[var(--sc-surface-interactive)] text-[var(--sc-text-muted)] hover:text-[var(--sc-text-secondary)]"}`,children:"all"===e?"All activity":e},e))}),0===ei.length?(0,t.jsx)(h.GlassCard,{className:"p-8 text-center text-sm text-[var(--sc-text-muted)]",children:"No matching automatic events yet."}):(0,t.jsx)("div",{className:"space-y-3",children:ei.map(e=>(0,t.jsx)(h.GlassCard,{className:"p-4",children:(0,t.jsxs)("div",{className:"flex items-start justify-between gap-3",children:[(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(o,{size:14,className:"shrink-0 text-[var(--sc-coral)]"}),(0,t.jsx)("span",{className:"text-sm font-semibold capitalize text-[var(--sc-text-primary)]",children:e.kind})]}),(0,t.jsx)("p",{className:"mt-1 truncate text-sm text-[var(--sc-text-secondary)]",children:e.target}),(0,t.jsx)("p",{className:"mt-1 text-xs text-[var(--sc-text-muted)]",children:e.summary})]}),(0,t.jsx)(p.Badge,{variant:"pass"===e.status?"safe":"blocked"===e.status?"critical":"warn"===e.status?"medium":"amber",children:e.status})]})},e.id))})]}),"findings"===e&&(0,t.jsxs)("div",{className:"space-y-4",children:[ea&&(0,t.jsxs)("div",{className:"flex flex-wrap gap-2",children:[(0,t.jsxs)(p.Badge,{variant:"coral",children:[ea.new," new"]}),(0,t.jsxs)(p.Badge,{variant:"muted",children:[ea.reviewed," reviewed"]}),(0,t.jsxs)(p.Badge,{variant:"cyan",children:[ea.resolved," resolved"]}),(0,t.jsxs)(p.Badge,{variant:"amber",children:[ea.quarantined," quarantined"]}),(0,t.jsxs)(p.Badge,{variant:"muted",children:[ea.ignored," ignored"]}),(0,t.jsxs)(p.Badge,{variant:"muted",children:[ea.total," total"]})]}),(0,t.jsx)("div",{className:"flex flex-wrap gap-2",children:[{key:"new",label:"Needs attention",accent:!0},{key:"reviewed",label:"Reviewed",accent:!1},{key:"resolved",label:"Resolved",accent:!1},{key:"ignored",label:"Ignored",accent:!1},{key:"quarantined",label:"Quarantined",accent:!1},{key:"all",label:"Everything",accent:!1}].map(({key:e,label:a,accent:s})=>(0,t.jsxs)("button",{onClick:()=>J(e),className:`rounded-lg px-3 py-1.5 text-xs font-medium transition-all ${_===e?s?"bg-[var(--sc-coral)] text-white":"bg-[var(--sc-cyan)] text-[var(--sc-bg-deep)]":"bg-[var(--sc-surface-interactive)] text-[var(--sc-text-muted)] hover:text-[var(--sc-text-secondary)]"}`,children:[a,"new"===e&&ea&&ea.new>0&&(0,t.jsx)("span",{className:"ml-1.5 rounded-full bg-white/20 px-1.5 py-0.5 text-[10px] font-bold",children:ea.new})]},e))}),es?.findings&&0!==es.findings.length?(0,t.jsx)("div",{className:"space-y-3",children:es.findings.map(e=>(0,t.jsxs)(h.GlassCard,{severity:e.severity,className:"p-5",children:[(0,t.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,t.jsx)(p.Badge,{variant:(0,p.riskVariant)(e.severity),children:e.severity}),(0,t.jsx)(p.Badge,{variant:"muted",children:e.category}),e.systemFile&&(0,t.jsx)(p.Badge,{variant:"muted",children:"System file — likely safe"}),e.guidance?.urgency==="usually-safe"&&!e.systemFile&&(0,t.jsx)(p.Badge,{variant:"cyan",children:"Usually safe"}),e.guidance?.urgency==="act-now"&&(0,t.jsx)(p.Badge,{variant:"critical",dot:!0,pulse:!0,children:"Act now"})]}),(0,t.jsx)("p",{className:"mt-3 text-sm font-semibold text-[var(--sc-text-primary)]",children:e.title}),e.guidance&&(0,t.jsxs)("div",{className:"mt-3 space-y-3 rounded-xl bg-[var(--sc-bg-elevated)] p-4",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-[11px] font-semibold uppercase tracking-wider text-[var(--sc-text-muted)]",children:"What this means"}),(0,t.jsx)("p",{className:"mt-1 text-sm leading-relaxed text-[var(--sc-text-secondary)]",children:e.guidance.whatItMeans})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-[11px] font-semibold uppercase tracking-wider text-[var(--sc-cyan)]",children:"What to do"}),(0,t.jsx)("p",{className:"mt-1 text-sm leading-relaxed text-[var(--sc-text-secondary)]",children:e.guidance.whatToDo})]}),(0,t.jsxs)("div",{children:[(0,t.jsx)("p",{className:"text-[11px] font-semibold uppercase tracking-wider text-[var(--sc-text-muted)]",children:"False positive?"}),(0,t.jsx)("p",{className:"mt-1 text-xs leading-relaxed text-[var(--sc-text-muted)]",children:e.guidance.falsePositiveNote})]})]}),(e.file||e.evidence)&&(0,t.jsxs)("div",{className:"mt-3 space-y-0.5 font-mono text-xs text-[var(--sc-text-muted)]",children:[e.file&&(0,t.jsxs)("div",{children:["File: ",e.line?`${e.file}:${e.line}`:e.file]}),e.evidence&&(0,t.jsxs)("div",{children:["Evidence: ",e.evidence]})]}),(0,t.jsx)(Q,{finding:e}),(0,t.jsx)("div",{className:"mt-2 text-xs text-[var(--sc-text-muted)]",children:X(e.detectedAt)}),(0,t.jsx)("div",{className:"mt-3 border-t border-[var(--sc-border)] pt-3",children:(0,t.jsx)(R,{findingId:e.id,status:e.status,hasFile:!!e.file,compact:!0})})]},e.id))}):(0,t.jsxs)(h.GlassCard,{className:"p-8 text-center",children:[(0,t.jsx)("p",{className:"text-sm text-[var(--sc-text-primary)]",children:"new"===_?"All clear — no findings need attention":`No ${"all"===_?"":_+" "}findings`}),(0,t.jsx)("p",{className:"mt-1 text-xs text-[var(--sc-text-muted)]",children:"new"===_?"Run an X-Ray scan or start a watcher to monitor for threats.":"Findings move here when you take action on them."})]})]})]})})}e.s(["XRayOverview",()=>K],27918)}]);
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,87927,e=>{"use strict";let t="shieldcortex.graph.intensity",r=new Set(["subtle","moderate","strong"]);function a(e){let a=e??window.localStorage;if(!a)return"moderate";let n=a.getItem(t);return"string"==typeof n&&r.has(n)?n:"moderate"}function n(e,r){let a=r??window.localStorage;a&&(a.setItem(t,e),"u">typeof CustomEvent&&window.dispatchEvent(new CustomEvent("shieldcortex:intensity-changed",{detail:e})))}function l(){return!!window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches}e.s(["INTENSITY",0,{subtle:{breathPeriod:6e3,breathAmp:.03,particleCap:20,decayCreate:.98,decayRecall:.96},moderate:{breathPeriod:3e3,breathAmp:.08,particleCap:60,decayCreate:.96,decayRecall:.93},strong:{breathPeriod:1600,breathAmp:.14,particleCap:120,decayCreate:.94,decayRecall:.9}},"REDUCED_INTENSITY",0,{breathPeriod:1/0,breathAmp:0,particleCap:0,decayCreate:0,decayRecall:0},"isReducedMotion",()=>l,"loadIntensity",()=>a,"saveIntensity",()=>n])},68595,e=>{"use strict";var t=e.i(27493),r=e.i(4),a=e.i(6847),n=e.i(17278),l=e.i(16467),s=e.i(95659),i=e.i(74133);let o=(e,t,r)=>Math.min(r,Math.max(t,e)),c="#7dd3fc";function d(e){return"string"==typeof e?e:e.id}var u=e.i(87927);class m{level;settings;knownNodes=new Set;phase=new Map;spikeEnergy=new Map;recallEnergy=new Map;breathOffset=new Map;now;lastFrameAt=0;constructor(e){this.level=e.intensity,this.settings=u.INTENSITY[e.intensity],this.now=e.now??("u">typeof performance?()=>performance.now():Date.now)}setIntensity(e){this.level=e,this.settings=u.INTENSITY[e]}observeNodes(e){for(let t of e)this.knownNodes.has(t)||(this.knownNodes.add(t),this.phase.set(t,function(e){let t=0x811c9dc5;for(let r=0;r<e.length;r++)t^=e.charCodeAt(r),t=0x1000193*t>>>0;return t/0x100000000}(t)*Math.PI*2))}dispatch(e){this.knownNodes.has(e.entityId)&&("memory.created"===e.type&&this.spikeEnergy.set(e.entityId,1),"memory.accessed"===e.type&&this.recallEnergy.set(e.entityId,1))}onFrame(e){this.lastFrameAt=e;let{breathPeriod:t,breathAmp:r}=this.settings,a=2*Math.PI/t;for(let t of this.knownNodes){let n=this.phase.get(t)??0;this.breathOffset.set(t,Math.sin(a*e+n)*r)}let n=this.settings.decayCreate;for(let[e,t]of this.spikeEnergy){let r=t*n;r<.001?this.spikeEnergy.delete(e):this.spikeEnergy.set(e,r)}let l=this.settings.decayRecall;for(let[e,t]of this.recallEnergy){let r=t*l;r<.001?this.recallEnergy.delete(e):this.recallEnergy.set(e,r)}}getEnergy(e){return this.knownNodes.has(e)?(this.breathOffset.get(e)??0)+(this.spikeEnergy.get(e)??0):0}getRecallEnergy(e){return this.knownNodes.has(e)?this.recallEnergy.get(e)??0:0}pickParticleEdges(e,t,r){let a=r??this.settings.particleCap;if(a<=0||0===e.length)return[];let n=e=>"string"==typeof e?e:e.id,l=e.map(e=>{let r=n(e.source),a=n(e.target);return{link:e,score:Math.max(Math.max(this.getEnergy(r),this.getRecallEnergy(r)),Math.max(this.getEnergy(a),this.getRecallEnergy(a))),anchorAdjacent:+(null!==t&&(r===t||a===t))}});return l.sort((e,t)=>t.score!==e.score?t.score-e.score:t.anchorAdjacent-e.anchorAdjacent),l.slice(0,a).map(e=>e.link)}}function h({driver:e}){let[a,n]=(0,r.useState)("");return"1"===window.localStorage.getItem("SHIELDCORTEX_DEBUG_PULSE")&&e?(0,t.jsxs)("div",{style:{position:"absolute",bottom:8,right:8,padding:8,background:"#0a0d14cc",color:"#e2e8f0",fontSize:12,border:"1px solid #1e293b",zIndex:10},children:[(0,t.jsx)("div",{style:{marginBottom:4,opacity:.6},children:"pulse debug"}),(0,t.jsx)("input",{value:a,onChange:e=>n(e.target.value),placeholder:"entity id",style:{width:140,background:"#06070d",color:"#e2e8f0",border:"1px solid #1e293b",padding:"2px 4px"}}),(0,t.jsxs)("div",{style:{display:"flex",gap:4,marginTop:4},children:[(0,t.jsx)("button",{onClick:()=>e.dispatch({type:"memory.created",entityId:a}),children:"created"}),(0,t.jsx)("button",{onClick:()=>e.dispatch({type:"memory.accessed",entityId:a}),children:"accessed"})]})]}):null}var f=e.i(22534),p=e.i(35372);let y=f.default.env.NEXT_PUBLIC_API_URL||"http://localhost:3001",g=(0,i.default)(()=>e.A(23531),{loadableGenerated:{modules:[23272]},ssr:!1}),x={tool:"#00e5cc",concept:"#ff4d4d",project:"#f59e0b",file:"#5a6480",service:"#a78bfa",person:"#34d399",language:"#a78bfa",pattern:"#fb923c"};function b({clusters:e,allTriples:a,totalEntities:n,totalConnections:l,width:s,height:i,onSelectEntity:f,selectedEntityId:b}){let v=(0,r.useRef)(void 0),C=(0,r.useRef)(null),j=(0,r.useRef)(1),[k,w]=(0,r.useState)(null),[S,N]=(0,r.useState)(null),[M,E]=(0,r.useState)(null),[I,P]=(0,r.useState)("moderate"),T=(0,r.useMemo)(()=>(0,u.isReducedMotion)(),[]),R=(0,r.useMemo)(()=>T?u.REDUCED_INTENSITY:u.INTENSITY[I],[T,I]),A=(0,r.useMemo)(()=>(function(e){let t=new Map;for(let r of e)for(let e of r.entities)t.set(e.id,r.type);return t})(e),[e]),F=(0,r.useMemo)(()=>{let t=function(e,t){let r=new Map;for(let a of e){let e=t.get(a.source),n=t.get(a.target);if(e&&n&&e!==n){let t=[e,n].sort().join("::");r.set(t,(r.get(t)||0)+1)}}return r}(a,A),r=e.map((t,r)=>{let a=r/e.length*Math.PI*2-Math.PI/2;return{id:`cluster::${t.type}`,name:t.type,type:t.type,memoryCount:t.entities.reduce((e,t)=>e+t.memoryCount,0),colour:t.colour,isCluster:!0,clusterType:t.type,entityCount:t.entities.length,x:150*Math.cos(a),y:150*Math.sin(a)}}),n=[];for(let[e,r]of t.entries()){let[t,a]=e.split("::");r>5&&n.push({source:`cluster::${t}`,target:`cluster::${a}`,weight:Math.min(r/100,1)})}return{nodes:r,links:n}},[e,a,A]),$=(0,r.useMemo)(()=>{if(!S)return null;let t=e.find(e=>e.type===S);if(!t)return null;let r=t.entities.slice(0,100),n=new Set(r.map(e=>e.id)),l=r.map(e=>({id:e.id,name:e.name,type:e.type,memoryCount:e.memoryCount,colour:t.colour})),s=new Map;for(let e of a){if(n.has(e.source)&&!n.has(e.target)){let t=A.get(e.target);t&&t!==S&&s.set(t,(s.get(t)||0)+1)}if(n.has(e.target)&&!n.has(e.source)){let t=A.get(e.source);t&&t!==S&&s.set(t,(s.get(t)||0)+1)}}for(let[e,t]of s.entries())t>2&&l.push({id:`ghost::${e}`,name:e,type:e,memoryCount:t,colour:x[e]||"#8892b0",isCluster:!0,clusterType:e,entityCount:t});let i=[],o=new Set;for(let e of a){let t=n.has(e.source),r=n.has(e.target);if(t&&r){let t=`${e.source}::${e.target}`;o.has(t)||(o.add(t),i.push({source:e.source,target:e.target,predicate:e.predicate}))}else if(t&&!r){let t=A.get(e.target);if(t&&t!==S&&s.has(t)){let r=`${e.source}::ghost::${t}`;o.has(r)||(o.add(r),i.push({source:e.source,target:`ghost::${t}`}))}}else if(r&&!t){let t=A.get(e.source);if(t&&t!==S&&s.has(t)){let r=`ghost::${t}::${e.target}`;o.has(r)||(o.add(r),i.push({source:`ghost::${t}`,target:e.target}))}}}return{nodes:l,links:i}},[S,e,a,A]),_=S&&$?$:F;(0,r.useEffect)(()=>{let e=(0,u.loadIntensity)();P(e);let t=new m({intensity:e});w(t);let r=e=>{let r=e.detail;("subtle"===r||"moderate"===r||"strong"===r)&&(P(r),t.setIntensity(r))};return window.addEventListener("shieldcortex:intensity-changed",r),()=>{window.removeEventListener("shieldcortex:intensity-changed",r)}},[]),(0,r.useEffect)(()=>{k?.observeNodes(_.nodes.map(e=>e.id))},[k,_.nodes]),function(e,t=!0){let{subscribe:a,isConnected:n}=(0,p.useMemoryWebSocketContext)(),l=(0,r.useRef)(null);(0,r.useEffect)(()=>{if(e&&t)return a(t=>{if(!t?.type||!t.data)return;let r="memory_created"===t.type?"memory.created":"memory_accessed"===t.type?"memory.accessed":null;if(r)for(let a of t.data.entity_ids??[])e.dispatch({type:r,entityId:String(a)})})},[e,t,a]),(0,r.useEffect)(()=>{if(!e||!t||n)return;let r=!1,a=setInterval(()=>{let t=l.current;fetch(`${y}/api/memories?mode=recent&limit=50`,{credentials:"include"}).then(e=>e.ok?e.json():null).then(a=>{if(!a||r)return;let n=a.memories??[];for(let r of n)if(!t||!r.created_at||!(r.created_at<=t))for(let t of r.entity_ids??[])e.dispatch({type:"memory.created",entityId:String(t)});n[0]?.created_at&&(l.current=n[0].created_at)}).catch(()=>{})},1e4);return()=>{r=!0,clearInterval(a)}},[e,t,n])}(k,!0),(0,r.useEffect)(()=>{let e=function(e,t){if(0===e.length)return null;let r=new Set(e.map(e=>e.id)),a=new Map;for(let e of t){let t=d(e.source),n=d(e.target);r.has(t)&&a.set(t,(a.get(t)??0)+1),r.has(n)&&a.set(n,(a.get(n)??0)+1)}let n=null,l=0;for(let t of e){let e=t.memoryCount*(a.get(t.id)??0);0!==e&&(null===n||e>l||e===l&&0>t.name.localeCompare(n.name))&&(n=t,l=e)}if(n)return n.id;let s=0;for(let t of e)0!==t.memoryCount&&(null===n||t.memoryCount>s||t.memoryCount===s&&0>t.name.localeCompare(n.name))&&(n=t,s=t.memoryCount);return n?.id??null}(_.nodes.map(e=>({id:e.id,name:e.name,memoryCount:e.memoryCount})),_.links);e!==M&&(!function(e,t,r){let a=e.find(e=>e.id===t);if(a){if(r&&r!==t){let t=e.find(e=>e.id===r);t&&(t.fx=null,t.fy=null)}a.fx=0,a.fy=0}}(_.nodes,e??"",M),E(e))},[_.nodes,_.links,M]),(0,r.useEffect)(()=>{let e=v.current;e&&(S?(e.d3Force("charge")?.strength(-80),e.d3Force("link")?.distance(40),e.d3Force("center")?.strength(.05)):(e.d3Force("charge")?.strength(-2e3),e.d3Force("link")?.distance(180),e.d3Force("center")?.strength(.03)))},[S,_]);let D=(0,r.useRef)(!1);(0,r.useEffect)(()=>{if(D.current||!_.nodes.length)return;D.current=!0;let e=setTimeout(()=>v.current?.zoomToFit(400*!T,80),1500);return()=>clearTimeout(e)},[_.nodes.length,T]);let B=(0,r.useCallback)(({k:e})=>{j.current=e},[]),L=(0,r.useMemo)(()=>(function(e,t={}){let r=new Map;return{handleNodeDragEnd(e){void 0!==e.x&&void 0!==e.y&&(e.fx=e.x,e.fy=e.y)},handleNodeClick(a,n){if(n.shiftKey&&null!==a.fx&&void 0!==a.fx)return a.fx=null,a.fy=null,t.onUnpin?.(String(a.id)),r.delete(String(a.id)),"unpin";let l=String(a.id),s=performance.now(),i=r.get(l)??0;return(r.set(l,s),s-i<=300)?(void 0!==a.x&&void 0!==a.y&&(e.current?.centerAt(a.x,a.y,600),e.current?.zoom(2,600)),r.delete(l),"double-click"):"single-click"},handleBackgroundDoubleClick(t){t(),e.current?.zoomToFit(600,80)}}})(v),[]),O=(0,r.useCallback)((e,t)=>{"single-click"===L.handleNodeClick(e,t)&&(e.isCluster?(N((e.clusterType||e.type).replace("ghost::","")),f?.(null)):f?.({id:e.id,name:e.name,type:e.type,memoryCount:e.memoryCount}))},[L,f]),z=(0,r.useCallback)(()=>{S&&(N(null),f?.(null))},[S,f]),G=(0,r.useCallback)(()=>{L.handleBackgroundDoubleClick(()=>{N(null),f?.(null)})},[L,f]),U=(0,r.useCallback)(e=>{C.current=e?String(e.id):null},[]),q=(0,r.useCallback)((e,t,r)=>{if(void 0===e.x||void 0===e.y)return;let a=String(e.id),n=a===C.current,l=null!=b&&a===b,s=j.current;if(t.save(),l&&!e.isCluster){let r=.8+Math.min(.4*Math.log2((e.memoryCount||1)+1),2.5),a=t.createRadialGradient(e.x,e.y,r,e.x,e.y,8*r);a.addColorStop(0,"#ffffff18"),a.addColorStop(1,"#ffffff00"),t.beginPath(),t.arc(e.x,e.y,8*r,0,2*Math.PI),t.fillStyle=a,t.fill()}if(e.isCluster){!function(e,t,r,a){let n=t.entityCount||5,l=Math.min(15+3*Math.sqrt(n),60),s=3*l,i=e.createRadialGradient(t.x,t.y,.5*l,t.x,t.y,s);i.addColorStop(0,t.colour+"15"),i.addColorStop(.4,t.colour+"08"),i.addColorStop(1,t.colour+"00"),e.beginPath(),e.arc(t.x,t.y,s,0,2*Math.PI),e.fillStyle=i,e.fill();let o=e.createRadialGradient(t.x,t.y,0,t.x,t.y,.8*l);o.addColorStop(0,t.colour+"28"),o.addColorStop(.6,t.colour+"10"),o.addColorStop(1,t.colour+"02"),e.beginPath(),e.arc(t.x,t.y,.8*l,0,2*Math.PI),e.fillStyle=o,e.fill();let c=Math.min(n,40),d=t.id.charCodeAt(t.id.length-1);for(let r=0;r<c;r++){let a=(d+137.508*r)%360*(Math.PI/180),n=.1*l+.85*l*Math.pow((7*d+31*r)%100/100,.6),s=t.x+Math.cos(a)*n,i=t.y+Math.sin(a)*n,o=.5+(17*r+d)%4*.3;e.beginPath(),e.arc(s,i,o,0,2*Math.PI),e.fillStyle=t.colour+(r<5?"dd":r<15?"88":"44"),e.fill()}a&&(e.beginPath(),e.arc(t.x,t.y,l,0,2*Math.PI),e.strokeStyle=t.colour+"50",e.lineWidth=1.5,e.setLineDash([4,4]),e.stroke(),e.setLineDash([]));let u=Math.max(13/Math.max(r,.3),8);e.font=`600 ${u}px Inter, system-ui, sans-serif`,e.textAlign="center",e.textBaseline="top",e.fillStyle=t.colour+"bb",e.fillText(t.name,t.x,t.y+l+8);let m=Math.max(10/Math.max(r,.3),6);e.font=`400 ${m}px Inter, system-ui, sans-serif`,e.fillStyle="#ffffff30",e.fillText(`${n} entities`,t.x,t.y+l+8+u+3)}(t,e,s,n),t.restore();return}let i=k?.getEnergy(a)??0,o=k?.getRecallEnergy(a)??0,c=.8+Math.min(.4*Math.log2((e.memoryCount??0)+1),2.5);if(!function(e,t={}){var r;let a,{ctx:n,node:l,intensity:s,energy:i,recallEnergy:o,isAnchor:c,isSelected:d,baseRadius:u}=e;if(void 0===l.x||void 0===l.y)return;let m=(a=(r={baseRadius:u,energy:i,breathAmp:s.breathAmp}).baseRadius*(1+r.energy*r.breathAmp),Math.max(.2*r.baseRadius,a));t._paintHook?.({nodeId:l.id,radius:m,energy:i,recallEnergy:o});let h=m*(c?5:3.5),f=n.createRadialGradient(l.x,l.y,.2*m,l.x,l.y,h);if(f.addColorStop(0,l.colour+(c?"40":d?"50":"20")),f.addColorStop(1,l.colour+"00"),n.beginPath(),n.arc(l.x,l.y,h,0,2*Math.PI),n.fillStyle=f,n.fill(),o>.05&&(n.beginPath(),n.arc(l.x,l.y,1.6*m,0,2*Math.PI),n.strokeStyle="#fb923c",n.globalAlpha=Math.min(.7,o),n.lineWidth=1.5,n.stroke(),n.globalAlpha=1),c){n.beginPath(),n.arc(l.x,l.y,m,0,2*Math.PI),n.fillStyle="#fde68a",n.fill(),n.lineWidth=1.5,n.strokeStyle="#fbbf24",n.stroke();return}n.beginPath(),n.arc(l.x,l.y,m,0,2*Math.PI),n.fillStyle=l.colour,n.fill(),d&&(n.lineWidth=1.5,n.strokeStyle="#ffffff",n.stroke())}({ctx:t,globalScale:r,node:e,intensity:R,energy:i,recallEnergy:o,isAnchor:a===M,isSelected:l,isHovered:n,baseRadius:c}),n&&!l&&a!==M){let r=c*(1+i*R.breathAmp);t.beginPath(),t.arc(e.x,e.y,r,0,2*Math.PI),t.strokeStyle=e.colour,t.lineWidth=.7,t.stroke()}let d=e.memoryCount||1;if(l||n||s>=3||s>=1.5&&d>30||s>=.8&&d>100){let r=c*(1+i*R.breathAmp),a=Math.max((l?11:n?10:8)/Math.max(s,.4),5);t.font=`${a}px Inter, system-ui, sans-serif`,t.textAlign="center",t.textBaseline="top",t.fillStyle=l?"#ffffff":n?"#f0f4ffcc":"#f0f4ff66",t.fillText(e.name,e.x,e.y+r+2)}t.restore()},[b,M,R,k]),W=(0,r.useCallback)((e,t)=>{let r=e.source,a=e.target;if("object"!=typeof r||"object"!=typeof a||void 0===r.x||void 0===r.y||void 0===a.x||void 0===a.y)return;let n=String(r.id),l=String(a.id),s=k?.getEnergy(n)??0,i=k?.getEnergy(l)??0;!function(e){let{ctx:t,link:r,srcEnergy:a,dstEnergy:n}=e,l=r.source,s=r.target;if(void 0===l.x||void 0===l.y||void 0===s.x||void 0===s.y)return;let i=t.globalCompositeOperation;t.globalCompositeOperation="lighter";let d=t.createLinearGradient(l.x,l.y,s.x,s.y);d.addColorStop(0,l.colour??c),d.addColorStop(1,s.colour??c),t.strokeStyle=d,t.globalAlpha=o(.35+.6*Math.max(a,n),0,1),t.lineWidth=o(1+.8*Math.max(a,n),.5,3),t.beginPath(),t.moveTo(l.x,l.y),t.lineTo(s.x,s.y),t.stroke(),t.globalAlpha=1,t.globalCompositeOperation=i}({ctx:t,link:{source:{x:r.x,y:r.y,colour:r.colour,id:n},target:{x:a.x,y:a.y,colour:a.colour,id:l}},srcEnergy:s,dstEnergy:i})},[k]),K=(0,r.useRef)(new Set),Y=(0,r.useCallback)(()=>{if(!k)return;k.onFrame(performance.now());let e=k.pickParticleEdges(_.links.map(e=>({source:String(e.source),target:String(e.target)})),M),t=new Set;for(let r of e)t.add(`${r.source}::${r.target}`);K.current=t},[k,_.links,M]);if(s<10||i<10)return null;let H=S?e.find(e=>e.type===S):null;return(0,t.jsxs)("div",{className:"relative h-full w-full",children:[S&&(0,t.jsxs)("button",{type:"button",onClick:z,className:"absolute left-4 top-4 z-20 flex items-center gap-2 rounded-lg border border-[var(--sc-border)] bg-[var(--sc-bg-deep)]/90 px-3 py-1.5 text-xs text-[var(--sc-text-secondary)] backdrop-blur-sm transition-colors hover:border-[var(--sc-text-muted)] hover:text-[var(--sc-text-primary)]",children:[(0,t.jsx)("span",{children:"←"}),(0,t.jsx)("span",{children:"All clusters"})]}),H&&(0,t.jsxs)("div",{className:"absolute right-4 top-4 z-20 flex items-center gap-2 rounded-lg border border-[var(--sc-border)] bg-[var(--sc-bg-deep)]/90 px-3 py-1.5 backdrop-blur-sm",children:[(0,t.jsx)("span",{className:"h-2.5 w-2.5 rounded-full",style:{backgroundColor:H.colour}}),(0,t.jsx)("span",{className:"text-xs font-semibold text-[var(--sc-text-primary)]",children:H.type}),(0,t.jsxs)("span",{className:"text-xs text-[var(--sc-text-muted)]",children:[H.entities.length," entities"]})]}),(0,t.jsxs)("div",{onDoubleClick:G,style:{position:"relative"},children:[(0,t.jsx)(g,{ref:v,graphData:_,width:s,height:i,backgroundColor:"rgba(0,0,0,0)",nodeCanvasObjectMode:()=>"replace",nodeCanvasObject:q,nodePointerAreaPaint:(e,t,r)=>{let a;void 0!==e.x&&void 0!==e.y&&(a=e.isCluster?Math.min(15+3*Math.sqrt(e.entityCount||5),60):4+Math.min(.5*Math.log2((e.memoryCount||1)+1),3),r.beginPath(),r.arc(e.x,e.y,a,0,2*Math.PI),r.fillStyle=t,r.fill())},linkCanvasObjectMode:()=>"replace",linkCanvasObject:W,linkDirectionalParticles:e=>{let t="object"==typeof e.source?e.source.id:String(e.source),r="object"==typeof e.target?e.target.id:String(e.target);return 2*!!K.current.has(`${t}::${r}`)},linkDirectionalParticleWidth:1.2,linkDirectionalParticleSpeed:.005,onNodeClick:O,onNodeDragEnd:e=>L.handleNodeDragEnd(e),onNodeHover:U,onBackgroundClick:z,onZoom:B,onRenderFramePre:Y,d3AlphaDecay:.02,d3VelocityDecay:.3,cooldownTicks:300,warmupTicks:80,nodeRelSize:1,enableNodeDrag:!0,enableZoomInteraction:!0,onEngineStop:()=>{!D.current&&_.nodes.length&&(D.current=!0,v.current?.zoomToFit(400*!T,80))}}),(0,t.jsx)(h,{driver:k})]}),(0,t.jsxs)("div",{className:"absolute bottom-3 left-0 right-0 z-10 flex items-center justify-center gap-4 text-[11px] text-[var(--sc-text-muted)]",children:[(0,t.jsxs)("span",{children:[n.toLocaleString()," entities"]}),(0,t.jsx)("span",{className:"text-[var(--sc-border)]",children:"·"}),(0,t.jsxs)("span",{children:[l.toLocaleString()," connections"]}),(0,t.jsx)("span",{className:"text-[var(--sc-border)]",children:"·"}),(0,t.jsxs)("span",{children:[e.length," clusters"]}),H&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)("span",{className:"text-[var(--sc-border)]",children:"·"}),(0,t.jsxs)("span",{style:{color:H.colour},children:[H.entities.length," ",S," entities"]})]})]})]})}let v={tool:"cyan",concept:"coral",project:"amber",service:"cyan",person:"cyan"},C={architecture:"cyan",error:"coral",decision:"amber",learning:"cyan",preference:"muted"};function j({entity:e,relatedEntities:r,recentMemories:a,onNavigate:n}){return(0,t.jsxs)("div",{className:"flex flex-col gap-4 overflow-y-auto",children:[(0,t.jsx)(l.GlassCard,{className:"p-4",children:(0,t.jsxs)("div",{className:"flex items-start gap-3",children:[(0,t.jsx)("span",{className:"mt-1 h-3 w-3 shrink-0 rounded-full",style:{backgroundColor:"coral"===v[e.type]?"#ff4d4d":"amber"===v[e.type]?"#f59e0b":"#00e5cc"}}),(0,t.jsxs)("div",{className:"min-w-0",children:[(0,t.jsx)("h2",{className:"truncate text-lg font-semibold text-[var(--sc-text-primary)]",children:e.label}),(0,t.jsxs)("div",{className:"mt-1 flex items-center gap-2",children:[(0,t.jsx)(s.Badge,{variant:v[e.type]||"muted",children:e.type}),(0,t.jsxs)("span",{className:"text-xs text-[var(--sc-text-muted)]",children:[e.memoryCount," ",1===e.memoryCount?"memory":"memories"]})]})]})]})}),r.length>0&&(0,t.jsxs)("div",{children:[(0,t.jsx)("h3",{className:"mb-2 text-[11px] font-semibold uppercase tracking-wider text-[var(--sc-text-muted)]",children:"Related Entities"}),(0,t.jsx)(l.GlassCard,{className:"divide-y divide-[var(--sc-border)] p-0",children:r.map(e=>(0,t.jsxs)("button",{onClick:()=>n(e.id),className:"flex w-full items-center justify-between px-4 py-2.5 text-left transition-colors hover:bg-[var(--sc-surface-interactive)]",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 min-w-0",children:[(0,t.jsx)("span",{className:"h-2 w-2 shrink-0 rounded-full",style:{backgroundColor:"coral"===v[e.type]?"#ff4d4d":"amber"===v[e.type]?"#f59e0b":"#00e5cc"}}),(0,t.jsx)("span",{className:"truncate text-sm text-[var(--sc-text-primary)]",children:e.label})]}),(0,t.jsx)("span",{className:"shrink-0 text-xs tabular-nums text-[var(--sc-text-muted)]",children:e.memoryCount})]},e.id))})]}),a.length>0&&(0,t.jsxs)("div",{children:[(0,t.jsx)("h3",{className:"mb-2 text-[11px] font-semibold uppercase tracking-wider text-[var(--sc-text-muted)]",children:"Recent Memories"}),(0,t.jsx)("div",{className:"flex flex-col gap-2",children:a.slice(0,8).map(e=>(0,t.jsxs)(l.GlassCard,{className:"p-3",children:[(0,t.jsx)("p",{className:"truncate text-sm text-[var(--sc-text-primary)]",children:e.title}),(0,t.jsxs)("div",{className:"mt-1.5 flex items-center gap-2",children:[(0,t.jsx)(s.Badge,{variant:C[e.category]||"muted",className:"text-[10px]",children:e.category}),(0,t.jsx)("span",{className:"text-[10px] text-[var(--sc-text-muted)]",children:new Date(e.created_at).toLocaleDateString("en-GB",{day:"2-digit",month:"2-digit",year:"numeric"})})]})]},e.id))})]})]})}var k=e.i(45688),w=e.i(88969);let S=f.default.env.NEXT_PUBLIC_API_URL||"http://localhost:3001",N={tool:"#00e5cc",concept:"#ff4d4d",project:"#f59e0b",file:"#5a6480",service:"#a78bfa",person:"#34d399",language:"#a78bfa",pattern:"#fb923c"};function M(){var e,i;let[o,c]=(0,r.useState)(null),[d,u]=(0,r.useState)(""),[m,h]=(0,r.useState)(!1),f=function(e,t=300){let[a,n]=(0,r.useState)(e);return(0,r.useEffect)(()=>{let r=setTimeout(()=>{n(e)},t);return()=>{clearTimeout(r)}},[e,t]),a}(d,250),p=(0,r.useRef)(null),[y,g]=(0,r.useState)({width:600,height:500});(0,r.useEffect)(()=>{let e=p.current;if(!e)return;let t=new ResizeObserver(e=>{for(let t of e){let{width:e,height:r}=t.contentRect;g({width:Math.floor(e),height:Math.max(Math.floor(r),500)})}});return t.observe(e),()=>t.disconnect()},[]);let{data:x,isLoading:v}=(0,k.useQuery)({queryKey:["graph","full"],queryFn:async()=>{let[e,t]=await Promise.all([(0,w.authFetch)(`${S}/api/graph/entities?limit=2000`),(0,w.authFetch)(`${S}/api/graph/triples?limit=10000`)]);if(!e.ok||!t.ok)throw Error("Failed to fetch graph data");let[r,a]=await Promise.all([e.json(),t.json()]),n=(r.entities||[]).map(e=>({id:String(e.id),name:e.name,type:e.type,memoryCount:e.memoryCount??e.memory_count??0})),l=(a.triples||[]).map(e=>({source:String(e.subject_id),target:String(e.object_id),predicate:e.predicate})),s=new Map;for(let e of n){let t=s.get(e.type)||[];t.push(e),s.set(e.type,t)}return{entities:n,triples:l,clusters:Array.from(s.entries()).map(([e,t])=>({type:e,entities:t.sort((e,t)=>t.memoryCount-e.memoryCount),colour:N[e]||"#8892b0"})).sort((e,t)=>t.entities.length-e.entities.length),totalConnections:l.length}},staleTime:6e4}),{data:C}=(e=o?.id??null,(0,k.useQuery)({queryKey:["graph","neighbourhood",e],queryFn:async()=>{if(!e)return null;let t=await (0,w.authFetch)(`${S}/api/graph/entities/${e}/neighbourhood`);if(!t.ok)throw Error("Failed to fetch neighbourhood");let r=await t.json(),a={id:String(r.focal.id),name:r.focal.name,type:r.focal.type,memoryCount:r.focal.memoryCount,isFocal:!0},n=new Map;for(let e of(n.set(a.id,a),r.neighbours))n.set(String(e.id),{id:String(e.id),name:e.name,type:e.type,memoryCount:e.memoryCount});let l=r.triples.map(e=>({source:String(e.subject_id),target:String(e.object_id),predicate:e.predicate}));return{nodes:Array.from(n.values()),links:l,focal:a,totalConnections:r.totalConnections}},enabled:null!==e,staleTime:15e3})),{data:M}=(i=o?.id??null,(0,k.useQuery)({queryKey:["graph","memories",i],queryFn:async()=>{if(!i)return[];let e=await (0,w.authFetch)(`${S}/api/graph/entities/${i}/memories`);if(!e.ok)throw Error("Failed to fetch memories");return(await e.json()).memories||[]},enabled:null!==i,staleTime:15e3})),{data:E}=(0,k.useQuery)({queryKey:["graph","search",f],queryFn:async()=>{let e=await (0,w.authFetch)(`${S}/api/graph/search?q=${encodeURIComponent(f)}&limit=8`);if(!e.ok)throw Error("Search failed");return((await e.json()).entities||[]).map(e=>({id:String(e.id),name:e.name,type:e.type,memoryCount:e.memoryCount}))},enabled:f.trim().length>0,staleTime:1e4}),I=(0,r.useCallback)(e=>{c(e)},[]),P=(0,r.useCallback)(e=>{let t=x?.entities.find(t=>t.id===e);t&&c(t)},[x]),T=(0,r.useCallback)(e=>{let t=x?.entities.find(t=>t.id===e);t&&c(t),u(""),h(!1)},[x]),R=(0,r.useMemo)(()=>C?C.nodes.filter(e=>!e.isFocal).sort((e,t)=>t.memoryCount-e.memoryCount).slice(0,15).map(e=>({id:e.id,label:e.name,type:e.type,memoryCount:e.memoryCount})):[],[C]),A=o?{id:o.id,label:o.name,type:o.type,memoryCount:o.memoryCount}:null,F=null!==o;return(0,t.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,t.jsx)("div",{className:"flex items-center gap-3",children:(0,t.jsxs)("div",{className:"relative flex-1",children:[(0,t.jsx)(a.Search,{className:"absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[var(--sc-text-muted)]"}),(0,t.jsx)("input",{type:"text",value:d,onChange:e=>{u(e.target.value),h(!0)},onFocus:()=>d.trim()&&h(!0),placeholder:"Search entities...",className:"glass-card w-full py-2.5 pl-10 pr-10 text-sm text-[var(--sc-text-primary)] placeholder:text-[var(--sc-text-muted)] focus:outline-none focus:ring-1 focus:ring-[var(--sc-cyan)]/40"}),d&&(0,t.jsx)("button",{type:"button",onClick:()=>{u(""),h(!1)},className:"absolute right-3 top-1/2 -translate-y-1/2 text-[var(--sc-text-muted)] hover:text-[var(--sc-text-primary)]",children:(0,t.jsx)(n.X,{className:"h-4 w-4"})}),m&&E&&E.length>0&&(0,t.jsx)("div",{className:"absolute left-0 right-0 top-full z-50 mt-1 glass-card-strong overflow-hidden py-1",children:E.map(e=>(0,t.jsxs)("button",{type:"button",onClick:()=>T(e.id),className:"flex w-full items-center justify-between px-4 py-2 text-left transition-colors hover:bg-[var(--sc-surface-interactive)]",children:[(0,t.jsx)("span",{className:"truncate text-sm text-[var(--sc-text-primary)]",children:e.name}),(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)(s.Badge,{variant:"muted",className:"text-[10px]",children:e.type}),(0,t.jsx)("span",{className:"text-xs tabular-nums text-[var(--sc-text-muted)]",children:e.memoryCount})]})]},e.id))})]})}),(0,t.jsxs)("div",{className:`grid gap-4 ${F?"grid-cols-1 md:grid-cols-[1fr_340px]":"grid-cols-1"}`,children:[(0,t.jsxs)(l.GlassCard,{className:"relative min-h-[500px] overflow-hidden border-0 p-0",children:[v&&(0,t.jsx)("div",{className:"absolute inset-0 z-10 flex items-center justify-center bg-[var(--sc-bg-deep)]/60",children:(0,t.jsx)("div",{className:"h-6 w-6 animate-spin rounded-full border-2 border-[var(--sc-cyan)] border-t-transparent"})}),(0,t.jsx)("div",{ref:p,className:"h-full w-full",style:{minHeight:500},children:x&&(0,t.jsx)(b,{clusters:x.clusters,allTriples:x.triples,totalEntities:x.entities.length,totalConnections:x.totalConnections,width:y.width,height:y.height,onSelectEntity:I,selectedEntityId:o?.id})})]}),F&&A&&(0,t.jsx)("div",{className:"min-h-[500px]",children:(0,t.jsx)(j,{entity:A,relatedEntities:R,recentMemories:M??[],onNavigate:P})})]})]})}e.s(["default",()=>M],68595)},13213,e=>{e.n(e.i(68595))},23531,e=>{e.v(t=>Promise.all(["static/chunks/364656baa57adaa7.js"].map(t=>e.l(t))).then(()=>t(23272)))}]);
|