shieldcortex 4.31.1 → 4.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (346) 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/mcp.d.ts +13 -0
  239. package/dist/cli/mcp.js +0 -0
  240. package/dist/cli/remember.d.ts +75 -0
  241. package/dist/cli/remember.js +195 -0
  242. package/dist/cloud/config.d.ts +23 -1
  243. package/dist/cloud/config.js +453 -193
  244. package/dist/cloud/quarantine-sync.d.ts +12 -2
  245. package/dist/cloud/quarantine-sync.js +28 -6
  246. package/dist/cloud/sync-queue.d.ts +21 -2
  247. package/dist/cloud/sync-queue.js +124 -29
  248. package/dist/database/better-sqlite3-guard.d.ts +27 -2
  249. package/dist/database/better-sqlite3-guard.js +58 -5
  250. package/dist/database/init.js +85 -17
  251. package/dist/database/inline-schema.js +35 -1
  252. package/dist/database/migrations.js +104 -8
  253. package/dist/database/schema.sql +39 -1
  254. package/dist/defence/audit/queries.d.ts +10 -2
  255. package/dist/defence/audit/queries.js +30 -4
  256. package/dist/defence/audit/retention.d.ts +50 -0
  257. package/dist/defence/audit/retention.js +161 -0
  258. package/dist/defence/credential-leak/entropy.d.ts +11 -0
  259. package/dist/defence/credential-leak/entropy.js +27 -0
  260. package/dist/defence/credential-leak/index.js +27 -1
  261. package/dist/defence/credential-leak/patterns.d.ts +9 -0
  262. package/dist/defence/credential-leak/patterns.js +21 -0
  263. package/dist/defence/custom-patterns/store.js +8 -1
  264. package/dist/defence/custom-rules/store.d.ts +18 -0
  265. package/dist/defence/custom-rules/store.js +63 -0
  266. package/dist/defence/firewall/confusables.d.ts +30 -0
  267. package/dist/defence/firewall/confusables.js +87 -0
  268. package/dist/defence/firewall/encoding-detector.js +23 -9
  269. package/dist/defence/firewall/index.d.ts +11 -1
  270. package/dist/defence/firewall/index.js +34 -1
  271. package/dist/defence/firewall/instruction-detector.js +18 -7
  272. package/dist/defence/firewall/markdown-image-detector.d.ts +34 -0
  273. package/dist/defence/firewall/markdown-image-detector.js +83 -0
  274. package/dist/defence/fragmentation/entity-extractor.js +17 -6
  275. package/dist/defence/index.d.ts +5 -0
  276. package/dist/defence/index.js +8 -0
  277. package/dist/defence/iron-dome/index.js +7 -1
  278. package/dist/defence/pipeline.js +62 -10
  279. package/dist/defence/scan-windows.d.ts +41 -0
  280. package/dist/defence/scan-windows.js +61 -0
  281. package/dist/defence/semantic/attack-corpus.d.ts +22 -0
  282. package/dist/defence/semantic/attack-corpus.js +75 -0
  283. package/dist/defence/semantic/index.d.ts +67 -0
  284. package/dist/defence/semantic/index.js +138 -0
  285. package/dist/defence/skill-scanner/deep-scan.js +35 -15
  286. package/dist/defence/skill-scanner/patterns.d.ts +1 -1
  287. package/dist/defence/skill-scanner/patterns.js +8 -7
  288. package/dist/defence/tool-response-scanner.d.ts +21 -5
  289. package/dist/defence/tool-response-scanner.js +111 -22
  290. package/dist/defence/types.d.ts +11 -1
  291. package/dist/index.d.ts +29 -0
  292. package/dist/index.js +104 -20
  293. package/dist/memory/consolidate.js +1 -1
  294. package/dist/memory/decay.js +3 -1
  295. package/dist/memory/embedding.d.ts +18 -2
  296. package/dist/memory/embedding.js +32 -11
  297. package/dist/memory/expiry.js +1 -1
  298. package/dist/memory/search-recall.js +107 -49
  299. package/dist/memory/search.d.ts +19 -3
  300. package/dist/memory/search.js +25 -10
  301. package/dist/memory/store.d.ts +13 -2
  302. package/dist/memory/store.js +115 -11
  303. package/dist/scan-only.d.ts +64 -0
  304. package/dist/scan-only.js +173 -0
  305. package/dist/server.d.ts +5 -0
  306. package/dist/server.js +6 -4
  307. package/dist/setup/claude-md.js +39 -34
  308. package/dist/setup/codex.js +9 -2
  309. package/dist/setup/copilot.js +160 -47
  310. package/dist/setup/json-config.d.ts +99 -0
  311. package/dist/setup/json-config.js +167 -0
  312. package/dist/setup/migrate.js +1 -1
  313. package/dist/setup/settings-hooks.js +8 -13
  314. package/dist/setup/uninstall.js +1 -21
  315. package/dist/tools/context.d.ts +8 -8
  316. package/dist/tools/forget.d.ts +9 -8
  317. package/dist/tools/forget.js +17 -4
  318. package/dist/tools/recall.d.ts +13 -13
  319. package/dist/tools/remember.d.ts +16 -16
  320. package/dist/tools/remember.js +19 -8
  321. package/dist/worker/brain-worker.d.ts +1 -0
  322. package/dist/worker/brain-worker.js +79 -16
  323. package/dist/worker/types.d.ts +8 -0
  324. package/dist/worker/types.js +8 -0
  325. package/dist/xray/dir-scanner.d.ts +18 -0
  326. package/dist/xray/dir-scanner.js +23 -1
  327. package/dist/xray/file-scanner.js +16 -1
  328. package/dist/xray/findings-store.js +9 -1
  329. package/dist/xray/index.d.ts +2 -0
  330. package/dist/xray/index.js +10 -1
  331. package/dist/xray/npm-inspector.d.ts +31 -0
  332. package/dist/xray/npm-inspector.js +135 -29
  333. package/dist/xray/patterns.d.ts +1 -1
  334. package/dist/xray/patterns.js +20 -23
  335. package/dist/xray/sarif.d.ts +78 -0
  336. package/dist/xray/sarif.js +166 -0
  337. package/dist/xray/watch.d.ts +1 -0
  338. package/dist/xray/watch.js +10 -1
  339. package/hooks/openclaw/cortex-memory/handler.ts +122 -18
  340. package/hooks/openclaw/cortex-memory/runtime.mjs +10 -4
  341. package/package.json +10 -3
  342. package/dist/memory/embedding-cache.d.ts +0 -20
  343. package/dist/memory/embedding-cache.js +0 -91
  344. /package/dashboard/.next/standalone/dashboard/.next/static/{T0hqc-Le01c8QVY0VrHnu → Ox9scglBehbbCk7DD8-Vn}/_buildManifest.js +0 -0
  345. /package/dashboard/.next/standalone/dashboard/.next/static/{T0hqc-Le01c8QVY0VrHnu → Ox9scglBehbbCk7DD8-Vn}/_clientMiddlewareManifest.json +0 -0
  346. /package/dashboard/.next/standalone/dashboard/.next/static/{T0hqc-Le01c8QVY0VrHnu → Ox9scglBehbbCk7DD8-Vn}/_ssgManifest.js +0 -0
@@ -9,44 +9,108 @@ import fs from 'fs';
9
9
  import path from 'path';
10
10
  import os from 'os';
11
11
  import { fileURLToPath } from 'url';
12
+ import { readJsonConfigOrAbort, writeJsonConfigWithBackup, looksLikeShieldcortex, resolveMcpServerCommand, } from './json-config.js';
12
13
  const __filename = fileURLToPath(import.meta.url);
13
14
  const __dirname = path.dirname(__filename);
14
15
  const SERVER_NAME = 'shieldcortex-memory';
15
16
  // MCP entry point: dist/index.js (one level up from dist/setup/)
16
17
  const MCP_ENTRY = path.resolve(__dirname, '..', 'index.js');
17
18
  /**
18
- * Read a JSON file, returning {} if it doesn't exist or is invalid.
19
+ * Read a JSON config file. Missing {}; existing-but-unparseable THROWS.
20
+ *
21
+ * VS Code / Cursor `mcp.json` files are JSONC and may contain `//` comments
22
+ * and trailing commas, which `JSON.parse` rejects. Aborting on that is the
23
+ * CORRECT safe behaviour — silently treating an unparseable-but-present file
24
+ * as `{}` and writing it back would delete every OTHER MCP server the user
25
+ * configured. The thrown error (from readJsonConfigOrAbort) explains that
26
+ * JSONC isn't supported so the user knows why the install stopped.
19
27
  */
20
28
  function readJson(filePath) {
29
+ return readJsonConfigOrAbort(filePath);
30
+ }
31
+ /**
32
+ * Write a JSON config file, backing up any existing file first and creating
33
+ * parent directories as needed.
34
+ */
35
+ function writeJson(filePath, data) {
36
+ writeJsonConfigWithBackup(filePath, data);
37
+ }
38
+ /**
39
+ * Read for the informational `status` command only: never throw. A JSONC/
40
+ * unparseable file is reported as unreadable (null) instead of aborting the
41
+ * whole status run. Mutating paths use readJson (which throws to abort).
42
+ */
43
+ function readJsonForStatus(filePath) {
21
44
  try {
22
- if (!fs.existsSync(filePath))
23
- return {};
24
- const raw = fs.readFileSync(filePath, 'utf-8').trim();
25
- if (!raw)
26
- return {};
27
- return JSON.parse(raw);
45
+ return readJson(filePath);
28
46
  }
29
47
  catch {
30
- return {};
48
+ return null;
31
49
  }
32
50
  }
33
51
  /**
34
- * Write a JSON file, creating parent directories as needed.
52
+ * Uninstall-side read: returns the parsed config, or `null` if the file is
53
+ * unparseable. When it returns `null` for a file that ACTUALLY EXISTS (JSONC /
54
+ * trailing comma), print a warning naming the path — otherwise a real
55
+ * `shieldcortex` entry that can't be parsed is silently left in place while
56
+ * uninstall reports "not configured." An absent file is silent (normal). The
57
+ * caller treats `null` as a no-op (we never corrupt on parse failure).
35
58
  */
36
- function writeJson(filePath, data) {
37
- fs.mkdirSync(path.dirname(filePath), { recursive: true });
38
- fs.writeFileSync(filePath, JSON.stringify(data, null, 2) + '\n');
59
+ function readJsonForRemoval(filePath) {
60
+ const config = readJsonForStatus(filePath);
61
+ if (config === null && fs.existsSync(filePath)) {
62
+ console.warn(` ! ${filePath} is JSONC/unparseable — could not auto-remove; ` +
63
+ `remove the shieldcortex entry manually.`);
64
+ }
65
+ return config;
39
66
  }
40
67
  /**
41
- * Build the server entry for ShieldCortex MCP.
68
+ * Build the VS Code server entry for ShieldCortex MCP.
69
+ *
70
+ * Resolves to the absolute global binary (or `node <absolute dist/index.js>`),
71
+ * never `npx -y` — see resolveMcpServerCommand for why a re-resolving command
72
+ * thrashes the editor's MCP-config hash. VS Code format includes `type`.
42
73
  */
43
74
  function serverEntry() {
75
+ const { command, args } = resolveMcpServerCommand(MCP_ENTRY);
44
76
  return {
45
77
  type: 'stdio',
46
- command: 'node',
47
- args: [MCP_ENTRY],
78
+ command,
79
+ args,
48
80
  };
49
81
  }
82
+ /**
83
+ * Build the Cursor server entry. Same resolved command as VS Code, but Cursor's
84
+ * schema omits the `type` field.
85
+ */
86
+ function cursorServerEntry() {
87
+ const { command, args } = resolveMcpServerCommand(MCP_ENTRY);
88
+ return { command, args };
89
+ }
90
+ /**
91
+ * Decide what to do with an EXISTING entry under our server name.
92
+ *
93
+ * - not ours (looksLikeShieldcortex false) → leave it alone (`'foreign'`)
94
+ * - ours but the command/args already match the desired entry → `'current'`
95
+ * - ours but stale (old `node dist/index.js`, `npx -y shieldcortex`, a stale
96
+ * absolute path, …) → `'stale'`, caller refreshes it
97
+ *
98
+ * `SERVER_NAME` is ShieldCortex-specific (unlike the generic `memory` key in
99
+ * ~/.claude.json), so a present entry under it is almost always ours — but we
100
+ * still guard with looksLikeShieldcortex so a user who parked an unrelated
101
+ * server under the same name isn't clobbered.
102
+ */
103
+ function classifyExisting(existing, desired) {
104
+ if (!looksLikeShieldcortex(existing))
105
+ return 'foreign';
106
+ const e = existing;
107
+ const sameCommand = e.command === desired.command;
108
+ const desiredArgs = desired.args ?? [];
109
+ const sameArgs = Array.isArray(e.args) &&
110
+ e.args.length === desiredArgs.length &&
111
+ e.args.every((v, i) => v === desiredArgs[i]);
112
+ return sameCommand && sameArgs ? 'current' : 'stale';
113
+ }
50
114
  // ── VS Code ──
51
115
  /**
52
116
  * Find VS Code user config directories (supports standard + Insiders).
@@ -75,8 +139,14 @@ function findVsCodeDirs() {
75
139
  return dirs;
76
140
  }
77
141
  /**
78
- * Add ShieldCortex to a VS Code mcp.json file.
142
+ * Add (or refresh) ShieldCortex in a VS Code mcp.json file.
79
143
  * VS Code format: { "servers": { "name": { ... } } }
144
+ *
145
+ * On re-install, a stale ShieldCortex entry (e.g. an old `node dist/index.js`
146
+ * path or an `npx -y` command from a previous version) is UPDATED to the
147
+ * currently-resolved command rather than left in place — otherwise the editor
148
+ * keeps launching the wrong/old server forever. A foreign entry parked under
149
+ * our name is never touched.
80
150
  */
81
151
  function addToVsCode(configDir) {
82
152
  const mcpPath = path.join(configDir, 'mcp.json');
@@ -85,19 +155,36 @@ function addToVsCode(configDir) {
85
155
  config.servers = {};
86
156
  }
87
157
  const servers = config.servers;
158
+ const desired = serverEntry();
88
159
  if (servers[SERVER_NAME]) {
89
- return false; // already configured
160
+ const verdict = classifyExisting(servers[SERVER_NAME], desired);
161
+ if (verdict === 'foreign')
162
+ return 'foreign';
163
+ if (verdict === 'current')
164
+ return 'unchanged';
165
+ servers[SERVER_NAME] = desired; // stale → refresh
166
+ writeJson(mcpPath, config);
167
+ return 'refreshed';
90
168
  }
91
- servers[SERVER_NAME] = serverEntry();
169
+ servers[SERVER_NAME] = desired;
92
170
  writeJson(mcpPath, config);
93
- return true;
171
+ return 'added';
94
172
  }
95
173
  /**
96
174
  * Remove ShieldCortex from a VS Code mcp.json file.
175
+ *
176
+ * If the file is unparseable (JSONC), leave it untouched and report nothing
177
+ * removed — same "don't corrupt on parse failure" stance as readJson, but on
178
+ * the uninstall side we degrade to a no-op rather than throwing through the
179
+ * uninstaller loop. A present-but-unparseable file warns (via
180
+ * readJsonForRemoval) so the user isn't told "not configured" while an entry
181
+ * silently lingers.
97
182
  */
98
183
  function removeFromVsCode(configDir) {
99
184
  const mcpPath = path.join(configDir, 'mcp.json');
100
- const config = readJson(mcpPath);
185
+ const config = readJsonForRemoval(mcpPath);
186
+ if (config === null)
187
+ return false;
101
188
  if (!config.servers || typeof config.servers !== 'object')
102
189
  return false;
103
190
  const servers = config.servers;
@@ -127,23 +214,32 @@ function addToCursor(cursorDir) {
127
214
  config.mcpServers = {};
128
215
  }
129
216
  const servers = config.mcpServers;
217
+ const desired = cursorServerEntry(); // Cursor schema omits "type"
130
218
  if (servers[SERVER_NAME]) {
131
- return false; // already configured
219
+ const verdict = classifyExisting(servers[SERVER_NAME], desired);
220
+ if (verdict === 'foreign')
221
+ return 'foreign';
222
+ if (verdict === 'current')
223
+ return 'unchanged';
224
+ servers[SERVER_NAME] = desired; // stale → refresh
225
+ writeJson(mcpPath, config);
226
+ return 'refreshed';
132
227
  }
133
- // Cursor doesn't use "type" field
134
- servers[SERVER_NAME] = {
135
- command: 'node',
136
- args: [MCP_ENTRY],
137
- };
228
+ servers[SERVER_NAME] = desired;
138
229
  writeJson(mcpPath, config);
139
- return true;
230
+ return 'added';
140
231
  }
141
232
  /**
142
233
  * Remove ShieldCortex from Cursor's mcp.json.
234
+ *
235
+ * Unparseable file → no-op (don't corrupt on parse failure), as in
236
+ * removeFromVsCode; a present-but-unparseable file warns via readJsonForRemoval.
143
237
  */
144
238
  function removeFromCursor(cursorDir) {
145
239
  const mcpPath = path.join(cursorDir, 'mcp.json');
146
- const config = readJson(mcpPath);
240
+ const config = readJsonForRemoval(mcpPath);
241
+ if (config === null)
242
+ return false;
147
243
  if (!config.mcpServers || typeof config.mcpServers !== 'object')
148
244
  return false;
149
245
  const servers = config.mcpServers;
@@ -162,17 +258,31 @@ export async function installCopilot() {
162
258
  process.exit(1);
163
259
  }
164
260
  let installed = 0;
261
+ // Report an add/refresh/unchanged/foreign outcome with the right glyph + text,
262
+ // and count add+refresh toward `installed` (both mutate the config).
263
+ const report = (outcome, label, target) => {
264
+ switch (outcome) {
265
+ case 'added':
266
+ console.log(` ✓ ${label} — added to ${target}`);
267
+ installed++;
268
+ break;
269
+ case 'refreshed':
270
+ console.log(` ↑ ${label} — refreshed stale entry in ${target}`);
271
+ installed++;
272
+ break;
273
+ case 'unchanged':
274
+ console.log(` · ${label} — already configured`);
275
+ break;
276
+ case 'foreign':
277
+ console.warn(` ! ${label} — '${SERVER_NAME}' exists but is not ShieldCortex-owned; leaving it alone`);
278
+ break;
279
+ }
280
+ };
165
281
  // VS Code
166
282
  const vscodeDirs = findVsCodeDirs();
167
283
  for (const dir of vscodeDirs) {
168
284
  const variant = path.basename(path.dirname(dir)); // "Code" or "Code - Insiders"
169
- if (addToVsCode(dir)) {
170
- console.log(` ✓ VS Code (${variant}) — added to ${path.join(dir, 'mcp.json')}`);
171
- installed++;
172
- }
173
- else {
174
- console.log(` · VS Code (${variant}) — already configured`);
175
- }
285
+ report(addToVsCode(dir), `VS Code (${variant})`, path.join(dir, 'mcp.json'));
176
286
  }
177
287
  if (vscodeDirs.length === 0) {
178
288
  console.log(' · VS Code — not found');
@@ -180,13 +290,7 @@ export async function installCopilot() {
180
290
  // Cursor
181
291
  const cursorDir = findCursorDir();
182
292
  if (cursorDir) {
183
- if (addToCursor(cursorDir)) {
184
- console.log(` ✓ Cursor — added to ${path.join(cursorDir, 'mcp.json')}`);
185
- installed++;
186
- }
187
- else {
188
- console.log(' · Cursor — already configured');
189
- }
293
+ report(addToCursor(cursorDir), 'Cursor', path.join(cursorDir, 'mcp.json'));
190
294
  }
191
295
  else {
192
296
  console.log(' · Cursor — not found');
@@ -248,7 +352,11 @@ export async function copilotStatus() {
248
352
  for (const dir of vscodeDirs) {
249
353
  const variant = path.basename(path.dirname(dir));
250
354
  const mcpPath = path.join(dir, 'mcp.json');
251
- const config = readJson(mcpPath);
355
+ const config = readJsonForStatus(mcpPath);
356
+ if (config === null) {
357
+ console.log(`VS Code (${variant}): unreadable (not valid JSON — JSONC/comments not supported)`);
358
+ continue;
359
+ }
252
360
  const servers = (config.servers ?? {});
253
361
  const installed = !!servers[SERVER_NAME];
254
362
  console.log(`VS Code (${variant}): ${installed ? 'configured' : 'not configured'}`);
@@ -260,10 +368,15 @@ export async function copilotStatus() {
260
368
  }
261
369
  else {
262
370
  const mcpPath = path.join(cursorDir, 'mcp.json');
263
- const config = readJson(mcpPath);
264
- const servers = (config.mcpServers ?? {});
265
- const installed = !!servers[SERVER_NAME];
266
- console.log(`Cursor: ${installed ? 'configured' : 'not configured'}`);
371
+ const config = readJsonForStatus(mcpPath);
372
+ if (config === null) {
373
+ console.log('Cursor: unreadable (not valid JSON — JSONC/comments not supported)');
374
+ }
375
+ else {
376
+ const servers = (config.mcpServers ?? {});
377
+ const installed = !!servers[SERVER_NAME];
378
+ console.log(`Cursor: ${installed ? 'configured' : 'not configured'}`);
379
+ }
267
380
  }
268
381
  }
269
382
  export async function handleCopilotCommand(subcommand) {
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Shared, dependency-free helpers for reading and writing user-owned JSON
3
+ * config files during install.
4
+ *
5
+ * The whole point: an installer must NEVER replace a user's config because a
6
+ * file was momentarily unparseable (trailing comma, JSONC `// comments` — VS
7
+ * Code / Cursor config files are JSONC — or a partial concurrent write by
8
+ * Claude Code itself). The historical bug: read with `catch { return {} }`,
9
+ * then unconditionally write the mutated object back, wiping everything the
10
+ * file held.
11
+ *
12
+ * This mirrors the discipline the uninstall path already follows
13
+ * (uninstall.ts: "aborting to avoid corruption"): if a file EXISTS but won't
14
+ * parse, abort — don't pretend it was empty.
15
+ */
16
+ /** Suffix for the safety copy written before any mutating write. */
17
+ export declare const BACKUP_SUFFIX = ".bak-shieldcortex";
18
+ /**
19
+ * Read a JSON config file.
20
+ *
21
+ * - Missing file → `{}` (a fresh install legitimately starts from nothing).
22
+ * - Exists and parses → the parsed object.
23
+ * - Exists but does NOT parse → THROW (never silently return `{}`, which would
24
+ * let the caller overwrite the file with only its own entries).
25
+ *
26
+ * VS Code / Cursor `mcp.json` files are JSONC and may contain `//` comments;
27
+ * `JSON.parse` rejects those. That rejection is the CORRECT safe outcome here
28
+ * (better to abort than wipe), so the thrown message says so explicitly rather
29
+ * than silently stripping comments and rewriting (which would still lose the
30
+ * user's formatting and comments).
31
+ */
32
+ export declare function readJsonConfigOrAbort(filePath: string): Record<string, any>;
33
+ /**
34
+ * Write a JSON config file atomically, backing up any existing file first.
35
+ *
36
+ * The torn-write hazard this guards against: an in-place `fs.writeFileSync`
37
+ * can leave a TRUNCATED file if the process dies mid-write — and the targets
38
+ * here include `~/.claude.json`, Claude Code's primary state file. So instead
39
+ * the new content is written to a sibling temp file and then `renameSync`d
40
+ * into place (atomic on the same filesystem); a reader never sees a partial
41
+ * file, and a crash between temp-write and rename leaves the ORIGINAL intact.
42
+ *
43
+ * Sequence:
44
+ * 1. Ensure the parent directory exists.
45
+ * 2. If the target already exists, copy it to `<path>${BACKUP_SUFFIX}` first.
46
+ * 3. Write the new JSON (2-space indent + trailing newline) to a temp file.
47
+ * 4. `renameSync` the temp file over the target.
48
+ *
49
+ * The original file is never deleted or overwritten before step 4 succeeds, so
50
+ * a failure during the temp-write leaves the live config untouched; the temp
51
+ * file is cleaned up on failure. Mirrors the tmp+rename precedent in
52
+ * `openclaw.ts`.
53
+ *
54
+ * Note: the backup is SINGLE-GENERATION — it captures the pre-write state and
55
+ * is overwritten on every run, so it only ever reflects the file as it was
56
+ * immediately before the most recent write.
57
+ */
58
+ export declare function writeJsonConfigWithBackup(filePath: string, data: unknown): void;
59
+ /**
60
+ * Ownership check: an `mcpServers` entry "looks like ShieldCortex" if its
61
+ * command path or any args string contains a `shieldcortex` / `shield-cortex`
62
+ * token.
63
+ *
64
+ * `mcpServers.memory` is a generic key — the official upstream
65
+ * `@modelcontextprotocol/server-memory` registers under the same name — so
66
+ * BOTH the install path (before overwriting an entry) and the uninstall path
67
+ * (before deleting one) MUST verify ownership or risk clobbering an unrelated
68
+ * MCP server the user installed. This is the single canonical definition;
69
+ * `claude-md.ts` and `uninstall.ts` import it rather than each holding a copy.
70
+ */
71
+ export declare function looksLikeShieldcortex(entry: unknown): boolean;
72
+ /** A resolved MCP stdio command: an executable plus its argv. */
73
+ export interface McpServerCommand {
74
+ command: string;
75
+ args: string[];
76
+ }
77
+ /**
78
+ * Resolve the stdio command an editor (Codex / VS Code Copilot / Cursor) should
79
+ * launch to start the ShieldCortex MCP server.
80
+ *
81
+ * Mirrors `claude-md.ts setupGlobalMcp`'s v4.11.1 fix: prefer the installed
82
+ * GLOBAL binary, resolved to an ABSOLUTE path via `which`/`where`, and invoke
83
+ * it directly. The hazard being avoided is `npx -y shieldcortex` as the MCP
84
+ * command — `npx` re-resolves dynamically on every spawn, so a cache shift
85
+ * (version drift / fresh publish / cache miss) silently changes the effective
86
+ * command. Editors hash their MCP config; a changed command changes the hash
87
+ * and resets the active session, wiping context (the 2026-04-22 fleet "fresh
88
+ * session" bug). An absolute path never drifts.
89
+ *
90
+ * Fallback when no global binary is on PATH: `node <absoluteDistEntry>` — the
91
+ * bundled `dist/index.js` resolved to an absolute path from this module's
92
+ * location. That is ALSO stable (a fixed absolute path, not `npx`), so a
93
+ * single-shot install without a global binary still gets a hash-stable command
94
+ * rather than re-introducing the npx hash-thrash class.
95
+ *
96
+ * @param distEntry Absolute path to the package's `dist/index.js` (the caller
97
+ * resolves it from its own `__dirname` so we don't guess the layout).
98
+ */
99
+ export declare function resolveMcpServerCommand(distEntry: string): McpServerCommand;
@@ -0,0 +1,167 @@
1
+ /**
2
+ * Shared, dependency-free helpers for reading and writing user-owned JSON
3
+ * config files during install.
4
+ *
5
+ * The whole point: an installer must NEVER replace a user's config because a
6
+ * file was momentarily unparseable (trailing comma, JSONC `// comments` — VS
7
+ * Code / Cursor config files are JSONC — or a partial concurrent write by
8
+ * Claude Code itself). The historical bug: read with `catch { return {} }`,
9
+ * then unconditionally write the mutated object back, wiping everything the
10
+ * file held.
11
+ *
12
+ * This mirrors the discipline the uninstall path already follows
13
+ * (uninstall.ts: "aborting to avoid corruption"): if a file EXISTS but won't
14
+ * parse, abort — don't pretend it was empty.
15
+ */
16
+ import fs from 'fs';
17
+ import path from 'path';
18
+ import { execSync } from 'child_process';
19
+ /** Suffix for the safety copy written before any mutating write. */
20
+ export const BACKUP_SUFFIX = '.bak-shieldcortex';
21
+ /**
22
+ * Read a JSON config file.
23
+ *
24
+ * - Missing file → `{}` (a fresh install legitimately starts from nothing).
25
+ * - Exists and parses → the parsed object.
26
+ * - Exists but does NOT parse → THROW (never silently return `{}`, which would
27
+ * let the caller overwrite the file with only its own entries).
28
+ *
29
+ * VS Code / Cursor `mcp.json` files are JSONC and may contain `//` comments;
30
+ * `JSON.parse` rejects those. That rejection is the CORRECT safe outcome here
31
+ * (better to abort than wipe), so the thrown message says so explicitly rather
32
+ * than silently stripping comments and rewriting (which would still lose the
33
+ * user's formatting and comments).
34
+ */
35
+ export function readJsonConfigOrAbort(filePath) {
36
+ if (!fs.existsSync(filePath)) {
37
+ return {};
38
+ }
39
+ const raw = fs.readFileSync(filePath, 'utf-8');
40
+ // An existing but empty/whitespace file is treated as empty config — there
41
+ // is no content to lose, so this is not the corruption case.
42
+ if (raw.trim() === '') {
43
+ return {};
44
+ }
45
+ try {
46
+ return JSON.parse(raw);
47
+ }
48
+ catch (err) {
49
+ throw new Error(`ShieldCortex: refusing to overwrite ${filePath} — it exists but is not valid JSON ` +
50
+ `(${err.message}). Aborting to avoid corruption. ` +
51
+ `Note: JSON-with-comments (JSONC, // comments) and trailing commas are not supported here. ` +
52
+ `Fix or remove the file, then re-run the installer.`);
53
+ }
54
+ }
55
+ /**
56
+ * Write a JSON config file atomically, backing up any existing file first.
57
+ *
58
+ * The torn-write hazard this guards against: an in-place `fs.writeFileSync`
59
+ * can leave a TRUNCATED file if the process dies mid-write — and the targets
60
+ * here include `~/.claude.json`, Claude Code's primary state file. So instead
61
+ * the new content is written to a sibling temp file and then `renameSync`d
62
+ * into place (atomic on the same filesystem); a reader never sees a partial
63
+ * file, and a crash between temp-write and rename leaves the ORIGINAL intact.
64
+ *
65
+ * Sequence:
66
+ * 1. Ensure the parent directory exists.
67
+ * 2. If the target already exists, copy it to `<path>${BACKUP_SUFFIX}` first.
68
+ * 3. Write the new JSON (2-space indent + trailing newline) to a temp file.
69
+ * 4. `renameSync` the temp file over the target.
70
+ *
71
+ * The original file is never deleted or overwritten before step 4 succeeds, so
72
+ * a failure during the temp-write leaves the live config untouched; the temp
73
+ * file is cleaned up on failure. Mirrors the tmp+rename precedent in
74
+ * `openclaw.ts`.
75
+ *
76
+ * Note: the backup is SINGLE-GENERATION — it captures the pre-write state and
77
+ * is overwritten on every run, so it only ever reflects the file as it was
78
+ * immediately before the most recent write.
79
+ */
80
+ export function writeJsonConfigWithBackup(filePath, data) {
81
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
82
+ if (fs.existsSync(filePath)) {
83
+ fs.copyFileSync(filePath, `${filePath}${BACKUP_SUFFIX}`);
84
+ }
85
+ const tmp = `${filePath}.tmp-shieldcortex`;
86
+ try {
87
+ fs.writeFileSync(tmp, JSON.stringify(data, null, 2) + '\n', 'utf-8');
88
+ fs.renameSync(tmp, filePath);
89
+ }
90
+ catch (err) {
91
+ // Leave the original file untouched; just clean up the temp file.
92
+ try {
93
+ if (fs.existsSync(tmp))
94
+ fs.unlinkSync(tmp);
95
+ }
96
+ catch {
97
+ /* best-effort cleanup */
98
+ }
99
+ throw err;
100
+ }
101
+ }
102
+ /**
103
+ * Ownership check: an `mcpServers` entry "looks like ShieldCortex" if its
104
+ * command path or any args string contains a `shieldcortex` / `shield-cortex`
105
+ * token.
106
+ *
107
+ * `mcpServers.memory` is a generic key — the official upstream
108
+ * `@modelcontextprotocol/server-memory` registers under the same name — so
109
+ * BOTH the install path (before overwriting an entry) and the uninstall path
110
+ * (before deleting one) MUST verify ownership or risk clobbering an unrelated
111
+ * MCP server the user installed. This is the single canonical definition;
112
+ * `claude-md.ts` and `uninstall.ts` import it rather than each holding a copy.
113
+ */
114
+ export function looksLikeShieldcortex(entry) {
115
+ if (!entry || typeof entry !== 'object')
116
+ return false;
117
+ const e = entry;
118
+ const tokens = [];
119
+ if (typeof e.command === 'string')
120
+ tokens.push(e.command);
121
+ if (Array.isArray(e.args))
122
+ for (const a of e.args)
123
+ if (typeof a === 'string')
124
+ tokens.push(a);
125
+ return tokens.some((t) => /shield[-]?cortex/i.test(t));
126
+ }
127
+ /**
128
+ * Resolve the stdio command an editor (Codex / VS Code Copilot / Cursor) should
129
+ * launch to start the ShieldCortex MCP server.
130
+ *
131
+ * Mirrors `claude-md.ts setupGlobalMcp`'s v4.11.1 fix: prefer the installed
132
+ * GLOBAL binary, resolved to an ABSOLUTE path via `which`/`where`, and invoke
133
+ * it directly. The hazard being avoided is `npx -y shieldcortex` as the MCP
134
+ * command — `npx` re-resolves dynamically on every spawn, so a cache shift
135
+ * (version drift / fresh publish / cache miss) silently changes the effective
136
+ * command. Editors hash their MCP config; a changed command changes the hash
137
+ * and resets the active session, wiping context (the 2026-04-22 fleet "fresh
138
+ * session" bug). An absolute path never drifts.
139
+ *
140
+ * Fallback when no global binary is on PATH: `node <absoluteDistEntry>` — the
141
+ * bundled `dist/index.js` resolved to an absolute path from this module's
142
+ * location. That is ALSO stable (a fixed absolute path, not `npx`), so a
143
+ * single-shot install without a global binary still gets a hash-stable command
144
+ * rather than re-introducing the npx hash-thrash class.
145
+ *
146
+ * @param distEntry Absolute path to the package's `dist/index.js` (the caller
147
+ * resolves it from its own `__dirname` so we don't guess the layout).
148
+ */
149
+ export function resolveMcpServerCommand(distEntry) {
150
+ try {
151
+ const whichCmd = process.platform === 'win32' ? 'where' : 'which';
152
+ const resolved = execSync(`${whichCmd} shieldcortex`, {
153
+ encoding: 'utf-8',
154
+ stdio: ['ignore', 'pipe', 'ignore'],
155
+ })
156
+ .trim()
157
+ .split('\n')[0]
158
+ .trim();
159
+ if (resolved && fs.existsSync(resolved)) {
160
+ return { command: resolved, args: [] };
161
+ }
162
+ }
163
+ catch {
164
+ // No global install on PATH — fall through to the bundled entry.
165
+ }
166
+ return { command: 'node', args: [distEntry] };
167
+ }
@@ -8,6 +8,7 @@ import fs from 'fs';
8
8
  import path from 'path';
9
9
  import os from 'os';
10
10
  import { execSync } from 'child_process';
11
+ import Database from '../database/better-sqlite3-guard.js';
11
12
  const SETTINGS_PATH = path.join(os.homedir(), '.claude', 'settings.json');
12
13
  const CLAUDE_MD_PATH = path.join(os.homedir(), '.claude', 'CLAUDE.md');
13
14
  const NEW_DB_DIR = path.join(os.homedir(), '.shieldcortex');
@@ -224,7 +225,6 @@ export function migrateDatabase() {
224
225
  }
225
226
  // Target exists — merge memories that don't already exist
226
227
  try {
227
- const Database = require('better-sqlite3');
228
228
  const db = new Database(targetPath);
229
229
  db.pragma('journal_mode = WAL');
230
230
  db.pragma('busy_timeout = 5000');
@@ -1,10 +1,10 @@
1
1
  /**
2
2
  * Auto-configure Claude Code hooks in ~/.claude/settings.json.
3
3
  */
4
- import fs from 'fs';
5
4
  import path from 'path';
6
5
  import os from 'os';
7
6
  import { setAutoMemoryEnableConfig } from '../cloud/config.js';
7
+ import { readJsonConfigOrAbort, writeJsonConfigWithBackup } from './json-config.js';
8
8
  const SETTINGS_PATH = path.join(os.homedir(), '.claude', 'settings.json');
9
9
  const CORTEX_HOOKS = {
10
10
  PreCompact: {
@@ -52,21 +52,16 @@ const SESSION_END_HOOK = {
52
52
  function hasCortexHook(entries) {
53
53
  return entries.some((e) => e.hooks?.some((h) => typeof h.command === 'string' && h.command.includes('shieldcortex')));
54
54
  }
55
+ // Reads settings.json. A missing file yields {} (fresh install); a file that
56
+ // EXISTS but won't parse THROWS — setupHooks() must surface that and abort
57
+ // rather than write a hooks-only file over the user's permissions/env/model
58
+ // settings. Mirrors uninstall.ts's "aborting to avoid corruption" discipline.
55
59
  function readSettings() {
56
- if (!fs.existsSync(SETTINGS_PATH)) {
57
- return {};
58
- }
59
- try {
60
- return JSON.parse(fs.readFileSync(SETTINGS_PATH, 'utf-8'));
61
- }
62
- catch {
63
- return {};
64
- }
60
+ return readJsonConfigOrAbort(SETTINGS_PATH);
65
61
  }
62
+ // Backs up an existing settings.json before overwriting it.
66
63
  function writeSettings(settings) {
67
- const dir = path.dirname(SETTINGS_PATH);
68
- fs.mkdirSync(dir, { recursive: true });
69
- fs.writeFileSync(SETTINGS_PATH, JSON.stringify(settings, null, 2) + '\n', 'utf-8');
64
+ writeJsonConfigWithBackup(SETTINGS_PATH, settings);
70
65
  }
71
66
  /**
72
67
  * Migrate stale `npx shieldcortex hook ...` commands to `shieldcortex hook ...`.
@@ -12,6 +12,7 @@ import os from 'os';
12
12
  import readline from 'readline';
13
13
  import { uninstallService } from '../service/install.js';
14
14
  import { uninstallOpenClawHook } from './openclaw.js';
15
+ import { looksLikeShieldcortex } from './json-config.js';
15
16
  /**
16
17
  * Check if the current process is running in an agent context.
17
18
  * Agents (sub-agents) should not be able to uninstall ShieldCortex.
@@ -128,27 +129,6 @@ export function removeClaudeMdBlock() {
128
129
  fs.writeFileSync(CLAUDE_MD_PATH, newContent, 'utf-8');
129
130
  console.log('CLAUDE.md: removed ShieldCortex memory instructions block.');
130
131
  }
131
- /**
132
- * Ownership check: an mcpServers entry "looks like ShieldCortex" if its
133
- * command path or args contain a shieldcortex / shield-cortex token.
134
- * `mcpServers.memory` is a generic key — the official upstream
135
- * `@modelcontextprotocol/server-memory` registers under the same name —
136
- * so we MUST verify ownership before deletion or risk clobbering an
137
- * unrelated MCP server the user installed.
138
- */
139
- function looksLikeShieldcortex(entry) {
140
- if (!entry || typeof entry !== 'object')
141
- return false;
142
- const e = entry;
143
- const tokens = [];
144
- if (typeof e.command === 'string')
145
- tokens.push(e.command);
146
- if (Array.isArray(e.args))
147
- for (const a of e.args)
148
- if (typeof a === 'string')
149
- tokens.push(a);
150
- return tokens.some((t) => /shield[-]?cortex/i.test(t));
151
- }
152
132
  /**
153
133
  * Remove the ShieldCortex MCP server entry from ~/.claude.json.
154
134
  *