open-loam 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (273) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -8
  3. data/LICENSE +1 -1
  4. data/README.md +24 -24
  5. data/app/jobs/{loam → open_loam}/custom_field_reindex_job.rb +6 -6
  6. data/app/jobs/{loam → open_loam}/event_delivery_job.rb +8 -8
  7. data/app/jobs/{loam → open_loam}/event_redelivery_sweep_job.rb +4 -4
  8. data/app/jobs/{loam → open_loam}/webhook_delivery_job.rb +7 -7
  9. data/app/models/{loam → open_loam}/api_token.rb +7 -7
  10. data/app/models/{loam → open_loam}/audit_record.rb +3 -3
  11. data/app/models/{loam → open_loam}/auth_attempt.rb +5 -5
  12. data/app/models/{loam → open_loam}/business_rule.rb +10 -10
  13. data/app/models/{loam → open_loam}/business_rule_run.rb +5 -5
  14. data/app/models/{loam → open_loam}/comment.rb +9 -9
  15. data/app/models/{loam → open_loam}/config.rb +7 -7
  16. data/app/models/{loam → open_loam}/custom_field_value.rb +5 -5
  17. data/app/models/{loam → open_loam}/dashboard_widget.rb +5 -5
  18. data/app/models/open_loam/dictionary.rb +20 -0
  19. data/app/models/{loam → open_loam}/dictionary_entry.rb +7 -7
  20. data/app/models/{loam → open_loam}/event_delivery.rb +4 -4
  21. data/app/models/{loam → open_loam}/field_definition.rb +8 -8
  22. data/app/models/{loam → open_loam}/inbound_webhook_delivery.rb +4 -4
  23. data/app/models/{loam → open_loam}/inbound_webhook_source.rb +13 -13
  24. data/app/models/{loam → open_loam}/membership.rb +6 -6
  25. data/app/models/{loam → open_loam}/mfa_credential.rb +8 -8
  26. data/app/models/{loam → open_loam}/notification.rb +10 -10
  27. data/app/models/{loam → open_loam}/pending_action.rb +23 -23
  28. data/app/models/{loam → open_loam}/perspective.rb +5 -5
  29. data/app/models/{loam → open_loam}/progress_job.rb +7 -7
  30. data/app/models/{loam → open_loam}/record_lock.rb +5 -5
  31. data/app/models/{loam → open_loam}/scheduled_job.rb +7 -7
  32. data/app/models/open_loam/search_token.rb +9 -0
  33. data/app/models/{loam → open_loam}/sso_identity.rb +4 -4
  34. data/app/models/{loam → open_loam}/sso_provider.rb +8 -8
  35. data/app/models/open_loam/tenant.rb +20 -0
  36. data/app/models/{loam → open_loam}/translation.rb +5 -5
  37. data/app/models/{loam → open_loam}/webhook_endpoint.rb +6 -6
  38. data/app/views/{loam → open_loam}/attachments/_attachments.html.erb +1 -1
  39. data/app/views/{loam → open_loam}/comments/_comments.html.erb +1 -1
  40. data/app/views/{loam → open_loam}/custom_fields/_fields.html.erb +2 -2
  41. data/lib/generators/{loam → open_loam}/entity/entity_generator.rb +9 -9
  42. data/lib/generators/{loam → open_loam}/entity/templates/api_controller.rb +1 -1
  43. data/lib/generators/{loam → open_loam}/entity/templates/controller.rb +21 -21
  44. data/lib/generators/{loam → open_loam}/entity/templates/entity_test.rb +12 -12
  45. data/lib/generators/{loam → open_loam}/entity/templates/migration.rb +5 -5
  46. data/lib/generators/{loam → open_loam}/entity/templates/model.rb +10 -10
  47. data/lib/generators/{loam → open_loam}/entity/templates/policy.rb +1 -1
  48. data/lib/generators/{loam → open_loam}/entity/templates/views/_form.html.erb +4 -4
  49. data/lib/generators/{loam → open_loam}/entity/templates/views/deleted.html.erb +7 -7
  50. data/lib/generators/open_loam/entity/templates/views/edit.html.erb +3 -0
  51. data/lib/generators/open_loam/entity/templates/views/index.html.erb +90 -0
  52. data/lib/generators/open_loam/entity/templates/views/new.html.erb +3 -0
  53. data/lib/generators/open_loam/entity/templates/views/show.html.erb +36 -0
  54. data/lib/generators/{loam → open_loam}/install/install_generator.rb +47 -47
  55. data/lib/generators/open_loam/install/templates/AGENTS.md +341 -0
  56. data/lib/generators/{loam → open_loam}/install/templates/admin/api_docs_controller.rb +2 -2
  57. data/lib/generators/{loam → open_loam}/install/templates/admin/api_docs_index.html.erb +1 -1
  58. data/lib/generators/{loam → open_loam}/install/templates/admin/api_tokens_controller.rb +1 -1
  59. data/lib/generators/{loam → open_loam}/install/templates/admin/base_controller.rb +38 -38
  60. data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_controller.rb +7 -7
  61. data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_form.html.erb +2 -2
  62. data/lib/generators/{loam → open_loam}/install/templates/admin/comments_controller.rb +4 -4
  63. data/lib/generators/{loam → open_loam}/install/templates/admin/configs_controller.rb +9 -9
  64. data/lib/generators/open_loam/install/templates/admin/dashboard_controller.rb +10 -0
  65. data/lib/generators/{loam → open_loam}/install/templates/admin/dashboard_widgets_controller.rb +5 -5
  66. data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_controller.rb +5 -5
  67. data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_form.html.erb +1 -1
  68. data/lib/generators/{loam → open_loam}/install/templates/admin/dictionary_entries_controller.rb +2 -2
  69. data/lib/generators/{loam → open_loam}/install/templates/admin/event_deliveries_controller.rb +5 -5
  70. data/lib/generators/{loam → open_loam}/install/templates/admin/event_deliveries_index.html.erb +1 -1
  71. data/lib/generators/{loam → open_loam}/install/templates/admin/events_controller.rb +5 -5
  72. data/lib/generators/{loam → open_loam}/install/templates/admin/features_controller.rb +9 -9
  73. data/lib/generators/{loam → open_loam}/install/templates/admin/field_definitions_controller.rb +5 -5
  74. data/lib/generators/{loam → open_loam}/install/templates/admin/field_definitions_new.html.erb +2 -2
  75. data/lib/generators/{loam → open_loam}/install/templates/admin/history_controller.rb +7 -7
  76. data/lib/generators/{loam → open_loam}/install/templates/admin/history_index.html.erb +1 -1
  77. data/lib/generators/{loam → open_loam}/install/templates/admin/imports_controller.rb +12 -12
  78. data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_controller.rb +6 -6
  79. data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_new.html.erb +2 -2
  80. data/lib/generators/open_loam/install/templates/admin/layout.html.erb +76 -0
  81. data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_controller.rb +6 -6
  82. data/lib/generators/{loam → open_loam}/install/templates/admin/notifications_controller.rb +3 -3
  83. data/lib/generators/{loam → open_loam}/install/templates/admin/overrides_controller.rb +3 -3
  84. data/lib/generators/{loam → open_loam}/install/templates/admin/overrides_index.html.erb +2 -2
  85. data/lib/generators/{loam → open_loam}/install/templates/admin/pending_actions_controller.rb +3 -3
  86. data/lib/generators/{loam → open_loam}/install/templates/admin/perspectives_controller.rb +7 -7
  87. data/lib/generators/{loam → open_loam}/install/templates/admin/perspectives_index.html.erb +1 -1
  88. data/lib/generators/open_loam/install/templates/admin/progress_jobs_controller.rb +19 -0
  89. data/lib/generators/{loam → open_loam}/install/templates/admin/progress_jobs_index.html.erb +1 -1
  90. data/lib/generators/{loam → open_loam}/install/templates/admin/record_locks_controller.rb +4 -4
  91. data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_controller.rb +7 -7
  92. data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_form.html.erb +1 -1
  93. data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_index.html.erb +1 -1
  94. data/lib/generators/{loam → open_loam}/install/templates/admin/search_controller.rb +5 -5
  95. data/lib/generators/{loam → open_loam}/install/templates/admin/sessions_controller.rb +32 -32
  96. data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_controller.rb +6 -6
  97. data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_form.html.erb +2 -2
  98. data/lib/generators/{loam → open_loam}/install/templates/admin/sudo_controller.rb +5 -5
  99. data/lib/generators/{loam → open_loam}/install/templates/admin/sudo_new.html.erb +1 -1
  100. data/lib/generators/{loam → open_loam}/install/templates/admin/translations_controller.rb +7 -7
  101. data/lib/generators/{loam → open_loam}/install/templates/admin/translations_index.html.erb +3 -3
  102. data/lib/generators/{loam → open_loam}/install/templates/admin/webhook_endpoints_controller.rb +4 -4
  103. data/lib/generators/{loam → open_loam}/install/templates/admin/webhook_endpoints_index.html.erb +1 -1
  104. data/lib/generators/{loam → open_loam}/install/templates/admin.css +1 -1
  105. data/lib/generators/{loam → open_loam}/install/templates/api_base_controller.rb +15 -15
  106. data/lib/generators/{loam → open_loam}/install/templates/guardrails_test.rb +17 -17
  107. data/lib/generators/{loam → open_loam}/install/templates/import_job.rb +7 -7
  108. data/lib/generators/{loam → open_loam}/install/templates/inbound_webhooks_controller.rb +4 -4
  109. data/lib/generators/{loam → open_loam}/install/templates/initializer.rb +74 -74
  110. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_api_tokens.rb +15 -0
  111. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_audit_records.rb +14 -0
  112. data/lib/generators/{loam/install/templates/migrations/create_loam_auth_attempts.rb → open_loam/install/templates/migrations/create_open_loam_auth_attempts.rb} +3 -3
  113. data/lib/generators/{loam/install/templates/migrations/create_loam_business_rules.rb → open_loam/install/templates/migrations/create_open_loam_business_rules.rb} +10 -10
  114. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_comments.rb +13 -0
  115. data/lib/generators/{loam/install/templates/migrations/create_loam_configs.rb → open_loam/install/templates/migrations/create_open_loam_configs.rb} +7 -7
  116. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_custom_field_values.rb +19 -0
  117. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_dashboard_widgets.rb +12 -0
  118. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_dictionaries.rb +11 -0
  119. data/lib/generators/{loam/install/templates/migrations/create_loam_dictionary_entries.rb → open_loam/install/templates/migrations/create_open_loam_dictionary_entries.rb} +6 -6
  120. data/lib/generators/{loam/install/templates/migrations/create_loam_event_deliveries.rb → open_loam/install/templates/migrations/create_open_loam_event_deliveries.rb} +5 -5
  121. data/lib/generators/{loam/install/templates/migrations/create_loam_field_definitions.rb → open_loam/install/templates/migrations/create_open_loam_field_definitions.rb} +4 -4
  122. data/lib/generators/{loam/install/templates/migrations/create_loam_inbound_webhooks.rb → open_loam/install/templates/migrations/create_open_loam_inbound_webhooks.rb} +9 -9
  123. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_memberships.rb +11 -0
  124. data/lib/generators/{loam/install/templates/migrations/create_loam_mfa_credentials.rb → open_loam/install/templates/migrations/create_open_loam_mfa_credentials.rb} +4 -4
  125. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_notifications.rb +15 -0
  126. data/lib/generators/{loam/install/templates/migrations/create_loam_pending_actions.rb → open_loam/install/templates/migrations/create_open_loam_pending_actions.rb} +9 -9
  127. data/lib/generators/{loam/install/templates/migrations/create_loam_perspectives.rb → open_loam/install/templates/migrations/create_open_loam_perspectives.rb} +5 -5
  128. data/lib/generators/{loam/install/templates/migrations/create_loam_progress_jobs.rb → open_loam/install/templates/migrations/create_open_loam_progress_jobs.rb} +5 -5
  129. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_record_locks.rb +16 -0
  130. data/lib/generators/{loam/install/templates/migrations/create_loam_scheduled_jobs.rb → open_loam/install/templates/migrations/create_open_loam_scheduled_jobs.rb} +5 -5
  131. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_search_tokens.rb +18 -0
  132. data/lib/generators/{loam/install/templates/migrations/create_loam_sso_providers.rb → open_loam/install/templates/migrations/create_open_loam_sso_providers.rb} +12 -12
  133. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_tenants.rb +9 -0
  134. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_translations.rb +15 -0
  135. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_webhook_endpoints.rb +13 -0
  136. data/lib/generators/{loam → open_loam}/install/templates/migrations/create_users.rb +1 -1
  137. data/lib/generators/{loam → open_loam}/install/templates/user.rb +5 -5
  138. data/lib/generators/{loam → open_loam}/primary_key_options.rb +23 -23
  139. data/lib/open-loam.rb +2 -2
  140. data/lib/{loam → open_loam}/attachable.rb +4 -4
  141. data/lib/{loam → open_loam}/auditable.rb +23 -23
  142. data/lib/{loam → open_loam}/auth_throttle.rb +10 -10
  143. data/lib/{loam → open_loam}/base32.rb +1 -1
  144. data/lib/{loam → open_loam}/bulk.rb +7 -7
  145. data/lib/{loam → open_loam}/business_rules/actions.rb +7 -7
  146. data/lib/{loam → open_loam}/business_rules/condition.rb +5 -5
  147. data/lib/{loam → open_loam}/business_rules.rb +19 -19
  148. data/lib/{loam → open_loam}/commentable.rb +6 -6
  149. data/lib/{loam → open_loam}/configs.rb +19 -19
  150. data/lib/{loam → open_loam}/cron.rb +2 -2
  151. data/lib/{loam → open_loam}/csv.rb +2 -2
  152. data/lib/{loam → open_loam}/current.rb +5 -5
  153. data/lib/{loam → open_loam}/custom_field_index.rb +23 -23
  154. data/lib/{loam → open_loam}/custom_fields.rb +17 -17
  155. data/lib/{loam → open_loam}/dashboard.rb +5 -5
  156. data/lib/{loam → open_loam}/dictionaries.rb +12 -12
  157. data/lib/{loam → open_loam}/durable_events.rb +19 -19
  158. data/lib/{loam → open_loam}/encryptable.rb +33 -33
  159. data/lib/{loam → open_loam}/encryption/cipher.rb +3 -3
  160. data/lib/{loam → open_loam}/encryption/key_provider.rb +3 -3
  161. data/lib/{loam → open_loam}/encryption.rb +11 -11
  162. data/lib/open_loam/engine.rb +57 -0
  163. data/lib/{loam → open_loam}/enrichers.rb +5 -5
  164. data/lib/{loam → open_loam}/errors.rb +10 -10
  165. data/lib/{loam → open_loam}/eval.rb +2 -2
  166. data/lib/{loam → open_loam}/event_stream.rb +14 -14
  167. data/lib/{loam → open_loam}/eventful.rb +12 -12
  168. data/lib/{loam → open_loam}/events.rb +5 -5
  169. data/lib/{loam → open_loam}/export.rb +8 -8
  170. data/lib/{loam → open_loam}/features.rb +15 -15
  171. data/lib/{loam → open_loam}/generated_key.rb +6 -6
  172. data/lib/{loam → open_loam}/import.rb +12 -12
  173. data/lib/{loam → open_loam}/inbound_webhooks.rb +7 -7
  174. data/lib/{loam → open_loam}/lifecycle.rb +25 -25
  175. data/lib/{loam/locales/loam.en.yml → open_loam/locales/open_loam.en.yml} +5 -5
  176. data/lib/{loam → open_loam}/mcp/server.rb +9 -9
  177. data/lib/{loam → open_loam}/mcp.rb +21 -21
  178. data/lib/{loam → open_loam}/notifications.rb +5 -5
  179. data/lib/{loam → open_loam}/open_api.rb +16 -16
  180. data/lib/{loam → open_loam}/overrides.rb +10 -10
  181. data/lib/{loam → open_loam}/pending_actions.rb +9 -9
  182. data/lib/{loam → open_loam}/permissions.rb +8 -8
  183. data/lib/{loam → open_loam}/perspectives.rb +9 -9
  184. data/lib/{loam → open_loam}/policy.rb +6 -6
  185. data/lib/{loam → open_loam}/progress.rb +6 -6
  186. data/lib/{loam → open_loam}/record_locks.rb +9 -9
  187. data/lib/{loam → open_loam}/scheduler.rb +20 -20
  188. data/lib/{loam → open_loam}/search/driver.rb +3 -3
  189. data/lib/{loam → open_loam}/search/like_driver.rb +5 -5
  190. data/lib/{loam → open_loam}/search/token_driver.rb +15 -15
  191. data/lib/{loam → open_loam}/search.rb +5 -5
  192. data/lib/{loam → open_loam}/searchable.rb +22 -22
  193. data/lib/{loam → open_loam}/soft_deletable.rb +10 -10
  194. data/lib/{loam → open_loam}/sso/claims.rb +1 -1
  195. data/lib/{loam → open_loam}/sso/fake_provider.rb +1 -1
  196. data/lib/{loam → open_loam}/sso/http_client.rb +3 -3
  197. data/lib/{loam → open_loam}/sso/oidc_provider.rb +2 -2
  198. data/lib/{loam → open_loam}/sso.rb +17 -17
  199. data/lib/{loam → open_loam}/telemetry.rb +6 -6
  200. data/lib/{loam → open_loam}/tenant_record.rb +10 -10
  201. data/lib/{loam → open_loam}/test_helpers.rb +4 -4
  202. data/lib/{loam → open_loam}/totp.rb +3 -3
  203. data/lib/{loam → open_loam}/translatable.rb +24 -24
  204. data/lib/{loam → open_loam}/undo.rb +11 -11
  205. data/lib/open_loam/version.rb +3 -0
  206. data/lib/{loam → open_loam}/webhooks.rb +4 -4
  207. data/lib/{loam → open_loam}/widgets.rb +9 -9
  208. data/lib/{loam → open_loam}/workflow.rb +45 -45
  209. data/lib/open_loam.rb +122 -0
  210. data/lib/tasks/{loam.rake → open_loam.rake} +43 -43
  211. data/lib/tasks/{loam_eval.rake → open_loam_eval.rake} +7 -7
  212. data/lib/tasks/open_loam_mcp.rake +20 -0
  213. metadata +242 -242
  214. data/app/models/loam/dictionary.rb +0 -20
  215. data/app/models/loam/search_token.rb +0 -9
  216. data/app/models/loam/tenant.rb +0 -20
  217. data/lib/generators/loam/entity/templates/views/edit.html.erb +0 -3
  218. data/lib/generators/loam/entity/templates/views/index.html.erb +0 -90
  219. data/lib/generators/loam/entity/templates/views/new.html.erb +0 -3
  220. data/lib/generators/loam/entity/templates/views/show.html.erb +0 -36
  221. data/lib/generators/loam/install/templates/AGENTS.md +0 -341
  222. data/lib/generators/loam/install/templates/admin/dashboard_controller.rb +0 -10
  223. data/lib/generators/loam/install/templates/admin/layout.html.erb +0 -76
  224. data/lib/generators/loam/install/templates/admin/progress_jobs_controller.rb +0 -19
  225. data/lib/generators/loam/install/templates/migrations/create_loam_api_tokens.rb +0 -15
  226. data/lib/generators/loam/install/templates/migrations/create_loam_audit_records.rb +0 -14
  227. data/lib/generators/loam/install/templates/migrations/create_loam_comments.rb +0 -13
  228. data/lib/generators/loam/install/templates/migrations/create_loam_custom_field_values.rb +0 -19
  229. data/lib/generators/loam/install/templates/migrations/create_loam_dashboard_widgets.rb +0 -12
  230. data/lib/generators/loam/install/templates/migrations/create_loam_dictionaries.rb +0 -11
  231. data/lib/generators/loam/install/templates/migrations/create_loam_memberships.rb +0 -11
  232. data/lib/generators/loam/install/templates/migrations/create_loam_notifications.rb +0 -15
  233. data/lib/generators/loam/install/templates/migrations/create_loam_record_locks.rb +0 -16
  234. data/lib/generators/loam/install/templates/migrations/create_loam_search_tokens.rb +0 -18
  235. data/lib/generators/loam/install/templates/migrations/create_loam_tenants.rb +0 -9
  236. data/lib/generators/loam/install/templates/migrations/create_loam_translations.rb +0 -15
  237. data/lib/generators/loam/install/templates/migrations/create_loam_webhook_endpoints.rb +0 -13
  238. data/lib/loam/engine.rb +0 -57
  239. data/lib/loam/version.rb +0 -3
  240. data/lib/loam.rb +0 -122
  241. data/lib/tasks/loam_mcp.rake +0 -20
  242. /data/lib/generators/{loam → open_loam}/install/templates/admin/api_tokens_index.html.erb +0 -0
  243. /data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_edit.html.erb +0 -0
  244. /data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_index.html.erb +0 -0
  245. /data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_new.html.erb +0 -0
  246. /data/lib/generators/{loam → open_loam}/install/templates/admin/configs_edit.html.erb +0 -0
  247. /data/lib/generators/{loam → open_loam}/install/templates/admin/configs_index.html.erb +0 -0
  248. /data/lib/generators/{loam → open_loam}/install/templates/admin/dashboard_index.html.erb +0 -0
  249. /data/lib/generators/{loam → open_loam}/install/templates/admin/dashboard_widgets_index.html.erb +0 -0
  250. /data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_edit.html.erb +0 -0
  251. /data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_index.html.erb +0 -0
  252. /data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_new.html.erb +0 -0
  253. /data/lib/generators/{loam → open_loam}/install/templates/admin/features_index.html.erb +0 -0
  254. /data/lib/generators/{loam → open_loam}/install/templates/admin/field_definitions_index.html.erb +0 -0
  255. /data/lib/generators/{loam → open_loam}/install/templates/admin/imports_new.html.erb +0 -0
  256. /data/lib/generators/{loam → open_loam}/install/templates/admin/imports_preview.html.erb +0 -0
  257. /data/lib/generators/{loam → open_loam}/install/templates/admin/imports_summary.html.erb +0 -0
  258. /data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_index.html.erb +0 -0
  259. /data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_activated.html.erb +0 -0
  260. /data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_new.html.erb +0 -0
  261. /data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_show.html.erb +0 -0
  262. /data/lib/generators/{loam → open_loam}/install/templates/admin/notifications_index.html.erb +0 -0
  263. /data/lib/generators/{loam → open_loam}/install/templates/admin/pagination.rb +0 -0
  264. /data/lib/generators/{loam → open_loam}/install/templates/admin/pending_actions_index.html.erb +0 -0
  265. /data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_edit.html.erb +0 -0
  266. /data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_new.html.erb +0 -0
  267. /data/lib/generators/{loam → open_loam}/install/templates/admin/search_index.html.erb +0 -0
  268. /data/lib/generators/{loam → open_loam}/install/templates/admin/sessions_mfa_challenge.html.erb +0 -0
  269. /data/lib/generators/{loam → open_loam}/install/templates/admin/sessions_new.html.erb +0 -0
  270. /data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_edit.html.erb +0 -0
  271. /data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_index.html.erb +0 -0
  272. /data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_new.html.erb +0 -0
  273. /data/lib/generators/{loam → open_loam}/install/templates/admin/webhook_endpoints_new.html.erb +0 -0
@@ -1,4 +1,4 @@
1
- module Loam
1
+ module OpenLoam
2
2
  # A thin domain event bus over ActiveSupport::Notifications.
3
3
  #
4
4
  # Convention: event names are `domain.thing.happened`, e.g.
@@ -7,7 +7,7 @@ module Loam
7
7
  # subscribers are always tenant-aware.
8
8
  module Events
9
9
  NAME_FORMAT = /\A[a-z0-9_]+(\.[a-z0-9_]+){2,}\z/
10
- PREFIX = "loam.event."
10
+ PREFIX = "open_loam.event."
11
11
 
12
12
  def self.publish(name, payload = {})
13
13
  name = name.to_s
@@ -17,12 +17,12 @@ module Loam
17
17
 
18
18
  ActiveSupport::Notifications.instrument(
19
19
  PREFIX + name,
20
- payload.merge(tenant_id: Loam::Current.tenant&.id, actor_id: Loam::Current.actor&.id)
20
+ payload.merge(tenant_id: OpenLoam::Current.tenant&.id, actor_id: OpenLoam::Current.actor&.id)
21
21
  )
22
22
  end
23
23
 
24
24
  # The subscription rule, in one place: a trailing dot is a domain prefix,
25
- # anything else is an exact event name. Loam::WebhookEndpoint matches
25
+ # anything else is an exact event name. OpenLoam::WebhookEndpoint matches
26
26
  # against this too, so a pattern means the same thing everywhere.
27
27
  def self.pattern_matches?(pattern, event_name)
28
28
  pattern = pattern.to_s
@@ -31,7 +31,7 @@ module Loam
31
31
  pattern.end_with?(".") ? event_name.start_with?(pattern) : event_name == pattern
32
32
  end
33
33
 
34
- # Every Loam event, whatever its domain — the empty prefix matches them
34
+ # Every OpenLoam event, whatever its domain — the empty prefix matches them
35
35
  # all. Used by the webhook dispatcher, which decides per event which
36
36
  # endpoints care.
37
37
  def self.subscribe_all(&block)
@@ -1,16 +1,16 @@
1
1
  require "csv"
2
2
 
3
- module Loam
3
+ module OpenLoam
4
4
  # CSV export of a tenant-scoped relation, POLICY- and ENCRYPTION-aware:
5
5
  #
6
- # Loam::Export.csv(Equipment.all, actor: current_actor)
6
+ # OpenLoam::Export.csv(Equipment.all, actor: current_actor)
7
7
  #
8
- # * only fields the actor's role may READ are columns (Loam::Policy#readable?);
8
+ # * only fields the actor's role may READ are columns (OpenLoam::Policy#readable?);
9
9
  # * an ENCRYPTED column is NEVER exported in the clear — its cell is
10
10
  # "[encrypted]" (the same redaction as the audit trail), so a bulk export can
11
11
  # never become a plaintext dump of PII a role shouldn't see;
12
12
  # * declared custom fields are included (a dictionary field exports its stored
13
- # code, so the file round-trips back through Loam::Import);
13
+ # code, so the file round-trips back through OpenLoam::Import);
14
14
  # * tenant isolation is free — the relation is already scoped.
15
15
  #
16
16
  # Prototype scale: builds the CSV in memory with the stdlib CSV. A very large
@@ -37,10 +37,10 @@ module Loam
37
37
  # redacted), then declared custom fields.
38
38
  def exportable_columns(model, actor)
39
39
  policy = policy_for(model, actor)
40
- encrypted = model.respond_to?(:loam_encrypted_attributes) ? model.loam_encrypted_attributes : []
40
+ encrypted = model.respond_to?(:open_loam_encrypted_attributes) ? model.open_loam_encrypted_attributes : []
41
41
  # The blind-index columns behind searchable encrypted fields (e.g.
42
42
  # email_hash) are internal HMACs — never export them either.
43
- blind = model.respond_to?(:loam_searchable_encrypted_attributes) ? model.loam_searchable_encrypted_attributes.map { |a| "#{a}_hash" } : []
43
+ blind = model.respond_to?(:open_loam_searchable_encrypted_attributes) ? model.open_loam_searchable_encrypted_attributes.map { |a| "#{a}_hash" } : []
44
44
 
45
45
  columns = model.column_names.reject { |c| SKIP_COLUMNS.include?(c) || blind.include?(c) || c == "custom_fields" }
46
46
  .select { |c| policy.readable?(c) }
@@ -61,14 +61,14 @@ module Loam
61
61
  when :custom then (record.custom_field(column[:name]) rescue nil)
62
62
  else record.public_send(column[:name])
63
63
  end
64
- Loam::Csv.safe(value) # neutralize CSV formula injection (=, +, -, @, tab/CR)
64
+ OpenLoam::Csv.safe(value) # neutralize CSV formula injection (=, +, -, @, tab/CR)
65
65
  end
66
66
 
67
67
  def policy_for(model, actor)
68
68
  klass = "#{model.name}Policy".safe_constantize
69
69
  # A blank instance as the record: readable? keys off the role, but the
70
70
  # policy's custom-field checks read record.class.
71
- (klass || Loam::Policy).new(actor, model.new)
71
+ (klass || OpenLoam::Policy).new(actor, model.new)
72
72
  end
73
73
  end
74
74
  end
@@ -1,18 +1,18 @@
1
- module Loam
1
+ module OpenLoam
2
2
  # Runtime feature toggles: is a capability turned ON for this tenant right now.
3
3
  #
4
- # Loam::Features.on?(:beta_dashboard) # for the current tenant
5
- # Loam::Features.enable(:beta_dashboard) # this tenant only
6
- # Loam::Features.enable(:beta_dashboard, scope: :global) # everyone
7
- # Loam::Features.disable(:beta_dashboard)
8
- # Loam::Features.reset(:beta_dashboard) # drop the override → default
4
+ # OpenLoam::Features.on?(:beta_dashboard) # for the current tenant
5
+ # OpenLoam::Features.enable(:beta_dashboard) # this tenant only
6
+ # OpenLoam::Features.enable(:beta_dashboard, scope: :global) # everyone
7
+ # OpenLoam::Features.disable(:beta_dashboard)
8
+ # OpenLoam::Features.reset(:beta_dashboard) # drop the override → default
9
9
  #
10
10
  # A flag gates a CAPABILITY (is this feature live for the tenant), which is
11
11
  # orthogonal to a policy — that gates a PERSON (may this user act). The two
12
12
  # coexist: a manager may be allowed to approve reports AND the approvals
13
13
  # feature may be switched off for their tenant during a rollout.
14
14
  #
15
- # This is deliberately a thin wrapper over Loam::Configs: a flag is a boolean
15
+ # This is deliberately a thin wrapper over OpenLoam::Configs: a flag is a boolean
16
16
  # setting with the same override → global → declared-default resolution, so it
17
17
  # reuses that store (no new table) and its per-request cache. Flags live under
18
18
  # the reserved `features.` key prefix and get their own admin screen, because
@@ -22,7 +22,7 @@ module Loam
22
22
 
23
23
  class << self
24
24
  def on?(name)
25
- !!Loam::Configs.get(key_for(name), default: default_for(name))
25
+ !!OpenLoam::Configs.get(key_for(name), default: default_for(name))
26
26
  end
27
27
 
28
28
  def off?(name)
@@ -32,37 +32,37 @@ module Loam
32
32
  # Flip a flag on. scope: :tenant (default) overrides for the current tenant
33
33
  # and requires a tenant in context; scope: :global sets the app-wide state.
34
34
  def enable(name, scope: :tenant)
35
- Loam::Configs.set(key_for(name), true, scope: scope)
35
+ OpenLoam::Configs.set(key_for(name), true, scope: scope)
36
36
  end
37
37
 
38
38
  def disable(name, scope: :tenant)
39
- Loam::Configs.set(key_for(name), false, scope: scope)
39
+ OpenLoam::Configs.set(key_for(name), false, scope: scope)
40
40
  end
41
41
 
42
42
  # Drop the current tenant's override so the flag falls back to the global
43
43
  # state / declared default.
44
44
  def reset(name)
45
- Loam::Configs.reset(key_for(name))
45
+ OpenLoam::Configs.reset(key_for(name))
46
46
  end
47
47
 
48
48
  def overridden?(name)
49
- Loam::Configs.overridden?(key_for(name))
49
+ OpenLoam::Configs.overridden?(key_for(name))
50
50
  end
51
51
 
52
52
  # Every declared flag, sorted — the admin lists these whether or not a row
53
53
  # exists yet, so a flag is visible the moment it is declared.
54
54
  def declared
55
- Loam.feature_defaults.keys.sort
55
+ OpenLoam.feature_defaults.keys.sort
56
56
  end
57
57
 
58
58
  def description(name)
59
- Loam.feature_defaults.dig(name.to_s, :description)
59
+ OpenLoam.feature_defaults.dig(name.to_s, :description)
60
60
  end
61
61
 
62
62
  # The declared-default state of a flag (false for an unknown one), used as
63
63
  # the last resort when there is no override and no global row.
64
64
  def default_for(name)
65
- !!Loam.feature_defaults.dig(name.to_s, :default)
65
+ !!OpenLoam.feature_defaults.dig(name.to_s, :default)
66
66
  end
67
67
 
68
68
  private
@@ -1,4 +1,4 @@
1
- module Loam
1
+ module OpenLoam
2
2
  # Primary-key generation for tables whose key is not an integer.
3
3
  #
4
4
  # Rails leaves key generation to the database, which works for integer keys
@@ -7,22 +7,22 @@ module Loam
7
7
  # has neither: the INSERT sends NULL and the row is rejected or lands with an
8
8
  # empty key.
9
9
  #
10
- # Loam's tables follow the host app's key type (see
11
- # Loam::Generators::PrimaryKeyOptions), so on a string-keyed app every Loam
10
+ # OpenLoam's tables follow the host app's key type (see
11
+ # OpenLoam::Generators::PrimaryKeyOptions), so on a string-keyed app every OpenLoam
12
12
  # model needs its key generated in Ruby. Before this, hosts patched it in
13
13
  # themselves with a global before_create on ActiveRecord::Base — a lot to ask
14
14
  # of an app whose only deviation was not using bigints, and a hook broad
15
- # enough to reach models that had nothing to do with Loam.
15
+ # enough to reach models that had nothing to do with OpenLoam.
16
16
  #
17
17
  # Integer keys take the early return, so nothing changes for the default app.
18
18
  module GeneratedKey
19
19
  def self.included(base)
20
- base.before_create :assign_loam_generated_key
20
+ base.before_create :assign_open_loam_generated_key
21
21
  end
22
22
 
23
23
  private
24
24
 
25
- def assign_loam_generated_key
25
+ def assign_open_loam_generated_key
26
26
  key = self.class.primary_key
27
27
  return if key.nil? # a join table declared with id: false
28
28
  return if self[key].present? # the caller chose the key
@@ -1,14 +1,14 @@
1
1
  require "csv"
2
2
  require "set"
3
3
 
4
- module Loam
4
+ module OpenLoam
5
5
  # CSV import mapping engine — reusable, tenant-scoped, policy-safe.
6
6
  #
7
- # Loam::Import.preview(csv) # headers + first rows for the mapping UI
8
- # Loam::Import.run(csv, model:, mapping:, actor:, # map CSV header => field
7
+ # OpenLoam::Import.preview(csv) # headers + first rows for the mapping UI
8
+ # OpenLoam::Import.run(csv, model:, mapping:, actor:, # map CSV header => field
9
9
  # match_key: "name", # update-or-create by a key (nil = create-only)
10
10
  # dry_run: true, # validate + report, commit nothing
11
- # progress: progress_job) # advance a Loam::ProgressJob per row
11
+ # progress: progress_job) # advance a OpenLoam::ProgressJob per row
12
12
  #
13
13
  # Safety: the mapping may only target fields the actor's role can WRITE (real
14
14
  # columns + declared custom fields); tenant_id, plumbing, and non-permitted
@@ -27,14 +27,14 @@ module Loam
27
27
 
28
28
  module_function
29
29
 
30
- # Resolve an entity_type string to a model — ONLY a Loam::TenantRecord
30
+ # Resolve an entity_type string to a model — ONLY a OpenLoam::TenantRecord
31
31
  # subclass (never an arbitrary constant), so an import target can't be
32
32
  # smuggled to a global model like User (same guard as the business-rules
33
33
  # engine).
34
34
  def allowed_model(entity_type)
35
35
  klass = entity_type.to_s.safe_constantize
36
- unless klass.is_a?(Class) && klass < Loam::TenantRecord
37
- raise Loam::Error, "import target #{entity_type.inspect} is not a Loam entity"
36
+ unless klass.is_a?(Class) && klass < OpenLoam::TenantRecord
37
+ raise OpenLoam::Error, "import target #{entity_type.inspect} is not a OpenLoam entity"
38
38
  end
39
39
 
40
40
  klass
@@ -79,7 +79,7 @@ module Loam
79
79
  is_new ? (result.created += 1) : (result.updated += 1)
80
80
  rescue StandardError => error
81
81
  # Store ONLY the row number + message — NEVER the raw cell values. The
82
- # result is persisted (Loam::ProgressJob.result); a failed row into an
82
+ # result is persisted (OpenLoam::ProgressJob.result); a failed row into an
83
83
  # encrypted field would otherwise write PLAINTEXT PII at rest.
84
84
  result.failed += 1
85
85
  result.errors << { "row" => line, "message" => error.message }
@@ -103,7 +103,7 @@ module Loam
103
103
  out << (Array(headers) + [ "_error" ])
104
104
  result.errors.each do |error|
105
105
  original = data_rows[error["row"] - 2] || [] # row is 1-based incl. the header
106
- out << original.map { |cell| Loam::Csv.safe(cell) } + [ error["message"] ]
106
+ out << original.map { |cell| OpenLoam::Csv.safe(cell) } + [ error["message"] ]
107
107
  end
108
108
  end
109
109
  end
@@ -115,7 +115,7 @@ module Loam
115
115
  next if target.to_s.blank?
116
116
  next if allowed.include?(target.to_s)
117
117
 
118
- raise Loam::Error, "import mapping refuses #{target.inspect} — not a writable column or custom field"
118
+ raise OpenLoam::Error, "import mapping refuses #{target.inspect} — not a writable column or custom field"
119
119
  end
120
120
  end
121
121
 
@@ -155,14 +155,14 @@ module Loam
155
155
  def safe_parse(csv_string)
156
156
  CSV.parse(csv_string.to_s)
157
157
  rescue CSV::MalformedCSVError => error
158
- raise Loam::Error, "could not parse CSV: #{error.message}"
158
+ raise OpenLoam::Error, "could not parse CSV: #{error.message}"
159
159
  end
160
160
 
161
161
  def policy_for(model, actor)
162
162
  klass = "#{model.name}Policy".safe_constantize
163
163
  # A blank instance as the record: readable?/writable? key off the role, but
164
164
  # custom_field_writable? reads record.class.custom_field_definitions.
165
- (klass || Loam::Policy).new(actor, model.new)
165
+ (klass || OpenLoam::Policy).new(actor, model.new)
166
166
  end
167
167
  end
168
168
  end
@@ -1,9 +1,9 @@
1
1
  require "openssl"
2
2
  require "digest"
3
3
 
4
- module Loam
4
+ module OpenLoam
5
5
  # Receiving webhooks FROM external systems (the inbound sibling of
6
- # Loam::Webhooks). One entry point — `ingest` — does the whole verified,
6
+ # OpenLoam::Webhooks). One entry point — `ingest` — does the whole verified,
7
7
  # replay-resistant pipeline and returns a Result the controller turns into an
8
8
  # HTTP status. Kept here (not in a controller) so it is testable without HTTP
9
9
  # and shared by the generated app and the demo.
@@ -30,13 +30,13 @@ module Loam
30
30
  module_function
31
31
 
32
32
  def ingest(token:, raw_body:, headers:)
33
- Loam::Telemetry.span("inbound_webhook") { run_ingest(token, raw_body.to_s, headers) }
33
+ OpenLoam::Telemetry.span("inbound_webhook") { run_ingest(token, raw_body.to_s, headers) }
34
34
  end
35
35
 
36
36
  def run_ingest(token, raw_body, headers)
37
37
  return Result.new(status: 413, reason: "body too large") if raw_body.bytesize > MAX_BYTES
38
38
 
39
- source = Loam::InboundWebhookSource.resolve(token)
39
+ source = OpenLoam::InboundWebhookSource.resolve(token)
40
40
  return Result.new(status: 404, reason: "unknown or inactive source") if source.nil?
41
41
 
42
42
  signature = header(headers, source.signature_header_key)
@@ -51,8 +51,8 @@ module Loam
51
51
 
52
52
  begin
53
53
  delivery = nil
54
- Loam::InboundWebhookDelivery.transaction do
55
- delivery = Loam::InboundWebhookDelivery.create!(
54
+ OpenLoam::InboundWebhookDelivery.transaction do
55
+ delivery = OpenLoam::InboundWebhookDelivery.create!(
56
56
  source: source, external_id: external_id, event_name: source.event_name,
57
57
  status: "received", received_at: Time.current, payload: parse(raw_body)
58
58
  )
@@ -60,7 +60,7 @@ module Loam
60
60
  # lives on the delivery row, subscribers read it from there. Publishing
61
61
  # inside the txn ties capture to the row — a publish failure rolls the
62
62
  # row back so the sender's retry isn't deduped away.
63
- Loam::Events.publish(source.event_name, { source_id: source.id, delivery_id: delivery.id })
63
+ OpenLoam::Events.publish(source.event_name, { source_id: source.id, delivery_id: delivery.id })
64
64
  end
65
65
  Result.new(status: 202, reason: "accepted", delivery: delivery)
66
66
  rescue ActiveRecord::RecordNotUnique
@@ -1,17 +1,17 @@
1
- module Loam
1
+ module OpenLoam
2
2
  # Tenant lifecycle: what a brand-new tenant gets for free.
3
3
  #
4
- # An app declares seeding once, in config/initializers/loam.rb:
4
+ # An app declares seeding once, in config/initializers/open_loam.rb:
5
5
  #
6
- # Loam.on_tenant_created do |tenant|
7
- # Loam::FieldDefinition.find_or_create_by!(entity_type: "Equipment", name: "asset_tag") { ... }
6
+ # OpenLoam.on_tenant_created do |tenant|
7
+ # OpenLoam::FieldDefinition.find_or_create_by!(entity_type: "Equipment", name: "asset_tag") { ... }
8
8
  # end
9
9
  #
10
- # The block runs inside `Loam.as_tenant(tenant)`, so tenant-scoped writes
10
+ # The block runs inside `OpenLoam.as_tenant(tenant)`, so tenant-scoped writes
11
11
  # need no extra ceremony.
12
12
  #
13
13
  # THE CONTRACT: callbacks MUST be idempotent. They fire once when a tenant is
14
- # created, and again for EVERY existing tenant whenever `bin/rails loam:sync`
14
+ # created, and again for EVERY existing tenant whenever `bin/rails open_loam:sync`
15
15
  # runs — which is how a role/field/default added by a later release reaches
16
16
  # tenants that already exist. Write `find_or_create_by!`, never `create!`.
17
17
  module Lifecycle
@@ -27,14 +27,14 @@ module Loam
27
27
  end
28
28
 
29
29
  # The single execution path for a tenant's callbacks — used both by
30
- # Loam::Tenant's after_create_commit and by sync_tenants!, so "runs inside
30
+ # OpenLoam::Tenant's after_create_commit and by sync_tenants!, so "runs inside
31
31
  # as_tenant, in declaration order" can never drift between the two.
32
32
  #
33
33
  # Exceptions propagate: a failing callback fails the tenant creation (Rails
34
34
  # re-raises from after_commit) or the sync run, loudly, like every other
35
- # Loam guardrail.
35
+ # OpenLoam guardrail.
36
36
  def self.run_tenant_created(tenant)
37
- Loam.as_tenant(tenant) do
37
+ OpenLoam.as_tenant(tenant) do
38
38
  tenant_created_callbacks.each { |callback| callback.call(tenant) }
39
39
  end
40
40
  end
@@ -44,7 +44,7 @@ module Loam
44
44
  # Returns the number of tenants synced.
45
45
  def self.sync_tenants!
46
46
  count = 0
47
- Loam::Tenant.find_each do |tenant|
47
+ OpenLoam::Tenant.find_each do |tenant|
48
48
  run_tenant_created(tenant)
49
49
  count += 1
50
50
  end
@@ -52,8 +52,8 @@ module Loam
52
52
  end
53
53
 
54
54
  # Role names this app expects every tenant to have — declared in the
55
- # initializer (`Loam.default_roles = %w[manager employee]`) and read by
56
- # whatever seeds memberships. A registry, not a mechanism: Loam does not
55
+ # initializer (`OpenLoam.default_roles = %w[manager employee]`) and read by
56
+ # whatever seeds memberships. A registry, not a mechanism: OpenLoam does not
57
57
  # create roles for you, because who gets which role is business logic.
58
58
  def self.default_roles
59
59
  @default_roles ||= []
@@ -64,7 +64,7 @@ module Loam
64
64
  end
65
65
 
66
66
  # App-wide setting defaults: `{ "billing.currency" => "USD" }`, declared in
67
- # the initializer and read by Loam::Configs as the baseline a key resolves
67
+ # the initializer and read by OpenLoam::Configs as the baseline a key resolves
68
68
  # to when no global row and no tenant override exist. A registry, like
69
69
  # default_roles — declaring a default here needs no migration and no row.
70
70
  def self.config_defaults
@@ -75,8 +75,8 @@ module Loam
75
75
  @config_defaults = defaults.to_h.transform_keys(&:to_s)
76
76
  end
77
77
 
78
- # Event-name patterns (Loam::Events.pattern_matches?) whose events may be
79
- # pushed to the browser over SSE (Loam::EventStream). DEFAULT OFF — an empty
78
+ # Event-name patterns (OpenLoam::Events.pattern_matches?) whose events may be
79
+ # pushed to the browser over SSE (OpenLoam::EventStream). DEFAULT OFF — an empty
80
80
  # list means nothing reaches a browser; an app opts in explicitly, so a stray
81
81
  # event never leaks by default.
82
82
  def self.broadcast_events
@@ -87,8 +87,8 @@ module Loam
87
87
  @broadcast_events = Array(patterns).map(&:to_s)
88
88
  end
89
89
 
90
- # The locales content translations (Loam::Translatable) may be authored in —
91
- # declared in the initializer (`Loam.locales = %w[en de pl]`), so the admin
90
+ # The locales content translations (OpenLoam::Translatable) may be authored in —
91
+ # declared in the initializer (`OpenLoam.locales = %w[en de pl]`), so the admin
92
92
  # knows which languages to offer. A registry like the others; defaults to the
93
93
  # single default locale.
94
94
  def self.locales
@@ -100,9 +100,9 @@ module Loam
100
100
  end
101
101
 
102
102
  # Job classes an app EXPLICITLY allows the scheduler to run, beyond the ones
103
- # it registers via Loam::Scheduler.register. An allowlist (not "any
103
+ # it registers via OpenLoam::Scheduler.register. An allowlist (not "any
104
104
  # ActiveJob") so a tenant admin can't schedule ActiveStorage::PurgeJob or a
105
- # mailer. Declared in the initializer: `Loam.schedulable_jobs = %w[DigestJob]`.
105
+ # mailer. Declared in the initializer: `OpenLoam.schedulable_jobs = %w[DigestJob]`.
106
106
  def self.schedulable_jobs
107
107
  @schedulable_jobs ||= []
108
108
  end
@@ -116,17 +116,17 @@ module Loam
116
116
  end
117
117
 
118
118
  # The current request/job locale — content reads overlay onto it. Request
119
- # state like the tenant (set in a before_action, reset with Loam::Current).
119
+ # state like the tenant (set in a before_action, reset with OpenLoam::Current).
120
120
  def self.locale
121
- (Loam::Current.locale || default_locale).to_s
121
+ (OpenLoam::Current.locale || default_locale).to_s
122
122
  end
123
123
 
124
124
  def self.locale=(code)
125
- Loam::Current.locale = code&.to_s
125
+ OpenLoam::Current.locale = code&.to_s
126
126
  end
127
127
 
128
128
  # Known feature flags: `{ "beta_dashboard" => { default: false, description:
129
- # "..." } }`, declared in the initializer and read by Loam::Features. A
129
+ # "..." } }`, declared in the initializer and read by OpenLoam::Features. A
130
130
  # registry like the others — a flag with no row resolves to its declared
131
131
  # default, and the admin can list EVERY known flag, not just toggled ones.
132
132
  def self.feature_defaults
@@ -143,8 +143,8 @@ module Loam
143
143
  end
144
144
  end
145
145
 
146
- # The public surface is on Loam itself — apps and agents write
147
- # `Loam.on_tenant_created`, never `Loam::Lifecycle.on_tenant_created`.
146
+ # The public surface is on OpenLoam itself — apps and agents write
147
+ # `OpenLoam.on_tenant_created`, never `OpenLoam::Lifecycle.on_tenant_created`.
148
148
  def self.on_tenant_created(&block) = Lifecycle.on_tenant_created(&block)
149
149
  def self.tenant_created_callbacks = Lifecycle.tenant_created_callbacks
150
150
  def self.sync_tenants! = Lifecycle.sync_tenants!
@@ -1,11 +1,11 @@
1
- # Loam's own UI strings (the framework chrome). Shipped inside lib/ so the gem
2
- # packages it, and added to the app's I18n load path by Loam::Engine. An app
3
- # localizes Loam by adding its own `config/locales/loam.<locale>.yml` overriding
4
- # these keys — distinct from Loam::Translatable, which localizes record DATA.
1
+ # OpenLoam's own UI strings (the framework chrome). Shipped inside lib/ so the gem
2
+ # packages it, and added to the app's I18n load path by OpenLoam::Engine. An app
3
+ # localizes OpenLoam by adding its own `config/locales/open_loam.<locale>.yml` overriding
4
+ # these keys — distinct from OpenLoam::Translatable, which localizes record DATA.
5
5
  # Entity and field names come from Rails' own activerecord.models /
6
6
  # activerecord.attributes (via model_name.human / human_attribute_name).
7
7
  en:
8
- loam:
8
+ open_loam:
9
9
  chrome:
10
10
  tenant: "Tenant"
11
11
  user: "User"
@@ -1,22 +1,22 @@
1
1
  require "json"
2
2
 
3
- module Loam
3
+ module OpenLoam
4
4
  module Mcp
5
- # The stdio transport for the Loam MCP server (L-302): newline-delimited
5
+ # The stdio transport for the OpenLoam MCP server (L-302): newline-delimited
6
6
  # JSON-RPC over stdin/stdout, the MCP-spec stdio binding. Authenticates ONCE
7
- # from LOAM_MCP_TOKEN (a Loam API token — never a tool argument, so it can't
7
+ # from OPEN_LOAM_MCP_TOKEN (a OpenLoam API token — never a tool argument, so it can't
8
8
  # land in an agent transcript), then runs every message inside that token's
9
9
  # tenant + actor. Nothing but JSON-RPC is written to stdout; logs go to stderr
10
10
  # (wired in the rake task) — a stray stdout line corrupts the stream.
11
11
  class Server
12
- def initialize(input: $stdin, output: $stdout, token: ENV["LOAM_MCP_TOKEN"])
12
+ def initialize(input: $stdin, output: $stdout, token: ENV["OPEN_LOAM_MCP_TOKEN"])
13
13
  @input = input
14
14
  @output = output
15
15
  @token = token
16
16
  end
17
17
 
18
18
  def run
19
- api_token = Loam::ApiToken.authenticate(@token)
19
+ api_token = OpenLoam::ApiToken.authenticate(@token)
20
20
  return fail_auth unless api_token
21
21
 
22
22
  tenant = api_token.tenant
@@ -27,13 +27,13 @@ module Loam
27
27
  next if line.empty?
28
28
 
29
29
  request = parse(line)
30
- next write(Loam::Mcp.err(nil, -32700, "parse error")) if request.nil?
30
+ next write(OpenLoam::Mcp.err(nil, -32700, "parse error")) if request.nil?
31
31
 
32
32
  begin
33
- response = Loam.as_tenant(tenant, actor: actor) { Loam::Mcp.handle_jsonrpc(request) }
33
+ response = OpenLoam.as_tenant(tenant, actor: actor) { OpenLoam::Mcp.handle_jsonrpc(request) }
34
34
  write(response) if response
35
35
  ensure
36
- Loam::Current.reset
36
+ OpenLoam::Current.reset
37
37
  end
38
38
  end
39
39
  end
@@ -52,7 +52,7 @@ module Loam
52
52
  end
53
53
 
54
54
  def fail_auth
55
- write(Loam::Mcp.err(nil, -32001, "authentication failed: set LOAM_MCP_TOKEN to a valid Loam API token"))
55
+ write(OpenLoam::Mcp.err(nil, -32001, "authentication failed: set OPEN_LOAM_MCP_TOKEN to a valid OpenLoam API token"))
56
56
  exit(1)
57
57
  end
58
58
  end