nitro_kit 0.8.0 → 2.0.0.alpha.1

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 (219) hide show
  1. checksums.yaml +4 -4
  2. data/.agents/plugins/marketplace.json +20 -0
  3. data/CHANGELOG.md +151 -0
  4. data/LICENSE +28 -0
  5. data/README.md +21 -16
  6. data/STYLE_GUIDE.md +425 -0
  7. data/app/assets/stylesheets/nitro_kit-tailwind-v4.css +38 -0
  8. data/app/assets/stylesheets/nitro_kit.css +7225 -0
  9. data/app/components/nitro_kit/accordion.rb +125 -65
  10. data/app/components/nitro_kit/alert.rb +80 -43
  11. data/app/components/nitro_kit/app_navigation.rb +307 -0
  12. data/app/components/nitro_kit/app_shell.rb +227 -0
  13. data/app/components/nitro_kit/appearance_bootstrap.rb +146 -0
  14. data/app/components/nitro_kit/appearance_picker.rb +156 -0
  15. data/app/components/nitro_kit/auth_shell.rb +34 -0
  16. data/app/components/nitro_kit/avatar.rb +85 -29
  17. data/app/components/nitro_kit/avatar_stack.rb +155 -9
  18. data/app/components/nitro_kit/badge.rb +43 -81
  19. data/app/components/nitro_kit/button.rb +180 -103
  20. data/app/components/nitro_kit/button_group.rb +63 -11
  21. data/app/components/nitro_kit/button_to.rb +69 -0
  22. data/app/components/nitro_kit/card.rb +42 -45
  23. data/app/components/nitro_kit/checkbox.rb +115 -62
  24. data/app/components/nitro_kit/checkbox_group.rb +128 -22
  25. data/app/components/nitro_kit/choice.rb +55 -0
  26. data/app/components/nitro_kit/combobox.rb +292 -105
  27. data/app/components/nitro_kit/command_palette.rb +412 -0
  28. data/app/components/nitro_kit/component.rb +322 -46
  29. data/app/components/nitro_kit/container.rb +32 -0
  30. data/app/components/nitro_kit/control_group.rb +45 -0
  31. data/app/components/nitro_kit/danger_zone.rb +78 -0
  32. data/app/components/nitro_kit/data_section.rb +106 -0
  33. data/app/components/nitro_kit/details_table.rb +229 -0
  34. data/app/components/nitro_kit/dialog.rb +257 -83
  35. data/app/components/nitro_kit/dropdown.rb +336 -119
  36. data/app/components/nitro_kit/dropzone.rb +326 -0
  37. data/app/components/nitro_kit/empty_state.rb +99 -0
  38. data/app/components/nitro_kit/field.rb +461 -236
  39. data/app/components/nitro_kit/field_group.rb +15 -8
  40. data/app/components/nitro_kit/fieldset.rb +37 -39
  41. data/app/components/nitro_kit/flex.rb +49 -0
  42. data/app/components/nitro_kit/form_builder.rb +313 -72
  43. data/app/components/nitro_kit/form_section.rb +79 -0
  44. data/app/components/nitro_kit/grid.rb +34 -0
  45. data/app/components/nitro_kit/icon.rb +54 -25
  46. data/app/components/nitro_kit/input.rb +97 -10
  47. data/app/components/nitro_kit/label.rb +22 -6
  48. data/app/components/nitro_kit/layout_options.rb +7 -0
  49. data/app/components/nitro_kit/page_header.rb +76 -0
  50. data/app/components/nitro_kit/pagination.rb +355 -69
  51. data/app/components/nitro_kit/pagination_bar.rb +90 -0
  52. data/app/components/nitro_kit/progressive_image.rb +181 -0
  53. data/app/components/nitro_kit/radio_button.rb +77 -55
  54. data/app/components/nitro_kit/radio_button_group.rb +104 -36
  55. data/app/components/nitro_kit/responsive_value.rb +94 -0
  56. data/app/components/nitro_kit/rich_text_area.rb +31 -0
  57. data/app/components/nitro_kit/select.rb +129 -64
  58. data/app/components/nitro_kit/settings_layout.rb +152 -0
  59. data/app/components/nitro_kit/sheet.rb +202 -0
  60. data/app/components/nitro_kit/stat_grid.rb +75 -0
  61. data/app/components/nitro_kit/switch.rb +108 -51
  62. data/app/components/nitro_kit/table.rb +237 -45
  63. data/app/components/nitro_kit/tabs.rb +168 -63
  64. data/app/components/nitro_kit/textarea.rb +81 -10
  65. data/app/components/nitro_kit/toast.rb +211 -80
  66. data/app/components/nitro_kit/toolbar.rb +75 -0
  67. data/app/components/nitro_kit/tooltip.rb +235 -34
  68. data/app/components/nitro_kit/typeset.rb +28 -0
  69. data/app/javascript/controllers/nk/app_shell_controller.js +224 -0
  70. data/app/javascript/controllers/nk/appearance_controller.js +73 -0
  71. data/app/javascript/controllers/nk/avatar_controller.js +15 -0
  72. data/app/javascript/controllers/nk/button_controller.js +56 -0
  73. data/app/javascript/controllers/nk/checkable_controller.js +41 -0
  74. data/app/javascript/controllers/nk/combobox_controller.js +314 -82
  75. data/app/javascript/controllers/nk/command_palette_controller.js +249 -0
  76. data/app/javascript/controllers/nk/dialog_controller.js +14 -10
  77. data/app/javascript/controllers/nk/dropdown_controller.js +106 -58
  78. data/app/javascript/controllers/nk/dropzone/direct_upload.js +61 -0
  79. data/app/javascript/controllers/nk/dropzone/file_rules.js +77 -0
  80. data/app/javascript/controllers/nk/dropzone/form_submit_lock.js +30 -0
  81. data/app/javascript/controllers/nk/dropzone_controller.js +482 -0
  82. data/app/javascript/controllers/nk/overlay_position.js +37 -0
  83. data/app/javascript/controllers/nk/progressive_image_controller.js +116 -0
  84. data/app/javascript/controllers/nk/tabs_controller.js +135 -23
  85. data/app/javascript/controllers/nk/toast_controller.js +112 -45
  86. data/app/javascript/controllers/nk/tooltip_controller.js +12 -47
  87. data/config/importmap.rb +2 -0
  88. data/config/locales/en.yml +98 -0
  89. data/docs/agent_guide.md +139 -0
  90. data/docs/agent_native_spec.md +422 -0
  91. data/docs/component_contracts.md +263 -0
  92. data/docs/customization.md +595 -0
  93. data/docs/hotwire.md +94 -0
  94. data/docs/implementation_plan.md +279 -0
  95. data/docs/initialization_prompt.md +36 -0
  96. data/docs/migration_1_to_2.md +318 -0
  97. data/docs/new_app_strategy.md +24 -0
  98. data/docs/patterns/application_foundation.md +136 -0
  99. data/docs/patterns/crud_resource.md +144 -0
  100. data/docs/patterns/destructive_action.md +105 -0
  101. data/docs/patterns/flash_and_toast.md +57 -0
  102. data/docs/patterns/inline_edit.md +59 -0
  103. data/docs/patterns/queryable_collection.md +187 -0
  104. data/docs/patterns/resource_form.md +126 -0
  105. data/docs/rails_conventions.md +95 -0
  106. data/docs/rails_integration.md +514 -0
  107. data/lib/generators/nitro_kit/install_generator.rb +48 -0
  108. data/lib/generators/nitro_kit/upgrade_smoke_tests_generator.rb +67 -0
  109. data/lib/nitro_kit/engine.rb +20 -0
  110. data/lib/nitro_kit/installation.rb +671 -0
  111. data/lib/nitro_kit/migration_inventory.rb +345 -0
  112. data/lib/nitro_kit/upgrade_smoke_test.rb +403 -0
  113. data/lib/nitro_kit/version.rb +1 -1
  114. data/lib/nitro_kit.rb +5 -42
  115. data/lib/rails/commands/nitro_kit/nitro_kit_command.rb +42 -0
  116. data/lib/tasks/nitro_kit_tasks.rake +79 -4
  117. data/plugins/nitro-kit/.codex-plugin/plugin.json +28 -0
  118. data/plugins/nitro-kit/skills/nitro-kit-hotwire/SKILL.md +67 -0
  119. data/plugins/nitro-kit/skills/nitro-kit-hotwire/agents/openai.yaml +4 -0
  120. data/plugins/nitro-kit/skills/nitro-kit-rails/SKILL.md +60 -0
  121. data/plugins/nitro-kit/skills/nitro-kit-rails/agents/openai.yaml +4 -0
  122. data/plugins/nitro-kit/skills/nitro-kit-ui/SKILL.md +62 -0
  123. data/plugins/nitro-kit/skills/nitro-kit-ui/agents/openai.yaml +4 -0
  124. data/src/stylesheets/nitro_kit/components/accordion.css +119 -0
  125. data/src/stylesheets/nitro_kit/components/alert.css +82 -0
  126. data/src/stylesheets/nitro_kit/components/app_navigation.css +156 -0
  127. data/src/stylesheets/nitro_kit/components/app_shell.css +605 -0
  128. data/src/stylesheets/nitro_kit/components/appearance_picker.css +117 -0
  129. data/src/stylesheets/nitro_kit/components/auth_shell.css +8 -0
  130. data/src/stylesheets/nitro_kit/components/avatar.css +81 -0
  131. data/src/stylesheets/nitro_kit/components/avatar_stack.css +80 -0
  132. data/src/stylesheets/nitro_kit/components/badge.css +76 -0
  133. data/src/stylesheets/nitro_kit/components/button.css +283 -0
  134. data/src/stylesheets/nitro_kit/components/button_group.css +53 -0
  135. data/src/stylesheets/nitro_kit/components/button_to.css +6 -0
  136. data/src/stylesheets/nitro_kit/components/card.css +70 -0
  137. data/src/stylesheets/nitro_kit/components/checkbox.css +160 -0
  138. data/src/stylesheets/nitro_kit/components/checkbox_group.css +61 -0
  139. data/src/stylesheets/nitro_kit/components/combobox.css +148 -0
  140. data/src/stylesheets/nitro_kit/components/command_palette.css +255 -0
  141. data/src/stylesheets/nitro_kit/components/container.css +25 -0
  142. data/src/stylesheets/nitro_kit/components/control_group.css +149 -0
  143. data/src/stylesheets/nitro_kit/components/danger_zone.css +54 -0
  144. data/src/stylesheets/nitro_kit/components/data_section.css +40 -0
  145. data/src/stylesheets/nitro_kit/components/details_table.css +53 -0
  146. data/src/stylesheets/nitro_kit/components/dialog.css +80 -0
  147. data/src/stylesheets/nitro_kit/components/dropdown.css +152 -0
  148. data/src/stylesheets/nitro_kit/components/dropzone.css +189 -0
  149. data/src/stylesheets/nitro_kit/components/empty_state.css +53 -0
  150. data/src/stylesheets/nitro_kit/components/field.css +79 -0
  151. data/src/stylesheets/nitro_kit/components/field_group.css +6 -0
  152. data/src/stylesheets/nitro_kit/components/fieldset.css +28 -0
  153. data/src/stylesheets/nitro_kit/components/flex.css +455 -0
  154. data/src/stylesheets/nitro_kit/components/form_section.css +71 -0
  155. data/src/stylesheets/nitro_kit/components/grid.css +308 -0
  156. data/src/stylesheets/nitro_kit/components/icon.css +26 -0
  157. data/src/stylesheets/nitro_kit/components/input.css +80 -0
  158. data/src/stylesheets/nitro_kit/components/label.css +9 -0
  159. data/src/stylesheets/nitro_kit/components/layout.css +440 -0
  160. data/src/stylesheets/nitro_kit/components/page_header.css +62 -0
  161. data/src/stylesheets/nitro_kit/components/pagination.css +119 -0
  162. data/src/stylesheets/nitro_kit/components/pagination_bar.css +41 -0
  163. data/src/stylesheets/nitro_kit/components/palette.css +113 -0
  164. data/src/stylesheets/nitro_kit/components/progressive_image.css +139 -0
  165. data/src/stylesheets/nitro_kit/components/radio_button.css +127 -0
  166. data/src/stylesheets/nitro_kit/components/radio_button_group.css +143 -0
  167. data/src/stylesheets/nitro_kit/components/rich_text_area.css +21 -0
  168. data/src/stylesheets/nitro_kit/components/select.css +70 -0
  169. data/src/stylesheets/nitro_kit/components/settings_layout.css +100 -0
  170. data/src/stylesheets/nitro_kit/components/sheet.css +100 -0
  171. data/src/stylesheets/nitro_kit/components/stat_grid.css +51 -0
  172. data/src/stylesheets/nitro_kit/components/switch.css +152 -0
  173. data/src/stylesheets/nitro_kit/components/table.css +110 -0
  174. data/src/stylesheets/nitro_kit/components/tabs.css +138 -0
  175. data/src/stylesheets/nitro_kit/components/textarea.css +39 -0
  176. data/src/stylesheets/nitro_kit/components/toast.css +131 -0
  177. data/src/stylesheets/nitro_kit/components/toolbar.css +78 -0
  178. data/src/stylesheets/nitro_kit/components/tooltip.css +124 -0
  179. data/src/stylesheets/nitro_kit/components/typeset.css +191 -0
  180. data/src/stylesheets/nitro_kit/layers.css +7 -0
  181. data/src/stylesheets/nitro_kit/reset.css +192 -0
  182. data/src/stylesheets/nitro_kit/tokens.css +198 -0
  183. metadata +183 -50
  184. data/Rakefile +0 -8
  185. data/app/components/nitro_kit/datepicker.rb +0 -9
  186. data/app/helpers/nitro_kit/accordion_helper.rb +0 -9
  187. data/app/helpers/nitro_kit/alert_helper.rb +0 -11
  188. data/app/helpers/nitro_kit/avatar_helper.rb +0 -13
  189. data/app/helpers/nitro_kit/badge_helper.rb +0 -13
  190. data/app/helpers/nitro_kit/button_group_helper.rb +0 -9
  191. data/app/helpers/nitro_kit/button_helper.rb +0 -49
  192. data/app/helpers/nitro_kit/card_helper.rb +0 -9
  193. data/app/helpers/nitro_kit/checkbox_helper.rb +0 -50
  194. data/app/helpers/nitro_kit/combobox_helper.rb +0 -9
  195. data/app/helpers/nitro_kit/datepicker_helper.rb +0 -9
  196. data/app/helpers/nitro_kit/dialog_helper.rb +0 -9
  197. data/app/helpers/nitro_kit/dropdown_helper.rb +0 -9
  198. data/app/helpers/nitro_kit/field_group_helper.rb +0 -9
  199. data/app/helpers/nitro_kit/field_helper.rb +0 -9
  200. data/app/helpers/nitro_kit/fieldset_helper.rb +0 -9
  201. data/app/helpers/nitro_kit/form_helper.rb +0 -13
  202. data/app/helpers/nitro_kit/icon_helper.rb +0 -9
  203. data/app/helpers/nitro_kit/input_helper.rb +0 -37
  204. data/app/helpers/nitro_kit/label_helper.rb +0 -19
  205. data/app/helpers/nitro_kit/pagination_helper.rb +0 -42
  206. data/app/helpers/nitro_kit/radio_button_helper.rb +0 -23
  207. data/app/helpers/nitro_kit/select_helper.rb +0 -24
  208. data/app/helpers/nitro_kit/switch_helper.rb +0 -9
  209. data/app/helpers/nitro_kit/table_helper.rb +0 -9
  210. data/app/helpers/nitro_kit/tabs_helper.rb +0 -9
  211. data/app/helpers/nitro_kit/textarea_helper.rb +0 -9
  212. data/app/helpers/nitro_kit/toast_helper.rb +0 -25
  213. data/app/helpers/nitro_kit/tooltip_helper.rb +0 -9
  214. data/app/javascript/controllers/nk/accordion_controller.js +0 -18
  215. data/app/javascript/controllers/nk/datepicker_controller.js +0 -5
  216. data/app/javascript/controllers/nk/switch_controller.js +0 -32
  217. data/lib/generators/nitro_kit/component_generator.rb +0 -84
  218. data/lib/nitro_kit/schema_builder.rb +0 -121
  219. data/lib/nitro_kit/variants.rb +0 -21
@@ -0,0 +1,279 @@
1
+ # Nitro Kit 2.0 implementation record
2
+
3
+ This document records the staged delivery program used for the agent-native pivot. `tk` is the source of truth for live status and dependency order; ticket IDs below connect durable design intent to executable work. Candidate lists in early stages are historical investigation prompts, not current public API. The settled contract lives in [`agent_native_spec.md`](agent_native_spec.md) and [`component_contracts.md`](component_contracts.md).
4
+
5
+ Nitro Kit 2.0 is allowed to break 1.x completely. Each stage should leave one simpler system behind rather than maintaining parallel APIs.
6
+
7
+ The original implementation program reached release-quality consolidation. Component migration, evidence-gathering flows, accepted layout/block extraction, the expanded gallery, 1.x removal, documentation, packaging, and browser verification are retained here as history; later contract revisions such as responsive Flex/Grid remain tracked in `tk` and the canonical contract documents.
8
+
9
+ ## Definition of done
10
+
11
+ The 2.0 pivot is complete when:
12
+
13
+ - Every component is constructed directly from Phlex with explicit Ruby options.
14
+ - Nitro Kit owns the Ruby, markup contract, behavior, CSS, examples, and documentation.
15
+ - No Nitro-authored component, layout, block, flow, or gallery subject emits `class`, `style`, or an escape marker.
16
+ - Applications can theme the system through documented `--nk-*` variables and compose or subclass components.
17
+ - Rails forms, routes, assets, Turbo Frames, and Turbo Streams remain first-class.
18
+ - The gem does not expose `nk_*` view helpers, copied-component generators, a Tailwind runtime, or a template-buffer bridge.
19
+ - The complete catalog renders through explicit Rails routes in light/dark and narrow/wide states.
20
+ - Keyboard behavior and Turbo lifecycle behavior pass browser tests.
21
+ - The full Ruby, CSS, JavaScript formatting, package, and browser checks pass from a clean checkout.
22
+
23
+ ## Delivery rules
24
+
25
+ Every migration ticket follows the same sequence:
26
+
27
+ 1. Define the smallest explicit Ruby API and closed vocabularies.
28
+ 2. Render native, self-describing HTML with `data-nk` and qualified `data-slot` identities.
29
+ 3. Preserve Rails and accessibility semantics before visual styling.
30
+ 4. Add static zero-specificity CSS driven by public theme tokens and private mechanics variables.
31
+ 5. Add focused render, invalid-option, reserved-attribute, and integration tests.
32
+ 6. Add representative and exhaustive gallery examples without classes or escape hatches.
33
+ 7. Verify the family independently before allowing dependent flows to use it.
34
+
35
+ No compatibility layer should survive merely to keep a legacy example green. Replace the example and delete the obsolete API.
36
+
37
+ ## Stage 0 — ownership and execution scaffold
38
+
39
+ Tickets: `nk-rzxf`, `nk-g3qu`
40
+
41
+ - Work on the dedicated `2.0-agent-native` branch.
42
+ - Keep the agent-native specification, component contracts, repository guidance, and this plan tracked with the gem.
43
+ - Track the entire program in the workspace-level `.tickets` database.
44
+ - Record implementation decisions and verification counts on each ticket before closing it.
45
+
46
+ Gate: an agent can explain who owns Ruby, markup, CSS, behavior, theming, composition, and the class escape hatch by reading the tracked docs.
47
+
48
+ ## Stage 1 — kernel and distribution foundation
49
+
50
+ Tickets: `nk-6q5i`, `nk-fooc`, `nk-rx0j`
51
+
52
+ - Replace permissive attributes with explicit component options plus `html:`, `aria:`, and `data:` boundaries.
53
+ - Centralize identity, slot attachment, reserved attributes, validation, additive Stimulus data, and `desperately_need_a_class:`.
54
+ - Build deterministic layered CSS from split plain-CSS sources.
55
+ - Ship the built stylesheet, optional Tailwind adapter, importmap pins, and controllers from the gem without vendored third-party JavaScript.
56
+ - Prove the engine still boots when importmap-rails is absent.
57
+
58
+ Gate: a minimal Rails app can render and style a Nitro component without copying sources or configuring Tailwind or JavaScript pins.
59
+
60
+ ## Stage 2 — representative vertical slice
61
+
62
+ Ticket: `nk-g3x1`
63
+
64
+ Migrate Button/Icon, Card, Input/Field/FormBuilder, Table, and Dialog all the way through Ruby, HTML, CSS, behavior, Rails integration, tests, and gallery routes.
65
+
66
+ Use this slice to settle:
67
+
68
+ - Direct compound-component methods and nested slot ownership.
69
+ - Native attribute boundaries and error messages.
70
+ - Intrinsic versus stretch sizing.
71
+ - Rails form names, IDs, values, errors, multipart behavior, and checkbox semantics.
72
+ - Native dialog behavior, stable ARIA relationships, and Stimulus cleanup.
73
+ - The explicit gallery catalog and route contract.
74
+
75
+ Gate: the slice is classless, invalid options fail immediately, focused tests pass, and its examples render through real Rails routes with Nitro CSS alone.
76
+
77
+ ## Stage 3 — complete atom migration
78
+
79
+ Tickets: `nk-t17c`, `nk-b18t`, `nk-7lkw`, `nk-4r36`, `nk-i4xu`, `nk-19gd`
80
+
81
+ ### Display
82
+
83
+ Migrate Alert, Avatar, AvatarStack, Badge, and Icon. Cover semantic intents, long content, image/fallback behavior, overflow, sizes, labeled/decorative icons, and nested combinations.
84
+
85
+ ### Actions and navigation
86
+
87
+ Migrate ButtonGroup and Pagination. Preserve native links/buttons, current-page semantics, disabled previous/next controls, ellipses, compact ranges, and stable labels.
88
+
89
+ ### Forms
90
+
91
+ Migrate Label, Textarea, Select, Checkbox, CheckboxGroup, RadioButton, RadioButtonGroup, Switch, FieldGroup, Fieldset, and all FormBuilder methods. Cover:
92
+
93
+ - Bound and unbound forms.
94
+ - Required, disabled, readonly, checked, indeterminate, invalid, prompt, and empty states.
95
+ - Array and nested parameter names.
96
+ - Active Model values and errors.
97
+ - Multipart uploads and native file-input constraints.
98
+ - Accessible descriptions, legends, labels, and error relationships.
99
+
100
+ ### Structured content
101
+
102
+ Migrate Accordion and Tabs alongside the Card and Table slice. Require deterministic IDs and keys, direct compound APIs, semantic table structure, and keyboard-visible state.
103
+
104
+ ### Interaction
105
+
106
+ Migrate Dropdown, Tooltip, Combobox, and Toast alongside Dialog. Require closed placement/state APIs, visible ARIA/data state, keyboard behavior, native controls where possible, and complete disconnect cleanup.
107
+
108
+ Gate: every shipped atom has a classless direct-Phlex API, static CSS, focused tests, exhaustive examples, and no dependency on a legacy helper.
109
+
110
+ ## Stage 4 — Rails and Hotwire proof
111
+
112
+ Ticket: `nk-19gd`
113
+
114
+ - Exercise `form_with` directly from Phlex using `NitroKit::FormBuilder`.
115
+ - Prove route helpers, DOM ID helpers, CSRF behavior, model errors, submit paths, and multipart forms.
116
+ - Render Turbo Frames and Turbo Streams from direct-Phlex pages.
117
+ - Add one small validation submit path that demonstrates the real request/response loop.
118
+ - Document the supported Rails boundary and show examples without introducing Nitro view helpers.
119
+
120
+ Gate: Rails supplies framework semantics while Phlex remains the only general UI composition language.
121
+
122
+ ## Stage 5 — gallery infrastructure and exhaustive combinations
123
+
124
+ Tickets: `nk-q4mj`, `nk-put2`, `nk-jp63`, `nk-5028`, `nk-t23x`, `nk-rtwj`, `nk-8mh8`, `nk-t66i`, `nk-vnwu`
125
+
126
+ - Keep one explicit catalog of component, block, and flow entries.
127
+ - Render the shell, pages, sections, examples, samples, and notes in Phlex.
128
+ - Pair every preview with highlighted, copyable Ruby extracted from the exact rendering block or concrete flow method.
129
+ - Generate route contract tests from the catalog.
130
+ - Assert every subject has stable Nitro identities and no `class`, `style`, or escape markers.
131
+ - Add meaningful Cartesian coverage without mechanically showing nonsense combinations.
132
+
133
+ Required pressure cases:
134
+
135
+ - All closed variants and sizes.
136
+ - Default, hover/focus-capable, disabled, readonly, invalid, empty, loading-like, open, and selected states where meaningful.
137
+ - Short, long, wrapped, numeric, missing-image, and high-item-count content.
138
+ - Nested atoms and compound slots.
139
+ - Light and dark themes.
140
+ - Narrow and wide viewports.
141
+ - Forms, tables, overlays, and navigation used together rather than only in isolation.
142
+
143
+ Gate: every catalog entry succeeds through an explicit route and the gallery itself requires no Tailwind or ERB templates.
144
+
145
+ ## Stage 6 — atom-only product flows
146
+
147
+ Tickets: `nk-31ne`, `nk-7d05`, `nk-q37g`, `nk-tcig`, `nk-32vc`
148
+
149
+ Build realistic screens before inventing layout abstractions:
150
+
151
+ - Authentication, registration, password reset, and verification.
152
+ - Onboarding progress, validation, resume, and completion.
153
+ - Dashboard overview, statistics, recent records, and activity.
154
+ - Profile, preferences, account, and destructive settings.
155
+ - Billing plans, payment methods, invoices, and upgrade states.
156
+ - Users search, filters, pagination, empty state, and detail.
157
+ - Team members, invitations, roles, and removal confirmation.
158
+ - API credential empty, create, reveal-once, list, and revoke states.
159
+
160
+ Use deterministic PORO data and explicit state slugs. Record repeated layout and responsibility friction in `notes/block_candidates.md`; do not abstract a one-off screen.
161
+
162
+ Gate: all required product states exist using atoms and plain Phlex composition, and repeated structures are backed by concrete evidence.
163
+
164
+ ## Stage 7 — evidence-driven layouts and blocks
165
+
166
+ Tickets: `nk-okls`, `nk-bjv5`, `nk-b8eg`
167
+
168
+ Extract the smallest vocabulary that removes proven repetition. The evidence pass accepted:
169
+
170
+ - Layouts: VStack, HStack, the three-column Grid, and Container.
171
+ - Shell: AuthShell.
172
+ - Sections and blocks: SettingsLayout, Toolbar, PaginationBar, PageHeader, StatGrid, DataSection, FormSection, DangerZone, and EmptyState.
173
+
174
+ This list records the first extraction decision. It has since been superseded: `VStack` and `HStack` were removed in favor of unified responsive `Flex`, and the fixed three-column Grid became a responsive 1–12-column `Grid`. See the canonical specification and component contracts for the current API.
175
+
176
+ At that stage, the evidence pass deferred Spacer, Split, Frame, AppShell, MarketingShell, AuthenticationPanel, and ProgressSteps because their responsibilities were not stable across enough domains. A later application-layout mandate supplied enough evidence to accept AppShell; the other deferred candidates remain outside 2.0. The settled contracts, rather than this historical stage record, live in [`agent_native_spec.md`](agent_native_spec.md) and [`component_contracts.md`](component_contracts.md).
177
+
178
+ Each abstraction must:
179
+
180
+ - Have one clear responsibility.
181
+ - Use closed layout options.
182
+ - Own only structure that actually repeats.
183
+ - Accept atoms/content through direct Ruby composition.
184
+ - Emit classless self-describing markup.
185
+ - Include examples showing reuse in at least two flows.
186
+
187
+ Then rewrite the atom-only flows with blocks and compare the result. Delete abstractions that do not make application code meaningfully clearer.
188
+
189
+ Gate: flow code describes product intent, while layouts and blocks remain a small coherent vocabulary rather than a second page framework.
190
+
191
+ ## Stage 8 — expanded application gallery
192
+
193
+ Tickets: `nk-pmcn`, `nk-q1tc`, `nk-oi4y`, `nk-gn4s`, `nk-ky42`
194
+
195
+ Extend the block-based gallery across:
196
+
197
+ - Data detail, activity, audit, uploads, and integrations.
198
+ - Billing, authentication, onboarding, team, and API states.
199
+ - System error, permission, empty, loading-like, and marketing states.
200
+ - Changelog, support, and help experiences.
201
+
202
+ Prefer depth of state over disconnected decorative pages. Each flow should show success, empty/error, destructive/confirmation, and constrained-width behavior where applicable.
203
+
204
+ Gate: the gallery demonstrates that the vocabulary can build a credible Rails product, not only isolated controls.
205
+
206
+ ## Stage 9 — remove the old system
207
+
208
+ Ticket: `nk-u534`
209
+
210
+ - Delete all `nk_*` view helpers and automatic variant aliases.
211
+ - Delete copied-component generators, schemas, manifests, and installation paths.
212
+ - Delete the Action View/template capture bridge and legacy builder path.
213
+ - Remove Tailwind Merge and consumer Tailwind dependencies.
214
+ - Remove legacy ERB test pages, Tailwind assets, and obsolete tests.
215
+ - Audit packaged gem files and runtime dependencies.
216
+
217
+ Gate: repository-wide searches find no public legacy invocation, copied-source promise, internal component class string, or required Tailwind runtime.
218
+
219
+ ## Stage 10 — browser behavior and lifecycle verification
220
+
221
+ Tickets: `nk-352j`, `nk-6ivz`, `nk-gxwn`, `nk-lij5`, `nk-tkds`
222
+
223
+ - Enumerate every catalog URL and state in a real browser.
224
+ - Exercise keyboard order, arrows, Escape, Enter/Space, tab trapping/return, and focus visibility.
225
+ - Exercise open/close, select, filter, validation, submit, and destructive confirmation paths.
226
+ - Navigate through Turbo Drive, Frames, Streams, and morph refreshes; look for duplicate controllers and leaked listeners/positioners/timers.
227
+ - Review representative pages at narrow/wide sizes and light/dark themes.
228
+ - Check for horizontal overflow, clipped overlays, unstable layout, unreadable content, and broken focus state.
229
+
230
+ Gate: browser coverage proves both route completeness and interaction lifecycle behavior.
231
+
232
+ ## Stage 11 — release-quality consolidation
233
+
234
+ Tickets: `nk-g3qu`, `nk-obb7`
235
+
236
+ - Reconcile actual component APIs with `docs/component_contracts.md` and `STYLE_GUIDE.md`.
237
+ - Document Rails integration, theming tokens, composition, subclass caveats, and the escape hatch.
238
+ - Run a data-structure review for duplicated collections, scattered state, and invalid intermediate states.
239
+ - Run a simplification pass and remove compatibility branches, duplicate validation, dead CSS, dead JavaScript, and unused dependencies.
240
+ - Audit all CSS selectors for zero specificity and owner scoping.
241
+ - Audit all controllers for disconnect cleanup and Turbo safety.
242
+ - Run the complete test, lint, format, CSS build/check, package, route, and browser suites.
243
+
244
+ Gate: every child of `nk-rzxf` is closed with evidence and the repository contains one coherent 2.0 architecture.
245
+
246
+ ## Stage 12 — deterministic agent installation
247
+
248
+ Ticket: `2an-5ayl`
249
+
250
+ - Ship concise Nitro Kit Rails, Hotwire, and UI skills that resolve the
251
+ installed gem before acting.
252
+ - Add a setup-only generator that installs the skills for Codex and Claude and
253
+ maintains a bounded `AGENTS.md` section without copying component source.
254
+ - Add diagnostics for the resolved version, agent guidance, Hotwire wiring,
255
+ Phlex Kit inclusion, stylesheet loading, and Nitro Kit 1.x shadows.
256
+ - Print or copy an initialization prompt without launching an agent.
257
+ - Make guided and Pro eval profiles run the real installer and name Nitro Kit
258
+ 2.x explicitly; retain cold profiles for diagnostic comparisons.
259
+
260
+ Gate: installation is idempotent, preserves application-owned instructions,
261
+ routes agents to version-matched doctrine, and is exercised by the eval
262
+ harness.
263
+
264
+ ## Verification matrix
265
+
266
+ | Surface | Required verification |
267
+ | ------------- | ------------------------------------------------------------------------------------------------- |
268
+ | Ruby API | Focused construction/render tests; invalid vocabulary; missing content; reserved attributes |
269
+ | Markup | Native semantics; stable IDs; ARIA relationships; `data-nk`; qualified `data-slot`; visible state |
270
+ | CSS | Deterministic build/check; zero-specificity owner-scoped selectors; token audit; light/dark |
271
+ | Rails | Real `form_with`; Active Model; routes/DOM IDs; multipart; validation submit; Frame/Stream |
272
+ | JavaScript | Keyboard behavior; open/close/select; disconnect cleanup; Turbo navigation and morph |
273
+ | Gallery | Catalog routes; exact escaped source; copy behavior; no class/style/escape; narrow/wide |
274
+ | Packaging | Engine boot with optional integrations absent; gem contents and dependencies audited |
275
+ | Documentation | Specification, contracts, style guide, Rails boundary, theming, examples, repository commands |
276
+
277
+ ## Execution and handoff
278
+
279
+ Use `tk ready` to select dependency-safe work. Preparatory parallel work is permitted only when the orchestrator explicitly assigns non-overlapping ownership. Every handoff names changed files, behavior decisions, focused test counts, and known failures. The orchestrator independently reviews and reproduces meaningful checks before closing a feature ticket.
@@ -0,0 +1,36 @@
1
+ # Initialize Nitro Kit 2 in this Rails application
2
+
3
+ Finish the application-specific Nitro Kit 2 setup. Do not use Nitro Kit 1.x
4
+ APIs or examples.
5
+
6
+ 1. Run `bundle show nitro_kit` and confirm the resolved version begins with
7
+ `2.`.
8
+ 2. Read `docs/agent_guide.md` from that installed gem, then read the locally
9
+ installed `nitro-kit-rails`, `nitro-kit-hotwire`, and `nitro-kit-ui` skills.
10
+ 3. Inspect the application before editing. Preserve established application
11
+ conventions unless they conflict with the requested Nitro Kit 2 setup.
12
+ 4. Ensure an application base Phlex component includes `NitroKit` once and
13
+ product components inherit from it.
14
+ 5. Re-run `bin/rails generate nitro_kit:install`. Ensure its application layout
15
+ setup has one appearance bootstrap before every stylesheet, then optional
16
+ third-party base styles, the optional Tailwind adapter, `nitro_kit`, compiled
17
+ Tailwind, and application token overrides in that order. Add flash toast
18
+ rendering when the application uses it.
19
+ 6. Ensure Turbo and Stimulus are wired and the normal Stimulus loader can
20
+ discover the gem-owned `nk--*` controllers. Never copy Nitro components,
21
+ helpers, or controllers into the application.
22
+ 7. Remove confirmed Nitro Kit 1.x shadows such as application-owned
23
+ `NitroKit` components, `nk_*` helpers, or `controllers/nk` only when this
24
+ task is authorized to migrate the application.
25
+ 8. Use ordinary Rails routes, models, forms, and server-rendered HTML. Follow
26
+ the installed Rails and Hotwire guidance for new work. During a migration,
27
+ replace an existing control only when Nitro Kit 2 has a genuine semantic
28
+ and behavioral equivalent. Otherwise preserve it as application-owned
29
+ Rails and semantic HTML; never downgrade specialized behavior or retain
30
+ copied Nitro Kit 1.x source as the fallback.
31
+ 9. Run `bin/rails nitro_kit:doctor`, fix actionable failures, and run the
32
+ application's relevant tests.
33
+
34
+ Report what you changed, any existing convention you deliberately preserved,
35
+ any unsupported control recorded as a Nitro Kit coverage gap, and any warning
36
+ that still needs a product decision.
@@ -0,0 +1,318 @@
1
+ # Migrating a Nitro Kit 1.x application
2
+
3
+ Treat a 1.x migration as a product-flow review, not a helper rename. Nitro Kit
4
+ 2 deliberately removed copied components, `nk_*` helpers, application-owned
5
+ `controllers/nk`, and unrestricted utility-class customization.
6
+
7
+ ## Install the 2.0 alpha before migrating
8
+
9
+ Add the 2.0 alpha prerelease to the application's Gemfile:
10
+
11
+ ```ruby
12
+ gem "nitro_kit", "2.0.0.alpha.1"
13
+ ```
14
+
15
+ Bundler records the exact released version in `Gemfile.lock`; commit `Gemfile`
16
+ and `Gemfile.lock` together. Before upgrading during the migration, review the
17
+ changelog, run `bundle update nitro_kit`, rerun the installer and doctor, and
18
+ exercise the converted flows before committing the updated lockfile.
19
+ Production applications should use the released gem and a committed lockfile
20
+ rather than a moving Git branch.
21
+
22
+ ## Inventory behavior before editing
23
+
24
+ 1. List every `nk_*` helper, `NitroKit::*` component, copied Nitro source file,
25
+ and `controllers/nk` controller.
26
+ 2. Group usage by user flow: authentication, settings, collection browsing,
27
+ mobile navigation, editing, destructive actions, notifications, and
28
+ copy/share controls.
29
+ 3. Record behavior that must survive: native element, submitted method and
30
+ parameters, Turbo target, accessible name and description, focus behavior,
31
+ narrow-screen presentation, empty/error state, and visual density.
32
+ 4. Capture representative wide and narrow screenshots before conversion.
33
+
34
+ If the Nitro Kit MCP catalog is connected, search it by workflow after this
35
+ inventory — for example `mobile transcript navigation`, `settings form`, or
36
+ `empty query results`. Do not search only for an old component name. MCP can
37
+ deliver complete compositions; the installed gem remains the authority for
38
+ the free component contract.
39
+
40
+ ## Select semantics before atoms
41
+
42
+ Map each flow to the highest-level matching 2.x component first:
43
+
44
+ | Existing need | Begin with |
45
+ | --------------------------------------- | --------------------------------------- |
46
+ | Sign-in or recovery card | `AuthShell` |
47
+ | Application navigation | `AppShell`, `AppNavigation` |
48
+ | Mobile contextual navigation or details | `Sheet` |
49
+ | Settings screen | `SettingsLayout`, `FormSection` |
50
+ | Empty collection card | `EmptyState` |
51
+ | Data collection | `DataSection`, `Table`, `PaginationBar` |
52
+ | Destructive settings | `DangerZone`, `Dialog`, `ButtonTo` |
53
+ | Joined copy or filter controls | `ControlGroup` |
54
+
55
+ Only then replace remaining atoms. Common direct mappings include:
56
+
57
+ - `nk_button_link_to` → `NitroKit::Button.new(..., href:)`
58
+ - `nk_button_to` → `NitroKit::ButtonTo.new(..., href:, method:)`
59
+ - `nk_form_with` → Rails `form_with(..., builder: NitroKit::FormBuilder)`
60
+ - block-wrapped tooltips → a linked Button trigger or Tooltip `as: :custom`
61
+ - copied mobile Sidebar → `Sheet`, not a plain disclosure
62
+
63
+ Do not preserve a Card merely because 1.x used one. Empty states,
64
+ authentication shells, settings regions, and data sections have stronger
65
+ semantics and more useful responsive behavior.
66
+
67
+ ## Move ERB collections and yielded content into compound declarations
68
+
69
+ The ERB below is representative application-owned migration input, not a
70
+ Nitro Kit 2 API. Nitro Kit 2 has no ERB component bridge. Move the collection
71
+ to the Phlex component, then declare entries only inside their owning compound
72
+ region. Content formerly yielded by a partial belongs directly inside the
73
+ matching `panel` or `content` block.
74
+
75
+ ### AppNavigation
76
+
77
+ ERB source — the call site owns the destination collection and the partial
78
+ iterates it:
79
+
80
+ ```erb
81
+ <% destinations = [["Home", root_path], ["Projects", projects_path]] %>
82
+ <%= render "app_navigation", label: "Primary", destinations: destinations %>
83
+
84
+ <%# _app_navigation.html.erb %>
85
+ <nav aria-label="<%= label %>">
86
+ <ul>
87
+ <% destinations.each do |text, href| %>
88
+ <li><%= link_to text, href %></li>
89
+ <% end %>
90
+ </ul>
91
+ </nav>
92
+ ```
93
+
94
+ Phlex destination — declare the collection before `AppNavigation`; consume it
95
+ inside the required `body` collection region:
96
+
97
+ ```ruby
98
+ destinations = [["Home", root_path], ["Projects", projects_path]]
99
+
100
+ render NitroKit::AppNavigation.new(label: "Primary") do |navigation|
101
+ navigation.body do
102
+ destinations.each_with_index do |(text, href), index|
103
+ navigation.item(text, href:, current: index.zero?)
104
+ end
105
+ end
106
+ end
107
+ ```
108
+
109
+ The executable minimal version is on the
110
+ [`AppNavigation` gallery page](/gallery/components/app-navigation#example-app-navigation-minimal).
111
+
112
+ ### Dialog
113
+
114
+ ERB source — the call-site block is yielded inside the partial's panel:
115
+
116
+ ```erb
117
+ <%= render "dialog", id: "transcript-details", title: "Transcript details" do %>
118
+ <p>The transcript was recorded at 09:42 UTC.</p>
119
+ <% end %>
120
+
121
+ <%# _dialog.html.erb %>
122
+ <button command="show-modal" commandfor="<%= id %>-panel">Details</button>
123
+ <dialog id="<%= id %>-panel">
124
+ <h2><%= title %></h2>
125
+ <%= yield %>
126
+ </dialog>
127
+ ```
128
+
129
+ Phlex destination — trigger and panel declarations live inside `Dialog`; the
130
+ former yielded content lives inside `panel`:
131
+
132
+ ```ruby
133
+ render NitroKit::Dialog.new(id: "transcript-details") do |dialog|
134
+ dialog.trigger("Details")
135
+ dialog.panel(title: "Transcript details") do
136
+ p { "The transcript was recorded at 09:42 UTC." }
137
+ end
138
+ end
139
+ ```
140
+
141
+ Placement belongs to the parent. In the conversion that exposed this rule, a
142
+ `Flex` containing **Redact** and **Permalink** was followed by a `Dialog`
143
+ sibling, so the Dialog trigger started a second line. Put the Dialog root
144
+ inside the same no-wrap action cluster:
145
+
146
+ ```ruby
147
+ Flex(dir: :row, gap: 1, align: :center, wrap: :nowrap) do
148
+ Button("Redact", size: :sm, variant: :destructive)
149
+ Button("Permalink", href: transcript_path(transcript), size: :sm)
150
+
151
+ Dialog(id: dom_id(transcript, :details)) do |dialog|
152
+ dialog.trigger("Details", size: :sm)
153
+ dialog.panel(title: "Transcript details") do
154
+ render UI::TranscriptDetails.new(transcript)
155
+ end
156
+ end
157
+ end
158
+ ```
159
+
160
+ The gallery runs this structure at narrow widths in
161
+ [`Narrow transcript actions`](/gallery/components/dialog#example-dialog-narrow-action-cluster).
162
+
163
+ ### Sheet
164
+
165
+ ERB source — the partial yields contextual content into its side panel:
166
+
167
+ ```erb
168
+ <%= render "sheet", id: "transcript-prompts", title: "Prompts" do %>
169
+ <%= render "prompts", prompts: @prompts %>
170
+ <% end %>
171
+
172
+ <%# _sheet.html.erb %>
173
+ <button command="show-modal" commandfor="<%= id %>-panel">Prompts</button>
174
+ <dialog id="<%= id %>-panel">
175
+ <h2><%= title %></h2>
176
+ <%= yield %>
177
+ </dialog>
178
+ ```
179
+
180
+ Phlex destination — declare the collection before `Sheet`; render it only
181
+ inside the `panel` content slot:
182
+
183
+ ```ruby
184
+ prompts = transcript.prompts.map { |prompt| [prompt.title, prompt_path(prompt)] }
185
+
186
+ render NitroKit::Sheet.new(id: "transcript-prompts", side: :left) do |sheet|
187
+ sheet.trigger("Prompts", icon: :list)
188
+ sheet.panel(title: "Transcript prompts") do
189
+ render NitroKit::AppNavigation.new(label: "Transcript prompts") do |navigation|
190
+ navigation.body do
191
+ prompts.each do |text, href|
192
+ navigation.item(text, href:)
193
+ end
194
+ end
195
+ end
196
+ end
197
+ end
198
+ ```
199
+
200
+ See the executable
201
+ [`Sheet` collection example](/gallery/components/sheet#example-sheet-constructions).
202
+
203
+ ### SettingsLayout
204
+
205
+ ERB source — the call site supplies both the navigation collection and yielded
206
+ settings content:
207
+
208
+ ```erb
209
+ <% sections = [["Profile", profile_settings_path], ["Security", security_settings_path]] %>
210
+ <%= render "settings_layout", sections: sections do %>
211
+ <%= render "profile_form" %>
212
+ <% end %>
213
+
214
+ <%# _settings_layout.html.erb %>
215
+ <nav aria-label="Settings">
216
+ <% sections.each do |text, href| %>
217
+ <%= link_to text, href %>
218
+ <% end %>
219
+ </nav>
220
+ <main><%= yield %></main>
221
+ ```
222
+
223
+ Phlex destination — navigation entries stay inside `navigation`; the former
224
+ yield lives inside the one `content` region:
225
+
226
+ ```ruby
227
+ sections = [["Profile", profile_settings_path], ["Security", security_settings_path]]
228
+
229
+ render NitroKit::SettingsLayout.new do |layout|
230
+ layout.navigation(label: "Settings") do
231
+ sections.each_with_index do |(text, href), index|
232
+ layout.item(text, href:, current: index.zero?)
233
+ end
234
+ end
235
+ layout.content { render UI::ProfileForm.new(profile) }
236
+ end
237
+ ```
238
+
239
+ See the executable
240
+ [`SettingsLayout` minimal example](/gallery/components/settings-layout#example-settings-layout-cardinality-states).
241
+
242
+ ## Preserve unsupported behavior honestly
243
+
244
+ When no equivalent exists, keep semantic Rails or HTML under the application
245
+ namespace and report the missing capability. Do not retain copied 1.x source,
246
+ downgrade a specialized control, or hide the gap behind a generic component.
247
+
248
+ Tooltip custom triggers are the explicit composition path for an existing
249
+ focusable control. Forward every yielded boundary to that actual control:
250
+
251
+ ```ruby
252
+ render NitroKit::Tooltip.new(id: "revoke-help", content: "Revokes access immediately") do |tooltip|
253
+ tooltip.trigger(as: :custom) do |attributes|
254
+ render NitroKit::ButtonTo.new(
255
+ "Revoke",
256
+ href: token_path(token),
257
+ method: :delete,
258
+ variant: :destructive,
259
+ button_html: attributes.html,
260
+ button_aria: attributes.aria,
261
+ button_data: attributes.data
262
+ )
263
+ end
264
+ end
265
+ ```
266
+
267
+ ## Verify fidelity
268
+
269
+ Install and run Nitro Kit's focused host-integration acceptance flow:
270
+
271
+ ```sh
272
+ bin/rails generate nitro_kit:upgrade_smoke_tests
273
+ bin/rails test test/integration/nitro_kit_upgrade_smoke_test.rb
274
+ bin/rails test test/system/nitro_kit_upgrade_smoke_test.rb
275
+ ```
276
+
277
+ The generator does not overwrite existing tests. It generates only files
278
+ supported by the host's Rails Minitest and system-test setup and prints setup
279
+ guidance for skipped files. The tests use the currently bundled gem and cover
280
+ the shared upgrade boundary — browser-submitted Turbo validation and mutation,
281
+ Dialog and Sheet, layout-owned Rails flash, Turbo Frame identity, redirects,
282
+ and post-mutation Phlex rendering. Their collision-checked route exists only
283
+ during each test and is restored afterward; they add no production route or
284
+ component source. Keep application-specific migration tests for inventoried
285
+ product behavior alongside them.
286
+
287
+ The endpoint deliberately inherits `ApplicationController` callbacks. If the
288
+ application requires authentication or current-account state, fill in the
289
+ generated `prepare_nitro_kit_upgrade_smoke_test` methods with the same sign-in
290
+ and account-selection helpers used by ordinary integration and system tests.
291
+ Extend those application-owned classes rather than changing gem test support
292
+ or skipping host callbacks.
293
+
294
+ Run focused request and component tests, then compare the converted flows in a
295
+ browser at wide and narrow widths. Exercise keyboard focus, dialogs and sheets,
296
+ Turbo submissions, errors, empty states, light/dark appearance, and dense
297
+ metadata. A green request suite does not prove that a tooltip, off-canvas
298
+ panel, interactive Card treatment, or responsive composition survived.
299
+
300
+ Finish by deleting copied components, helpers, and controllers; run
301
+ `bin/rails nitro_kit:doctor`; and record every remaining application-owned
302
+ fallback as either intentional product UI or a Nitro Kit coverage gap.
303
+
304
+ Doctor inventories only concrete Nitro Kit 1.x conventions: `nk_*` helpers,
305
+ generated files under `app/components/nitro_kit`, controllers under
306
+ `app/javascript/controllers/nk`, the old Floating UI and combobox packages,
307
+ and `tailwind_merge`. Every finding includes a file and replacement. Its
308
+ disposition is:
309
+
310
+ - `migrated` — no remaining occurrence in that category.
311
+ - `unresolved` — a known 1.x integration still needs its documented 2.x
312
+ replacement or removal.
313
+ - `application-owned` — custom or unsupported behavior must be preserved under
314
+ an application namespace, not as a Nitro shadow.
315
+
316
+ The inventory deliberately does not guess from generic component, JavaScript,
317
+ or dependency names. Review application-owned product behavior separately and
318
+ keep its migration record with the application.
@@ -0,0 +1,24 @@
1
+ # New application strategy
2
+
3
+ Recommend a Rails application template for new applications, not a return to Nitro Kit's old component-copying generator.
4
+
5
+ Rails application templates are designed to configure a new app during `rails new`, can add gems, and can run generators after Bundler finishes. That gives Nitro Kit an eventual one-command entry point:
6
+
7
+ ```sh
8
+ rails new my_app -m https://nitrokit.dev/template.rb
9
+ ```
10
+
11
+ The template should remain thin while the conventions settle. Its first
12
+ version should add Nitro Kit and invoke `nitro_kit:install`. The generator owns
13
+ the project-local skills and `AGENTS.md`; the template may add an application
14
+ layout that renders the stylesheet, appearance bootstrap, and flash toasts. It
15
+ must not copy Nitro components or their controllers.
16
+
17
+ Existing applications install the gem directly and run the setup generator.
18
+ Agent discovery, version-matched skill routing, diagnostics, and initialization
19
+ handoff are meaningful application-owned setup; component source remains
20
+ gem-owned.
21
+
22
+ An optional `nitro_kit:application` generator can later create an application-owned base: layout, `UI` namespace, shell choice, root screen, and authentication hooks. Keep that separate from installing the UI gem so teams can adopt Nitro Kit without adopting an application architecture.
23
+
24
+ Promote the template into a versioned starter application only when Nitro Kit deliberately owns opinions beyond UI and interaction conventions, such as authentication, accounts, teams, billing, jobs, mail, and deployment. Until then, the application template is easier to inspect, test, and evolve and does not impose the maintenance cost of a forked starter repository.