gina 0.6.8 → 0.6.9

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 (579) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +25 -28
  3. package/ROADMAP.md +2 -1
  4. package/framework/v0.6.9/VERSION +1 -0
  5. package/framework/{v0.6.8 → v0.6.9}/core/config.js +102 -1
  6. package/framework/{v0.6.8 → v0.6.9}/core/controller/controller.js +32 -4
  7. package/framework/{v0.6.8 → v0.6.9}/core/gna.js +107 -0
  8. package/framework/{v0.6.8 → v0.6.9}/core/server.express.js +40 -1
  9. package/framework/{v0.6.8 → v0.6.9}/core/server.isaac.js +110 -3
  10. package/framework/{v0.6.8 → v0.6.9}/core/server.js +16 -2
  11. package/framework/{v0.6.8 → v0.6.9}/helpers/path.js +108 -26
  12. package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/build.js +37 -0
  13. package/framework/{v0.6.8 → v0.6.9}/lib/cmd/helper.js +148 -49
  14. package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/add.js +75 -3
  15. package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/build.js +24 -0
  16. package/framework/{v0.6.8 → v0.6.9}/lib/index.js +8 -0
  17. package/framework/v0.6.9/lib/push/package.json +19 -0
  18. package/framework/v0.6.9/lib/push/src/main.js +144 -0
  19. package/framework/{v0.6.8 → v0.6.9}/lib/secrets/src/backends/env.js +15 -4
  20. package/framework/{v0.6.8 → v0.6.9}/lib/secrets/src/main.js +48 -4
  21. package/framework/{v0.6.8 → v0.6.9}/package.json +1 -1
  22. package/gna.js +4 -4
  23. package/llms.txt +9 -6
  24. package/package.json +3 -3
  25. package/schema/manifest.json +6 -0
  26. package/schema/settings.json +3 -2
  27. package/types/index.d.ts +39 -0
  28. package/framework/v0.6.8/VERSION +0 -1
  29. /package/framework/{v0.6.8 → v0.6.9}/AUTHORS +0 -0
  30. /package/framework/{v0.6.8 → v0.6.9}/LICENSE +0 -0
  31. /package/framework/{v0.6.8 → v0.6.9}/core/asset/html/nolayout.html +0 -0
  32. /package/framework/{v0.6.8 → v0.6.9}/core/asset/html/static.html +0 -0
  33. /package/framework/{v0.6.8 → v0.6.9}/core/asset/img/android-chrome-192x192.png +0 -0
  34. /package/framework/{v0.6.8 → v0.6.9}/core/asset/img/android-chrome-512x512.png +0 -0
  35. /package/framework/{v0.6.8 → v0.6.9}/core/asset/img/apple-touch-icon.png +0 -0
  36. /package/framework/{v0.6.8 → v0.6.9}/core/asset/img/favicon-16x16.png +0 -0
  37. /package/framework/{v0.6.8 → v0.6.9}/core/asset/img/favicon-32x32.png +0 -0
  38. /package/framework/{v0.6.8 → v0.6.9}/core/asset/img/favicon.ico +0 -0
  39. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/README.md +0 -0
  40. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.css +0 -0
  41. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/beemaster/beemaster.js +0 -0
  42. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/beemaster/index.html +0 -0
  43. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/css/gina.min.css +0 -0
  44. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.br +0 -0
  45. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/css/gina.min.css.gz +0 -0
  46. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/html/statusbar.html +0 -0
  47. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.br +0 -0
  48. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/html/statusbar.html.gz +0 -0
  49. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/inspector/have_heart_one-webfont.woff2 +0 -0
  50. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/inspector/index.html +0 -0
  51. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/inspector/inspector.css +0 -0
  52. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/inspector/inspector.js +0 -0
  53. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/inspector/logo.svg +0 -0
  54. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/js/gina.js +0 -0
  55. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/js/gina.min.js +0 -0
  56. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/js/gina.min.js.br +0 -0
  57. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/js/gina.min.js.gz +0 -0
  58. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js +0 -0
  59. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.br +0 -0
  60. /package/framework/{v0.6.8 → v0.6.9}/core/asset/plugin/dist/vendor/gina/js/gina.onload.min.js.gz +0 -0
  61. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/ai/index.js +0 -0
  62. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/ai/lib/connector.js +0 -0
  63. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/couchbase/index.js +0 -0
  64. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/couchbase/lib/connector.js +0 -0
  65. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/couchbase/lib/connector.v3.js +0 -0
  66. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/couchbase/lib/connector.v4.js +0 -0
  67. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/couchbase/lib/n1ql.js +0 -0
  68. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/couchbase/lib/session-store.js +0 -0
  69. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/couchbase/lib/session-store.v3.js +0 -0
  70. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/couchbase/lib/session-store.v4.js +0 -0
  71. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/couchbase/lib/storage-store.js +0 -0
  72. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/duckdb/index.js +0 -0
  73. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/duckdb/lib/connector.js +0 -0
  74. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/mongodb/index.js +0 -0
  75. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/mongodb/lib/connector.js +0 -0
  76. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/mongodb/lib/job-store.js +0 -0
  77. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/mongodb/lib/pipeline-loader.js +0 -0
  78. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/mongodb/lib/session-store.js +0 -0
  79. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/mysql/index.js +0 -0
  80. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/mysql/lib/connector.js +0 -0
  81. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/param-redact.js +0 -0
  82. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/postgresql/index.js +0 -0
  83. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/postgresql/lib/connector.js +0 -0
  84. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/redis/index.js +0 -0
  85. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/redis/lib/connector.js +0 -0
  86. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/redis/lib/job-store.js +0 -0
  87. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/redis/lib/render-cache-store.js +0 -0
  88. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/redis/lib/session-store.js +0 -0
  89. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/scylladb/index.js +0 -0
  90. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/scylladb/lib/connector.js +0 -0
  91. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/scylladb/lib/session-store.js +0 -0
  92. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/sql-parser.js +0 -0
  93. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/sqlite/index.js +0 -0
  94. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/sqlite/lib/connector.js +0 -0
  95. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/sqlite/lib/job-store.js +0 -0
  96. /package/framework/{v0.6.8 → v0.6.9}/core/connectors/sqlite/lib/session-store.js +0 -0
  97. /package/framework/{v0.6.8 → v0.6.9}/core/content.encoding +0 -0
  98. /package/framework/{v0.6.8 → v0.6.9}/core/controller/controller.framework.js +0 -0
  99. /package/framework/{v0.6.8 → v0.6.9}/core/controller/controller.render-json.js +0 -0
  100. /package/framework/{v0.6.8 → v0.6.9}/core/controller/controller.render-nunjucks-async.js +0 -0
  101. /package/framework/{v0.6.8 → v0.6.9}/core/controller/controller.render-nunjucks.js +0 -0
  102. /package/framework/{v0.6.8 → v0.6.9}/core/controller/controller.render-stream.js +0 -0
  103. /package/framework/{v0.6.8 → v0.6.9}/core/controller/controller.render-swig-async.js +0 -0
  104. /package/framework/{v0.6.8 → v0.6.9}/core/controller/controller.render-swig.js +0 -0
  105. /package/framework/{v0.6.8 → v0.6.9}/core/controller/controller.render-v1.js +0 -0
  106. /package/framework/{v0.6.8 → v0.6.9}/core/controller/index.js +0 -0
  107. /package/framework/{v0.6.8 → v0.6.9}/core/controller/inspector-window-emit.js +0 -0
  108. /package/framework/{v0.6.8 → v0.6.9}/core/controller/release-banner.js +0 -0
  109. /package/framework/{v0.6.8 → v0.6.9}/core/dev/index.js +0 -0
  110. /package/framework/{v0.6.8 → v0.6.9}/core/dev/lib/class.js +0 -0
  111. /package/framework/{v0.6.8 → v0.6.9}/core/dev/lib/factory.js +0 -0
  112. /package/framework/{v0.6.8 → v0.6.9}/core/dev/lib/tools.js +0 -0
  113. /package/framework/{v0.6.8 → v0.6.9}/core/locales/README.md +0 -0
  114. /package/framework/{v0.6.8 → v0.6.9}/core/locales/currency.json +0 -0
  115. /package/framework/{v0.6.8 → v0.6.9}/core/locales/dist/language/en.json +0 -0
  116. /package/framework/{v0.6.8 → v0.6.9}/core/locales/dist/language/fr.json +0 -0
  117. /package/framework/{v0.6.8 → v0.6.9}/core/locales/dist/region/en.json +0 -0
  118. /package/framework/{v0.6.8 → v0.6.9}/core/locales/dist/region/fr.json +0 -0
  119. /package/framework/{v0.6.8 → v0.6.9}/core/locales/index.js +0 -0
  120. /package/framework/{v0.6.8 → v0.6.9}/core/mime.types +0 -0
  121. /package/framework/{v0.6.8 → v0.6.9}/core/model/entity.js +0 -0
  122. /package/framework/{v0.6.8 → v0.6.9}/core/model/index.js +0 -0
  123. /package/framework/{v0.6.8 → v0.6.9}/core/model/template/entityFactory.js +0 -0
  124. /package/framework/{v0.6.8 → v0.6.9}/core/model/template/index.js +0 -0
  125. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/README.md +0 -0
  126. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/index.js +0 -0
  127. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/csrf/README.md +0 -0
  128. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/csrf/package.json +0 -0
  129. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/csrf/src/main.js +0 -0
  130. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/README.md +0 -0
  131. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/coep/README.md +0 -0
  132. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/coep/package.json +0 -0
  133. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/coep/src/main.js +0 -0
  134. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/coop/README.md +0 -0
  135. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/coop/package.json +0 -0
  136. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/coop/src/main.js +0 -0
  137. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/corp/README.md +0 -0
  138. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/corp/package.json +0 -0
  139. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/corp/src/main.js +0 -0
  140. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/csp/README.md +0 -0
  141. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/csp/package.json +0 -0
  142. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/csp/src/main.js +0 -0
  143. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/hide-powered-by/README.md +0 -0
  144. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/hide-powered-by/package.json +0 -0
  145. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/hide-powered-by/src/main.js +0 -0
  146. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/hsts/README.md +0 -0
  147. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/hsts/package.json +0 -0
  148. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/hsts/src/main.js +0 -0
  149. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/origin-agent-cluster/README.md +0 -0
  150. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/origin-agent-cluster/package.json +0 -0
  151. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/origin-agent-cluster/src/main.js +0 -0
  152. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/package.json +0 -0
  153. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/referrer-policy/README.md +0 -0
  154. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/referrer-policy/package.json +0 -0
  155. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/referrer-policy/src/main.js +0 -0
  156. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/src/main.js +0 -0
  157. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-content-type-options/README.md +0 -0
  158. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-content-type-options/package.json +0 -0
  159. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-content-type-options/src/main.js +0 -0
  160. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-dns-prefetch-control/README.md +0 -0
  161. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-dns-prefetch-control/package.json +0 -0
  162. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-dns-prefetch-control/src/main.js +0 -0
  163. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-download-options/README.md +0 -0
  164. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-download-options/package.json +0 -0
  165. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-download-options/src/main.js +0 -0
  166. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-frame-options/README.md +0 -0
  167. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-frame-options/package.json +0 -0
  168. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-frame-options/src/main.js +0 -0
  169. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/README.md +0 -0
  170. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/package.json +0 -0
  171. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-permitted-cross-domain-policies/src/main.js +0 -0
  172. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-xss-protection/README.md +0 -0
  173. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-xss-protection/package.json +0 -0
  174. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/security-headers/x-xss-protection/src/main.js +0 -0
  175. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/session/README.md +0 -0
  176. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/session/package.json +0 -0
  177. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/session/src/main.js +0 -0
  178. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/storage/README.md +0 -0
  179. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/storage/build.json +0 -0
  180. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/storage/package.json +0 -0
  181. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/storage/src/main.js +0 -0
  182. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/validator/README.md +0 -0
  183. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/validator/build.json +0 -0
  184. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/validator/package.json +0 -0
  185. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/validator/src/form-validator.js +0 -0
  186. /package/framework/{v0.6.8 → v0.6.9}/core/plugins/lib/validator/src/main.js +0 -0
  187. /package/framework/{v0.6.8 → v0.6.9}/core/router.js +0 -0
  188. /package/framework/{v0.6.8 → v0.6.9}/core/status.codes +0 -0
  189. /package/framework/{v0.6.8 → v0.6.9}/core/template/_gitignore +0 -0
  190. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle/config/app.json +0 -0
  191. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle/config/connectors.json +0 -0
  192. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle/config/routing.json +0 -0
  193. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle/config/settings.json +0 -0
  194. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle/config/settings.server.json +0 -0
  195. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle/config/templates.json +0 -0
  196. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle/config/watchers.json +0 -0
  197. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle/controllers/controller.content.js +0 -0
  198. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle/controllers/controller.js +0 -0
  199. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle/controllers/setup.js +0 -0
  200. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle/index.js +0 -0
  201. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle/locales/en.json +0 -0
  202. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle_namespace/controllers/controller.js +0 -0
  203. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle_public/css/default.css +0 -0
  204. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle_public/css/home.css +0 -0
  205. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle_public/css/vendor/readme.md +0 -0
  206. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle_public/favicon.ico +0 -0
  207. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle_public/js/components/x-checklist.js +0 -0
  208. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle_public/js/vendor/readme.md +0 -0
  209. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle_public/manifest.webmanifest +0 -0
  210. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle_public/readme.md +0 -0
  211. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle_public/sw.js +0 -0
  212. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle_templates/handlers/main.js +0 -0
  213. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle_templates/html/content/homepage.html +0 -0
  214. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle_templates/html/includes/error-msg-noscript.html +0 -0
  215. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle_templates/html/includes/error-msg-outdated-browser.html +0 -0
  216. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle_templates/html/includes/x-checklist.html +0 -0
  217. /package/framework/{v0.6.8 → v0.6.9}/core/template/boilerplate/bundle_templates/html/layouts/main.html +0 -0
  218. /package/framework/{v0.6.8 → v0.6.9}/core/template/command/gina.bat.tpl +0 -0
  219. /package/framework/{v0.6.8 → v0.6.9}/core/template/command/gina.tpl +0 -0
  220. /package/framework/{v0.6.8 → v0.6.9}/core/template/conf/env.json +0 -0
  221. /package/framework/{v0.6.8 → v0.6.9}/core/template/conf/manifest.json +0 -0
  222. /package/framework/{v0.6.8 → v0.6.9}/core/template/conf/package.json +0 -0
  223. /package/framework/{v0.6.8 → v0.6.9}/core/template/conf/settings.json +0 -0
  224. /package/framework/{v0.6.8 → v0.6.9}/core/template/conf/statics.json +0 -0
  225. /package/framework/{v0.6.8 → v0.6.9}/core/template/conf/templates.json +0 -0
  226. /package/framework/{v0.6.8 → v0.6.9}/core/template/error/client/json/401.json +0 -0
  227. /package/framework/{v0.6.8 → v0.6.9}/core/template/error/client/json/403.json +0 -0
  228. /package/framework/{v0.6.8 → v0.6.9}/core/template/error/client/json/404.json +0 -0
  229. /package/framework/{v0.6.8 → v0.6.9}/core/template/error/server/html/50x.html +0 -0
  230. /package/framework/{v0.6.8 → v0.6.9}/core/template/error/server/json/500.json +0 -0
  231. /package/framework/{v0.6.8 → v0.6.9}/core/template/error/server/json/503.json +0 -0
  232. /package/framework/{v0.6.8 → v0.6.9}/core/template/extensions/logger/config.json +0 -0
  233. /package/framework/{v0.6.8 → v0.6.9}/helpers/console.js +0 -0
  234. /package/framework/{v0.6.8 → v0.6.9}/helpers/context.js +0 -0
  235. /package/framework/{v0.6.8 → v0.6.9}/helpers/data/LICENSE +0 -0
  236. /package/framework/{v0.6.8 → v0.6.9}/helpers/data/README.md +0 -0
  237. /package/framework/{v0.6.8 → v0.6.9}/helpers/data/package.json +0 -0
  238. /package/framework/{v0.6.8 → v0.6.9}/helpers/data/src/main.js +0 -0
  239. /package/framework/{v0.6.8 → v0.6.9}/helpers/dateFormat.js +0 -0
  240. /package/framework/{v0.6.8 → v0.6.9}/helpers/index.js +0 -0
  241. /package/framework/{v0.6.8 → v0.6.9}/helpers/json/LICENSE +0 -0
  242. /package/framework/{v0.6.8 → v0.6.9}/helpers/json/README.md +0 -0
  243. /package/framework/{v0.6.8 → v0.6.9}/helpers/json/package.json +0 -0
  244. /package/framework/{v0.6.8 → v0.6.9}/helpers/json/src/main.js +0 -0
  245. /package/framework/{v0.6.8 → v0.6.9}/helpers/plugins/README.md +0 -0
  246. /package/framework/{v0.6.8 → v0.6.9}/helpers/plugins/package.json +0 -0
  247. /package/framework/{v0.6.8 → v0.6.9}/helpers/plugins/src/api-error.js +0 -0
  248. /package/framework/{v0.6.8 → v0.6.9}/helpers/plugins/src/main.js +0 -0
  249. /package/framework/{v0.6.8 → v0.6.9}/helpers/prototypes.js +0 -0
  250. /package/framework/{v0.6.8 → v0.6.9}/helpers/task.js +0 -0
  251. /package/framework/{v0.6.8 → v0.6.9}/helpers/text.js +0 -0
  252. /package/framework/{v0.6.8 → v0.6.9}/lib/admin/package.json +0 -0
  253. /package/framework/{v0.6.8 → v0.6.9}/lib/admin/src/main.js +0 -0
  254. /package/framework/{v0.6.8 → v0.6.9}/lib/archiver/README.md +0 -0
  255. /package/framework/{v0.6.8 → v0.6.9}/lib/archiver/build.json +0 -0
  256. /package/framework/{v0.6.8 → v0.6.9}/lib/archiver/package.json +0 -0
  257. /package/framework/{v0.6.8 → v0.6.9}/lib/archiver/src/dep/jszip.min.js +0 -0
  258. /package/framework/{v0.6.8 → v0.6.9}/lib/archiver/src/main.js +0 -0
  259. /package/framework/{v0.6.8 → v0.6.9}/lib/async/package.json +0 -0
  260. /package/framework/{v0.6.8 → v0.6.9}/lib/async/src/main.js +0 -0
  261. /package/framework/{v0.6.8 → v0.6.9}/lib/audit/package.json +0 -0
  262. /package/framework/{v0.6.8 → v0.6.9}/lib/audit/src/main.js +0 -0
  263. /package/framework/{v0.6.8 → v0.6.9}/lib/audit-store.js +0 -0
  264. /package/framework/{v0.6.8 → v0.6.9}/lib/authn/package.json +0 -0
  265. /package/framework/{v0.6.8 → v0.6.9}/lib/authn/src/lockout.js +0 -0
  266. /package/framework/{v0.6.8 → v0.6.9}/lib/authn/src/main.js +0 -0
  267. /package/framework/{v0.6.8 → v0.6.9}/lib/authn/src/totp.js +0 -0
  268. /package/framework/{v0.6.8 → v0.6.9}/lib/authz-gate/package.json +0 -0
  269. /package/framework/{v0.6.8 → v0.6.9}/lib/authz-gate/src/main.js +0 -0
  270. /package/framework/{v0.6.8 → v0.6.9}/lib/cache/README.md +0 -0
  271. /package/framework/{v0.6.8 → v0.6.9}/lib/cache/build.json +0 -0
  272. /package/framework/{v0.6.8 → v0.6.9}/lib/cache/package.json +0 -0
  273. /package/framework/{v0.6.8 → v0.6.9}/lib/cache/src/main.js +0 -0
  274. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/aliases.json +0 -0
  275. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/audit/arguments.json +0 -0
  276. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/audit/help.txt +0 -0
  277. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/audit/verify.js +0 -0
  278. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/add.js +0 -0
  279. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/arguments.json +0 -0
  280. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/copy.js +0 -0
  281. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/cp.js +0 -0
  282. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/help.js +0 -0
  283. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/help.txt +0 -0
  284. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/inc/name-rewrite.js +0 -0
  285. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/list.js +0 -0
  286. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/man.js +0 -0
  287. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/mcp-start.js +0 -0
  288. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/mcp.js +0 -0
  289. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/oas.js +0 -0
  290. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/openapi.js +0 -0
  291. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/remove.js +0 -0
  292. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/rename.js +0 -0
  293. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/restart.js +0 -0
  294. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/rm.js +0 -0
  295. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/start.js +0 -0
  296. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/status.js +0 -0
  297. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/stop.js +0 -0
  298. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/bundle/types.js +0 -0
  299. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/cache/arguments.json +0 -0
  300. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/cache/clear.js +0 -0
  301. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/cache/help.txt +0 -0
  302. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/cache/stats.js +0 -0
  303. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/connector/add.js +0 -0
  304. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/connector/arguments.json +0 -0
  305. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/connector/help.js +0 -0
  306. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/connector/help.txt +0 -0
  307. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/connector/infer.js +0 -0
  308. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/connector/list.js +0 -0
  309. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/connector/migrate.js +0 -0
  310. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/connector/models.js +0 -0
  311. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/connector/remove.js +0 -0
  312. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/connector/rm.js +0 -0
  313. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/connector/test.js +0 -0
  314. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/container/arguments.json +0 -0
  315. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/container/help.js +0 -0
  316. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/container/help.txt +0 -0
  317. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/container/man.js +0 -0
  318. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/container/ps.js +0 -0
  319. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/container/stop.js +0 -0
  320. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/controller/add.js +0 -0
  321. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/controller/arguments.json +0 -0
  322. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/controller/help.txt +0 -0
  323. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/controller/inc/args.js +0 -0
  324. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/controller/inc/namespace.js +0 -0
  325. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/controller/inc/reference-rewrite.js +0 -0
  326. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/controller/inc/reference-scan.js +0 -0
  327. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/controller/inc/scaffold.js +0 -0
  328. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/controller/remove.js +0 -0
  329. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/controller/rename.js +0 -0
  330. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/controller/rm.js +0 -0
  331. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/env/add.js +0 -0
  332. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/env/get.js +0 -0
  333. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/env/help.js +0 -0
  334. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/env/help.txt +0 -0
  335. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/env/link-dev.js +0 -0
  336. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/env/list.js +0 -0
  337. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/env/remove.js +0 -0
  338. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/env/rm.js +0 -0
  339. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/env/set.js +0 -0
  340. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/env/unset.js +0 -0
  341. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/env/use.js +0 -0
  342. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/add.js +0 -0
  343. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/arguments.json +0 -0
  344. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/build.js +0 -0
  345. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/dot.js +0 -0
  346. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/get.js +0 -0
  347. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/help.js +0 -0
  348. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/help.txt +0 -0
  349. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/init.js +0 -0
  350. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/link-node-modules.js +0 -0
  351. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/link.js +0 -0
  352. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/list.js +0 -0
  353. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/man.js +0 -0
  354. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/msg.json +0 -0
  355. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/open.js +0 -0
  356. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/remove.js +0 -0
  357. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/reset.js +0 -0
  358. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/restart.js +0 -0
  359. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/set.js +0 -0
  360. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/start.js +0 -0
  361. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/status.js +0 -0
  362. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/stop.js +0 -0
  363. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/tail.js +0 -0
  364. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/update.js +0 -0
  365. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/framework/version.js +0 -0
  366. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/gina-dev.1.md +0 -0
  367. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/gina-framework.1.md +0 -0
  368. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/gina.1.md +0 -0
  369. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/i18n/add.js +0 -0
  370. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/i18n/arguments.json +0 -0
  371. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/i18n/export.js +0 -0
  372. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/i18n/help.js +0 -0
  373. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/i18n/help.txt +0 -0
  374. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/i18n/import.js +0 -0
  375. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/i18n/scan.js +0 -0
  376. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/image/_host.js +0 -0
  377. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/image/arguments.json +0 -0
  378. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/image/build.js +0 -0
  379. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/image/help.js +0 -0
  380. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/image/help.txt +0 -0
  381. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/image/list.js +0 -0
  382. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/image/man.js +0 -0
  383. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/image/rm.js +0 -0
  384. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/image/run.js +0 -0
  385. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/index.js +0 -0
  386. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/inspector/help.js +0 -0
  387. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/inspector/help.txt +0 -0
  388. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/inspector/open.js +0 -0
  389. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/man-render.js +0 -0
  390. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/minion/arguments.json +0 -0
  391. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/minion/help.js +0 -0
  392. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/minion/help.txt +0 -0
  393. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/minion/kill.js +0 -0
  394. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/minion/list.js +0 -0
  395. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/msg.json +0 -0
  396. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/port/help.js +0 -0
  397. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/port/help.txt +0 -0
  398. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/port/inc/scan.js +0 -0
  399. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/port/list.js +0 -0
  400. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/port/reset.js +0 -0
  401. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/port/set.js +0 -0
  402. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/arguments.json +0 -0
  403. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/backup.js +0 -0
  404. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/help.js +0 -0
  405. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/help.txt +0 -0
  406. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/import.js +0 -0
  407. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/list.js +0 -0
  408. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/man.js +0 -0
  409. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/move.js +0 -0
  410. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/remove.js +0 -0
  411. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/rename.js +0 -0
  412. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/restart.js +0 -0
  413. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/restore.js +0 -0
  414. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/rm.js +0 -0
  415. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/start.js +0 -0
  416. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/status.js +0 -0
  417. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/project/stop.js +0 -0
  418. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/protocol/arguments.json +0 -0
  419. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/protocol/help.js +0 -0
  420. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/protocol/help.txt +0 -0
  421. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/protocol/list.js +0 -0
  422. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/protocol/remove.js +0 -0
  423. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/protocol/set.js +0 -0
  424. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/scope/add.js +0 -0
  425. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/scope/help.js +0 -0
  426. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/scope/help.txt +0 -0
  427. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/scope/link-local.js +0 -0
  428. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/scope/link-production.js +0 -0
  429. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/scope/list.js +0 -0
  430. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/scope/remove.js +0 -0
  431. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/scope/rm.js +0 -0
  432. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/scope/use.js +0 -0
  433. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/secrets/arguments.json +0 -0
  434. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/secrets/check.js +0 -0
  435. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/secrets/help.js +0 -0
  436. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/secrets/help.txt +0 -0
  437. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/secrets/scan.js +0 -0
  438. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/service/help.js +0 -0
  439. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/service/help.txt +0 -0
  440. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/service/list.js +0 -0
  441. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/service/man.js +0 -0
  442. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/service/start.js +0 -0
  443. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/storage/arguments.json +0 -0
  444. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/storage/gc.js +0 -0
  445. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/storage/help.txt +0 -0
  446. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/storage/stats.js +0 -0
  447. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/storage/verify.js +0 -0
  448. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd/view/add.js +0 -0
  449. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd-status-format/package.json +0 -0
  450. /package/framework/{v0.6.8 → v0.6.9}/lib/cmd-status-format/src/main.js +0 -0
  451. /package/framework/{v0.6.8 → v0.6.9}/lib/collection/README.md +0 -0
  452. /package/framework/{v0.6.8 → v0.6.9}/lib/collection/build.json +0 -0
  453. /package/framework/{v0.6.8 → v0.6.9}/lib/collection/package.json +0 -0
  454. /package/framework/{v0.6.8 → v0.6.9}/lib/collection/src/main.js +0 -0
  455. /package/framework/{v0.6.8 → v0.6.9}/lib/config.js +0 -0
  456. /package/framework/{v0.6.8 → v0.6.9}/lib/connector-config/package.json +0 -0
  457. /package/framework/{v0.6.8 → v0.6.9}/lib/connector-config/src/main.js +0 -0
  458. /package/framework/{v0.6.8 → v0.6.9}/lib/connector-error/package.json +0 -0
  459. /package/framework/{v0.6.8 → v0.6.9}/lib/connector-error/src/main.js +0 -0
  460. /package/framework/{v0.6.8 → v0.6.9}/lib/connector-registry/package.json +0 -0
  461. /package/framework/{v0.6.8 → v0.6.9}/lib/connector-registry/src/main.js +0 -0
  462. /package/framework/{v0.6.8 → v0.6.9}/lib/cron/README.md +0 -0
  463. /package/framework/{v0.6.8 → v0.6.9}/lib/cron/package.json +0 -0
  464. /package/framework/{v0.6.8 → v0.6.9}/lib/cron/src/main.js +0 -0
  465. /package/framework/{v0.6.8 → v0.6.9}/lib/domain/LICENSE +0 -0
  466. /package/framework/{v0.6.8 → v0.6.9}/lib/domain/README.md +0 -0
  467. /package/framework/{v0.6.8 → v0.6.9}/lib/domain/package.json +0 -0
  468. /package/framework/{v0.6.8 → v0.6.9}/lib/domain/src/main.js +0 -0
  469. /package/framework/{v0.6.8 → v0.6.9}/lib/dto/package.json +0 -0
  470. /package/framework/{v0.6.8 → v0.6.9}/lib/dto/src/main.js +0 -0
  471. /package/framework/{v0.6.8 → v0.6.9}/lib/dto-pipe/package.json +0 -0
  472. /package/framework/{v0.6.8 → v0.6.9}/lib/dto-pipe/src/main.js +0 -0
  473. /package/framework/{v0.6.8 → v0.6.9}/lib/dto-types/package.json +0 -0
  474. /package/framework/{v0.6.8 → v0.6.9}/lib/dto-types/src/main.js +0 -0
  475. /package/framework/{v0.6.8 → v0.6.9}/lib/generator/index.js +0 -0
  476. /package/framework/{v0.6.8 → v0.6.9}/lib/i18n/package.json +0 -0
  477. /package/framework/{v0.6.8 → v0.6.9}/lib/i18n/src/main.js +0 -0
  478. /package/framework/{v0.6.8 → v0.6.9}/lib/image-build/package.json +0 -0
  479. /package/framework/{v0.6.8 → v0.6.9}/lib/image-build/src/main.js +0 -0
  480. /package/framework/{v0.6.8 → v0.6.9}/lib/inherits/LICENSE +0 -0
  481. /package/framework/{v0.6.8 → v0.6.9}/lib/inherits/README.md +0 -0
  482. /package/framework/{v0.6.8 → v0.6.9}/lib/inherits/package.json +0 -0
  483. /package/framework/{v0.6.8 → v0.6.9}/lib/inherits/src/main.js +0 -0
  484. /package/framework/{v0.6.8 → v0.6.9}/lib/inspector-events/package.json +0 -0
  485. /package/framework/{v0.6.8 → v0.6.9}/lib/inspector-events/src/main.js +0 -0
  486. /package/framework/{v0.6.8 → v0.6.9}/lib/inspector-redact/package.json +0 -0
  487. /package/framework/{v0.6.8 → v0.6.9}/lib/inspector-redact/src/main.js +0 -0
  488. /package/framework/{v0.6.8 → v0.6.9}/lib/instrument/package.json +0 -0
  489. /package/framework/{v0.6.8 → v0.6.9}/lib/instrument/src/main.js +0 -0
  490. /package/framework/{v0.6.8 → v0.6.9}/lib/job/package.json +0 -0
  491. /package/framework/{v0.6.8 → v0.6.9}/lib/job/src/main.js +0 -0
  492. /package/framework/{v0.6.8 → v0.6.9}/lib/job-store.js +0 -0
  493. /package/framework/{v0.6.8 → v0.6.9}/lib/json-config-header/package.json +0 -0
  494. /package/framework/{v0.6.8 → v0.6.9}/lib/json-config-header/src/main.js +0 -0
  495. /package/framework/{v0.6.8 → v0.6.9}/lib/loading-state/package.json +0 -0
  496. /package/framework/{v0.6.8 → v0.6.9}/lib/loading-state/src/main.js +0 -0
  497. /package/framework/{v0.6.8 → v0.6.9}/lib/logger/README.md +0 -0
  498. /package/framework/{v0.6.8 → v0.6.9}/lib/logger/package.json +0 -0
  499. /package/framework/{v0.6.8 → v0.6.9}/lib/logger/src/containers/default/index.js +0 -0
  500. /package/framework/{v0.6.8 → v0.6.9}/lib/logger/src/containers/file/index.js +0 -0
  501. /package/framework/{v0.6.8 → v0.6.9}/lib/logger/src/containers/file/lib/logrotator/README.md +0 -0
  502. /package/framework/{v0.6.8 → v0.6.9}/lib/logger/src/containers/file/lib/logrotator/index.js +0 -0
  503. /package/framework/{v0.6.8 → v0.6.9}/lib/logger/src/containers/mq/index.js +0 -0
  504. /package/framework/{v0.6.8 → v0.6.9}/lib/logger/src/containers/mq/listener.js +0 -0
  505. /package/framework/{v0.6.8 → v0.6.9}/lib/logger/src/containers/mq/speaker.js +0 -0
  506. /package/framework/{v0.6.8 → v0.6.9}/lib/logger/src/helper.js +0 -0
  507. /package/framework/{v0.6.8 → v0.6.9}/lib/logger/src/main.js +0 -0
  508. /package/framework/{v0.6.8 → v0.6.9}/lib/math/index.js +0 -0
  509. /package/framework/{v0.6.8 → v0.6.9}/lib/mcp-dispatch/package.json +0 -0
  510. /package/framework/{v0.6.8 → v0.6.9}/lib/mcp-dispatch/src/main.js +0 -0
  511. /package/framework/{v0.6.8 → v0.6.9}/lib/mcp-http/package.json +0 -0
  512. /package/framework/{v0.6.8 → v0.6.9}/lib/mcp-http/src/main.js +0 -0
  513. /package/framework/{v0.6.8 → v0.6.9}/lib/mcp-server/package.json +0 -0
  514. /package/framework/{v0.6.8 → v0.6.9}/lib/mcp-server/src/main.js +0 -0
  515. /package/framework/{v0.6.8 → v0.6.9}/lib/merge/README.md +0 -0
  516. /package/framework/{v0.6.8 → v0.6.9}/lib/merge/package.json +0 -0
  517. /package/framework/{v0.6.8 → v0.6.9}/lib/merge/src/main.js +0 -0
  518. /package/framework/{v0.6.8 → v0.6.9}/lib/metrics/package.json +0 -0
  519. /package/framework/{v0.6.8 → v0.6.9}/lib/metrics/src/main.js +0 -0
  520. /package/framework/{v0.6.8 → v0.6.9}/lib/model.js +0 -0
  521. /package/framework/{v0.6.8 → v0.6.9}/lib/net-locality/package.json +0 -0
  522. /package/framework/{v0.6.8 → v0.6.9}/lib/net-locality/src/main.js +0 -0
  523. /package/framework/{v0.6.8 → v0.6.9}/lib/nunjucks-filters/README.md +0 -0
  524. /package/framework/{v0.6.8 → v0.6.9}/lib/nunjucks-filters/package.json +0 -0
  525. /package/framework/{v0.6.8 → v0.6.9}/lib/nunjucks-filters/src/main.js +0 -0
  526. /package/framework/{v0.6.8 → v0.6.9}/lib/nunjucks-resolver/package.json +0 -0
  527. /package/framework/{v0.6.8 → v0.6.9}/lib/nunjucks-resolver/src/main.js +0 -0
  528. /package/framework/{v0.6.8 → v0.6.9}/lib/proc.js +0 -0
  529. /package/framework/{v0.6.8 → v0.6.9}/lib/release-watch/package.json +0 -0
  530. /package/framework/{v0.6.8 → v0.6.9}/lib/release-watch/src/main.js +0 -0
  531. /package/framework/{v0.6.8 → v0.6.9}/lib/render-cache/package.json +0 -0
  532. /package/framework/{v0.6.8 → v0.6.9}/lib/render-cache/src/main.js +0 -0
  533. /package/framework/{v0.6.8 → v0.6.9}/lib/render-cache-store.js +0 -0
  534. /package/framework/{v0.6.8 → v0.6.9}/lib/routing/README.md +0 -0
  535. /package/framework/{v0.6.8 → v0.6.9}/lib/routing/build.json +0 -0
  536. /package/framework/{v0.6.8 → v0.6.9}/lib/routing/package.json +0 -0
  537. /package/framework/{v0.6.8 → v0.6.9}/lib/routing/src/main.js +0 -0
  538. /package/framework/{v0.6.8 → v0.6.9}/lib/routing/src/radix.js +0 -0
  539. /package/framework/{v0.6.8 → v0.6.9}/lib/routing-introspect/package.json +0 -0
  540. /package/framework/{v0.6.8 → v0.6.9}/lib/routing-introspect/src/main.js +0 -0
  541. /package/framework/{v0.6.8 → v0.6.9}/lib/secrets/package.json +0 -0
  542. /package/framework/{v0.6.8 → v0.6.9}/lib/secrets/src/backends/file.js +0 -0
  543. /package/framework/{v0.6.8 → v0.6.9}/lib/secrets/src/env-file.js +0 -0
  544. /package/framework/{v0.6.8 → v0.6.9}/lib/session-store.js +0 -0
  545. /package/framework/{v0.6.8 → v0.6.9}/lib/shell.js +0 -0
  546. /package/framework/{v0.6.8 → v0.6.9}/lib/sqlite-driver.js +0 -0
  547. /package/framework/{v0.6.8 → v0.6.9}/lib/state.js +0 -0
  548. /package/framework/{v0.6.8 → v0.6.9}/lib/storage/package.json +0 -0
  549. /package/framework/{v0.6.8 → v0.6.9}/lib/storage/src/local-cas.js +0 -0
  550. /package/framework/{v0.6.8 → v0.6.9}/lib/storage/src/local-stream.js +0 -0
  551. /package/framework/{v0.6.8 → v0.6.9}/lib/storage/src/local.js +0 -0
  552. /package/framework/{v0.6.8 → v0.6.9}/lib/storage/src/main.js +0 -0
  553. /package/framework/{v0.6.8 → v0.6.9}/lib/storage/src/meta-store.js +0 -0
  554. /package/framework/{v0.6.8 → v0.6.9}/lib/storage/src/s3.js +0 -0
  555. /package/framework/{v0.6.8 → v0.6.9}/lib/storage/src/util.js +0 -0
  556. /package/framework/{v0.6.8 → v0.6.9}/lib/storage-store.js +0 -0
  557. /package/framework/{v0.6.8 → v0.6.9}/lib/swig-filters/README.md +0 -0
  558. /package/framework/{v0.6.8 → v0.6.9}/lib/swig-filters/package.json +0 -0
  559. /package/framework/{v0.6.8 → v0.6.9}/lib/swig-filters/src/main.js +0 -0
  560. /package/framework/{v0.6.8 → v0.6.9}/lib/swig-resolver/package.json +0 -0
  561. /package/framework/{v0.6.8 → v0.6.9}/lib/swig-resolver/src/main.js +0 -0
  562. /package/framework/{v0.6.8 → v0.6.9}/lib/template-loaders/package.json +0 -0
  563. /package/framework/{v0.6.8 → v0.6.9}/lib/template-loaders/src/loaders/http.js +0 -0
  564. /package/framework/{v0.6.8 → v0.6.9}/lib/template-loaders/src/loaders/memory.js +0 -0
  565. /package/framework/{v0.6.8 → v0.6.9}/lib/template-loaders/src/main.js +0 -0
  566. /package/framework/{v0.6.8 → v0.6.9}/lib/url/README.md +0 -0
  567. /package/framework/{v0.6.8 → v0.6.9}/lib/url/index.js +0 -0
  568. /package/framework/{v0.6.8 → v0.6.9}/lib/url/routing.json +0 -0
  569. /package/framework/{v0.6.8 → v0.6.9}/lib/uuid/package.json +0 -0
  570. /package/framework/{v0.6.8 → v0.6.9}/lib/uuid/src/main.js +0 -0
  571. /package/framework/{v0.6.8 → v0.6.9}/lib/validator.js +0 -0
  572. /package/framework/{v0.6.8 → v0.6.9}/lib/watcher/package.json +0 -0
  573. /package/framework/{v0.6.8 → v0.6.9}/lib/watcher/src/main.js +0 -0
  574. /package/framework/{v0.6.8 → v0.6.9}/lib/ws-framing/package.json +0 -0
  575. /package/framework/{v0.6.8 → v0.6.9}/lib/ws-framing/src/main.js +0 -0
  576. /package/framework/{v0.6.8 → v0.6.9}/lib/ws-query/package.json +0 -0
  577. /package/framework/{v0.6.8 → v0.6.9}/lib/ws-query/src/main.js +0 -0
  578. /package/framework/{v0.6.8 → v0.6.9}/lib/ws-session/package.json +0 -0
  579. /package/framework/{v0.6.8 → v0.6.9}/lib/ws-session/src/main.js +0 -0
package/CHANGELOG.md CHANGED
@@ -6,6 +6,24 @@ adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html),
6
6
  and is generated by [Changie](https://github.com/miniscruff/changie).
7
7
 
8
8
 
9
+ ## 0.6.9 - 2026-08-16
10
+ ### Added
11
+ * `gina.pushToSession(sessionID, payload[, option][, callback])` — a sanctioned way to push to a session from OUTSIDE a request (#B366). `self.push()` needs a live request-bound controller, so code that has none (a `lib/job` handler, a cron tick, a boot hook) had no route to a user's socket at all; the pattern consumers reached for instead — a background worker making an HTTP hop carrying the user's session id in the request body — was the #B364 vulnerability, and closing it left that shape with nowhere to go. This is the replacement, and it is deliberately narrow. The recipient is a REQUIRED argument: an absent or empty `sessionID` is an error, never a fan-out, and no broadcast is reachable from this API at all — the deliberate all-clients send stays in-request as `self.push(payload, { broadcast: true })`. Source the recipient from server-held state (capture it when the work is queued, keep it server-side); round-tripping a recipient id, or a token naming one, through the browser hands the choice back to the caller and re-opens #B364 one layer up. Delivery is reported rather than assumed: `callback(err, { delivered })` fires exactly once with the number of sockets written, and `delivered: 0` is a normal outcome (the user closed the tab), not an error — the shape this replaces was fire-and-forget and blind. Errors carry a machine-readable `err.code` (`PUSH_INVALID_RECIPIENT`, `PUSH_INVALID_PAYLOAD`, `PUSH_CHANNEL_NOT_CONFIGURED`, `PUSH_CHANNEL_NOT_READY`, `PUSH_PAYLOAD_SERIALIZE_FAILED`). Requires the isaac engine with `settings.json > server.ioServer` attached; the express engine has no engine.io channel and now says so by name instead of failing as a 500. Available as `lib.push.toSession()` for code holding its own server instance.
12
+ * A bundle can now declare which scopes it is deployed in, via an optional `scopes` allow-list on its `manifest.json` entry (#B373). Until now a registered bundle was deployed in EVERY scope, and the only way to exclude one was to leave it out of the manifest entirely — which removes it from all scopes at once. The motivating case is a bundle you are still building: `"scopes": ["local"]` keeps it running locally while every other scope behaves as though it does not exist. An ABSENT (or null) key means every scope, so existing manifests are completely unaffected; an empty array parks the bundle everywhere; and a value that is not an array is reported as a manifest error by name rather than silently read as "no scopes". The semantics deliberately mirror a route's rule-level `scopes`. How an exclusion is reported depends on whether you asked for it: the boot and `gina project:build` SKIP an excluded bundle with a notice naming the scope and the one-line remedy, so one parked bundle never blocks a project build; starting an excluded bundle, or naming it explicitly in `gina bundle:build <name> --scope=<scope>`, is REFUSED by name, because silently producing no artifact would read as success in a deploy script. Note that deleting a bundle's `releases.<scope>` entry by hand was never a working substitute for this: both build commands walk every scope in the project and re-create any missing release entry, so a hand-deleted one reappears on the next build. A `scopes` declaration also survives `gina project:add` and `gina project:import`: the long-standing manifest reset those commands used to perform on a bundle-count mismatch — which would have silently dropped this key — is fixed in this same release (#B375), so the declaration round-trips.
13
+ ### Fixed
14
+ * `self.push()` now refuses by name when the server instance has no engine.io channel, instead of failing as an opaque 500 (#B371). The push channel is an isaac-engine facility — `serverInstance.eio` is attached there and nowhere else — so on the express engine the client lookup dereferenced an absent `eio` and surfaced as a TypeError-derived 500 whose message named neither push nor the missing channel, leaving "why is this route 500-ing?" as the only signal a developer got. It now warns, hands a supplied `callback` a `PUSH_CHANNEL_NOT_CONFIGURED` error, and sends nothing — WITHOUT failing the request, so a notification side-channel no longer takes down the response it rode in on. This is also the first time push() honours the `callback(err, result)` contract its own documentation has always described: the body accepted a callback and forwarded it to the transport, but never once invoked it itself. The condition is structural rather than per-call — the channel either exists in this process or it never will — so it is reported identically on every call, matching the refusal `gina.pushToSession()` gives for the same cause.
15
+ * A bundle whose release tree cannot be linked now refuses to boot with a message naming the bundle, the env and the scope, instead of an opaque `TypeError` (#B372). The config loader links each registered bundle's release target for a non-dev env and, when that fails, builds a `[ releaseError ]` carrying the offending path — but the receiving callback never inspected its error argument and dereferenced the (absent) configuration object instead, so the useful reason was discarded and the process died on `TypeError: Cannot set properties of undefined (setting 'env')` as an uncaughtException. The server never binds, so a startup probe sees only a refused connection, and the error points at framework internals rather than at the path an operator has to fix. Because the configuration load is shared across the project, ONE bundle's missing release tree took down EVERY bundle in it. The error is now propagated and reported through the same sink the bundle-configuration loader already used — logged, flushed synchronously to stderr so the reason survives on an async pipe, then a clean exit 1. Note that omitting a bundle's `releases.<scope>` entry is NOT how you mark it as undeployed — that produces this same refusal rather than skipping the bundle. To exclude a bundle from a scope deliberately, use the `scopes` allow-list on its manifest entry, added in this same release.
16
+ * The path helper's file copier — the byte-writer behind `_().cp()` and `PathObject.mv()`, which CLI copy, build and rename paths ride — no longer destroys or truncates the destination on a failed copy (#B227). Bytes now stage to a temp sibling in the destination's directory and publish with an atomic rename, so a reader never observes a partial file and a pre-existing destination is replaced only on success (previously it was unlinked BEFORE the copy started); a source-side read error is now handled instead of raising an unhandled `error` event that killed the process; a failed copy settles the callback exactly once (previously a destination-side failure settled twice — the second time as a success, which forked directory-copy recursion); and failures propagate a real `Error` (previously a plain string, so callers printing `err.stack` logged `undefined`). Contract note: a consumer matching the exact pre-existing failure string `Error on Path.cp(...): Not found ...` now receives an `Error` whose message names the copy that failed.
17
+ * A bundle with `engine: "express"` now boots and serves on Express 5, and the supported range is declared for the first time (#B211). Express 5 broke the engine twice over: its router rejects the bare-string `'*'` catch-all at mount time (the bundle aborted with `TypeError: Missing parameter name` before ever listening), and it turned `req.query` into a prototype getter, so even past the mount every request died on the framework's strict-mode query assignment. The catch-all now mounts a RegExp (accepted and verified live-dispatching on Express 4 AND 5 — no version branching; inert on the default isaac engine, which never reads the pattern), and the Express adapter shadows `query` on the per-app request prototype with a writable property (a measured no-op on Express 4). The adapter also logs the detected Express version at engine construction — supported range `>= 4 < 6`, both majors verified live — and an out-of-range major logs a loud warning but still boots. Express remains consumer-provided: it is deliberately not a dependency of the framework, and not a peerDependency either, since npm 7+ auto-installs peers.
18
+ * The secrets resolver no longer lets a swept framework-environment value beat `process.env`, and three malformed `settings.secrets.file` shapes that used to pass in silence are now caught (#B270, #B271, #B272). **Precedence (#B270):** the two environment tiers were joined with `||`, and `filterArgs()` stores swept `GINA_*`/`VENDOR_*`/`USER_*` values as REAL booleans — so a key whose swept value was boolean `true` satisfied the short-circuit, `process.env` was never consulted, and the file tier won over a perfectly good environment variable. That inverts the precedence the file backend exists to enforce: a stale plaintext file could shadow the credential the platform injected. The tiers are now read independently and only a non-empty STRING from the framework tier wins. **Shape guards (#B271, #B272), all three affecting boot:** an empty array still disables the file tier exactly like `null` — boot is not refused, since an empty list genuinely means "no files" — but it now WARNS, because emptying the array to drop one layer drops the whole tier and used to do so without a word. A whitespace-only entry is now REFUSED rather than building a tier that can never resolve anything: the schema's `minLength: 1` counts a space, so `[" "]` cleared both layers and failed only as a suppressed debug line. And a path containing an empty segment (`//`) is now REFUSED, which is what a `${...}` token that resolved to an EMPTY value leaves behind — `${homedir}/${scope}/secrets.env` with an empty scope collapses to a read of the file one directory UP, silently, with no unresolved token left for the existing guard to catch. ACTION REQUIRED if a config carries either refused shape, and each error names the offending path. The whitespace-only entry is a typo rather than a working configuration. The empty segment may NOT be: the dangerous cause is a token that resolved to nothing, but a token carrying a trailing slash produces the same `//` and resolves to exactly the intended file — `GINA_HOMEDIR=/opt/gina/` with the documented `"${homedir}/secrets.env"` is the shape to check. That configuration worked before this release and now refuses to boot. The two are indistinguishable by the time the path is assembled, so boot refuses on both rather than risk running a bundle on the wrong credential, and the error names both causes; removing the doubled separator, or the trailing slash from the token, resolves it. Both guards apply only to configs that declared `settings.secrets.file`, which is opt-in and absent by default. The schema gains `minItems: 1` as an editor-facing hint — no runtime validator reads `schema/settings.json`, so the runtime guard is the enforcement.
19
+ * `gina project:add` now writes the project's `.gitignore`, which it never did (#B258, #B291). The framework has always shipped a `core/template/_gitignore` whose `_` prefix implies a rename to the dotted form at scaffold time — but nothing performed that rename, so the template had zero consumers and every scaffolded project came out with no `.gitignore` at all. The practical consequence was that the secret-file globs the template carries (`.env`, `.env.*`, `*.env`, with `!.env.example` negations so a sample can still be committed) protected nothing: a new project would happily track a `secrets.env` or `.env.production` on its first commit. The glob shape is the point — a bare `.env` matches neither of those names. The copy is SKIP-IF-EXISTS: your `.gitignore` is your file, routinely carrying rules the framework knows nothing about, so the scaffold fills a gap and never replaces or appends to one. That also makes it idempotent, so re-running `project:add` over an existing project changes nothing. It applies to the import path as well as to new projects, since an imported project without a `.gitignore` has exactly the same exposure. A failure to read the template warns rather than aborting — a scaffold that produced an otherwise complete project should not die over an ignore file. No action required: existing projects are untouched, and if you already have a `.gitignore` you will not notice this at all.
20
+ * `gina project:add` and `gina project:import` no longer destroy `manifest.json` bundle declarations when the declared bundle count differs from what is on disk (#B375). Previously, ANY count mismatch made those commands empty the whole `bundles` block and rebuild it from the directory listing — dropping every key the rebuild template does not carry (the new `scopes` allow-list, `gina_version`, any custom key) and resetting each bundle's `version`, `tag` and release targets to defaults — and the reset hit EVERY registered project on the machine, not just the one being added or imported: a bystander project got no rebuild at all and was left with a permanently empty `bundles` block that fails its next boot. Plain `project:add` suffered the same total loss, since only the import path rebuilds. The commands now treat the manifest as the authority: declared bundles are preserved untouched, bundles found on disk but missing from the manifest are still registered additively on import (the legitimate function the old reset served), and a declared bundle whose directory is absent is reported with a warning naming the bundle and the scanned location — never auto-pruned, since the declaration may be deliberate (e.g. a bundle restricted to other scopes). Removing an entry for good remains `gina bundle:remove`'s job. Also guarded: importing a project whose manifest declares a bundle with no tree on disk no longer risks a crash in the port/settings pass.
21
+ * During `gina project:add`/`gina project:import`, the rescan that registers bundles found on disk built a wrong `settings.json` path for every bundle after the first — the scan root grew by one path segment per bundle, so the second bundle's settings were looked up under the first bundle's directory, the third under the first two, and so on (#B376). Only the first bundle's settings file could ever be found by the pass that reconciles a bundle's declared protocol and scheme with the project's lists; every later bundle was silently skipped. Each bundle's path is now derived from the scan root and its own name.
22
+ * A project's `protocols` and `schemes` lists in `~/.gina/projects.json` can no longer be polluted by a bundle's invalid `server.protocol`/`server.scheme` declaration — nor by another project's bundles (#B378, #B379). Two defects compounded here. First, `gina project:add`/`gina project:import` adopted whatever protocol or scheme a bundle's `settings.json` declared straight into the project's registry lists, unchecked: an arbitrary string became a registered "valid" value, persisted, and `gina image:build` then baked the polluted list into the synthesized container image's environment. Second, the same pass resolved every registered project's bundles against the path of the project being added or imported — so when two projects each had a bundle of the same name (an `api` or `web` in both, say), one project's declarations silently leaked into the OTHER project's registry entry, from a command that never named it. Both are fixed under one contract: the framework's supported sets in `~/main.json` are the authority, and a project's lists stay a subset of them. A bundle's declared value may still extend its own project's list when the framework supports it (that is how the port matrix learns what a project's bundles use); an unsupported value is now reported by name — bundle, value, and the allowed set — once per command, and is adopted nowhere, not even as the bundle entry's default. Each project's bundles are resolved against that project's own path. The import-time heal that rewrites an invalid bundle declaration to the project default still runs (it is what keeps the bundle bootable), but it now reports each change by name (`server.protocol "x" -> "http/1.1"`) as a warning instead of rewriting the file behind a debug line.
23
+ * The port-setup merge that folds newly seen protocols and schemes into a project's registry lists read the wrong array — the project's own list indexed by the contextual list's position — so once the contextual list outgrew the project's, the overshoot read `undefined` (#B380). No user-visible consequence was demonstrated (a scene built to arm the overshoot produced none), so this ships as a correctness fix: the merge now reads the contextual list by its own index, exactly as the environment merge beside it always did, and it admits only values the framework supports — the contextual list also grows from `ports.json` keys, which can retain protocols a framework update removed, and those no longer re-enter the project's lists.
24
+ ### Security
25
+ * An engine.io socket's session identity is now derived SERVER-side instead of being asserted by the client (#B365). The socket's `sessionId` — the value every targeted `self.push()` matches against — used to be set from `payload.session.id`, a field the browser sends, on every message, never checked against the connection's own session. Any client could therefore claim another user's session and receive the pushes addressed to it; and because a rendered page carries the BARE session id in its bootstrap script while the cookie carries the signed form, claiming one required strictly less than stealing the cookie. Affects every published release that attaches `server.ioServer`. The binding now happens once, at connection, from the upgrade request's own cookie: gina replays the bundle's OWN session middleware over that request, so the same secret, store and cookie name apply with no new configuration and no framework access to the secret — and it works whether or not the bundle adopted `gina.plugins.Session()`. The response handed to that middleware is inert, so a socket upgrade can never emit `Set-Cookie` or persist a session. It fails CLOSED: no session middleware, no cookie, or a cookie that does not verify leaves the socket with no id, and an id-less socket matches no targeted push — it receives only deliberate broadcasts. A client that still asserts an id is logged and ignored, which doubles as an impersonation detector. This is the receiver half of the axis #B364 left open: that fix decided who a SENDER may aim at, this one decides how a RECEIVER proves who it is.
26
+
9
27
  ## 0.6.8 - 2026-08-15
10
28
  ### Added
11
29
  * Storage drivers can now read a byte range. `getRange(key, start, end, cb)` ships on every local strategy (`sharded`, `cas` and `stream`) and `capabilities.ranges` is true for all of them, where it was false in every prior release. `end` is INCLUSIVE, matching the HTTP `Range` header, so a header's byte offsets pass through unchanged; an `end` past the last byte is clamped rather than refused, and only a `start` at or beyond the object's size is unsatisfiable — that is the caller's `416`. Both size tiers answer (an inline object slices its stored bytes, a published one gets a positioned read), and under `cas` a released blob stays invisible to `getRange()` exactly as it already is to `get()`. The serving half ships alongside it: `self.serveFromStorage()` answers `206`/`416`/`304` with `Accept-Ranges`/`Content-Range` on both engines, gated on `capabilities.ranges`, so a controller only reaches for raw `getRange()` when it wants custom protocol handling.
package/README.md CHANGED
@@ -61,38 +61,35 @@ open https://localhost:3100
61
61
 
62
62
  > **npm 12+** blocks install scripts by default, and gina's post-install bootstraps `~/.gina` and the framework dependencies. Install with `npm install -g gina@latest --allow-scripts=gina`, or allow it once for all global installs with `npm config set allow-scripts=gina --location=user`. (Not needed on npm ≤ 11.)
63
63
 
64
- ## What's in 0.6.8
64
+ ## What's in 0.6.9
65
65
 
66
- > **Restart your bundles — no re-bake this time.** The browser bundle is
67
- > byte-identical to `0.6.7`, so `gina bundle:restart` is enough; everything below
68
- > is server-side. (`0.6.7` did need the rebuild — this one does not.)
66
+ > **Restart your bundles — no re-bake.** The browser bundle is byte-identical to
67
+ > `0.6.8`, so `gina bundle:restart` is enough; everything below is server-side
68
+ > or CLI.
69
69
 
70
- > **No settings reset.** `0.6.8` is a patch — the `shortVersion` stays `0.6`, so
70
+ > **No settings reset.** `0.6.9` is a patch — the `shortVersion` stays `0.6`, so
71
71
  > your `~/.gina/0.6/settings.json` is untouched. (`0.6.0` was the reset.)
72
72
 
73
- **This release fixes two security flaws, and both were live in every published
74
- version up to and including `0.6.7`.** One of them changes behaviour you may be
75
- relying on: `self.push()` no longer lets the request choose who receives a push,
76
- which stops a pattern some applications use to report background-job progress.
77
- Read that entry before upgrading. Both are covered in the
78
- [migration guide](https://gina.io/docs/migration).
79
-
80
- - **Security — `self.push()` decides its own recipient.** The recipient was read from the request body, so a caller could aim a push at any session by sending a session id and omitting that id broadcast to *every* connected client. The payload defaults to request input too, so on any route reaching `push()` an unprivileged caller could deliver arbitrary content to everyone, or to a chosen victim. The recipient is now decided server-side: an explicit `option.sessionID` wins, otherwise the caller's own session; with neither a resolvable session nor a deliberate `{ broadcast: true }`, `push()` sends nothing and warns, where it previously fell open to everybody. The request body can no longer influence the recipient at all. **Action required if you push at all:** a bare `self.push()` driven over an HTTP hop by a background worker a job runner reporting progress to the user who queued it, threading that user's session id through the request now resolves to the caller's own session and stops delivering. That pattern *is* the vulnerability, so it cannot be preserved; but be aware there is no in-process substitute yet, because `push()` is reachable only from a live request-bound controller. Until an explicit out-of-request channel exists, poll `GET /_gina/jobs/:id` or use a transport your application owns. In-request callers are unaffected unless they relied on the implicit fan-out, which now needs `{ broadcast: true }`.
81
- - **Securityforwarded headers can no longer inject script.** `X-Forwarded-Host`, `X-Forwarded-Proto`, `X-Forwarded-Prefix` and the request's own `Host` were spliced unescaped into the client bootstrap script gina emits on every rendered page, landing inside JavaScript string literals. A header containing a single quote closed the literal and ran attacker-chosen script in the browser of anyone served that page no authentication, any route that renders a view. Forwarded values are now validated where they are read: a host must be a hostname with an optional port or a bracketed IPv6 literal, a scheme must be exactly `http` or `https`, and a path prefix must be URL-path characters only. Anything else is refused and the request falls back to the bundle's own configured host and webroot, exactly as if the header had never been sent. Whether you were reachable depended on your proxy one that sets or strips the `X-Forwarded-*` headers it forwards never passed an injected value through, while a bundle exposed directly, or behind a proxy relaying client headers verbatim, could be driven by any anonymous caller. No action beyond upgrading; a well-formed host, scheme and prefix behave identically.
82
- - **Added — storage metadata on Couchbase, which makes a driver root shareable.** The embedded SQLite store is single-process-per-root, so two bundles or two replicas of one could not share a root until now. Point a driver's `store` at a `connectors.json` entry whose connector is `couchbase` and every metadata row, inline payloads included, lives on the cluster. Per-key atomicity comes from Couchbase's own CAS, so `cas` reference counting behaves exactly as on the embedded store, and the GC sweep needs no election layer when several replicas run it at once the claim step is itself compare-and-set, so each blob is collected exactly once. Rows are namespaced by driver name. The two secondary indexes the maintenance verbs need are created at boot when missing; if the account may not create them the boot still succeeds and the exact `CREATE INDEX` statements are logged. Inline payloads are base64-encoded inside the document, which costs about a third more space and puts a practical ceiling near a 14MB `inlineThreshold`.
83
- - **Addeda `stream` strategy for large sequential media, with resumable uploads.** Keys name an *asset* rather than a file (`assets/<ulid>/original<ext>`), so an object and anything later derived from it live in one directory you can move or delete as a unit. Alongside `put()`, a stream driver carries `createUpload()`, `writeSegment()` (at a byte offset segments may arrive out of order and in parallel, and re-sending a landed range is harmless), `statUpload()` (which reports what is still *missing*), `finalize()` and `abortUpload()`. Sessions survive a restart. `createUpload()` requires the object's total size deliberately: without it nothing can verify the received ranges actually cover the object. Finalise checks coverage as an interval union and refuses to publish a gap an unwritten range reads back as zeros rather than failing, so a finalise that merely summed what it received could publish a plausible object with silently wrong bytes. Finalise is idempotent. New optional per-driver keys: `chunkSize` (default `"8MB"`), `sessionTtl` (`"24h"`) and `sessionSweepInterval` (`"1h"`).
84
- - **AddedHTTP Range serving for stored objects.** `self.serveFromStorage(driverName, key[, opts])` is the read-side companion of `store()`'s driver routing, and owns the whole protocol dance on both engines: `stat()`-gated 404s, a strong ETag minted from the immutable storage key, conditional GET answering 304 with no driver read, and single-range `bytes=` evaluation a satisfiable range answers 206 with an exact `Content-Length`, an unsatisfiable one 416, and multi-range lists, foreign units and syntactic garbage fall back to the full 200 as RFC 9110 sanctions. Every response carries `X-Content-Type-Options: nosniff`, and a stored `contentType` for active-content types (html/xml/svg/javascript) downgrades to `application/octet-stream` unless you pass an explicit `opts.contentType`. `opts.download`/`opts.filename` emit an RFC 6266 attachment disposition.
85
- - **Addedthe `s3` storage adapter, completing the pluggable object-storage layer.** `adapter: 's3'` plus a `bucket` stores objects on any S3-compatible provider (AWS S3, Scaleway, MinIO, R2…) under the sharded key grammar. Storeless by design: the provider carries each object's metadata on the object itself, so there is no metadata store, no tiering and no drift class to verify. The SDK stays your project's dependency install `@aws-sdk/client-s3`, `@aws-sdk/lib-storage` and `@aws-sdk/s3-request-presigner`; a configured s3 driver whose SDK is missing refuses the boot with that hint. `resolve()` answers `{kind: 'url'}` with a presigned GET, and `capabilities.offload` flips true for the first time: `serveFromStorage()` answers GET/HEAD with a 307 to the presigned URL after the local 304 check, with the content-type downgrade riding the signed `response-content-type` so the stored-XSS guard holds when the provider serves the bytes. `opts.offload: false` keeps the in-process proxy path. Static credentials are optional; omitted, the SDK's default provider chain runs.
86
- - **Addedstorage drivers can read a byte range.** `getRange(key, start, end, cb)` ships on every local strategy (`sharded`, `cas`, `stream`), returning a readable stream over the requested slice.
87
- - **Addedmachine-readable storage read errors.** Read-verb failures now carry `err.code` `STORAGE_NO_OBJECT` for an unknown, released or vanished key, and siblings for the other classes so callers can branch on the cause instead of matching message text.
88
- - **AddedCouchbase soak probes ship in the package.** The soak probes for the Couchbase metadata store live at `script/soak/storage/`, so you can exercise a cluster-backed driver root against your own deployment rather than trusting ours.
89
- - **Changed`renderStream()` is byte-serving-capable.** On non-SSE content types, `Buffer` chunks now pass through verbatim instead of being UTF-8-decoded binary payloads previously arrived corrupted, with every invalid-UTF-8 byte replaced by U+FFFD. Valid-UTF-8 buffers re-encode byte-identically, so text consumers are unaffected, and SSE keeps its decode. HEAD requests answer headers-only without consuming the iterable (a destroyable source is destroyed rather than leaking its handle), and the delegate's default headers now yield to values the caller pre-set instead of clobbering them.
90
- - **Fixed — `renderStream()` honours a caller-set status code on both engines.** The HTTP/2 arm built its response headers before the caller's status was read, so a streamed 206 or 404 went out as 200.
91
- - **Fixed — `renderStream()` no longer throws a swallowed `TypeError` at the end of every streamed response.** The post-end `headersSent` bookkeeping ran against a response object that no longer accepted it.
92
- - **Fixed — a redirect no longer treats `HEAD` as a wrong method.** `HEAD` is a safe method — `GET` without a response body — but the redirect path rejected it as if it were a write.
93
- - **Fixed — a redirect keeps the caller's query string under `keep-params: true`.** The declared parameters were carried but the query string was dropped.
94
- - **Fixed — a `sharded` driver reclaims temp files left by a crashed `put()`.** A `put()` whose *process* died left its temp file behind to accumulate forever; an age-gated best-effort sweep now clears them.
95
- - **Fixed — a refused or interrupted `put()` leaves no temp residue.** The stray temp file a rejected write left in a local storage root is now removed on the failure path.
73
+ **This release fixes one security flaw, live in every published version that
74
+ attaches `server.ioServer`.** It closes the receiver half of the axis `0.6.8`
75
+ opened, and it fails closed so if you use targeted pushes, confirm they still
76
+ arrive after upgrading. Separately, two malformed `settings.secrets.file` shapes
77
+ now refuse to boot; check that config if you use the file tier. Both are covered
78
+ in the [migration guide](https://gina.io/docs/migration).
79
+
80
+ - **Security — an engine.io socket's session is now proven, not claimed.** A socket's `sessionId` — the value every targeted `self.push()` matches against was set from `payload.session.id`, a field the browser sends, on every message, and was never checked against the connection's own session. Any client could therefore claim another user's session and receive the pushes addressed to it; and because a rendered page carries the *bare* session id in its bootstrap script while the cookie carries the signed form, doing so took strictly less than stealing the cookie the signature exists to protect. The binding now happens once, at connection, from the upgrade request's own cookie: gina replays the bundle's own session middleware over that request, so the same secret, store and cookie name apply with no new configuration and no framework access to your secret and it works whether or not the bundle adopted `gina.plugins.Session()`. The response handed to that middleware is inert, so a socket upgrade can never emit `Set-Cookie` or persist a session. It fails closed: no session middleware, no cookie, or a cookie that does not verify leaves the socket with no id, and an id-less socket matches no targeted push. A client that still asserts an id is logged and ignored, which doubles as an impersonation detector. No code change is needed but because the failure direction is silence rather than an error, verify your targeted pushes still land.
81
+ - **Added`gina.pushToSession()`, a sanctioned push from outside a request.** `self.push()` needs a live request-bound controller, so a `lib/job` handler, a cron tick or a boot hook had no route to a user's socket at all and the pattern reached for instead, a worker making an HTTP hop carrying the session id in the request body, *was* the flaw `0.6.8` closed. This is the replacement `0.6.8` promised, and it is deliberately narrow: the recipient is a required argument, an absent or empty `sessionID` is an error rather than a fan-out, and no broadcast is reachable from this API at all (a deliberate all-clients send stays in-request as `self.push(payload, { broadcast: true })`). Source the recipient from server-held state round-tripping a recipient id, or a token naming one, through the browser hands the choice back to the caller and re-opens the same flaw one layer up. Delivery is reported rather than assumed: `callback(err, { delivered })` fires exactly once with the number of sockets written, and `delivered: 0` is a normal outcome, not an error. Errors carry a machine-readable `err.code`. Requires the `isaac` engine with `server.ioServer` attached; also available as `lib.push.toSession()`.
82
+ - **Added — a bundle can declare which scopes it is deployed in.** An optional `scopes` allow-list on a bundle's `manifest.json` entry replaces the all-or-nothing choice between "registered everywhere" and "not in the manifest at all". The motivating case is a bundle you are still building: `"scopes": ["local"]` keeps it running locally while every other scope behaves as though it does not exist. An absent or null key means every scope, so existing manifests are completely unaffected; an empty array parks the bundle everywhere; a non-array value is reported as a manifest error by name. How an exclusion is reported depends on whether you asked for it the boot and `gina project:build` skip an excluded bundle with a notice, so one parked bundle never blocks a project build, while starting it or naming it in `gina bundle:build --scope=` is refused by name, because silently producing no artifact would read as success in a deploy script.
83
+ - **Fixed — `engine: "express"` bundles boot and serve on Express 5.** Express 5 broke the engine twice over: its router rejected the bare-string `'*'` catch-all at mount time, so the bundle aborted before ever listening, and it turned `req.query` into a prototype getter, so even past the mount every request died on the framework's strict-mode query assignment. Both are fixed, and the supported range is declared for the first time `>= 4 < 6`, with both majors verified live. An out-of-range major logs a loud warning but still boots, since a wrong refusal is a total outage while a wrong warning is a log line. Express remains yours to provide: it is deliberately neither a dependency nor a peer dependency.
84
+ - **Fixed`project:add` / `project:import` no longer rebuild the `bundles` block destructively.** Any mismatch between the declared bundle count and what was on disk made those commands empty the whole block and rebuild it from the directory listing dropping every key the rebuild template does not carry (the new `scopes` allow-list, `gina_version`, any custom key) and resetting each bundle's version, tag and release targets. The reset hit *every* registered project on the machine, not just the one being named: a bystander project got no rebuild at all and was left with a permanently empty `bundles` block that fails its next boot. The manifest is now the authority declared bundles are preserved untouched, bundles found on disk but missing from the manifest are still registered additively on import, and a declared bundle whose directory is absent is reported with a warning rather than auto-pruned. A related path bug is fixed with it: the rescan built a wrong `settings.json` path for every bundle after the first, so only the first bundle's settings could ever be found.
85
+ - **Fixedregistration no longer adopts invalid protocol/scheme declarations, nor reads other projects' bundles.** `project:add`/`project:import` adopted whatever `server.protocol` or `server.scheme` a bundle declared straight into the project's registry lists, unchecked an arbitrary string became a registered "valid" value, persisted, and `gina image:build` then baked the polluted list into the synthesized image's environment. The same pass also resolved *every* registered project's bundles against the path of the project being added, so when two projects each had a bundle of the same name, one project's declarations leaked into the other's registry entry from a command that never named it. The framework's supported sets are now the authority, a project's lists stay a subset of them, an unsupported value is reported by name and adopted nowhere, and each project's bundles are resolved against that project's own path.
86
+ - **Fixed`project:add` writes the project's `.gitignore`.** The framework has always shipped a `core/template/_gitignore` whose underscore prefix implies a rename at scaffold time, but nothing performed that rename — so the template had zero consumers and every scaffolded project came out with no `.gitignore` at all, leaving the secret-file globs it carries protecting nothing. The copy is skip-if-exists, so your own file is never replaced or appended to, and re-running the command changes nothing.
87
+ - **Fixeda failed file copy can no longer destroy the destination it was replacing.** The path helper's copier — the byte-writer behind `_().cp()` and `PathObject.mv()`, which CLI copy, build and rename paths all ride — wrote directly to the final name and unlinked an existing destination *before* the copy started. Bytes now stage to a temp sibling and publish with an atomic rename, so a reader never observes a partial file and the destination is replaced only on success. A source-side read error is handled instead of killing the process, a failed copy settles its callback exactly once, and failures propagate a real `Error` rather than a plain string. **Contract note:** code matching the exact former failure string now receives an `Error` instead.
88
+ - **Fixedthe environment beats the secrets file again, and three malformed `secrets.file` shapes are caught.** The two environment tiers were joined with `||`, and the CLI stores swept `GINA_*`/`VENDOR_*`/`USER_*` values as real booleans — so a key whose swept value was boolean `true` satisfied the short-circuit, `process.env` was never consulted, and the file tier won over a perfectly good environment variable, letting a stale plaintext file shadow a platform-injected credential. The tiers are now read independently. **Action required if you use the file tier:** a whitespace-only entry and a path containing an empty segment (`//`) now refuse to boot rather than failing as a suppressed debug line. The empty segment is worth a look — it is what a `${...}` token that resolved to nothing leaves behind, but a token carrying a *trailing slash* produces the same shape and resolves to exactly the intended file, so a config that worked before will now refuse; removing the doubled separator resolves it.
89
+ - **Fixeda bundle whose release tree cannot be linked says which bundle, and why.** The config loader built a useful error carrying the offending path, but the receiving callback never inspected it and dereferenced the absent configuration object instead — so the reason was discarded and the process died on an opaque `TypeError`. Because the configuration load is shared across the project, one bundle's missing release tree took down every bundle in it. The error is now reported through the same sink the bundle-configuration loader already used, naming the bundle, env and scope.
90
+ - **Fixed — `self.push()` refuses by name when there is no engine.io channel.** The push channel is an isaac-engine facility, so on the Express engine the client lookup dereferenced an absent `eio` and surfaced as an opaque 500 that named neither push nor the missing channel. It now warns, hands a supplied callback a `PUSH_CHANNEL_NOT_CONFIGURED` error, and sends nothing — without failing the request, so a notification side-channel no longer takes down the response it rode in on. This is also the first time `push()` honours the `callback(err, result)` contract its documentation always described.
91
+ - **Fixed — the port-setup merge read the wrong list.** The pass that folds newly seen protocols and schemes into a project's registry lists indexed the project's own list by the contextual list's position, so once the contextual list outgrew it the overshoot read `undefined`. No user-visible consequence was demonstrated, so this ships as a correctness fix.
92
+
96
93
  ## Documentation
97
94
 
98
95
  Full installation guide, tutorials, configuration reference, and API docs at **[gina.io/docs](https://gina.io/docs/)**.
package/ROADMAP.md CHANGED
@@ -59,7 +59,8 @@ This roadmap covers planned features, architectural improvements, new connectors
59
59
  | **Q4 2026** | `0.6.5` ✅ | **Fixed**: the silent-dead-control release — a family of defects where a control looked completely normal and did nothing at all. A submit trigger disabled by your own double-submit guard during the click (a `0.6.4` regression), a submit button whose DOM node an AJAX update or popin re-render replaced, a form left blocked after its async uniqueness check came back clean, a popin close button given your own id or wrapping an icon, a `data-gina-link` given your own id, and a popin holding several forms releasing only every other one — all now work. Trusted gestures (Enter, wrapped-label clicks) respect the submit gate; `data-gina-link` stops swallowing `download`, `target`, `#`-fragment and modified clicks, and gains the disabled gate it never had; download filenames parse and serialize per RFC 6266; `gina.setOptions()` writes the config the framework reads, having been silently ignored since it shipped; `isRequired` accepts padded input and `trim` strips both sides · **Changed**: the not-ready submit-trigger state moves off `aria-disabled` onto the framework-owned `data-gina-form-submit-gated`, with a default look — the marker no longer claims a control is inoperable while gina deliberately answers its click |
60
60
  | **Q4 2026** | `0.6.6` ✅ | **Fixed**: the logging-transport release. A slow boot no longer silences a bundle's logging for the life of the process — a two-second connect deadline added in `0.6.5` read a socket flag Node clears one event-loop phase later, so any boot that blocked the loop past it destroyed a connection the kernel had already established (every container start and network-filesystem mount was exposed, and the transport never redialled). The MQ and file log transports also stopped dialling `host_v4`, which on a `~/.gina` shared across hosts silently shipped every log line off-host while all connection lines read healthy. Plus: the popin `success` event fires again instead of raising a 422 carrying the successful response body; a link request belongs to the anchor you clicked rather than the first anchor sharing its url; and constructing the link handler twice no longer corrupts the first instance · **Added**: the log transport reconnects — exponential backoff to a 30-second ceiling, one report per outage, frames dropped rather than queued while down so an outage cannot grow memory |
61
61
  | **Q4 2026** | `0.6.7` ✅ | **Added**: the object-storage release — a `storage` block declares named drivers (an adapter crossed with a strategy) reachable as `gina.storage()`, publishing objects atomically under opaque keys with their metadata written through a pluggable store seam; a content-addressed `cas` strategy deduplicates identical bytes behind a reference count, reclaiming them only after a grace-gated sweep; size tiering keeps sub-`64KB` objects inline in the metadata store, measurably faster than per-file writes; `storage:stats` / `storage:gc` / `storage:verify` operate a bundle's drivers whether it is running or stopped, through always-on admin-gated endpoints; and an upload group can route its `self.store()` step straight into a driver · **Security**: bound query parameter values no longer reach dev consoles or the Inspector query log — count and type markers replace them, with `inspector.queries.captureValues` to opt back in · **Fixed**: the `is` rule compiles regex literals as authored instead of stripping their parentheses (stricter — review patterns containing parens), forms with an async `query` rule complete correctly across a cluster of interacting defects (a submit leaving before the verdict landed, a completion carrying only the query field's slice, a re-click clearing later fields' errors, a clean form whose query field was not declared last never submitting at all, replayed submits from stale listeners, and an id-less trigger bound twice), `getConfig().settings` resolves path placeholders, `req.files[].group` reports the resolved group instead of `undefined`, and the Inspector's Data and Forms tabs stop putting framework-internal keys and the bundle catalog above your own data · **Changed**: framework default looks ship inside a `@layer gina` cascade layer, so any un-layered project rule overrides them without `!important` |
62
- | **Q4 2026** | `0.6.8` ✅ | **Security**: `self.push()` decides its recipient server-side instead of reading it from the request, where a supplied session id aimed the push at any session and an absent one broadcast to every connected client (ACTION REQUIRED — a background worker pushing over an HTTP hop stops delivering; poll `GET /_gina/jobs/:id` in the meantime) · forwarded headers (`X-Forwarded-Host`, `-Proto`, `-Prefix` and the request's own `Host`) are validated where they are read, closing a reflected-XSS path that spliced them unescaped into the client bootstrap script emitted on every rendered page · **Added**: storage metadata can live on Couchbase, which is what makes a driver root shareable across bundles and replicas; a `stream` strategy for large sequential media brings resumable, out-of-order, restart-surviving uploads whose finalise verifies coverage as an interval union and refuses to publish a gap; HTTP Range serving through `self.serveFromStorage()` on both engines, with conditional GET and a fail-closed content-type downgrade; the `s3` adapter completes the pluggable object-storage layer, storeless by design and able to offload GET/HEAD to a presigned URL; `getRange()` on every local strategy; machine-readable `err.code` on storage read verbs; and the Couchbase soak probes ship in the package · **Changed**: `renderStream()` is byte-serving-capable — `Buffer` chunks pass through verbatim on non-SSE content types (binary payloads previously arrived corrupted), HEAD answers headers-only without consuming the iterable, and caller-set headers are no longer clobbered · **Fixed**: `renderStream()` honours a caller-set status on both engines and stops throwing a swallowed error at the end of every streamed response, a redirect treats `HEAD` as the safe method it is and keeps the caller's query string under `keep-params: true`, and a local storage driver reclaims the temp files left behind by a crashed or refused `put()` |
62
+ | **Q4 2026** | `0.6.8` ✅ | **Security**: `self.push()` decides its recipient server-side instead of reading it from the request, where a supplied session id aimed the push at any session and an absent one broadcast to every connected client (ACTION REQUIRED — a bare worker push over an HTTP hop that carried the recipient IN THE REQUEST stops delivering; where the hop is authenticated the controller can pass `{ sessionID }` explicitly and keep working, and a worker with no request context at all polls `GET /_gina/jobs/:id`) · forwarded headers (`X-Forwarded-Host`, `-Proto`, `-Prefix` and the request's own `Host`) are validated where they are read, closing a reflected-XSS path that spliced them unescaped into the client bootstrap script emitted on every rendered page · **Added**: storage metadata can live on Couchbase, which is what makes a driver root shareable across bundles and replicas; a `stream` strategy for large sequential media brings resumable, out-of-order, restart-surviving uploads whose finalise verifies coverage as an interval union and refuses to publish a gap; HTTP Range serving through `self.serveFromStorage()` on both engines, with conditional GET and a fail-closed content-type downgrade; the `s3` adapter completes the pluggable object-storage layer, storeless by design and able to offload GET/HEAD to a presigned URL; `getRange()` on every local strategy; machine-readable `err.code` on storage read verbs; and the Couchbase soak probes ship in the package · **Changed**: `renderStream()` is byte-serving-capable — `Buffer` chunks pass through verbatim on non-SSE content types (binary payloads previously arrived corrupted), HEAD answers headers-only without consuming the iterable, and caller-set headers are no longer clobbered · **Fixed**: `renderStream()` honours a caller-set status on both engines and stops throwing a swallowed error at the end of every streamed response, a redirect treats `HEAD` as the safe method it is and keeps the caller's query string under `keep-params: true`, and a local storage driver reclaims the temp files left behind by a crashed or refused `put()` |
63
+ | **Q4 2026** | `0.6.9` ✅ | **Security**: an engine.io socket's session identity is derived server-side from the upgrade request's own cookie instead of a field the browser asserts on every message — any client could previously claim another user's session and receive the pushes addressed to it, which took strictly less than stealing the cookie, since a rendered page carries the bare session id while the cookie carries the signed form; the binding replays the bundle's own session middleware (same secret, store and cookie name, no new configuration) and fails closed, so an id-less socket receives only deliberate broadcasts · **Added**: `gina.pushToSession()` gives code with no request context — a job handler, a cron tick, a boot hook — a sanctioned route to a user's socket, with a required recipient, no reachable broadcast, and delivery reported rather than assumed; and a bundle can declare which scopes it is deployed in through a `scopes` allow-list on its manifest entry, so one still under development stays out of every other scope · **Fixed**: `engine: "express"` bundles boot and serve on Express 5, with the supported range declared for the first time (`>= 4 < 6`, both majors verified live) · `project:add`/`project:import` no longer empty a project's `bundles` block on a declared-count mismatch, no longer adopt a bundle's invalid `server.protocol`/`server.scheme` into the project's registry lists, and no longer resolve one project's bundles against another project's path · `project:add` writes the `.gitignore` the shipped template's underscore prefix has always implied · the path helper's copier stages to a temp sibling and publishes with an atomic rename, so a failed copy can no longer destroy the destination it was replacing · the secrets resolver reads its two environment tiers independently, so a swept boolean no longer lets a plaintext file shadow `process.env`, and three malformed `settings.secrets.file` shapes that used to pass in silence are caught (ACTION REQUIRED — two of them now refuse to boot) · a bundle whose release tree cannot be linked refuses by name instead of dying as an opaque TypeError · `self.push()` refuses by name when the server instance has no engine.io channel |
63
64
  | **Q1 2027** | `0.6.x` | HTTP/2 priorities (blocked on Node scheduler hooks) · Beemaster admin + visual translation editor |
64
65
  | **2027** | `0.7.0` | Performance — remaining measure-gated candidates: multipart & WebSocket fast paths, render/log cleanups, SIMD scanner (the render-path deep-clone & id-mint reduction shipped early in `0.6.2` with a measured 4.4× render-throughput gain; the profiling baseline itself also shipped in `0.6.2`) |
65
66
  | **2027** | `0.8.0` | Financial-messaging foundations — XML request/response handling · pluggable message-schema validation · IBAN/BIC validation rules · money & ISO 4217 minor-unit utilities · idempotency keys · sequence primitive · OAuth2 client-credentials egress |
@@ -0,0 +1 @@
1
+ 0.6.9
@@ -175,6 +175,22 @@ function Config(opt, contextResetNeeded) {
175
175
 
176
176
  self.Env.load( function(err, envConf) {
177
177
 
178
+ // #B372 — the env load can fail (an unlinkable release path, most often one
179
+ // bundle's release tree missing on the target host). Nothing consumed that
180
+ // error before, so it either vanished or resurfaced as an opaque deref later
181
+ // in the boot. Refuse here, through the same sink loadBundlesConfiguration
182
+ // uses below, so the reason reaches stderr and the process exits cleanly.
183
+ if (err) {
184
+ var _envMsg = (err.stack||err.message);
185
+ console.error(_envMsg);
186
+ // Guarantee the reason survives process.exit() on an async pipe (e.g. bin/gina-container).
187
+ try { fs.writeSync(2, _envMsg + '\n'); } catch (_e) { /* best-effort */ }
188
+ setTimeout(() => {
189
+ process.exit(1);
190
+ }, 0);
191
+ return;
192
+ }
193
+
178
194
  if ( typeof(self.Env.loaded) == 'undefined') {
179
195
  // Need to globalize some of them.
180
196
  self.envConf = envConf;
@@ -400,6 +416,17 @@ function Config(opt, contextResetNeeded) {
400
416
  template : requireJSON( getEnvVar('GINA_FRAMEWORK_DIR') +'/core/template/conf/env.json'),
401
417
  load : function(callback) {
402
418
  loadWithTemplate(this.parent.userConf, this.template, function(err, envConf) {
419
+ // #B372 — loadWithTemplate calls back with an error and NO envConf (e.g. a
420
+ // release path that cannot be linked). Dereferencing envConf here discarded
421
+ // that well-formed reason — which already names the offending path — and
422
+ // replaced it with `TypeError: Cannot set properties of undefined (setting
423
+ // 'env')`, so the operator got an uncaughtException pointing at framework
424
+ // internals instead of at the path they had to fix. Propagate: getConf's
425
+ // callback turns it into a named exit(1).
426
+ if (err) {
427
+ return callback(err);
428
+ }
429
+
403
430
  self.envConf = envConf;
404
431
  envConf.env = self.env;
405
432
  envConf.scope = self.scope;
@@ -640,6 +667,36 @@ function Config(opt, contextResetNeeded) {
640
667
  // }
641
668
  // }
642
669
 
670
+ /**
671
+ * Whether a manifest bundle entry is deployed in the given scope.
672
+ *
673
+ * `bundles[<name>].scopes` is an OPTIONAL allow-list of scope names — the
674
+ * same semantics as a route's rule-level `scopes`: the key ABSENT (or null)
675
+ * means every scope (back-compat, the historical behaviour), an empty array
676
+ * means no scope at all (the bundle is parked), and a non-array is INVALID —
677
+ * callers fail fast on that shape with a named error before relying on this
678
+ * predicate, which returns false for it only as a defensive default.
679
+ *
680
+ * A twin of this predicate lives in `core/gna.js` (the mount-resolution
681
+ * path runs before Config and cannot reach this closure) — keep the two
682
+ * in sync.
683
+ *
684
+ * @inner
685
+ * @private
686
+ * @param {object} bundleEntry - The bundle's `manifest.json` entry (`bundles[<name>]`)
687
+ * @param {string} scopeName - Scope being booted/loaded
688
+ * @returns {boolean} `true` when the bundle is deployed in `scopeName`
689
+ */
690
+ var isBundleDeployedInScope = function(bundleEntry, scopeName) {
691
+ if ( !bundleEntry || typeof(bundleEntry.scopes) == 'undefined' || bundleEntry.scopes === null ) {
692
+ return true;
693
+ }
694
+ if ( !Array.isArray(bundleEntry.scopes) ) {
695
+ return false;
696
+ }
697
+ return bundleEntry.scopes.indexOf(scopeName) > -1;
698
+ }
699
+
643
700
  /**
644
701
  * Merges the user's project config (`userConf`) against the framework's
645
702
  * `env.json` template, resolving port assignments, bundle paths, model
@@ -699,6 +756,27 @@ function Config(opt, contextResetNeeded) {
699
756
  return callback(err);
700
757
  }
701
758
 
759
+ // #B373 — the STARTING bundle is a special case: skipping it would leave the
760
+ // boot with no bundle to serve and it would die further down in the #B181(b)
761
+ // env.json guard, whose message describes the wrong cause entirely. Refuse
762
+ // here instead, naming the scope and the one-line remedy. Reaches exit(1)
763
+ // through the same sink #B372 installed on this callback.
764
+ if (
765
+ typeof(pkg) != 'undefined' && pkg !== null
766
+ && typeof(pkg[self.startingApp]) != 'undefined'
767
+ && !isBundleDeployedInScope(pkg[self.startingApp], scope)
768
+ ) {
769
+ let _startingScopeError = new Error(
770
+ '[ scope ] cannot start `'+ self.startingApp +'` in scope `'+ scope +'`: the bundle is not deployed there. '
771
+ + '`bundles.'+ self.startingApp +'.scopes` in manifest.json declares '
772
+ + ( Array.isArray(pkg[self.startingApp].scopes) && pkg[self.startingApp].scopes.length
773
+ ? '`'+ pkg[self.startingApp].scopes.join('`, `') +'`'
774
+ : 'no scope at all' )
775
+ + '. Add `'+ scope +'` to that list, or start the bundle in a scope it belongs to.'
776
+ );
777
+ return callback(_startingScopeError);
778
+ }
779
+
702
780
 
703
781
  // For each app.
704
782
  var isCacheless = self.isCacheless()
@@ -748,6 +826,22 @@ function Config(opt, contextResetNeeded) {
748
826
  continue;
749
827
  }
750
828
 
829
+ // #B373 — per-scope deployment. `bundles[<name>].scopes` is an optional
830
+ // allow-list: absent means every scope (back-compat), so this can only
831
+ // skip a bundle whose manifest OPTS OUT of the scope being booted. A
832
+ // non-array is a manifest error, not an opt-out — refuse rather than
833
+ // silently parking the bundle everywhere.
834
+ if ( typeof(pkg[app].scopes) != 'undefined' && pkg[app].scopes !== null && !Array.isArray(pkg[app].scopes) ) {
835
+ let _scopesTypeError = new Error('[ manifest ] `bundles.'+ app +'.scopes` must be an array of scope names (got '+ typeof(pkg[app].scopes) +'). Remove the key to deploy `'+ app +'` in every scope, or list the scopes it belongs to.');
836
+ return callback(_scopesTypeError);
837
+ }
838
+ if ( !isBundleDeployedInScope(pkg[app], scope) ) {
839
+ // Say so rather than letting the bundle vanish from the boot with
840
+ // nothing explaining why — the #B183 skipped-sibling lesson.
841
+ console.warn('[CONFIG] Skipping bundle [ '+ app +' ]: not deployed in scope `'+ scope +'` (declared scopes: '+ (pkg[app].scopes.length ? '`'+ pkg[app].scopes.join('`, `') +'`' : 'none') +'). Add `'+ scope +'` to `bundles.'+ app +'.scopes` in manifest.json to deploy it here.');
842
+ continue;
843
+ }
844
+
751
845
  appPath = _(root +'/'+ pkg[app].link, true);
752
846
  console.debug('[CONFIG] Checking appPath [ '+ appPath +' ] ');
753
847
  // cleanup symlinks
@@ -767,7 +861,14 @@ function Config(opt, contextResetNeeded) {
767
861
  }
768
862
  } catch (releaseError) {
769
863
  console.error('[ releaseError ] ', releaseError);
770
- let _releaseError = new Error('[ releaseError ] path: '+ targetAppPathObj.toString() );
864
+ // #B372 name the bundle, env and scope. One bundle's unlinkable release
865
+ // tree aborts the SHARED config load for every bundle in the project, so
866
+ // "which one?" is the operator's first question and the loop already knows.
867
+ // `targetAppPathObj` is deliberately not reported: when the throw comes from
868
+ // `pkg[app].releases[scope][env]` itself, the assignment above never ran and
869
+ // the object still holds the LINK path, so reporting it names the wrong file.
870
+ // The underlying message does name the real one (ENOENT carries the path).
871
+ let _releaseError = new Error('[ releaseError ] bundle: `'+ app +'` (env: `'+ env +'`, scope: `'+ scope +'`), link: '+ appPath +' — '+ (releaseError.message || releaseError) );
771
872
  return callback(_releaseError);
772
873
  }
773
874
  targetAppPathObj = null;
@@ -6441,12 +6441,19 @@ if ( /^local$/i.test(process.env.NODE_SCOPE) ) {
6441
6441
  * Reaching every connected client requires `option.broadcast === true`,
6442
6442
  * supplied by your code rather than inferred from a missing value.
6443
6443
  *
6444
+ * The channel itself is an isaac-engine facility. On the express engine there
6445
+ * is none, so a push sends nothing, warns, and reports
6446
+ * `PUSH_CHANNEL_NOT_CONFIGURED` to a supplied callback rather than failing the
6447
+ * request (#B371) — a structural condition, identical on every call.
6448
+ *
6444
6449
  * @param {object|null} payload - Data to push; falls back to `req[method].payload` when `null`
6445
6450
  * @param {object} [option] - Push options, also forwarded to the transport (e.g. `{ compress: true }`)
6446
6451
  * @param {string} [option.sessionID] - Explicit recipient session id; defaults to the caller's own session
6447
6452
  * @param {boolean} [option.broadcast] - `true` (strictly) to reach every connected client
6448
6453
  * @param {string} [option.section] - Section stamped onto the payload; falls back to `req[method].section`
6449
- * @param {function} [callback] - `callback(err, result)`
6454
+ * @param {function} [callback] - `callback(err, result)`; receives a
6455
+ * `PUSH_CHANNEL_NOT_CONFIGURED` error when this
6456
+ * server instance has no engine.io channel
6450
6457
  * @returns {void}
6451
6458
  *
6452
6459
  * @example
@@ -6474,6 +6481,25 @@ if ( /^local$/i.test(process.env.NODE_SCOPE) ) {
6474
6481
  var req = local.req, res = local.res;
6475
6482
  var method = req.method.toLowerCase();
6476
6483
 
6484
+ // #B371 — the push channel is an isaac-engine facility: `serverInstance.eio`
6485
+ // is attached there and nowhere else, so on the express engine the client
6486
+ // lookup further down dereferenced `undefined` and surfaced as an opaque
6487
+ // TypeError-derived 500 that named neither push nor the missing channel.
6488
+ // Refuse by name instead, the way the out-of-request sibling does
6489
+ // (`lib/push` → PUSH_CHANNEL_NOT_CONFIGURED): warn, tell a caller that
6490
+ // passed a callback, and send nothing. This is a structural, process-wide
6491
+ // condition — unlike the per-call no-recipient case below — so it can
6492
+ // never resolve on a later call and is reported the same way every time.
6493
+ if ( self.serverInstance == null || self.serverInstance.eio == null ) {
6494
+ console.warn('[CONTROLLER][ push ] no engine.io channel on this server instance, so nothing was sent. The push channel needs the isaac engine with `settings.json > server.ioServer.integrationMode: "attach"`; the express engine has no `eio`.');
6495
+ if ( typeof(callback) == 'function' ) {
6496
+ var noChannelErr = new Error('no engine.io channel on this server instance. The push channel needs the isaac engine with `settings.json > server.ioServer.integrationMode: "attach"`; the express engine has no `eio`.');
6497
+ noChannelErr.code = 'PUSH_CHANNEL_NOT_CONFIGURED';
6498
+ callback(noChannelErr);
6499
+ }
6500
+ return;
6501
+ }
6502
+
6477
6503
  // #B364 — the recipient is NEVER read from the request body. It used to be
6478
6504
  // (`req[method].sessionID`), which let a caller aim a push at any session by
6479
6505
  // sending an id — and, when the id was absent, at EVERY connected client.
@@ -6548,9 +6574,11 @@ if ( /^local$/i.test(process.env.NODE_SCOPE) ) {
6548
6574
  && clients[s].sessionId == sessionId
6549
6575
  )
6550
6576
  ) {
6551
- // #B364 — was `options`, an identifier that exists nowhere in this
6552
- // scope: every call threw ReferenceError here before sending, so
6553
- // push() had never delivered a packet in any published release.
6577
+ // #B364 — was `options`: SuperController's own constructor
6578
+ // parameter, in scope here by closure, where the caller's
6579
+ // `option` was meant. It resolved, so nothing threw and the
6580
+ // packet WAS sent — carrying the controller's options in
6581
+ // place of the caller's, which never reached the transport.
6554
6582
  clients[s].sendPacket("message", payload, option, callback);
6555
6583
  }
6556
6584
  }
@@ -2093,6 +2093,31 @@ isBundleMounted(projects, bundlesPath, getContext('bundle'), function onBundleMo
2093
2093
  , path = null
2094
2094
  , packs = project.bundles
2095
2095
  ;
2096
+
2097
+ /**
2098
+ * Whether a manifest bundle entry is deployed in the given scope (#B373).
2099
+ *
2100
+ * TWIN of `isBundleDeployedInScope` in `core/config.js` — this path runs
2101
+ * BEFORE Config exists and cannot reach that closure, so the predicate is
2102
+ * duplicated deliberately. Keep both in sync: `scopes` absent/null means
2103
+ * every scope (back-compat), `[]` means none, a non-array is invalid.
2104
+ *
2105
+ * @inner
2106
+ * @private
2107
+ * @param {object} bundleEntry - The bundle's manifest entry
2108
+ * @param {string} scopeName - Scope being mounted
2109
+ * @returns {boolean} `true` when deployed in `scopeName`
2110
+ */
2111
+ var isBundleDeployedInScope = function(bundleEntry, scopeName) {
2112
+ if ( !bundleEntry || typeof(bundleEntry.scopes) == 'undefined' || bundleEntry.scopes === null ) {
2113
+ return true;
2114
+ }
2115
+ if ( !Array.isArray(bundleEntry.scopes) ) {
2116
+ return false;
2117
+ }
2118
+ return bundleEntry.scopes.indexOf(scopeName) > -1;
2119
+ };
2120
+
2096
2121
  if (isLoadedThroughCLI) {
2097
2122
  appName = getContext('bundle');
2098
2123
  if (!isPath) {
@@ -2100,6 +2125,28 @@ isBundleMounted(projects, bundlesPath, getContext('bundle'), function onBundleMo
2100
2125
  if (typeof (packs[appName].version) == 'undefined' && typeof (packs[appName].tag) != 'undefined') {
2101
2126
  packs[appName].version = packs[appName].tag
2102
2127
  }
2128
+ // #B373 — refuse by name BEFORE the release deref below. This deref sits
2129
+ // outside any try, so an opted-out bundle used to die here as an opaque
2130
+ // TypeError before Config (and its named refusal) ever ran. The type
2131
+ // check comes first: a malformed `scopes` is a manifest error, and
2132
+ // reporting it as "not deployed" would send the operator hunting the
2133
+ // wrong thing (the predicate returns false for both).
2134
+ if (
2135
+ typeof (packs[appName].scopes) != 'undefined' && packs[appName].scopes !== null
2136
+ && !Array.isArray(packs[appName].scopes)
2137
+ ) {
2138
+ return abort('[ manifest ] `bundles.' + appName + '.scopes` must be an array of scope names (got '
2139
+ + typeof (packs[appName].scopes) + '). Remove the key to deploy `' + appName + '` in every scope, '
2140
+ + 'or list the scopes it belongs to.');
2141
+ }
2142
+ if ( !isBundleDeployedInScope(packs[appName], scope) ) {
2143
+ return abort('[ scope ] cannot mount `'+ appName +'` in scope `'+ scope +'`: the bundle is not deployed there. '
2144
+ + '`bundles.'+ appName +'.scopes` in manifest.json declares '
2145
+ + ( Array.isArray(packs[appName].scopes) && packs[appName].scopes.length
2146
+ ? '`'+ packs[appName].scopes.join('`, `') +'`'
2147
+ : 'no scope at all' )
2148
+ + '. Add `'+ scope +'` to that list, or start the bundle in a scope it belongs to.');
2149
+ }
2103
2150
  packs[appName].releases[scope][env].target = 'releases/' + appName + '/' + scope + '/' + env + '/' + packs[appName].version;
2104
2151
  path = (isDev) ? packs[appName].src : packs[appName].releases[scope][env].target
2105
2152
  } else {
@@ -2127,6 +2174,13 @@ isBundleMounted(projects, bundlesPath, getContext('bundle'), function onBundleMo
2127
2174
  for (let bundle in packs) {
2128
2175
  //is bundle ?
2129
2176
  let tmp = '';
2177
+ // #B373 — a bundle not deployed in this scope can never be the one
2178
+ // being mounted here, and its release deref below sits in a try whose
2179
+ // catch ABORTS the whole mount — so without this skip one opted-out
2180
+ // sibling would take the process down at any non-dev scope.
2181
+ if ( !isBundleDeployedInScope(packs[bundle], scope) ) {
2182
+ continue;
2183
+ }
2130
2184
  // For all but dev
2131
2185
  if (
2132
2186
  typeof (packs[bundle].releases) != 'undefined'
@@ -2467,6 +2521,59 @@ gna.storage = function(name) {
2467
2521
  return lib.storage.get(name);
2468
2522
  };
2469
2523
 
2524
+ /**
2525
+ * #B366 — push a payload to ONE named session from OUTSIDE a request.
2526
+ *
2527
+ * `self.push()` needs a live request-bound controller, so code that has none —
2528
+ * a `lib/job` handler, a cron tick, a boot hook — had no sanctioned route to a
2529
+ * user's socket. This is that route, and it is deliberately narrow:
2530
+ *
2531
+ * - `sessionID` is REQUIRED. An absent or empty recipient is an error, never
2532
+ * a fan-out. There is no broadcast reachable from here at all; the
2533
+ * deliberate all-clients send stays in-request as
2534
+ * `self.push(payload, { broadcast: true })`.
2535
+ * - The recipient must come from server-held state — captured when the work
2536
+ * was queued, and kept server-side. Never round-trip it (or a token naming
2537
+ * it) through the browser: that hands the choice back to the caller and
2538
+ * re-opens #B364 one layer up.
2539
+ * - Delivery is reported, not assumed: `delivered` is how many sockets were
2540
+ * written, and `0` is a normal outcome, not an error.
2541
+ *
2542
+ * Requires the isaac engine with `settings.json > server.ioServer` attached;
2543
+ * the express engine has no engine.io channel and gets a named error.
2544
+ *
2545
+ * Assigned UNCONDITIONALLY (same reasoning as `gna.storage` above), so a
2546
+ * misconfigured bundle gets an error naming the fix rather than
2547
+ * `gna.pushToSession is not a function`.
2548
+ *
2549
+ * @param {string} sessionID - REQUIRED recipient session id.
2550
+ * @param {object|string} payload - Object (JSON-stringified) or a pre-serialized string.
2551
+ * @param {object} [option] - Forwarded to the transport (e.g. `{ compress: true }`).
2552
+ * @param {string} [option.section] - Stamped onto an object payload lacking one.
2553
+ * @param {function} [callback] - `callback(err, { delivered })`, called exactly once.
2554
+ * @returns {void}
2555
+ * @example
2556
+ * // in a job handler — sessionID was captured when the job was created
2557
+ * gina.pushToSession(job.sessionID, { event: 'export:ready', key: res.key }, function (err, out) {
2558
+ * if (err) { return console.error(err.code, err.message); }
2559
+ * if (!out.delivered) { console.debug('nobody listening — the user closed the tab'); }
2560
+ * });
2561
+ */
2562
+ gna.pushToSession = function(sessionID, payload, option, callback) {
2563
+ var instance = ( process.gina ) ? process.gina._serverInstance : null;
2564
+ if ( instance == null ) {
2565
+ var err = new Error(
2566
+ '[ push ] the server instance is not published yet, so there is no socket set to reach. '
2567
+ + 'This is normal before the bundle has served its first request.'
2568
+ );
2569
+ err.code = 'PUSH_CHANNEL_NOT_READY';
2570
+ if ( typeof(option) == 'function' ) { return option(err); }
2571
+ if ( typeof(callback) == 'function' ) { return callback(err); }
2572
+ throw err;
2573
+ }
2574
+ return lib.push.toSession(instance, sessionID, payload, option, callback);
2575
+ };
2576
+
2470
2577
  // ── JSON helper (framework/v*/helpers/json/src/main.js) ──────────────────
2471
2578
 
2472
2579
  /**