gemi 0.108.0 → 0.110.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (280) hide show
  1. package/dist/ai/index.js +2 -2
  2. package/dist/ai/index.js.map +1 -1
  3. package/dist/app/index.js +2 -2
  4. package/dist/app/index.js.map +1 -1
  5. package/dist/bin/gemi.js +535 -55
  6. package/dist/bin/gemi.js.map +11 -6
  7. package/dist/bun/plugin.js +2 -2
  8. package/dist/bun/plugin.js.map +1 -1
  9. package/dist/bun/preload.js +2 -2
  10. package/dist/bun/preload.js.map +1 -1
  11. package/dist/{chunk-xpyhmg45.js → chunk-09ypnhjv.js} +3 -3
  12. package/dist/{chunk-3s3awh38.js.map → chunk-09ypnhjv.js.map} +1 -1
  13. package/dist/{chunk-rjernda5.js → chunk-0d9qsmx2.js} +3 -3
  14. package/dist/{chunk-rjernda5.js.map → chunk-0d9qsmx2.js.map} +1 -1
  15. package/dist/{chunk-xg9vye7c.js → chunk-0sjh5v1n.js} +1 -1
  16. package/dist/{chunk-2mhx4e4g.js → chunk-11fsn5mr.js} +3 -3
  17. package/dist/{chunk-2mhx4e4g.js.map → chunk-11fsn5mr.js.map} +1 -1
  18. package/dist/{chunk-wzqkdmjd.js → chunk-1c1d0e60.js} +3 -3
  19. package/dist/{chunk-wzqkdmjd.js.map → chunk-1c1d0e60.js.map} +1 -1
  20. package/dist/{chunk-wedwkqe7.js → chunk-1kr25rcg.js} +3 -3
  21. package/dist/{chunk-wedwkqe7.js.map → chunk-1kr25rcg.js.map} +1 -1
  22. package/dist/{chunk-6wrhc9bq.js → chunk-1pem26zc.js} +3 -3
  23. package/dist/{chunk-6wrhc9bq.js.map → chunk-1pem26zc.js.map} +1 -1
  24. package/dist/{chunk-ydkjf626.js → chunk-1va15sfq.js} +2 -2
  25. package/dist/{chunk-ydkjf626.js.map → chunk-1va15sfq.js.map} +2 -2
  26. package/dist/{chunk-3s3awh38.js → chunk-1yx2e0bh.js} +2 -2
  27. package/dist/{chunk-xpyhmg45.js.map → chunk-1yx2e0bh.js.map} +1 -1
  28. package/dist/{chunk-9r3znmqq.js → chunk-303mprnv.js} +2 -2
  29. package/dist/{chunk-9r3znmqq.js.map → chunk-303mprnv.js.map} +1 -1
  30. package/dist/{chunk-sbyqs03h.js → chunk-30xjcyzh.js} +2 -2
  31. package/dist/{chunk-sbyqs03h.js.map → chunk-30xjcyzh.js.map} +1 -1
  32. package/dist/{chunk-k17prwhx.js → chunk-358sdcx9.js} +3 -3
  33. package/dist/{chunk-k17prwhx.js.map → chunk-358sdcx9.js.map} +1 -1
  34. package/dist/{chunk-2gmgd05c.js → chunk-3cg7y62b.js} +2 -2
  35. package/dist/{chunk-2gmgd05c.js.map → chunk-3cg7y62b.js.map} +1 -1
  36. package/dist/{chunk-t26n9vzw.js → chunk-3y8q8x11.js} +2 -2
  37. package/dist/{chunk-t26n9vzw.js.map → chunk-3y8q8x11.js.map} +1 -1
  38. package/dist/chunk-4mfrgd5m.js +34 -0
  39. package/dist/chunk-4mfrgd5m.js.map +10 -0
  40. package/dist/chunk-5cygrbxv.js +4 -0
  41. package/dist/{chunk-vj2t77x1.js.map → chunk-5cygrbxv.js.map} +2 -2
  42. package/dist/{chunk-tvy2fqza.js → chunk-5stgtwqw.js} +2 -2
  43. package/dist/{chunk-tvy2fqza.js.map → chunk-5stgtwqw.js.map} +1 -1
  44. package/dist/chunk-61f4m5px.js +6 -0
  45. package/dist/chunk-61f4m5px.js.map +12 -0
  46. package/dist/chunk-6chz1ktz.js +9 -0
  47. package/dist/chunk-6chz1ktz.js.map +13 -0
  48. package/dist/{chunk-1rs13253.js → chunk-6vr7f5fq.js} +4 -4
  49. package/dist/{chunk-1rs13253.js.map → chunk-6vr7f5fq.js.map} +1 -1
  50. package/dist/{chunk-2q7m8a16.js → chunk-7tx5y712.js} +2 -2
  51. package/dist/{chunk-2q7m8a16.js.map → chunk-7tx5y712.js.map} +1 -1
  52. package/dist/{chunk-eytdyahy.js → chunk-8afxrmdc.js} +3 -3
  53. package/dist/{chunk-eytdyahy.js.map → chunk-8afxrmdc.js.map} +1 -1
  54. package/dist/{chunk-anp4kv3w.js → chunk-8b2tw2yp.js} +1 -1
  55. package/dist/{chunk-kqff894s.js → chunk-9rchedr4.js} +2 -2
  56. package/dist/{chunk-kqff894s.js.map → chunk-9rchedr4.js.map} +1 -1
  57. package/dist/{chunk-6rz8kyqb.js → chunk-9s851qz8.js} +2 -2
  58. package/dist/{chunk-6rz8kyqb.js.map → chunk-9s851qz8.js.map} +1 -1
  59. package/dist/{chunk-8pynv9rw.js → chunk-a6453d9s.js} +3 -3
  60. package/dist/{chunk-8pynv9rw.js.map → chunk-a6453d9s.js.map} +1 -1
  61. package/dist/{chunk-5wt25tyd.js → chunk-bn5yn731.js} +2 -2
  62. package/dist/{chunk-5wt25tyd.js.map → chunk-bn5yn731.js.map} +1 -1
  63. package/dist/{chunk-zrdbytx4.js → chunk-c098fzvk.js} +2 -2
  64. package/dist/{chunk-zrdbytx4.js.map → chunk-c098fzvk.js.map} +1 -1
  65. package/dist/{chunk-mhq2bd9c.js → chunk-cttmy1jp.js} +4 -4
  66. package/dist/{chunk-mhq2bd9c.js.map → chunk-cttmy1jp.js.map} +2 -2
  67. package/dist/{chunk-331s9wqr.js → chunk-cy5qp6mz.js} +3 -3
  68. package/dist/{chunk-331s9wqr.js.map → chunk-cy5qp6mz.js.map} +1 -1
  69. package/dist/{chunk-kh273hj0.js → chunk-ddr4qvvt.js} +3 -3
  70. package/dist/{chunk-kh273hj0.js.map → chunk-ddr4qvvt.js.map} +1 -1
  71. package/dist/chunk-e1n8zs3h.js +58 -0
  72. package/dist/chunk-e1n8zs3h.js.map +14 -0
  73. package/dist/{chunk-2xqrh6d0.js → chunk-et4pv1b1.js} +1 -1
  74. package/dist/{chunk-a1g0bahx.js → chunk-frerzsxq.js} +2 -2
  75. package/dist/{chunk-a1g0bahx.js.map → chunk-frerzsxq.js.map} +1 -1
  76. package/dist/{chunk-pj2e1p07.js → chunk-gb37722w.js} +3 -3
  77. package/dist/{chunk-pj2e1p07.js.map → chunk-gb37722w.js.map} +1 -1
  78. package/dist/chunk-h3864a8z.js +17 -0
  79. package/dist/{chunk-ncfxmtd5.js.map → chunk-h3864a8z.js.map} +14 -11
  80. package/dist/{chunk-661wezaf.js → chunk-h4sw6nt3.js} +3 -3
  81. package/dist/{chunk-661wezaf.js.map → chunk-h4sw6nt3.js.map} +1 -1
  82. package/dist/{chunk-m31pfz1s.js → chunk-he7z7y9j.js} +2 -2
  83. package/dist/{chunk-m31pfz1s.js.map → chunk-he7z7y9j.js.map} +1 -1
  84. package/dist/{chunk-kstvyvr0.js → chunk-hf7a51s3.js} +2 -2
  85. package/dist/{chunk-kstvyvr0.js.map → chunk-hf7a51s3.js.map} +1 -1
  86. package/dist/chunk-hn67spz6.js +5 -0
  87. package/dist/{chunk-mrvcaakf.js.map → chunk-hn67spz6.js.map} +1 -1
  88. package/dist/{chunk-fq3sb3xt.js → chunk-jbrwt3cs.js} +4 -4
  89. package/dist/{chunk-fq3sb3xt.js.map → chunk-jbrwt3cs.js.map} +1 -1
  90. package/dist/{chunk-jnw73s8c.js → chunk-k1vw22t2.js} +2 -2
  91. package/dist/{chunk-jnw73s8c.js.map → chunk-k1vw22t2.js.map} +1 -1
  92. package/dist/chunk-k1xt2tw7.js +4 -0
  93. package/dist/{chunk-hdhahvd4.js.map → chunk-k1xt2tw7.js.map} +2 -2
  94. package/dist/chunk-k9wgtrc5.js +24 -0
  95. package/dist/{chunk-h2hdpm70.js.map → chunk-k9wgtrc5.js.map} +4 -4
  96. package/dist/{chunk-00y49jcf.js → chunk-kf71mjxa.js} +3 -3
  97. package/dist/{chunk-00y49jcf.js.map → chunk-kf71mjxa.js.map} +1 -1
  98. package/dist/{chunk-kqz8jp6v.js → chunk-m6ystvtk.js} +2 -2
  99. package/dist/{chunk-kqz8jp6v.js.map → chunk-m6ystvtk.js.map} +1 -1
  100. package/dist/{chunk-ftgd68se.js → chunk-mb7q7s0a.js} +3 -3
  101. package/dist/{chunk-ftgd68se.js.map → chunk-mb7q7s0a.js.map} +1 -1
  102. package/dist/{chunk-rh9j8cwv.js → chunk-mn5xw79b.js} +3 -3
  103. package/dist/{chunk-rh9j8cwv.js.map → chunk-mn5xw79b.js.map} +1 -1
  104. package/dist/{chunk-wsftnxzs.js → chunk-mwqg079k.js} +2 -2
  105. package/dist/{chunk-wsftnxzs.js.map → chunk-mwqg079k.js.map} +1 -1
  106. package/dist/{chunk-yebaheh7.js → chunk-nncz308h.js} +3 -3
  107. package/dist/{chunk-yebaheh7.js.map → chunk-nncz308h.js.map} +1 -1
  108. package/dist/{chunk-82hpq0bq.js → chunk-nsvktvp4.js} +2 -2
  109. package/dist/{chunk-82hpq0bq.js.map → chunk-nsvktvp4.js.map} +1 -1
  110. package/dist/{chunk-h7pafjej.js → chunk-nvv9wej6.js} +3 -3
  111. package/dist/{chunk-h7pafjej.js.map → chunk-nvv9wej6.js.map} +1 -1
  112. package/dist/chunk-p1aqq0ga.js +16 -0
  113. package/dist/{chunk-q7y9v2v5.js.map → chunk-p1aqq0ga.js.map} +5 -8
  114. package/dist/chunk-p7r2w4qw.js +5 -0
  115. package/dist/{chunk-h3t4n0bn.js.map → chunk-p7r2w4qw.js.map} +2 -2
  116. package/dist/{chunk-fwympxqk.js → chunk-pwmgqq7z.js} +2 -2
  117. package/dist/{chunk-fwympxqk.js.map → chunk-pwmgqq7z.js.map} +1 -1
  118. package/dist/chunk-pyj7cd9t.js +4 -0
  119. package/dist/{chunk-q2fyp44f.js.map → chunk-pyj7cd9t.js.map} +2 -2
  120. package/dist/{chunk-9mqqr05d.js → chunk-q9s7kwgt.js} +3 -3
  121. package/dist/{chunk-9mqqr05d.js.map → chunk-q9s7kwgt.js.map} +1 -1
  122. package/dist/{chunk-9hbwvcxn.js → chunk-qd2v93y4.js} +2 -2
  123. package/dist/{chunk-9hbwvcxn.js.map → chunk-qd2v93y4.js.map} +1 -1
  124. package/dist/{chunk-tyhrrnp5.js → chunk-rfcygmf5.js} +3 -3
  125. package/dist/{chunk-tyhrrnp5.js.map → chunk-rfcygmf5.js.map} +1 -1
  126. package/dist/{chunk-4rr9wmh8.js → chunk-s6jjy4y9.js} +2 -2
  127. package/dist/{chunk-4rr9wmh8.js.map → chunk-s6jjy4y9.js.map} +1 -1
  128. package/dist/{chunk-njkk498k.js → chunk-sq2wkynk.js} +2 -2
  129. package/dist/{chunk-njkk498k.js.map → chunk-sq2wkynk.js.map} +1 -1
  130. package/dist/{chunk-kda25fn4.js → chunk-td8tha3j.js} +3 -3
  131. package/dist/{chunk-kda25fn4.js.map → chunk-td8tha3j.js.map} +1 -1
  132. package/dist/{chunk-cfsscms3.js → chunk-tk5q8hkv.js} +4 -4
  133. package/dist/{chunk-cfsscms3.js.map → chunk-tk5q8hkv.js.map} +2 -2
  134. package/dist/{chunk-1npdp1w2.js → chunk-tq85n8zh.js} +2 -2
  135. package/dist/{chunk-1npdp1w2.js.map → chunk-tq85n8zh.js.map} +1 -1
  136. package/dist/{chunk-gqpge54c.js → chunk-twnn7r66.js} +2 -2
  137. package/dist/{chunk-gqpge54c.js.map → chunk-twnn7r66.js.map} +1 -1
  138. package/dist/chunk-w7jsh3xd.js +5 -0
  139. package/dist/{chunk-9jz4rggd.js.map → chunk-w7jsh3xd.js.map} +2 -2
  140. package/dist/{chunk-we2sj339.js → chunk-wsttx9rg.js} +2 -2
  141. package/dist/{chunk-we2sj339.js.map → chunk-wsttx9rg.js.map} +1 -1
  142. package/dist/{chunk-47rgq59q.js → chunk-wvsv1jgg.js} +2 -2
  143. package/dist/{chunk-47rgq59q.js.map → chunk-wvsv1jgg.js.map} +1 -1
  144. package/dist/chunk-x78jrs4y.js +4 -0
  145. package/dist/{chunk-ffagkj3x.js.map → chunk-x78jrs4y.js.map} +2 -2
  146. package/dist/chunk-xk930yaw.js +5 -0
  147. package/dist/{chunk-rn2kgbg4.js.map → chunk-xk930yaw.js.map} +2 -2
  148. package/dist/chunk-xkc7ftnq.js +9 -0
  149. package/dist/chunk-xkc7ftnq.js.map +10 -0
  150. package/dist/{chunk-564zfdd1.js → chunk-yer1r3t3.js} +2 -2
  151. package/dist/{chunk-564zfdd1.js.map → chunk-yer1r3t3.js.map} +1 -1
  152. package/dist/{chunk-v52dyw0q.js → chunk-yqavgpwd.js} +3 -3
  153. package/dist/{chunk-v52dyw0q.js.map → chunk-yqavgpwd.js.map} +1 -1
  154. package/dist/{chunk-hyfzw1fk.js → chunk-z10cas5r.js} +2 -2
  155. package/dist/{chunk-hyfzw1fk.js.map → chunk-z10cas5r.js.map} +1 -1
  156. package/dist/{chunk-h4x7cba0.js → chunk-zhs1r1z0.js} +3 -3
  157. package/dist/{chunk-h4x7cba0.js.map → chunk-zhs1r1z0.js.map} +1 -1
  158. package/dist/chunks/{ThemeProvider-Cqfwr6dk.js → ThemeProvider-BgLyzzOL.js} +8 -2
  159. package/dist/chunks/ThemeProvider-BgLyzzOL.js.map +1 -0
  160. package/dist/client/ClientRouterContext.d.ts.map +1 -1
  161. package/dist/client/ServerDataProvider.d.ts +2 -0
  162. package/dist/client/ServerDataProvider.d.ts.map +1 -1
  163. package/dist/client/createRoot.d.ts.map +1 -1
  164. package/dist/client/index.d.ts +2 -0
  165. package/dist/client/index.d.ts.map +1 -1
  166. package/dist/client/index.js +127 -4
  167. package/dist/client/index.js.map +1 -1
  168. package/dist/client/islands.d.ts +127 -0
  169. package/dist/client/islands.d.ts.map +1 -0
  170. package/dist/config/index.d.ts +8 -1
  171. package/dist/config/index.d.ts.map +1 -1
  172. package/dist/config/index.js +1 -1
  173. package/dist/config/index.js.map +2 -2
  174. package/dist/console/run.js +2 -2
  175. package/dist/console/run.js.map +1 -1
  176. package/dist/container/index.js +2 -2
  177. package/dist/container/index.js.map +1 -1
  178. package/dist/database/index.js +2 -2
  179. package/dist/database/index.js.map +1 -1
  180. package/dist/email/index.js +2 -2
  181. package/dist/email/index.js.map +1 -1
  182. package/dist/facades/Lang.d.ts +7 -1
  183. package/dist/facades/Lang.d.ts.map +1 -1
  184. package/dist/facades/index.js +2 -2
  185. package/dist/facades/index.js.map +1 -1
  186. package/dist/foundation/index.js +2 -2
  187. package/dist/foundation/index.js.map +1 -1
  188. package/dist/http/CorsMiddleware.d.ts +13 -0
  189. package/dist/http/CorsMiddleware.d.ts.map +1 -1
  190. package/dist/http/Middleware.d.ts +11 -0
  191. package/dist/http/Middleware.d.ts.map +1 -1
  192. package/dist/http/ViewRouter.d.ts +67 -0
  193. package/dist/http/ViewRouter.d.ts.map +1 -1
  194. package/dist/http/index.d.ts +1 -1
  195. package/dist/http/index.d.ts.map +1 -1
  196. package/dist/http/index.js +2 -2
  197. package/dist/http/index.js.map +1 -1
  198. package/dist/i18n/dictionaryRuntime.js +2 -2
  199. package/dist/i18n/dictionaryRuntime.js.map +1 -1
  200. package/dist/i18n/index.js +2 -2
  201. package/dist/i18n/index.js.map +1 -1
  202. package/dist/internal/islandRuntime.d.ts +45 -0
  203. package/dist/internal/islandRuntime.d.ts.map +1 -0
  204. package/dist/kernel/index.js +2 -2
  205. package/dist/kernel/index.js.map +1 -1
  206. package/dist/orm/context.d.ts +24 -0
  207. package/dist/orm/context.d.ts.map +1 -1
  208. package/dist/orm/index.d.ts +1 -1
  209. package/dist/orm/index.d.ts.map +1 -1
  210. package/dist/orm/index.js +3 -3
  211. package/dist/orm/index.js.map +2 -2
  212. package/dist/server/devFetch.d.ts.map +1 -1
  213. package/dist/server/httpDev.d.ts.map +1 -1
  214. package/dist/server/httpProd.d.ts.map +1 -1
  215. package/dist/server/idleTimeout.d.ts +24 -0
  216. package/dist/server/idleTimeout.d.ts.map +1 -0
  217. package/dist/server/index.js +2 -2
  218. package/dist/server/index.js.map +1 -1
  219. package/dist/server/modulePreloads.d.ts +18 -0
  220. package/dist/server/modulePreloads.d.ts.map +1 -1
  221. package/dist/server/styles.d.ts +3 -1
  222. package/dist/server/styles.d.ts.map +1 -1
  223. package/dist/services/index.d.ts +1 -0
  224. package/dist/services/index.d.ts.map +1 -1
  225. package/dist/services/index.js +3 -3
  226. package/dist/services/index.js.map +2 -2
  227. package/dist/services/middleware/MiddlewareRegistry.d.ts +13 -2
  228. package/dist/services/middleware/MiddlewareRegistry.d.ts.map +1 -1
  229. package/dist/services/queue/work.js +2 -2
  230. package/dist/services/queue/work.js.map +1 -1
  231. package/dist/services/router/DomainRouter.d.ts +10 -0
  232. package/dist/services/router/DomainRouter.d.ts.map +1 -1
  233. package/dist/services/router/ViewRouteDispatcher.d.ts +30 -2
  234. package/dist/services/router/ViewRouteDispatcher.d.ts.map +1 -1
  235. package/dist/services/router/createFlatViewRoutes.d.ts +13 -1
  236. package/dist/services/router/createFlatViewRoutes.d.ts.map +1 -1
  237. package/dist/services/router/staticCache.d.ts +23 -0
  238. package/dist/services/router/staticCache.d.ts.map +1 -0
  239. package/dist/services/router/staticDocument.d.ts +66 -0
  240. package/dist/services/router/staticDocument.d.ts.map +1 -0
  241. package/dist/stats/bundleStats.d.ts +104 -0
  242. package/dist/stats/bundleStats.d.ts.map +1 -0
  243. package/dist/stats/route-table.d.ts +2 -0
  244. package/dist/stats/route-table.d.ts.map +1 -0
  245. package/dist/stats/route-table.js +4 -0
  246. package/dist/stats/route-table.js.map +11 -0
  247. package/dist/stats/routeTable.d.ts +25 -0
  248. package/dist/stats/routeTable.d.ts.map +1 -0
  249. package/dist/stats/run.d.ts +43 -0
  250. package/dist/stats/run.d.ts.map +1 -0
  251. package/dist/support/index.js +2 -2
  252. package/dist/support/index.js.map +1 -1
  253. package/dist/testing/index.js +1 -1
  254. package/dist/vite/index.mjs +173 -2
  255. package/dist/vitest/index.d.ts +18 -0
  256. package/dist/vitest/index.d.ts.map +1 -1
  257. package/dist/vitest/index.js +2 -2
  258. package/dist/vitest/index.js.map +3 -3
  259. package/package.json +2 -1
  260. package/dist/chunk-9jz4rggd.js +0 -5
  261. package/dist/chunk-b9av1sgb.js +0 -58
  262. package/dist/chunk-b9av1sgb.js.map +0 -14
  263. package/dist/chunk-cewyag0d.js +0 -6
  264. package/dist/chunk-cewyag0d.js.map +0 -11
  265. package/dist/chunk-ffagkj3x.js +0 -4
  266. package/dist/chunk-h2hdpm70.js +0 -24
  267. package/dist/chunk-h3t4n0bn.js +0 -5
  268. package/dist/chunk-hdhahvd4.js +0 -4
  269. package/dist/chunk-k9qmr2wa.js +0 -9
  270. package/dist/chunk-k9qmr2wa.js.map +0 -10
  271. package/dist/chunk-mrvcaakf.js +0 -5
  272. package/dist/chunk-ncfxmtd5.js +0 -17
  273. package/dist/chunk-q2fyp44f.js +0 -4
  274. package/dist/chunk-q7y9v2v5.js +0 -18
  275. package/dist/chunk-rn2kgbg4.js +0 -5
  276. package/dist/chunk-vj2t77x1.js +0 -4
  277. package/dist/chunks/ThemeProvider-Cqfwr6dk.js.map +0 -1
  278. /package/dist/{chunk-xg9vye7c.js.map → chunk-0sjh5v1n.js.map} +0 -0
  279. /package/dist/{chunk-anp4kv3w.js.map → chunk-8b2tw2yp.js.map} +0 -0
  280. /package/dist/{chunk-2xqrh6d0.js.map → chunk-et4pv1b1.js.map} +0 -0
package/dist/bin/gemi.js CHANGED
@@ -35956,7 +35956,7 @@ function camelCase(text) {
35956
35956
 
35957
35957
  // bin/ai-client/extract.ts
35958
35958
  import { createRequire } from "module";
35959
- import path7 from "path";
35959
+ import path8 from "path";
35960
35960
  function parseAgentReference(reference) {
35961
35961
  const hash = reference.lastIndexOf("#");
35962
35962
  if (hash === -1)
@@ -35970,7 +35970,7 @@ function parseAgentReference(reference) {
35970
35970
  }
35971
35971
  async function loadTypeScript(cwd) {
35972
35972
  try {
35973
- return createRequire(path7.join(cwd, "package.json"))("typescript");
35973
+ return createRequire(path8.join(cwd, "package.json"))("typescript");
35974
35974
  } catch {
35975
35975
  try {
35976
35976
  return (await import("typescript")).default;
@@ -35980,7 +35980,7 @@ async function loadTypeScript(cwd) {
35980
35980
  }
35981
35981
  }
35982
35982
  function extractAgent(ts, reference, { cwd = process.cwd(), name } = {}) {
35983
- const file = path7.resolve(cwd, reference.file);
35983
+ const file = path8.resolve(cwd, reference.file);
35984
35984
  if (!ts.sys.fileExists(file)) {
35985
35985
  throw new GenerateClientError(`${reference.file} does not exist.`);
35986
35986
  }
@@ -35992,7 +35992,7 @@ function extractAgent(ts, reference, { cwd = process.cwd(), name } = {}) {
35992
35992
  if (agentType.getSymbol()?.getName() !== "Agent" || !agentFile) {
35993
35993
  throw new GenerateClientError(`${reference.file}#${reference.exportName} is not an Agent \u2014 it is ` + `\`${checker.typeToString(agentType)}\`. Point at the value \`Agent.create(...)\` returned.`);
35994
35994
  }
35995
- const probe = path7.join(path7.dirname(file), `__gemi_generate_client_${process.pid}.ts`);
35995
+ const probe = path8.join(path8.dirname(file), `__gemi_generate_client_${process.pid}.ts`);
35996
35996
  const source = [
35997
35997
  `import type { OutputOf, ToolShapesOf } from ${JSON.stringify(specifier(probe, agentFile))};`,
35998
35998
  `import type * as agentModule from ${JSON.stringify(specifier(probe, file))};`,
@@ -36013,7 +36013,7 @@ function extractAgent(ts, reference, { cwd = process.cwd(), name } = {}) {
36013
36013
  return second.getTypeChecker().getTypeAtLocation(declaration.name);
36014
36014
  };
36015
36015
  const mapper = new TypeMapper(ts, second.getTypeChecker());
36016
- const agentName = name ?? pascalCase(exported === "default" ? path7.parse(file).name : exported);
36016
+ const agentName = name ?? pascalCase(exported === "default" ? path8.parse(file).name : exported);
36017
36017
  const toolsType = alias("Tools");
36018
36018
  const tools = mapper.checker.getPropertiesOfType(toolsType).map((tool) => {
36019
36019
  const shape = mapper.checker.getTypeOfSymbol(tool);
@@ -36029,7 +36029,7 @@ function extractAgent(ts, reference, { cwd = process.cwd(), name } = {}) {
36029
36029
  const output = mapper.map(alias("Output"), "StructuredOutput", "the agent's output");
36030
36030
  return {
36031
36031
  name: agentName,
36032
- source: `${path7.relative(cwd, file).split(path7.sep).join("/")}#${reference.exportName}`,
36032
+ source: `${path8.relative(cwd, file).split(path8.sep).join("/")}#${reference.exportName}`,
36033
36033
  tools,
36034
36034
  output,
36035
36035
  types: mapper.types,
@@ -36037,7 +36037,7 @@ function extractAgent(ts, reference, { cwd = process.cwd(), name } = {}) {
36037
36037
  };
36038
36038
  }
36039
36039
  function compilerOptions(ts, file) {
36040
- const configPath = ts.findConfigFile(path7.dirname(file), ts.sys.fileExists);
36040
+ const configPath = ts.findConfigFile(path8.dirname(file), ts.sys.fileExists);
36041
36041
  let options = {
36042
36042
  target: ts.ScriptTarget.ESNext,
36043
36043
  module: ts.ModuleKind.ESNext,
@@ -36045,7 +36045,7 @@ function compilerOptions(ts, file) {
36045
36045
  };
36046
36046
  if (configPath) {
36047
36047
  const config = ts.readConfigFile(configPath, ts.sys.readFile);
36048
- options = ts.parseJsonConfigFileContent(config.config, ts.sys, path7.dirname(configPath)).options;
36048
+ options = ts.parseJsonConfigFileContent(config.config, ts.sys, path8.dirname(configPath)).options;
36049
36049
  }
36050
36050
  return {
36051
36051
  ...options,
@@ -36067,8 +36067,8 @@ function exportedType(ts, checker, sourceFile, reference) {
36067
36067
  return { type: checker.getTypeOfSymbolAtLocation(symbol, sourceFile), name: symbol.getName() };
36068
36068
  }
36069
36069
  function specifier(from, to) {
36070
- const relative4 = path7.relative(path7.dirname(from), to).split(path7.sep).join("/").replace(/(\.d)?\.(ts|tsx|mts|cts)$/, "");
36071
- return relative4.startsWith(".") ? relative4 : `./${relative4}`;
36070
+ const relative5 = path8.relative(path8.dirname(from), to).split(path8.sep).join("/").replace(/(\.d)?\.(ts|tsx|mts|cts)$/, "");
36071
+ return relative5.startsWith(".") ? relative5 : `./${relative5}`;
36072
36072
  }
36073
36073
  function isFrameworkJsonValue(type) {
36074
36074
  const alias = type.aliasSymbol;
@@ -36687,8 +36687,8 @@ __export(exports_generate, {
36687
36687
  PLATFORMS: () => PLATFORMS,
36688
36688
  GenerateClientError: () => GenerateClientError
36689
36689
  });
36690
- import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync3 } from "fs";
36691
- import path8 from "path";
36690
+ import { mkdirSync as mkdirSync3, writeFileSync as writeFileSync4 } from "fs";
36691
+ import path9 from "path";
36692
36692
  async function generateClient(options) {
36693
36693
  const cwd = options.cwd ?? process.cwd();
36694
36694
  const platform = parsePlatform(options.platform);
@@ -36701,10 +36701,10 @@ async function generateClient(options) {
36701
36701
  }
36702
36702
  const ts = await loadTypeScript(cwd);
36703
36703
  const model = extractAgent(ts, parseAgentReference(options.agent), { cwd, name: options.name });
36704
- const directory = path8.resolve(cwd, options.out);
36705
- const file = path8.join(directory, `${model.name}.${platform === "swift" ? "swift" : "kt"}`);
36704
+ const directory = path9.resolve(cwd, options.out);
36705
+ const file = path9.join(directory, `${model.name}.${platform === "swift" ? "swift" : "kt"}`);
36706
36706
  mkdirSync3(directory, { recursive: true });
36707
- writeFileSync3(file, platform === "swift" ? renderSwift(model) : renderKotlin(model, options.package));
36707
+ writeFileSync4(file, platform === "swift" ? renderSwift(model) : renderKotlin(model, options.package));
36708
36708
  const warnings = [...model.warnings];
36709
36709
  if (platform === "swift" && options.package) {
36710
36710
  warnings.push("--package is for Kotlin; a Swift file has no package, so it was ignored.");
@@ -36726,10 +36726,10 @@ var init_generate = __esm(() => {
36726
36726
  });
36727
36727
 
36728
36728
  // bin/gemi.ts
36729
- import path9 from "path";
36730
- import { existsSync as existsSync8 } from "fs";
36729
+ import path10 from "path";
36730
+ import { existsSync as existsSync10 } from "fs";
36731
36731
  import { mkdtemp, rm } from "fs/promises";
36732
- import { tmpdir } from "os";
36732
+ import { tmpdir as tmpdir2 } from "os";
36733
36733
 
36734
36734
  // bin/createRollupInput.ts
36735
36735
  var {Glob } = globalThis.Bun;
@@ -40088,6 +40088,128 @@ function documentBase(base) {
40088
40088
  return base.startsWith("/") || /^[a-z][a-z\d+.-]*:\/\//i.test(base) ? normalizeAssetBase(base) : DEFAULT_ASSET_BASE;
40089
40089
  }
40090
40090
 
40091
+ // vite/islandPlugin.ts
40092
+ import { realpathSync } from "fs";
40093
+ import { relative, sep } from "path";
40094
+
40095
+ // internal/islandRuntime.ts
40096
+ var ISLAND_RUNTIME_ID = "virtual:gemi-island-runtime";
40097
+ var RESOLVED_ISLAND_RUNTIME_ID = `\x00${ISLAND_RUNTIME_ID}`;
40098
+ var ISLAND_ENTRY_QUERY = "?gemi-island";
40099
+ function islandEntrySource(file) {
40100
+ return `import * as m from ${JSON.stringify(file)};
40101
+ export { m };
40102
+ export { h } from ${JSON.stringify(ISLAND_RUNTIME_ID)};
40103
+ `;
40104
+ }
40105
+ var ISLAND_HYDRATE_SOURCE = `function h(marker, Component) {
40106
+ if (typeof Component !== "function" && (typeof Component !== "object" || Component === null)) {
40107
+ throw new Error("gemi: island module has no component export for " + marker.outerHTML.slice(0, 80));
40108
+ }
40109
+ const json = marker.getAttribute("data-props");
40110
+ const props = json ? JSON.parse(json) : {};
40111
+ let slot = null;
40112
+ for (const candidate of marker.querySelectorAll("gemi-slot")) {
40113
+ if (candidate.closest("gemi-island") === marker) {
40114
+ slot = candidate;
40115
+ break;
40116
+ }
40117
+ }
40118
+ const children = slot
40119
+ ? [createElement("gemi-slot", {
40120
+ style: { display: "contents" },
40121
+ suppressHydrationWarning: true,
40122
+ dangerouslySetInnerHTML: { __html: slot.innerHTML },
40123
+ })]
40124
+ : [];
40125
+ return hydrateRoot(marker, createElement(Component, props, ...children), {
40126
+ identifierPrefix: marker.getAttribute("data-uid") || undefined,
40127
+ });
40128
+ }`;
40129
+ var ISLAND_RUNTIME_SOURCE = `import { createElement } from "react";
40130
+ import { hydrateRoot } from "react-dom/client";
40131
+ export ${ISLAND_HYDRATE_SOURCE}
40132
+ `;
40133
+
40134
+ // vite/islandPlugin.ts
40135
+ var ISLAND_CALL = /\bisland\s*\(\s*(\(\s*\)\s*=>\s*import\(\s*(["'])([^"'\n]+)\2\s*\))/g;
40136
+ function realPath(path3) {
40137
+ try {
40138
+ return realpathSync(path3);
40139
+ } catch {
40140
+ return path3;
40141
+ }
40142
+ }
40143
+ function gemiIslandPlugin() {
40144
+ let root = process.cwd();
40145
+ let clientBuild = false;
40146
+ const emitted = new Set;
40147
+ return {
40148
+ name: "gemi-plugin-islands",
40149
+ enforce: "pre",
40150
+ configResolved(config) {
40151
+ root = realPath(config.root);
40152
+ clientBuild = config.command === "build" && !config.build.ssr;
40153
+ },
40154
+ buildStart() {
40155
+ emitted.clear();
40156
+ },
40157
+ resolveId(id) {
40158
+ return id === ISLAND_RUNTIME_ID ? RESOLVED_ISLAND_RUNTIME_ID : null;
40159
+ },
40160
+ load(id) {
40161
+ if (id === RESOLVED_ISLAND_RUNTIME_ID)
40162
+ return ISLAND_RUNTIME_SOURCE;
40163
+ if (id.endsWith(ISLAND_ENTRY_QUERY)) {
40164
+ return islandEntrySource(id.slice(0, -ISLAND_ENTRY_QUERY.length));
40165
+ }
40166
+ return null;
40167
+ },
40168
+ async transform(code, id) {
40169
+ if (id.includes("/node_modules/") || id.startsWith("\x00") || id.endsWith(ISLAND_ENTRY_QUERY)) {
40170
+ return null;
40171
+ }
40172
+ if (!/\.[cm]?[jt]sx?$/.test(id.split("?")[0]))
40173
+ return null;
40174
+ if (!code.includes("island"))
40175
+ return null;
40176
+ const environmentConsumer = this.environment?.config?.consumer;
40177
+ const emitEntries = clientBuild && (environmentConsumer === undefined || environmentConsumer === "client");
40178
+ const s = new MagicString(code);
40179
+ const imports = [];
40180
+ for (const match of code.matchAll(ISLAND_CALL)) {
40181
+ const [, loader, quote, specifier] = match;
40182
+ const resolved = await this.resolve(specifier, id);
40183
+ if (!resolved || resolved.external)
40184
+ continue;
40185
+ const file = realPath(resolved.id.split("?")[0]);
40186
+ const key = relative(root, file).split(sep).join("/");
40187
+ if (key.startsWith(".."))
40188
+ continue;
40189
+ const name = `__gemi_island_${imports.length}`;
40190
+ imports.push(`import * as ${name} from ${quote}${specifier}${quote};`);
40191
+ const start = match.index + match[0].length - loader.length;
40192
+ s.overwrite(start, start + loader.length, `Object.assign(() => Promise.resolve(${name}), { gemiIsland: ${JSON.stringify(key)}, gemiModule: ${name} })`);
40193
+ const moduleId = resolved.id.split("?")[0];
40194
+ if (emitEntries && !emitted.has(moduleId)) {
40195
+ emitted.add(moduleId);
40196
+ this.emitFile({
40197
+ type: "chunk",
40198
+ id: `${moduleId}${ISLAND_ENTRY_QUERY}`,
40199
+ preserveSignature: "strict"
40200
+ });
40201
+ }
40202
+ }
40203
+ if (imports.length === 0)
40204
+ return null;
40205
+ s.prepend(`${imports.join(`
40206
+ `)}
40207
+ `);
40208
+ return { code: s.toString(), map: s.generateMap({ hires: true }) };
40209
+ }
40210
+ };
40211
+ }
40212
+
40091
40213
  // vite/index.ts
40092
40214
  var gemi = async () => {
40093
40215
  const userConfig = await loadGemiConfig(process.cwd());
@@ -40124,6 +40246,7 @@ var gemi = async () => {
40124
40246
  config: () => userViteConfig
40125
40247
  },
40126
40248
  gemiAssetBasePlugin(assetBase),
40249
+ gemiIslandPlugin(),
40127
40250
  {
40128
40251
  name: "gemi-plugin-hot-reload",
40129
40252
  handleHotUpdate({ server, modules }) {
@@ -40140,7 +40263,7 @@ var vite_default = gemi;
40140
40263
 
40141
40264
  // vite/previousAssets.ts
40142
40265
  import { copyFile, lstat, mkdir as mkdir2, readdir, readFile, stat, writeFile as writeFile2 } from "fs/promises";
40143
- import { dirname as dirname2, isAbsolute, join as join4, relative, resolve, sep } from "path";
40266
+ import { dirname as dirname2, isAbsolute, join as join4, relative as relative2, resolve, sep as sep2 } from "path";
40144
40267
  var PREVIOUS_ASSETS_RECORD = ".vite/previous-assets.json";
40145
40268
  var DEFAULT_RETAINED_RELEASES = 2;
40146
40269
  var DEFAULT_RETAINED_MAX_AGE_SECONDS = 7 * 24 * 60 * 60;
@@ -40274,8 +40397,8 @@ function isCarriable(file) {
40274
40397
  }
40275
40398
  function inside(root, file) {
40276
40399
  const path3 = resolve(root, file);
40277
- const rel2 = relative(root, path3);
40278
- return rel2 && !rel2.startsWith("..") && !isAbsolute(rel2) && rel2.split(sep)[0] === ASSETS_DIR ? path3 : null;
40400
+ const rel2 = relative2(root, path3);
40401
+ return rel2 && !rel2.startsWith("..") && !isAbsolute(rel2) && rel2.split(sep2)[0] === ASSETS_DIR ? path3 : null;
40279
40402
  }
40280
40403
  async function isDirectory(path3) {
40281
40404
  try {
@@ -40427,15 +40550,15 @@ var {
40427
40550
 
40428
40551
  // bin/check-models.ts
40429
40552
  import { statSync as statSync2 } from "fs";
40430
- import { relative as relative3, resolve as resolve2 } from "path";
40553
+ import { relative as relative4, resolve as resolve2 } from "path";
40431
40554
 
40432
40555
  // support/discover.ts
40433
40556
  import { existsSync as existsSync3, readdirSync as readdirSync2 } from "fs";
40434
- import { join as join6, relative as relative2 } from "path";
40557
+ import { join as join6, relative as relative3 } from "path";
40435
40558
  function sourceFiles(dir, ignore = []) {
40436
40559
  const out = [];
40437
40560
  const ignored = (path3) => {
40438
- const rel2 = relative2(dir, path3).split("\\").join("/");
40561
+ const rel2 = relative3(dir, path3).split("\\").join("/");
40439
40562
  return ignore.some((pattern) => rel2 === pattern || rel2.startsWith(`${pattern}/`));
40440
40563
  };
40441
40564
  const walk3 = (current) => {
@@ -40539,7 +40662,7 @@ async function declaredModules(rootDir) {
40539
40662
  try {
40540
40663
  ({ default: Kernel } = await import(path3));
40541
40664
  } catch (error) {
40542
- throw new CheckModelsError(`Could not load ${relative3(rootDir, path3)}:
40665
+ throw new CheckModelsError(`Could not load ${relative4(rootDir, path3)}:
40543
40666
  ${error.message}`);
40544
40667
  }
40545
40668
  return new Kernel().models ?? [];
@@ -40592,8 +40715,8 @@ ${error.message}`);
40592
40715
  const paths = modelFiles(modelsDir, ignore);
40593
40716
  const files = [];
40594
40717
  for (const path3 of paths) {
40595
- const label = relative3(rootDir, path3);
40596
- const specifier = `./${relative3(modelsDir, path3).split("\\").join("/").replace(/\.tsx?$/, "")}`;
40718
+ const label = relative4(rootDir, path3);
40719
+ const specifier = `./${relative4(modelsDir, path3).split("\\").join("/").replace(/\.tsx?$/, "")}`;
40597
40720
  try {
40598
40721
  files.push({
40599
40722
  label,
@@ -41126,11 +41249,11 @@ function hashDirectory(dir) {
41126
41249
  const entries = readdirSync3(current, { withFileTypes: true }).sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
41127
41250
  for (const entry of entries) {
41128
41251
  const full = path5.join(current, entry.name);
41129
- const relative4 = prefix ? `${prefix}/${entry.name}` : entry.name;
41252
+ const relative5 = prefix ? `${prefix}/${entry.name}` : entry.name;
41130
41253
  if (entry.isDirectory()) {
41131
- walk3(full, relative4);
41254
+ walk3(full, relative5);
41132
41255
  } else if (entry.isFile()) {
41133
- hash.update(relative4);
41256
+ hash.update(relative5);
41134
41257
  hash.update("\x00");
41135
41258
  hash.update(readFileSync3(full));
41136
41259
  hash.update("\x00");
@@ -41427,15 +41550,350 @@ function exitCodeOf(proc) {
41427
41550
  return signal ? 128 + signal : 1;
41428
41551
  }
41429
41552
 
41553
+ // stats/run.ts
41554
+ import path7 from "path";
41555
+ import { existsSync as existsSync9, mkdtempSync, readFileSync as readFileSync6, rmSync as rmSync3, writeFileSync as writeFileSync3 } from "fs";
41556
+ import { tmpdir } from "os";
41557
+
41558
+ // stats/bundleStats.ts
41559
+ import { existsSync as existsSync8, readFileSync as readFileSync5, statSync as statSync3 } from "fs";
41560
+ import { join as join8 } from "path";
41561
+ import { brotliCompressSync, constants as constants3, gzipSync } from "zlib";
41562
+
41563
+ // server/modulePreloads.ts
41564
+ var CLIENT_ENTRY_KEY = "app/client.tsx";
41565
+
41566
+ // stats/bundleStats.ts
41567
+ var VIEW_PREFIX = "app/views/";
41568
+ var VIEW_EXTENSIONS = [".tsx", ".ts", ".jsx", ".js"];
41569
+ var ROOT_LAYOUT = "RootLayout";
41570
+ var ZERO = { raw: 0, gzip: 0, brotli: 0 };
41571
+ var add = (a, b) => ({
41572
+ raw: a.raw + b.raw,
41573
+ gzip: a.gzip + b.gzip,
41574
+ brotli: a.brotli + b.brotli
41575
+ });
41576
+ function chunkName(file) {
41577
+ return file.replace(/^.*\//, "").replace(/-[\w-]{8}(?=\.\w+$)/, "");
41578
+ }
41579
+ function routeKey(entry) {
41580
+ return entry.group ? `${entry.group}:${entry.path}` : entry.path;
41581
+ }
41582
+ function bundleStats(options) {
41583
+ const { clientDir } = options;
41584
+ const manifest = options.manifest ?? JSON.parse(readFileSync5(join8(clientDir, ".vite/manifest.json"), "utf8"));
41585
+ const sizes = new Map;
41586
+ const size = (file) => {
41587
+ let known = sizes.get(file);
41588
+ if (!known)
41589
+ sizes.set(file, known = measure(clientDir, file));
41590
+ return known;
41591
+ };
41592
+ const sum = (files) => [...files].map(size).reduce(add, ZERO);
41593
+ const closure = (key, seen = new Set) => {
41594
+ if (seen.has(key) || !manifest[key])
41595
+ return seen;
41596
+ seen.add(key);
41597
+ for (const imported of manifest[key].imports ?? [])
41598
+ closure(imported, seen);
41599
+ return seen;
41600
+ };
41601
+ const jsFiles = (keys) => [...new Set([...keys].map((key) => manifest[key].file))].filter(isJs).sort();
41602
+ const islandEntries = Object.keys(manifest).filter(isIslandEntry).sort();
41603
+ const shared = closure(CLIENT_ENTRY_KEY);
41604
+ for (const [key, chunk] of Object.entries(manifest)) {
41605
+ if (key.includes(ISLAND_RUNTIME_NAME) || chunk.name?.includes(ISLAND_RUNTIME_NAME))
41606
+ closure(key, shared);
41607
+ }
41608
+ const islandModules = new Map(islandEntries.map((entry) => [
41609
+ entry,
41610
+ (manifest[entry].imports ?? []).filter((imported) => !shared.has(imported))
41611
+ ]));
41612
+ const islandsBelow = (keys) => {
41613
+ const seen = new Set;
41614
+ const walk3 = (at) => {
41615
+ if (seen.has(at) || !manifest[at] || isIslandEntry(at))
41616
+ return;
41617
+ seen.add(at);
41618
+ for (const next of [...manifest[at].imports ?? [], ...manifest[at].dynamicImports ?? []])
41619
+ walk3(next);
41620
+ };
41621
+ for (const key of keys)
41622
+ walk3(key);
41623
+ return islandEntries.filter((entry) => islandModules.get(entry).some((module) => seen.has(module)));
41624
+ };
41625
+ const viewKey = (view) => VIEW_EXTENSIONS.map((ext) => `${VIEW_PREFIX}${view}${ext}`).find((key) => manifest[key]);
41626
+ const hydrated = (views) => {
41627
+ const keys = closure(CLIENT_ENTRY_KEY);
41628
+ for (const view of views) {
41629
+ const key = viewKey(view);
41630
+ if (key)
41631
+ closure(key, keys);
41632
+ }
41633
+ const files = jsFiles(keys);
41634
+ return { ...sum(files), views, chunks: files.map(chunkName) };
41635
+ };
41636
+ const staticRoute = (views, layout) => {
41637
+ const roots = [layout ?? ROOT_LAYOUT, ...views].map(viewKey).filter((key) => Boolean(key));
41638
+ const islands2 = islandsBelow(roots);
41639
+ const keys = new Set;
41640
+ for (const island of islands2)
41641
+ closure(island, keys);
41642
+ const files = jsFiles(keys);
41643
+ return { ...sum(files), views, static: true, islands: islands2, chunks: files.map(chunkName) };
41644
+ };
41645
+ const routes = {};
41646
+ if (options.routes) {
41647
+ for (const entry of options.routes) {
41648
+ routes[routeKey(entry)] = entry.static ? staticRoute(entry.views, entry.static.layout) : hydrated(entry.views);
41649
+ }
41650
+ } else {
41651
+ for (const [key, chunk] of Object.entries(manifest)) {
41652
+ if (!chunk.isEntry || !key.startsWith(VIEW_PREFIX) || isIslandEntry(key))
41653
+ continue;
41654
+ const view = key.slice(VIEW_PREFIX.length).replace(/\.[jt]sx?$/, "");
41655
+ routes[view] = hydrated([view]);
41656
+ }
41657
+ }
41658
+ const islands = {};
41659
+ for (const key of islandEntries) {
41660
+ const files = jsFiles(closure(key));
41661
+ islands[key] = { ...sum(files), chunks: files.map(chunkName) };
41662
+ }
41663
+ const chunks = {};
41664
+ const allFiles = [...new Set(Object.values(manifest).map((chunk) => chunk.file))];
41665
+ for (const file of allFiles.filter(isJs).sort()) {
41666
+ const name = chunkName(file);
41667
+ let unique = name;
41668
+ for (let n2 = 2;chunks[unique]; n2++)
41669
+ unique = `${name}~${n2}`;
41670
+ chunks[unique] = size(file);
41671
+ }
41672
+ const css = new Set(Object.values(manifest).flatMap((chunk) => chunk.css ?? []));
41673
+ return {
41674
+ version: 1,
41675
+ by: options.routes ? "routes" : "views",
41676
+ routes,
41677
+ islands,
41678
+ chunks,
41679
+ css: sum(css)
41680
+ };
41681
+ }
41682
+ var ISLAND_RUNTIME_NAME = "gemi-island-runtime";
41683
+ function isIslandEntry(key) {
41684
+ return key.endsWith(ISLAND_ENTRY_QUERY);
41685
+ }
41686
+ function isJs(file) {
41687
+ return /\.m?js$/.test(file);
41688
+ }
41689
+ function measure(clientDir, file) {
41690
+ const path7 = join8(clientDir, file);
41691
+ const sibling = (ext) => existsSync8(path7 + ext) ? statSync3(path7 + ext).size : null;
41692
+ let buffer;
41693
+ const read = () => buffer ??= readFileSync5(path7);
41694
+ return {
41695
+ raw: statSync3(path7).size,
41696
+ gzip: sibling(".gz") ?? gzipSync(read(), { level: 9 }).length,
41697
+ brotli: sibling(".br") ?? brotliCompressSync(read(), {
41698
+ params: { [constants3.BROTLI_PARAM_QUALITY]: 11 }
41699
+ }).length
41700
+ };
41701
+ }
41702
+ var kb = (bytes) => bytes / 1024;
41703
+ var format = (bytes) => kb(bytes).toFixed(1);
41704
+ var signed = (bytes) => `${bytes > 0 ? "+" : ""}${format(bytes)}`;
41705
+ function budgetFor(key, route, budgets) {
41706
+ if (!budgets)
41707
+ return;
41708
+ const page = route.views.at(-1);
41709
+ return budgets.routes?.[key] ?? (page ? budgets.routes?.[page] : undefined) ?? budgets.default;
41710
+ }
41711
+ function overBudget(stats, budgets) {
41712
+ if (!budgets)
41713
+ return [];
41714
+ const unit = budgets.unit ?? "gzip";
41715
+ return Object.entries(stats.routes).flatMap(([key, route]) => {
41716
+ const budget = budgetFor(key, route, budgets);
41717
+ return budget !== undefined && kb(route[unit]) > budget ? [`${key}: ${format(route[unit])} KB ${unit} is over its budget of ${budget} KB`] : [];
41718
+ });
41719
+ }
41720
+ function unusedBudgets(stats, budgets) {
41721
+ const keys = Object.keys(budgets?.routes ?? {});
41722
+ const known = new Set(Object.keys(stats.routes));
41723
+ for (const route of Object.values(stats.routes)) {
41724
+ const page = route.views.at(-1);
41725
+ if (page)
41726
+ known.add(page);
41727
+ }
41728
+ return keys.filter((key) => !known.has(key));
41729
+ }
41730
+ var NOISE_KB = 2;
41731
+ var byGzip = (stats) => Object.keys(stats.routes).sort((a, b) => stats.routes[b].gzip - stats.routes[a].gzip);
41732
+ function markdownReport(stats, base, budgets) {
41733
+ const unit = budgets?.unit ?? "gzip";
41734
+ const lines = [
41735
+ `| Route | ${unit} KB | \u0394 gzip | \u0394 raw | \u0394 brotli | budget |`,
41736
+ "|---|---:|---:|---:|---:|---:|"
41737
+ ];
41738
+ for (const key of byGzip(stats)) {
41739
+ const now = stats.routes[key];
41740
+ const before = base?.routes[key];
41741
+ const delta = (size) => before ? signed(now[size] - before[size]) : base ? "new" : "\u2013";
41742
+ const budget = budgetFor(key, now, budgets);
41743
+ const flag = budget !== undefined && kb(now[unit]) > budget ? " \u274C" : before && kb(now.gzip - before.gzip) > NOISE_KB ? " \u26A0\uFE0F" : "";
41744
+ const kind = now.static ? " (static)" : "";
41745
+ lines.push(`| \`${key}\`${kind}${flag} | ${format(now[unit])} | ${delta("gzip")} | ${delta("raw")} | ${delta("brotli")} | ${budget ?? ""} |`);
41746
+ }
41747
+ if (base) {
41748
+ const removedRoutes = Object.keys(base.routes).filter((key) => !stats.routes[key]);
41749
+ if (removedRoutes.length) {
41750
+ lines.push("", `**Removed routes:** ${removedRoutes.map((key) => `\`${key}\``).join(", ")}`);
41751
+ }
41752
+ const added = Object.keys(stats.chunks).filter((name) => !base.chunks[name]);
41753
+ const removed = Object.keys(base.chunks).filter((name) => !stats.chunks[name]);
41754
+ const changed = Object.keys(stats.chunks).filter((name) => base.chunks[name] && kb(Math.abs(stats.chunks[name].gzip - base.chunks[name].gzip)) > 0.5);
41755
+ const list = (names, describe) => names.length ? names.map((name) => `\`${name}\` ${describe(name)}`).join(", ") : "none";
41756
+ lines.push("", `**New chunks:** ${list(added, (name) => `(${format(stats.chunks[name].gzip)} KB gzip)`)}`, `**Removed chunks:** ${list(removed, (name) => `(${format(base.chunks[name].gzip)} KB gzip)`)}`, `**Changed chunks (> 0.5 KB gzip):** ${list(changed, (name) => `(${signed(stats.chunks[name].gzip - base.chunks[name].gzip)} KB gzip)`)}`, `**CSS:** ${format(stats.css.gzip)} KB gzip (${signed(stats.css.gzip - base.css.gzip)})`);
41757
+ }
41758
+ return lines.join(`
41759
+ `);
41760
+ }
41761
+ function textReport(stats, budgets) {
41762
+ const unit = budgets?.unit ?? "gzip";
41763
+ const rows = byGzip(stats).map((key) => {
41764
+ const route = stats.routes[key];
41765
+ const budget = budgetFor(key, route, budgets);
41766
+ const over = budget !== undefined && kb(route[unit]) > budget;
41767
+ return [
41768
+ key,
41769
+ route.static ? "static" : "hydrated",
41770
+ format(route.raw),
41771
+ format(route.gzip),
41772
+ format(route.brotli),
41773
+ String(route.chunks.length),
41774
+ budget === undefined ? "" : `${budget}${over ? " OVER" : ""}`
41775
+ ];
41776
+ });
41777
+ const header = [
41778
+ stats.by === "routes" ? "Route" : "View",
41779
+ "Kind",
41780
+ "raw KB",
41781
+ "gzip KB",
41782
+ "br KB",
41783
+ "files",
41784
+ `budget (${unit})`
41785
+ ];
41786
+ const table = [header, ...rows];
41787
+ const widths = header.map((_, i) => Math.max(...table.map((row) => row[i].length)));
41788
+ const line = (row) => row.map((cell, i) => i < 2 ? cell.padEnd(widths[i]) : cell.padStart(widths[i])).join(" ").trimEnd();
41789
+ const islands = Object.entries(stats.islands);
41790
+ return [
41791
+ "Initial JavaScript per " + (stats.by === "routes" ? "route" : "view") + ":",
41792
+ "",
41793
+ ...table.map(line),
41794
+ ...islands.length ? [
41795
+ "",
41796
+ "Islands (each with its imports):",
41797
+ ...islands.map(([key, island]) => ` ${key} ${format(island.gzip)} KB gzip, ${island.chunks.length} file(s)`)
41798
+ ] : [],
41799
+ "",
41800
+ `CSS: ${format(stats.css.raw)} KB raw, ${format(stats.css.gzip)} KB gzip`
41801
+ ].join(`
41802
+ `);
41803
+ }
41804
+
41805
+ // stats/run.ts
41806
+ async function runStats(options) {
41807
+ const log = options.log ?? console.log;
41808
+ const error = options.error ?? console.error;
41809
+ const clientDir = path7.join(options.rootDir, "dist", "client");
41810
+ if (!existsSync9(path7.join(clientDir, ".vite/manifest.json"))) {
41811
+ error(`No client build in ${clientDir}. Run \`gemi build\` first.`);
41812
+ return 1;
41813
+ }
41814
+ let routes = null;
41815
+ if (options.routes !== false) {
41816
+ const table = await loadRouteTable(options.rootDir, options.preloadArgs ?? []);
41817
+ if ("routes" in table)
41818
+ routes = table.routes;
41819
+ else
41820
+ error(`Could not read the route table, so this reports per view and can't tell static ` + `views apart (pass --no-routes to skip it):
41821
+ ${table.message}`);
41822
+ }
41823
+ const stats = bundleStats({ clientDir, routes });
41824
+ const budgets = options.config?.budgets;
41825
+ log(textReport(stats, budgets));
41826
+ if (options.json) {
41827
+ writeFileSync3(options.json, `${JSON.stringify(stats, null, 2)}
41828
+ `);
41829
+ }
41830
+ if (options.markdown) {
41831
+ const base = options.base && existsSync9(options.base) ? JSON.parse(readFileSync6(options.base, "utf8")) : null;
41832
+ writeFileSync3(options.markdown, `${markdownReport(stats, base, budgets)}
41833
+ `);
41834
+ }
41835
+ for (const key of unusedBudgets(stats, budgets)) {
41836
+ error(`warning: the budget for "${key}" matches no route or view.`);
41837
+ }
41838
+ const problems = overBudget(stats, budgets);
41839
+ if (problems.length) {
41840
+ error(`
41841
+ Over budget (stats.budgets in gemi.config.ts):
41842
+ ${problems.join(`
41843
+ `)}`);
41844
+ return 1;
41845
+ }
41846
+ return 0;
41847
+ }
41848
+ async function loadRouteTable(rootDir, preloadArgs, options = {}) {
41849
+ let entry;
41850
+ try {
41851
+ entry = Bun.resolveSync("gemi/stats/route-table", rootDir);
41852
+ } catch {
41853
+ return { ok: false, message: `gemi/stats/route-table does not resolve from ${rootDir}.` };
41854
+ }
41855
+ const dir = mkdtempSync(path7.join(tmpdir(), "gemi-stats-"));
41856
+ const out = path7.join(dir, "routes.json");
41857
+ try {
41858
+ const child = Bun.spawn({
41859
+ cmd: ["bun", "--preload", "gemi/bun/preload", ...preloadArgs, entry, out],
41860
+ cwd: rootDir,
41861
+ env: { ...process.env, GEMI_NO_SCHEDULE: "1" },
41862
+ stdout: "ignore",
41863
+ stderr: "pipe"
41864
+ });
41865
+ const timeoutMs = options.timeoutMs ?? 60000;
41866
+ let timedOut = false;
41867
+ const timer = setTimeout(() => {
41868
+ timedOut = true;
41869
+ child.kill();
41870
+ }, timeoutMs);
41871
+ const [code, stderr] = await Promise.all([child.exited, new Response(child.stderr).text()]);
41872
+ clearTimeout(timer);
41873
+ if (timedOut) {
41874
+ return { ok: false, message: `reading the route table took over ${timeoutMs / 1000}s.` };
41875
+ }
41876
+ if (code !== 0 || !existsSync9(out)) {
41877
+ return {
41878
+ ok: false,
41879
+ message: stderr.trim() || `the route table process exited with ${code}.`
41880
+ };
41881
+ }
41882
+ return { ok: true, routes: JSON.parse(readFileSync6(out, "utf8")) };
41883
+ } finally {
41884
+ rmSync3(dir, { recursive: true, force: true });
41885
+ }
41886
+ }
41887
+
41430
41888
  // bin/gemi.ts
41431
41889
  function appPreloadArgs(appDir) {
41432
- const preloadPath = path9.join(appDir, "preload.ts");
41433
- return existsSync8(preloadPath) ? ["--preload", preloadPath] : [];
41890
+ const preloadPath = path10.join(appDir, "preload.ts");
41891
+ return existsSync10(preloadPath) ? ["--preload", preloadPath] : [];
41434
41892
  }
41435
41893
  program.command("dev").action(async () => {
41436
41894
  console.log("Starting dev server...");
41437
- const rootDir = path9.resolve(process.cwd());
41438
- const appDir = path9.join(rootDir, "app");
41895
+ const rootDir = path10.resolve(process.cwd());
41896
+ const appDir = path10.join(rootDir, "app");
41439
41897
  process.env.NODE_ENV = "development";
41440
41898
  const exited = spawnForwardingSignals({
41441
41899
  cmd: [
@@ -41445,16 +41903,34 @@ program.command("dev").action(async () => {
41445
41903
  "--preload",
41446
41904
  "gemi/bun/preload",
41447
41905
  ...appPreloadArgs(appDir),
41448
- `${path9.join(appDir, "server.ts")}`
41906
+ `${path10.join(appDir, "server.ts")}`
41449
41907
  ]
41450
41908
  });
41451
41909
  reportUpdate({ rootDir });
41452
41910
  process.exit(await exited);
41453
41911
  });
41454
- program.command("build").action(async () => {
41912
+ function withStatsOptions(command) {
41913
+ return command.option("--json <file>", "Also write the stats as JSON (for CI diffs)").option("--base <file>", "Another build's JSON to compare with in --markdown (e.g. main's)").option("--markdown <file>", "Write the stats as a Markdown table, compared with --base").option("--no-routes", "Don't read the route table; report per view");
41914
+ }
41915
+ async function printStats(rootDir, options) {
41916
+ const config = await loadGemiConfig(rootDir);
41917
+ return runStats({
41918
+ rootDir,
41919
+ config: config.stats,
41920
+ json: options.json && path10.resolve(options.json),
41921
+ base: options.base && path10.resolve(options.base),
41922
+ markdown: options.markdown && path10.resolve(options.markdown),
41923
+ routes: options.routes,
41924
+ preloadArgs: appPreloadArgs(path10.join(rootDir, "app"))
41925
+ });
41926
+ }
41927
+ withStatsOptions(program.command("stats").description("Print the initial JavaScript each route loads (raw, gzip, brotli) from the " + "last `gemi build`, and fail when a route is over its budget " + "(`stats.budgets` in gemi.config.ts)")).action(async (options) => {
41928
+ process.exit(await printStats(path10.resolve(process.cwd()), options));
41929
+ });
41930
+ withStatsOptions(program.command("build").option("--stats", "After building, print the initial JS per route and check the budgets")).action(async (options) => {
41455
41931
  if (process.env.GEMI_BUILD_PROD !== "1") {
41456
41932
  const proc = Bun.spawn({
41457
- cmd: ["bun", process.argv[1], "build"],
41933
+ cmd: ["bun", process.argv[1], ...process.argv.slice(2)],
41458
41934
  env: { ...process.env, NODE_ENV: "production", GEMI_BUILD_PROD: "1" },
41459
41935
  stdout: "inherit",
41460
41936
  stderr: "inherit"
@@ -41463,14 +41939,14 @@ program.command("build").action(async () => {
41463
41939
  process.exit(proc.exitCode ?? 0);
41464
41940
  }
41465
41941
  process.env.NODE_ENV = "production";
41466
- const rootDir = path9.resolve(process.cwd());
41467
- const appDir = path9.join(rootDir, "app");
41942
+ const rootDir = path10.resolve(process.cwd());
41943
+ const appDir = path10.join(rootDir, "app");
41468
41944
  const config = await loadGemiConfig(rootDir);
41469
41945
  const input = await createRollupInput_default(appDir);
41470
41946
  process.env.GEMI_INPUT = JSON.stringify(input);
41471
41947
  const previousAssets = resolvePreviousAssets(config.previousAssets, rootDir);
41472
- const stagingDir = previousAssets ? await mkdtemp(path9.join(tmpdir(), "gemi-previous-assets-")) : undefined;
41473
- const clientDir = path9.join(rootDir, "dist", "client");
41948
+ const stagingDir = previousAssets ? await mkdtemp(path10.join(tmpdir2(), "gemi-previous-assets-")) : undefined;
41949
+ const clientDir = path10.join(rootDir, "dist", "client");
41474
41950
  const emitted = [];
41475
41951
  let carriedPaths = [];
41476
41952
  try {
@@ -41509,8 +41985,8 @@ program.command("build").action(async () => {
41509
41985
  await writeStaticAssetsRecord(clientDir, {
41510
41986
  files: { ...carried.record.files, ...fresh.record.files }
41511
41987
  });
41512
- const kb = (bytes) => `${(bytes / 1024).toFixed(1)} kB`;
41513
- console.log(`Precompressed ${fresh.stats.files} asset(s): ${kb(fresh.stats.identityBytes)} \u2192 ` + `${kb(fresh.stats.brBytes)} br / ${kb(fresh.stats.gzipBytes)} gzip ` + `(${Math.round(performance.now() - startedAt)} ms).`);
41988
+ const kb2 = (bytes) => `${(bytes / 1024).toFixed(1)} kB`;
41989
+ console.log(`Precompressed ${fresh.stats.files} asset(s): ${kb2(fresh.stats.identityBytes)} \u2192 ` + `${kb2(fresh.stats.brBytes)} br / ${kb2(fresh.stats.gzipBytes)} gzip ` + `(${Math.round(performance.now() - startedAt)} ms).`);
41514
41990
  console.log("Building server...");
41515
41991
  await build({
41516
41992
  configFile: false,
@@ -41533,12 +42009,16 @@ program.command("build").action(async () => {
41533
42009
  console.error(message);
41534
42010
  process.exit(1);
41535
42011
  }
42012
+ if (options.stats || options.json || options.markdown) {
42013
+ console.log("");
42014
+ process.exit(await printStats(rootDir, options));
42015
+ }
41536
42016
  process.exit();
41537
42017
  });
41538
42018
  program.command("start").action(async () => {
41539
42019
  console.log("Starting server...");
41540
- const rootDir = path9.resolve(process.cwd());
41541
- const appDir = path9.join(rootDir, "app");
42020
+ const rootDir = path10.resolve(process.cwd());
42021
+ const appDir = path10.join(rootDir, "app");
41542
42022
  const code = await spawnForwardingSignals({
41543
42023
  cmd: [
41544
42024
  "bun",
@@ -41552,8 +42032,8 @@ program.command("start").action(async () => {
41552
42032
  process.exit(code);
41553
42033
  });
41554
42034
  program.command("queue:work").description("Boot the app and run queued jobs, without serving HTTP, so job capacity " + "scales apart from web traffic. Needs a queue driver every process can " + 'reach, such as "database". Drains on SIGTERM/SIGINT like `gemi start`').action(async () => {
41555
- const rootDir = path9.resolve(process.cwd());
41556
- const appDir = path9.join(rootDir, "app");
42035
+ const rootDir = path10.resolve(process.cwd());
42036
+ const appDir = path10.join(rootDir, "app");
41557
42037
  let entry;
41558
42038
  try {
41559
42039
  entry = Bun.resolveSync("gemi/queue/work", rootDir);
@@ -41569,8 +42049,8 @@ program.command("queue:work").description("Boot the app and run queued jobs, wit
41569
42049
  });
41570
42050
  program.enablePositionalOptions();
41571
42051
  program.command("run").description("Run a Command from app/commands. Everything after the name is the " + "command's own, including its flags. Omit the name to list them").argument("[name]", "The command's name").argument("[args...]", "Passed through to the command untouched").passThroughOptions().action(async (name, args) => {
41572
- const rootDir = path9.resolve(process.cwd());
41573
- const appDir = path9.join(rootDir, "app");
42052
+ const rootDir = path10.resolve(process.cwd());
42053
+ const appDir = path10.join(rootDir, "app");
41574
42054
  let entry;
41575
42055
  try {
41576
42056
  entry = Bun.resolveSync("gemi/console/run", rootDir);
@@ -41594,13 +42074,13 @@ program.command("run").description("Run a Command from app/commands. Everything
41594
42074
  process.exit(code);
41595
42075
  });
41596
42076
  program.command("migrate").description("Migrate an app from the 0.42 service-provider layout to the config + " + "container layout, flagging APIs retired since").option("--dry-run", "Print the plan without writing anything").action(async (options) => {
41597
- const rootDir = path9.resolve(process.cwd());
42077
+ const rootDir = path10.resolve(process.cwd());
41598
42078
  console.log(options.dryRun ? `Planning migration of ${rootDir}...` : `Migrating ${rootDir}...`);
41599
42079
  await runMigrate({ rootDir, dryRun: options.dryRun });
41600
42080
  });
41601
42081
  program.command("upgrade").description("Upgrade the `gemi` package. With no argument it moves to the newest " + "release on the channel you are already on \u2014 `rc` for a release " + "candidate, `latest` otherwise \u2014 so an rc is never 'upgraded' backwards " + "onto the older stable release").argument("[target]", "A version (`0.59.0`) to pin or roll back to, or a dist-tag (`rc`, " + "`latest`). Defaults to the current channel's tag").option("--dry-run", "Resolve the version and print the install command, run nothing").action(async (target, options) => {
41602
42082
  const code = await runUpgrade({
41603
- rootDir: path9.resolve(process.cwd()),
42083
+ rootDir: path10.resolve(process.cwd()),
41604
42084
  target,
41605
42085
  dryRun: options.dryRun
41606
42086
  });
@@ -41608,7 +42088,7 @@ program.command("upgrade").description("Upgrade the `gemi` package. With no argu
41608
42088
  });
41609
42089
  program.command("install-skill").description(`Install the \`${SKILL_NAME}\` agent skill that ships with your gemi into ` + `.agents/skills/. \`gemi upgrade\` re-runs this afterwards, so the rules an ` + `agent reads stay pinned to the gemi the app actually runs`).option("--force", "Replace an installed copy that has local edits, or one this command did not write").action(async (options) => {
41610
42090
  process.exit(installSkill({
41611
- rootDir: path9.resolve(process.cwd()),
42091
+ rootDir: path10.resolve(process.cwd()),
41612
42092
  force: options.force
41613
42093
  }));
41614
42094
  });
@@ -41622,7 +42102,7 @@ check.command("models").description("Report policied model classes that the modu
41622
42102
  ], []).action(async (options) => {
41623
42103
  try {
41624
42104
  const report2 = await checkModels({
41625
- rootDir: path9.resolve(process.cwd()),
42105
+ rootDir: path10.resolve(process.cwd()),
41626
42106
  modelsDir: options.dir,
41627
42107
  ignore: options.ignore,
41628
42108
  models: options.models
@@ -41641,7 +42121,7 @@ program.command("ai:generate-client").description("Generate an agent's tool and
41641
42121
  const { file, warnings } = await generateClient2({ agent, ...options });
41642
42122
  for (const warning of warnings)
41643
42123
  console.warn(`warning: ${warning}`);
41644
- console.log(`Wrote ${path9.relative(process.cwd(), file)}`);
42124
+ console.log(`Wrote ${path10.relative(process.cwd(), file)}`);
41645
42125
  process.exit(0);
41646
42126
  } catch (error) {
41647
42127
  if (!(error instanceof GenerateClientError2))
@@ -41666,5 +42146,5 @@ program.command("app:route-manifest").action(async () => {
41666
42146
  });
41667
42147
  program.parse();
41668
42148
 
41669
- //# debugId=45F966AEDDDBFC5864756E2164756E21
42149
+ //# debugId=0E49B3FD0C1F8A9E64756E2164756E21
41670
42150
  //# sourceMappingURL=gemi.js.map