shieldcortex 4.31.2 → 4.32.1

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 (353) hide show
  1. package/README.md +78 -2
  2. package/dashboard/.next/standalone/dashboard/.next/BUILD_ID +1 -1
  3. package/dashboard/.next/standalone/dashboard/.next/build-manifest.json +2 -2
  4. package/dashboard/.next/standalone/dashboard/.next/prerender-manifest.json +3 -3
  5. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.html +2 -2
  6. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
  7. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  8. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  9. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  10. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  11. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  12. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +2 -2
  13. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +1 -1
  14. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  15. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  16. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  17. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  18. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  19. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  20. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.html +1 -1
  21. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.rsc +1 -1
  22. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin/__PAGE__.segment.rsc +1 -1
  23. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin.segment.rsc +1 -1
  24. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  25. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_full.segment.rsc +1 -1
  26. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_head.segment.rsc +1 -1
  27. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_index.segment.rsc +1 -1
  28. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_tree.segment.rsc +1 -1
  29. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.html +1 -1
  30. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.rsc +1 -1
  31. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud/__PAGE__.segment.rsc +1 -1
  32. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud.segment.rsc +1 -1
  33. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  34. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_full.segment.rsc +1 -1
  35. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_head.segment.rsc +1 -1
  36. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_index.segment.rsc +1 -1
  37. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_tree.segment.rsc +1 -1
  38. package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
  39. package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +1 -1
  40. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  41. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +1 -1
  42. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
  43. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +1 -1
  44. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  45. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.html +1 -1
  46. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.rsc +1 -1
  47. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture/__PAGE__.segment.rsc +1 -1
  48. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture.segment.rsc +1 -1
  49. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  50. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  51. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_full.segment.rsc +1 -1
  52. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_head.segment.rsc +1 -1
  53. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_index.segment.rsc +1 -1
  54. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_tree.segment.rsc +1 -1
  55. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.html +1 -1
  56. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.rsc +1 -1
  57. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph/__PAGE__.segment.rsc +1 -1
  58. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph.segment.rsc +1 -1
  59. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  60. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  61. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_full.segment.rsc +1 -1
  62. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_head.segment.rsc +1 -1
  63. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_index.segment.rsc +1 -1
  64. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_tree.segment.rsc +1 -1
  65. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.html +1 -1
  66. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.rsc +1 -1
  67. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall/__PAGE__.segment.rsc +1 -1
  68. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall.segment.rsc +1 -1
  69. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  70. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  71. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_full.segment.rsc +1 -1
  72. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_head.segment.rsc +1 -1
  73. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_index.segment.rsc +1 -1
  74. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_tree.segment.rsc +1 -1
  75. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.html +2 -2
  76. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.rsc +1 -1
  77. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory/replay/__PAGE__.segment.rsc +1 -1
  78. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory/replay.segment.rsc +1 -1
  79. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  80. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  81. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_full.segment.rsc +1 -1
  82. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_head.segment.rsc +1 -1
  83. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_index.segment.rsc +1 -1
  84. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/replay.segments/_tree.segment.rsc +1 -1
  85. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.html +1 -1
  86. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.rsc +1 -1
  87. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review/__PAGE__.segment.rsc +1 -1
  88. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review.segment.rsc +1 -1
  89. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  90. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  91. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_full.segment.rsc +1 -1
  92. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_head.segment.rsc +1 -1
  93. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_index.segment.rsc +1 -1
  94. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_tree.segment.rsc +1 -1
  95. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.html +1 -1
  96. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.rsc +1 -1
  97. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline/__PAGE__.segment.rsc +1 -1
  98. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline.segment.rsc +1 -1
  99. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  100. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  101. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_full.segment.rsc +1 -1
  102. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_head.segment.rsc +1 -1
  103. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_index.segment.rsc +1 -1
  104. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_tree.segment.rsc +1 -1
  105. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.html +2 -2
  106. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.rsc +1 -1
  107. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory/__PAGE__.segment.rsc +1 -1
  108. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  109. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  110. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_full.segment.rsc +1 -1
  111. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_head.segment.rsc +1 -1
  112. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_index.segment.rsc +1 -1
  113. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_tree.segment.rsc +1 -1
  114. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.html +2 -2
  115. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.rsc +1 -1
  116. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview/__PAGE__.segment.rsc +1 -1
  117. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview.segment.rsc +1 -1
  118. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  119. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_full.segment.rsc +1 -1
  120. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_head.segment.rsc +1 -1
  121. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_index.segment.rsc +1 -1
  122. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_tree.segment.rsc +1 -1
  123. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.html +1 -1
  124. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.rsc +1 -1
  125. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit/__PAGE__.segment.rsc +1 -1
  126. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit.segment.rsc +1 -1
  127. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  128. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  129. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_full.segment.rsc +1 -1
  130. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_head.segment.rsc +1 -1
  131. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_index.segment.rsc +1 -1
  132. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_tree.segment.rsc +1 -1
  133. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.html +1 -1
  134. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.rsc +1 -1
  135. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts/__PAGE__.segment.rsc +1 -1
  136. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts.segment.rsc +1 -1
  137. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  138. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  139. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_full.segment.rsc +1 -1
  140. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_head.segment.rsc +1 -1
  141. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_index.segment.rsc +1 -1
  142. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_tree.segment.rsc +1 -1
  143. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.html +1 -1
  144. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.rsc +1 -1
  145. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome/__PAGE__.segment.rsc +1 -1
  146. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome.segment.rsc +1 -1
  147. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  148. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  149. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_full.segment.rsc +1 -1
  150. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_head.segment.rsc +1 -1
  151. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_index.segment.rsc +1 -1
  152. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_tree.segment.rsc +1 -1
  153. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.html +1 -1
  154. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.rsc +1 -1
  155. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies/__PAGE__.segment.rsc +1 -1
  156. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies.segment.rsc +1 -1
  157. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  158. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  159. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_full.segment.rsc +1 -1
  160. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_head.segment.rsc +1 -1
  161. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_index.segment.rsc +1 -1
  162. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_tree.segment.rsc +1 -1
  163. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.html +1 -1
  164. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.rsc +1 -1
  165. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine/__PAGE__.segment.rsc +1 -1
  166. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine.segment.rsc +1 -1
  167. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  168. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  169. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_full.segment.rsc +1 -1
  170. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_head.segment.rsc +1 -1
  171. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_index.segment.rsc +1 -1
  172. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_tree.segment.rsc +1 -1
  173. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.html +2 -2
  174. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.rsc +1 -1
  175. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection/__PAGE__.segment.rsc +1 -1
  176. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  177. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  178. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_full.segment.rsc +1 -1
  179. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_head.segment.rsc +1 -1
  180. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_index.segment.rsc +1 -1
  181. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_tree.segment.rsc +1 -1
  182. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.html +2 -2
  183. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.rsc +1 -1
  184. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings/__PAGE__.segment.rsc +1 -1
  185. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings.segment.rsc +1 -1
  186. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  187. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_full.segment.rsc +1 -1
  188. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  189. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  190. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  191. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.html +1 -1
  192. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.rsc +1 -1
  193. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray/__PAGE__.segment.rsc +1 -1
  194. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray.segment.rsc +1 -1
  195. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
  196. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  197. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_full.segment.rsc +1 -1
  198. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_head.segment.rsc +1 -1
  199. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_index.segment.rsc +1 -1
  200. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_tree.segment.rsc +1 -1
  201. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.html +1 -1
  202. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.rsc +1 -1
  203. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain/__PAGE__.segment.rsc +1 -1
  204. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
  205. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  206. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_full.segment.rsc +1 -1
  207. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_head.segment.rsc +1 -1
  208. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_index.segment.rsc +1 -1
  209. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_tree.segment.rsc +1 -1
  210. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.html +2 -2
  211. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.rsc +1 -1
  212. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray/__PAGE__.segment.rsc +1 -1
  213. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray.segment.rsc +1 -1
  214. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  215. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_full.segment.rsc +1 -1
  216. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_head.segment.rsc +1 -1
  217. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_index.segment.rsc +1 -1
  218. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_tree.segment.rsc +1 -1
  219. package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +2 -2
  220. package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
  221. package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.js +1 -1
  222. package/dashboard/.next/standalone/dashboard/.next/server/server-reference-manifest.json +1 -1
  223. package/dist/api/control.d.ts +2 -0
  224. package/dist/api/control.js +119 -2
  225. package/dist/api/routes/memories.js +19 -14
  226. package/dist/api/routes/system.js +2 -3
  227. package/dist/api/visualization-server.d.ts +13 -1
  228. package/dist/api/visualization-server.js +57 -1
  229. package/dist/audit/env-scanner.js +5 -2
  230. package/dist/audit/index.d.ts +4 -1
  231. package/dist/audit/index.js +2 -1
  232. package/dist/audit/mcp-config-scanner.d.ts +23 -0
  233. package/dist/audit/mcp-config-scanner.js +110 -0
  234. package/dist/audit/mcp-tools-scanner.d.ts +112 -0
  235. package/dist/audit/mcp-tools-scanner.js +299 -0
  236. package/dist/cli/audit.d.ts +1 -0
  237. package/dist/cli/audit.js +12 -1
  238. package/dist/cli/doctor.js +4 -1
  239. package/dist/cli/mcp.d.ts +13 -0
  240. package/dist/cli/mcp.js +0 -0
  241. package/dist/cli/remember.d.ts +75 -0
  242. package/dist/cli/remember.js +195 -0
  243. package/dist/cli/repair.d.ts +8 -0
  244. package/dist/cli/repair.js +34 -0
  245. package/dist/cli/update.js +34 -0
  246. package/dist/cloud/config.d.ts +23 -1
  247. package/dist/cloud/config.js +453 -193
  248. package/dist/cloud/quarantine-sync.d.ts +12 -2
  249. package/dist/cloud/quarantine-sync.js +28 -6
  250. package/dist/cloud/sync-queue.d.ts +21 -2
  251. package/dist/cloud/sync-queue.js +124 -29
  252. package/dist/database/better-sqlite3-guard.d.ts +21 -2
  253. package/dist/database/better-sqlite3-guard.js +29 -5
  254. package/dist/database/init.js +68 -16
  255. package/dist/database/inline-schema.js +35 -1
  256. package/dist/database/migrations.js +104 -8
  257. package/dist/database/schema.sql +39 -1
  258. package/dist/defence/audit/queries.d.ts +10 -2
  259. package/dist/defence/audit/queries.js +30 -4
  260. package/dist/defence/audit/retention.d.ts +50 -0
  261. package/dist/defence/audit/retention.js +161 -0
  262. package/dist/defence/credential-leak/entropy.d.ts +11 -0
  263. package/dist/defence/credential-leak/entropy.js +27 -0
  264. package/dist/defence/credential-leak/index.js +27 -1
  265. package/dist/defence/credential-leak/patterns.d.ts +9 -0
  266. package/dist/defence/credential-leak/patterns.js +21 -0
  267. package/dist/defence/custom-patterns/store.js +8 -1
  268. package/dist/defence/custom-rules/store.d.ts +18 -0
  269. package/dist/defence/custom-rules/store.js +63 -0
  270. package/dist/defence/firewall/confusables.d.ts +30 -0
  271. package/dist/defence/firewall/confusables.js +87 -0
  272. package/dist/defence/firewall/encoding-detector.js +23 -9
  273. package/dist/defence/firewall/index.d.ts +11 -1
  274. package/dist/defence/firewall/index.js +34 -1
  275. package/dist/defence/firewall/instruction-detector.js +18 -7
  276. package/dist/defence/firewall/markdown-image-detector.d.ts +34 -0
  277. package/dist/defence/firewall/markdown-image-detector.js +83 -0
  278. package/dist/defence/fragmentation/entity-extractor.js +17 -6
  279. package/dist/defence/index.d.ts +5 -0
  280. package/dist/defence/index.js +8 -0
  281. package/dist/defence/iron-dome/index.js +7 -1
  282. package/dist/defence/pipeline.js +62 -10
  283. package/dist/defence/scan-windows.d.ts +41 -0
  284. package/dist/defence/scan-windows.js +61 -0
  285. package/dist/defence/semantic/attack-corpus.d.ts +22 -0
  286. package/dist/defence/semantic/attack-corpus.js +75 -0
  287. package/dist/defence/semantic/index.d.ts +67 -0
  288. package/dist/defence/semantic/index.js +138 -0
  289. package/dist/defence/skill-scanner/deep-scan.js +35 -15
  290. package/dist/defence/skill-scanner/patterns.d.ts +1 -1
  291. package/dist/defence/skill-scanner/patterns.js +8 -7
  292. package/dist/defence/tool-response-scanner.d.ts +21 -5
  293. package/dist/defence/tool-response-scanner.js +111 -22
  294. package/dist/defence/types.d.ts +11 -1
  295. package/dist/index.d.ts +29 -0
  296. package/dist/index.js +112 -21
  297. package/dist/memory/consolidate.js +1 -1
  298. package/dist/memory/decay.js +3 -1
  299. package/dist/memory/embedding.d.ts +18 -2
  300. package/dist/memory/embedding.js +32 -11
  301. package/dist/memory/expiry.js +1 -1
  302. package/dist/memory/search-recall.js +107 -49
  303. package/dist/memory/search.d.ts +19 -3
  304. package/dist/memory/search.js +25 -10
  305. package/dist/memory/store.d.ts +13 -2
  306. package/dist/memory/store.js +115 -11
  307. package/dist/scan-only.d.ts +64 -0
  308. package/dist/scan-only.js +173 -0
  309. package/dist/server.d.ts +5 -0
  310. package/dist/server.js +6 -4
  311. package/dist/setup/claude-md.js +39 -34
  312. package/dist/setup/codex.js +9 -2
  313. package/dist/setup/copilot.js +160 -47
  314. package/dist/setup/json-config.d.ts +99 -0
  315. package/dist/setup/json-config.js +167 -0
  316. package/dist/setup/migrate.js +1 -1
  317. package/dist/setup/native-binding.d.ts +75 -0
  318. package/dist/setup/native-binding.js +146 -0
  319. package/dist/setup/settings-hooks.js +8 -13
  320. package/dist/setup/uninstall.js +1 -21
  321. package/dist/tools/context.d.ts +8 -8
  322. package/dist/tools/forget.d.ts +9 -8
  323. package/dist/tools/forget.js +17 -4
  324. package/dist/tools/recall.d.ts +13 -13
  325. package/dist/tools/remember.d.ts +16 -16
  326. package/dist/tools/remember.js +19 -8
  327. package/dist/worker/brain-worker.d.ts +1 -0
  328. package/dist/worker/brain-worker.js +79 -16
  329. package/dist/worker/types.d.ts +8 -0
  330. package/dist/worker/types.js +8 -0
  331. package/dist/xray/dir-scanner.d.ts +18 -0
  332. package/dist/xray/dir-scanner.js +23 -1
  333. package/dist/xray/file-scanner.js +16 -1
  334. package/dist/xray/findings-store.js +9 -1
  335. package/dist/xray/index.d.ts +2 -0
  336. package/dist/xray/index.js +10 -1
  337. package/dist/xray/npm-inspector.d.ts +31 -0
  338. package/dist/xray/npm-inspector.js +135 -29
  339. package/dist/xray/patterns.d.ts +1 -1
  340. package/dist/xray/patterns.js +20 -23
  341. package/dist/xray/sarif.d.ts +78 -0
  342. package/dist/xray/sarif.js +166 -0
  343. package/dist/xray/watch.d.ts +1 -0
  344. package/dist/xray/watch.js +10 -1
  345. package/hooks/openclaw/cortex-memory/handler.ts +122 -18
  346. package/hooks/openclaw/cortex-memory/runtime.mjs +10 -4
  347. package/package.json +10 -3
  348. package/scripts/postinstall.mjs +8 -3
  349. package/dist/memory/embedding-cache.d.ts +0 -20
  350. package/dist/memory/embedding-cache.js +0 -91
  351. /package/dashboard/.next/standalone/dashboard/.next/static/{_j4TeMpss-w79QtNNWqZw → tjJ3X8xQ-2_WQTPGF3zCA}/_buildManifest.js +0 -0
  352. /package/dashboard/.next/standalone/dashboard/.next/static/{_j4TeMpss-w79QtNNWqZw → tjJ3X8xQ-2_WQTPGF3zCA}/_clientMiddlewareManifest.json +0 -0
  353. /package/dashboard/.next/standalone/dashboard/.next/static/{_j4TeMpss-w79QtNNWqZw → tjJ3X8xQ-2_WQTPGF3zCA}/_ssgManifest.js +0 -0
@@ -4,21 +4,11 @@
4
4
  * Comprehensive pattern groups for detecting hidden risk in packages, files,
5
5
  * and metadata. Follows the same conventions as skill-scanner/patterns.ts:
6
6
  * - safeRegexTest wrapper for every test
7
- * - MAX_SCAN_LENGTH truncation to prevent ReDOS
7
+ * - Overlapping windowed scanning to bound per-regex work (ReDOS guard)
8
8
  * - PatternGroup style with weighted confidence
9
9
  * - One match per group is enough (break after first)
10
10
  */
11
- // ── Constants ───────────────────────────────────────────────────────────────
12
- /** Maximum content length to analyse (prevents ReDOS on very long inputs). */
13
- const MAX_SCAN_LENGTH = 50000;
14
- // ── Helpers ─────────────────────────────────────────────────────────────────
15
- /**
16
- * Safely test a regex against content with a length limit.
17
- */
18
- function safeRegexTest(pattern, text) {
19
- const truncated = text.length > MAX_SCAN_LENGTH ? text.slice(0, MAX_SCAN_LENGTH) : text;
20
- return pattern.test(truncated);
21
- }
11
+ import { forEachWindow } from '../defence/scan-windows.js';
22
12
  // ── Pattern Groups ──────────────────────────────────────────────────────────
23
13
  const XRAY_PATTERN_GROUPS = [
24
14
  // 1. eval/exec with dynamic input
@@ -210,19 +200,26 @@ const XRAY_PATTERN_GROUPS = [
210
200
  */
211
201
  export function detectPatterns(content, filePath) {
212
202
  const findings = [];
213
- const truncated = content.length > MAX_SCAN_LENGTH ? content.slice(0, MAX_SCAN_LENGTH) : content;
214
203
  for (const group of XRAY_PATTERN_GROUPS) {
215
204
  for (const pattern of group.patterns) {
216
- if (safeRegexTest(pattern, truncated)) {
217
- const match = pattern.exec(truncated);
218
- let line;
219
- let evidence;
220
- if (match) {
221
- // Calculate line number from match index
222
- const before = truncated.slice(0, match.index);
223
- line = (before.match(/\n/g) || []).length + 1;
224
- evidence = match[0].slice(0, 120);
225
- }
205
+ // Scan the WHOLE content as overlapping windows (<= SCAN_WINDOW_SIZE each)
206
+ // instead of truncating to the first 50KB, so a finding buried past the
207
+ // cap is still detected. `start` is the window's absolute char offset, used
208
+ // to translate the window-local match index back to a content-absolute one
209
+ // for an accurate line number.
210
+ let line;
211
+ let evidence;
212
+ const matched = forEachWindow(content, (window, start) => {
213
+ const match = pattern.exec(window);
214
+ if (!match)
215
+ return false;
216
+ const absoluteIndex = start + match.index;
217
+ const before = content.slice(0, absoluteIndex);
218
+ line = (before.match(/\n/g) || []).length + 1;
219
+ evidence = match[0].slice(0, 120);
220
+ return true;
221
+ });
222
+ if (matched) {
226
223
  findings.push({
227
224
  severity: group.severity,
228
225
  category: group.category,
@@ -0,0 +1,78 @@
1
+ /**
2
+ * SARIF 2.1.0 output for ShieldCortex findings.
3
+ *
4
+ * Phase 15b — turns X-Ray / audit / mcp-scan findings into a SARIF 2.1.0
5
+ * document so they surface in GitHub Code Scanning (the Security tab).
6
+ *
7
+ * Lives in the xray layer (its `index.ts` already re-exports the other
8
+ * formatters) but is shape-agnostic: it accepts BOTH the xray `XRayFinding`
9
+ * and the audit `AuditFinding` via a single internal normaliser, so the SARIF
10
+ * builder never branches on the source shape.
11
+ *
12
+ * Spec: https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html
13
+ */
14
+ import type { XRayFinding } from './types.js';
15
+ import type { AuditFinding } from '../audit/types.js';
16
+ export type SarifLevel = 'error' | 'warning' | 'note' | 'none';
17
+ export interface SarifRule {
18
+ id: string;
19
+ name?: string;
20
+ shortDescription?: {
21
+ text: string;
22
+ };
23
+ helpUri?: string;
24
+ }
25
+ export interface SarifArtifactLocation {
26
+ uri: string;
27
+ }
28
+ export interface SarifRegion {
29
+ startLine: number;
30
+ }
31
+ export interface SarifPhysicalLocation {
32
+ artifactLocation: SarifArtifactLocation;
33
+ region?: SarifRegion;
34
+ }
35
+ export interface SarifLogicalLocation {
36
+ fullyQualifiedName: string;
37
+ kind?: string;
38
+ }
39
+ export interface SarifLocation {
40
+ physicalLocation?: SarifPhysicalLocation;
41
+ logicalLocations?: SarifLogicalLocation[];
42
+ }
43
+ export interface SarifResult {
44
+ ruleId: string;
45
+ level: SarifLevel;
46
+ message: {
47
+ text: string;
48
+ };
49
+ locations?: SarifLocation[];
50
+ }
51
+ export interface SarifDriver {
52
+ name: string;
53
+ version: string;
54
+ informationUri: string;
55
+ rules: SarifRule[];
56
+ }
57
+ export interface SarifRun {
58
+ tool: {
59
+ driver: SarifDriver;
60
+ };
61
+ results: SarifResult[];
62
+ }
63
+ export interface SarifLog {
64
+ $schema: string;
65
+ version: '2.1.0';
66
+ runs: SarifRun[];
67
+ }
68
+ export interface ToSarifOptions {
69
+ /** Tool version recorded in tool.driver.version. Resolved from package.json when omitted. */
70
+ version?: string;
71
+ /** Base directory to make file URIs relative to (defaults to process.cwd()). */
72
+ baseDir?: string;
73
+ }
74
+ /**
75
+ * Build a SARIF 2.1.0 log from a list of findings (either shape).
76
+ * Rules are deduped into `tool.driver.rules` by ruleId.
77
+ */
78
+ export declare function toSarif(findings: (XRayFinding | AuditFinding)[], options?: ToSarifOptions): SarifLog;
@@ -0,0 +1,166 @@
1
+ /**
2
+ * SARIF 2.1.0 output for ShieldCortex findings.
3
+ *
4
+ * Phase 15b — turns X-Ray / audit / mcp-scan findings into a SARIF 2.1.0
5
+ * document so they surface in GitHub Code Scanning (the Security tab).
6
+ *
7
+ * Lives in the xray layer (its `index.ts` already re-exports the other
8
+ * formatters) but is shape-agnostic: it accepts BOTH the xray `XRayFinding`
9
+ * and the audit `AuditFinding` via a single internal normaliser, so the SARIF
10
+ * builder never branches on the source shape.
11
+ *
12
+ * Spec: https://docs.oasis-open.org/sarif/sarif/v2.1.0/sarif-v2.1.0.html
13
+ */
14
+ import path from 'path';
15
+ import { createRequire } from 'module';
16
+ const INFORMATION_URI = 'https://shieldcortex.ai';
17
+ const SARIF_SCHEMA = 'https://json.schemastore.org/sarif-2.1.0.json';
18
+ // ── Helpers ────────────────────────────────────────────────────
19
+ /**
20
+ * Map a ShieldCortex severity onto a SARIF result level.
21
+ * critical / high → error
22
+ * medium → warning
23
+ * low / info → note
24
+ */
25
+ function severityToLevel(severity) {
26
+ switch (severity) {
27
+ case 'critical':
28
+ case 'high':
29
+ return 'error';
30
+ case 'medium':
31
+ return 'warning';
32
+ case 'low':
33
+ case 'info':
34
+ default:
35
+ return 'note';
36
+ }
37
+ }
38
+ /**
39
+ * Stable rule id from a category/scanner key + title. SARIF rule ids should be
40
+ * opaque, stable, and free of whitespace so they read well in the GitHub UI and
41
+ * dedupe deterministically across runs.
42
+ */
43
+ function makeRuleId(prefix, title) {
44
+ const slug = `${prefix}/${title}`
45
+ .toLowerCase()
46
+ .replace(/[^a-z0-9]+/g, '-')
47
+ .replace(/^-+|-+$/g, '');
48
+ return `shieldcortex/${slug}`;
49
+ }
50
+ function isXRayFinding(f) {
51
+ // XRayFinding has `category`; AuditFinding has `scanner`. They are disjoint.
52
+ return f.category !== undefined;
53
+ }
54
+ /** Make a file path relative to baseDir + posix-separated for SARIF URIs. */
55
+ function toUri(file, baseDir) {
56
+ let rel = file;
57
+ if (path.isAbsolute(file)) {
58
+ rel = path.relative(baseDir, file);
59
+ // If the file is outside baseDir, relative() yields ../ — fall back to the
60
+ // absolute path rather than emitting a confusing climb-out URI.
61
+ if (rel.startsWith('..'))
62
+ rel = file;
63
+ }
64
+ return rel.split(path.sep).join('/');
65
+ }
66
+ function normalise(f) {
67
+ if (isXRayFinding(f)) {
68
+ const category = f.category;
69
+ return {
70
+ ruleId: makeRuleId(category, f.title),
71
+ ruleName: f.title,
72
+ level: severityToLevel(f.severity),
73
+ message: f.description,
74
+ file: f.file,
75
+ line: f.line,
76
+ };
77
+ }
78
+ // AuditFinding. May or may not have a filePath.
79
+ const audit = f;
80
+ const norm = {
81
+ ruleId: makeRuleId(audit.scanner, audit.title),
82
+ ruleName: audit.title,
83
+ level: severityToLevel(audit.severity),
84
+ message: audit.description,
85
+ helpUri: audit.learnMoreUrl,
86
+ };
87
+ if (audit.filePath) {
88
+ norm.file = audit.filePath;
89
+ }
90
+ else {
91
+ // Fileless: synthesise a logical location from scanner + title so the
92
+ // result still carries a location and stays schema-valid without a
93
+ // physicalLocation.
94
+ norm.logicalName = `${audit.scanner}/${audit.title}`;
95
+ }
96
+ return norm;
97
+ }
98
+ // ── Builder ────────────────────────────────────────────────────
99
+ function resolveVersion() {
100
+ try {
101
+ const require = createRequire(import.meta.url);
102
+ const pkg = require('../../package.json');
103
+ return pkg.version ?? '0.0.0';
104
+ }
105
+ catch {
106
+ return '0.0.0';
107
+ }
108
+ }
109
+ /**
110
+ * Build a SARIF 2.1.0 log from a list of findings (either shape).
111
+ * Rules are deduped into `tool.driver.rules` by ruleId.
112
+ */
113
+ export function toSarif(findings, options = {}) {
114
+ const version = options.version ?? resolveVersion();
115
+ const baseDir = options.baseDir ?? process.cwd();
116
+ const rulesById = new Map();
117
+ const results = [];
118
+ for (const finding of findings) {
119
+ const n = normalise(finding);
120
+ if (!rulesById.has(n.ruleId)) {
121
+ const rule = {
122
+ id: n.ruleId,
123
+ name: n.ruleName,
124
+ shortDescription: { text: n.ruleName },
125
+ };
126
+ if (n.helpUri)
127
+ rule.helpUri = n.helpUri;
128
+ rulesById.set(n.ruleId, rule);
129
+ }
130
+ const result = {
131
+ ruleId: n.ruleId,
132
+ level: n.level,
133
+ message: { text: n.message },
134
+ };
135
+ if (n.file) {
136
+ const physicalLocation = {
137
+ artifactLocation: { uri: toUri(n.file, baseDir) },
138
+ };
139
+ if (typeof n.line === 'number') {
140
+ physicalLocation.region = { startLine: n.line };
141
+ }
142
+ result.locations = [{ physicalLocation }];
143
+ }
144
+ else if (n.logicalName) {
145
+ result.locations = [{ logicalLocations: [{ fullyQualifiedName: n.logicalName }] }];
146
+ }
147
+ results.push(result);
148
+ }
149
+ return {
150
+ $schema: SARIF_SCHEMA,
151
+ version: '2.1.0',
152
+ runs: [
153
+ {
154
+ tool: {
155
+ driver: {
156
+ name: 'ShieldCortex',
157
+ version,
158
+ informationUri: INFORMATION_URI,
159
+ rules: Array.from(rulesById.values()),
160
+ },
161
+ },
162
+ results,
163
+ },
164
+ ],
165
+ };
166
+ }
@@ -4,6 +4,7 @@
4
4
  * Watches a directory for file changes and incrementally re-scans
5
5
  * only the changed files, printing new findings as they appear.
6
6
  */
7
+ export declare function shouldIgnore(filePath: string): boolean;
7
8
  /**
8
9
  * Watch a directory for changes and incrementally scan changed files.
9
10
  */
@@ -10,6 +10,7 @@ import path from 'path';
10
10
  import crypto from 'crypto';
11
11
  import { scanFile } from './file-scanner.js';
12
12
  import { calculateTrustScore } from './trust-score.js';
13
+ import { ALLOW_HIDDEN_DIRS } from './dir-scanner.js';
13
14
  import { appendActivity, emitDetectionEvent, endWatchSession, heartbeatWatchSession, recordWatchSessionEvent, startWatchSession, } from './activity.js';
14
15
  import { addFindings } from './findings-store.js';
15
16
  // ── Constants ───────────────────────────────────────────────
@@ -34,10 +35,18 @@ const IGNORE_PATH_PATTERNS = [
34
35
  '/tmp/com.apple.',
35
36
  ];
36
37
  // ── Helpers ─────────────────────────────────────────────────
37
- function shouldIgnore(filePath) {
38
+ export function shouldIgnore(filePath) {
38
39
  const parts = filePath.split(path.sep);
39
40
  if (parts.some(p => IGNORE_DIRS.has(p)))
40
41
  return true;
42
+ // Security-relevant hidden dirs (.github/.claude/.cursor/.codex/.vscode/…)
43
+ // are explicitly in scope for watch mode — they hold the agent-instruction /
44
+ // CI surfaces X-Ray exists to protect. Shares ALLOW_HIDDEN_DIRS with the
45
+ // directory scanner so a scan and a watch agree on what's watched. `.git`,
46
+ // `node_modules`, `.venv` etc. are NOT in the allow-list and remain excluded
47
+ // via the IGNORE_DIRS check above (which runs first).
48
+ if (parts.some(p => ALLOW_HIDDEN_DIRS.has(p)))
49
+ return false;
41
50
  // Resolve symlinks to check the real path
42
51
  let abs;
43
52
  try {
@@ -215,6 +215,84 @@ async function getSharedNoveltyGate() {
215
215
  * Uses ShieldCortex's scanSkill via mcporter
216
216
  * @returns {Promise<Array<{hookName: string, threat: string}>>}
217
217
  */
218
+ // Content-hash cache for hook scan_skill verdicts. Byte-identical
219
+ // HOOK.md/handler.js files produce the same sha256, so we skip the (cold MCP)
220
+ // scan_skill shell-out on a cache hit and reuse the stored verdict. Keyed by
221
+ // sha256(content) → "unsafe" | "clean". Persisted to ~/.shieldcortex so the
222
+ // cache survives gateway restarts. A file edit changes the hash and forces a
223
+ // fresh scan, so this never masks a newly-introduced threat.
224
+ const HOOK_SCAN_CACHE_FILE = path.join(homedir(), ".shieldcortex", "openclaw-hook-scan-cache.json");
225
+
226
+ async function loadHookScanCache() {
227
+ try {
228
+ const raw = JSON.parse(await fs.readFile(HOOK_SCAN_CACHE_FILE, "utf-8"));
229
+ if (raw && typeof raw === "object" && !Array.isArray(raw)) return raw;
230
+ } catch { /* no cache yet / unreadable */ }
231
+ return {};
232
+ }
233
+
234
+ async function saveHookScanCache(cache) {
235
+ try {
236
+ await fs.mkdir(path.dirname(HOOK_SCAN_CACHE_FILE), { recursive: true });
237
+ await fs.writeFile(HOOK_SCAN_CACHE_FILE, JSON.stringify(cache) + "\n", "utf-8");
238
+ } catch { /* best-effort — never block bootstrap on cache write */ }
239
+ }
240
+
241
+ function hashHookContent(content) {
242
+ return createHash("sha256").update(content).digest("hex");
243
+ }
244
+
245
+ /**
246
+ * Parse the scan_skill verdict from its structured markdown output.
247
+ *
248
+ * The MCP `scan_skill` tool emits a fixed `**Safe:** Yes|No` field (see
249
+ * server.ts). We parse THAT exact field rather than substring-matching the
250
+ * whole report. The old `result.includes("unsafe")` was wrong twice over: the
251
+ * report never even prints the literal word "unsafe" (the verdict field is
252
+ * `**Safe:** No`), and any finding `description`/`matchedText` that merely
253
+ * mentions "unsafe" (e.g. "unsafe deserialization") would false-positive a
254
+ * clean file into a bootstrap security warning.
255
+ *
256
+ * Returns:
257
+ * true → definitively unsafe (`**Safe:** No`)
258
+ * false → definitively safe (`**Safe:** Yes`)
259
+ * null → verdict could not be parsed (treat as indeterminate; don't cache)
260
+ *
261
+ * @param {string} result
262
+ * @returns {boolean|null}
263
+ */
264
+ function parseScanSkillUnsafe(result) {
265
+ if (typeof result !== "string") return null;
266
+ // Tolerate optional markdown bold markers and surrounding whitespace.
267
+ const m = result.match(/\*{0,2}Safe:\*{0,2}\s*(Yes|No)\b/i);
268
+ if (!m) return null;
269
+ return m[1].toLowerCase() === "no";
270
+ }
271
+
272
+ /**
273
+ * Scan one hook file, reusing a cached verdict when the content hash matches.
274
+ * Mutates `cache` in place and sets `dirty.changed` when a fresh scan runs.
275
+ * @returns {Promise<boolean>} true when the file is flagged unsafe
276
+ */
277
+ async function scanHookFileCached(content, name, format, cache, dirty) {
278
+ const hash = hashHookContent(content);
279
+ const cached = cache[hash];
280
+ if (cached === "unsafe") return true;
281
+ if (cached === "clean") return false;
282
+
283
+ const result = await callCortex("scan_skill", { content, name, format });
284
+ // Only memoise a definitive verdict. A null/failed call is NOT cached, so a
285
+ // transient MCP failure doesn't get pinned as "clean" for an unscanned file.
286
+ if (result == null) return false;
287
+ const unsafe = parseScanSkillUnsafe(result);
288
+ // Indeterminate parse (null) → don't flag and don't cache, so the next scan
289
+ // retries rather than pinning a guessed verdict.
290
+ if (unsafe === null) return false;
291
+ cache[hash] = unsafe ? "unsafe" : "clean";
292
+ dirty.changed = true;
293
+ return unsafe;
294
+ }
295
+
218
296
  async function scanInstalledHooks() {
219
297
  const path = await import("node:path");
220
298
  const { homedir } = await import("node:os");
@@ -224,6 +302,8 @@ async function scanInstalledHooks() {
224
302
 
225
303
  try {
226
304
  const entries = await fs.readdir(hooksDir, { withFileTypes: true });
305
+ const cache = await loadHookScanCache();
306
+ const dirty = { changed: false };
227
307
 
228
308
  for (const entry of entries) {
229
309
  if (!entry.isDirectory()) continue;
@@ -237,13 +317,7 @@ async function scanInstalledHooks() {
237
317
  const hookMdPath = path.join(hookDir, "HOOK.md");
238
318
  try {
239
319
  const hookContent = await fs.readFile(hookMdPath, "utf-8");
240
- const result = await callCortex("scan_skill", {
241
- content: hookContent,
242
- name: entry.name,
243
- format: "hook-md",
244
- });
245
-
246
- if (result && result.includes("unsafe")) {
320
+ if (await scanHookFileCached(hookContent, entry.name, "hook-md", cache, dirty)) {
247
321
  threats.push({ hookName: entry.name, threat: `HOOK.md flagged as unsafe` });
248
322
  }
249
323
  } catch { /* No HOOK.md, skip */ }
@@ -252,17 +326,13 @@ async function scanInstalledHooks() {
252
326
  const handlerPath = path.join(hookDir, "handler.js");
253
327
  try {
254
328
  const handlerContent = await fs.readFile(handlerPath, "utf-8");
255
- const result = await callCortex("scan_skill", {
256
- content: handlerContent,
257
- name: `${entry.name}/handler.js`,
258
- format: "hook-js",
259
- });
260
-
261
- if (result && result.includes("unsafe")) {
329
+ if (await scanHookFileCached(handlerContent, `${entry.name}/handler.js`, "hook-js", cache, dirty)) {
262
330
  threats.push({ hookName: entry.name, threat: `handler.js flagged as unsafe` });
263
331
  }
264
332
  } catch { /* No handler.js, skip */ }
265
333
  }
334
+
335
+ if (dirty.changed) await saveHookScanCache(cache);
266
336
  } catch {
267
337
  // Hooks directory doesn't exist or is unreadable
268
338
  }
@@ -303,10 +373,37 @@ function assistantConversationText(messages: string[]): string {
303
373
  * @param {string} sessionFilePath
304
374
  * @returns {Promise<string[]>} Array of "role: content" strings
305
375
  */
376
+ // Read only the tail of a (potentially large) JSONL transcript. We need the
377
+ // last 30 lines; reading the whole file just to discard the head wastes memory
378
+ // on long sessions. Read up to TAIL_BYTES from the end via a file descriptor.
379
+ // If the window started mid-file we drop its first (possibly partial) line so
380
+ // only complete lines are parsed — JSON.parse failures are skipped anyway, but
381
+ // dropping the fragment keeps the "last 30 complete lines" semantics exact.
382
+ const TAIL_BYTES = 64 * 1024;
383
+
384
+ async function readSessionTail(sessionFilePath) {
385
+ const fh = await fs.open(sessionFilePath, "r");
386
+ try {
387
+ const { size } = await fh.stat();
388
+ if (size <= TAIL_BYTES) {
389
+ // Small file — read it whole (identical to the original behaviour).
390
+ return { text: await fh.readFile("utf-8"), truncated: false };
391
+ }
392
+ const start = size - TAIL_BYTES;
393
+ const buf = Buffer.allocUnsafe(TAIL_BYTES);
394
+ const { bytesRead } = await fh.read(buf, 0, TAIL_BYTES, start);
395
+ return { text: buf.toString("utf-8", 0, bytesRead), truncated: true };
396
+ } finally {
397
+ await fh.close();
398
+ }
399
+ }
400
+
306
401
  async function getRecentMessages(sessionFilePath) {
307
402
  try {
308
- const content = await fs.readFile(sessionFilePath, "utf-8");
309
- const lines = content.trim().split("\n");
403
+ const { text, truncated } = await readSessionTail(sessionFilePath);
404
+ let lines = text.trim().split("\n");
405
+ // Drop the leading partial line when we started reading mid-file.
406
+ if (truncated && lines.length > 1) lines = lines.slice(1);
310
407
  const recentLines = lines.slice(-30);
311
408
 
312
409
  const messages = [];
@@ -665,8 +762,15 @@ async function proactiveRecall(event) {
665
762
  project: "*",
666
763
  });
667
764
 
668
- if (result && typeof result === "string" && result.includes("Found") && !result.includes("Found 0")) {
669
- if (event.messages) {
765
+ // Parse the structured `Found N memor(y|ies):` header (recall.ts) at the
766
+ // START of the result, rather than substring-matching "Found" anywhere —
767
+ // a recalled memory's own content can contain the word "Found" and the old
768
+ // `!result.includes("Found 0")` clause was dead (the empty result is
769
+ // "No memories found...", never "Found 0"). Surface only on N >= 1.
770
+ if (result && typeof result === "string") {
771
+ const m = result.match(/^Found\s+(\d+)\s+memor/m);
772
+ const count = m ? Number(m[1]) : 0;
773
+ if (count >= 1 && event.messages) {
670
774
  event.messages.push(`🧠 ${result}`);
671
775
  }
672
776
  }
@@ -143,10 +143,16 @@ export function createOpenClawRuntime({
143
143
  const serverCmd = await resolveServerCmd();
144
144
 
145
145
  return new Promise((resolve) => {
146
- const cmdArgs = ["mcporter", "call", "--stdio", serverCmd, tool];
147
- for (const [key, value] of Object.entries(args)) {
148
- cmdArgs.push(`${key}:${String(value).replace(/'/g, "''")}`);
149
- }
146
+ // Pass arguments as a single `--args <json>` payload, NOT as per-key
147
+ // `key:value` flags. The old form did `String(value).replace(/'/g, "''")`
148
+ // — SQL-style apostrophe doubling — on each value, which mangled saved
149
+ // memory content (an apostrophe in "it's" became "it''s" and was stored
150
+ // literally; this is a key:value CLI flag, not a bound SQL param, so no
151
+ // such escaping should ever happen). A JSON payload also round-trips
152
+ // colons, spaces, and newlines in content without the `key:value`
153
+ // splitter misreading them. execFile passes argv elements directly (no
154
+ // shell), so the JSON string needs no further quoting/escaping.
155
+ const cmdArgs = ["mcporter", "call", "--stdio", serverCmd, tool, "--args", JSON.stringify(args)];
150
156
 
151
157
  let attempts = 0;
152
158
  const maxAttempts = (options.retries || 0) + 1;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shieldcortex",
3
- "version": "4.31.2",
3
+ "version": "4.32.1",
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",
@@ -30,6 +30,10 @@
30
30
  "import": "./dist/defence/index.js",
31
31
  "types": "./dist/defence/index.d.ts"
32
32
  },
33
+ "./scan": {
34
+ "import": "./dist/scan-only.js",
35
+ "types": "./dist/scan-only.d.ts"
36
+ },
33
37
  "./environment": {
34
38
  "import": "./dist/environment/index.js",
35
39
  "types": "./dist/environment/index.d.ts"
@@ -57,12 +61,13 @@
57
61
  "test": "node scripts/run-jest.mjs",
58
62
  "test:watch": "node scripts/run-jest.mjs --watch",
59
63
  "test:coverage": "node scripts/run-jest.mjs --coverage",
64
+ "test:dist": "node scripts/check-no-bare-require.mjs",
60
65
  "bench": "tsx benchmark/longmemeval/run.ts",
61
66
  "bench:smoke": "SHIELDCORTEX_SKIP_EMBEDDINGS=1 tsx benchmark/longmemeval/run.ts --quiet",
62
67
  "audit:security": "npm audit --audit-level=moderate",
63
68
  "prepack": "node scripts/ensure-bin-executable.mjs",
64
69
  "version": "node scripts/sync-plugin-version.mjs && git add plugins/openclaw/package.json plugins/openclaw/openclaw.plugin.json",
65
- "prepublishOnly": "node scripts/sync-plugin-version.mjs --check && npm run build"
70
+ "prepublishOnly": "node scripts/sync-plugin-version.mjs --check && npm run build && npm run test:dist"
66
71
  },
67
72
  "keywords": [
68
73
  "ai-memory",
@@ -112,7 +117,6 @@
112
117
  "node": ">=20.0.0"
113
118
  },
114
119
  "dependencies": {
115
- "@huggingface/transformers": "^3.7.2",
116
120
  "@modelcontextprotocol/sdk": "^1.0.0",
117
121
  "better-sqlite3": "^12.0.0",
118
122
  "cors": "^2.8.5",
@@ -122,6 +126,9 @@
122
126
  "ws": "^8.18.0",
123
127
  "zod": "^3.23.0"
124
128
  },
129
+ "optionalDependencies": {
130
+ "@huggingface/transformers": "^3.7.2"
131
+ },
125
132
  "devDependencies": {
126
133
  "@types/better-sqlite3": "^7.6.11",
127
134
  "@types/cors": "^2.8.17",
@@ -140,13 +140,18 @@ function verifyNativeModule() {
140
140
  return true;
141
141
  } catch (err) {
142
142
  const detail = err && err.message ? err.message : String(err);
143
+ // Install dir = this package's root (where better-sqlite3 lives). A bare
144
+ // `npm rebuild better-sqlite3` from $HOME is a silent no-op — the cd matters.
145
+ const installDir = join(dirname(fileURLToPath(import.meta.url)), '..');
143
146
  console.log('');
144
147
  console.warn('\x1b[33m[shieldcortex] ⚠ Database engine (better-sqlite3) failed to load.\x1b[0m');
145
148
  console.warn(`[shieldcortex] Node ${process.version} (ABI ${process.versions.modules}) has no matching`);
146
149
  console.warn('[shieldcortex] prebuilt binary and it was not compiled locally.');
147
- console.warn('[shieldcortex] Fix one of these before running ShieldCortex:');
148
- console.warn('[shieldcortex] npm rebuild better-sqlite3 (needs a C/C++ toolchain)');
149
- console.warn('[shieldcortex] or run on Node LTS 20.x / 22.x (ships prebuilt binaries)');
150
+ console.warn('[shieldcortex] Fix it (one command, self-healing):');
151
+ console.warn('[shieldcortex] \x1b[36mshieldcortex repair\x1b[0m');
152
+ console.warn('[shieldcortex] Or rebuild manually IN THE INSTALL DIR (the cd is required):');
153
+ console.warn(`[shieldcortex] cd "${installDir}" && npm rebuild better-sqlite3`);
154
+ console.warn('[shieldcortex] (rebuild needs a C/C++ toolchain — e.g. python3 make g++)');
150
155
  console.warn(`[shieldcortex] Underlying error: ${detail}`);
151
156
  return false;
152
157
  }
@@ -1,20 +0,0 @@
1
- /**
2
- * Embedding Cache
3
- *
4
- * Stores pre-computed embeddings in SQLite to avoid re-embedding on every recall.
5
- * Self-migrating: creates the table on first use.
6
- */
7
- /**
8
- * Get a cached embedding for a memory ID.
9
- * Returns null if not cached or DB unavailable.
10
- */
11
- export declare function getCachedEmbedding(memoryId: number): Float32Array | null;
12
- /**
13
- * Store a computed embedding in the cache.
14
- */
15
- export declare function setCachedEmbedding(memoryId: number, embedding: Float32Array): void;
16
- /**
17
- * Get embedding from cache, or compute + store if missing.
18
- * Returns null if both cache and computation fail.
19
- */
20
- export declare function getOrComputeEmbedding(memoryId: number, text: string): Promise<Float32Array | null>;