shieldcortex 4.12.14 → 4.13.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.
Files changed (386) hide show
  1. package/dashboard/.next/standalone/dashboard/.next/BUILD_ID +1 -1
  2. package/dashboard/.next/standalone/dashboard/.next/build-manifest.json +2 -2
  3. package/dashboard/.next/standalone/dashboard/.next/prerender-manifest.json +3 -3
  4. package/dashboard/.next/standalone/dashboard/.next/required-server-files.json +4 -4
  5. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/admin/page.js +1 -1
  6. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/admin/page.js.nft.json +1 -1
  7. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/admin/page_client-reference-manifest.js +1 -1
  8. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/cloud/page.js +1 -1
  9. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/cloud/page.js.nft.json +1 -1
  10. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/cloud/page_client-reference-manifest.js +1 -1
  11. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/capture/page.js +1 -1
  12. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/capture/page.js.nft.json +1 -1
  13. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/capture/page_client-reference-manifest.js +1 -1
  14. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/graph/page.js +1 -1
  15. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/graph/page.js.nft.json +1 -1
  16. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/graph/page_client-reference-manifest.js +1 -1
  17. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/page.js +1 -1
  18. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/page.js.nft.json +1 -1
  19. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/page_client-reference-manifest.js +1 -1
  20. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/recall/page.js +1 -1
  21. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/recall/page.js.nft.json +1 -1
  22. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/recall/page_client-reference-manifest.js +1 -1
  23. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/review/page.js +1 -1
  24. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/review/page.js.nft.json +1 -1
  25. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/review/page_client-reference-manifest.js +1 -1
  26. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/timeline/page.js +1 -1
  27. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/timeline/page.js.nft.json +1 -1
  28. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/memory/timeline/page_client-reference-manifest.js +1 -1
  29. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/overview/page.js +1 -1
  30. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/overview/page.js.nft.json +1 -1
  31. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/overview/page_client-reference-manifest.js +1 -1
  32. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/audit/page.js +1 -1
  33. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/audit/page.js.nft.json +1 -1
  34. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/audit/page_client-reference-manifest.js +1 -1
  35. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/intercepts/page.js +1 -1
  36. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/intercepts/page.js.nft.json +1 -1
  37. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/intercepts/page_client-reference-manifest.js +1 -1
  38. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/iron-dome/page.js +1 -1
  39. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/iron-dome/page.js.nft.json +1 -1
  40. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/iron-dome/page_client-reference-manifest.js +1 -1
  41. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/page.js +1 -1
  42. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/page.js.nft.json +1 -1
  43. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/page_client-reference-manifest.js +1 -1
  44. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/policies/page.js +1 -1
  45. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/policies/page.js.nft.json +1 -1
  46. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/policies/page_client-reference-manifest.js +1 -1
  47. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/quarantine/page.js +1 -1
  48. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/quarantine/page.js.nft.json +1 -1
  49. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/protection/quarantine/page_client-reference-manifest.js +1 -1
  50. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/settings/page.js +1 -1
  51. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/settings/page.js.nft.json +1 -1
  52. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/settings/page_client-reference-manifest.js +1 -1
  53. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/supply-chain/page.js +1 -1
  54. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/supply-chain/page.js.nft.json +1 -1
  55. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/supply-chain/page_client-reference-manifest.js +1 -1
  56. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/supply-chain/xray/page.js +1 -1
  57. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/supply-chain/xray/page.js.nft.json +1 -1
  58. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/supply-chain/xray/page_client-reference-manifest.js +1 -1
  59. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/xray/page.js +1 -1
  60. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/xray/page.js.nft.json +1 -1
  61. package/dashboard/.next/standalone/dashboard/.next/server/app/(dashboard)/xray/page_client-reference-manifest.js +1 -1
  62. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error/page.js.nft.json +1 -1
  63. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  64. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.html +2 -2
  65. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
  66. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  67. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  68. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  69. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  70. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  71. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found/page.js.nft.json +1 -1
  72. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  73. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +1 -1
  74. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +2 -2
  75. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  76. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  77. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  78. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  79. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  80. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  81. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.html +1 -1
  82. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.rsc +17 -15
  83. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin/__PAGE__.segment.rsc +1 -1
  84. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin.segment.rsc +1 -1
  85. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  86. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_full.segment.rsc +17 -15
  87. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_head.segment.rsc +1 -1
  88. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_index.segment.rsc +2 -2
  89. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_tree.segment.rsc +2 -2
  90. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.html +1 -1
  91. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.rsc +17 -15
  92. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud/__PAGE__.segment.rsc +1 -1
  93. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud.segment.rsc +1 -1
  94. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  95. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_full.segment.rsc +17 -15
  96. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_head.segment.rsc +1 -1
  97. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_index.segment.rsc +2 -2
  98. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_tree.segment.rsc +2 -2
  99. package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
  100. package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +2 -2
  101. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  102. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +2 -2
  103. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
  104. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +2 -2
  105. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  106. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.html +1 -1
  107. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.rsc +17 -15
  108. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture/__PAGE__.segment.rsc +1 -1
  109. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture.segment.rsc +1 -1
  110. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  111. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  112. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_full.segment.rsc +17 -15
  113. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_head.segment.rsc +1 -1
  114. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_index.segment.rsc +2 -2
  115. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_tree.segment.rsc +2 -2
  116. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.html +1 -1
  117. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.rsc +17 -15
  118. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph/__PAGE__.segment.rsc +1 -1
  119. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph.segment.rsc +1 -1
  120. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  121. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  122. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_full.segment.rsc +17 -15
  123. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_head.segment.rsc +1 -1
  124. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_index.segment.rsc +2 -2
  125. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_tree.segment.rsc +2 -2
  126. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.html +1 -1
  127. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.rsc +17 -15
  128. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall/__PAGE__.segment.rsc +1 -1
  129. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall.segment.rsc +1 -1
  130. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  131. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  132. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_full.segment.rsc +17 -15
  133. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_head.segment.rsc +1 -1
  134. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_index.segment.rsc +2 -2
  135. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_tree.segment.rsc +2 -2
  136. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.html +1 -1
  137. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.rsc +17 -15
  138. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review/__PAGE__.segment.rsc +1 -1
  139. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review.segment.rsc +1 -1
  140. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  141. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  142. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_full.segment.rsc +17 -15
  143. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_head.segment.rsc +1 -1
  144. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_index.segment.rsc +2 -2
  145. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_tree.segment.rsc +2 -2
  146. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.html +1 -1
  147. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.rsc +17 -15
  148. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline/__PAGE__.segment.rsc +1 -1
  149. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline.segment.rsc +1 -1
  150. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  151. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  152. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_full.segment.rsc +17 -15
  153. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_head.segment.rsc +1 -1
  154. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_index.segment.rsc +2 -2
  155. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_tree.segment.rsc +2 -2
  156. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.html +1 -1
  157. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.rsc +21 -18
  158. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory/__PAGE__.segment.rsc +2 -2
  159. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  160. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  161. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_full.segment.rsc +21 -18
  162. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_head.segment.rsc +1 -1
  163. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_index.segment.rsc +2 -2
  164. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_tree.segment.rsc +2 -2
  165. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.html +1 -1
  166. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.rsc +20 -18
  167. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview/__PAGE__.segment.rsc +2 -2
  168. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview.segment.rsc +1 -1
  169. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  170. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_full.segment.rsc +20 -18
  171. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_head.segment.rsc +1 -1
  172. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_index.segment.rsc +2 -2
  173. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_tree.segment.rsc +2 -2
  174. package/dashboard/.next/standalone/dashboard/.next/server/app/page.js.nft.json +1 -1
  175. package/dashboard/.next/standalone/dashboard/.next/server/app/page_client-reference-manifest.js +1 -1
  176. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.html +1 -1
  177. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.rsc +17 -15
  178. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit/__PAGE__.segment.rsc +1 -1
  179. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit.segment.rsc +1 -1
  180. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  181. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  182. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_full.segment.rsc +17 -15
  183. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_head.segment.rsc +1 -1
  184. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_index.segment.rsc +2 -2
  185. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_tree.segment.rsc +2 -2
  186. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.html +1 -1
  187. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.rsc +17 -15
  188. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts/__PAGE__.segment.rsc +1 -1
  189. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts.segment.rsc +1 -1
  190. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  191. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  192. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_full.segment.rsc +17 -15
  193. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_head.segment.rsc +1 -1
  194. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_index.segment.rsc +2 -2
  195. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_tree.segment.rsc +2 -2
  196. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.html +1 -1
  197. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.rsc +17 -15
  198. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome/__PAGE__.segment.rsc +1 -1
  199. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome.segment.rsc +1 -1
  200. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  201. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  202. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_full.segment.rsc +17 -15
  203. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_head.segment.rsc +1 -1
  204. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_index.segment.rsc +2 -2
  205. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_tree.segment.rsc +2 -2
  206. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.html +1 -1
  207. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.rsc +17 -15
  208. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies/__PAGE__.segment.rsc +1 -1
  209. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies.segment.rsc +1 -1
  210. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  211. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  212. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_full.segment.rsc +17 -15
  213. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_head.segment.rsc +1 -1
  214. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_index.segment.rsc +2 -2
  215. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_tree.segment.rsc +2 -2
  216. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.html +1 -1
  217. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.rsc +17 -15
  218. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine/__PAGE__.segment.rsc +1 -1
  219. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine.segment.rsc +1 -1
  220. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  221. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  222. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_full.segment.rsc +17 -15
  223. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_head.segment.rsc +1 -1
  224. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_index.segment.rsc +2 -2
  225. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_tree.segment.rsc +2 -2
  226. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.html +1 -1
  227. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.rsc +17 -15
  228. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection/__PAGE__.segment.rsc +2 -2
  229. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  230. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  231. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_full.segment.rsc +17 -15
  232. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_head.segment.rsc +1 -1
  233. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_index.segment.rsc +2 -2
  234. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_tree.segment.rsc +2 -2
  235. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.html +1 -1
  236. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.rsc +17 -15
  237. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings/__PAGE__.segment.rsc +2 -2
  238. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings.segment.rsc +1 -1
  239. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  240. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_full.segment.rsc +17 -15
  241. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  242. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_index.segment.rsc +2 -2
  243. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  244. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.html +1 -1
  245. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.rsc +17 -15
  246. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray/__PAGE__.segment.rsc +1 -1
  247. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray.segment.rsc +1 -1
  248. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
  249. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  250. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_full.segment.rsc +17 -15
  251. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_head.segment.rsc +1 -1
  252. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_index.segment.rsc +2 -2
  253. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_tree.segment.rsc +2 -2
  254. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.html +1 -1
  255. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.rsc +17 -15
  256. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain/__PAGE__.segment.rsc +1 -1
  257. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
  258. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  259. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_full.segment.rsc +17 -15
  260. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_head.segment.rsc +1 -1
  261. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_index.segment.rsc +2 -2
  262. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_tree.segment.rsc +2 -2
  263. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.html +1 -1
  264. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.rsc +17 -15
  265. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray/__PAGE__.segment.rsc +2 -2
  266. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray.segment.rsc +1 -1
  267. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +9 -7
  268. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_full.segment.rsc +17 -15
  269. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_head.segment.rsc +1 -1
  270. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_index.segment.rsc +2 -2
  271. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_tree.segment.rsc +2 -2
  272. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/9f1d4_@tanstack_68dcbde9._.js +3 -0
  273. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/{[root-of-the-server]__fb5796ae._.js → [root-of-the-server]__2de25d56._.js} +2 -2
  274. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/[root-of-the-server]__52bd7a9f._.js +3 -0
  275. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/{[root-of-the-server]__b789489c._.js → [root-of-the-server]__6f881a23._.js} +2 -2
  276. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_01f6ceb0._.js +1 -1
  277. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_20c6acea._.js +3 -0
  278. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/{9f1d4_next_c9fe89e1._.js → dashboard_25b568c3._.js} +2 -2
  279. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_2a8eef6b._.js +3 -0
  280. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_35a9932a._.js +1 -1
  281. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_37f17371._.js +1 -1
  282. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_77cb2b63._.js +3 -0
  283. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_91003e6d._.js +3 -0
  284. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_9b8695d8._.js +3 -0
  285. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_a16ef10a._.js +3 -0
  286. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_c219bf07._.js +4 -4
  287. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_f9cd1dc2._.js +3 -0
  288. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_fefd3b85._.js +1 -1
  289. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_src_44a9f72c._.js +3 -0
  290. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_src_components_de7ac4f9._.js +3 -0
  291. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_src_components_protection_ProtectionOverview_tsx_54554a97._.js +3 -3
  292. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_src_components_settings_SettingsView_tsx_16dc83a7._.js +1 -1
  293. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_src_components_xray_XRayOverview_tsx_ceba698e._.js +1 -1
  294. package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +1 -1
  295. package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
  296. package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.js +1 -1
  297. package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.json +1 -1
  298. package/dashboard/.next/standalone/dashboard/.next/static/chunks/015dc64369f26b7d.css +3 -0
  299. package/dashboard/.next/standalone/dashboard/.next/static/chunks/2fe84829530e61a3.js +1 -0
  300. package/dashboard/.next/standalone/dashboard/.next/static/chunks/34d0309a4e34b084.js +1 -0
  301. package/dashboard/.next/standalone/dashboard/.next/static/chunks/3729c748a4361c1f.js +1 -0
  302. package/dashboard/.next/standalone/dashboard/.next/static/chunks/3b7fdf1ee828254c.js +1 -0
  303. package/dashboard/.next/standalone/dashboard/.next/static/chunks/{3d53807a9a943ce7.js → 4c90ebd2c08cd656.js} +4 -4
  304. package/dashboard/.next/standalone/dashboard/.next/static/chunks/4d4af0cecaef56f2.js +1 -0
  305. package/dashboard/.next/standalone/dashboard/.next/static/chunks/4eb86dc2f379d3ca.js +1 -0
  306. package/dashboard/.next/standalone/dashboard/.next/static/chunks/6aba18b7aac42ccd.js +1 -0
  307. package/dashboard/.next/standalone/dashboard/.next/static/chunks/{b4b3fb5729bead7e.js → 6ea97c8dc9e30ea5.js} +1 -1
  308. package/dashboard/.next/standalone/dashboard/.next/static/chunks/74ea1a87751e93a3.js +1 -0
  309. package/dashboard/.next/standalone/dashboard/.next/static/chunks/910628c23329a773.js +1 -0
  310. package/dashboard/.next/standalone/dashboard/.next/static/chunks/{c288964c4c00982a.js → b308a787e8cbc2a9.js} +3 -3
  311. package/dashboard/.next/standalone/dashboard/.next/static/chunks/bdb50889a1c1ab37.js +1 -0
  312. package/dashboard/.next/standalone/dashboard/.next/static/chunks/d0bf5ccba09917dd.js +1 -0
  313. package/dashboard/.next/standalone/dashboard/.next/static/chunks/e804a1fda2839550.js +1 -0
  314. package/dashboard/.next/standalone/dashboard/server.js +1 -1
  315. package/dist/api/routes/digest.d.ts +59 -0
  316. package/dist/api/routes/digest.js +305 -0
  317. package/dist/api/routes/memories.js +84 -15
  318. package/dist/api/routes/system.js +10 -2
  319. package/dist/api/visualization-server.js +2 -0
  320. package/dist/cli/doctor.d.ts +27 -0
  321. package/dist/cli/doctor.js +88 -0
  322. package/dist/cli/migrate-legacy.d.ts +28 -0
  323. package/dist/cli/migrate-legacy.js +291 -0
  324. package/dist/cloud/cli.js +2 -2
  325. package/dist/database/init.js +26 -1
  326. package/dist/index.js +8 -1
  327. package/dist/memory/backup.d.ts +19 -0
  328. package/dist/memory/backup.js +47 -0
  329. package/dist/memory/dedupe-runner.d.ts +33 -0
  330. package/dist/memory/dedupe-runner.js +103 -0
  331. package/dist/memory/fts.d.ts +26 -0
  332. package/dist/memory/fts.js +59 -0
  333. package/dist/memory/lifecycle.d.ts +83 -0
  334. package/dist/memory/lifecycle.js +274 -0
  335. package/dist/memory/links.d.ts +63 -0
  336. package/dist/memory/links.js +232 -0
  337. package/dist/memory/prune.d.ts +34 -0
  338. package/dist/memory/prune.js +76 -0
  339. package/dist/memory/search-recall.d.ts +48 -0
  340. package/dist/memory/search-recall.js +367 -0
  341. package/dist/memory/store.d.ts +6 -121
  342. package/dist/memory/store.js +45 -854
  343. package/dist/setup/claude-md.d.ts +1 -0
  344. package/dist/setup/deep-clean.d.ts +33 -0
  345. package/dist/setup/deep-clean.js +26 -0
  346. package/dist/setup/doctor.js +7 -2
  347. package/dist/setup/settings-hooks.d.ts +1 -0
  348. package/dist/setup/settings-hooks.js +30 -5
  349. package/dist/setup/status.js +39 -0
  350. package/hooks/openclaw/cortex-memory/runtime.mjs +18 -4
  351. package/package.json +1 -1
  352. package/plugins/openclaw/dist/index.js +12 -6
  353. package/plugins/openclaw/dist/openclaw.plugin.json +1 -1
  354. package/scripts/lib/auto-memory-config.mjs +45 -0
  355. package/scripts/lib/telemetry.mjs +58 -0
  356. package/scripts/lib/transcript-reader.mjs +123 -0
  357. package/scripts/postinstall.mjs +47 -1
  358. package/scripts/pre-compact-hook.mjs +76 -124
  359. package/scripts/session-end-hook.mjs +102 -97
  360. package/scripts/stop-hook.mjs +346 -116
  361. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/9f1d4_@tanstack_785e068c._.js +0 -3
  362. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/[root-of-the-server]__c2b92077._.js +0 -3
  363. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_11878109._.js +0 -3
  364. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_35c9f22e._.js +0 -3
  365. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_836b4a04._.js +0 -3
  366. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_9770c429._.js +0 -3
  367. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_9dd626ed._.js +0 -3
  368. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_e94d2da2._.js +0 -3
  369. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_src_564ea5ae._.js +0 -3
  370. package/dashboard/.next/standalone/dashboard/.next/server/chunks/ssr/dashboard_src_lib_3f1490a1._.js +0 -3
  371. package/dashboard/.next/standalone/dashboard/.next/static/chunks/079a5be036130e37.js +0 -1
  372. package/dashboard/.next/standalone/dashboard/.next/static/chunks/1770a8ce7abb2437.js +0 -1
  373. package/dashboard/.next/standalone/dashboard/.next/static/chunks/1a074f8ddc7cd385.js +0 -1
  374. package/dashboard/.next/standalone/dashboard/.next/static/chunks/24da99d1341bd573.css +0 -3
  375. package/dashboard/.next/standalone/dashboard/.next/static/chunks/2aa8afb655c1c2e5.js +0 -1
  376. package/dashboard/.next/standalone/dashboard/.next/static/chunks/302ad459a0e5c4ba.js +0 -1
  377. package/dashboard/.next/standalone/dashboard/.next/static/chunks/385ec610bad1acc5.js +0 -1
  378. package/dashboard/.next/standalone/dashboard/.next/static/chunks/4f57582c2d186438.js +0 -1
  379. package/dashboard/.next/standalone/dashboard/.next/static/chunks/52843253e4b833a5.js +0 -1
  380. package/dashboard/.next/standalone/dashboard/.next/static/chunks/7fca141efba9d353.js +0 -1
  381. package/dashboard/.next/standalone/dashboard/.next/static/chunks/8593e1796c9d043d.js +0 -1
  382. package/dashboard/.next/standalone/dashboard/.next/static/chunks/cbc2e6ffcad6e91c.js +0 -1
  383. package/dashboard/.next/standalone/dashboard/.next/static/chunks/fced7dd3c9874ed1.js +0 -1
  384. /package/dashboard/.next/standalone/dashboard/.next/static/{P2sW3M-qHaW9VS9YwCEg3 → kiA_iEHG_1wWOEYFsD0Tj}/_buildManifest.js +0 -0
  385. /package/dashboard/.next/standalone/dashboard/.next/static/{P2sW3M-qHaW9VS9YwCEg3 → kiA_iEHG_1wWOEYFsD0Tj}/_clientMiddlewareManifest.json +0 -0
  386. /package/dashboard/.next/standalone/dashboard/.next/static/{P2sW3M-qHaW9VS9YwCEg3 → kiA_iEHG_1wWOEYFsD0Tj}/_ssgManifest.js +0 -0
@@ -0,0 +1,305 @@
1
+ import { getDatabase, isDatabaseInitialized } from '../../database/init.js';
2
+ const WINDOW_HOURS = {
3
+ '24h': 24,
4
+ '7d': 168,
5
+ '30d': 720,
6
+ };
7
+ const HIGH_SALIENCE_THRESHOLD = 0.6;
8
+ function isoSinceHoursAgo(hours) {
9
+ return new Date(Date.now() - hours * 3600_000).toISOString();
10
+ }
11
+ function safeCount(rows, key) {
12
+ if (!rows.length)
13
+ return 0;
14
+ const v = rows[0][key];
15
+ return typeof v === 'number' ? v : Number(v ?? 0);
16
+ }
17
+ function getCountsBetween(sinceIso, untilIso, project) {
18
+ const db = getDatabase();
19
+ const projectAudit = project ? 'AND da.project = @project' : '';
20
+ const projectMem = project ? 'AND m.project = @project' : '';
21
+ const upperBound = untilIso ? 'AND da.timestamp < @until' : '';
22
+ const upperBoundMem = untilIso ? 'AND m.created_at < @until' : '';
23
+ const upperBoundRecall = untilIso ? 'AND m.last_accessed < @until' : '';
24
+ const params = { since: sinceIso };
25
+ if (project)
26
+ params.project = project;
27
+ if (untilIso)
28
+ params.until = untilIso;
29
+ // Defence audit counts (single grouped query)
30
+ const auditRows = db.prepare(`
31
+ SELECT da.firewall_result AS result, COUNT(*) AS cnt
32
+ FROM defence_audit da
33
+ WHERE da.timestamp >= @since ${upperBound} ${projectAudit}
34
+ GROUP BY da.firewall_result
35
+ `).all(params);
36
+ let allowed = 0, blocked = 0, quarantined = 0;
37
+ for (const row of auditRows) {
38
+ if (row.result === 'ALLOW')
39
+ allowed = row.cnt;
40
+ else if (row.result === 'BLOCK')
41
+ blocked = row.cnt;
42
+ else if (row.result === 'QUARANTINE')
43
+ quarantined = row.cnt;
44
+ }
45
+ const scanned = allowed + blocked + quarantined;
46
+ // Memories captured in window
47
+ const memCapturedRows = db.prepare(`
48
+ SELECT COUNT(*) AS cnt FROM memories m
49
+ WHERE m.created_at >= @since ${upperBoundMem} ${projectMem}
50
+ `).all(params);
51
+ const memoriesCaptured = safeCount(memCapturedRows, 'cnt');
52
+ // High-salience captures (salience >= threshold)
53
+ const highSalRows = db.prepare(`
54
+ SELECT COUNT(*) AS cnt FROM memories m
55
+ WHERE m.created_at >= @since ${upperBoundMem} AND m.salience >= ${HIGH_SALIENCE_THRESHOLD} ${projectMem}
56
+ `).all(params);
57
+ const highSalienceCaptures = safeCount(highSalRows, 'cnt');
58
+ // Memories recalled (last_accessed advanced past created_at within window)
59
+ const recalledRows = db.prepare(`
60
+ SELECT COUNT(*) AS cnt FROM memories m
61
+ WHERE m.last_accessed >= @since ${upperBoundRecall}
62
+ AND m.last_accessed > m.created_at
63
+ ${projectMem}
64
+ `).all(params);
65
+ const memoriesRecalled = safeCount(recalledRows, 'cnt');
66
+ return {
67
+ scanned,
68
+ allowed,
69
+ blocked,
70
+ quarantined,
71
+ memoriesCaptured,
72
+ memoriesRecalled,
73
+ highSalienceCaptures,
74
+ };
75
+ }
76
+ function getTopMoments(sinceIso, project, limit = 5) {
77
+ const db = getDatabase();
78
+ const projectAudit = project ? 'AND da.project = ?' : '';
79
+ const projectMem = project ? 'AND m.project = ?' : '';
80
+ const moments = [];
81
+ // Top blocks/quarantines (most severe firewall actions)
82
+ const auditParams = project ? [sinceIso, project] : [sinceIso];
83
+ const blocks = db.prepare(`
84
+ SELECT da.id, da.timestamp, da.firewall_result, da.reason, da.source_type, da.source_identifier,
85
+ da.threat_indicators, da.anomaly_score
86
+ FROM defence_audit da
87
+ WHERE da.timestamp >= ? ${projectAudit}
88
+ AND da.firewall_result IN ('BLOCK', 'QUARANTINE')
89
+ ORDER BY da.anomaly_score DESC, da.timestamp DESC
90
+ LIMIT 3
91
+ `).all(...auditParams);
92
+ for (const b of blocks) {
93
+ let indicators = [];
94
+ try {
95
+ indicators = b.threat_indicators ? JSON.parse(b.threat_indicators) : [];
96
+ }
97
+ catch { /* ignore */ }
98
+ const top = indicators.slice(0, 2).join(', ');
99
+ moments.push({
100
+ kind: b.firewall_result === 'BLOCK' ? 'block' : 'quarantine',
101
+ title: b.firewall_result === 'BLOCK'
102
+ ? `Blocked ${top || b.reason || 'a suspicious payload'}`
103
+ : `Quarantined ${top || b.reason || 'a suspicious memory'}`,
104
+ detail: `${b.source_type}: ${b.source_identifier}`,
105
+ timestamp: b.timestamp,
106
+ auditId: b.id,
107
+ });
108
+ }
109
+ // Top high-salience captures
110
+ const memParams = project ? [sinceIso, project] : [sinceIso];
111
+ const captures = db.prepare(`
112
+ SELECT m.id, m.title, m.salience, m.category, m.created_at, m.project
113
+ FROM memories m
114
+ WHERE m.created_at >= ? ${projectMem}
115
+ AND m.salience >= ${HIGH_SALIENCE_THRESHOLD}
116
+ ORDER BY m.salience DESC, m.created_at DESC
117
+ LIMIT 3
118
+ `).all(...memParams);
119
+ for (const m of captures) {
120
+ moments.push({
121
+ kind: 'capture',
122
+ title: `Captured: ${m.title}`,
123
+ detail: `${m.category} · salience ${m.salience.toFixed(2)}${m.project ? ` · ${m.project}` : ''}`,
124
+ timestamp: m.created_at,
125
+ memoryId: m.id,
126
+ });
127
+ }
128
+ // Top recalls in window (high access count + recently accessed)
129
+ const recalls = db.prepare(`
130
+ SELECT m.id, m.title, m.access_count, m.last_accessed, m.salience
131
+ FROM memories m
132
+ WHERE m.last_accessed >= ? ${projectMem}
133
+ AND m.last_accessed > m.created_at
134
+ ORDER BY m.access_count DESC, m.last_accessed DESC
135
+ LIMIT 2
136
+ `).all(...memParams);
137
+ for (const r of recalls) {
138
+ moments.push({
139
+ kind: 'recall',
140
+ title: `Recalled: ${r.title}`,
141
+ detail: `accessed ${r.access_count}× · salience ${r.salience.toFixed(2)}`,
142
+ timestamp: r.last_accessed,
143
+ memoryId: r.id,
144
+ });
145
+ }
146
+ return moments
147
+ .sort((a, b) => b.timestamp.localeCompare(a.timestamp))
148
+ .slice(0, limit);
149
+ }
150
+ function getTopThreatPatterns(sinceIso, project) {
151
+ const db = getDatabase();
152
+ const projectCond = project ? 'AND da.project = ?' : '';
153
+ const params = project ? [sinceIso, project] : [sinceIso];
154
+ const rows = db.prepare(`
155
+ SELECT da.threat_indicators
156
+ FROM defence_audit da
157
+ WHERE da.timestamp >= ? ${projectCond}
158
+ AND da.threat_indicators IS NOT NULL
159
+ AND da.threat_indicators != '[]'
160
+ LIMIT 500
161
+ `).all(...params);
162
+ const counts = {};
163
+ for (const r of rows) {
164
+ try {
165
+ const list = JSON.parse(r.threat_indicators);
166
+ for (const p of list)
167
+ counts[p] = (counts[p] ?? 0) + 1;
168
+ }
169
+ catch { /* ignore */ }
170
+ }
171
+ return Object.entries(counts)
172
+ .map(([pattern, count]) => ({ pattern, count }))
173
+ .sort((a, b) => b.count - a.count)
174
+ .slice(0, 5);
175
+ }
176
+ function buildDeltas(current, previous) {
177
+ const delta = {};
178
+ for (const key of Object.keys(current)) {
179
+ delta[key] = current[key] - previous[key];
180
+ }
181
+ return delta;
182
+ }
183
+ function windowLabelFor(window) {
184
+ switch (window) {
185
+ case '24h': return 'Last 24 hours';
186
+ case '7d': return 'Last 7 days';
187
+ case '30d': return 'Last 30 days';
188
+ }
189
+ }
190
+ export function buildDigest(window, project) {
191
+ const hours = WINDOW_HOURS[window];
192
+ const since = isoSinceHoursAgo(hours);
193
+ const previousSince = isoSinceHoursAgo(hours * 2);
194
+ const current = getCountsBetween(since, null, project);
195
+ const previous = getCountsBetween(previousSince, since, project);
196
+ return {
197
+ window,
198
+ windowLabel: windowLabelFor(window),
199
+ since,
200
+ current,
201
+ previous,
202
+ delta: buildDeltas(current, previous),
203
+ topMoments: getTopMoments(since, project, 5),
204
+ topThreatPatterns: getTopThreatPatterns(since, project),
205
+ generatedAt: new Date().toISOString(),
206
+ };
207
+ }
208
+ /**
209
+ * Returns one row per day for the last `days` days, oldest first.
210
+ * Days with zero activity are still included (gives a clean sparkline shape).
211
+ */
212
+ export function buildTimeline(days, project) {
213
+ const db = getDatabase();
214
+ const projectAudit = project ? 'AND da.project = @project' : '';
215
+ const projectMem = project ? 'AND m.project = @project' : '';
216
+ const since = isoSinceHoursAgo(days * 24);
217
+ const params = { since };
218
+ if (project)
219
+ params.project = project;
220
+ // Audit counts grouped by day (UTC)
221
+ const auditRows = db.prepare(`
222
+ SELECT substr(da.timestamp, 1, 10) AS day, da.firewall_result AS result, COUNT(*) AS cnt
223
+ FROM defence_audit da
224
+ WHERE da.timestamp >= @since ${projectAudit}
225
+ GROUP BY day, da.firewall_result
226
+ `).all(params);
227
+ const captureRows = db.prepare(`
228
+ SELECT substr(m.created_at, 1, 10) AS day, COUNT(*) AS cnt
229
+ FROM memories m
230
+ WHERE m.created_at >= @since ${projectMem}
231
+ GROUP BY day
232
+ `).all(params);
233
+ const recallRows = db.prepare(`
234
+ SELECT substr(m.last_accessed, 1, 10) AS day, COUNT(*) AS cnt
235
+ FROM memories m
236
+ WHERE m.last_accessed >= @since
237
+ AND m.last_accessed > m.created_at
238
+ ${projectMem}
239
+ GROUP BY day
240
+ `).all(params);
241
+ // Build a complete day map with zero defaults
242
+ const byDay = {};
243
+ const today = new Date();
244
+ for (let i = days - 1; i >= 0; i--) {
245
+ const d = new Date(today);
246
+ d.setUTCDate(d.getUTCDate() - i);
247
+ const key = d.toISOString().slice(0, 10);
248
+ byDay[key] = { date: key, scanned: 0, blocked: 0, quarantined: 0, captured: 0, recalled: 0 };
249
+ }
250
+ for (const row of auditRows) {
251
+ const day = byDay[row.day];
252
+ if (!day)
253
+ continue;
254
+ if (row.result === 'BLOCK')
255
+ day.blocked = row.cnt;
256
+ else if (row.result === 'QUARANTINE')
257
+ day.quarantined = row.cnt;
258
+ day.scanned += row.cnt;
259
+ }
260
+ for (const row of captureRows) {
261
+ if (byDay[row.day])
262
+ byDay[row.day].captured = row.cnt;
263
+ }
264
+ for (const row of recallRows) {
265
+ if (byDay[row.day])
266
+ byDay[row.day].recalled = row.cnt;
267
+ }
268
+ return Object.values(byDay).sort((a, b) => a.date.localeCompare(b.date));
269
+ }
270
+ export function registerDigestRoutes(app) {
271
+ app.get('/api/digest', (req, res) => {
272
+ try {
273
+ if (!isDatabaseInitialized()) {
274
+ return res.status(503).json({ error: 'Database not initialised' });
275
+ }
276
+ const rawWindow = String(req.query.window ?? '24h');
277
+ const window = (rawWindow === '7d' || rawWindow === '30d') ? rawWindow : '24h';
278
+ const project = typeof req.query.project === 'string' && req.query.project.trim()
279
+ ? req.query.project.trim()
280
+ : undefined;
281
+ const digest = buildDigest(window, project);
282
+ res.json(digest);
283
+ }
284
+ catch (err) {
285
+ res.status(500).json({ error: err.message });
286
+ }
287
+ });
288
+ app.get('/api/digest/timeline', (req, res) => {
289
+ try {
290
+ if (!isDatabaseInitialized()) {
291
+ return res.status(503).json({ error: 'Database not initialised' });
292
+ }
293
+ const daysRaw = parseInt(String(req.query.days ?? '7'), 10);
294
+ const days = Number.isFinite(daysRaw) ? Math.max(1, Math.min(90, daysRaw)) : 7;
295
+ const project = typeof req.query.project === 'string' && req.query.project.trim()
296
+ ? req.query.project.trim()
297
+ : undefined;
298
+ const timeline = buildTimeline(days, project);
299
+ res.json({ days, project: project ?? null, timeline });
300
+ }
301
+ catch (err) {
302
+ res.status(500).json({ error: err.message });
303
+ }
304
+ });
305
+ }
@@ -4,7 +4,7 @@ import { existsSync, readdirSync, readFileSync } from 'fs';
4
4
  import { getDatabase } from '../../database/init.js';
5
5
  import { searchMemories, getRecentMemories, getHighPriorityMemories, getMemoryStats, getMemoryById, addMemory, deleteMemory, accessMemory, updateMemory, mergeMemories, promoteMemory, createMemoryLink, rowToMemory, enrichMemory, } from '../../memory/store.js';
6
6
  import { calculateDecayedScore } from '../../memory/decay.js';
7
- import { consolidate, findDuplicateMemoryPairs, formatContextSummary, generateContextSummary, consolidateMemories, } from '../../memory/consolidate.js';
7
+ import { consolidate, findDuplicateMemoryPairs, formatContextSummary, generateContextSummary, } from '../../memory/consolidate.js';
8
8
  import { getActivationStats, getActiveMemories } from '../../memory/activation.js';
9
9
  import { detectContradictions, getContradictionsFor } from '../../memory/contradiction.js';
10
10
  import { emitConsolidation } from '../events.js';
@@ -831,10 +831,15 @@ export function registerMemoryRoutes(app, deps) {
831
831
  res.status(500).json({ error: error.message });
832
832
  }
833
833
  });
834
+ // Consolidation is a maintenance operation (STM→LTM promotion + low-salience
835
+ // dedupe), not arbitrary delete. Use 'modify_records' (AMBER) so the
836
+ // dashboard can trigger it without the RED 'delete' gate that always blocks.
837
+ // Mirrors the action used by /api/worker/trigger-{light,medium}.
834
838
  app.post('/api/consolidate', requireNotLocked, requireIronDomeAction({
835
- action: 'delete',
839
+ action: 'modify_records',
836
840
  channel: 'dashboard',
837
841
  sourceIdentifier: 'dashboard:consolidate',
842
+ enforceAmber: true,
838
843
  }), (_req, res) => {
839
844
  try {
840
845
  const result = consolidate();
@@ -845,6 +850,78 @@ export function registerMemoryRoutes(app, deps) {
845
850
  res.status(500).json({ error: error.message });
846
851
  }
847
852
  });
853
+ // Threshold-based prune: delete memories below salience X older than Y days.
854
+ // dryRun:true (default) returns counts + sample without touching the DB.
855
+ // Auto-backs-up the DB before any destructive write — backupPath returned.
856
+ app.post('/api/memories/prune', requireNotLocked, requireIronDomeAction({
857
+ action: 'modify_records',
858
+ channel: 'dashboard',
859
+ sourceIdentifier: 'dashboard:memories-prune',
860
+ enforceAmber: true,
861
+ }), async (req, res) => {
862
+ try {
863
+ const { salienceLte, ageDaysGte, project, excludePinned, dryRun } = req.body ?? {};
864
+ if (salienceLte !== undefined && (typeof salienceLte !== 'number' || salienceLte < 0 || salienceLte > 1)) {
865
+ return res.status(400).json({ error: 'salienceLte must be a number 0..1' });
866
+ }
867
+ if (ageDaysGte !== undefined && (typeof ageDaysGte !== 'number' || ageDaysGte < 0)) {
868
+ return res.status(400).json({ error: 'ageDaysGte must be a number >= 0' });
869
+ }
870
+ if (project !== undefined && project !== null && typeof project !== 'string') {
871
+ return res.status(400).json({ error: 'project must be a string when provided' });
872
+ }
873
+ if (excludePinned !== undefined && typeof excludePinned !== 'boolean') {
874
+ return res.status(400).json({ error: 'excludePinned must be a boolean' });
875
+ }
876
+ if (dryRun !== undefined && typeof dryRun !== 'boolean') {
877
+ return res.status(400).json({ error: 'dryRun must be a boolean' });
878
+ }
879
+ const { pruneMemories } = await import('../../memory/prune.js');
880
+ const result = await pruneMemories({
881
+ salienceLte,
882
+ ageDaysGte,
883
+ project: project ?? undefined,
884
+ excludePinned,
885
+ dryRun,
886
+ });
887
+ res.json({ success: true, ...result });
888
+ }
889
+ catch (error) {
890
+ res.status(500).json({ error: error.message });
891
+ }
892
+ });
893
+ // Project-scoped dedupe: cluster near-duplicate long-term memories and keep
894
+ // the highest-salience representative. dryRun:true (default) returns the
895
+ // groups without merging. Auto-backs-up the DB before any merge.
896
+ app.post('/api/memories/dedupe', requireNotLocked, requireIronDomeAction({
897
+ action: 'modify_records',
898
+ channel: 'dashboard',
899
+ sourceIdentifier: 'dashboard:memories-dedupe',
900
+ enforceAmber: true,
901
+ }), async (req, res) => {
902
+ try {
903
+ const { project, dryRun, limit } = req.body ?? {};
904
+ if (project !== undefined && project !== null && typeof project !== 'string') {
905
+ return res.status(400).json({ error: 'project must be a string when provided' });
906
+ }
907
+ if (dryRun !== undefined && typeof dryRun !== 'boolean') {
908
+ return res.status(400).json({ error: 'dryRun must be a boolean' });
909
+ }
910
+ if (limit !== undefined && (typeof limit !== 'number' || limit < 1 || limit > 1000)) {
911
+ return res.status(400).json({ error: 'limit must be a number 1..1000' });
912
+ }
913
+ const { dedupeMemories } = await import('../../memory/dedupe-runner.js');
914
+ const result = await dedupeMemories({
915
+ project: project ?? undefined,
916
+ dryRun,
917
+ limit,
918
+ });
919
+ res.json({ success: true, ...result });
920
+ }
921
+ catch (error) {
922
+ res.status(500).json({ error: error.message });
923
+ }
924
+ });
848
925
  app.get('/api/context', requireNotLocked, async (req, res) => {
849
926
  try {
850
927
  const project = typeof req.query.project === 'string' ? req.query.project : undefined;
@@ -1151,17 +1228,9 @@ export function registerMemoryRoutes(app, deps) {
1151
1228
  res.status(500).json({ error: error.message });
1152
1229
  }
1153
1230
  });
1154
- // v4.0.0: Dream Mode comprehensive memory consolidation
1155
- app.post('/api/consolidate', requireNotLocked, (_req, res) => {
1156
- try {
1157
- const result = consolidateMemories();
1158
- res.json({
1159
- success: true,
1160
- ...result,
1161
- });
1162
- }
1163
- catch (error) {
1164
- res.status(500).json({ error: error.message });
1165
- }
1166
- });
1231
+ // (Note: there used to be a second, ungated `app.post('/api/consolidate', ...)`
1232
+ // here calling `consolidateMemories()`. It was dead code — Express dispatches
1233
+ // to the first matching route and the gated one above won. Removed in
1234
+ // favour of the gated route to avoid future contributors thinking either
1235
+ // would actually run.)
1167
1236
  }
@@ -2,7 +2,7 @@ import { WebSocket } from 'ws';
2
2
  import { getLifetimeStats } from '../../defence/audit/queries.js';
3
3
  import { getAuditStats } from '../../defence/audit/queries.js';
4
4
  import { isDatabaseInitialized } from '../../database/init.js';
5
- import { getCloudConfig, getCloudSyncControls, getDeviceId, getDeviceName, getDefenceMode, getOpenClawMemoryConfig, isConfigTampered, readRawConfig, setCloudConfig, setCloudSyncControls, setDefenceMode, setOpenClawMemoryConfig, } from '../../cloud/config.js';
5
+ import { getCloudConfig, getCloudSyncControls, getDeviceId, getDeviceName, getDefenceMode, getOpenClawMemoryConfig, isConfigTampered, isProactiveRecallEnabled, readRawConfig, setCloudConfig, setCloudSyncControls, setDefenceMode, setOpenClawMemoryConfig, setProactiveRecall, } from '../../cloud/config.js';
6
6
  import { getQueueStats, reconcileSyncQueue } from '../../cloud/sync-queue.js';
7
7
  import { getDatabase } from '../../database/init.js';
8
8
  import { getRequiredTier, isFeatureEnabled } from '../../license/gate.js';
@@ -111,6 +111,7 @@ export function registerSystemRoutes(app, deps) {
111
111
  baseUrl: config.cloudBaseUrl,
112
112
  syncControls: getCloudSyncControls(),
113
113
  openclawMemory: getOpenClawMemoryConfig(),
114
+ proactiveRecall: isProactiveRecallEnabled(),
114
115
  });
115
116
  }
116
117
  catch (error) {
@@ -125,7 +126,7 @@ export function registerSystemRoutes(app, deps) {
125
126
  }), (req, res) => {
126
127
  try {
127
128
  const existingConfig = getCloudConfig();
128
- const { cloudApiKey, cloudEnabled, cloudBaseUrl, cloudSyncProjectMode, cloudSyncProjects, cloudSyncContentMode, cloudSyncExcludeSensitive, openclawAutoMemory, openclawAutoMemoryDedupe, openclawAutoMemoryNoveltyThreshold, openclawAutoMemoryMaxRecent, } = req.body;
129
+ const { cloudApiKey, cloudEnabled, cloudBaseUrl, cloudSyncProjectMode, cloudSyncProjects, cloudSyncContentMode, cloudSyncExcludeSensitive, openclawAutoMemory, openclawAutoMemoryDedupe, openclawAutoMemoryNoveltyThreshold, openclawAutoMemoryMaxRecent, proactiveRecall, } = req.body;
129
130
  if (cloudApiKey !== undefined && typeof cloudApiKey !== 'string') {
130
131
  return res.status(400).json({ error: 'cloudApiKey must be a string' });
131
132
  }
@@ -168,6 +169,9 @@ export function registerSystemRoutes(app, deps) {
168
169
  (!Array.isArray(cloudSyncProjects) || cloudSyncProjects.some((value) => typeof value !== 'string'))) {
169
170
  return res.status(400).json({ error: 'cloudSyncProjects must be an array of strings' });
170
171
  }
172
+ if (proactiveRecall !== undefined && typeof proactiveRecall !== 'boolean') {
173
+ return res.status(400).json({ error: 'proactiveRecall must be a boolean' });
174
+ }
171
175
  const normalizedApiKey = cloudApiKey !== undefined
172
176
  ? cloudApiKey.trim()
173
177
  : existingConfig.cloudApiKey;
@@ -207,6 +211,9 @@ export function registerSystemRoutes(app, deps) {
207
211
  ...(openclawAutoMemoryNoveltyThreshold !== undefined && { noveltyThreshold: openclawAutoMemoryNoveltyThreshold }),
208
212
  ...(openclawAutoMemoryMaxRecent !== undefined && { maxRecent: openclawAutoMemoryMaxRecent }),
209
213
  });
214
+ if (proactiveRecall !== undefined) {
215
+ setProactiveRecall(proactiveRecall);
216
+ }
210
217
  const updated = getCloudConfig();
211
218
  res.json({
212
219
  success: true,
@@ -215,6 +222,7 @@ export function registerSystemRoutes(app, deps) {
215
222
  baseUrl: updated.cloudBaseUrl,
216
223
  syncControls: getCloudSyncControls(),
217
224
  openclawMemory: getOpenClawMemoryConfig(),
225
+ proactiveRecall: isProactiveRecallEnabled(),
218
226
  });
219
227
  }
220
228
  catch (error) {
@@ -36,6 +36,7 @@ import { registerRecallRoutes } from './routes/recall.js';
36
36
  import { registerSystemRoutes } from './routes/system.js';
37
37
  import { registerXRayRoutes } from './routes/xray.js';
38
38
  import { registerXRayFindingRoutes } from './routes/xray-findings.js';
39
+ import { registerDigestRoutes } from './routes/digest.js';
39
40
  import { createIronDomeRouteGuard } from './iron-dome-route-guard.js';
40
41
  import { readAndClearDetectionEvents } from '../xray/activity.js';
41
42
  const PORT = process.env.PORT || 3001;
@@ -191,6 +192,7 @@ export function startVisualizationServer(dbPath) {
191
192
  clients,
192
193
  requireIronDomeAction: createIronDomeRouteGuard,
193
194
  });
195
+ registerDigestRoutes(app);
194
196
  // ============================================
195
197
  // INSIGHTS ENDPOINTS
196
198
  // ============================================
@@ -2,4 +2,31 @@
2
2
  * ShieldCortex Doctor — Installation health checker.
3
3
  * Runs diagnostics and reports issues with actionable fixes.
4
4
  */
5
+ export type CheckStatus = 'pass' | 'warn' | 'fail' | 'info';
6
+ export interface CheckResult {
7
+ label: string;
8
+ status: CheckStatus;
9
+ message: string;
10
+ fix?: string;
11
+ }
12
+ /**
13
+ * The honest "is it working?" check.
14
+ *
15
+ * Doctor checks have historically gone green while writes were silently
16
+ * failing (v4.12.4 path-encoding bug, v4.12.5 NOT NULL UUID schema gap).
17
+ * The pattern: schema introspection passed (columns existed) but actual
18
+ * INSERTs threw constraint violations during real workloads.
19
+ *
20
+ * This check does a real round-trip — INSERT a tagged probe memory,
21
+ * SELECT it back, DELETE it. If any step fails, doctor reports the
22
+ * actual error string instead of "all green". The probe is tagged with
23
+ * a unique source identifier so it can never be confused with real data
24
+ * and gets deleted at the end of the check.
25
+ */
26
+ /**
27
+ * Pure helper for the write-path round-trip. Exported so tests can
28
+ * exercise it against any database path (in-memory or temp file)
29
+ * without going through doctor's homedir-derived getDbPath().
30
+ */
31
+ export declare function runWritePathProbe(dbPath: string): CheckResult;
5
32
  export declare function runDoctor(): Promise<void>;
@@ -197,6 +197,93 @@ async function checkMemoryStats() {
197
197
  return { label: 'Memories', status: 'warn', message: `check failed — ${msg}` };
198
198
  }
199
199
  }
200
+ // ── Check 3b: Write-path smoke test ───────────────────────
201
+ /**
202
+ * The honest "is it working?" check.
203
+ *
204
+ * Doctor checks have historically gone green while writes were silently
205
+ * failing (v4.12.4 path-encoding bug, v4.12.5 NOT NULL UUID schema gap).
206
+ * The pattern: schema introspection passed (columns existed) but actual
207
+ * INSERTs threw constraint violations during real workloads.
208
+ *
209
+ * This check does a real round-trip — INSERT a tagged probe memory,
210
+ * SELECT it back, DELETE it. If any step fails, doctor reports the
211
+ * actual error string instead of "all green". The probe is tagged with
212
+ * a unique source identifier so it can never be confused with real data
213
+ * and gets deleted at the end of the check.
214
+ */
215
+ /**
216
+ * Pure helper for the write-path round-trip. Exported so tests can
217
+ * exercise it against any database path (in-memory or temp file)
218
+ * without going through doctor's homedir-derived getDbPath().
219
+ */
220
+ export function runWritePathProbe(dbPath) {
221
+ if (!fs.existsSync(dbPath)) {
222
+ return { label: 'Write path', status: 'warn', message: 'skipped (no database)' };
223
+ }
224
+ let db = null;
225
+ const probeUuid = `doctor-probe-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
226
+ const probeTitle = '__shieldcortex_doctor_probe__';
227
+ try {
228
+ const Database = require('better-sqlite3');
229
+ db = new Database(dbPath);
230
+ // INSERT — exercises NOT NULL columns + CHECK constraints. The schema
231
+ // adds these silently across versions; an INSERT against a stale schema
232
+ // is the exact failure mode v4.12.5 had.
233
+ db.prepare(`
234
+ INSERT INTO memories (uuid, type, category, title, content, salience, source, capture_method)
235
+ VALUES (?, 'short_term', 'note', ?, 'doctor probe — safe to delete', 0.01, 'cli:doctor', 'doctor-probe')
236
+ `).run(probeUuid, probeTitle);
237
+ // SELECT — exercises the FTS5 + index path
238
+ const row = db.prepare('SELECT id, title FROM memories WHERE uuid = ?').get(probeUuid);
239
+ if (!row || row.title !== probeTitle) {
240
+ return {
241
+ label: 'Write path',
242
+ status: 'fail',
243
+ message: 'wrote a probe row but could not read it back',
244
+ fix: 'Database may be corrupted. Run `shieldcortex consolidate` then re-run doctor.',
245
+ };
246
+ }
247
+ // DELETE — exercises the cascade triggers (FTS5 cleanup)
248
+ const deleteResult = db.prepare('DELETE FROM memories WHERE uuid = ?').run(probeUuid);
249
+ if (deleteResult.changes !== 1) {
250
+ return {
251
+ label: 'Write path',
252
+ status: 'warn',
253
+ message: `probe row written + read OK but delete affected ${deleteResult.changes} rows (expected 1)`,
254
+ fix: 'Manual cleanup may be needed. Check ~/.shieldcortex/memories.db for orphaned rows.',
255
+ };
256
+ }
257
+ return { label: 'Write path', status: 'pass', message: 'INSERT/SELECT/DELETE round-trip OK' };
258
+ }
259
+ catch (err) {
260
+ const msg = err instanceof Error ? err.message : String(err);
261
+ // Best-effort cleanup so we don't leave probe rows behind on a partial failure
262
+ if (db) {
263
+ try {
264
+ db.prepare('DELETE FROM memories WHERE uuid = ?').run(probeUuid);
265
+ }
266
+ catch { /* ignore */ }
267
+ }
268
+ return {
269
+ label: 'Write path',
270
+ status: 'fail',
271
+ message: `round-trip failed — ${msg}`,
272
+ fix: 'This is the smoking gun for a stale schema or migration drift. Try restarting the MCP server (auto-migrates), or re-install: shieldcortex install',
273
+ };
274
+ }
275
+ finally {
276
+ if (db) {
277
+ try {
278
+ db.close();
279
+ }
280
+ catch { /* ignore */ }
281
+ }
282
+ }
283
+ }
284
+ async function checkWritePath() {
285
+ return runWritePathProbe(getDbPath());
286
+ }
200
287
  // ── Check 4: Hook installation ────────────────────────────
201
288
  async function checkHooks() {
202
289
  const settingsPath = path.join(os.homedir(), '.claude', 'settings.json');
@@ -498,6 +585,7 @@ export async function runDoctor() {
498
585
  const checks = [
499
586
  checkDatabase,
500
587
  checkSchema,
588
+ checkWritePath, // Smoke test: real INSERT/SELECT/DELETE round-trip — catches silent schema drift
501
589
  checkMemoryStats,
502
590
  checkHooks,
503
591
  checkProcesses,
@@ -0,0 +1,28 @@
1
+ interface MigrateOptions {
2
+ /** Source legacy DB paths to import from. Defaults to both ~/.claude-memory/ and ~/.claude-cortex/ */
3
+ sources?: string[];
4
+ /** Target DB path. Default ~/.shieldcortex/memories.db */
5
+ target?: string;
6
+ /** If true, count + report only — no writes. */
7
+ dryRun?: boolean;
8
+ }
9
+ interface SourceReport {
10
+ path: string;
11
+ exists: boolean;
12
+ memoriesFound: number;
13
+ memoriesImported: number;
14
+ linksFound: number;
15
+ linksImported: number;
16
+ linksSkipped: number;
17
+ error?: string;
18
+ }
19
+ interface MigrationReport {
20
+ target: string;
21
+ dryRun: boolean;
22
+ sources: SourceReport[];
23
+ totalMemories: number;
24
+ totalLinks: number;
25
+ }
26
+ export declare function migrateLegacy(options?: MigrateOptions): MigrationReport;
27
+ export declare function handleMemoriesCommand(args: string[]): Promise<void>;
28
+ export {};