shieldcortex 4.13.0 → 4.14.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 (235) hide show
  1. package/dashboard/.next/standalone/dashboard/.next/BUILD_ID +1 -1
  2. package/dashboard/.next/standalone/dashboard/.next/build-manifest.json +2 -2
  3. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.html +2 -2
  4. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.rsc +1 -1
  5. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  6. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  7. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  8. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  9. package/dashboard/.next/standalone/dashboard/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  10. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.html +1 -1
  11. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.rsc +1 -1
  12. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  13. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  14. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  15. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  16. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  17. package/dashboard/.next/standalone/dashboard/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  18. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.html +1 -1
  19. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.rsc +1 -1
  20. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin/__PAGE__.segment.rsc +1 -1
  21. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk/admin.segment.rsc +1 -1
  22. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  23. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_full.segment.rsc +1 -1
  24. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_head.segment.rsc +1 -1
  25. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_index.segment.rsc +1 -1
  26. package/dashboard/.next/standalone/dashboard/.next/server/app/admin.segments/_tree.segment.rsc +1 -1
  27. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.html +1 -1
  28. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.rsc +1 -1
  29. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud/__PAGE__.segment.rsc +1 -1
  30. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk/cloud.segment.rsc +1 -1
  31. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  32. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_full.segment.rsc +1 -1
  33. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_head.segment.rsc +1 -1
  34. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_index.segment.rsc +1 -1
  35. package/dashboard/.next/standalone/dashboard/.next/server/app/cloud.segments/_tree.segment.rsc +1 -1
  36. package/dashboard/.next/standalone/dashboard/.next/server/app/index.html +1 -1
  37. package/dashboard/.next/standalone/dashboard/.next/server/app/index.rsc +1 -1
  38. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  39. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_full.segment.rsc +1 -1
  40. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_head.segment.rsc +1 -1
  41. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_index.segment.rsc +1 -1
  42. package/dashboard/.next/standalone/dashboard/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  43. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.html +1 -1
  44. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.rsc +1 -1
  45. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture/__PAGE__.segment.rsc +1 -1
  46. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory/capture.segment.rsc +1 -1
  47. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  48. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  49. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_full.segment.rsc +1 -1
  50. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_head.segment.rsc +1 -1
  51. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_index.segment.rsc +1 -1
  52. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/capture.segments/_tree.segment.rsc +1 -1
  53. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.html +1 -1
  54. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.rsc +1 -1
  55. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph/__PAGE__.segment.rsc +1 -1
  56. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory/graph.segment.rsc +1 -1
  57. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  58. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  59. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_full.segment.rsc +1 -1
  60. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_head.segment.rsc +1 -1
  61. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_index.segment.rsc +1 -1
  62. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/graph.segments/_tree.segment.rsc +1 -1
  63. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.html +1 -1
  64. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.rsc +1 -1
  65. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall/__PAGE__.segment.rsc +1 -1
  66. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory/recall.segment.rsc +1 -1
  67. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  68. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  69. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_full.segment.rsc +1 -1
  70. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_head.segment.rsc +1 -1
  71. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_index.segment.rsc +1 -1
  72. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/recall.segments/_tree.segment.rsc +1 -1
  73. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.html +1 -1
  74. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.rsc +1 -1
  75. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review/__PAGE__.segment.rsc +1 -1
  76. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory/review.segment.rsc +1 -1
  77. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  78. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  79. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_full.segment.rsc +1 -1
  80. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_head.segment.rsc +1 -1
  81. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_index.segment.rsc +1 -1
  82. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/review.segments/_tree.segment.rsc +1 -1
  83. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.html +1 -1
  84. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.rsc +1 -1
  85. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline/__PAGE__.segment.rsc +1 -1
  86. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory/timeline.segment.rsc +1 -1
  87. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  88. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  89. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_full.segment.rsc +1 -1
  90. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_head.segment.rsc +1 -1
  91. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_index.segment.rsc +1 -1
  92. package/dashboard/.next/standalone/dashboard/.next/server/app/memory/timeline.segments/_tree.segment.rsc +1 -1
  93. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.html +1 -1
  94. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.rsc +1 -1
  95. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory/__PAGE__.segment.rsc +1 -1
  96. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk/memory.segment.rsc +1 -1
  97. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  98. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_full.segment.rsc +1 -1
  99. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_head.segment.rsc +1 -1
  100. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_index.segment.rsc +1 -1
  101. package/dashboard/.next/standalone/dashboard/.next/server/app/memory.segments/_tree.segment.rsc +1 -1
  102. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.html +1 -1
  103. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.rsc +1 -1
  104. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview/__PAGE__.segment.rsc +1 -1
  105. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk/overview.segment.rsc +1 -1
  106. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  107. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_full.segment.rsc +1 -1
  108. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_head.segment.rsc +1 -1
  109. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_index.segment.rsc +1 -1
  110. package/dashboard/.next/standalone/dashboard/.next/server/app/overview.segments/_tree.segment.rsc +1 -1
  111. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.html +1 -1
  112. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.rsc +1 -1
  113. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit/__PAGE__.segment.rsc +1 -1
  114. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection/audit.segment.rsc +1 -1
  115. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  116. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  117. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_full.segment.rsc +1 -1
  118. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_head.segment.rsc +1 -1
  119. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_index.segment.rsc +1 -1
  120. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/audit.segments/_tree.segment.rsc +1 -1
  121. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.html +1 -1
  122. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.rsc +1 -1
  123. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts/__PAGE__.segment.rsc +1 -1
  124. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection/intercepts.segment.rsc +1 -1
  125. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  126. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  127. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_full.segment.rsc +1 -1
  128. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_head.segment.rsc +1 -1
  129. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_index.segment.rsc +1 -1
  130. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/intercepts.segments/_tree.segment.rsc +1 -1
  131. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.html +1 -1
  132. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.rsc +1 -1
  133. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome/__PAGE__.segment.rsc +1 -1
  134. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection/iron-dome.segment.rsc +1 -1
  135. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  136. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  137. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_full.segment.rsc +1 -1
  138. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_head.segment.rsc +1 -1
  139. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_index.segment.rsc +1 -1
  140. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/iron-dome.segments/_tree.segment.rsc +1 -1
  141. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.html +1 -1
  142. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.rsc +1 -1
  143. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies/__PAGE__.segment.rsc +1 -1
  144. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection/policies.segment.rsc +1 -1
  145. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  146. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  147. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_full.segment.rsc +1 -1
  148. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_head.segment.rsc +1 -1
  149. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_index.segment.rsc +1 -1
  150. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/policies.segments/_tree.segment.rsc +1 -1
  151. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.html +1 -1
  152. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.rsc +1 -1
  153. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine/__PAGE__.segment.rsc +1 -1
  154. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection/quarantine.segment.rsc +1 -1
  155. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  156. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  157. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_full.segment.rsc +1 -1
  158. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_head.segment.rsc +1 -1
  159. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_index.segment.rsc +1 -1
  160. package/dashboard/.next/standalone/dashboard/.next/server/app/protection/quarantine.segments/_tree.segment.rsc +1 -1
  161. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.html +1 -1
  162. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.rsc +1 -1
  163. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection/__PAGE__.segment.rsc +1 -1
  164. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk/protection.segment.rsc +1 -1
  165. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  166. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_full.segment.rsc +1 -1
  167. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_head.segment.rsc +1 -1
  168. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_index.segment.rsc +1 -1
  169. package/dashboard/.next/standalone/dashboard/.next/server/app/protection.segments/_tree.segment.rsc +1 -1
  170. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.html +1 -1
  171. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.rsc +1 -1
  172. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings/__PAGE__.segment.rsc +1 -1
  173. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk/settings.segment.rsc +1 -1
  174. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  175. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_full.segment.rsc +1 -1
  176. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  177. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  178. package/dashboard/.next/standalone/dashboard/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  179. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.html +1 -1
  180. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.rsc +1 -1
  181. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray/__PAGE__.segment.rsc +1 -1
  182. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain/xray.segment.rsc +1 -1
  183. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
  184. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  185. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_full.segment.rsc +1 -1
  186. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_head.segment.rsc +1 -1
  187. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_index.segment.rsc +1 -1
  188. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain/xray.segments/_tree.segment.rsc +1 -1
  189. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.html +1 -1
  190. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.rsc +1 -1
  191. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain/__PAGE__.segment.rsc +1 -1
  192. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk/supply-chain.segment.rsc +1 -1
  193. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  194. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_full.segment.rsc +1 -1
  195. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_head.segment.rsc +1 -1
  196. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_index.segment.rsc +1 -1
  197. package/dashboard/.next/standalone/dashboard/.next/server/app/supply-chain.segments/_tree.segment.rsc +1 -1
  198. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.html +1 -1
  199. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.rsc +1 -1
  200. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray/__PAGE__.segment.rsc +1 -1
  201. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk/xray.segment.rsc +1 -1
  202. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/!KGRhc2hib2FyZCk.segment.rsc +1 -1
  203. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_full.segment.rsc +1 -1
  204. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_head.segment.rsc +1 -1
  205. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_index.segment.rsc +1 -1
  206. package/dashboard/.next/standalone/dashboard/.next/server/app/xray.segments/_tree.segment.rsc +1 -1
  207. package/dashboard/.next/standalone/dashboard/.next/server/pages/404.html +1 -1
  208. package/dashboard/.next/standalone/dashboard/.next/server/pages/500.html +2 -2
  209. package/dist/cli/doctor.d.ts +16 -0
  210. package/dist/cli/doctor.js +329 -8
  211. package/dist/cli/migrate-legacy.d.ts +30 -0
  212. package/dist/cli/migrate-legacy.js +199 -0
  213. package/dist/cloud/config.d.ts +22 -0
  214. package/dist/cloud/config.js +38 -0
  215. package/dist/context/derive-project-key.d.ts +36 -0
  216. package/dist/context/derive-project-key.js +150 -0
  217. package/dist/context/project-context.d.ts +8 -5
  218. package/dist/context/project-context.js +16 -32
  219. package/dist/index.js +16 -1
  220. package/dist/setup/settings-hooks.d.ts +6 -0
  221. package/dist/setup/settings-hooks.js +37 -3
  222. package/dist/worker/brain-worker.d.ts +13 -5
  223. package/dist/worker/brain-worker.js +80 -40
  224. package/dist/worker/types.d.ts +19 -0
  225. package/dist/worker/types.js +7 -0
  226. package/package.json +1 -1
  227. package/plugins/openclaw/dist/openclaw.plugin.json +1 -1
  228. package/scripts/lib/auto-memory-config.mjs +22 -4
  229. package/scripts/lib/project-key.mjs +6 -0
  230. package/scripts/pre-compact-hook.mjs +2 -34
  231. package/scripts/session-end-hook.mjs +2 -24
  232. package/scripts/stop-hook.mjs +88 -44
  233. /package/dashboard/.next/standalone/dashboard/.next/static/{kiA_iEHG_1wWOEYFsD0Tj → wrB1TUcOfBtV94V2I9t9N}/_buildManifest.js +0 -0
  234. /package/dashboard/.next/standalone/dashboard/.next/static/{kiA_iEHG_1wWOEYFsD0Tj → wrB1TUcOfBtV94V2I9t9N}/_clientMiddlewareManifest.json +0 -0
  235. /package/dashboard/.next/standalone/dashboard/.next/static/{kiA_iEHG_1wWOEYFsD0Tj → wrB1TUcOfBtV94V2I9t9N}/_ssgManifest.js +0 -0
@@ -338,6 +338,90 @@ async function checkHooks() {
338
338
  return { label: 'Hooks', status: 'warn', message: `check failed — ${msg}` };
339
339
  }
340
340
  }
341
+ // ── Check 4b: Auto-memory hook gates ──────────────────────
342
+ /**
343
+ * Surfaces the resolved on/off state of the opt-in Stop and SessionEnd
344
+ * auto-memory hooks. Pre-v4.13.1 these were triple-gated (install flag,
345
+ * runtime config, sampling) with the runtime gate failing silently —
346
+ * users who wired the hook saw zero captures and zero feedback (#41).
347
+ *
348
+ * The check looks at both layers:
349
+ * - settings.json: is the hook wired so Claude Code will fire it?
350
+ * - autoMemory.enableStop / enableSessionEnd: will the hook actually run?
351
+ *
352
+ * Both layers must agree for the hook to do work. v4.13.1 onwards, the
353
+ * install flag flips both — if they disagree here, the user edited one
354
+ * side by hand and should re-run setup.
355
+ */
356
+ export async function checkAutoMemoryHooks() {
357
+ const settingsPath = path.join(os.homedir(), '.claude', 'settings.json');
358
+ let wiredStop = false;
359
+ let wiredSessionEnd = false;
360
+ try {
361
+ if (fs.existsSync(settingsPath)) {
362
+ const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
363
+ const hooks = settings?.hooks || {};
364
+ const isCortexWired = (entries) => Array.isArray(entries) && entries.some((entry) => Array.isArray(entry?.hooks) && entry.hooks.some((h) => typeof h?.command === 'string' && h.command.includes('shieldcortex')));
365
+ wiredStop = isCortexWired(hooks.Stop);
366
+ wiredSessionEnd = isCortexWired(hooks.SessionEnd);
367
+ }
368
+ }
369
+ catch { /* fall through — both stay false, user gets a clean info row */ }
370
+ // Lazy-import to avoid pulling cloud/config into doctor's static graph
371
+ // when the user hasn't configured anything yet.
372
+ let gateStop = false;
373
+ let gateSessionEnd = false;
374
+ let samplingTurns = 10;
375
+ try {
376
+ const cfg = await import('../cloud/config.js');
377
+ const enable = cfg.getAutoMemoryEnableConfig();
378
+ gateStop = enable.enableStop;
379
+ gateSessionEnd = enable.enableSessionEnd;
380
+ const raw = cfg.readRawConfig();
381
+ const am = raw.autoMemory && typeof raw.autoMemory === 'object'
382
+ ? raw.autoMemory
383
+ : {};
384
+ if (typeof am.stopHookSamplingTurns === 'number' && am.stopHookSamplingTurns > 0) {
385
+ samplingTurns = Math.floor(am.stopHookSamplingTurns);
386
+ }
387
+ }
388
+ catch { /* defaults already set */ }
389
+ const rowFor = (label, wired, gate, flag, extra) => {
390
+ if (!wired && !gate) {
391
+ return {
392
+ label,
393
+ status: 'info',
394
+ message: 'opt-in (not installed)',
395
+ };
396
+ }
397
+ if (wired && gate) {
398
+ return {
399
+ label,
400
+ status: 'pass',
401
+ message: extra ? `enabled (${extra})` : 'enabled',
402
+ };
403
+ }
404
+ if (wired && !gate) {
405
+ return {
406
+ label,
407
+ status: 'warn',
408
+ message: 'wired in settings.json but runtime gate is off — hook will exit silently every turn',
409
+ fix: `Run \`shieldcortex setup ${flag}\` to flip the gate, or set autoMemory.enableStop/enableSessionEnd=true in ~/.shieldcortex/config.json`,
410
+ };
411
+ }
412
+ // gate && !wired
413
+ return {
414
+ label,
415
+ status: 'warn',
416
+ message: 'runtime gate is on but hook is not wired in settings.json — hook will never fire',
417
+ fix: `Run \`shieldcortex setup ${flag}\` to wire the hook`,
418
+ };
419
+ };
420
+ return [
421
+ rowFor('Auto-memory: Stop hook', wiredStop, gateStop, '--with-stop-hook', `samples turn % ${samplingTurns} == 0`),
422
+ rowFor('Auto-memory: SessionEnd hook', wiredSessionEnd, gateSessionEnd, '--with-session-end'),
423
+ ];
424
+ }
341
425
  // ── Check 5: Process check ────────────────────────────────
342
426
  async function checkProcesses() {
343
427
  const results = [];
@@ -461,8 +545,12 @@ async function checkDiskUsage() {
461
545
  }
462
546
  }
463
547
  // ── Check 7: Lock file ───────────────────────────────────
464
- async function checkLockFile() {
465
- const scDir = getShieldCortexDir();
548
+ //
549
+ // A lock is stale only if its recorded PID is no longer running. Pure mtime age
550
+ // is unreliable: a long-running daemon (e.g. `shieldcortex dashboard` started
551
+ // at boot) holds the same lock for days, and flagging it stale tells the user
552
+ // to delete a file that is still in active use.
553
+ export async function checkLockFile(scDir = getShieldCortexDir()) {
466
554
  if (!fs.existsSync(scDir)) {
467
555
  return { label: 'Lock', status: 'pass', message: 'clean' };
468
556
  }
@@ -477,18 +565,45 @@ async function checkLockFile() {
477
565
  if (lockFiles.length === 0) {
478
566
  return { label: 'Lock', status: 'pass', message: 'clean' };
479
567
  }
480
- // Check if lock files are stale (older than 1 hour)
481
568
  const stale = [];
482
569
  const active = [];
483
- const oneHourAgo = Date.now() - 60 * 60 * 1000;
570
+ // Fallback only used when the lock file is unparseable or has no PID.
571
+ const oneDayAgo = Date.now() - 24 * 60 * 60 * 1000;
484
572
  for (const lockFile of lockFiles) {
485
573
  const lockPath = path.join(scDir, lockFile);
486
- const stat = fs.statSync(lockPath);
487
- if (stat.mtimeMs < oneHourAgo) {
488
- stale.push(lockFile);
574
+ let pid = null;
575
+ try {
576
+ const parsed = JSON.parse(fs.readFileSync(lockPath, 'utf-8'));
577
+ if (typeof parsed.pid === 'number' && Number.isFinite(parsed.pid)) {
578
+ pid = parsed.pid;
579
+ }
580
+ }
581
+ catch {
582
+ // Unparseable lock — fall through to mtime fallback below.
583
+ }
584
+ if (pid !== null) {
585
+ try {
586
+ process.kill(pid, 0);
587
+ active.push(lockFile);
588
+ }
589
+ catch (err) {
590
+ if (err.code === 'ESRCH') {
591
+ stale.push(lockFile);
592
+ }
593
+ else {
594
+ // EPERM = process exists, owned by another user. Treat as active.
595
+ active.push(lockFile);
596
+ }
597
+ }
489
598
  }
490
599
  else {
491
- active.push(lockFile);
600
+ const stat = fs.statSync(lockPath);
601
+ if (stat.mtimeMs < oneDayAgo) {
602
+ stale.push(lockFile);
603
+ }
604
+ else {
605
+ active.push(lockFile);
606
+ }
492
607
  }
493
608
  }
494
609
  if (stale.length > 0) {
@@ -542,6 +657,207 @@ async function checkOpenClawResidue() {
542
657
  return { label: 'OpenClaw residue', status: 'warn', message: `check failed — ${msg}` };
543
658
  }
544
659
  }
660
+ // ── Check 9: Auto-memory sampling rate (#44) ──────────────
661
+ /**
662
+ * Reports the resolved `autoMemory.stopHookSamplingTurns` and salience-bypass
663
+ * setting. Defaults dropped 10 → 5 (and salience bypass added) in v4.14.0;
664
+ * warn if a user pinned a sparser cadence likely to under-feed LTM.
665
+ *
666
+ * Reads the config file directly rather than importing the .mjs helper so
667
+ * doctor doesn't depend on path layout between dist/ and scripts/.
668
+ */
669
+ async function checkAutoMemorySampling() {
670
+ try {
671
+ const configPath = path.join(getShieldCortexDir(), 'config.json');
672
+ let raw = {};
673
+ if (fs.existsSync(configPath)) {
674
+ try {
675
+ raw = JSON.parse(fs.readFileSync(configPath, 'utf-8'));
676
+ }
677
+ catch {
678
+ /* fall through to defaults */
679
+ }
680
+ }
681
+ const overrides = raw.autoMemory ?? {};
682
+ const sampling = typeof overrides.stopHookSamplingTurns === 'number' &&
683
+ Number.isFinite(overrides.stopHookSamplingTurns) &&
684
+ overrides.stopHookSamplingTurns > 0
685
+ ? Math.floor(overrides.stopHookSamplingTurns)
686
+ : 5; // default in auto-memory-config.mjs as of v4.14.0
687
+ const bypassEnabled = typeof overrides.stopHookSalienceBypass === 'boolean' ? overrides.stopHookSalienceBypass : true;
688
+ const bypass = bypassEnabled ? 'on' : 'off';
689
+ if (sampling <= 5) {
690
+ return {
691
+ label: 'Auto-memory sampling',
692
+ status: 'pass',
693
+ message: `every ${sampling} turn(s), salience-bypass ${bypass}`,
694
+ };
695
+ }
696
+ return {
697
+ label: 'Auto-memory sampling',
698
+ status: 'warn',
699
+ message: `every ${sampling} turn(s), salience-bypass ${bypass} — sparser than recommended`,
700
+ fix: 'Edit ~/.shieldcortex/config.json autoMemory.stopHookSamplingTurns (≤ 5 recommended)',
701
+ };
702
+ }
703
+ catch (err) {
704
+ const msg = err instanceof Error ? err.message : String(err);
705
+ return { label: 'Auto-memory sampling', status: 'info', message: `check skipped — ${msg}` };
706
+ }
707
+ }
708
+ // ── Check 10: Brain-worker freshness (#45) ────────────────
709
+ /**
710
+ * The MCP server starts a lite-profile brain worker on connect (v4.14.0).
711
+ * Each light tick writes to ~/.shieldcortex/state/worker.json. If the
712
+ * timestamp is missing or older than 30 min, consolidation has likely
713
+ * stalled — STM won't graduate to LTM.
714
+ */
715
+ async function checkBrainWorker() {
716
+ if (process.env.SHIELDCORTEX_DISABLE_WORKER === '1') {
717
+ return {
718
+ label: 'Brain worker',
719
+ status: 'info',
720
+ message: 'disabled via SHIELDCORTEX_DISABLE_WORKER=1',
721
+ };
722
+ }
723
+ const statePath = path.join(getShieldCortexDir(), 'state', 'worker.json');
724
+ if (!fs.existsSync(statePath)) {
725
+ return {
726
+ label: 'Brain worker',
727
+ status: 'warn',
728
+ message: 'no worker.json — worker has not run yet',
729
+ fix: 'Start an MCP-bound session (Claude Code) or run `shieldcortex worker` to drive consolidation',
730
+ };
731
+ }
732
+ try {
733
+ const raw = JSON.parse(fs.readFileSync(statePath, 'utf-8'));
734
+ const last = raw.lastLightTick ? new Date(raw.lastLightTick) : null;
735
+ if (!last || Number.isNaN(last.getTime())) {
736
+ return {
737
+ label: 'Brain worker',
738
+ status: 'warn',
739
+ message: 'worker.json present but lastLightTick missing/invalid',
740
+ fix: 'Restart Claude Code to spawn a fresh MCP server',
741
+ };
742
+ }
743
+ const ageMs = Date.now() - last.getTime();
744
+ const ageMin = Math.round(ageMs / 60000);
745
+ if (ageMs > 30 * 60 * 1000) {
746
+ return {
747
+ label: 'Brain worker',
748
+ status: 'warn',
749
+ message: `last tick ${ageMin}m ago (profile=${raw.profile ?? '?'}, pid=${raw.pid ?? '?'})`,
750
+ fix: 'Restart Claude Code or run `shieldcortex worker` to resume consolidation',
751
+ };
752
+ }
753
+ return {
754
+ label: 'Brain worker',
755
+ status: 'pass',
756
+ message: `last tick ${ageMin}m ago (profile=${raw.profile ?? '?'}, pid=${raw.pid ?? '?'})`,
757
+ };
758
+ }
759
+ catch (err) {
760
+ const msg = err instanceof Error ? err.message : String(err);
761
+ return { label: 'Brain worker', status: 'warn', message: `check failed — ${msg}` };
762
+ }
763
+ }
764
+ // ── Check 11: Project-key consistency (#42) ───────────────
765
+ /**
766
+ * Detects rows tagged with both legacy basename keys and canonical
767
+ * owner-repo keys (the symptom of pre-v4.14.0 stop-hook writes). If any
768
+ * basename collides with a `<something>-<basename>` form already in the
769
+ * DB, point the user at `repair-project-keys`.
770
+ */
771
+ async function checkProjectKeyConsistency() {
772
+ const dbPath = getDbPath();
773
+ if (!fs.existsSync(dbPath)) {
774
+ return { label: 'Project keys', status: 'info', message: 'skipped (no DB yet)' };
775
+ }
776
+ try {
777
+ const Database = require('better-sqlite3');
778
+ const db = new Database(dbPath, { readonly: true });
779
+ try {
780
+ const rows = db
781
+ .prepare("SELECT DISTINCT project FROM memories WHERE project IS NOT NULL AND project != ''")
782
+ .all();
783
+ const keys = rows.map((r) => r.project);
784
+ const collisions = [];
785
+ for (const candidate of keys) {
786
+ // A candidate is "legacy-looking" if it has no hyphen (cwd basename).
787
+ if (candidate.includes('-'))
788
+ continue;
789
+ const suffix = `-${candidate}`;
790
+ const matched = keys.find((k) => k !== candidate && k.endsWith(suffix));
791
+ if (matched)
792
+ collisions.push({ legacy: candidate, canonical: matched });
793
+ }
794
+ if (collisions.length === 0) {
795
+ return { label: 'Project keys', status: 'pass', message: `${keys.length} distinct, no legacy/canonical collisions` };
796
+ }
797
+ const example = collisions.slice(0, 3).map((c) => `${c.legacy} ↔ ${c.canonical}`).join('; ');
798
+ const more = collisions.length > 3 ? ` (+${collisions.length - 3} more)` : '';
799
+ return {
800
+ label: 'Project keys',
801
+ status: 'warn',
802
+ message: `${collisions.length} legacy/canonical collision(s): ${example}${more}`,
803
+ fix: 'Run `shieldcortex memories repair-project-keys --scan-paths <root>` (dry-run by default)',
804
+ };
805
+ }
806
+ finally {
807
+ db.close();
808
+ }
809
+ }
810
+ catch (err) {
811
+ const msg = err instanceof Error ? err.message : String(err);
812
+ return { label: 'Project keys', status: 'warn', message: `check failed — ${msg}` };
813
+ }
814
+ }
815
+ // ── Check 12: Hook timeouts (#43) ─────────────────────────
816
+ /**
817
+ * Compares each ShieldCortex hook's timeout in ~/.claude/settings.json
818
+ * against the canonical values written by `shieldcortex setup`. Catches
819
+ * the v4.13.x silent-recall failure mode where users on a hand-edited
820
+ * settings.json still ran with `UserPromptSubmit.timeout: 2`.
821
+ */
822
+ async function checkHookTimeouts() {
823
+ const settingsPath = path.join(os.homedir(), '.claude', 'settings.json');
824
+ if (!fs.existsSync(settingsPath)) {
825
+ return { label: 'Hook timeouts', status: 'info', message: 'skipped (settings.json not found)' };
826
+ }
827
+ try {
828
+ const { CANONICAL_HOOK_TIMEOUTS } = await import('../setup/settings-hooks.js');
829
+ const settings = JSON.parse(fs.readFileSync(settingsPath, 'utf-8'));
830
+ const hooks = settings.hooks ?? {};
831
+ const drift = [];
832
+ for (const [name, expected] of Object.entries(CANONICAL_HOOK_TIMEOUTS)) {
833
+ const entries = hooks[name];
834
+ if (!Array.isArray(entries))
835
+ continue;
836
+ for (const entry of entries) {
837
+ for (const h of entry.hooks ?? []) {
838
+ if (typeof h.command !== 'string' || !h.command.includes('shieldcortex'))
839
+ continue;
840
+ if (typeof h.timeout === 'number' && h.timeout < expected) {
841
+ drift.push(`${name}=${h.timeout}s (canonical ${expected}s)`);
842
+ }
843
+ }
844
+ }
845
+ }
846
+ if (drift.length === 0) {
847
+ return { label: 'Hook timeouts', status: 'pass', message: 'all canonical' };
848
+ }
849
+ return {
850
+ label: 'Hook timeouts',
851
+ status: 'warn',
852
+ message: `below canonical: ${drift.join(', ')}`,
853
+ fix: 'Re-run `shieldcortex install` to restore canonical timeouts',
854
+ };
855
+ }
856
+ catch (err) {
857
+ const msg = err instanceof Error ? err.message : String(err);
858
+ return { label: 'Hook timeouts', status: 'info', message: `check skipped — ${msg}` };
859
+ }
860
+ }
545
861
  // ── Check 8: Model cache ─────────────────────────────────
546
862
  async function checkModelCache() {
547
863
  const cacheDir = path.join(os.homedir(), '.cache', 'shieldcortex', 'models', 'Xenova', 'all-MiniLM-L6-v2');
@@ -588,6 +904,11 @@ export async function runDoctor() {
588
904
  checkWritePath, // Smoke test: real INSERT/SELECT/DELETE round-trip — catches silent schema drift
589
905
  checkMemoryStats,
590
906
  checkHooks,
907
+ checkHookTimeouts,
908
+ checkAutoMemoryHooks,
909
+ checkAutoMemorySampling,
910
+ checkBrainWorker,
911
+ checkProjectKeyConsistency,
591
912
  checkProcesses,
592
913
  checkDiskUsage,
593
914
  checkLockFile,
@@ -25,4 +25,34 @@ interface MigrationReport {
25
25
  }
26
26
  export declare function migrateLegacy(options?: MigrateOptions): MigrationReport;
27
27
  export declare function handleMemoriesCommand(args: string[]): Promise<void>;
28
+ interface RepairOptions {
29
+ /** Path to memories.db (defaults to ~/.shieldcortex/memories.db) */
30
+ dbPath?: string;
31
+ /** Walk these dev roots one level deep, propose mappings unambiguously */
32
+ scanPaths?: string[];
33
+ /** Explicit overrides; basename → canonical-key */
34
+ map?: Record<string, string>;
35
+ /** Limit the scan to a single legacy project key */
36
+ onlyProject?: string;
37
+ /** Include short-term rows (default: long-term + episodic only) */
38
+ includeStm?: boolean;
39
+ /** Default false — must be true to actually write */
40
+ execute?: boolean;
41
+ /** When true, never prompt (used by tests). Defaults to interactive. */
42
+ noConfirm?: boolean;
43
+ }
44
+ interface RepairProposal {
45
+ legacy: string;
46
+ canonical: string;
47
+ count: number;
48
+ source: 'map' | 'scan';
49
+ }
50
+ interface RepairReport {
51
+ dryRun: boolean;
52
+ proposals: RepairProposal[];
53
+ applied: number;
54
+ logPath?: string;
55
+ backupPath?: string;
56
+ }
57
+ export declare function repairProjectKeys(opts?: RepairOptions): Promise<RepairReport>;
28
58
  export {};
@@ -2,7 +2,9 @@ import fs from 'fs';
2
2
  import path from 'path';
3
3
  import os from 'os';
4
4
  import { randomUUID } from 'crypto';
5
+ import readline from 'readline';
5
6
  import Database from 'better-sqlite3';
7
+ import { deriveProjectKey } from '../context/derive-project-key.js';
6
8
  const DEFAULT_LEGACY_SOURCES = [
7
9
  path.join(os.homedir(), '.claude-cortex', 'memories.db'),
8
10
  path.join(os.homedir(), '.claude-memory', 'memories.db'),
@@ -265,6 +267,14 @@ function printUsage() {
265
267
  console.log(' Cluster near-duplicate long-term memories and keep the highest-');
266
268
  console.log(' salience representative. DRY-RUN BY DEFAULT — pass --execute.');
267
269
  console.log(' Backup auto-saved before any merge.');
270
+ console.log('');
271
+ console.log(' repair-project-keys [--scan-paths <dir,dir,...>]');
272
+ console.log(' [--map basename=canonical] (repeatable)');
273
+ console.log(' [--project <key>] [--include-stm] [--execute]');
274
+ console.log(' Relabel memories tagged under a legacy basename project key');
275
+ console.log(' to their canonical owner-repo key (#42). DRY-RUN BY DEFAULT.');
276
+ console.log(' Backup auto-saved before any rewrite; per-rewrite log written');
277
+ console.log(' to ~/.shieldcortex/logs/project-key-repair-<ts>.json.');
268
278
  }
269
279
  export async function handleMemoriesCommand(args) {
270
280
  const sub = args[0];
@@ -286,6 +296,195 @@ export async function handleMemoriesCommand(args) {
286
296
  await runDedupe(args.slice(1));
287
297
  return;
288
298
  }
299
+ if (sub === 'repair-project-keys') {
300
+ await runRepairProjectKeys(args.slice(1));
301
+ return;
302
+ }
289
303
  printUsage();
290
304
  process.exit(1);
291
305
  }
306
+ function parseMapFlags(args) {
307
+ const map = {};
308
+ for (let i = 0; i < args.length; i++) {
309
+ if (args[i] === '--map' && args[i + 1]) {
310
+ const pair = args[i + 1];
311
+ const eq = pair.indexOf('=');
312
+ if (eq <= 0 || eq === pair.length - 1) {
313
+ throw new Error(`--map expects 'basename=canonical', got '${pair}'`);
314
+ }
315
+ const k = pair.slice(0, eq).trim();
316
+ const v = pair.slice(eq + 1).trim();
317
+ if (!k || !v)
318
+ throw new Error(`--map basename and canonical must be non-empty: '${pair}'`);
319
+ map[k] = v;
320
+ i++;
321
+ }
322
+ }
323
+ return map;
324
+ }
325
+ function parseScanPaths(args) {
326
+ const v = flagValue(args, '--scan-paths');
327
+ if (!v)
328
+ return [];
329
+ return v
330
+ .split(',')
331
+ .map((s) => s.trim().replace(/^~(?=\/|$)/, os.homedir()))
332
+ .filter(Boolean);
333
+ }
334
+ async function confirmExecute(prompt) {
335
+ if (!process.stdin.isTTY)
336
+ return false;
337
+ const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
338
+ try {
339
+ const answer = await new Promise((resolve) => rl.question(prompt, resolve));
340
+ return /^y(es)?$/i.test(answer.trim());
341
+ }
342
+ finally {
343
+ rl.close();
344
+ }
345
+ }
346
+ export async function repairProjectKeys(opts = {}) {
347
+ const dbPath = opts.dbPath ?? DEFAULT_TARGET;
348
+ if (!fs.existsSync(dbPath)) {
349
+ throw new Error(`memories DB not found at ${dbPath} — run \`shieldcortex setup\` first`);
350
+ }
351
+ const explicit = opts.map ?? {};
352
+ const scanPaths = opts.scanPaths ?? [];
353
+ const includeStm = opts.includeStm === true;
354
+ const dryRun = opts.execute !== true;
355
+ const db = new Database(dbPath);
356
+ db.pragma('busy_timeout = 10000');
357
+ let report;
358
+ try {
359
+ // 1. Distinct legacy project keys in the DB.
360
+ const typeFilter = includeStm ? '' : "AND type IN ('long_term', 'episodic')";
361
+ const distinct = db
362
+ .prepare(`SELECT DISTINCT project FROM memories WHERE project IS NOT NULL ${typeFilter}`)
363
+ .all();
364
+ const dbProjects = new Set(distinct.map((r) => r.project));
365
+ // 2. Build the proposal set.
366
+ const proposals = [];
367
+ const seen = new Set();
368
+ const addProposal = (legacy, canonical, source) => {
369
+ if (legacy === canonical)
370
+ return;
371
+ if (opts.onlyProject && legacy !== opts.onlyProject)
372
+ return;
373
+ if (!dbProjects.has(legacy))
374
+ return;
375
+ const key = `${legacy}${canonical}`;
376
+ if (seen.has(key))
377
+ return;
378
+ seen.add(key);
379
+ const countQ = db
380
+ .prepare(`SELECT COUNT(*) AS n FROM memories WHERE project = ? ${typeFilter}`)
381
+ .get(legacy);
382
+ proposals.push({ legacy, canonical, count: countQ.n, source });
383
+ };
384
+ // 2a. --map overrides win.
385
+ for (const [legacy, canonical] of Object.entries(explicit)) {
386
+ addProposal(legacy, canonical, 'map');
387
+ }
388
+ // 2b. --scan-paths: walk one level deep, run deriveProjectKey, match by basename.
389
+ for (const root of scanPaths) {
390
+ let entries = [];
391
+ try {
392
+ entries = fs.readdirSync(root);
393
+ }
394
+ catch {
395
+ continue;
396
+ }
397
+ for (const name of entries) {
398
+ const child = path.join(root, name);
399
+ let isDir = false;
400
+ try {
401
+ isDir = fs.statSync(child).isDirectory();
402
+ }
403
+ catch {
404
+ continue;
405
+ }
406
+ if (!isDir)
407
+ continue;
408
+ const canonical = deriveProjectKey(child);
409
+ if (!canonical || canonical === name)
410
+ continue;
411
+ addProposal(name, canonical, 'scan');
412
+ }
413
+ }
414
+ report = {
415
+ dryRun,
416
+ proposals,
417
+ applied: 0,
418
+ };
419
+ // 3. Print proposal table.
420
+ const banner = dryRun ? '[DRY RUN] ' : '';
421
+ console.log(`${banner}Project-key repair plan (${dbPath}):`);
422
+ if (proposals.length === 0) {
423
+ console.log(' No proposed rewrites — nothing to do.');
424
+ console.log('');
425
+ console.log('Tip: pass `--scan-paths ~/Development` (or `--map old=new`) so the');
426
+ console.log(' repair tool can match legacy basename keys against canonical');
427
+ console.log(' owner-repo keys derived from the git origin.');
428
+ return report;
429
+ }
430
+ for (const p of proposals) {
431
+ console.log(` ${p.legacy.padEnd(40)} → ${p.canonical.padEnd(48)} (${p.count} rows, source: ${p.source})`);
432
+ }
433
+ const totalRows = proposals.reduce((s, p) => s + p.count, 0);
434
+ console.log('');
435
+ console.log(`Total: ${totalRows} rows across ${proposals.length} project key(s).`);
436
+ if (dryRun) {
437
+ console.log('');
438
+ console.log('Re-run with --execute to apply. To undo later:');
439
+ console.log(' shieldcortex memories repair-project-keys \\');
440
+ console.log(' ' + proposals.map((p) => `--map ${p.canonical}=${p.legacy}`).join(' \\\n ') + ' --execute');
441
+ return report;
442
+ }
443
+ // 4. Confirm + backup + write.
444
+ if (!opts.noConfirm) {
445
+ const ok = await confirmExecute(`\nApply ${proposals.length} rewrite(s) to ${totalRows} rows? [y/N] `);
446
+ if (!ok) {
447
+ console.log('Aborted — no changes written.');
448
+ return report;
449
+ }
450
+ }
451
+ const backupPath = `${dbPath}.bak.${new Date().toISOString().replace(/[:.]/g, '-')}`;
452
+ fs.copyFileSync(dbPath, backupPath);
453
+ report.backupPath = backupPath;
454
+ console.log(`Backup: ${backupPath}`);
455
+ const update = db.prepare(`UPDATE memories SET project = ? WHERE project = ? ${typeFilter}`);
456
+ const txn = db.transaction(() => {
457
+ for (const p of proposals) {
458
+ const r = update.run(p.canonical, p.legacy);
459
+ report.applied += r.changes;
460
+ }
461
+ });
462
+ txn();
463
+ // 5. Per-rewrite JSON log under ~/.shieldcortex/logs/.
464
+ const logsDir = path.join(os.homedir(), '.shieldcortex', 'logs');
465
+ fs.mkdirSync(logsDir, { recursive: true });
466
+ const logPath = path.join(logsDir, `project-key-repair-${new Date().toISOString().replace(/[:.]/g, '-')}.json`);
467
+ fs.writeFileSync(logPath, JSON.stringify({
468
+ dbPath,
469
+ backupPath,
470
+ appliedAt: new Date().toISOString(),
471
+ rewrites: proposals,
472
+ totalRowsAffected: report.applied,
473
+ }, null, 2), 'utf-8');
474
+ report.logPath = logPath;
475
+ console.log(`Applied: ${report.applied} rows`);
476
+ console.log(`Log: ${logPath}`);
477
+ }
478
+ finally {
479
+ db.close();
480
+ }
481
+ return report;
482
+ }
483
+ async function runRepairProjectKeys(args) {
484
+ const map = parseMapFlags(args);
485
+ const scanPaths = parseScanPaths(args);
486
+ const onlyProject = flagValue(args, '--project');
487
+ const includeStm = args.includes('--include-stm');
488
+ const execute = args.includes('--execute');
489
+ await repairProjectKeys({ map, scanPaths, onlyProject, includeStm, execute });
490
+ }
@@ -116,6 +116,28 @@ export declare function setProactiveRecall(enabled: boolean): void;
116
116
  * so the flip is a one-command undo.
117
117
  */
118
118
  export declare function restore410Defaults(): void;
119
+ export interface AutoMemoryEnableConfig {
120
+ enableStop: boolean;
121
+ enableSessionEnd: boolean;
122
+ }
123
+ /**
124
+ * Returns the resolved on/off state of the opt-in auto-memory hooks.
125
+ *
126
+ * Default is false for both — preserves the OpenClaw-safe default that
127
+ * shipped in v4.13.0. The install flags (`--with-stop-hook` /
128
+ * `--with-session-end`) flip these to true so that wiring the hook in
129
+ * settings.json and enabling the runtime gate are a single user action.
130
+ */
131
+ export declare function getAutoMemoryEnableConfig(): AutoMemoryEnableConfig;
132
+ /**
133
+ * Persists the on/off state of the opt-in auto-memory hooks.
134
+ *
135
+ * Lives in `autoMemory.enableStop` / `autoMemory.enableSessionEnd` under
136
+ * `~/.shieldcortex/config.json` — the same namespace `auto-memory-config.mjs`
137
+ * reads from at hook fire time. Single source of truth: install flag +
138
+ * runtime gate cannot disagree.
139
+ */
140
+ export declare function setAutoMemoryEnableConfig(updates: Partial<AutoMemoryEnableConfig>): void;
119
141
  export interface ToolResponseScanConfig {
120
142
  scanToolResponses: boolean;
121
143
  toolResponseMode: 'advisory' | 'enforce';