shieldcortex 4.13.1 → 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 (233) 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 +1 -0
  210. package/dist/cli/doctor.js +244 -8
  211. package/dist/cli/migrate-legacy.d.ts +30 -0
  212. package/dist/cli/migrate-legacy.js +199 -0
  213. package/dist/context/derive-project-key.d.ts +36 -0
  214. package/dist/context/derive-project-key.js +150 -0
  215. package/dist/context/project-context.d.ts +8 -5
  216. package/dist/context/project-context.js +16 -32
  217. package/dist/index.js +16 -1
  218. package/dist/setup/settings-hooks.d.ts +6 -0
  219. package/dist/setup/settings-hooks.js +14 -1
  220. package/dist/worker/brain-worker.d.ts +13 -5
  221. package/dist/worker/brain-worker.js +80 -40
  222. package/dist/worker/types.d.ts +19 -0
  223. package/dist/worker/types.js +7 -0
  224. package/package.json +1 -1
  225. package/plugins/openclaw/dist/openclaw.plugin.json +1 -1
  226. package/scripts/lib/auto-memory-config.mjs +11 -1
  227. package/scripts/lib/project-key.mjs +6 -0
  228. package/scripts/pre-compact-hook.mjs +2 -34
  229. package/scripts/session-end-hook.mjs +2 -24
  230. package/scripts/stop-hook.mjs +48 -43
  231. /package/dashboard/.next/standalone/dashboard/.next/static/{2JvJZkELhPQRzhTlgun1M → wrB1TUcOfBtV94V2I9t9N}/_buildManifest.js +0 -0
  232. /package/dashboard/.next/standalone/dashboard/.next/static/{2JvJZkELhPQRzhTlgun1M → wrB1TUcOfBtV94V2I9t9N}/_clientMiddlewareManifest.json +0 -0
  233. /package/dashboard/.next/standalone/dashboard/.next/static/{2JvJZkELhPQRzhTlgun1M → wrB1TUcOfBtV94V2I9t9N}/_ssgManifest.js +0 -0
@@ -0,0 +1,150 @@
1
+ /**
2
+ * TypeScript port of scripts/lib/project-key.mjs.
3
+ *
4
+ * Both the MCP-server side (this module) and the hook scripts must agree on
5
+ * how a cwd maps to a project key — otherwise writes and reads fall under
6
+ * different scopes and recall silently misses (issue #42).
7
+ *
8
+ * Resolution order:
9
+ * 1. SHIELDCORTEX_PROJECT_KEY env override
10
+ * 2. CLAUDE_MEMORY_PROJECT env override (legacy alias for SC env var)
11
+ * 3. ~/.shieldcortex/config.json projectKey
12
+ * 4. ~/.shieldcortex/config.json projectAliases[basename]
13
+ * 5. Git origin owner-repo (walk up from cwd)
14
+ * 6. Cwd basename (legacy behaviour), skipping noise directories
15
+ */
16
+ import { existsSync, readFileSync, statSync } from 'fs';
17
+ import { join, dirname } from 'path';
18
+ import { homedir } from 'os';
19
+ const SKIP_DIRECTORIES = [
20
+ 'src', 'lib', 'dist', 'build', 'out',
21
+ 'node_modules', '.git', '.next', '.cache',
22
+ 'test', 'tests', '__tests__', 'spec',
23
+ 'bin', 'scripts', 'config', 'public', 'static',
24
+ ];
25
+ function resolveHome() {
26
+ return process.env.HOME || process.env.USERPROFILE || homedir();
27
+ }
28
+ function configPath() {
29
+ return join(resolveHome(), '.shieldcortex', 'config.json');
30
+ }
31
+ function loadConfig() {
32
+ try {
33
+ const p = configPath();
34
+ if (!existsSync(p))
35
+ return {};
36
+ return JSON.parse(readFileSync(p, 'utf-8'));
37
+ }
38
+ catch {
39
+ return {};
40
+ }
41
+ }
42
+ export function basenameFromCwd(path) {
43
+ if (!path)
44
+ return null;
45
+ const segments = path.split(/[/\\]/).filter(Boolean);
46
+ for (let i = segments.length - 1; i >= 0; i--) {
47
+ const segment = segments[i];
48
+ if (SKIP_DIRECTORIES.includes(segment.toLowerCase()))
49
+ continue;
50
+ if (segment.startsWith('.'))
51
+ continue;
52
+ return segment;
53
+ }
54
+ return null;
55
+ }
56
+ function findGitDir(startPath) {
57
+ let current = startPath;
58
+ const root = '/';
59
+ for (let i = 0; i < 40 && current && current !== root; i++) {
60
+ const candidate = join(current, '.git');
61
+ if (existsSync(candidate))
62
+ return candidate;
63
+ const parent = dirname(current);
64
+ if (parent === current)
65
+ break;
66
+ current = parent;
67
+ }
68
+ return null;
69
+ }
70
+ function parseOriginUrl(url) {
71
+ if (!url)
72
+ return null;
73
+ const trimmed = url.trim();
74
+ const sshMatch = trimmed.match(/^[^@]+@[^:]+:([^/]+)\/(.+?)(?:\.git)?$/);
75
+ if (sshMatch)
76
+ return { owner: sshMatch[1], repo: sshMatch[2] };
77
+ const urlMatch = trimmed.match(/^[a-z]+:\/\/[^/]+\/(.+?)\/([^/]+?)(?:\.git)?$/i);
78
+ if (urlMatch)
79
+ return { owner: urlMatch[1], repo: urlMatch[2] };
80
+ return null;
81
+ }
82
+ function readOriginFromGitConfig(gitPath) {
83
+ try {
84
+ let realGitDir = gitPath;
85
+ const stats = statSync(gitPath);
86
+ if (stats.isFile()) {
87
+ const content = readFileSync(gitPath, 'utf-8');
88
+ if (content.startsWith('gitdir:')) {
89
+ realGitDir = content.slice('gitdir:'.length).trim();
90
+ }
91
+ else {
92
+ return null;
93
+ }
94
+ }
95
+ const cfgPath = join(realGitDir, 'config');
96
+ if (!existsSync(cfgPath))
97
+ return null;
98
+ const content = readFileSync(cfgPath, 'utf-8');
99
+ const section = content.match(/\[remote\s+"origin"\][^[]*/);
100
+ if (!section)
101
+ return null;
102
+ const urlMatch = section[0].match(/\burl\s*=\s*(.+)/);
103
+ if (!urlMatch)
104
+ return null;
105
+ return parseOriginUrl(urlMatch[1]);
106
+ }
107
+ catch {
108
+ return null;
109
+ }
110
+ }
111
+ /**
112
+ * Derive the project key for a given working directory. Mirrors
113
+ * scripts/lib/project-key.mjs::deriveProjectKey so MCP-server-side and
114
+ * hook-side keys agree.
115
+ */
116
+ export function deriveProjectKey(cwd) {
117
+ if (process.env.SHIELDCORTEX_PROJECT_KEY) {
118
+ return process.env.SHIELDCORTEX_PROJECT_KEY;
119
+ }
120
+ if (process.env.CLAUDE_MEMORY_PROJECT) {
121
+ const v = process.env.CLAUDE_MEMORY_PROJECT.trim();
122
+ if (v)
123
+ return v;
124
+ }
125
+ const config = loadConfig();
126
+ const projectKey = config.projectKey;
127
+ if (typeof projectKey === 'string' && projectKey.trim()) {
128
+ return projectKey.trim();
129
+ }
130
+ const basename = basenameFromCwd(cwd);
131
+ const aliases = config.projectAliases;
132
+ if (aliases && typeof aliases === 'object' && basename) {
133
+ const alias = aliases[basename];
134
+ if (typeof alias === 'string' && alias.trim())
135
+ return alias.trim();
136
+ }
137
+ const gitDir = cwd ? findGitDir(cwd) : null;
138
+ if (gitDir) {
139
+ const origin = readOriginFromGitConfig(gitDir);
140
+ if (origin?.owner && origin?.repo) {
141
+ return `${origin.owner}-${origin.repo}`;
142
+ }
143
+ }
144
+ return basename;
145
+ }
146
+ export const __internal = {
147
+ parseOriginUrl,
148
+ basenameFromCwd,
149
+ readOriginFromGitConfig,
150
+ };
@@ -2,22 +2,25 @@
2
2
  * Project Context Module
3
3
  * Automatically detects and manages the active project scope for memory operations.
4
4
  *
5
- * Detection priority:
6
- * 1. CLAUDE_MEMORY_PROJECT environment variable
7
- * 2. Extract from process.cwd() (working directory)
5
+ * Project key derivation is delegated to deriveProjectKey (mirroring
6
+ * scripts/lib/project-key.mjs) so reads and writes share one source of truth.
8
7
  *
9
8
  * The "*" sentinel means "global/all projects" (no filtering).
10
9
  */
11
10
  /** Sentinel value meaning "all projects" - no project filtering */
12
11
  export declare const GLOBAL_PROJECT_SENTINEL = "*";
13
12
  /**
14
- * Extract project name from a file path.
15
- * Skips common directory names that don't represent projects.
13
+ * Extract project name from a file path (basename only, with noise-dir skip).
14
+ * Retained for backwards compatibility with consumers that need just the
15
+ * basename component. New code should call deriveProjectKey instead.
16
16
  */
17
17
  export declare function extractProjectFromPath(path: string): string | null;
18
18
  /**
19
19
  * Initialize project context from environment or working directory.
20
20
  * Call this once at server startup.
21
+ *
22
+ * Uses the shared deriveProjectKey helper, so the resolved key is identical
23
+ * to whatever the .mjs hooks would resolve from the same cwd / env / config.
21
24
  */
22
25
  export declare function initProjectContext(): void;
23
26
  /**
@@ -2,54 +2,38 @@
2
2
  * Project Context Module
3
3
  * Automatically detects and manages the active project scope for memory operations.
4
4
  *
5
- * Detection priority:
6
- * 1. CLAUDE_MEMORY_PROJECT environment variable
7
- * 2. Extract from process.cwd() (working directory)
5
+ * Project key derivation is delegated to deriveProjectKey (mirroring
6
+ * scripts/lib/project-key.mjs) so reads and writes share one source of truth.
8
7
  *
9
8
  * The "*" sentinel means "global/all projects" (no filtering).
10
9
  */
10
+ import { deriveProjectKey, basenameFromCwd } from './derive-project-key.js';
11
11
  /** Sentinel value meaning "all projects" - no project filtering */
12
12
  export const GLOBAL_PROJECT_SENTINEL = '*';
13
13
  /** Currently active project (null = global/no filter) */
14
14
  let activeProject = null;
15
15
  /** How the project was detected */
16
16
  let projectDetectionSource = 'none';
17
- /** Directories to skip when extracting project name from path */
18
- const SKIP_DIRECTORIES = [
19
- 'src', 'lib', 'dist', 'build', 'out',
20
- 'node_modules', '.git', '.next', '.cache',
21
- 'test', 'tests', '__tests__', 'spec',
22
- 'bin', 'scripts', 'config', 'public', 'static',
23
- ];
24
17
  /**
25
- * Extract project name from a file path.
26
- * Skips common directory names that don't represent projects.
18
+ * Extract project name from a file path (basename only, with noise-dir skip).
19
+ * Retained for backwards compatibility with consumers that need just the
20
+ * basename component. New code should call deriveProjectKey instead.
27
21
  */
28
22
  export function extractProjectFromPath(path) {
29
- if (!path)
30
- return null;
31
- const segments = path.split(/[/\\]/).filter(Boolean);
32
- if (segments.length === 0)
33
- return null;
34
- // Start from the end and find first non-skipped segment
35
- for (let i = segments.length - 1; i >= 0; i--) {
36
- const segment = segments[i];
37
- if (!SKIP_DIRECTORIES.includes(segment.toLowerCase())) {
38
- // Skip hidden directories (starting with .)
39
- if (segment.startsWith('.'))
40
- continue;
41
- return segment;
42
- }
43
- }
44
- return null;
23
+ return basenameFromCwd(path);
45
24
  }
46
25
  /**
47
26
  * Initialize project context from environment or working directory.
48
27
  * Call this once at server startup.
28
+ *
29
+ * Uses the shared deriveProjectKey helper, so the resolved key is identical
30
+ * to whatever the .mjs hooks would resolve from the same cwd / env / config.
49
31
  */
50
32
  export function initProjectContext() {
51
- // Priority 1: Environment variable (explicit override)
52
- const envProject = process.env.CLAUDE_MEMORY_PROJECT;
33
+ // Env overrides match deriveProjectKey's order. We track these separately
34
+ // so projectDetectionSource keeps reporting 'env' when the user pinned the
35
+ // project explicitly (visible in get_project / dashboard).
36
+ const envProject = process.env.SHIELDCORTEX_PROJECT_KEY || process.env.CLAUDE_MEMORY_PROJECT;
53
37
  if (envProject) {
54
38
  const trimmed = envProject.trim();
55
39
  if (trimmed === GLOBAL_PROJECT_SENTINEL) {
@@ -62,9 +46,9 @@ export function initProjectContext() {
62
46
  }
63
47
  return;
64
48
  }
65
- // Priority 2: Extract from current working directory
49
+ // Otherwise: config override projectAliases → git origin → basename.
66
50
  const cwd = process.cwd();
67
- const detected = extractProjectFromPath(cwd);
51
+ const detected = deriveProjectKey(cwd);
68
52
  if (detected) {
69
53
  activeProject = detected;
70
54
  projectDetectionSource = 'cwd';
package/dist/index.js CHANGED
@@ -77,7 +77,7 @@ import { handleCodexCommand } from './setup/codex.js';
77
77
  import { createRequire } from 'module';
78
78
  import { execSync } from 'child_process';
79
79
  import { disposeModel, preloadModel } from './embeddings/index.js';
80
- import { stopDefaultWorker } from './worker/brain-worker.js';
80
+ import { startDefaultWorker, stopDefaultWorker } from './worker/brain-worker.js';
81
81
  const require = createRequire(import.meta.url);
82
82
  const pkg = require('../package.json');
83
83
  /**
@@ -172,6 +172,21 @@ async function startMcpServer(dbPath) {
172
172
  });
173
173
  // Connect via stdio transport
174
174
  await server.connect(transport);
175
+ // Start the brain worker in MCP-lite profile so STM→LTM consolidation runs
176
+ // even on hooks-only installs (no dashboard, no `service install`). Without
177
+ // this, MCP-only deployments accumulate STM forever and never promote (#45).
178
+ // The MCP profile uses a 15 min cadence and skips medium-tick + cloud-sync
179
+ // work to keep total background load bounded across many open windows.
180
+ // Disabled via SHIELDCORTEX_DISABLE_WORKER=1 for forensics / debugging.
181
+ if (process.env.SHIELDCORTEX_DISABLE_WORKER !== '1') {
182
+ try {
183
+ startDefaultWorker({ profile: 'mcp' });
184
+ }
185
+ catch (err) {
186
+ const msg = err instanceof Error ? err.message : String(err);
187
+ console.error('[shieldcortex] Brain worker autostart failed (continuing without):', msg);
188
+ }
189
+ }
175
190
  // Preload embedding model in background so first tool call doesn't hang.
176
191
  // Fire-and-forget: failure is fine — searchMemories falls back to FTS-only.
177
192
  if (process.env.SHIELDCORTEX_SKIP_EMBEDDINGS !== '1') {
@@ -7,6 +7,12 @@
7
7
  * Keep this alongside CORTEX_HOOKS — drift between the two is what caused #23.
8
8
  */
9
9
  export declare const REQUIRED_HOOK_NAMES: readonly string[];
10
+ /**
11
+ * Canonical timeout (seconds) for each ShieldCortex hook. Used by
12
+ * `shieldcortex doctor` to flag drift in hand-edited settings.json files —
13
+ * a too-tight UserPromptSubmit timeout silently dropped recall pre-#43.
14
+ */
15
+ export declare const CANONICAL_HOOK_TIMEOUTS: Readonly<Record<string, number>>;
10
16
  export declare function setupHooks(options?: {
11
17
  stopHook?: boolean;
12
18
  sessionEnd?: boolean;
@@ -17,7 +17,11 @@ const CORTEX_HOOKS = {
17
17
  // agents when the session is already gone. PreCompact handles memory
18
18
  // extraction. The cortex-memory hook handles session-end for OpenClaw.
19
19
  UserPromptSubmit: {
20
- hooks: [{ type: 'command', command: 'shieldcortex hook prompt-recall', timeout: 2 }],
20
+ // Cold-spawn floor for the recall hook is ~1.5 s (Node + better-sqlite3 +
21
+ // FTS query). The previous 2 s ceiling SIGKILLed the hook silently under
22
+ // any IO pressure, dropping recall context with no user-visible error
23
+ // (#43). 5 s leaves ~3 s headroom on a busy host.
24
+ hooks: [{ type: 'command', command: 'shieldcortex hook prompt-recall', timeout: 5 }],
21
25
  },
22
26
  };
23
27
  /**
@@ -26,6 +30,15 @@ const CORTEX_HOOKS = {
26
30
  * Keep this alongside CORTEX_HOOKS — drift between the two is what caused #23.
27
31
  */
28
32
  export const REQUIRED_HOOK_NAMES = Object.freeze(Object.keys(CORTEX_HOOKS));
33
+ /**
34
+ * Canonical timeout (seconds) for each ShieldCortex hook. Used by
35
+ * `shieldcortex doctor` to flag drift in hand-edited settings.json files —
36
+ * a too-tight UserPromptSubmit timeout silently dropped recall pre-#43.
37
+ */
38
+ export const CANONICAL_HOOK_TIMEOUTS = Object.freeze(Object.fromEntries(Object.entries(CORTEX_HOOKS).map(([name, entry]) => [
39
+ name,
40
+ entry.hooks?.[0]?.timeout ?? 0,
41
+ ])));
29
42
  const STOP_HOOK = {
30
43
  hooks: [{ type: 'command', command: 'shieldcortex hook stop', timeout: 10 }],
31
44
  };
@@ -29,7 +29,10 @@ export declare class BrainWorker {
29
29
  /**
30
30
  * Create a new BrainWorker
31
31
  *
32
- * @param config - Partial configuration to override defaults
32
+ * @param config - Partial configuration to override defaults. When `profile`
33
+ * is 'mcp' and no explicit `lightTickIntervalMs` is provided,
34
+ * the lite 15-minute cadence is applied so MCP-server-mode
35
+ * workers don't run as often as dashboard-mode ones.
33
36
  */
34
37
  constructor(config?: Partial<WorkerConfig>);
35
38
  /**
@@ -87,13 +90,18 @@ export declare class BrainWorker {
87
90
  triggerMediumTick(): Promise<MediumTickResult>;
88
91
  }
89
92
  /**
90
- * Get or create the default worker instance
93
+ * Get or create the default worker instance.
94
+ * The first call wins — subsequent calls return the existing singleton even
95
+ * if a different config is passed. That's intentional: it prevents accidental
96
+ * re-instantiation from creating two competing timer sets within one process.
91
97
  */
92
- export declare function getDefaultWorker(): BrainWorker;
98
+ export declare function getDefaultWorker(config?: Partial<WorkerConfig>): BrainWorker;
93
99
  /**
94
- * Start the default worker if not already running
100
+ * Start the default worker if not already running. Forwards config to the
101
+ * underlying constructor on first call (used by MCP-server mode to start
102
+ * with `profile: 'mcp'`).
95
103
  */
96
- export declare function startDefaultWorker(): BrainWorker;
104
+ export declare function startDefaultWorker(config?: Partial<WorkerConfig>): BrainWorker;
97
105
  /**
98
106
  * Stop the default worker
99
107
  */
@@ -9,7 +9,7 @@
9
9
  *
10
10
  * This transforms the memory system from reactive to continuously organic.
11
11
  */
12
- import { DEFAULT_WORKER_CONFIG, } from './types.js';
12
+ import { DEFAULT_WORKER_CONFIG, MCP_LIGHT_TICK_INTERVAL_MS, } from './types.js';
13
13
  import { getDatabase } from '../database/init.js';
14
14
  import { pruneActivationCache } from '../memory/activation.js';
15
15
  import { getMemoryStats } from '../memory/store.js';
@@ -22,6 +22,21 @@ import { processRetryQueue, purgeOldEntries } from '../cloud/sync-queue.js';
22
22
  import { sendHeartbeat } from '../cloud/sync.js';
23
23
  import { refreshCloudIronDome, applyCachedCloudPatterns } from '../cloud/iron-dome-sync.js';
24
24
  import { isFeatureEnabled } from '../license/gate.js';
25
+ import { existsSync, mkdirSync, writeFileSync } from 'fs';
26
+ import { join } from 'path';
27
+ import { homedir } from 'os';
28
+ const WORKER_STATE_DIR = join(homedir(), '.shieldcortex', 'state');
29
+ const WORKER_STATE_FILE = join(WORKER_STATE_DIR, 'worker.json');
30
+ function persistWorkerState(profile, lastLightTick) {
31
+ try {
32
+ if (!existsSync(WORKER_STATE_DIR))
33
+ mkdirSync(WORKER_STATE_DIR, { recursive: true });
34
+ writeFileSync(WORKER_STATE_FILE, JSON.stringify({ pid: process.pid, profile, lastLightTick: lastLightTick.toISOString() }, null, 2), 'utf-8');
35
+ }
36
+ catch {
37
+ // Best-effort: doctor will warn if the file is stale or missing
38
+ }
39
+ }
25
40
  /**
26
41
  * Brain Worker Class
27
42
  *
@@ -47,10 +62,17 @@ export class BrainWorker {
47
62
  /**
48
63
  * Create a new BrainWorker
49
64
  *
50
- * @param config - Partial configuration to override defaults
65
+ * @param config - Partial configuration to override defaults. When `profile`
66
+ * is 'mcp' and no explicit `lightTickIntervalMs` is provided,
67
+ * the lite 15-minute cadence is applied so MCP-server-mode
68
+ * workers don't run as often as dashboard-mode ones.
51
69
  */
52
70
  constructor(config = {}) {
53
- this.config = { ...DEFAULT_WORKER_CONFIG, ...config };
71
+ const merged = { ...DEFAULT_WORKER_CONFIG, ...config };
72
+ if (merged.profile === 'mcp' && config.lightTickIntervalMs === undefined) {
73
+ merged.lightTickIntervalMs = MCP_LIGHT_TICK_INTERVAL_MS;
74
+ }
75
+ this.config = merged;
54
76
  }
55
77
  /**
56
78
  * Start the background worker
@@ -62,17 +84,26 @@ export class BrainWorker {
62
84
  return;
63
85
  }
64
86
  this.isRunning = true;
65
- console.log('[BrainWorker] Starting background worker');
87
+ console.log(`[BrainWorker] Starting background worker (profile=${this.config.profile} pid=${process.pid})`);
66
88
  console.log(`[BrainWorker] Light tick interval: ${this.config.lightTickIntervalMs / 1000}s`);
67
- console.log(`[BrainWorker] Medium tick interval: ${this.config.mediumTickIntervalMs / 1000}s`);
68
- // Light tick every 5 minutes (by default)
89
+ if (this.config.profile === 'full') {
90
+ console.log(`[BrainWorker] Medium tick interval: ${this.config.mediumTickIntervalMs / 1000}s`);
91
+ }
92
+ else {
93
+ console.log('[BrainWorker] MCP profile — medium tick + cloud sync disabled');
94
+ }
95
+ // Light tick — every 5 min (full) or every 15 min (mcp)
69
96
  this.lightTimer = setInterval(() => this.lightTick(), this.config.lightTickIntervalMs);
70
97
  this.lightTimer.unref();
71
- // Medium tick every 30 minutes (by default)
72
- this.mediumTimer = setInterval(() => this.mediumTick(), this.config.mediumTickIntervalMs);
73
- this.mediumTimer.unref();
74
- // Apply cached cloud Iron Dome patterns immediately on start (requires Pro+)
75
- if (isFeatureEnabled('custom_injection_patterns')) {
98
+ // Medium tick full profile only. mcp-mode skips link discovery,
99
+ // contradiction scans, graph maintenance, and sync-queue purging — those
100
+ // are dashboard concerns and shouldn't multiply across N MCP windows.
101
+ if (this.config.profile === 'full') {
102
+ this.mediumTimer = setInterval(() => this.mediumTick(), this.config.mediumTickIntervalMs);
103
+ this.mediumTimer.unref();
104
+ }
105
+ // Apply cached cloud Iron Dome patterns immediately on start (Pro+, full only)
106
+ if (this.config.profile === 'full' && isFeatureEnabled('custom_injection_patterns')) {
76
107
  try {
77
108
  applyCachedCloudPatterns();
78
109
  }
@@ -150,38 +181,42 @@ export class BrainWorker {
150
181
  result: result.predictiveConsolidation,
151
182
  });
152
183
  }
153
- // 3. Process cloud sync retry queue
154
- try {
155
- const retryResult = await processRetryQueue();
156
- if (retryResult.processed > 0) {
157
- console.log(`[BrainWorker] Sync retry queue: processed ${retryResult.processed} ` +
158
- `(${retryResult.succeeded} ok, ${retryResult.failed} retry, ${retryResult.permanentlyFailed} failed)`);
159
- }
160
- }
161
- catch (retryError) {
162
- console.error('[BrainWorker] Sync retry queue failed:', retryError);
163
- }
164
- // 4. Send cloud heartbeat (keeps device status "Online") — Team+ only
165
- if (isFeatureEnabled('cloud_sync')) {
184
+ // 3-5: cloud sync (retry queue, heartbeat, Iron Dome) — full profile only.
185
+ // Skipped under MCP profile so we don't fan out N concurrent network calls
186
+ // from N open Claude Code windows.
187
+ if (this.config.profile === 'full') {
166
188
  try {
167
- sendHeartbeat();
189
+ const retryResult = await processRetryQueue();
190
+ if (retryResult.processed > 0) {
191
+ console.log(`[BrainWorker] Sync retry queue: processed ${retryResult.processed} ` +
192
+ `(${retryResult.succeeded} ok, ${retryResult.failed} retry, ${retryResult.permanentlyFailed} failed)`);
193
+ }
168
194
  }
169
- catch {
170
- // Truly silent heartbeat is best-effort
195
+ catch (retryError) {
196
+ console.error('[BrainWorker] Sync retry queue failed:', retryError);
171
197
  }
172
- }
173
- // 5. Refresh Iron Dome cloud patterns + policy — Pro+ only
174
- if (isFeatureEnabled('custom_injection_patterns')) {
175
- try {
176
- await refreshCloudIronDome();
198
+ if (isFeatureEnabled('cloud_sync')) {
199
+ try {
200
+ sendHeartbeat();
201
+ }
202
+ catch {
203
+ // Truly silent — heartbeat is best-effort
204
+ }
177
205
  }
178
- catch {
179
- // Non-critical — cloud Iron Dome sync is best-effort
206
+ if (isFeatureEnabled('custom_injection_patterns')) {
207
+ try {
208
+ await refreshCloudIronDome();
209
+ }
210
+ catch {
211
+ // Non-critical — cloud Iron Dome sync is best-effort
212
+ }
180
213
  }
181
214
  }
182
215
  // Update stats
183
216
  this.lastLightTick = result.timestamp;
184
217
  this.stats.lightTicks++;
218
+ // Persist worker freshness for `shieldcortex doctor` to detect stalls.
219
+ persistWorkerState(this.config.profile, result.timestamp);
185
220
  // Emit light tick event
186
221
  emitWorkerLightTick(result);
187
222
  // Log summary
@@ -314,19 +349,24 @@ export class BrainWorker {
314
349
  // Default singleton instance (optional - server can create its own)
315
350
  let defaultWorker = null;
316
351
  /**
317
- * Get or create the default worker instance
352
+ * Get or create the default worker instance.
353
+ * The first call wins — subsequent calls return the existing singleton even
354
+ * if a different config is passed. That's intentional: it prevents accidental
355
+ * re-instantiation from creating two competing timer sets within one process.
318
356
  */
319
- export function getDefaultWorker() {
357
+ export function getDefaultWorker(config) {
320
358
  if (!defaultWorker) {
321
- defaultWorker = new BrainWorker();
359
+ defaultWorker = new BrainWorker(config);
322
360
  }
323
361
  return defaultWorker;
324
362
  }
325
363
  /**
326
- * Start the default worker if not already running
364
+ * Start the default worker if not already running. Forwards config to the
365
+ * underlying constructor on first call (used by MCP-server mode to start
366
+ * with `profile: 'mcp'`).
327
367
  */
328
- export function startDefaultWorker() {
329
- const worker = getDefaultWorker();
368
+ export function startDefaultWorker(config) {
369
+ const worker = getDefaultWorker(config);
330
370
  if (!worker.isActive()) {
331
371
  worker.start();
332
372
  }
@@ -7,6 +7,17 @@
7
7
  * for the background brain worker.
8
8
  */
9
9
  import { ConsolidationResult } from '../memory/types.js';
10
+ /**
11
+ * Worker profile.
12
+ * - 'full': dashboard / api / worker modes — runs medium tick, cloud sync,
13
+ * link discovery, the works.
14
+ * - 'mcp': default MCP-server mode (one process per Claude Code window) —
15
+ * keeps consolidation alive but skips heavy/networked work so we don't
16
+ * multiply background load by the number of open windows. Without this,
17
+ * hooks-only installs never run consolidation and STM never graduates
18
+ * to LTM (#45).
19
+ */
20
+ export type WorkerProfile = 'full' | 'mcp';
10
21
  /**
11
22
  * Configuration for the brain worker
12
23
  */
@@ -27,11 +38,19 @@ export interface WorkerConfig {
27
38
  contradictionScanLimit: number;
28
39
  /** High activity threshold - memories created in 30 min (default: 5) */
29
40
  highActivityThreshold: number;
41
+ /** Worker profile - 'full' (default) or 'mcp' (lite, see WorkerProfile docs) */
42
+ profile: WorkerProfile;
30
43
  }
31
44
  /**
32
45
  * Default worker configuration
33
46
  */
34
47
  export declare const DEFAULT_WORKER_CONFIG: WorkerConfig;
48
+ /**
49
+ * MCP-profile interval override. 15 min vs full's 5 min — one MCP server runs
50
+ * per Claude Code window, so we want lower per-window cadence to keep total
51
+ * background work in check across many windows.
52
+ */
53
+ export declare const MCP_LIGHT_TICK_INTERVAL_MS: number;
35
54
  /**
36
55
  * Result of a light tick operation
37
56
  */
@@ -18,4 +18,11 @@ export const DEFAULT_WORKER_CONFIG = {
18
18
  maxLinksPerCycle: 10,
19
19
  contradictionScanLimit: 50,
20
20
  highActivityThreshold: 5,
21
+ profile: 'full',
21
22
  };
23
+ /**
24
+ * MCP-profile interval override. 15 min vs full's 5 min — one MCP server runs
25
+ * per Claude Code window, so we want lower per-window cadence to keep total
26
+ * background work in check across many windows.
27
+ */
28
+ export const MCP_LIGHT_TICK_INTERVAL_MS = 15 * 60 * 1000;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shieldcortex",
3
- "version": "4.13.1",
3
+ "version": "4.14.0",
4
4
  "description": "Trustworthy memory and security for AI agents. Recall debugging, review queue, OpenClaw session capture, and memory poisoning defence for Claude Code, Codex, OpenClaw, LangChain, and MCP agents.",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "shieldcortex-realtime",
3
- "version": "4.13.1",
3
+ "version": "4.14.0",
4
4
  "name": "ShieldCortex Real-time Scanner",
5
5
  "description": "Real-time defence scanning on LLM input, memory extraction on LLM output, and active tool call interception with approval gating.",
6
6
  "kind": null,
@@ -15,7 +15,14 @@ const DEFAULTS = Object.freeze({
15
15
  maxTranscriptBytes: 1024 * 1024,
16
16
  maxTranscriptLines: 5000,
17
17
  keepSlashCommandProse: true,
18
- stopHookSamplingTurns: 10,
18
+ // Lowered 10 → 5 in v4.14.0. At 1-in-10 the realistic capture rate over
19
+ // typical sessions was ~7%, which left LTM near-empty (#44). Salience
20
+ // bypass below catches high-signal turns at any cadence.
21
+ stopHookSamplingTurns: 5,
22
+ // Bypass the modulo gate when the last assistant turn carries a fenced
23
+ // code block or hits multiple keyword categories — those turns are
24
+ // disproportionately what we want to remember.
25
+ stopHookSalienceBypass: true,
19
26
  stopHookWindowBytes: 256 * 1024,
20
27
  enableSessionEnd: false,
21
28
  enableStop: false,
@@ -39,6 +46,9 @@ export function getAutoMemoryConfig() {
39
46
  ? overrides.keepSlashCommandProse
40
47
  : DEFAULTS.keepSlashCommandProse,
41
48
  stopHookSamplingTurns: pickPositiveInt(overrides.stopHookSamplingTurns, DEFAULTS.stopHookSamplingTurns),
49
+ stopHookSalienceBypass: typeof overrides.stopHookSalienceBypass === 'boolean'
50
+ ? overrides.stopHookSalienceBypass
51
+ : DEFAULTS.stopHookSalienceBypass,
42
52
  stopHookWindowBytes: pickPositiveInt(overrides.stopHookWindowBytes, DEFAULTS.stopHookWindowBytes),
43
53
  enableSessionEnd: overrides.enableSessionEnd === true,
44
54
  enableStop: overrides.enableStop === true,