@pyric/cli 0.1.0-alpha.13 → 0.1.0-alpha.15

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 (614) hide show
  1. package/dist/assurance/.generated/conformance-verdicts.d.ts +120 -75
  2. package/dist/assurance/.generated/conformance-verdicts.d.ts.map +1 -1
  3. package/dist/assurance/.generated/conformance-verdicts.js +120 -75
  4. package/dist/assurance/.generated/conformance-verdicts.js.map +1 -1
  5. package/dist/cli/serve.d.ts +1 -1
  6. package/dist/cli/serve.d.ts.map +1 -1
  7. package/dist/cli/serve.js +208 -285
  8. package/dist/cli/serve.js.map +1 -1
  9. package/dist/cli/service-command-records/database-rules-generate.d.ts +4 -0
  10. package/dist/cli/service-command-records/database-rules-generate.d.ts.map +1 -0
  11. package/dist/cli/service-command-records/database-rules-generate.js +3 -0
  12. package/dist/cli/service-command-records/database-rules-generate.js.map +1 -0
  13. package/dist/cli/service-command-records/database-rules-lint.d.ts +4 -0
  14. package/dist/cli/service-command-records/database-rules-lint.d.ts.map +1 -0
  15. package/dist/cli/service-command-records/database-rules-lint.js +3 -0
  16. package/dist/cli/service-command-records/database-rules-lint.js.map +1 -0
  17. package/dist/cli/service-command-records/database-rules-simulate.d.ts +4 -0
  18. package/dist/cli/service-command-records/database-rules-simulate.d.ts.map +1 -0
  19. package/dist/cli/service-command-records/database-rules-simulate.js +3 -0
  20. package/dist/cli/service-command-records/database-rules-simulate.js.map +1 -0
  21. package/dist/cli/service-command-records/database-rules-validate.d.ts +4 -0
  22. package/dist/cli/service-command-records/database-rules-validate.d.ts.map +1 -0
  23. package/dist/cli/service-command-records/database-rules-validate.js +3 -0
  24. package/dist/cli/service-command-records/database-rules-validate.js.map +1 -0
  25. package/dist/cli/service-command-records/firestore-indexes-generate.d.ts +4 -0
  26. package/dist/cli/service-command-records/firestore-indexes-generate.d.ts.map +1 -0
  27. package/dist/cli/service-command-records/firestore-indexes-generate.js +3 -0
  28. package/dist/cli/service-command-records/firestore-indexes-generate.js.map +1 -0
  29. package/dist/cli/service-command-records/firestore-rules-lint.d.ts +4 -0
  30. package/dist/cli/service-command-records/firestore-rules-lint.d.ts.map +1 -0
  31. package/dist/cli/service-command-records/firestore-rules-lint.js +3 -0
  32. package/dist/cli/service-command-records/firestore-rules-lint.js.map +1 -0
  33. package/dist/cli/service-command-records/firestore-rules-resolve.d.ts +4 -0
  34. package/dist/cli/service-command-records/firestore-rules-resolve.d.ts.map +1 -0
  35. package/dist/cli/service-command-records/firestore-rules-resolve.js +3 -0
  36. package/dist/cli/service-command-records/firestore-rules-resolve.js.map +1 -0
  37. package/dist/cli/service-command-records/firestore-rules-simulate.d.ts +4 -0
  38. package/dist/cli/service-command-records/firestore-rules-simulate.d.ts.map +1 -0
  39. package/dist/cli/service-command-records/firestore-rules-simulate.js +3 -0
  40. package/dist/cli/service-command-records/firestore-rules-simulate.js.map +1 -0
  41. package/dist/cli/service-command-records/firestore-rules-validate.d.ts +4 -0
  42. package/dist/cli/service-command-records/firestore-rules-validate.d.ts.map +1 -0
  43. package/dist/cli/service-command-records/firestore-rules-validate.js +3 -0
  44. package/dist/cli/service-command-records/firestore-rules-validate.js.map +1 -0
  45. package/dist/cli/service-command-records/storage-rules-lint.d.ts +4 -0
  46. package/dist/cli/service-command-records/storage-rules-lint.d.ts.map +1 -0
  47. package/dist/cli/service-command-records/storage-rules-lint.js +3 -0
  48. package/dist/cli/service-command-records/storage-rules-lint.js.map +1 -0
  49. package/dist/cli/service-command-records/storage-rules-simulate.d.ts +4 -0
  50. package/dist/cli/service-command-records/storage-rules-simulate.d.ts.map +1 -0
  51. package/dist/cli/service-command-records/storage-rules-simulate.js +3 -0
  52. package/dist/cli/service-command-records/storage-rules-simulate.js.map +1 -0
  53. package/dist/cli/service-commands.d.ts +7 -0
  54. package/dist/cli/service-commands.d.ts.map +1 -1
  55. package/dist/cli/service-commands.generated.d.ts +35 -0
  56. package/dist/cli/service-commands.generated.d.ts.map +1 -0
  57. package/dist/cli/service-commands.generated.js +25 -0
  58. package/dist/cli/service-commands.generated.js.map +1 -0
  59. package/dist/cli/service-commands.js +23 -40
  60. package/dist/cli/service-commands.js.map +1 -1
  61. package/dist/conformance/.generated/can-i-use-browser.d.ts.map +1 -1
  62. package/dist/conformance/.generated/can-i-use-browser.js +1 -1
  63. package/dist/conformance/.generated/can-i-use-browser.js.map +1 -1
  64. package/dist/conformance/.generated/can-i-use.d.ts.map +1 -1
  65. package/dist/conformance/.generated/can-i-use.js +1 -1
  66. package/dist/conformance/.generated/can-i-use.js.map +1 -1
  67. package/dist/conformance/.generated/conformance-docs.d.ts.map +1 -1
  68. package/dist/conformance/.generated/conformance-docs.js +1 -1
  69. package/dist/conformance/.generated/conformance-docs.js.map +1 -1
  70. package/dist/functions-rtdb/development-runtime.d.ts +63 -0
  71. package/dist/functions-rtdb/development-runtime.d.ts.map +1 -0
  72. package/dist/functions-rtdb/development-runtime.js +244 -0
  73. package/dist/functions-rtdb/development-runtime.js.map +1 -0
  74. package/dist/serve/bridge-mount.d.ts +32 -2
  75. package/dist/serve/bridge-mount.d.ts.map +1 -1
  76. package/dist/serve/bridge-mount.js +232 -18
  77. package/dist/serve/bridge-mount.js.map +1 -1
  78. package/dist/serve/bundler.d.ts +4 -18
  79. package/dist/serve/bundler.d.ts.map +1 -1
  80. package/dist/serve/bundler.js +15 -37
  81. package/dist/serve/bundler.js.map +1 -1
  82. package/dist/serve/entries/app-client.d.ts.map +1 -1
  83. package/dist/serve/entries/app-client.js +5 -5
  84. package/dist/serve/entries/app-client.js.map +1 -1
  85. package/dist/serve/entries/auth-helper-core.d.ts +23 -6
  86. package/dist/serve/entries/auth-helper-core.d.ts.map +1 -1
  87. package/dist/serve/entries/auth-helper-core.js +55 -24
  88. package/dist/serve/entries/auth-helper-core.js.map +1 -1
  89. package/dist/serve/entries/database.d.ts +28 -0
  90. package/dist/serve/entries/database.d.ts.map +1 -1
  91. package/dist/serve/entries/database.js +95 -26
  92. package/dist/serve/entries/database.js.map +1 -1
  93. package/dist/serve/entries/init.d.ts.map +1 -1
  94. package/dist/serve/entries/init.js +21 -12
  95. package/dist/serve/entries/init.js.map +1 -1
  96. package/dist/serve/html-injection.d.ts +5 -0
  97. package/dist/serve/html-injection.d.ts.map +1 -0
  98. package/dist/serve/html-injection.js +59 -0
  99. package/dist/serve/html-injection.js.map +1 -0
  100. package/dist/serve/namespace.d.ts +6 -22
  101. package/dist/serve/namespace.d.ts.map +1 -1
  102. package/dist/serve/namespace.js +23 -145
  103. package/dist/serve/namespace.js.map +1 -1
  104. package/dist/serve/runtime/worker-generation.d.ts +10 -2
  105. package/dist/serve/runtime/worker-generation.d.ts.map +1 -1
  106. package/dist/serve/runtime/worker-generation.js +29 -8
  107. package/dist/serve/runtime/worker-generation.js.map +1 -1
  108. package/dist/serve/runtime/worker-replacement.d.ts +1 -2
  109. package/dist/serve/runtime/worker-replacement.d.ts.map +1 -1
  110. package/dist/serve/sandbox-session.d.ts +78 -0
  111. package/dist/serve/sandbox-session.d.ts.map +1 -0
  112. package/dist/serve/sandbox-session.js +171 -0
  113. package/dist/serve/sandbox-session.js.map +1 -0
  114. package/dist/serve/server.d.ts +5 -2
  115. package/dist/serve/server.d.ts.map +1 -1
  116. package/dist/serve/server.js +21 -5
  117. package/dist/serve/server.js.map +1 -1
  118. package/dist/serve/site-tree.d.ts +8 -0
  119. package/dist/serve/site-tree.d.ts.map +1 -0
  120. package/dist/serve/site-tree.js +113 -0
  121. package/dist/serve/site-tree.js.map +1 -0
  122. package/dist/serve/site-ui/_astro/RulesCodeEditor.CzwHdCi9.js +23 -0
  123. package/dist/serve/site-ui/_astro/_example_.jevZ7OdV.css +1 -0
  124. package/dist/serve/site-ui/_astro/_slug_.BoKXYrnu.css +1 -0
  125. package/dist/serve/site-ui/_astro/_studio_.BtYpqe1A.css +1 -0
  126. package/dist/serve/site-ui/_astro/app.BnMC0ywl.js +109 -0
  127. package/dist/serve/site-ui/_astro/app.BsFsMjn0.css +1 -0
  128. package/dist/serve/site-ui/_astro/app.DVXXR-WI.js +1 -0
  129. package/dist/serve/site-ui/_astro/chess-showcase.DzPO6kz0.js +1 -0
  130. package/dist/serve/site-ui/_astro/chess-source-explorer.C5k9c5yK.js +1 -0
  131. package/dist/serve/site-ui/_astro/chess-v2.CFHmd3UL.js +354 -0
  132. package/dist/serve/site-ui/_astro/client.D2ORs4B-.js +25 -0
  133. package/dist/serve/site-ui/_astro/example-runtime.CM0H02rx.js +291 -0
  134. package/dist/serve/site-ui/_astro/index.B4Kh80he.js +1 -0
  135. package/dist/serve/site-ui/_astro/index.DBy5LfQW.js +9 -0
  136. package/dist/serve/site-ui/_astro/index.DNyk7q8W.js +9 -0
  137. package/dist/serve/site-ui/_astro/jsx-runtime.D_zvdyIk.js +9 -0
  138. package/dist/serve/site-ui/_astro/reads.D1exkX1-.js +1 -0
  139. package/dist/serve/site-ui/_astro/sandbox-controls.BqMePr5V.js +1153 -0
  140. package/dist/serve/site-ui/_astro/seed.BCn5DhHS.js +20 -0
  141. package/dist/serve/site-ui/auth/index.html +11 -0
  142. package/dist/serve/site-ui/docs/_rhythm/index.html +100 -0
  143. package/dist/serve/site-ui/docs/agent/set-up-your-agent/index.html +43 -0
  144. package/dist/serve/site-ui/docs/agent/watch-and-review/index.html +26 -0
  145. package/dist/serve/site-ui/docs/agent/work-with-an-agent/index.html +70 -0
  146. package/dist/serve/{docs-ui → site-ui}/docs/ai-compat/index.html +3 -3
  147. package/dist/serve/site-ui/docs/api-reference/index.html +68 -0
  148. package/dist/serve/{docs-ui → site-ui}/docs/app-compat/index.html +3 -3
  149. package/dist/serve/{docs-ui → site-ui}/docs/auth-compat/index.html +3 -3
  150. package/dist/serve/site-ui/docs/build/ai-logic/index.html +64 -0
  151. package/dist/serve/site-ui/docs/build/authentication/index.html +66 -0
  152. package/dist/serve/site-ui/docs/build/cloud-firestore/index.html +84 -0
  153. package/dist/serve/site-ui/docs/build/cloud-messaging/index.html +71 -0
  154. package/dist/serve/site-ui/docs/build/cloud-storage/index.html +66 -0
  155. package/dist/serve/{docs-ui → site-ui}/docs/build/cloud-storage.md +2 -2
  156. package/dist/serve/site-ui/docs/build/realtime-database/index.html +67 -0
  157. package/dist/serve/site-ui/docs/conformance-scores/index.html +50 -0
  158. package/dist/serve/{docs-ui → site-ui}/docs/conformance-scores.md +3 -3
  159. package/dist/serve/site-ui/docs/create-pyric-reference-api/index.html +531 -0
  160. package/dist/serve/{docs-ui → site-ui}/docs/database-compat/index.html +211 -168
  161. package/dist/serve/{docs-ui → site-ui}/docs/database-compat.md +208 -170
  162. package/dist/serve/site-ui/docs/examples/chess/index.html +384 -0
  163. package/dist/serve/site-ui/docs/examples/chess.md +57 -0
  164. package/dist/serve/site-ui/docs/examples/index.html +3 -0
  165. package/dist/serve/site-ui/docs/examples.md +4 -0
  166. package/dist/serve/{docs-ui → site-ui}/docs/firestore-compat/index.html +55 -91
  167. package/dist/serve/{docs-ui → site-ui}/docs/firestore-compat.md +52 -88
  168. package/dist/serve/site-ui/docs/functions-rtdb-compat/index.html +73 -0
  169. package/dist/serve/site-ui/docs/get-started/how-the-swap-works/index.html +29 -0
  170. package/dist/serve/site-ui/docs/get-started/start-building/index.html +33 -0
  171. package/dist/serve/{docs-ui → site-ui}/docs/index.json +595 -26
  172. package/dist/serve/site-ui/docs/messaging-compat/index.html +324 -0
  173. package/dist/serve/{docs-ui → site-ui}/docs/messaging-compat.md +71 -1
  174. package/dist/serve/site-ui/docs/observe/resolve-runtime-status/index.html +28 -0
  175. package/dist/serve/site-ui/docs/observe/see-whats-happening/index.html +74 -0
  176. package/dist/serve/site-ui/docs/observe/shape-your-data/index.html +45 -0
  177. package/dist/serve/site-ui/docs/overview/index.html +17 -0
  178. package/dist/serve/site-ui/docs/pyric-admin-app-reference-api/index.html +186 -0
  179. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-auth-reference-api/index.html +4 -4
  180. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-database-reference-api/index.html +4 -4
  181. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-firestore-reference-api/index.html +318 -202
  182. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-firestore-reference-api.md +154 -27
  183. package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-messaging-reference-api/index.html +5 -5
  184. package/dist/serve/site-ui/docs/pyric-admin-storage-reference-api/index.html +318 -0
  185. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ai-reference-api/index.html +5 -5
  186. package/dist/serve/site-ui/docs/pyric-ai-scripting-reference-api/index.html +160 -0
  187. package/dist/serve/site-ui/docs/pyric-app-reference-api/index.html +425 -0
  188. package/dist/serve/{docs-ui → site-ui}/docs/pyric-auth-reference-api/index.html +5 -5
  189. package/dist/serve/site-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +60 -0
  190. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-assurance-reference-api/index.html +4 -4
  191. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-bridge-client-reference-api/index.html +4 -4
  192. package/dist/serve/site-ui/docs/pyric-cli-bridge-reference-api/index.html +507 -0
  193. package/dist/serve/site-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +258 -0
  194. package/dist/serve/site-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +51 -0
  195. package/dist/serve/site-ui/docs/pyric-cli-conformance-reference-api/index.html +308 -0
  196. package/dist/serve/site-ui/docs/pyric-cli-credentials-node-reference-api/index.html +68 -0
  197. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-discover-reference-api/index.html +4 -4
  198. package/dist/serve/site-ui/docs/pyric-cli-register-reference-api/index.html +11 -0
  199. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-remote-reference-api/index.html +4 -4
  200. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-serve-worker-reference-api/index.html +1186 -1384
  201. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-serve-worker-reference-api.md +817 -1291
  202. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-verify-reference-api/index.html +4 -4
  203. package/dist/serve/site-ui/docs/pyric-cli-vite-reference-api/index.html +126 -0
  204. package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-vite-reference-api.md +1 -1
  205. package/dist/serve/site-ui/docs/pyric-database-reference-api/index.html +2641 -0
  206. package/dist/serve/{docs-ui → site-ui}/docs/pyric-database-reference-api.md +1055 -158
  207. package/dist/serve/{docs-ui → site-ui}/docs/pyric-firestore-reference-api/index.html +311 -249
  208. package/dist/serve/{docs-ui → site-ui}/docs/pyric-firestore-reference-api.md +72 -54
  209. package/dist/serve/site-ui/docs/pyric-messaging-reference-api/index.html +509 -0
  210. package/dist/serve/site-ui/docs/pyric-messaging-sw-reference-api/index.html +182 -0
  211. package/dist/serve/{docs-ui → site-ui}/docs/pyric-rules-reference-api/index.html +7 -26
  212. package/dist/serve/{docs-ui → site-ui}/docs/pyric-rules-reference-api.md +13 -23
  213. package/dist/serve/site-ui/docs/pyric-sandbox-database-reference-api/index.html +121 -0
  214. package/dist/serve/site-ui/docs/pyric-sandbox-firestore-reference-api/index.html +203 -0
  215. package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-reference-api/index.html +26 -5
  216. package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-reference-api.md +22 -22
  217. package/dist/serve/{docs-ui → site-ui}/docs/pyric-storage-reference-api/index.html +5 -15
  218. package/dist/serve/{docs-ui → site-ui}/docs/pyric-storage-reference-api.md +0 -13
  219. package/dist/serve/site-ui/docs/pyric-ui-agents-reference-api/index.html +639 -0
  220. package/dist/serve/site-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +100 -0
  221. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-auth-reference-api/index.html +4 -4
  222. package/dist/serve/site-ui/docs/pyric-ui-events-hooks-reference-api/index.html +24 -0
  223. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-events-reference-api/index.html +4 -4
  224. package/dist/serve/site-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +136 -0
  225. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-firestore-reference-api/index.html +7 -7
  226. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-firestore-reference-api.md +4 -4
  227. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-primitives-reference-api/index.html +4 -4
  228. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rtdb-reference-api/index.html +4 -4
  229. package/dist/serve/site-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +16 -0
  230. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rules-reference-api/index.html +4 -4
  231. package/dist/serve/site-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +176 -0
  232. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-storage-reference-api/index.html +10 -11
  233. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-storage-reference-api.md +7 -8
  234. package/dist/serve/site-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +188 -0
  235. package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-traffic-reference-api/index.html +4 -4
  236. package/dist/serve/{docs-ui → site-ui}/docs/rules-compat/index.html +87 -57
  237. package/dist/serve/{docs-ui → site-ui}/docs/rules-compat.md +84 -54
  238. package/dist/serve/site-ui/docs/secure/audit-your-rules/index.html +51 -0
  239. package/dist/serve/site-ui/docs/secure/firestore-rules-limits/index.html +106 -0
  240. package/dist/serve/site-ui/docs/secure/read-a-denial/index.html +41 -0
  241. package/dist/serve/site-ui/docs/secure/rtdb-rules-in-typescript/index.html +67 -0
  242. package/dist/serve/site-ui/docs/secure/rules-standard-library/index.html +159 -0
  243. package/dist/serve/{docs-ui → site-ui}/docs/secure/rules-standard-library.md +2 -2
  244. package/dist/serve/site-ui/docs/secure/secure-it-with-rules/index.html +47 -0
  245. package/dist/serve/site-ui/docs/secure/simulate-and-lint/index.html +95 -0
  246. package/dist/serve/site-ui/docs/secure/write-a-rules-test-suite/index.html +82 -0
  247. package/dist/serve/site-ui/docs/ship/ship-to-production/index.html +37 -0
  248. package/dist/serve/site-ui/docs/ship/test-in-node/index.html +75 -0
  249. package/dist/serve/{docs-ui → site-ui}/docs/storage-compat/index.html +8 -8
  250. package/dist/serve/{docs-ui → site-ui}/docs/storage-compat.md +5 -5
  251. package/dist/serve/site-ui/docs/trust/how-we-know-it-matches-firebase/index.html +132 -0
  252. package/dist/serve/site-ui/docs/trust/rules-standard-library/index.html +861 -0
  253. package/dist/serve/site-ui/docs/trust/rules-standard-library.md +344 -0
  254. package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research/index.html +582 -0
  255. package/dist/serve/site-ui/docs/trust/storage-rules-stdlib-research.md +448 -0
  256. package/dist/serve/site-ui/docs/trust/versioning-and-compatibility/index.html +14 -0
  257. package/dist/serve/{docs-ui → site-ui}/docs/tutorial/index.html +4 -4
  258. package/dist/serve/{docs-ui → site-ui}/docs/tutorial.md +1 -1
  259. package/dist/serve/site-ui/examples/chess/index.html +2 -0
  260. package/dist/serve/site-ui/examples/firestore-first-write/index.html +2 -0
  261. package/dist/serve/site-ui/firestore/index.html +11 -0
  262. package/dist/serve/site-ui/index.html +11 -0
  263. package/dist/serve/{docs-ui → site-ui}/llms.txt +6 -2
  264. package/dist/serve/site-ui/rtdb/index.html +11 -0
  265. package/dist/serve/site-ui/settings/index.html +11 -0
  266. package/dist/serve/site-ui/storage/index.html +11 -0
  267. package/dist/serve/site-ui/studio-routes.json +1 -0
  268. package/dist/serve/site-ui/traffic/index.html +11 -0
  269. package/dist/serve/standalone-assets.d.ts +4 -10
  270. package/dist/serve/standalone-assets.d.ts.map +1 -1
  271. package/dist/serve/standalone-assets.js +8 -21
  272. package/dist/serve/standalone-assets.js.map +1 -1
  273. package/dist/serve/vite-ai-config.d.ts +2 -0
  274. package/dist/serve/vite-ai-config.d.ts.map +1 -1
  275. package/dist/serve/vite-ai-config.js +4 -0
  276. package/dist/serve/vite-ai-config.js.map +1 -1
  277. package/dist/serve/vite-functions-development.d.ts +29 -0
  278. package/dist/serve/vite-functions-development.d.ts.map +1 -0
  279. package/dist/serve/vite-functions-development.js +150 -0
  280. package/dist/serve/vite-functions-development.js.map +1 -0
  281. package/dist/serve/vite-generation-bridge.d.ts +17 -0
  282. package/dist/serve/vite-generation-bridge.d.ts.map +1 -0
  283. package/dist/serve/vite-generation-bridge.js +47 -0
  284. package/dist/serve/vite-generation-bridge.js.map +1 -0
  285. package/dist/serve/vite-generation-functions.d.ts +35 -0
  286. package/dist/serve/vite-generation-functions.d.ts.map +1 -0
  287. package/dist/serve/vite-generation-functions.js +46 -0
  288. package/dist/serve/vite-generation-functions.js.map +1 -0
  289. package/dist/serve/vite-generation-middleware.d.ts +10 -0
  290. package/dist/serve/vite-generation-middleware.d.ts.map +1 -0
  291. package/dist/serve/vite-generation-middleware.js +40 -0
  292. package/dist/serve/vite-generation-middleware.js.map +1 -0
  293. package/dist/serve/vite-generation-rules-watch.d.ts +8 -0
  294. package/dist/serve/vite-generation-rules-watch.d.ts.map +1 -0
  295. package/dist/serve/vite-generation-rules-watch.js +33 -0
  296. package/dist/serve/vite-generation-rules-watch.js.map +1 -0
  297. package/dist/serve/vite-module-swap.d.ts +16 -0
  298. package/dist/serve/vite-module-swap.d.ts.map +1 -0
  299. package/dist/serve/vite-module-swap.js +96 -0
  300. package/dist/serve/vite-module-swap.js.map +1 -0
  301. package/dist/serve/vite-page-runtime.d.ts +29 -0
  302. package/dist/serve/vite-page-runtime.d.ts.map +1 -0
  303. package/dist/serve/vite-page-runtime.js +71 -0
  304. package/dist/serve/vite-page-runtime.js.map +1 -0
  305. package/dist/serve/vite-plugin.d.ts +44 -4
  306. package/dist/serve/vite-plugin.d.ts.map +1 -1
  307. package/dist/serve/vite-plugin.js +62 -864
  308. package/dist/serve/vite-plugin.js.map +1 -1
  309. package/dist/serve/vite-sandbox-generation.d.ts +57 -0
  310. package/dist/serve/vite-sandbox-generation.d.ts.map +1 -0
  311. package/dist/serve/vite-sandbox-generation.js +178 -0
  312. package/dist/serve/vite-sandbox-generation.js.map +1 -0
  313. package/dist/serve/vite-worker-runtime.d.ts +1 -1
  314. package/dist/serve/vite-worker-runtime.d.ts.map +1 -1
  315. package/dist/serve/vite-worker-runtime.js +8 -4
  316. package/dist/serve/vite-worker-runtime.js.map +1 -1
  317. package/dist/serve/worker/client/disconnect.d.ts.map +1 -1
  318. package/dist/serve/worker/client/disconnect.js +2 -0
  319. package/dist/serve/worker/client/disconnect.js.map +1 -1
  320. package/dist/serve/worker/client/handles.d.ts +5 -0
  321. package/dist/serve/worker/client/handles.d.ts.map +1 -1
  322. package/dist/serve/worker/client/handles.js.map +1 -1
  323. package/dist/serve/worker/client/pagehide.d.ts +13 -0
  324. package/dist/serve/worker/client/pagehide.d.ts.map +1 -0
  325. package/dist/serve/worker/client/pagehide.js +19 -0
  326. package/dist/serve/worker/client/pagehide.js.map +1 -0
  327. package/dist/serve/worker/client/rtdb-admin.d.ts +8 -0
  328. package/dist/serve/worker/client/rtdb-admin.d.ts.map +1 -0
  329. package/dist/serve/worker/client/rtdb-admin.js +39 -0
  330. package/dist/serve/worker/client/rtdb-admin.js.map +1 -0
  331. package/dist/serve/worker/client/rtdb-connection-lifecycle.d.ts +15 -0
  332. package/dist/serve/worker/client/rtdb-connection-lifecycle.d.ts.map +1 -0
  333. package/dist/serve/worker/client/rtdb-connection-lifecycle.js +45 -0
  334. package/dist/serve/worker/client/rtdb-connection-lifecycle.js.map +1 -0
  335. package/dist/serve/worker/client/rtdb-controls.d.ts +6 -0
  336. package/dist/serve/worker/client/rtdb-controls.d.ts.map +1 -0
  337. package/dist/serve/worker/client/rtdb-controls.js +8 -0
  338. package/dist/serve/worker/client/rtdb-controls.js.map +1 -0
  339. package/dist/serve/worker/client/rtdb-listeners.d.ts +24 -0
  340. package/dist/serve/worker/client/rtdb-listeners.d.ts.map +1 -0
  341. package/dist/serve/worker/client/rtdb-listeners.js +262 -0
  342. package/dist/serve/worker/client/rtdb-listeners.js.map +1 -0
  343. package/dist/serve/worker/client/rtdb-reads.d.ts +4 -0
  344. package/dist/serve/worker/client/rtdb-reads.d.ts.map +1 -0
  345. package/dist/serve/worker/client/rtdb-reads.js +11 -0
  346. package/dist/serve/worker/client/rtdb-reads.js.map +1 -0
  347. package/dist/serve/worker/client/rtdb-references.d.ts +19 -0
  348. package/dist/serve/worker/client/rtdb-references.d.ts.map +1 -0
  349. package/dist/serve/worker/client/rtdb-references.js +63 -0
  350. package/dist/serve/worker/client/rtdb-references.js.map +1 -0
  351. package/dist/serve/worker/client/rtdb-snapshots.d.ts +20 -0
  352. package/dist/serve/worker/client/rtdb-snapshots.d.ts.map +1 -0
  353. package/dist/serve/worker/client/rtdb-snapshots.js +64 -0
  354. package/dist/serve/worker/client/rtdb-snapshots.js.map +1 -0
  355. package/dist/serve/worker/client/rtdb-transactions.d.ts +14 -0
  356. package/dist/serve/worker/client/rtdb-transactions.d.ts.map +1 -0
  357. package/dist/serve/worker/client/rtdb-transactions.js +34 -0
  358. package/dist/serve/worker/client/rtdb-transactions.js.map +1 -0
  359. package/dist/serve/worker/client/rtdb-writes.d.ts +8 -0
  360. package/dist/serve/worker/client/rtdb-writes.d.ts.map +1 -0
  361. package/dist/serve/worker/client/rtdb-writes.js +65 -0
  362. package/dist/serve/worker/client/rtdb-writes.js.map +1 -0
  363. package/dist/serve/worker/client.d.ts +0 -2
  364. package/dist/serve/worker/client.d.ts.map +1 -1
  365. package/dist/serve/worker/client.js +0 -2
  366. package/dist/serve/worker/client.js.map +1 -1
  367. package/dist/serve/worker/entry.js +2 -2
  368. package/dist/serve/worker/entry.js.map +1 -1
  369. package/dist/serve/worker/host/dispatch.d.ts +2 -0
  370. package/dist/serve/worker/host/dispatch.d.ts.map +1 -1
  371. package/dist/serve/worker/host/dispatch.js +24 -2
  372. package/dist/serve/worker/host/dispatch.js.map +1 -1
  373. package/dist/serve/worker/host/rtdb.d.ts +6 -2
  374. package/dist/serve/worker/host/rtdb.d.ts.map +1 -1
  375. package/dist/serve/worker/host/rtdb.js +224 -2
  376. package/dist/serve/worker/host/rtdb.js.map +1 -1
  377. package/dist/serve/worker/host/studio.d.ts.map +1 -1
  378. package/dist/serve/worker/host/studio.js +2 -0
  379. package/dist/serve/worker/host/studio.js.map +1 -1
  380. package/dist/serve/worker/host/subscriptions.d.ts.map +1 -1
  381. package/dist/serve/worker/host/subscriptions.js +3 -3
  382. package/dist/serve/worker/host/subscriptions.js.map +1 -1
  383. package/dist/serve/worker/host.d.ts +1 -1
  384. package/dist/serve/worker/host.d.ts.map +1 -1
  385. package/dist/serve/worker/host.js +1 -1
  386. package/dist/serve/worker/host.js.map +1 -1
  387. package/dist/serve/worker/index.d.ts +16 -1
  388. package/dist/serve/worker/index.d.ts.map +1 -1
  389. package/dist/serve/worker/index.js +17 -4
  390. package/dist/serve/worker/index.js.map +1 -1
  391. package/dist/serve/worker/protocol.d.ts +57 -0
  392. package/dist/serve/worker/protocol.d.ts.map +1 -1
  393. package/dist/serve/worker/protocol.js.map +1 -1
  394. package/dist/serve/worker/rtdb-value-equality.d.ts +3 -0
  395. package/dist/serve/worker/rtdb-value-equality.d.ts.map +1 -0
  396. package/dist/serve/worker/rtdb-value-equality.js +18 -0
  397. package/dist/serve/worker/rtdb-value-equality.js.map +1 -0
  398. package/dist/serve/worker/serve-init.js +2 -2
  399. package/dist/serve/worker/serve-init.js.map +1 -1
  400. package/dist/serve/worker/service-worker-relay.js +2 -2
  401. package/dist/serve/worker/service-worker-relay.js.map +1 -1
  402. package/package.json +7 -5
  403. package/src/assurance/.generated/conformance-verdicts.ts +120 -75
  404. package/src/cli/serve.ts +216 -308
  405. package/src/cli/service-command-records/database-rules-generate.ts +3 -0
  406. package/src/cli/service-command-records/database-rules-lint.ts +3 -0
  407. package/src/cli/service-command-records/database-rules-simulate.ts +3 -0
  408. package/src/cli/service-command-records/database-rules-validate.ts +3 -0
  409. package/src/cli/service-command-records/firestore-indexes-generate.ts +3 -0
  410. package/src/cli/service-command-records/firestore-rules-lint.ts +3 -0
  411. package/src/cli/service-command-records/firestore-rules-resolve.ts +3 -0
  412. package/src/cli/service-command-records/firestore-rules-simulate.ts +3 -0
  413. package/src/cli/service-command-records/firestore-rules-validate.ts +3 -0
  414. package/src/cli/service-command-records/storage-rules-lint.ts +3 -0
  415. package/src/cli/service-command-records/storage-rules-simulate.ts +3 -0
  416. package/src/cli/service-commands.generated.ts +27 -0
  417. package/src/cli/service-commands.test.ts +43 -0
  418. package/src/cli/service-commands.ts +36 -51
  419. package/src/conformance/.generated/can-i-use-browser.ts +1 -1
  420. package/src/conformance/.generated/can-i-use.ts +1 -1
  421. package/src/conformance/.generated/conformance-docs.ts +1 -1
  422. package/src/functions-rtdb/development-runtime.ts +299 -0
  423. package/src/serve/bridge-mount.ts +253 -19
  424. package/src/serve/bundler.ts +17 -36
  425. package/src/serve/entries/app-client.ts +5 -4
  426. package/src/serve/entries/auth-helper-core.ts +83 -30
  427. package/src/serve/entries/database.ts +180 -57
  428. package/src/serve/entries/init.ts +30 -20
  429. package/src/serve/html-injection.ts +65 -0
  430. package/src/serve/namespace.ts +26 -169
  431. package/src/serve/runtime/worker-generation.ts +29 -7
  432. package/src/serve/runtime/worker-replacement.ts +1 -1
  433. package/src/serve/sandbox-session.ts +233 -0
  434. package/src/serve/server.ts +20 -5
  435. package/src/serve/site-tree.ts +146 -0
  436. package/src/serve/standalone-assets.ts +9 -26
  437. package/src/serve/vite-ai-config.ts +8 -0
  438. package/src/serve/vite-functions-development.ts +201 -0
  439. package/src/serve/vite-generation-bridge.ts +66 -0
  440. package/src/serve/vite-generation-functions.ts +78 -0
  441. package/src/serve/vite-generation-middleware.ts +56 -0
  442. package/src/serve/vite-generation-rules-watch.ts +37 -0
  443. package/src/serve/vite-module-swap.ts +119 -0
  444. package/src/serve/vite-page-runtime.ts +100 -0
  445. package/src/serve/vite-plugin.ts +78 -882
  446. package/src/serve/vite-sandbox-generation.ts +255 -0
  447. package/src/serve/vite-worker-runtime.ts +12 -5
  448. package/src/serve/worker/client/disconnect.ts +3 -1
  449. package/src/serve/worker/client/handles.ts +5 -0
  450. package/src/serve/worker/client/pagehide.ts +31 -0
  451. package/src/serve/worker/client/rtdb-admin.ts +74 -0
  452. package/src/serve/worker/client/rtdb-connection-lifecycle.ts +52 -0
  453. package/src/serve/worker/client/rtdb-controls.ts +8 -0
  454. package/src/serve/worker/client/rtdb-listeners.ts +337 -0
  455. package/src/serve/worker/client/rtdb-reads.ts +12 -0
  456. package/src/serve/worker/client/rtdb-references.ts +85 -0
  457. package/src/serve/worker/client/rtdb-snapshots.ts +118 -0
  458. package/src/serve/worker/client/rtdb-transactions.ts +51 -0
  459. package/src/serve/worker/client/rtdb-writes.ts +74 -0
  460. package/src/serve/worker/client.ts +0 -2
  461. package/src/serve/worker/entry.ts +2 -2
  462. package/src/serve/worker/host/dispatch.ts +22 -2
  463. package/src/serve/worker/host/rtdb.ts +243 -2
  464. package/src/serve/worker/host/studio.ts +2 -0
  465. package/src/serve/worker/host/subscriptions.ts +8 -4
  466. package/src/serve/worker/host.ts +1 -1
  467. package/src/serve/worker/index.ts +58 -10
  468. package/src/serve/worker/protocol.ts +23 -2
  469. package/src/serve/worker/rtdb-value-equality.ts +17 -0
  470. package/src/serve/worker/serve-init.ts +2 -2
  471. package/src/serve/worker/service-worker-relay.ts +2 -2
  472. package/dist/serve/docs-ui/_astro/_slug_.DUci-duz.css +0 -1
  473. package/dist/serve/docs-ui/docs/_rhythm/index.html +0 -100
  474. package/dist/serve/docs-ui/docs/agent/set-up-your-agent/index.html +0 -43
  475. package/dist/serve/docs-ui/docs/agent/watch-and-review/index.html +0 -26
  476. package/dist/serve/docs-ui/docs/agent/work-with-an-agent/index.html +0 -70
  477. package/dist/serve/docs-ui/docs/api-reference/index.html +0 -68
  478. package/dist/serve/docs-ui/docs/build/ai-logic/index.html +0 -64
  479. package/dist/serve/docs-ui/docs/build/authentication/index.html +0 -66
  480. package/dist/serve/docs-ui/docs/build/cloud-firestore/index.html +0 -70
  481. package/dist/serve/docs-ui/docs/build/cloud-messaging/index.html +0 -71
  482. package/dist/serve/docs-ui/docs/build/cloud-storage/index.html +0 -66
  483. package/dist/serve/docs-ui/docs/build/realtime-database/index.html +0 -67
  484. package/dist/serve/docs-ui/docs/conformance-scores/index.html +0 -50
  485. package/dist/serve/docs-ui/docs/create-pyric-reference-api/index.html +0 -531
  486. package/dist/serve/docs-ui/docs/functions-rtdb-compat/index.html +0 -73
  487. package/dist/serve/docs-ui/docs/get-started/how-the-swap-works/index.html +0 -29
  488. package/dist/serve/docs-ui/docs/get-started/start-building/index.html +0 -33
  489. package/dist/serve/docs-ui/docs/messaging-compat/index.html +0 -265
  490. package/dist/serve/docs-ui/docs/observe/resolve-runtime-status/index.html +0 -28
  491. package/dist/serve/docs-ui/docs/observe/see-whats-happening/index.html +0 -74
  492. package/dist/serve/docs-ui/docs/observe/shape-your-data/index.html +0 -45
  493. package/dist/serve/docs-ui/docs/overview/index.html +0 -17
  494. package/dist/serve/docs-ui/docs/pyric-admin-app-reference-api/index.html +0 -186
  495. package/dist/serve/docs-ui/docs/pyric-admin-storage-reference-api/index.html +0 -318
  496. package/dist/serve/docs-ui/docs/pyric-ai-scripting-reference-api/index.html +0 -160
  497. package/dist/serve/docs-ui/docs/pyric-app-reference-api/index.html +0 -425
  498. package/dist/serve/docs-ui/docs/pyric-cli-assurance-browser-reference-api/index.html +0 -60
  499. package/dist/serve/docs-ui/docs/pyric-cli-bridge-reference-api/index.html +0 -507
  500. package/dist/serve/docs-ui/docs/pyric-cli-conformance-browser-reference-api/index.html +0 -258
  501. package/dist/serve/docs-ui/docs/pyric-cli-conformance-docs-reference-api/index.html +0 -51
  502. package/dist/serve/docs-ui/docs/pyric-cli-conformance-reference-api/index.html +0 -308
  503. package/dist/serve/docs-ui/docs/pyric-cli-credentials-node-reference-api/index.html +0 -68
  504. package/dist/serve/docs-ui/docs/pyric-cli-register-reference-api/index.html +0 -11
  505. package/dist/serve/docs-ui/docs/pyric-cli-vite-reference-api/index.html +0 -126
  506. package/dist/serve/docs-ui/docs/pyric-database-reference-api/index.html +0 -1852
  507. package/dist/serve/docs-ui/docs/pyric-messaging-reference-api/index.html +0 -509
  508. package/dist/serve/docs-ui/docs/pyric-messaging-sw-reference-api/index.html +0 -182
  509. package/dist/serve/docs-ui/docs/pyric-sandbox-database-reference-api/index.html +0 -121
  510. package/dist/serve/docs-ui/docs/pyric-sandbox-firestore-reference-api/index.html +0 -203
  511. package/dist/serve/docs-ui/docs/pyric-ui-agents-reference-api/index.html +0 -639
  512. package/dist/serve/docs-ui/docs/pyric-ui-auth-hooks-reference-api/index.html +0 -100
  513. package/dist/serve/docs-ui/docs/pyric-ui-events-hooks-reference-api/index.html +0 -24
  514. package/dist/serve/docs-ui/docs/pyric-ui-firestore-hooks-reference-api/index.html +0 -136
  515. package/dist/serve/docs-ui/docs/pyric-ui-rules-hooks-reference-api/index.html +0 -16
  516. package/dist/serve/docs-ui/docs/pyric-ui-storage-hooks-reference-api/index.html +0 -176
  517. package/dist/serve/docs-ui/docs/pyric-ui-traffic-hooks-reference-api/index.html +0 -188
  518. package/dist/serve/docs-ui/docs/secure/audit-your-rules/index.html +0 -51
  519. package/dist/serve/docs-ui/docs/secure/firestore-rules-limits/index.html +0 -106
  520. package/dist/serve/docs-ui/docs/secure/read-a-denial/index.html +0 -41
  521. package/dist/serve/docs-ui/docs/secure/rtdb-rules-in-typescript/index.html +0 -67
  522. package/dist/serve/docs-ui/docs/secure/rules-standard-library/index.html +0 -159
  523. package/dist/serve/docs-ui/docs/secure/secure-it-with-rules/index.html +0 -47
  524. package/dist/serve/docs-ui/docs/secure/simulate-and-lint/index.html +0 -95
  525. package/dist/serve/docs-ui/docs/secure/write-a-rules-test-suite/index.html +0 -82
  526. package/dist/serve/docs-ui/docs/ship/ship-to-production/index.html +0 -37
  527. package/dist/serve/docs-ui/docs/ship/test-in-node/index.html +0 -75
  528. package/dist/serve/docs-ui/docs/trust/how-we-know-it-matches-firebase/index.html +0 -132
  529. package/dist/serve/docs-ui/docs/trust/versioning-and-compatibility/index.html +0 -14
  530. package/dist/serve/docs-ui/index.html +0 -1
  531. package/dist/serve/studio-ui/assets/RulesCodeEditor-BDlH-5lp.js +0 -23
  532. package/dist/serve/studio-ui/assets/index-Bf9SSE8L.js +0 -1218
  533. package/dist/serve/studio-ui/assets/index-BlSGru_r.css +0 -1
  534. package/dist/serve/studio-ui/assets/seed-D_UjxfOU.js +0 -20
  535. package/dist/serve/studio-ui/index.html +0 -32
  536. package/dist/serve/worker/client/rtdb.d.ts +0 -36
  537. package/dist/serve/worker/client/rtdb.d.ts.map +0 -1
  538. package/dist/serve/worker/client/rtdb.js +0 -241
  539. package/dist/serve/worker/client/rtdb.js.map +0 -1
  540. package/src/serve/worker/client/rtdb.ts +0 -311
  541. /package/dist/serve/{docs-ui → site-ui}/404.html +0 -0
  542. /package/dist/serve/{docs-ui → site-ui}/_astro/_slug_.CXh9yTP1.css +0 -0
  543. /package/dist/serve/{docs-ui → site-ui}/docs/_rhythm.md +0 -0
  544. /package/dist/serve/{docs-ui → site-ui}/docs/agent/set-up-your-agent.md +0 -0
  545. /package/dist/serve/{docs-ui → site-ui}/docs/agent/watch-and-review.md +0 -0
  546. /package/dist/serve/{docs-ui → site-ui}/docs/agent/work-with-an-agent.md +0 -0
  547. /package/dist/serve/{docs-ui → site-ui}/docs/ai-compat.md +0 -0
  548. /package/dist/serve/{docs-ui → site-ui}/docs/api-reference.md +0 -0
  549. /package/dist/serve/{docs-ui → site-ui}/docs/app-compat.md +0 -0
  550. /package/dist/serve/{docs-ui → site-ui}/docs/auth-compat.md +0 -0
  551. /package/dist/serve/{docs-ui → site-ui}/docs/build/ai-logic.md +0 -0
  552. /package/dist/serve/{docs-ui → site-ui}/docs/build/authentication.md +0 -0
  553. /package/dist/serve/{docs-ui → site-ui}/docs/build/cloud-firestore.md +0 -0
  554. /package/dist/serve/{docs-ui → site-ui}/docs/build/cloud-messaging.md +0 -0
  555. /package/dist/serve/{docs-ui → site-ui}/docs/build/realtime-database.md +0 -0
  556. /package/dist/serve/{docs-ui → site-ui}/docs/create-pyric-reference-api.md +0 -0
  557. /package/dist/serve/{docs-ui → site-ui}/docs/functions-rtdb-compat.md +0 -0
  558. /package/dist/serve/{docs-ui → site-ui}/docs/get-started/how-the-swap-works.md +0 -0
  559. /package/dist/serve/{docs-ui → site-ui}/docs/get-started/start-building.md +0 -0
  560. /package/dist/serve/{docs-ui → site-ui}/docs/index.html +0 -0
  561. /package/dist/serve/{docs-ui → site-ui}/docs/observe/resolve-runtime-status.md +0 -0
  562. /package/dist/serve/{docs-ui → site-ui}/docs/observe/see-whats-happening.md +0 -0
  563. /package/dist/serve/{docs-ui → site-ui}/docs/observe/shape-your-data.md +0 -0
  564. /package/dist/serve/{docs-ui → site-ui}/docs/overview.md +0 -0
  565. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-app-reference-api.md +0 -0
  566. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-auth-reference-api.md +0 -0
  567. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-database-reference-api.md +0 -0
  568. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-messaging-reference-api.md +0 -0
  569. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-admin-storage-reference-api.md +0 -0
  570. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ai-reference-api.md +0 -0
  571. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ai-scripting-reference-api.md +0 -0
  572. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-app-reference-api.md +0 -0
  573. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-auth-reference-api.md +0 -0
  574. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-assurance-browser-reference-api.md +0 -0
  575. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-assurance-reference-api.md +0 -0
  576. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-bridge-client-reference-api.md +0 -0
  577. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-bridge-reference-api.md +0 -0
  578. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-conformance-browser-reference-api.md +0 -0
  579. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-conformance-docs-reference-api.md +0 -0
  580. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-conformance-reference-api.md +0 -0
  581. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-credentials-node-reference-api.md +0 -0
  582. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-discover-reference-api.md +0 -0
  583. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-register-reference-api.md +0 -0
  584. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-remote-reference-api.md +0 -0
  585. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-cli-verify-reference-api.md +0 -0
  586. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-messaging-reference-api.md +0 -0
  587. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-messaging-sw-reference-api.md +0 -0
  588. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-database-reference-api.md +0 -0
  589. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-sandbox-firestore-reference-api.md +0 -0
  590. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-agents-reference-api.md +0 -0
  591. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-auth-hooks-reference-api.md +0 -0
  592. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-auth-reference-api.md +0 -0
  593. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-events-hooks-reference-api.md +0 -0
  594. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-events-reference-api.md +0 -0
  595. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-firestore-hooks-reference-api.md +0 -0
  596. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-primitives-reference-api.md +0 -0
  597. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rtdb-reference-api.md +0 -0
  598. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rules-hooks-reference-api.md +0 -0
  599. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-rules-reference-api.md +0 -0
  600. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-storage-hooks-reference-api.md +0 -0
  601. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-traffic-hooks-reference-api.md +0 -0
  602. /package/dist/serve/{docs-ui → site-ui}/docs/pyric-ui-traffic-reference-api.md +0 -0
  603. /package/dist/serve/{docs-ui → site-ui}/docs/secure/audit-your-rules.md +0 -0
  604. /package/dist/serve/{docs-ui → site-ui}/docs/secure/firestore-rules-limits.md +0 -0
  605. /package/dist/serve/{docs-ui → site-ui}/docs/secure/read-a-denial.md +0 -0
  606. /package/dist/serve/{docs-ui → site-ui}/docs/secure/rtdb-rules-in-typescript.md +0 -0
  607. /package/dist/serve/{docs-ui → site-ui}/docs/secure/secure-it-with-rules.md +0 -0
  608. /package/dist/serve/{docs-ui → site-ui}/docs/secure/simulate-and-lint.md +0 -0
  609. /package/dist/serve/{docs-ui → site-ui}/docs/secure/write-a-rules-test-suite.md +0 -0
  610. /package/dist/serve/{docs-ui → site-ui}/docs/ship/ship-to-production.md +0 -0
  611. /package/dist/serve/{docs-ui → site-ui}/docs/ship/test-in-node.md +0 -0
  612. /package/dist/serve/{docs-ui → site-ui}/docs/trust/how-we-know-it-matches-firebase.md +0 -0
  613. /package/dist/serve/{docs-ui → site-ui}/docs/trust/versioning-and-compatibility.md +0 -0
  614. /package/dist/serve/{studio-ui → site-ui}/pyric-logo.svg +0 -0
@@ -0,0 +1,65 @@
1
+ import { SANDBOX_BUILD_MARKER } from './sandbox-marker.js';
2
+
3
+ /** The import-map targets. Spec → served URL. */
4
+ export function sdkImportMap(): Record<string, string> {
5
+ return {
6
+ 'firebase/ai': '/__pyric/sdk/ai.js',
7
+ 'firebase/app': '/__pyric/sdk/app.js',
8
+ 'firebase/auth': '/__pyric/sdk/auth.js',
9
+ 'firebase/database': '/__pyric/sdk/database.js',
10
+ 'firebase/firestore': '/__pyric/sdk/firestore.js',
11
+ 'firebase/messaging': '/__pyric/sdk/messaging.js',
12
+ 'firebase/messaging/sw': '/__pyric/sdk/messaging-sw.js',
13
+ 'firebase/storage': '/__pyric/sdk/storage.js',
14
+ };
15
+ }
16
+
17
+ /** Inject the sandbox import map and boot tags before application modules. */
18
+ export function injectServeTags(
19
+ html: string,
20
+ importMap: Record<string, string> = sdkImportMap(),
21
+ workerVersion?: string,
22
+ forceInPage = false,
23
+ ): string {
24
+ const marker = 'data-pyric-serve';
25
+ if (html.includes(marker)) return html;
26
+ // A sandbox build already bundles its runtime. Adding the import map and
27
+ // init module would boot a second backend; only the staleness stamp belongs.
28
+ if (html.includes(SANDBOX_BUILD_MARKER)) {
29
+ if (!workerVersion || html.includes('pyric-worker-v')) return html;
30
+ const meta = `<meta name="pyric-worker-v" content="${workerVersion}" ${marker}>`;
31
+ const headTag = html.match(/<head[^>]*>/i);
32
+ if (headTag && headTag.index !== undefined) {
33
+ const at = headTag.index + headTag[0].length;
34
+ return html.slice(0, at) + meta + html.slice(at);
35
+ }
36
+ return meta + html;
37
+ }
38
+
39
+ // SharedWorkers survive page reloads, so the page compares this served hash
40
+ // with the worker's baked hash and can offer an explicit worker update.
41
+ const versionMeta = workerVersion
42
+ ? `<meta name="pyric-worker-v" content="${workerVersion}" ${marker}>`
43
+ : '';
44
+ // Bridge mode must select the in-page backend before any application module
45
+ // runs, otherwise the agent and application would use different sandboxes.
46
+ const forceTag = forceInPage
47
+ ? `<script ${marker}>globalThis.__PYRIC_FORCE_INPAGE__=true;</script>`
48
+ : '';
49
+ const tags =
50
+ versionMeta +
51
+ forceTag +
52
+ `<script type="importmap" ${marker}>${JSON.stringify({ imports: importMap })}</script>` +
53
+ `<script type="module" src="/__pyric/sdk/init.js" ${marker}></script>`;
54
+ const head = html.match(/<head[^>]*>/i);
55
+ if (head && head.index !== undefined) {
56
+ const at = head.index + head[0].length;
57
+ return html.slice(0, at) + tags + html.slice(at);
58
+ }
59
+ const htmlTag = html.match(/<html[^>]*>/i);
60
+ if (htmlTag && htmlTag.index !== undefined) {
61
+ const at = htmlTag.index + htmlTag[0].length;
62
+ return html.slice(0, at) + tags + html.slice(at);
63
+ }
64
+ return tags + html;
65
+ }
@@ -10,18 +10,18 @@
10
10
  * Bridge routes (`/__pyric/mcp`, `/__pyric/sandbox`) mount here in P2.
11
11
  */
12
12
  import { randomBytes } from 'node:crypto';
13
- import { existsSync, statSync } from 'node:fs';
14
- import { basename, extname, join } from 'node:path';
13
+ import { existsSync } from 'node:fs';
14
+ import { basename, join } from 'node:path';
15
15
  import type { IncomingMessage, ServerResponse } from 'node:http';
16
16
  import type { ActivityIncident } from 'pyric/firestore/internal';
17
17
  import { collectBody } from '../bridge/server/peer.js';
18
18
  import { StateFileError, type StateSection, type StateStore } from './state-store.js';
19
19
  import { createWriterLock, type WriterLock } from './writer-lock.js';
20
20
  import { createStudioRoutes, type StudioRouteOptions } from './studio/index.js';
21
- import { contentTypeFor, pipeFileToResponse, resolveStaticFile, type ServeLogger } from './server.js';
22
- import { SANDBOX_BUILD_MARKER } from './sandbox-marker.js';
21
+ import { pipeFileToResponse, type ServeLogger } from './server.js';
23
22
  import type { InitPayload } from './init-payload.js';
24
23
  import { handleActivity } from './activity-route.js';
24
+ import { createSiteTreeHandler } from './site-tree.js';
25
25
  export type { InitPayload } from './init-payload.js';
26
26
 
27
27
  /**
@@ -34,12 +34,19 @@ export interface ServeEventHub {
34
34
  handle(req: IncomingMessage, res: ServerResponse): void;
35
35
  broadcast(event: string, data: unknown): void;
36
36
  clientCount(): number;
37
+ /** End all open streams. Idempotent; used by host-neutral session cleanup. */
38
+ close(): void;
37
39
  }
38
40
 
39
41
  export function createEventHub(): ServeEventHub {
40
42
  const clients = new Set<ServerResponse>();
43
+ let closed = false;
41
44
  return {
42
45
  handle(req, res) {
46
+ if (closed) {
47
+ res.writeHead(503, { 'content-type': 'text/plain' }).end('sandbox session closed');
48
+ return;
49
+ }
43
50
  res.writeHead(200, {
44
51
  'content-type': 'text/event-stream',
45
52
  'cache-control': 'no-store',
@@ -53,6 +60,7 @@ export function createEventHub(): ServeEventHub {
53
60
  res.on('error', () => clients.delete(res));
54
61
  },
55
62
  broadcast(event, data) {
63
+ if (closed) return;
56
64
  const frame = `event: ${event}\ndata: ${JSON.stringify(data)}\n\n`;
57
65
  for (const res of clients) {
58
66
  try {
@@ -63,6 +71,12 @@ export function createEventHub(): ServeEventHub {
63
71
  }
64
72
  },
65
73
  clientCount: () => clients.size,
74
+ close() {
75
+ if (closed) return;
76
+ closed = true;
77
+ for (const res of clients) res.end();
78
+ clients.clear();
79
+ },
66
80
  };
67
81
  }
68
82
 
@@ -85,22 +99,14 @@ export interface NamespaceOptions {
85
99
  * current fixture JSON (200) or 404 when nothing is captured yet, so the
86
100
  * served worker can re-hydrate its event history on boot after a death. */
87
101
  capture?: { write(json: string): void; read(): string | null };
102
+ /** Unified Astro documentation + Studio tree, built for `/__pyric/ui/`. */
103
+ siteUiDir?: string;
104
+ /** Served SharedWorker epoch stamped only into Studio entry documents. */
105
+ workerVersion?: string;
88
106
  /** `--ui` (Pyric Studio): mounts `/__pyric/workspace` + `/__pyric/projects`
89
107
  * (disk-backed `WorkspaceStore`/`ProjectStore`, plus the SSE watch stream)
90
108
  * that `@pyric/studio`'s `local` mode talks to. */
91
109
  studio?: StudioRouteOptions;
92
- /** `--ui` (Pyric Studio): the dir of the built Studio app, served under
93
- * `/__pyric/ui/`. Resolved by file path in the CLI (@pyric/cli never
94
- * imports `@pyric/studio`). Absent when `--ui` is off or the build is
95
- * missing. */
96
- studioUiDir?: string;
97
- /** `--ui` (Pyric Studio): the built docs site (site-docs), served so the
98
- * Studio Docs tab has local docs without the hosted site. Built with base
99
- * `/__pyric/ui/`, so its output straddles two subtrees under the mount:
100
- * the pages/twins/index.json live under `/__pyric/ui/docs/`, but the shared
101
- * assets live at `/__pyric/ui/_astro/` (Astro's asset dir, at the base
102
- * root — NOT under `docs/`). Both are served from this one dir. */
103
- docsUiDir?: string;
104
110
  /** The OpenAI-compatible upstream `/__pyric/ai-proxy` forwards to
105
111
  * (pyric/ai — cdd-deltas #98.2). Falls back to the
106
112
  * `PYRIC_AI_PROXY_UPSTREAM` env var, then `http://localhost:11434/v1`
@@ -467,6 +473,9 @@ async function handleDenials(
467
473
  export function createPyricNamespace(opts: NamespaceOptions) {
468
474
  const writerLock = createWriterLock();
469
475
  const studioRoutes = opts.studio ? createStudioRoutes(opts.studio) : null;
476
+ const siteTree = opts.siteUiDir
477
+ ? createSiteTreeHandler(opts.siteUiDir, opts.workerVersion)
478
+ : null;
470
479
  const denialThrottle = createDenialThrottle();
471
480
  // Issued once per server boot. The outer static/Vite host guard protects
472
481
  // init.json before this capability is disclosed to the served runtime.
@@ -517,159 +526,7 @@ export function createPyricNamespace(opts: NamespaceOptions) {
517
526
  pipeFileToResponse(file, res);
518
527
  return true;
519
528
  }
520
- // Embedded docs site (site-docs). MUST run BEFORE the general
521
- // `/__pyric/ui/` studio handler below: that handler's SPA fallback answers
522
- // every miss with Studio's index.html, which would swallow docs pages and
523
- // (worse) return HTML for a missing docs asset. Built with base
524
- // `/__pyric/ui/`, the docs output lives in TWO subtrees under the mount —
525
- // pages/twins/index.json under `/__pyric/ui/docs/`, and shared assets at
526
- // `/__pyric/ui/_astro/` (Astro's asset dir sits at the base root, not under
527
- // `docs/`). We claim both; `_astro` is Astro-specific and never collides
528
- // with Studio (Vite emits `/__pyric/ui/assets/`). No SPA fallback here — a
529
- // genuinely missing docs page 404s (a broken doc link must fail loudly, not
530
- // masquerade as another page). Directory-format pages (`<slug>/index.html`)
531
- // and `bunx serve`-style extensionless→trailing-slash redirects are handled
532
- // by resolveStaticFile + the directory redirect below.
533
- if (
534
- opts.docsUiDir &&
535
- (url.pathname === '/__pyric/ui/docs' ||
536
- url.pathname.startsWith('/__pyric/ui/docs/') ||
537
- url.pathname.startsWith('/__pyric/ui/_astro/'))
538
- ) {
539
- const rel = url.pathname.slice('/__pyric/ui'.length) || '/';
540
- // `bunx serve` parity: an extensionless path that names a real directory
541
- // (e.g. `/__pyric/ui/docs` or `/__pyric/ui/docs/<slug>`) redirects to the
542
- // trailing-slash form so the directory's index.html loads with correct
543
- // relative-URL resolution.
544
- if (!rel.endsWith('/') && !extname(rel)) {
545
- const dir = join(opts.docsUiDir, decodeURIComponent(rel));
546
- if (existsSync(dir) && statSync(dir).isDirectory()) {
547
- res.writeHead(301, { location: `${url.pathname}/` }).end();
548
- return true;
549
- }
550
- }
551
- const file = resolveStaticFile(opts.docsUiDir, rel);
552
- if (!file) {
553
- res.writeHead(404).end('not found');
554
- return true;
555
- }
556
- res.writeHead(200, { 'content-type': contentTypeFor(file), 'cache-control': 'no-store' });
557
- pipeFileToResponse(file, res);
558
- return true;
559
- }
560
- if (
561
- opts.studioUiDir &&
562
- (url.pathname === '/__pyric/ui' || url.pathname.startsWith('/__pyric/ui/'))
563
- ) {
564
- // The built Pyric Studio app. Served verbatim (NOT through
565
- // injectServeTags: that import-map/init injection is for sandbox pages,
566
- // not Studio). Studio uses History-API routing under this mount, so any
567
- // path that doesn't resolve to a real file falls back to index.html —
568
- // INCLUDING paths with dots (deep links like /storage/uploads/logo.png).
569
- // Only misses under Vite's content-hashed asset dir stay hard 404s, so a
570
- // broken script/style URL fails loudly instead of returning HTML.
571
- if (url.pathname === '/__pyric/ui') {
572
- res.writeHead(301, { location: '/__pyric/ui/' }).end();
573
- return true;
574
- }
575
- const rel = url.pathname.slice('/__pyric/ui'.length) || '/';
576
- let file = resolveStaticFile(opts.studioUiDir, rel);
577
- if (!file && !rel.startsWith('/assets/')) {
578
- file = resolveStaticFile(opts.studioUiDir, '/index.html');
579
- }
580
- if (!file) {
581
- res.writeHead(404).end('not found');
582
- return true;
583
- }
584
- res.writeHead(200, { 'content-type': contentTypeFor(file), 'cache-control': 'no-store' });
585
- pipeFileToResponse(file, res);
586
- return true;
587
- }
529
+ if (siteTree?.(req, res, url)) return true;
588
530
  return false; // unknown /__pyric/* → caller 404s
589
531
  };
590
532
  }
591
-
592
- // ─── HTML injection ───────────────────────────────────────────────────
593
-
594
- /** The import-map targets. Spec → served URL. */
595
- export function sdkImportMap(): Record<string, string> {
596
- return {
597
- 'firebase/ai': '/__pyric/sdk/ai.js',
598
- 'firebase/app': '/__pyric/sdk/app.js',
599
- 'firebase/auth': '/__pyric/sdk/auth.js',
600
- 'firebase/database': '/__pyric/sdk/database.js',
601
- 'firebase/firestore': '/__pyric/sdk/firestore.js',
602
- 'firebase/messaging': '/__pyric/sdk/messaging.js',
603
- 'firebase/messaging/sw': '/__pyric/sdk/messaging-sw.js',
604
- 'firebase/storage': '/__pyric/sdk/storage.js',
605
- };
606
- }
607
-
608
- /**
609
- * Inject the import map + init script into an HTML document. The import map
610
- * MUST precede any module script that imports a mapped specifier, so both
611
- * tags go at the very start of `<head>` (fallbacks: after `<html>`, else
612
- * prepended). Idempotent — a page already carrying the marker is untouched
613
- * (matters when transformHtml runs over an SPA fallback repeatedly).
614
- */
615
- export function injectServeTags(
616
- html: string,
617
- importMap: Record<string, string> = sdkImportMap(),
618
- workerVersion?: string,
619
- forceInPage = false,
620
- ): string {
621
- const MARKER = 'data-pyric-serve';
622
- if (html.includes(MARKER)) return html;
623
- // A pyric SANDBOX BUILD (`vite build` under the pyricSandbox plugin's sandbox
624
- // mode) already BUNDLES its own runtime + init chunk — injecting the import
625
- // map + /__pyric/sdk/init.js on top would boot a SECOND runtime instance on
626
- // the page (two banners, two bridge peer registrations, races between them).
627
- // The bundle owns the sandbox for a marked page: it fetches
628
- // /__pyric/init.json itself (worker path: the SharedWorker does; in-page
629
- // path: the runtime does) and owns rules hot-reload the same way. The ONLY
630
- // serve-time contribution left is the worker-version staleness stamp, which
631
- // the bundled runtime reads from this meta to warn about a stale
632
- // still-running SharedWorker.
633
- if (html.includes(SANDBOX_BUILD_MARKER)) {
634
- if (!workerVersion || html.includes('pyric-worker-v')) return html;
635
- const meta = `<meta name="pyric-worker-v" content="${workerVersion}" ${MARKER}>`;
636
- const headTag = html.match(/<head[^>]*>/i);
637
- if (headTag && headTag.index !== undefined) {
638
- const at = headTag.index + headTag[0].length;
639
- return html.slice(0, at) + meta + html.slice(at);
640
- }
641
- return meta + html;
642
- }
643
- // Stamp the worker's content hash so the page can DETECT staleness: a live
644
- // SharedWorker survives serve restarts + reloads and can't hot-update, so it
645
- // keeps running old code until every tab of the origin closes. The worker
646
- // name is intentionally STABLE (one backend shared by all tabs), so rather
647
- // than split tabs across versions, `runtime.ts` compares this served hash to
648
- // the running worker's baked hash and warns the user to close all tabs.
649
- const versionMeta = workerVersion
650
- ? `<meta name="pyric-worker-v" content="${workerVersion}" ${MARKER}>`
651
- : '';
652
- // `--bridge`: the MCP bridge peers with the IN-PAGE sandbox, so force the page
653
- // off the default SharedWorker path. Otherwise the agent drives an empty
654
- // in-page sandbox while the app's data lives in the worker. Set before any app
655
- // code runs; mirrors the Vite plugin's transformIndexHtml.
656
- const forceTag = forceInPage
657
- ? `<script ${MARKER}>globalThis.__PYRIC_FORCE_INPAGE__=true;</script>`
658
- : '';
659
- const tags =
660
- versionMeta +
661
- forceTag +
662
- `<script type="importmap" ${MARKER}>${JSON.stringify({ imports: importMap })}</script>` +
663
- `<script type="module" src="/__pyric/sdk/init.js" ${MARKER}></script>`;
664
- const head = html.match(/<head[^>]*>/i);
665
- if (head && head.index !== undefined) {
666
- const at = head.index + head[0].length;
667
- return html.slice(0, at) + tags + html.slice(at);
668
- }
669
- const htmlTag = html.match(/<html[^>]*>/i);
670
- if (htmlTag && htmlTag.index !== undefined) {
671
- const at = htmlTag.index + htmlTag[0].length;
672
- return html.slice(0, at) + tags + html.slice(at);
673
- }
674
- return tags + html;
675
- }
@@ -9,19 +9,41 @@ interface EpochStorage {
9
9
  removeItem?(key: string): void;
10
10
  }
11
11
 
12
- /** Select the replacement generation only after this page was told to move. */
12
+ /**
13
+ * Select the origin's active worker generation.
14
+ *
15
+ * A browser that predates generation-aware workers has no stored epoch but may
16
+ * still have the legacy `pyric-shared-worker` alive. Seed the first served
17
+ * epoch before connecting so a new client never attaches to that incompatible
18
+ * worker. Later releases keep using the stored generation until replacement
19
+ * is explicitly committed.
20
+ */
13
21
  export function workerNameForEpoch(
14
- _servedEpoch: string | null,
22
+ servedEpoch: string | null,
15
23
  storage: EpochStorage | undefined,
16
24
  ): string {
17
- if (!storage) return PYRIC_WORKER_NAME;
25
+ const validServedEpoch = servedEpoch && /^[a-f0-9]{16}$/.test(servedEpoch)
26
+ ? servedEpoch
27
+ : null;
28
+ if (!storage) {
29
+ return validServedEpoch
30
+ ? `${PYRIC_WORKER_NAME}:${validServedEpoch}`
31
+ : PYRIC_WORKER_NAME;
32
+ }
18
33
  try {
19
34
  const generation = storage.getItem(PYRIC_WORKER_GENERATION_KEY);
20
- return generation && /^[a-f0-9]{16}$/.test(generation)
21
- ? `${PYRIC_WORKER_NAME}:${generation}`
22
- : PYRIC_WORKER_NAME;
23
- } catch {
35
+ if (generation && /^[a-f0-9]{16}$/.test(generation)) {
36
+ return `${PYRIC_WORKER_NAME}:${generation}`;
37
+ }
38
+ if (validServedEpoch) {
39
+ storage.setItem(PYRIC_WORKER_GENERATION_KEY, validServedEpoch);
40
+ return `${PYRIC_WORKER_NAME}:${validServedEpoch}`;
41
+ }
24
42
  return PYRIC_WORKER_NAME;
43
+ } catch {
44
+ return validServedEpoch
45
+ ? `${PYRIC_WORKER_NAME}:${validServedEpoch}`
46
+ : PYRIC_WORKER_NAME;
25
47
  }
26
48
  }
27
49
 
@@ -1,4 +1,4 @@
1
- interface WorkerReplacementOptions {
1
+ export interface WorkerReplacementOptions {
2
2
  targetEpoch: string;
3
3
  retire(): Promise<void>;
4
4
  subscribeReload(listener: (epoch: string) => void): () => void;
@@ -0,0 +1,233 @@
1
+ import { existsSync, readFileSync, rmSync } from 'node:fs';
2
+ import { readFile } from 'node:fs/promises';
3
+ import { join, resolve } from 'node:path';
4
+ import type { IncomingMessage, ServerResponse } from 'node:http';
5
+ import type { ActivityIncident } from 'pyric/firestore/internal';
6
+ import type { FirebaseJson } from '../cli/firebase-json.js';
7
+ import { createCaptureStore, type CaptureStore } from './capture-store.js';
8
+ import type { InitPayload } from './init-payload.js';
9
+ import {
10
+ loadProjectDatabaseRules,
11
+ loadProjectRules,
12
+ loadProjectStorageRules,
13
+ prepareRulesSource,
14
+ rulesHashOf,
15
+ } from './rules.js';
16
+ import { createEventHub, createPyricNamespace } from './namespace.js';
17
+ import { diskProjectStore, diskWorkspace } from './studio/index.js';
18
+ import type { ServeLogger } from './server.js';
19
+ import {
20
+ createStateStore,
21
+ firestoreDocCount,
22
+ STATE_FILE_VERSION,
23
+ type PyricStateFile,
24
+ type StateStore,
25
+ } from './state-store.js';
26
+
27
+ export interface SandboxSessionOptions {
28
+ projectDir: string;
29
+ firebaseConfig: FirebaseJson | null;
30
+ sdk: { dir: string; workerVersion?: string };
31
+ seedFile?: string;
32
+ capture?: boolean;
33
+ persistence?: { fresh?: boolean };
34
+ studio?: false | { siteUiDir?: string };
35
+ bridgeUrl?: () => string | null;
36
+ ai?: InitPayload['ai'];
37
+ aiProxyUpstream?: string;
38
+ logger?: ServeLogger;
39
+ activity?: (incident: ActivityIncident) => void;
40
+ }
41
+
42
+ export interface SandboxSessionSummary {
43
+ rules: {
44
+ firestore: { sourcePath: string | null; hash: string | null };
45
+ database: { sourcePath: string | null; hash: string | null };
46
+ storage: { sourcePath: string | null; hash: string | null };
47
+ };
48
+ persistence: null | {
49
+ path: string;
50
+ backupPath: string;
51
+ restoredDocs: number;
52
+ restoredUsers: number;
53
+ restored: boolean;
54
+ };
55
+ capturePath: string | null;
56
+ seedLabel: string | null;
57
+ seedStaged: boolean;
58
+ studioMounted: boolean;
59
+ }
60
+
61
+ export interface SandboxSession {
62
+ readonly summary: SandboxSessionSummary;
63
+ payload(): InitPayload;
64
+ handle(req: IncomingMessage, res: ServerResponse, url: URL): boolean | Promise<boolean>;
65
+ reloadFirestoreRules(): Promise<RulesReloadResult>;
66
+ close(): Promise<void>;
67
+ }
68
+
69
+ export class SandboxSeedError extends Error {
70
+ constructor(
71
+ readonly kind: 'read' | 'shape',
72
+ readonly path: string,
73
+ readonly detail: string,
74
+ ) {
75
+ super(kind === 'read' ? `failed to read seed ${path}: ${detail}` : `seed must be a JSON object (${detail})`);
76
+ this.name = 'SandboxSeedError';
77
+ }
78
+ }
79
+
80
+ export type RulesReloadResult =
81
+ | { kind: 'not-configured' }
82
+ | { kind: 'reloaded'; rulesHash: string; clients: number }
83
+ | { kind: 'rejected'; error: Error };
84
+
85
+ export async function createSandboxSession(
86
+ options: SandboxSessionOptions,
87
+ ): Promise<SandboxSession> {
88
+ // Preserve the established fail-fast order: Firestore, then RTDB, then
89
+ // Storage. Callers historically surfaced the first error in this sequence.
90
+ const firestore = await loadProjectRules(options.projectDir, options.firebaseConfig);
91
+ const database = await loadProjectDatabaseRules(options.projectDir, options.firebaseConfig);
92
+ const storage = await loadProjectStorageRules(options.projectDir, options.firebaseConfig);
93
+ const live = {
94
+ rules: firestore.rules,
95
+ rulesHash: firestore.rulesHash,
96
+ };
97
+ const events = createEventHub();
98
+ const capture: CaptureStore | undefined = (options.capture ?? true)
99
+ ? createCaptureStore(options.projectDir)
100
+ : undefined;
101
+ const state: StateStore | undefined = options.persistence
102
+ ? createStateStore(options.projectDir)
103
+ : undefined;
104
+ if (state && options.persistence?.fresh) {
105
+ for (const file of [state.path, state.backupPath]) {
106
+ if (existsSync(file)) rmSync(file);
107
+ }
108
+ }
109
+ let persisted = state?.load() ?? null;
110
+ let seed: Record<string, Record<string, unknown>> | null = null;
111
+ let seedState: unknown | null = null;
112
+ let seedUsers: Record<string, unknown>[] | null = null;
113
+ let seedLabel: string | null = null;
114
+ if (options.seedFile) {
115
+ const seedPath = resolve(options.projectDir, options.seedFile);
116
+ let parsed: unknown;
117
+ try {
118
+ parsed = JSON.parse(readFileSync(seedPath, 'utf8')) as unknown;
119
+ } catch (error) {
120
+ throw new SandboxSeedError('read', seedPath, error instanceof Error ? error.message : String(error));
121
+ }
122
+ if (!parsed || typeof parsed !== 'object' || Array.isArray(parsed)) {
123
+ throw new SandboxSeedError('shape', seedPath, `got ${Array.isArray(parsed) ? 'array' : typeof parsed}`);
124
+ }
125
+ const record = parsed as Record<string, unknown>;
126
+ if (record.version === STATE_FILE_VERSION && ('firestore' in record || 'auth' in record)) {
127
+ const fixture = record as unknown as PyricStateFile;
128
+ const restoredDocs = firestoreDocCount(fixture.firestore);
129
+ const restoredUsers = fixture.auth?.users?.length ?? 0;
130
+ seedLabel = `${restoredDocs} doc(s) + ${restoredUsers} user(s) from state fixture`;
131
+ if (state && !state.exists()) {
132
+ if (fixture.firestore != null) state.writeSection('firestore', fixture.firestore);
133
+ if (fixture.auth != null) state.writeSection('auth', fixture.auth);
134
+ persisted = state.load();
135
+ } else if (!state) {
136
+ seedState = fixture.firestore ?? null;
137
+ seedUsers = (fixture.auth?.users as Record<string, unknown>[] | undefined) ?? null;
138
+ }
139
+ } else {
140
+ seed = record as Record<string, Record<string, unknown>>;
141
+ seedLabel = `${Object.keys(seed).length} document(s)`;
142
+ }
143
+ }
144
+
145
+ const payload = (): InitPayload => ({
146
+ rules: live.rules,
147
+ rulesHash: live.rulesHash,
148
+ databaseRules: database.rules,
149
+ databaseRulesHash: database.rulesHash,
150
+ databaseUrl: database.databaseUrl,
151
+ storageRules: storage.rules,
152
+ storageRulesHash: storage.rulesHash,
153
+ projectKey: options.projectDir,
154
+ bridgeUrl: options.bridgeUrl?.() ?? null,
155
+ seed: state?.exists() ? null : seed,
156
+ seedState,
157
+ persist: Boolean(state),
158
+ capture: Boolean(capture),
159
+ authUsers: state
160
+ ? ((state.readSection('auth') as { users?: Record<string, unknown>[] } | null)?.users ?? null)
161
+ : seedUsers,
162
+ messaging: true,
163
+ ai: options.ai ?? null,
164
+ });
165
+
166
+ const summary: SandboxSessionSummary = {
167
+ rules: {
168
+ firestore: { sourcePath: firestore.sourcePath, hash: firestore.rulesHash },
169
+ database: { sourcePath: database.sourcePath, hash: database.rulesHash },
170
+ storage: { sourcePath: storage.sourcePath, hash: storage.rulesHash },
171
+ },
172
+ persistence: state
173
+ ? {
174
+ path: state.path,
175
+ backupPath: state.backupPath,
176
+ restoredDocs: firestoreDocCount(persisted?.firestore),
177
+ restoredUsers: persisted?.auth?.users?.length ?? 0,
178
+ restored: persisted !== null,
179
+ }
180
+ : null,
181
+ capturePath: capture?.path ?? null,
182
+ seedLabel,
183
+ seedStaged: Boolean((seed && !state?.exists()) || seedState || seedUsers),
184
+ studioMounted: Boolean(options.studio),
185
+ };
186
+
187
+ const namespace = createPyricNamespace({
188
+ sdkDir: options.sdk.dir,
189
+ initPayload: payload,
190
+ events,
191
+ state,
192
+ capture,
193
+ studio: options.studio
194
+ ? {
195
+ workspace: diskWorkspace(options.projectDir),
196
+ projects: diskProjectStore(join(options.projectDir, '.pyric', 'projects')),
197
+ }
198
+ : undefined,
199
+ siteUiDir: options.studio ? options.studio.siteUiDir : undefined,
200
+ workerVersion: options.sdk.workerVersion,
201
+ aiProxyUpstream: options.aiProxyUpstream,
202
+ activity: options.activity,
203
+ logger: options.logger,
204
+ });
205
+
206
+ const reloadFirestoreRules = async (): Promise<RulesReloadResult> => {
207
+ if (!firestore.sourcePath) return { kind: 'not-configured' };
208
+ try {
209
+ const raw = await readFile(firestore.sourcePath, 'utf8');
210
+ const rules = prepareRulesSource(raw, firestore.sourcePath);
211
+ const rulesHash = rulesHashOf(rules);
212
+ live.rules = rules;
213
+ live.rulesHash = rulesHash;
214
+ events.broadcast('rules-changed', { rules, rulesHash });
215
+ return { kind: 'reloaded', rulesHash, clients: events.clientCount() };
216
+ } catch (error) {
217
+ return { kind: 'rejected', error: error instanceof Error ? error : new Error(String(error)) };
218
+ }
219
+ };
220
+ let closePromise: Promise<void> | null = null;
221
+ const close = (): Promise<void> => {
222
+ closePromise ??= Promise.resolve().then(() => events.close());
223
+ return closePromise;
224
+ };
225
+
226
+ return {
227
+ summary,
228
+ payload,
229
+ handle: namespace,
230
+ reloadFirestoreRules,
231
+ close,
232
+ };
233
+ }
@@ -173,14 +173,29 @@ export function contentTypeFor(path: string): string {
173
173
  return CONTENT_TYPES[extname(path).toLowerCase()] ?? 'application/octet-stream';
174
174
  }
175
175
 
176
- /** Resolve a request path inside `publicDir`, refusing traversal. Returns
177
- * null when the path escapes the root or doesn't exist as a file. */
178
- export function resolveStaticFile(publicDir: string, pathname: string): string | null {
179
- const decoded = decodeURIComponent(pathname);
176
+ /** Decode a URL pathname for static-file lookup. Malformed escapes are misses. */
177
+ export function decodeStaticPathname(pathname: string): string | null {
178
+ try {
179
+ return decodeURIComponent(pathname);
180
+ } catch {
181
+ return null;
182
+ }
183
+ }
184
+
185
+ /** Resolve a request path inside `publicDir`, refusing malformed or escaping paths. */
186
+ export function resolveStaticPath(publicDir: string, pathname: string): string | null {
187
+ const decoded = decodeStaticPathname(pathname);
188
+ if (decoded === null) return null;
180
189
  const root = resolve(publicDir);
181
190
  const candidate = normalize(join(root, decoded));
182
191
  if (candidate !== root && !candidate.startsWith(root + sep)) return null; // traversal
183
- let file = candidate;
192
+ return candidate;
193
+ }
194
+
195
+ /** Resolve an existing static file inside `publicDir`. */
196
+ export function resolveStaticFile(publicDir: string, pathname: string): string | null {
197
+ let file = resolveStaticPath(publicDir, pathname);
198
+ if (file === null) return null;
184
199
  if (existsSync(file) && statSync(file).isDirectory()) file = join(file, 'index.html');
185
200
  if (!existsSync(file) || !statSync(file).isFile()) return null;
186
201
  return file;