rails_ai_admin 0.1.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 (193) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +458 -0
  3. data/LICENSE +21 -0
  4. data/README.md +292 -0
  5. data/SECURITY.md +14 -0
  6. data/THIRD_PARTY_NOTICES.md +19 -0
  7. data/app/assets/builds/rails_ai_admin.LICENSE.txt +55 -0
  8. data/app/assets/builds/rails_ai_admin.css +345 -0
  9. data/app/assets/builds/rails_ai_admin.js +33 -0
  10. data/app/controllers/rails_ai_admin/application_controller.rb +255 -0
  11. data/app/controllers/rails_ai_admin/assistant_controller.rb +164 -0
  12. data/app/controllers/rails_ai_admin/audit_controller.rb +16 -0
  13. data/app/controllers/rails_ai_admin/collection_jobs_controller.rb +33 -0
  14. data/app/controllers/rails_ai_admin/collection_operations_controller.rb +79 -0
  15. data/app/controllers/rails_ai_admin/custom_controller.rb +26 -0
  16. data/app/controllers/rails_ai_admin/dashboard_controller.rb +17 -0
  17. data/app/controllers/rails_ai_admin/exports_controller.rb +31 -0
  18. data/app/controllers/rails_ai_admin/files_controller.rb +37 -0
  19. data/app/controllers/rails_ai_admin/imports_controller.rb +41 -0
  20. data/app/controllers/rails_ai_admin/mcp_controller.rb +81 -0
  21. data/app/controllers/rails_ai_admin/mcp_tokens_controller.rb +45 -0
  22. data/app/controllers/rails_ai_admin/operations_controller.rb +105 -0
  23. data/app/controllers/rails_ai_admin/references_controller.rb +16 -0
  24. data/app/controllers/rails_ai_admin/resources_controller.rb +290 -0
  25. data/app/controllers/rails_ai_admin/search_controller.rb +39 -0
  26. data/app/controllers/rails_ai_admin/selections_controller.rb +95 -0
  27. data/app/controllers/rails_ai_admin/surfaces_controller.rb +122 -0
  28. data/app/helpers/rails_ai_admin/dashboard_helper.rb +28 -0
  29. data/app/helpers/rails_ai_admin/fields_helper.rb +242 -0
  30. data/app/helpers/rails_ai_admin/filters_helper.rb +40 -0
  31. data/app/helpers/rails_ai_admin/history_helper.rb +36 -0
  32. data/app/helpers/rails_ai_admin/navigation_helper.rb +54 -0
  33. data/app/helpers/rails_ai_admin/tool_views_helper.rb +48 -0
  34. data/app/jobs/rails_ai_admin/assistant_turn_job.rb +15 -0
  35. data/app/jobs/rails_ai_admin/collections/execution_job.rb +12 -0
  36. data/app/jobs/rails_ai_admin/outbox/delivery_job.rb +13 -0
  37. data/app/models/rails_ai_admin/application_record.rb +8 -0
  38. data/app/models/rails_ai_admin/audit_event.rb +12 -0
  39. data/app/models/rails_ai_admin/batch_item.rb +8 -0
  40. data/app/models/rails_ai_admin/operation_run.rb +20 -0
  41. data/app/models/rails_ai_admin/selection.rb +9 -0
  42. data/app/models/rails_ai_admin/selection_item.rb +9 -0
  43. data/app/models/rails_ai_admin/work_item.rb +18 -0
  44. data/app/views/layouts/rails_ai_admin/application.html.erb +49 -0
  45. data/app/views/layouts/rails_ai_admin/frame.html.erb +5 -0
  46. data/app/views/layouts/rails_ai_admin/status.html.erb +13 -0
  47. data/app/views/rails_ai_admin/assistant/_ask.html.erb +16 -0
  48. data/app/views/rails_ai_admin/assistant/_transcript.html.erb +45 -0
  49. data/app/views/rails_ai_admin/assistant/frame.html.erb +1 -0
  50. data/app/views/rails_ai_admin/assistant/index.html.erb +14 -0
  51. data/app/views/rails_ai_admin/assistant/show.html.erb +44 -0
  52. data/app/views/rails_ai_admin/audit/index.html.erb +40 -0
  53. data/app/views/rails_ai_admin/collection_jobs/index.html.erb +5 -0
  54. data/app/views/rails_ai_admin/collection_jobs/show.html.erb +24 -0
  55. data/app/views/rails_ai_admin/collection_operations/confirmation.html.erb +25 -0
  56. data/app/views/rails_ai_admin/collection_operations/failure.html.erb +10 -0
  57. data/app/views/rails_ai_admin/collection_operations/new.html.erb +11 -0
  58. data/app/views/rails_ai_admin/dashboard/index.html.erb +33 -0
  59. data/app/views/rails_ai_admin/fields/_index.html.erb +1 -0
  60. data/app/views/rails_ai_admin/fields/_input.html.erb +21 -0
  61. data/app/views/rails_ai_admin/fields/_reference.html.erb +1 -0
  62. data/app/views/rails_ai_admin/fields/_reference_picker.html.erb +14 -0
  63. data/app/views/rails_ai_admin/fields/_row.html.erb +27 -0
  64. data/app/views/rails_ai_admin/fields/_show.html.erb +1 -0
  65. data/app/views/rails_ai_admin/imports/new.html.erb +34 -0
  66. data/app/views/rails_ai_admin/mcp_tokens/index.html.erb +33 -0
  67. data/app/views/rails_ai_admin/operations/confirmation.html.erb +32 -0
  68. data/app/views/rails_ai_admin/operations/failure.html.erb +5 -0
  69. data/app/views/rails_ai_admin/operations/form.html.erb +13 -0
  70. data/app/views/rails_ai_admin/resources/_associations.html.erb +12 -0
  71. data/app/views/rails_ai_admin/resources/_errors.html.erb +14 -0
  72. data/app/views/rails_ai_admin/resources/_recovery.html.erb +5 -0
  73. data/app/views/rails_ai_admin/resources/confirm_destroy.html.erb +11 -0
  74. data/app/views/rails_ai_admin/resources/edit.html.erb +1 -0
  75. data/app/views/rails_ai_admin/resources/form.html.erb +16 -0
  76. data/app/views/rails_ai_admin/resources/history.html.erb +27 -0
  77. data/app/views/rails_ai_admin/resources/index.html.erb +88 -0
  78. data/app/views/rails_ai_admin/resources/new.html.erb +1 -0
  79. data/app/views/rails_ai_admin/resources/show.html.erb +12 -0
  80. data/app/views/rails_ai_admin/search/index.html.erb +20 -0
  81. data/app/views/rails_ai_admin/selections/confirm_destroy.html.erb +13 -0
  82. data/app/views/rails_ai_admin/selections/destroyed.html.erb +15 -0
  83. data/app/views/rails_ai_admin/selections/show.html.erb +19 -0
  84. data/app/views/rails_ai_admin/shared/_input_fields.html.erb +23 -0
  85. data/app/views/rails_ai_admin/shared/_navigation.html.erb +8 -0
  86. data/app/views/rails_ai_admin/shared/_session.html.erb +5 -0
  87. data/app/views/rails_ai_admin/statuses/show.html.erb +4 -0
  88. data/app/views/rails_ai_admin/surfaces/_operation_review.html.erb +43 -0
  89. data/app/views/rails_ai_admin/surfaces/show.html.erb +4 -0
  90. data/config/locales/en.yml +549 -0
  91. data/config/routes.rb +64 -0
  92. data/db/assistant_migrate/20261103000001_create_rails_ai_admin_assistant.rb +138 -0
  93. data/db/assistant_migrate/20261112000001_upgrade_rails_ai_admin_assistant_to_ruby_llm_2_2.rb +102 -0
  94. data/db/assistant_migrate/20261114000001_add_streaming_and_access_tokens_to_rails_ai_admin_assistant.rb +29 -0
  95. data/db/migrate/20261029000001_create_rails_ai_admin_execution_tables.rb +35 -0
  96. data/db/migrate/20261029000002_add_callback_warning_to_rails_ai_admin_runs.rb +7 -0
  97. data/db/migrate/20261030000003_create_rails_ai_admin_work_items.rb +26 -0
  98. data/db/migrate/20261030000004_create_rails_ai_admin_selections.rb +28 -0
  99. data/db/migrate/20261030000005_create_rails_ai_admin_collection_runs.rb +41 -0
  100. data/db/migrate/20261113000001_add_record_index_to_rails_ai_admin_audit_events.rb +8 -0
  101. data/lib/generators/rails_ai_admin/assistant/assistant_generator.rb +25 -0
  102. data/lib/generators/rails_ai_admin/assistant/templates/admin_assistant.rb +18 -0
  103. data/lib/generators/rails_ai_admin/engine_migrations.rb +42 -0
  104. data/lib/generators/rails_ai_admin/install/engine_mounts.rb +19 -0
  105. data/lib/generators/rails_ai_admin/install/install_generator.rb +53 -0
  106. data/lib/generators/rails_ai_admin/install/templates/access_test.rb +17 -0
  107. data/lib/generators/rails_ai_admin/install/templates/admin_context.rb +25 -0
  108. data/lib/generators/rails_ai_admin/install/templates/admin_policy_adapter.rb +28 -0
  109. data/lib/generators/rails_ai_admin/install/templates/example_admin.rb +10 -0
  110. data/lib/generators/rails_ai_admin/install/templates/initializer.rb +7 -0
  111. data/lib/generators/rails_ai_admin/override/override_generator.rb +46 -0
  112. data/lib/generators/rails_ai_admin/resource/resource_generator.rb +88 -0
  113. data/lib/rails_ai_admin/assistant/continuation.rb +33 -0
  114. data/lib/rails_ai_admin/assistant/coordinator.rb +306 -0
  115. data/lib/rails_ai_admin/assistant/records.rb +71 -0
  116. data/lib/rails_ai_admin/assistant/runtime.rb +49 -0
  117. data/lib/rails_ai_admin/assistant/tools.rb +477 -0
  118. data/lib/rails_ai_admin/assistant/transcript.rb +140 -0
  119. data/lib/rails_ai_admin/assistant.rb +50 -0
  120. data/lib/rails_ai_admin/authorization/access.rb +296 -0
  121. data/lib/rails_ai_admin/authorization/adapter.rb +92 -0
  122. data/lib/rails_ai_admin/authorization/pundit_adapter.rb +195 -0
  123. data/lib/rails_ai_admin/collections/claim.rb +91 -0
  124. data/lib/rails_ai_admin/collections/contract.rb +113 -0
  125. data/lib/rails_ai_admin/collections/dispatcher.rb +126 -0
  126. data/lib/rails_ai_admin/collections/queries.rb +79 -0
  127. data/lib/rails_ai_admin/collections/result.rb +15 -0
  128. data/lib/rails_ai_admin/collections/runner.rb +208 -0
  129. data/lib/rails_ai_admin/configuration.rb +178 -0
  130. data/lib/rails_ai_admin/context.rb +29 -0
  131. data/lib/rails_ai_admin/doctor.rb +301 -0
  132. data/lib/rails_ai_admin/engine.rb +24 -0
  133. data/lib/rails_ai_admin/error.rb +16 -0
  134. data/lib/rails_ai_admin/field.rb +625 -0
  135. data/lib/rails_ai_admin/fields/association.rb +188 -0
  136. data/lib/rails_ai_admin/fields/computation.rb +43 -0
  137. data/lib/rails_ai_admin/fields/dependency_graph.rb +45 -0
  138. data/lib/rails_ai_admin/fields/file_value.rb +23 -0
  139. data/lib/rails_ai_admin/fields/hook_signatures.rb +18 -0
  140. data/lib/rails_ai_admin/fields/projection.rb +78 -0
  141. data/lib/rails_ai_admin/fields/registry.rb +48 -0
  142. data/lib/rails_ai_admin/fields/scalar_schema.rb +49 -0
  143. data/lib/rails_ai_admin/fields/type.rb +50 -0
  144. data/lib/rails_ai_admin/forms/plan.rb +90 -0
  145. data/lib/rails_ai_admin/input_schema.rb +76 -0
  146. data/lib/rails_ai_admin/integrations/propose_operation.rb +150 -0
  147. data/lib/rails_ai_admin/integrations/tool_views.rb +367 -0
  148. data/lib/rails_ai_admin/mcp.rb +130 -0
  149. data/lib/rails_ai_admin/navigation/list_state.rb +194 -0
  150. data/lib/rails_ai_admin/navigation/menu.rb +31 -0
  151. data/lib/rails_ai_admin/navigation/settings.rb +28 -0
  152. data/lib/rails_ai_admin/operation.rb +120 -0
  153. data/lib/rails_ai_admin/operations/default_handlers.rb +17 -0
  154. data/lib/rails_ai_admin/operations/execution_context.rb +38 -0
  155. data/lib/rails_ai_admin/operations/form_intent.rb +69 -0
  156. data/lib/rails_ai_admin/operations/registry.rb +80 -0
  157. data/lib/rails_ai_admin/operations/result.rb +21 -0
  158. data/lib/rails_ai_admin/operations/runner.rb +633 -0
  159. data/lib/rails_ai_admin/operations/runner_fingerprint.rb +12 -0
  160. data/lib/rails_ai_admin/outbox/delivery_context.rb +51 -0
  161. data/lib/rails_ai_admin/outbox/dispatcher.rb +189 -0
  162. data/lib/rails_ai_admin/outbox/registry.rb +36 -0
  163. data/lib/rails_ai_admin/outbox/request_digest.rb +42 -0
  164. data/lib/rails_ai_admin/outbox/writer.rb +43 -0
  165. data/lib/rails_ai_admin/presentation/association_panel.rb +90 -0
  166. data/lib/rails_ai_admin/presentation/audit_log.rb +63 -0
  167. data/lib/rails_ai_admin/presentation/csv_export.rb +85 -0
  168. data/lib/rails_ai_admin/presentation/csv_import.rb +142 -0
  169. data/lib/rails_ai_admin/presentation/dashboard.rb +122 -0
  170. data/lib/rails_ai_admin/presentation/history.rb +46 -0
  171. data/lib/rails_ai_admin/presentation/index_settings.rb +77 -0
  172. data/lib/rails_ai_admin/presentation/outcomes.rb +44 -0
  173. data/lib/rails_ai_admin/presentation/status.rb +40 -0
  174. data/lib/rails_ai_admin/prune.rb +61 -0
  175. data/lib/rails_ai_admin/queries/list.rb +162 -0
  176. data/lib/rails_ai_admin/queries/named_scope.rb +65 -0
  177. data/lib/rails_ai_admin/record_version.rb +40 -0
  178. data/lib/rails_ai_admin/registry.rb +45 -0
  179. data/lib/rails_ai_admin/request_log_filter.rb +24 -0
  180. data/lib/rails_ai_admin/resource.rb +249 -0
  181. data/lib/rails_ai_admin/resource_identity.rb +15 -0
  182. data/lib/rails_ai_admin/schema_suggestions.rb +105 -0
  183. data/lib/rails_ai_admin/selections/builder.rb +162 -0
  184. data/lib/rails_ai_admin/templates/catalog.rb +84 -0
  185. data/lib/rails_ai_admin/templates/inspector.rb +94 -0
  186. data/lib/rails_ai_admin/templates/metadata.rb +48 -0
  187. data/lib/rails_ai_admin/templates/safe_paths.rb +30 -0
  188. data/lib/rails_ai_admin/test_kit.rb +103 -0
  189. data/lib/rails_ai_admin/version.rb +5 -0
  190. data/lib/rails_ai_admin/work.rb +48 -0
  191. data/lib/rails_ai_admin.rb +112 -0
  192. data/lib/tasks/rails_ai_admin.rake +58 -0
  193. metadata +328 -0
@@ -0,0 +1,345 @@
1
+ .raa {
2
+ --raa-bg: #f3f6f8;
3
+ --raa-panel: #fff;
4
+ --raa-subtle: #f0f5f7;
5
+ --raa-accent: #e0eff3;
6
+ --raa-text: #122a38;
7
+ --raa-muted: #4e6472;
8
+ --raa-line: #d3dfe5;
9
+ --raa-control-line: #849aa6;
10
+ --raa-brand: #155e75;
11
+ --raa-on-brand: #fff;
12
+ --raa-danger: #a62237;
13
+ --raa-on-danger: #fff;
14
+ --raa-focus: #a9490d;
15
+ --raa-radius: .75rem;
16
+ --raa-shadow: 0 1px 2px rgb(12 41 55 / .06);
17
+ margin: 0;
18
+ background: var(--raa-bg);
19
+ color: var(--raa-text);
20
+ font: 16px/1.5 system-ui, sans-serif;
21
+ color-scheme: light;
22
+ }
23
+ .raa * { box-sizing:border-box; }
24
+ .raa a { color:var(--raa-brand); text-underline-offset:.18em; }
25
+ .raa :focus-visible { outline:3px solid var(--raa-focus); outline-offset:3px; }
26
+ .raa .raa-skip { position:fixed; top:-5rem; left:1rem; z-index:10; padding:.75rem; background:var(--raa-panel); }
27
+ .raa .raa-skip:focus { top:1rem; }
28
+ .raa .raa-header {
29
+ display:grid;
30
+ grid-template-columns:minmax(0, 14rem) minmax(0, 30rem) minmax(0, 1fr);
31
+ align-items:center;
32
+ gap:1rem;
33
+ padding:.75rem 1.25rem;
34
+ background:var(--raa-panel);
35
+ border-bottom:1px solid var(--raa-line);
36
+ }
37
+ .raa .raa-header > a { grid-column:1; color:var(--raa-text); font-size:1.125rem; font-weight:750; line-height:1.3; overflow-wrap:anywhere; text-decoration:none; }
38
+
39
+ .raa .raa-shell { display:grid; grid-template-columns:14rem minmax(0,1fr); min-height:calc(100vh - 4.25rem); }
40
+ .raa .raa-shell > nav { padding:1.25rem .9rem; background:var(--raa-panel); border-inline-end:1px solid var(--raa-line); }
41
+ .raa .raa-shell > nav a { display:flex; align-items:center; gap:.6rem; min-height:44px; padding:.45rem .7rem; border-radius:.5rem; color:var(--raa-muted); text-decoration:none; overflow-wrap:anywhere; }
42
+ .raa .raa-shell > nav a:hover { background:var(--raa-subtle); color:var(--raa-text); }
43
+ .raa .raa-shell > nav a[aria-current],.raa .raa-scopes a[aria-current] { background:var(--raa-accent); color:var(--raa-brand); font-weight:700; }
44
+ .raa main { padding:clamp(1.25rem,3vw,2.75rem); max-width:90rem; min-width:0; width:100%; }
45
+ .raa h1 { font-size:clamp(1.65rem,2.7vw,2.35rem); letter-spacing:-.025em; line-height:1.16; margin:0 0 1rem; overflow-wrap:anywhere; }
46
+ .raa h2 { font-size:1.2rem; line-height:1.3; overflow-wrap:anywhere; }
47
+ .raa .raa-heading,.raa .raa-actions { display:flex; flex-wrap:wrap; align-items:center; justify-content:space-between; gap:.65rem 1rem; min-width:0; }
48
+ .raa .raa-actions { justify-content:flex-start; }
49
+ .raa .raa-list-heading { align-items:stretch; flex-direction:column; margin-bottom:1rem; }
50
+ .raa .raa-list-heading h1 { margin:0; }
51
+ .raa .raa-list-toolbar { width:100%; padding:.65rem; border:1px solid var(--raa-line); border-radius:var(--raa-radius); background:var(--raa-panel); box-shadow:var(--raa-shadow); }
52
+ .raa .raa-list-toolbar .raa-search { flex:1 1 17rem; min-width:0; }
53
+ .raa .raa-list-toolbar input[type="search"] { flex:1 1 0; min-width:0; width:0; }
54
+ .raa .raa-list-toolbar .raa-search [type="submit"] { background:var(--raa-subtle); border-color:var(--raa-control-line); color:var(--raa-brand); }
55
+ .raa button:not(.trix-button),.raa input[type="submit"],.raa .raa-button {
56
+ display:inline-block;
57
+ border:1px solid var(--raa-brand);
58
+ border-radius:.5rem;
59
+ padding:.55rem .9rem;
60
+ background:var(--raa-brand);
61
+ color:var(--raa-on-brand);
62
+ font:inherit;
63
+ font-weight:650;
64
+ cursor:pointer;
65
+ text-decoration:none;
66
+ min-height:44px;
67
+ max-width:100%;
68
+ overflow-wrap:anywhere;
69
+ }
70
+ .raa :is(button:not(.trix-button), input[type="submit"], .raa-button):hover:not(:disabled) { filter:brightness(.92); }
71
+ .raa input[type="submit"]:disabled { border-color:var(--raa-line); background:var(--raa-subtle); color:var(--raa-muted); cursor:not-allowed; }
72
+ .raa input.raa-secondary,.raa button.raa-secondary,.raa a.raa-button.raa-secondary { border-color:var(--raa-control-line); background:var(--raa-panel); color:var(--raa-brand); }
73
+ .raa .raa-export { display:inline; }
74
+ .raa .raa-danger { color:var(--raa-danger); }
75
+ .raa input.raa-danger { color:var(--raa-on-danger); background:var(--raa-danger); border-color:var(--raa-danger); }
76
+ .raa .raa-table-scroll { overflow-x:auto; border:1px solid var(--raa-line); border-radius:var(--raa-radius); background:var(--raa-panel); box-shadow:var(--raa-shadow); margin:1rem 0; }
77
+ .raa table { border-collapse:collapse; width:100%; text-align:start; }
78
+ .raa .raa-table-scroll table { min-width:38rem; }
79
+ .raa caption { text-align:start; padding:.65rem 1rem; color:var(--raa-muted); font-size:.875rem; }
80
+ .raa th,.raa td { padding:.6rem .9rem; border-top:1px solid var(--raa-line); overflow-wrap:anywhere; vertical-align:middle; max-width:32rem; }
81
+ .raa thead { background:var(--raa-subtle); }
82
+ .raa tbody tr:hover { background:var(--raa-subtle); }
83
+ .raa th { font-size:.85rem; font-weight:700; overflow-wrap:break-word; }
84
+ .raa .raa-pagination { display:flex; gap:1rem; }
85
+ .raa .raa-count { margin:.85rem 0 0; color:var(--raa-muted); font-size:.875rem; font-variant-numeric:tabular-nums; }
86
+ .raa td.raa-cell-compact { white-space:nowrap; }
87
+ .raa .raa-search { display:flex; flex-wrap:wrap; align-items:center; gap:.75rem; }
88
+ .raa input:not([type="submit"],[type="checkbox"],[type="radio"]),.raa textarea,.raa select { font:inherit; color:var(--raa-text); background:var(--raa-panel); border:1px solid var(--raa-control-line); border-radius:.5rem; padding:.55rem .7rem; min-height:44px; max-width:100%; }
89
+ .raa input::placeholder,.raa textarea::placeholder { color:var(--raa-muted); opacity:1; }
90
+ .raa input:is([type="checkbox"],[type="radio"]) { accent-color:var(--raa-brand); inline-size:1rem; block-size:1rem; margin:0; flex:none; }
91
+ .raa [aria-invalid="true"] { border-color:var(--raa-danger); }
92
+ .raa .raa-field { margin:1.25rem 0; max-width:40rem; }
93
+ .raa .raa-field label { display:block; margin-bottom:.35rem; font-weight:600; }
94
+ .raa .raa-field input:not([type="checkbox"],[type="radio"]),.raa .raa-field textarea,.raa .raa-field select { width:100%; }
95
+ .raa .raa-record-form { max-width:48rem; padding:clamp(1rem,3vw,1.75rem); background:var(--raa-panel); border:1px solid var(--raa-line); border-radius:var(--raa-radius); box-shadow:var(--raa-shadow); }
96
+ .raa .raa-record-form > .raa-field-help:first-of-type { margin-top:0; }
97
+ .raa .raa-record-form > .raa-actions { margin-top:1.5rem; padding-top:1rem; border-top:1px solid var(--raa-line); }
98
+ .raa .raa-details { display:grid; grid-template-columns:minmax(8rem,1fr) minmax(0,3fr); background:var(--raa-panel); padding:1rem; border:1px solid var(--raa-line); border-radius:.6rem; }
99
+ .raa dt,.raa dd { padding:.7rem; margin:0; overflow-wrap:anywhere; }
100
+ .raa dt { color:var(--raa-muted); }
101
+ .raa .raa-notice,.raa .raa-errors { padding:1rem 1.25rem; background:var(--raa-panel); border:1px solid var(--raa-line); border-left:4px solid var(--raa-brand); border-radius:.4rem; }
102
+ .raa .raa-errors { border-left-color:var(--raa-danger); }
103
+ .raa .raa-field-error { color:var(--raa-danger); }
104
+ .raa .raa-dashboard-intro { margin:0; color:var(--raa-muted); }
105
+ .raa .raa-cards { padding:0; margin:1.25rem 0 1.5rem; list-style:none; display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,10.5rem),1fr)); gap:.75rem; }
106
+ .raa .raa-cards li { min-width:0; }
107
+ .raa .raa-cards a {
108
+ min-height:5rem;
109
+ height:100%;
110
+ display:grid;
111
+ grid-template-columns:1.1rem minmax(0,1fr) auto;
112
+ align-items:center;
113
+ gap:.65rem;
114
+ padding:.85rem;
115
+ border:1px solid var(--raa-line);
116
+ border-radius:var(--raa-radius);
117
+ background:var(--raa-panel);
118
+ box-shadow:var(--raa-shadow);
119
+ color:var(--raa-text);
120
+ font-weight:700;
121
+ text-decoration:none;
122
+ overflow-wrap:anywhere;
123
+ }
124
+ .raa .raa-cards a > span { grid-column:2; }
125
+ .raa .raa-cards a::after { content:""; width:.4rem; height:.4rem; border-block-start:2px solid; border-inline-end:2px solid; transform:rotate(45deg); color:var(--raa-brand); }
126
+ .raa .raa-cards a:dir(rtl)::after { transform:rotate(-45deg); }
127
+ .raa .raa-cards .raa-nav-icon { width:1.1rem; height:1.1rem; color:var(--raa-brand); }
128
+ .raa .raa-cards a:hover,.raa .raa-metrics a:hover { border-color:var(--raa-control-line); background:var(--raa-subtle); }
129
+ .raa .raa-association { margin-top:1.5rem; background:var(--raa-panel); border:1px solid var(--raa-line); border-radius:.6rem; padding:1rem; } .raa .raa-association ul { margin:.5rem 0; padding-left:1.25rem; } .raa .raa-association p { margin:.5rem 0 0; }
130
+
131
+ @media (prefers-color-scheme:dark) {
132
+ .raa {
133
+ --raa-bg: #101a23;
134
+ --raa-panel: #192832;
135
+ --raa-subtle: #21333f;
136
+ --raa-accent: #263e4a;
137
+ --raa-text: #e9f2f6;
138
+ --raa-muted: #b2c4cf;
139
+ --raa-line: #354c5a;
140
+ --raa-control-line: #72909f;
141
+ --raa-brand: #87d8eb;
142
+ --raa-on-brand: #10222d;
143
+ --raa-danger: #ff9fac;
144
+ --raa-on-danger: #28121a;
145
+ --raa-focus: #ffb37d;
146
+ --raa-shadow: none;
147
+ color-scheme: dark;
148
+ }
149
+ }
150
+
151
+ .raa .raa-tab-links { display:flex; gap:.5rem; overflow-x:auto; margin:1rem 0; border-bottom:1px solid var(--raa-line); }
152
+ .raa .raa-tab-links a { padding:.65rem 1rem; min-height:44px; white-space:nowrap; }
153
+ .raa .raa-tab-links [aria-selected="true"] { color:var(--raa-text); border-bottom:3px solid var(--raa-brand); font-weight:700; text-decoration:none; }
154
+ .raa .raa-form-panel { border:1px solid var(--raa-line); border-radius:.4rem; margin:1.25rem 0; padding:0 1rem; min-width:0; }
155
+ .raa .raa-form-panel legend { padding:0 .4rem; font-weight:600; }
156
+ .raa .raa-field-help { color:var(--raa-muted); font-size:.9rem; }
157
+ .raa .raa-field .raa-readonly { display:block; overflow-wrap:anywhere; padding:.6rem 0; }
158
+ .raa .raa-field .raa-label { display:block; margin-bottom:.35rem; font-weight:600; }
159
+ .raa .raa-required { color:var(--raa-danger); }
160
+ .raa .raa-visually-hidden { position:absolute; width:1px; height:1px; overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; }
161
+ .raa [hidden] { display:none !important; }
162
+
163
+ .raa .raa-status-page { max-width:48rem; margin:4rem auto; }
164
+ .raa .raa-status-code { color:var(--raa-muted); font-weight:600; }
165
+
166
+ .raa .raa-nav-group { margin-top:1rem; min-width:0; }
167
+ .raa .raa-nav-group-label { color:var(--raa-muted); font-size:.75rem; letter-spacing:.035em; margin:.3rem .7rem; overflow-wrap:anywhere; }
168
+
169
+ .raa .raa-nav-group a span { overflow-wrap:anywhere; min-width:0; }
170
+ .raa .raa-nav-icon { display:inline-block; width:1.25rem; height:1.25rem; flex:none; vertical-align:middle; margin-right:.35rem; }
171
+ .raa .raa-nav-group .raa-nav-icon { margin-right:0; }
172
+
173
+ .raa .raa-scopes ul { display:flex; flex-wrap:wrap; gap:.25rem; margin:1rem 0; padding:0 0 .5rem; list-style:none; border-bottom:1px solid var(--raa-line); }
174
+ .raa .raa-scopes a { display:inline-flex; align-items:center; min-height:44px; padding:0 1rem; border-radius:.4rem; overflow-wrap:anywhere; }
175
+ .raa .raa-filters fieldset { display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,12rem),1fr)); gap:.75rem 1rem; margin:.5rem 0 .75rem; padding:.75rem 1rem 1rem; border:1px solid var(--raa-line); border-radius:.5rem; min-width:0; }
176
+ .raa .raa-filters legend { padding:0 .4rem; font-weight:600; }
177
+ .raa .raa-filter { min-width:0; }
178
+ .raa .raa-filter label { display:block; margin-bottom:.25rem; font-weight:600; overflow-wrap:anywhere; }
179
+ .raa .raa-filter input:not([type="checkbox"],[type="radio"]),.raa .raa-filter select { width:100%; }
180
+
181
+ .raa .raa-conversation {
182
+ display:flex;
183
+ flex-direction:column;
184
+ min-width:0;
185
+ block-size:max(29rem, calc(100dvh - 9rem));
186
+ background:var(--raa-panel);
187
+ border:1px solid var(--raa-line);
188
+ border-radius:1rem;
189
+ box-shadow:var(--raa-shadow);
190
+ }
191
+ .raa .raa-conversation-header {
192
+ display:flex;
193
+ align-items:center;
194
+ justify-content:space-between;
195
+ flex-wrap:wrap;
196
+ gap:.5rem 1rem;
197
+ padding:.8rem clamp(.8rem,2vw,1.5rem);
198
+ border-block-end:1px solid var(--raa-line);
199
+ }
200
+ .raa .raa-conversation-header h1 { margin:.15rem 0 0; font-size:clamp(1.2rem,2vw,1.55rem); }
201
+ .raa .raa-conversation-header a,.raa .raa-conversation-header button { font-size:.875rem; }
202
+ .raa .raa-conversation-header .raa-actions { gap:.25rem; }
203
+ .raa .raa-conversation-header .raa-chat-archive { background:transparent; border-color:transparent; color:var(--raa-muted); }
204
+ .raa .raa-conversation-thread {
205
+ flex:1 1 auto;
206
+ min-block-size:8rem;
207
+ overflow:auto;
208
+ overflow-anchor:none;
209
+ padding:1rem clamp(.8rem,3vw,2rem);
210
+ }
211
+ .raa .raa-conversation-thread:focus-visible { outline-offset:-4px; }
212
+ .raa .raa-chat { display:block; max-inline-size:48rem; min-block-size:100%; margin-inline:auto; }
213
+ .raa .raa-chat:has(> .raa-chat-empty) { display:grid; align-content:center; }
214
+ .raa .raa-chat-empty {
215
+ display:grid;
216
+ justify-items:center;
217
+ padding:2rem 1rem;
218
+ text-align:center;
219
+ }
220
+ .raa .raa-chat-empty h2 { margin:0; font-size:clamp(1.6rem,3vw,2.2rem); letter-spacing:-.025em; }
221
+ .raa .raa-chat-empty p { margin:.5rem 0 0; color:var(--raa-muted); max-inline-size:36ch; }
222
+ .raa .raa-chat-log { list-style:none; margin:0; padding:0; display:grid; gap:1rem; }
223
+ .raa .raa-chat-message,.raa .raa-chat-records,.raa .raa-chat-surface { min-width:0; overflow-wrap:anywhere; }
224
+ .raa .raa-chat-message { inline-size:fit-content; max-inline-size:100%; padding:.65rem .9rem; }
225
+ .raa .raa-chat-user {
226
+ justify-self:end;
227
+ max-inline-size:85%;
228
+ background:var(--raa-accent);
229
+ border-radius:1rem 1rem .3rem 1rem;
230
+ }
231
+ .raa .raa-chat-assistant { padding-inline:0; max-inline-size:72ch; }
232
+ .raa .raa-chat-event,.raa .raa-chat-records,.raa .raa-chat-turn {
233
+ background:var(--raa-subtle);
234
+ border:1px solid var(--raa-line);
235
+ border-radius:var(--raa-radius);
236
+ }
237
+ .raa .raa-chat-records { padding:.75rem 1rem; }
238
+ .raa .raa-chat-surface > .rails-tool-views-surface { padding:.9rem 1rem; border:1px solid var(--raa-line); border-radius:var(--raa-radius); background:var(--raa-subtle); }
239
+ .raa .raa-chat-surface h2 { margin-top:0; }
240
+ .raa .raa-chat-role { display:block; color:var(--raa-muted); font-size:.8rem; font-weight:700; margin-bottom:.25rem; }
241
+ .raa .raa-chat-text { white-space:pre-wrap; }
242
+ .raa .raa-chat-activity { color:var(--raa-muted); font-size:.85rem; }
243
+ .raa .raa-chat-records ul { margin:0; padding-inline-start:1.25rem; }
244
+ .raa .raa-chat-turn { display:flex; flex-wrap:wrap; align-items:center; gap:.5rem .75rem; margin-block-start:1rem; padding:.5rem .75rem; font-size:.875rem; }
245
+ .raa .raa-chat-status { flex:1 1 13rem; margin:0; color:var(--raa-muted); }
246
+ .raa .raa-chat-failure { color:var(--raa-danger); }
247
+ .raa .raa-chat-status[data-raa-pending]::before {
248
+ content:"";
249
+ display:inline-block;
250
+ inline-size:.5rem;
251
+ block-size:.5rem;
252
+ margin-inline-end:.5rem;
253
+ vertical-align:.1em;
254
+ border-radius:50%;
255
+ background:var(--raa-brand);
256
+ }
257
+ .raa .raa-chat-composer { display:grid; gap:.5rem; margin-top:1rem; }
258
+ .raa .raa-chat-composer textarea { width:100%; }
259
+ .raa .raa-conversation-footer { position:relative; padding:.75rem clamp(.8rem,3vw,2rem); border-block-start:1px solid var(--raa-line); }
260
+ .raa .raa-conversation-composer { max-inline-size:48rem; margin:0 auto; }
261
+ .raa .raa-chat-input { display:flex; align-items:flex-end; gap:.65rem; }
262
+ .raa .raa-chat-input textarea { flex:1; min-width:0; max-block-size:10rem; resize:vertical; }
263
+ .raa .raa-chat-input textarea[aria-invalid="true"] { border-color:var(--raa-danger); }
264
+ .raa .raa-chat-input input[type="submit"] { flex:none; max-inline-size:45%; white-space:normal; }
265
+ .raa .raa-conversation-composer > p { margin:0; }
266
+ .raa .raa-chat-shortcut { font-size:.75rem; color:var(--raa-muted); }
267
+ .raa .raa-chat-latest { position:absolute; inset-block-end:calc(100% + .55rem); inset-inline-end:clamp(.8rem,3vw,2rem); box-shadow:var(--raa-shadow); }
268
+ .raa .raa-conversation-closed { padding:0 1.25rem 1.25rem; }
269
+ .raa .raa-conversation:has(.raa-conversation-closed) { block-size:auto; }
270
+ @media (max-width:768px) {
271
+ .raa .raa-conversation { block-size:max(29rem, calc(100dvh - 2rem)); }
272
+ .raa .raa-conversation-footer { position:sticky; inset-block-end:0; background:var(--raa-panel); border-end-start-radius:inherit; border-end-end-radius:inherit; }
273
+ .raa .raa-chat-user { max-inline-size:94%; }
274
+ }
275
+ .raa .raa-chat-list { padding-left:1.25rem; }
276
+ .raa .raa-code { color:var(--raa-muted); font-size:.8rem; font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }
277
+ .raa .raa-multiline { white-space:pre-wrap; }
278
+ .raa .raa-file-preview { display:block; max-width:min(100%,20rem); max-height:14rem; margin:.25rem 0; border:1px solid var(--raa-line); border-radius:.4rem; background:var(--raa-panel); }
279
+ .raa .raa-file-current,.raa .raa-file-remove { margin:.25rem 0; }
280
+ .raa .raa-file-list { list-style:none; padding:0; margin:.25rem 0; display:flex; flex-wrap:wrap; gap:.75rem 1.5rem; }
281
+ .raa .raa-rich-text { overflow-wrap:anywhere; }
282
+ .raa .raa-rich-text > :first-child { margin-top:0; }
283
+ .raa .raa-rich-text-editor { display:block; min-height:10rem; padding:.6rem .8rem; background:var(--raa-panel); border:1px solid var(--raa-line); border-radius:.4rem; }
284
+ .raa trix-toolbar [data-trix-button-group="file-tools"] { display:none; }
285
+ .raa .raa-references { display:flex; flex-wrap:wrap; gap:.35rem 1.25rem; padding:.4rem 0; }
286
+ .raa .raa-check { display:flex; align-items:center; gap:.4rem; }
287
+ .raa .raa-references .raa-reference { flex-basis:100%; }
288
+ .raa .raa-ask { margin:.85rem 0; padding:.55rem .85rem; background:var(--raa-panel); border:1px solid var(--raa-line); border-radius:.5rem; }
289
+ .raa .raa-ask summary { cursor:pointer; font-weight:600; color:var(--raa-brand); }
290
+ .raa .raa-chat-streaming .raa-chat-text::after { content:""; display:inline-block; width:.15em; height:1em; margin-inline-start:.15em; vertical-align:-.15em; background:var(--raa-brand); }
291
+ .raa .raa-json { margin:0; padding:.6rem .8rem; max-height:24rem; overflow:auto; white-space:pre; font:.85rem/1.45 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; background:var(--raa-bg); border:1px solid var(--raa-line); border-radius:.4rem; }
292
+ .raa textarea.raa-json-input { font:.85rem/1.45 ui-monospace,SFMono-Regular,Menlo,Consolas,monospace; }
293
+ .raa .raa-header-meta { grid-column:3; display:flex; flex-wrap:wrap; align-items:center; justify-content:flex-end; min-width:0; gap:.5rem; overflow-wrap:anywhere; }
294
+ .raa .raa-global-search { grid-column:2; min-width:0; margin:0; }
295
+ .raa .raa-global-search input { width:100%; }
296
+
297
+ .raa .raa-dashboard-section { margin:1.25rem 0; padding:clamp(1rem,2.4vw,1.5rem); background:var(--raa-panel); border:1px solid var(--raa-line); border-radius:var(--raa-radius); box-shadow:var(--raa-shadow); }
298
+ .raa .raa-dashboard-section h2 a { color:var(--raa-text); }
299
+ .raa .raa-dashboard-section h2 { margin-top:0; }
300
+ .raa .raa-metrics { list-style:none; margin:0; padding:0; display:grid; grid-template-columns:repeat(auto-fit,minmax(min(100%,10rem),1fr)); gap:.75rem; }
301
+ .raa .raa-metrics a { display:flex; flex-direction:column; height:100%; padding:.65rem .85rem; border:1px solid var(--raa-line); border-radius:.5rem; text-decoration:none; overflow-wrap:anywhere; }
302
+ .raa .raa-metric-value { font-size:1.75rem; font-weight:750; font-variant-numeric:tabular-nums; color:var(--raa-brand); }
303
+ .raa .raa-metric-label { color:var(--raa-muted); font-size:.875rem; }
304
+ .raa .raa-trend { margin:1.1rem 0 0; padding-top:1rem; border-top:1px solid var(--raa-line); }
305
+ .raa .raa-chart { display:block; width:100%; height:8rem; margin:.5rem 0 .25rem; }
306
+ .raa .raa-bar { fill:var(--raa-brand); }
307
+ .raa .raa-axis { stroke:var(--raa-line); stroke-width:1; }
308
+ .raa .raa-trend-axis { display:flex; justify-content:space-between; color:var(--raa-muted); font-size:.85rem; }
309
+ .raa .raa-trend details { margin-top:.5rem; }
310
+ .raa .raa-card-count { display:block; color:var(--raa-muted); font-size:.8125rem; font-weight:400; }
311
+
312
+ .raa .raa-environment { padding:.15rem .5rem; border:1px solid var(--raa-line); border-radius:.3rem; color:var(--raa-muted); font-size:.8rem; }
313
+
314
+ .raa .raa-filter-panel { margin:.75rem 0; padding:.15rem .85rem; border:1px solid var(--raa-line); border-radius:.5rem; background:var(--raa-panel); }
315
+ .raa .raa-filter-panel[open] { padding-bottom:.85rem; }
316
+ .raa .raa-filter-panel summary { cursor:pointer; font-weight:650; padding:.4rem 0; }
317
+ .raa .raa-selection-bar { display:flex; flex-wrap:wrap; align-items:center; gap:1rem; margin:.75rem 0; }
318
+ .raa .raa-selection-bar p { margin:0; }
319
+ .raa .raa-row-actions a { display:inline-block; padding:.125rem 0; }
320
+ .raa .raa-row-actions a + a { margin-inline-start:.65rem; }
321
+ .raa .raa-reference { display:grid; gap:.4rem; }
322
+ .raa .raa-reference-current { margin:0; color:var(--raa-muted); }
323
+ .raa .raa-reference-search { display:grid; gap:.3rem; }
324
+ .raa .raa-reference-search label { font-weight:400; }
325
+ .raa .raa-reference-status { margin:0; min-height:1.2em; color:var(--raa-muted); }
326
+ .raa .raa-reference-results { list-style:none; margin:0; padding:0; display:grid; gap:.25rem; }
327
+ .raa .raa-reference-results button { width:100%; text-align:left; overflow-wrap:anywhere; }
328
+ @media (max-width:768px) {
329
+ .raa .raa-shell { grid-template-columns:minmax(0,1fr); }
330
+ .raa .raa-header { grid-template-columns:minmax(0,1fr) auto; gap:.65rem; padding:.75rem 1rem; }
331
+ .raa .raa-header-meta { grid-column:2; grid-row:1; }
332
+ .raa .raa-header-meta:empty { display:none; }
333
+ .raa .raa-global-search { grid-column:1/-1; grid-row:2; }
334
+ .raa .raa-shell > nav { padding:.45rem .65rem; border-inline-end:0; border-bottom:1px solid var(--raa-line); }
335
+ .raa .raa-nav-primary,.raa .raa-nav-group { display:flex; flex-wrap:wrap; gap:0 .2rem; margin-top:0; }
336
+ .raa .raa-nav-group-label { flex-basis:100%; margin:.2rem .55rem 0; }
337
+ .raa .raa-shell > nav a { padding:.4rem .55rem; font-size:.875rem; }
338
+ .raa main { padding:1rem; }
339
+ .raa .raa-list-toolbar { gap:.5rem; }
340
+ .raa .raa-list-toolbar .raa-search { flex-basis:100%; }
341
+ .raa .raa-list-toolbar > :is(.raa-button,.raa-export) { font-size:.875rem; }
342
+ .raa .raa-list-toolbar > .raa-button,.raa .raa-export input { padding-inline:.65rem; }
343
+ .raa .raa-details { grid-template-columns:minmax(0,1fr); }
344
+ .raa dt { padding-bottom:0; }
345
+ }