@rubytech/create-maxy 1.0.773 → 1.0.775

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 (225) hide show
  1. package/package.json +1 -1
  2. package/payload/platform/config/brand.json +1 -0
  3. package/payload/platform/lib/entitlement/PUBKEY-HASH.txt +1 -0
  4. package/payload/platform/lib/entitlement/dist/canonicalize.d.ts +26 -0
  5. package/payload/platform/lib/entitlement/dist/canonicalize.d.ts.map +1 -0
  6. package/payload/platform/lib/entitlement/dist/canonicalize.js +54 -0
  7. package/payload/platform/lib/entitlement/dist/canonicalize.js.map +1 -0
  8. package/payload/platform/lib/entitlement/dist/index.d.ts +76 -0
  9. package/payload/platform/lib/entitlement/dist/index.d.ts.map +1 -0
  10. package/payload/platform/lib/entitlement/dist/index.js +293 -0
  11. package/payload/platform/lib/entitlement/dist/index.js.map +1 -0
  12. package/payload/platform/lib/entitlement/rubytech-pubkey.pem +3 -0
  13. package/payload/platform/package.json +2 -2
  14. package/payload/platform/plugins/admin/hooks/pre-tool-use.sh +32 -0
  15. package/payload/platform/plugins/admin/mcp/dist/index.js +97 -6
  16. package/payload/platform/plugins/admin/mcp/dist/index.js.map +1 -1
  17. package/payload/platform/plugins/admin/skills/plugin-management/SKILL.md +10 -5
  18. package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.d.ts +61 -0
  19. package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.d.ts.map +1 -0
  20. package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.js +266 -0
  21. package/payload/platform/plugins/memory/mcp/dist/lib/semantic-chunker.js.map +1 -0
  22. package/payload/platform/scripts/generate-entitlement-fixture.mjs +152 -0
  23. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/index.d.ts +2 -0
  24. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/index.d.ts.map +1 -0
  25. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/index.js +293 -0
  26. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/index.js.map +1 -0
  27. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/lib/crypto.d.ts +10 -0
  28. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/lib/crypto.d.ts.map +1 -0
  29. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/lib/crypto.js +88 -0
  30. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/lib/crypto.js.map +1 -0
  31. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/lib/loop-api.d.ts +80 -0
  32. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/lib/loop-api.d.ts.map +1 -0
  33. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/lib/loop-api.js +355 -0
  34. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/lib/loop-api.js.map +1 -0
  35. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/lib/neo4j.d.ts +5 -0
  36. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/lib/neo4j.d.ts.map +1 -0
  37. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/lib/neo4j.js +34 -0
  38. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/lib/neo4j.js.map +1 -0
  39. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/customer-preferences.d.ts +10 -0
  40. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/customer-preferences.d.ts.map +1 -0
  41. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/customer-preferences.js +24 -0
  42. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/customer-preferences.js.map +1 -0
  43. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/feedback-list.d.ts +6 -0
  44. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/feedback-list.d.ts.map +1 -0
  45. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/feedback-list.js +18 -0
  46. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/feedback-list.js.map +1 -0
  47. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/feedback.d.ts +16 -0
  48. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/feedback.d.ts.map +1 -0
  49. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/feedback.js +35 -0
  50. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/feedback.js.map +1 -0
  51. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/key-deregister.d.ts +5 -0
  52. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/key-deregister.d.ts.map +1 -0
  53. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/key-deregister.js +19 -0
  54. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/key-deregister.js.map +1 -0
  55. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/key-list.d.ts +4 -0
  56. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/key-list.d.ts.map +1 -0
  57. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/key-list.js +14 -0
  58. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/key-list.js.map +1 -0
  59. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/key-register.d.ts +9 -0
  60. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/key-register.d.ts.map +1 -0
  61. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/key-register.js +60 -0
  62. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/key-register.js.map +1 -0
  63. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-enquiry.d.ts +13 -0
  64. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-enquiry.d.ts.map +1 -0
  65. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-enquiry.js +41 -0
  66. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-enquiry.js.map +1 -0
  67. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match-batch.d.ts +9 -0
  68. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match-batch.d.ts.map +1 -0
  69. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match-batch.js +16 -0
  70. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match-batch.js.map +1 -0
  71. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match-request.d.ts +15 -0
  72. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match-request.d.ts.map +1 -0
  73. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match-request.js +11 -0
  74. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match-request.js.map +1 -0
  75. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match.d.ts +10 -0
  76. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match.d.ts.map +1 -0
  77. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match.js +39 -0
  78. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/marketing-match.js.map +1 -0
  79. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-detail.d.ts +9 -0
  80. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-detail.d.ts.map +1 -0
  81. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-detail.js +125 -0
  82. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-detail.js.map +1 -0
  83. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-list.d.ts +7 -0
  84. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-list.d.ts.map +1 -0
  85. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-list.js +16 -0
  86. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-list.js.map +1 -0
  87. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-search.d.ts +18 -0
  88. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-search.d.ts.map +1 -0
  89. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-search.js +87 -0
  90. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/people-search.js.map +1 -0
  91. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/properties-list.d.ts +7 -0
  92. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/properties-list.d.ts.map +1 -0
  93. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/properties-list.js +19 -0
  94. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/properties-list.js.map +1 -0
  95. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-detail.d.ts +10 -0
  96. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-detail.d.ts.map +1 -0
  97. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-detail.js +82 -0
  98. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-detail.js.map +1 -0
  99. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-listed.d.ts +12 -0
  100. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-listed.d.ts.map +1 -0
  101. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-listed.js +32 -0
  102. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-listed.js.map +1 -0
  103. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-request.d.ts +15 -0
  104. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-request.d.ts.map +1 -0
  105. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-request.js +11 -0
  106. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-request.js.map +1 -0
  107. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-search.d.ts +16 -0
  108. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-search.d.ts.map +1 -0
  109. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-search.js +41 -0
  110. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/property-search.js.map +1 -0
  111. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/supplier.d.ts +13 -0
  112. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/supplier.d.ts.map +1 -0
  113. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/supplier.js +49 -0
  114. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/supplier.js.map +1 -0
  115. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/team-availability.d.ts +7 -0
  116. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/team-availability.d.ts.map +1 -0
  117. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/team-availability.js +19 -0
  118. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/team-availability.js.map +1 -0
  119. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/team-info.d.ts +5 -0
  120. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/team-info.d.ts.map +1 -0
  121. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/team-info.js +32 -0
  122. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/team-info.js.map +1 -0
  123. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-create.d.ts +14 -0
  124. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-create.d.ts.map +1 -0
  125. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-create.js +11 -0
  126. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-create.js.map +1 -0
  127. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-detail.d.ts +9 -0
  128. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-detail.d.ts.map +1 -0
  129. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-detail.js +85 -0
  130. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-detail.js.map +1 -0
  131. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-search.d.ts +13 -0
  132. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-search.d.ts.map +1 -0
  133. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-search.js +44 -0
  134. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-search.js.map +1 -0
  135. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-update.d.ts +14 -0
  136. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-update.d.ts.map +1 -0
  137. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-update.js +18 -0
  138. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewing-update.js.map +1 -0
  139. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewings-list.d.ts +9 -0
  140. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewings-list.d.ts.map +1 -0
  141. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewings-list.js +25 -0
  142. package/payload/premium-plugins/real-agency/plugins/real-agency-loop/mcp/dist/tools/viewings-list.js.map +1 -0
  143. package/payload/server/chunk-26QT2HEQ.js +9483 -0
  144. package/payload/server/chunk-2T4RRIJK.js +9462 -0
  145. package/payload/server/chunk-2W7O63CK.js +3052 -0
  146. package/payload/server/chunk-32ZHQJNX.js +11395 -0
  147. package/payload/server/chunk-3KDVGWPQ.js +2920 -0
  148. package/payload/server/chunk-3RBKKDHC.js +783 -0
  149. package/payload/server/chunk-3VVHVJK2.js +11405 -0
  150. package/payload/server/chunk-43JK6WNK.js +3057 -0
  151. package/payload/server/chunk-57S5JC7G.js +9563 -0
  152. package/payload/server/chunk-5YIXIF6C.js +726 -0
  153. package/payload/server/chunk-7ODDM7L4.js +12370 -0
  154. package/payload/server/chunk-A5K3CFMI.js +12297 -0
  155. package/payload/server/chunk-AIWWYOBH.js +9439 -0
  156. package/payload/server/chunk-B54KBAK4.js +72 -0
  157. package/payload/server/chunk-BIOIXN5A.js +12165 -0
  158. package/payload/server/chunk-D53LK5YC.js +12171 -0
  159. package/payload/server/chunk-EIQT6QDH.js +9562 -0
  160. package/payload/server/chunk-FM5JMRED.js +12033 -0
  161. package/payload/server/chunk-HPU24BXP.js +12173 -0
  162. package/payload/server/chunk-HU5FSQYA.js +12186 -0
  163. package/payload/server/chunk-IAIGB5WN.js +11406 -0
  164. package/payload/server/chunk-IO2WQEY4.js +9562 -0
  165. package/payload/server/chunk-JDT3MGUY.js +12165 -0
  166. package/payload/server/chunk-JLVVVQN7.js +9447 -0
  167. package/payload/server/chunk-K7GQ5RMN.js +12172 -0
  168. package/payload/server/chunk-LQ5GSMEW.js +12036 -0
  169. package/payload/server/chunk-MIP54X7Q.js +3244 -0
  170. package/payload/server/chunk-MPWGVFU2.js +12340 -0
  171. package/payload/server/chunk-O2FWENOD.js +11530 -0
  172. package/payload/server/chunk-PE76FPYP.js +12040 -0
  173. package/payload/server/chunk-PQ6LDXZ4.js +2997 -0
  174. package/payload/server/chunk-Q6NDXCM6.js +11448 -0
  175. package/payload/server/chunk-QXAUMZXQ.js +9512 -0
  176. package/payload/server/chunk-S3M2NZMA.js +3136 -0
  177. package/payload/server/chunk-SGBNY4NP.js +9540 -0
  178. package/payload/server/chunk-SKXO42T6.js +2934 -0
  179. package/payload/server/chunk-SPTD7L7Z.js +9474 -0
  180. package/payload/server/chunk-TKYZ7AEB.js +3142 -0
  181. package/payload/server/chunk-TM3EQSID.js +9800 -0
  182. package/payload/server/chunk-TXPEEAV6.js +2997 -0
  183. package/payload/server/chunk-U3W5YIXU.js +11450 -0
  184. package/payload/server/chunk-U5JPRUYZ.js +12298 -0
  185. package/payload/server/chunk-UFLV7I6N.js +11678 -0
  186. package/payload/server/chunk-ULVR2RRY.js +9439 -0
  187. package/payload/server/chunk-VOD2IZ6J.js +2934 -0
  188. package/payload/server/chunk-VS7CRH4M.js +9439 -0
  189. package/payload/server/chunk-W6ZUNLLS.js +9446 -0
  190. package/payload/server/chunk-WW464F23.js +9512 -0
  191. package/payload/server/chunk-XHFMXKXI.js +3179 -0
  192. package/payload/server/chunk-Y57ACANQ.js +12292 -0
  193. package/payload/server/chunk-ZK3VNR7Y.js +9510 -0
  194. package/payload/server/chunk-ZL2A4ROK.js +11416 -0
  195. package/payload/server/client-pool-4MZN42GG.js +28 -0
  196. package/payload/server/client-pool-5V5GX3UT.js +28 -0
  197. package/payload/server/client-pool-67NUIL7H.js +28 -0
  198. package/payload/server/client-pool-CX2MFW75.js +28 -0
  199. package/payload/server/client-pool-DQBHSKAF.js +28 -0
  200. package/payload/server/client-pool-I5TCP7WI.js +28 -0
  201. package/payload/server/client-pool-ISMYJXCU.js +28 -0
  202. package/payload/server/client-pool-J4ZHJ6Z3.js +28 -0
  203. package/payload/server/client-pool-SGPHSYLK.js +28 -0
  204. package/payload/server/client-pool-TCKGDZLE.js +28 -0
  205. package/payload/server/client-pool-TULUIO6M.js +28 -0
  206. package/payload/server/maxy-edge.js +2 -2
  207. package/payload/server/public/assets/{Checkbox-DEE8t2QO.js → Checkbox-C_KxaLc-.js} +1 -1
  208. package/payload/server/public/assets/{admin-C4CTVtBu.js → admin-xbKPR6ZI.js} +30 -30
  209. package/payload/server/public/assets/data-D23IzpJ2.js +1 -0
  210. package/payload/server/public/assets/graph-D2AS9zFS.js +1 -0
  211. package/payload/server/public/assets/{jsx-runtime-DSbkOE76.css → jsx-runtime-BZtBxBng.css} +1 -1
  212. package/payload/server/public/assets/{page-YUT5e7hL.js → page-CjTfZ3O6.js} +2 -2
  213. package/payload/server/public/assets/{page-ZATk95ZG.js → page-DEWgk_nR.js} +1 -1
  214. package/payload/server/public/assets/{public-BLi3J8KU.js → public-CehiL-qZ.js} +1 -1
  215. package/payload/server/public/assets/{share-2-DS7Pnkkq.js → share-2-BG1VXt3z.js} +1 -1
  216. package/payload/server/public/assets/{useVoiceRecorder-pEHqS1ib.js → useVoiceRecorder-1Dvb-yHn.js} +1 -1
  217. package/payload/server/public/data.html +5 -5
  218. package/payload/server/public/graph.html +6 -6
  219. package/payload/server/public/index.html +8 -8
  220. package/payload/server/public/public.html +5 -5
  221. package/payload/server/server.js +31 -16
  222. package/payload/server/upgrade-progress-server.js +83 -0
  223. package/payload/server/public/assets/data-ryPag-T-.js +0 -1
  224. package/payload/server/public/assets/graph-BPnH-UZB.js +0 -1
  225. /package/payload/server/public/assets/{jsx-runtime-DeNudFNA.js → jsx-runtime-DrneHL3t.js} +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rubytech/create-maxy",
3
- "version": "1.0.773",
3
+ "version": "1.0.775",
4
4
  "description": "Install Maxy — AI for Productive People",
5
5
  "bin": {
6
6
  "create-maxy": "./dist/index.js"
@@ -9,6 +9,7 @@
9
9
  "domain": "getmaxy.com",
10
10
  "neo4jPort": 7687,
11
11
  "ttydPort": 7681,
12
+ "commercialMode": false,
12
13
 
13
14
  "defaultColors": {
14
15
  "primary": "#7C8C72",
@@ -0,0 +1 @@
1
+ 8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d99db79
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Deterministic canonical JSON serializer for Ed25519 signing/verification.
3
+ *
4
+ * Why purpose-built and not RFC 8785 (JCS) or a vendored canonicalize lib:
5
+ * the entitlement payload schema is tightly controlled — flat object, primitives
6
+ * plus one string array (purchasedPlugins). A 30-line implementation covers it
7
+ * exactly and stays zero-dep, which matters because the create-maxy bundle
8
+ * has a hardcoded externalDeps surface that any new runtime dep must thread.
9
+ *
10
+ * Rules:
11
+ * - object keys sorted lexicographically (Array.prototype.sort default)
12
+ * - no whitespace
13
+ * - strings JSON.stringify-escaped (handles unicode, quotes, backslashes)
14
+ * - numbers in finite IEEE 754; reject NaN / Infinity / -0
15
+ * - booleans + null verbatim
16
+ * - arrays preserve element order (signing party owns array semantics)
17
+ * - throws on unsupported value types (functions, undefined, symbols, bigint)
18
+ *
19
+ * Both sides (Rubytech signer + customer verifier) call canonicalize() before
20
+ * signing/verifying. Canonical bytes are UTF-8 of the returned string.
21
+ */
22
+ export type CanonicalValue = string | number | boolean | null | CanonicalValue[] | {
23
+ [k: string]: CanonicalValue;
24
+ };
25
+ export declare function canonicalize(value: CanonicalValue): string;
26
+ //# sourceMappingURL=canonicalize.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonicalize.d.ts","sourceRoot":"","sources":["../src/canonicalize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,MAAM,GACN,OAAO,GACP,IAAI,GACJ,cAAc,EAAE,GAChB;IAAE,CAAC,CAAC,EAAE,MAAM,GAAG,cAAc,CAAA;CAAE,CAAC;AAEpC,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAyB1D"}
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ /**
3
+ * Deterministic canonical JSON serializer for Ed25519 signing/verification.
4
+ *
5
+ * Why purpose-built and not RFC 8785 (JCS) or a vendored canonicalize lib:
6
+ * the entitlement payload schema is tightly controlled — flat object, primitives
7
+ * plus one string array (purchasedPlugins). A 30-line implementation covers it
8
+ * exactly and stays zero-dep, which matters because the create-maxy bundle
9
+ * has a hardcoded externalDeps surface that any new runtime dep must thread.
10
+ *
11
+ * Rules:
12
+ * - object keys sorted lexicographically (Array.prototype.sort default)
13
+ * - no whitespace
14
+ * - strings JSON.stringify-escaped (handles unicode, quotes, backslashes)
15
+ * - numbers in finite IEEE 754; reject NaN / Infinity / -0
16
+ * - booleans + null verbatim
17
+ * - arrays preserve element order (signing party owns array semantics)
18
+ * - throws on unsupported value types (functions, undefined, symbols, bigint)
19
+ *
20
+ * Both sides (Rubytech signer + customer verifier) call canonicalize() before
21
+ * signing/verifying. Canonical bytes are UTF-8 of the returned string.
22
+ */
23
+ Object.defineProperty(exports, "__esModule", { value: true });
24
+ exports.canonicalize = canonicalize;
25
+ function canonicalize(value) {
26
+ if (value === null)
27
+ return "null";
28
+ if (typeof value === "boolean")
29
+ return value ? "true" : "false";
30
+ if (typeof value === "string")
31
+ return JSON.stringify(value);
32
+ if (typeof value === "number") {
33
+ if (!Number.isFinite(value)) {
34
+ throw new Error(`canonicalize: non-finite number rejected (${value})`);
35
+ }
36
+ if (Object.is(value, -0)) {
37
+ throw new Error("canonicalize: negative zero rejected");
38
+ }
39
+ return JSON.stringify(value);
40
+ }
41
+ if (Array.isArray(value)) {
42
+ return "[" + value.map(canonicalize).join(",") + "]";
43
+ }
44
+ if (typeof value === "object") {
45
+ const keys = Object.keys(value).sort();
46
+ const parts = [];
47
+ for (const k of keys) {
48
+ parts.push(JSON.stringify(k) + ":" + canonicalize(value[k]));
49
+ }
50
+ return "{" + parts.join(",") + "}";
51
+ }
52
+ throw new Error(`canonicalize: unsupported value type ${typeof value}`);
53
+ }
54
+ //# sourceMappingURL=canonicalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"canonicalize.js","sourceRoot":"","sources":["../src/canonicalize.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;;AAUH,oCAyBC;AAzBD,SAAgB,YAAY,CAAC,KAAqB;IAChD,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,MAAM,CAAC;IAClC,IAAI,OAAO,KAAK,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;IAChE,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5D,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,6CAA6C,KAAK,GAAG,CAAC,CAAC;QACzE,CAAC;QACD,IAAI,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;IAC/B,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACvD,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QACvC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,CAAC;QACD,OAAO,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;IACrC,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,wCAAwC,OAAO,KAAK,EAAE,CAAC,CAAC;AAC1E,CAAC"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Entitlement verifier — single source of truth for effective tier and
3
+ * purchasedPlugins on a Maxy/Real-Agent install. Pre-launch security gate
4
+ * for paid tiers (Task 831).
5
+ *
6
+ * Doctrine: account.json is agent-writable; entitlement is not. Effective
7
+ * tier and purchasedPlugins derive from a Rubytech-signed Ed25519 payload,
8
+ * not from raw account.json values. Editing account.json directly has no
9
+ * runtime effect; the verifier compares disk against signed and uses signed.
10
+ *
11
+ * ┌────────────────────────────┐
12
+ * │ session start │
13
+ * └─────────────┬──────────────┘
14
+ * ▼
15
+ * ┌────────────────────────────┐
16
+ * │ read brand.json │
17
+ * │ commercialMode? (default │
18
+ * │ false on personal-mode) │
19
+ * └────────┬───────────────┬───┘
20
+ * │false │true
21
+ * ▼ ▼
22
+ * source=implicit-trust read entitlement.json
23
+ * (raw account.json) │
24
+ * ├─missing──▶ anonymous-fallback (lock)
25
+ * ├─malformed─▶ anonymous-fallback
26
+ * ├─pubkey-tampered─▶ anonymous-fallback
27
+ * ├─bad sig──▶ anonymous-fallback
28
+ * ├─binding mismatch─▶ anonymous-fallback
29
+ * ├─clock skew──▶ anonymous-fallback
30
+ * ├─expired+grace─▶ signed-grace
31
+ * ├─expired post-grace─▶ anonymous-fallback (lock)
32
+ * └─valid─▶ signed
33
+ *
34
+ * Threat model: this code closes the agent-self-elevation bypass and the
35
+ * casual operator vim-edit bypass. A determined operator with shell access
36
+ * who replaces the vendored pubkey AND regenerates the SHA-256 hash baked
37
+ * into PUBKEY_SHA256 below can still defeat the verifier — that is the
38
+ * accepted out-of-scope per task 831 ("raise bypass cost to break the
39
+ * signature, not to edit JSON"). Hardware binding is the only counter and
40
+ * is explicitly out of scope.
41
+ */
42
+ export declare const PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d99db79";
43
+ export type EntitlementSource = "signed" | "signed-grace" | "implicit-trust" | "anonymous-fallback";
44
+ export interface ResolvedEntitlement {
45
+ tier: string;
46
+ purchasedPlugins: string[];
47
+ source: EntitlementSource;
48
+ issued: string | null;
49
+ expires: string | null;
50
+ }
51
+ export interface AccountConfigSubset {
52
+ accountId: string;
53
+ customerEmail?: string;
54
+ tier?: string;
55
+ purchasedPlugins?: string[];
56
+ }
57
+ export interface BrandConfigSubset {
58
+ /** Absolute path to ~/<configDir> where entitlement.json is delivered. */
59
+ configDir: string;
60
+ /** Absolute path to platform/ root; pubkey lives at <platformRoot>/lib/entitlement/rubytech-pubkey.pem. */
61
+ platformRoot: string;
62
+ /** True only when this brand has flipped to commercial entitlement enforcement. */
63
+ commercialMode?: boolean;
64
+ }
65
+ /**
66
+ * Resolve effective entitlement for the current install. Sync — Ed25519
67
+ * verify is a CPU-bound primitive on the order of 0.3ms; no async surface.
68
+ *
69
+ * @param brand Brand config (read from platform/config/brand.json by caller)
70
+ * @param account Account config (read from data/accounts/<id>/account.json)
71
+ * @returns Effective entitlement plus the source tag for observability.
72
+ */
73
+ export declare function resolveEntitlement(brand: BrandConfigSubset, account: AccountConfigSubset): ResolvedEntitlement;
74
+ /** Test-only: clear the memoization cache. Not used in production. */
75
+ export declare function _clearMemo(): void;
76
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAoBH,eAAO,MAAM,aAAa,qEAAqE,CAAC;AAMhG,MAAM,MAAM,iBAAiB,GACzB,QAAQ,GACR,cAAc,GACd,gBAAgB,GAChB,oBAAoB,CAAC;AAEzB,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,MAAM,WAAW,iBAAiB;IAChC,0EAA0E;IAC1E,SAAS,EAAE,MAAM,CAAC;IAClB,2GAA2G;IAC3G,YAAY,EAAE,MAAM,CAAC;IACrB,mFAAmF;IACnF,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AA0BD;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,iBAAiB,EACxB,OAAO,EAAE,mBAAmB,GAC3B,mBAAmB,CAuBrB;AAED,sEAAsE;AACtE,wBAAgB,UAAU,IAAI,IAAI,CAEjC"}
@@ -0,0 +1,293 @@
1
+ "use strict";
2
+ /**
3
+ * Entitlement verifier — single source of truth for effective tier and
4
+ * purchasedPlugins on a Maxy/Real-Agent install. Pre-launch security gate
5
+ * for paid tiers (Task 831).
6
+ *
7
+ * Doctrine: account.json is agent-writable; entitlement is not. Effective
8
+ * tier and purchasedPlugins derive from a Rubytech-signed Ed25519 payload,
9
+ * not from raw account.json values. Editing account.json directly has no
10
+ * runtime effect; the verifier compares disk against signed and uses signed.
11
+ *
12
+ * ┌────────────────────────────┐
13
+ * │ session start │
14
+ * └─────────────┬──────────────┘
15
+ * ▼
16
+ * ┌────────────────────────────┐
17
+ * │ read brand.json │
18
+ * │ commercialMode? (default │
19
+ * │ false on personal-mode) │
20
+ * └────────┬───────────────┬───┘
21
+ * │false │true
22
+ * ▼ ▼
23
+ * source=implicit-trust read entitlement.json
24
+ * (raw account.json) │
25
+ * ├─missing──▶ anonymous-fallback (lock)
26
+ * ├─malformed─▶ anonymous-fallback
27
+ * ├─pubkey-tampered─▶ anonymous-fallback
28
+ * ├─bad sig──▶ anonymous-fallback
29
+ * ├─binding mismatch─▶ anonymous-fallback
30
+ * ├─clock skew──▶ anonymous-fallback
31
+ * ├─expired+grace─▶ signed-grace
32
+ * ├─expired post-grace─▶ anonymous-fallback (lock)
33
+ * └─valid─▶ signed
34
+ *
35
+ * Threat model: this code closes the agent-self-elevation bypass and the
36
+ * casual operator vim-edit bypass. A determined operator with shell access
37
+ * who replaces the vendored pubkey AND regenerates the SHA-256 hash baked
38
+ * into PUBKEY_SHA256 below can still defeat the verifier — that is the
39
+ * accepted out-of-scope per task 831 ("raise bypass cost to break the
40
+ * signature, not to edit JSON"). Hardware binding is the only counter and
41
+ * is explicitly out of scope.
42
+ */
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.PUBKEY_SHA256 = void 0;
45
+ exports.resolveEntitlement = resolveEntitlement;
46
+ exports._clearMemo = _clearMemo;
47
+ const node_crypto_1 = require("node:crypto");
48
+ const node_fs_1 = require("node:fs");
49
+ const node_path_1 = require("node:path");
50
+ const canonicalize_js_1 = require("./canonicalize.js");
51
+ // __dirname is undefined in pure ESM bundles (platform/ui's tsup output is
52
+ // format: ['esm'] with no shims:true). The MCP plugin path imports the CJS
53
+ // build (dist/) where __dirname works, but the UI server imports the TS
54
+ // source directly and tsup-bundles it as ESM. To work in both worlds, the
55
+ // caller passes the platform root explicitly via BrandConfigSubset.platformRoot.
56
+ // ---------------------------------------------------------------------------
57
+ // Vendored pubkey — shipped at platform/lib/entitlement/rubytech-pubkey.pem.
58
+ // PUBKEY_SHA256 is the expected hex SHA-256 of the file's bytes; if the
59
+ // on-disk file's hash diverges the verifier emits pubkey-tamper and falls
60
+ // back to anonymous. Update both when Rubytech rotates the keypair.
61
+ // ---------------------------------------------------------------------------
62
+ exports.PUBKEY_SHA256 = "8eee6bcb33545fd13b16d3199a5735ca5db5062834c7b49dfe4f23801d99db79";
63
+ const GRACE_DAYS = 7;
64
+ const GRACE_MS = GRACE_DAYS * 24 * 60 * 60 * 1000;
65
+ function pubkeyPath(brand) {
66
+ return (0, node_path_1.resolve)(brand.platformRoot, "lib", "entitlement", "rubytech-pubkey.pem");
67
+ }
68
+ // Memoize per-process, scoped to (mtime, accountId, customerEmail). Scoping
69
+ // by accountId is mandatory: the binding check at verifyAndResolve runs once
70
+ // per call, and a memo keyed on mtime alone would return account A's verified
71
+ // result to account B's request — bypassing the per-call binding check
72
+ // (account isolation doctrine, feedback_account_isolation_absolute).
73
+ let memo = null;
74
+ function memoKey(mtimeMs, account) {
75
+ // Coarse 60-second time bucket ensures the memo invalidates around the
76
+ // expires/grace boundary even when entitlement.json mtime never changes
77
+ // (long-running UI server, no file refresh until Task 832 ships).
78
+ const bucket = Math.floor(Date.now() / 60000);
79
+ return `${mtimeMs}:${bucket}:${account.accountId}:${account.customerEmail ?? ""}`;
80
+ }
81
+ const VALID_TIERS = new Set(["solo", "family", "pro"]);
82
+ /**
83
+ * Resolve effective entitlement for the current install. Sync — Ed25519
84
+ * verify is a CPU-bound primitive on the order of 0.3ms; no async surface.
85
+ *
86
+ * @param brand Brand config (read from platform/config/brand.json by caller)
87
+ * @param account Account config (read from data/accounts/<id>/account.json)
88
+ * @returns Effective entitlement plus the source tag for observability.
89
+ */
90
+ function resolveEntitlement(brand, account) {
91
+ // Personal mode (commercialMode !== true): always implicit-trust. A stray
92
+ // entitlement.json (backup-restore, dev artefact) must NOT lock out a
93
+ // personal-mode user — verification only runs when the brand is commercial.
94
+ if (brand.commercialMode !== true) {
95
+ return logResolved(implicitTrust(account), null);
96
+ }
97
+ const entitlementPath = (0, node_path_1.resolve)(brand.configDir, "entitlement.json");
98
+ if (!(0, node_fs_1.existsSync)(entitlementPath)) {
99
+ return logResolved(anonymousFallback("missing"), { reason: "missing" });
100
+ }
101
+ // (mtime, time-bucket, accountId, customerEmail)-keyed memoization
102
+ const stat = (0, node_fs_1.statSync)(entitlementPath);
103
+ const key = memoKey(stat.mtimeMs, account);
104
+ if (memo && memo.key === key) {
105
+ return memo.result;
106
+ }
107
+ const result = verifyAndResolve(brand, entitlementPath, account);
108
+ memo = { key, result };
109
+ return result;
110
+ }
111
+ /** Test-only: clear the memoization cache. Not used in production. */
112
+ function _clearMemo() {
113
+ memo = null;
114
+ }
115
+ // ---------------------------------------------------------------------------
116
+ // Internals
117
+ // ---------------------------------------------------------------------------
118
+ function verifyAndResolve(brand, entitlementPath, account) {
119
+ // Step 1: pubkey integrity. If the vendored pubkey has been swapped on
120
+ // disk, refuse to use it — emit verify-failed and degrade.
121
+ let pubkeyPem;
122
+ try {
123
+ pubkeyPem = (0, node_fs_1.readFileSync)(pubkeyPath(brand), "utf-8");
124
+ }
125
+ catch (err) {
126
+ return logResolved(anonymousFallback("pubkey-missing"), {
127
+ reason: "pubkey-missing",
128
+ });
129
+ }
130
+ const pubkeyHash = (0, node_crypto_1.createHash)("sha256").update(pubkeyPem).digest("hex");
131
+ if (pubkeyHash !== exports.PUBKEY_SHA256) {
132
+ return logResolved(anonymousFallback("pubkey-tamper"), {
133
+ reason: "pubkey-tamper",
134
+ });
135
+ }
136
+ // Step 2: parse the entitlement envelope.
137
+ let envelope;
138
+ try {
139
+ envelope = JSON.parse((0, node_fs_1.readFileSync)(entitlementPath, "utf-8"));
140
+ }
141
+ catch {
142
+ return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
143
+ }
144
+ if (typeof envelope !== "object" ||
145
+ envelope === null ||
146
+ typeof envelope.signature !== "string" ||
147
+ typeof envelope.payload !== "object" ||
148
+ envelope.payload === null) {
149
+ return logResolved(anonymousFallback("malformed"), { reason: "malformed" });
150
+ }
151
+ const payload = envelope.payload;
152
+ const signatureB64 = envelope.signature;
153
+ // Step 3: signature verification over canonical bytes.
154
+ let pubkey;
155
+ try {
156
+ pubkey = (0, node_crypto_1.createPublicKey)(pubkeyPem);
157
+ }
158
+ catch {
159
+ return logResolved(anonymousFallback("pubkey-malformed"), {
160
+ reason: "pubkey-malformed",
161
+ });
162
+ }
163
+ let canonical;
164
+ try {
165
+ canonical = (0, canonicalize_js_1.canonicalize)(payload);
166
+ }
167
+ catch {
168
+ return logResolved(anonymousFallback("payload-shape"), {
169
+ reason: "payload-shape",
170
+ });
171
+ }
172
+ let sigBuf;
173
+ try {
174
+ sigBuf = Buffer.from(signatureB64, "base64");
175
+ }
176
+ catch {
177
+ return logResolved(anonymousFallback("signature-encoding"), {
178
+ reason: "signature-encoding",
179
+ });
180
+ }
181
+ const ok = (0, node_crypto_1.verify)(null, Buffer.from(canonical, "utf-8"), pubkey, sigBuf);
182
+ if (!ok) {
183
+ return logResolved(anonymousFallback("signature"), { reason: "signature" });
184
+ }
185
+ // Step 4: bindings — accountId and customerEmail must match local truth.
186
+ if (typeof payload.accountId !== "string" || payload.accountId !== account.accountId) {
187
+ return logResolved(anonymousFallback("binding-account"), {
188
+ reason: "binding-account",
189
+ });
190
+ }
191
+ // customerEmail binding: enforce when EITHER side has a value. Skipping when
192
+ // only the local side is empty would let an attacker forge an account.json
193
+ // without customerEmail to silently bypass the email binding while keeping
194
+ // the matching accountId. Symmetric: signed has it OR local has it → must match.
195
+ const signedEmail = typeof payload.customerEmail === "string" ? payload.customerEmail : undefined;
196
+ if (signedEmail !== undefined || account.customerEmail !== undefined) {
197
+ if (signedEmail !== account.customerEmail) {
198
+ return logResolved(anonymousFallback("binding-email"), {
199
+ reason: "binding-email",
200
+ });
201
+ }
202
+ }
203
+ // Step 5: temporal checks.
204
+ const issuedRaw = payload.issued;
205
+ const expiresRaw = payload.expires;
206
+ if (typeof issuedRaw !== "string" || typeof expiresRaw !== "string") {
207
+ return logResolved(anonymousFallback("temporal-shape"), {
208
+ reason: "temporal-shape",
209
+ });
210
+ }
211
+ const issued = Date.parse(issuedRaw);
212
+ const expires = Date.parse(expiresRaw);
213
+ const now = Date.now();
214
+ if (Number.isNaN(issued) || Number.isNaN(expires)) {
215
+ return logResolved(anonymousFallback("temporal-shape"), {
216
+ reason: "temporal-shape",
217
+ });
218
+ }
219
+ if (issued > now) {
220
+ return logResolved(anonymousFallback("clock-skew"), {
221
+ reason: "clock-skew",
222
+ });
223
+ }
224
+ // Reject empty/unknown tier. An empty string passing through here would
225
+ // hit `MAX_ADMINS_BY_TIER[""] ?? MAX_ADMINS_DEFAULT` at admin-add and
226
+ // silently grant pro-tier admin slots — a signing-side bug becoming a
227
+ // privilege grant. Strict allowlist closes the gap.
228
+ const tier = typeof payload.tier === "string" ? payload.tier : "";
229
+ if (!VALID_TIERS.has(tier)) {
230
+ return logResolved(anonymousFallback("tier-shape"), { reason: "tier-shape" });
231
+ }
232
+ const purchased = Array.isArray(payload.purchasedPlugins)
233
+ ? payload.purchasedPlugins.filter((s) => typeof s === "string")
234
+ : [];
235
+ // Step 6: expiry gate.
236
+ if (now <= expires) {
237
+ return logResolved({
238
+ tier,
239
+ purchasedPlugins: purchased,
240
+ source: "signed",
241
+ issued: issuedRaw,
242
+ expires: expiresRaw,
243
+ }, maybeTamperLine(account, tier));
244
+ }
245
+ if (now <= expires + GRACE_MS) {
246
+ return logResolved({
247
+ tier,
248
+ purchasedPlugins: purchased,
249
+ source: "signed-grace",
250
+ issued: issuedRaw,
251
+ expires: expiresRaw,
252
+ }, maybeTamperLine(account, tier));
253
+ }
254
+ return logResolved(anonymousFallback("expired"), { reason: "expired" });
255
+ }
256
+ function implicitTrust(account) {
257
+ const tier = typeof account.tier === "string" ? account.tier : "";
258
+ const purchased = Array.isArray(account.purchasedPlugins) ? account.purchasedPlugins : [];
259
+ return {
260
+ tier,
261
+ purchasedPlugins: purchased,
262
+ source: "implicit-trust",
263
+ issued: null,
264
+ expires: null,
265
+ };
266
+ }
267
+ function anonymousFallback(_reason) {
268
+ return {
269
+ tier: "solo",
270
+ purchasedPlugins: [],
271
+ source: "anonymous-fallback",
272
+ issued: null,
273
+ expires: null,
274
+ };
275
+ }
276
+ function maybeTamperLine(account, signedTier) {
277
+ if (typeof account.tier === "string" && account.tier !== signedTier) {
278
+ return { reason: "tampered", diskTier: account.tier, signedTier };
279
+ }
280
+ return null;
281
+ }
282
+ function logResolved(result, detail) {
283
+ console.error(`[entitlement] resolved: tier=${result.tier} plugins=${result.purchasedPlugins.length} source=${result.source} issued=${result.issued ?? "-"} expires=${result.expires ?? "-"}`);
284
+ if (detail && "diskTier" in detail) {
285
+ console.error(`[entitlement] tampered: tier-on-disk=${detail.diskTier} signed=${detail.signedTier} action=using-signed`);
286
+ }
287
+ else if (detail && result.source === "anonymous-fallback") {
288
+ const action = detail.reason === "expired" || detail.reason === "missing" ? "lock" : "degrade";
289
+ console.error(`[entitlement] verify-failed: reason=${detail.reason} action=${action}`);
290
+ }
291
+ return result;
292
+ }
293
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ -----BEGIN PUBLIC KEY-----
2
+ MCowBQYDK2VwAyEAJ3AEVtAbYcVOpFcyKUan4I7JURaztHwwX4dx52ZE414=
3
+ -----END PUBLIC KEY-----
@@ -6,8 +6,8 @@
6
6
  "plugins/*/mcp"
7
7
  ],
8
8
  "scripts": {
9
- "build": "tsc -p lib/models/tsconfig.json && tsc -p lib/anthropic-key/tsconfig.json && tsc -p lib/oauth-llm/tsconfig.json && tsc -p lib/mcp-stderr-tee/tsconfig.json && tsc -p lib/mcp-spawn-tee/tsconfig.json && tsc -p lib/graph-write/tsconfig.json && tsc -p lib/graph-mcp/tsconfig.json && tsc -p lib/graph-trash/tsconfig.json && tsc -p lib/graph-search/tsconfig.json && tsc -p lib/screening-patterns/tsconfig.json && tsc -p lib/device-url/tsconfig.json && tsc -p lib/brand-templating/tsconfig.json && tsc -p plugins/whatsapp-import/lib/tsconfig.json && NODE_OPTIONS='--max-old-space-size=8192' tsc -b plugins/*/mcp/tsconfig.json",
10
- "build:lib": "tsc -p lib/models/tsconfig.json && tsc -p lib/anthropic-key/tsconfig.json && tsc -p lib/oauth-llm/tsconfig.json && tsc -p lib/mcp-stderr-tee/tsconfig.json && tsc -p lib/mcp-spawn-tee/tsconfig.json && tsc -p lib/graph-write/tsconfig.json && tsc -p lib/graph-mcp/tsconfig.json && tsc -p lib/graph-trash/tsconfig.json && tsc -p lib/graph-search/tsconfig.json && tsc -p lib/screening-patterns/tsconfig.json && tsc -p lib/device-url/tsconfig.json && tsc -p lib/brand-templating/tsconfig.json && tsc -p plugins/whatsapp-import/lib/tsconfig.json",
9
+ "build": "tsc -p lib/models/tsconfig.json && tsc -p lib/anthropic-key/tsconfig.json && tsc -p lib/oauth-llm/tsconfig.json && tsc -p lib/mcp-stderr-tee/tsconfig.json && tsc -p lib/mcp-spawn-tee/tsconfig.json && tsc -p lib/graph-write/tsconfig.json && tsc -p lib/graph-mcp/tsconfig.json && tsc -p lib/graph-trash/tsconfig.json && tsc -p lib/graph-search/tsconfig.json && tsc -p lib/screening-patterns/tsconfig.json && tsc -p lib/device-url/tsconfig.json && tsc -p lib/brand-templating/tsconfig.json && tsc -p lib/entitlement/tsconfig.json && tsc -p plugins/whatsapp-import/lib/tsconfig.json && NODE_OPTIONS='--max-old-space-size=8192' tsc -b plugins/*/mcp/tsconfig.json",
10
+ "build:lib": "tsc -p lib/models/tsconfig.json && tsc -p lib/anthropic-key/tsconfig.json && tsc -p lib/oauth-llm/tsconfig.json && tsc -p lib/mcp-stderr-tee/tsconfig.json && tsc -p lib/mcp-spawn-tee/tsconfig.json && tsc -p lib/graph-write/tsconfig.json && tsc -p lib/graph-mcp/tsconfig.json && tsc -p lib/graph-trash/tsconfig.json && tsc -p lib/graph-search/tsconfig.json && tsc -p lib/screening-patterns/tsconfig.json && tsc -p lib/device-url/tsconfig.json && tsc -p lib/brand-templating/tsconfig.json && tsc -p lib/entitlement/tsconfig.json && tsc -p plugins/whatsapp-import/lib/tsconfig.json",
11
11
  "build:memory": "tsc -p plugins/memory/mcp/tsconfig.json",
12
12
  "build:contacts": "tsc -p plugins/contacts/mcp/tsconfig.json",
13
13
  "build:telegram": "tsc -p plugins/telegram/mcp/tsconfig.json",
@@ -36,6 +36,26 @@ if [ "$AGENT_TYPE" = "admin" ]; then
36
36
  echo "Blocked: Admin agent cannot modify platform code at $FILE_PATH" >&2
37
37
  exit 2
38
38
  ;;
39
+ # Entitlement library (Task 831) — verifier source, compiled output, vendored
40
+ # pubkey, hash file, and any signed entitlement.json. Tampering here is the
41
+ # agent path to revenue bypass; the legitimate write path is the Rubytech
42
+ # issuance endpoint, never the agent's filesystem.
43
+ # Patterns intentionally cover both absolute (*/...) and relative
44
+ # (no leading slash) paths so an agent can't bypass via cwd-relative writes.
45
+ */platform/lib/entitlement/*|platform/lib/entitlement/*|*/entitlement.json|entitlement.json)
46
+ echo "Blocked: Admin agent cannot modify entitlement files at $FILE_PATH (Task 831). Effective tier and purchasedPlugins derive from a Rubytech-signed payload." >&2
47
+ echo "[entitlement] tool-deny: tool=${TOOL_NAME} path=${FILE_PATH} field=entitlement-file" >&2
48
+ exit 2
49
+ ;;
50
+ # account.json (Task 831) — agent must use the account-update MCP tool
51
+ # (or plugin-toggle-enabled for enabledPlugins changes), which whitelists
52
+ # editable fields server-side. Direct Edit/Write bypasses that whitelist;
53
+ # deny unconditionally including cwd-relative paths.
54
+ */data/accounts/*/account.json|*/config/accounts/*/account.json|data/accounts/*/account.json|config/accounts/*/account.json|account.json)
55
+ echo "Blocked: Admin agent cannot edit account.json directly. Use the account-update or plugin-toggle-enabled MCP tools — they whitelist editable fields server-side and exclude tier and purchasedPlugins by design." >&2
56
+ echo "[entitlement] tool-deny: tool=${TOOL_NAME} path=${FILE_PATH} field=account-json" >&2
57
+ exit 2
58
+ ;;
39
59
  # Pending action queue — only the hook and MCP tools may write here
40
60
  */pending-actions/*)
41
61
  echo "Blocked: Admin agent cannot modify pending action files directly" >&2
@@ -50,6 +70,18 @@ if [ "$AGENT_TYPE" = "admin" ]; then
50
70
  echo "Blocked: Admin agent cannot run shell commands against code directories" >&2
51
71
  exit 2
52
72
  ;;
73
+ # Entitlement files via shell (Task 831) — same surface, blocked symmetrically
74
+ *"platform/lib/entitlement/"*|*"entitlement.json"*)
75
+ echo "Blocked: Admin agent cannot reference entitlement files via shell (Task 831)." >&2
76
+ echo "[entitlement] tool-deny: tool=Bash path=entitlement-file field=entitlement-file" >&2
77
+ exit 2
78
+ ;;
79
+ # account.json via shell (Task 831) — same rationale as Edit/Write block
80
+ *"data/accounts/"*"account.json"*|*"config/accounts/"*"account.json"*)
81
+ echo "Blocked: Admin agent cannot edit account.json via shell. Use the account-update MCP tool." >&2
82
+ echo "[entitlement] tool-deny: tool=Bash path=account-json field=account-json" >&2
83
+ exit 2
84
+ ;;
53
85
  *"pending-actions/"*)
54
86
  echo "Blocked: Admin agent cannot modify pending action files via shell" >&2
55
87
  exit 2