@nadicodeai/ui 0.20.0 → 0.22.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 (350) hide show
  1. package/AGENTS.md +4 -3
  2. package/README.md +14 -21
  3. package/dist/agents.d.ts +10 -0
  4. package/dist/agents.d.ts.map +1 -0
  5. package/dist/agents.js +9 -0
  6. package/dist/components/badge.d.ts +1 -1
  7. package/dist/components/brand-icons/apple.d.ts +18 -0
  8. package/dist/components/brand-icons/apple.d.ts.map +1 -0
  9. package/dist/components/brand-icons/apple.js +22 -0
  10. package/dist/components/brand-icons/brand-icon.d.ts +22 -0
  11. package/dist/components/brand-icons/brand-icon.d.ts.map +1 -0
  12. package/dist/components/brand-icons/brand-icon.js +26 -0
  13. package/dist/components/brand-icons/linux.d.ts +18 -0
  14. package/dist/components/brand-icons/linux.d.ts.map +1 -0
  15. package/dist/components/brand-icons/linux.js +25 -0
  16. package/dist/components/brand-icons/windows.d.ts +18 -0
  17. package/dist/components/brand-icons/windows.d.ts.map +1 -0
  18. package/dist/components/brand-icons/windows.js +22 -0
  19. package/dist/components/brand-icons.d.ts +5 -0
  20. package/dist/components/brand-icons.d.ts.map +1 -0
  21. package/dist/components/brand-icons.js +10 -0
  22. package/dist/components/button.d.ts +1 -1
  23. package/dist/components/button.js +1 -1
  24. package/dist/components/card-marketing.js +2 -2
  25. package/dist/components/card.d.ts +4 -3
  26. package/dist/components/card.d.ts.map +1 -1
  27. package/dist/components/card.js +12 -2
  28. package/dist/components/chart-breakdown-table.js +1 -1
  29. package/dist/components/chart-bullet-bar.d.ts +18 -2
  30. package/dist/components/chart-bullet-bar.d.ts.map +1 -1
  31. package/dist/components/chart-bullet-bar.js +62 -9
  32. package/dist/components/chart-date-range-control.d.ts +11 -1
  33. package/dist/components/chart-date-range-control.d.ts.map +1 -1
  34. package/dist/components/chart-date-range-control.js +13 -3
  35. package/dist/components/chart-entity-colors.d.ts +7 -1
  36. package/dist/components/chart-entity-colors.d.ts.map +1 -1
  37. package/dist/components/chart-entity-colors.js +7 -1
  38. package/dist/components/chart-kpi-stat.d.ts.map +1 -1
  39. package/dist/components/chart-kpi-stat.js +1 -1
  40. package/dist/components/chart-time-series.d.ts.map +1 -1
  41. package/dist/components/chart-time-series.js +62 -4
  42. package/dist/components/chart.js +2 -2
  43. package/dist/components/code-editor-mockup.js +1 -1
  44. package/dist/components/nav-bar.js +1 -1
  45. package/dist/components/radio-group.d.ts +1 -1
  46. package/dist/components/radio-group.d.ts.map +1 -1
  47. package/dist/components/radio-group.js +2 -2
  48. package/dist/components/theme-mode-switcher.d.ts +10 -3
  49. package/dist/components/theme-mode-switcher.d.ts.map +1 -1
  50. package/dist/components/theme-mode-switcher.js +14 -7
  51. package/dist/components/use-case-bento.d.ts +2 -4
  52. package/dist/components/use-case-bento.d.ts.map +1 -1
  53. package/dist/components/use-case-bento.js +2 -3
  54. package/dist/eslint/index.js +91 -0
  55. package/dist/eslint/rules/jsx-class-utility.js +231 -0
  56. package/dist/eslint/rules/no-deprecated-zod-api.js +156 -0
  57. package/dist/eslint/rules/no-design-system-src-import.js +11 -0
  58. package/dist/eslint/rules/no-invalid-token-utility.js +46 -0
  59. package/dist/eslint/rules/no-native-visible-control.js +86 -0
  60. package/dist/eslint/rules/no-raw-color-utility.js +109 -0
  61. package/dist/eslint/rules/no-raw-focus-ring-width.js +30 -0
  62. package/dist/eslint/rules/no-raw-logo-import.js +41 -0
  63. package/dist/eslint/rules/no-shadcn-appearance-override.js +191 -0
  64. package/dist/eslint/rules/no-token-category-bypass.js +53 -0
  65. package/dist/eslint/rules/no-ui-src-import.js +10 -0
  66. package/dist/eslint/rules/no-unpinned-vercel-functions-import.js +100 -0
  67. package/dist/eslint/rules/src-import-boundary.js +207 -0
  68. package/dist/hooks/index.d.ts +0 -1
  69. package/dist/hooks/index.d.ts.map +1 -1
  70. package/dist/hooks/index.js +0 -1
  71. package/dist/index.d.ts +1 -16
  72. package/dist/index.d.ts.map +1 -1
  73. package/dist/index.js +1 -16
  74. package/dist/internal/assistant-ui/attachment.d.ts +5 -0
  75. package/dist/internal/assistant-ui/attachment.d.ts.map +1 -0
  76. package/dist/internal/assistant-ui/attachment.js +93 -0
  77. package/dist/internal/assistant-ui/follow-up-suggestions.d.ts +3 -0
  78. package/dist/internal/assistant-ui/follow-up-suggestions.d.ts.map +1 -0
  79. package/dist/internal/assistant-ui/follow-up-suggestions.js +8 -0
  80. package/dist/internal/assistant-ui/markdown-text.d.ts +2 -0
  81. package/dist/internal/assistant-ui/markdown-text.d.ts.map +1 -0
  82. package/dist/internal/assistant-ui/markdown-text.js +54 -0
  83. package/dist/internal/assistant-ui/reasoning.d.ts +31 -0
  84. package/dist/internal/assistant-ui/reasoning.d.ts.map +1 -0
  85. package/dist/internal/assistant-ui/reasoning.js +118 -0
  86. package/dist/internal/assistant-ui/thread.d.ts +26 -0
  87. package/dist/internal/assistant-ui/thread.d.ts.map +1 -0
  88. package/dist/internal/assistant-ui/thread.js +118 -0
  89. package/dist/internal/assistant-ui/tool-fallback.d.ts +10 -0
  90. package/dist/internal/assistant-ui/tool-fallback.d.ts.map +1 -0
  91. package/dist/internal/assistant-ui/tool-fallback.js +163 -0
  92. package/dist/internal/assistant-ui/tool-group.d.ts +18 -0
  93. package/dist/internal/assistant-ui/tool-group.d.ts.map +1 -0
  94. package/dist/internal/assistant-ui/tool-group.js +44 -0
  95. package/dist/internal/assistant-ui/tooltip-icon-button.d.ts +8 -0
  96. package/dist/internal/assistant-ui/tooltip-icon-button.d.ts.map +1 -0
  97. package/dist/internal/assistant-ui/tooltip-icon-button.js +10 -0
  98. package/dist/styles/globals.css +3 -209
  99. package/docs/agents/nadicodeai-ui.md +4 -6
  100. package/docs/component-classification.md +1 -1
  101. package/docs/consuming-cross-repo.md +32 -3
  102. package/docs/contract.md +16 -6
  103. package/docs/migration/base-ui-migration.md +0 -11
  104. package/docs/product-compositions.md +1 -1
  105. package/llms.txt +5 -6
  106. package/package.json +17 -29
  107. package/skills/nadicodeai-ui/SKILL.md +5 -7
  108. package/dist/ai-elements.d.ts +0 -49
  109. package/dist/ai-elements.d.ts.map +0 -1
  110. package/dist/ai-elements.js +0 -48
  111. package/dist/components/agent-avatar.d.ts +0 -7
  112. package/dist/components/agent-avatar.d.ts.map +0 -1
  113. package/dist/components/agent-avatar.js +0 -6
  114. package/dist/components/agent-chat.d.ts +0 -20
  115. package/dist/components/agent-chat.d.ts.map +0 -1
  116. package/dist/components/agent-chat.js +0 -10
  117. package/dist/components/agent-composer.d.ts +0 -56
  118. package/dist/components/agent-composer.d.ts.map +0 -1
  119. package/dist/components/agent-composer.js +0 -56
  120. package/dist/components/agent-message.d.ts +0 -117
  121. package/dist/components/agent-message.d.ts.map +0 -1
  122. package/dist/components/agent-message.js +0 -99
  123. package/dist/components/agent-thread.d.ts +0 -26
  124. package/dist/components/agent-thread.d.ts.map +0 -1
  125. package/dist/components/agent-thread.js +0 -63
  126. package/dist/components/agent-tool-approval.d.ts +0 -27
  127. package/dist/components/agent-tool-approval.d.ts.map +0 -1
  128. package/dist/components/agent-tool-approval.js +0 -43
  129. package/dist/components/ai-elements/agent.d.ts +0 -27
  130. package/dist/components/ai-elements/agent.d.ts.map +0 -1
  131. package/dist/components/ai-elements/agent.js +0 -25
  132. package/dist/components/ai-elements/artifact.d.ts +0 -24
  133. package/dist/components/ai-elements/artifact.d.ts.map +0 -1
  134. package/dist/components/ai-elements/artifact.js +0 -20
  135. package/dist/components/ai-elements/attachments.d.ts +0 -55
  136. package/dist/components/ai-elements/attachments.d.ts.map +0 -1
  137. package/dist/components/ai-elements/attachments.js +0 -125
  138. package/dist/components/ai-elements/audio-player.d.ts +0 -30
  139. package/dist/components/ai-elements/audio-player.d.ts.map +0 -1
  140. package/dist/components/ai-elements/audio-player.js +0 -41
  141. package/dist/components/ai-elements/canvas.d.ts +0 -8
  142. package/dist/components/ai-elements/canvas.d.ts.map +0 -1
  143. package/dist/components/ai-elements/canvas.js +0 -5
  144. package/dist/components/ai-elements/chain-of-thought.d.ts +0 -30
  145. package/dist/components/ai-elements/chain-of-thought.d.ts.map +0 -1
  146. package/dist/components/ai-elements/chain-of-thought.js +0 -49
  147. package/dist/components/ai-elements/checkpoint.d.ts +0 -12
  148. package/dist/components/ai-elements/checkpoint.d.ts.map +0 -1
  149. package/dist/components/ai-elements/checkpoint.js +0 -10
  150. package/dist/components/ai-elements/code-block.d.ts +0 -53
  151. package/dist/components/ai-elements/code-block.d.ts.map +0 -1
  152. package/dist/components/ai-elements/code-block.js +0 -239
  153. package/dist/components/ai-elements/commit.d.ts +0 -65
  154. package/dist/components/ai-elements/commit.d.ts.map +0 -1
  155. package/dist/components/ai-elements/commit.js +0 -83
  156. package/dist/components/ai-elements/confirmation.d.ts +0 -50
  157. package/dist/components/ai-elements/confirmation.d.ts.map +0 -1
  158. package/dist/components/ai-elements/confirmation.js +0 -57
  159. package/dist/components/ai-elements/connection.d.ts +0 -6
  160. package/dist/components/ai-elements/connection.d.ts.map +0 -1
  161. package/dist/components/ai-elements/connection.js +0 -10
  162. package/dist/components/ai-elements/context.d.ts +0 -33
  163. package/dist/components/ai-elements/context.d.ts.map +0 -1
  164. package/dist/components/ai-elements/context.js +0 -147
  165. package/dist/components/ai-elements/controls.d.ts +0 -5
  166. package/dist/components/ai-elements/controls.d.ts.map +0 -1
  167. package/dist/components/ai-elements/controls.js +0 -5
  168. package/dist/components/ai-elements/conversation.d.ts +0 -24
  169. package/dist/components/ai-elements/conversation.d.ts.map +0 -1
  170. package/dist/components/ai-elements/conversation.js +0 -41
  171. package/dist/components/ai-elements/edge.d.ts +0 -6
  172. package/dist/components/ai-elements/edge.d.ts.map +0 -1
  173. package/dist/components/ai-elements/edge.js +0 -88
  174. package/dist/components/ai-elements/environment-variables.d.ts +0 -39
  175. package/dist/components/ai-elements/environment-variables.d.ts.map +0 -1
  176. package/dist/components/ai-elements/environment-variables.js +0 -60
  177. package/dist/components/ai-elements/file-tree.d.ts +0 -27
  178. package/dist/components/ai-elements/file-tree.d.ts.map +0 -1
  179. package/dist/components/ai-elements/file-tree.js +0 -73
  180. package/dist/components/ai-elements/image.d.ts +0 -7
  181. package/dist/components/ai-elements/image.d.ts.map +0 -1
  182. package/dist/components/ai-elements/image.js +0 -3
  183. package/dist/components/ai-elements/inline-citation.d.ts +0 -39
  184. package/dist/components/ai-elements/inline-citation.d.ts.map +0 -1
  185. package/dist/components/ai-elements/inline-citation.js +0 -86
  186. package/dist/components/ai-elements/jsx-preview.d.ts +0 -30
  187. package/dist/components/ai-elements/jsx-preview.d.ts.map +0 -1
  188. package/dist/components/ai-elements/jsx-preview.js +0 -159
  189. package/dist/components/ai-elements/message.d.ts +0 -38
  190. package/dist/components/ai-elements/message.d.ts.map +0 -1
  191. package/dist/components/ai-elements/message.js +0 -91
  192. package/dist/components/ai-elements/mic-selector.d.ts +0 -46
  193. package/dist/components/ai-elements/mic-selector.d.ts.map +0 -1
  194. package/dist/components/ai-elements/mic-selector.js +0 -180
  195. package/dist/components/ai-elements/model-selector.d.ts +0 -36
  196. package/dist/components/ai-elements/model-selector.d.ts.map +0 -1
  197. package/dist/components/ai-elements/model-selector.js +0 -18
  198. package/dist/components/ai-elements/node.d.ts +0 -22
  199. package/dist/components/ai-elements/node.d.ts.map +0 -1
  200. package/dist/components/ai-elements/node.js +0 -12
  201. package/dist/components/ai-elements/open-in-chat.d.ts +0 -27
  202. package/dist/components/ai-elements/open-in-chat.d.ts.map +0 -1
  203. package/dist/components/ai-elements/open-in-chat.js +0 -81
  204. package/dist/components/ai-elements/package-info.d.ts +0 -30
  205. package/dist/components/ai-elements/package-info.d.ts.map +0 -1
  206. package/dist/components/ai-elements/package-info.js +0 -50
  207. package/dist/components/ai-elements/panel.d.ts +0 -6
  208. package/dist/components/ai-elements/panel.d.ts.map +0 -1
  209. package/dist/components/ai-elements/panel.js +0 -5
  210. package/dist/components/ai-elements/persona.d.ts +0 -49
  211. package/dist/components/ai-elements/persona.d.ts.map +0 -1
  212. package/dist/components/ai-elements/persona.js +0 -175
  213. package/dist/components/ai-elements/plan.d.ts +0 -27
  214. package/dist/components/ai-elements/plan.d.ts.map +0 -1
  215. package/dist/components/ai-elements/plan.js +0 -34
  216. package/dist/components/ai-elements/prompt-input.d.ts +0 -149
  217. package/dist/components/ai-elements/prompt-input.d.ts.map +0 -1
  218. package/dist/components/ai-elements/prompt-input.js +0 -704
  219. package/dist/components/ai-elements/queue.d.ts +0 -62
  220. package/dist/components/ai-elements/queue.d.ts.map +0 -1
  221. package/dist/components/ai-elements/queue.js +0 -24
  222. package/dist/components/ai-elements/reasoning.d.ts +0 -27
  223. package/dist/components/ai-elements/reasoning.d.ts.map +0 -1
  224. package/dist/components/ai-elements/reasoning.js +0 -92
  225. package/dist/components/ai-elements/sandbox.d.ts +0 -25
  226. package/dist/components/ai-elements/sandbox.d.ts.map +0 -1
  227. package/dist/components/ai-elements/sandbox.js +0 -15
  228. package/dist/components/ai-elements/schema-display.d.ts +0 -56
  229. package/dist/components/ai-elements/schema-display.d.ts.map +0 -1
  230. package/dist/components/ai-elements/schema-display.js +0 -90
  231. package/dist/components/ai-elements/shimmer.d.ts +0 -10
  232. package/dist/components/ai-elements/shimmer.d.ts.map +0 -1
  233. package/dist/components/ai-elements/shimmer.js +0 -11
  234. package/dist/components/ai-elements/snippet.d.ts +0 -19
  235. package/dist/components/ai-elements/snippet.d.ts.map +0 -1
  236. package/dist/components/ai-elements/snippet.js +0 -32
  237. package/dist/components/ai-elements/sources.d.ts +0 -13
  238. package/dist/components/ai-elements/sources.d.ts.map +0 -1
  239. package/dist/components/ai-elements/sources.js +0 -9
  240. package/dist/components/ai-elements/speech-input.d.ts +0 -55
  241. package/dist/components/ai-elements/speech-input.d.ts.map +0 -1
  242. package/dist/components/ai-elements/speech-input.js +0 -187
  243. package/dist/components/ai-elements/stack-trace.d.ts +0 -38
  244. package/dist/components/ai-elements/stack-trace.d.ts.map +0 -1
  245. package/dist/components/ai-elements/stack-trace.js +0 -181
  246. package/dist/components/ai-elements/suggestion.d.ts +0 -11
  247. package/dist/components/ai-elements/suggestion.d.ts.map +0 -1
  248. package/dist/components/ai-elements/suggestion.js +0 -13
  249. package/dist/components/ai-elements/task.d.ts +0 -15
  250. package/dist/components/ai-elements/task.d.ts.map +0 -1
  251. package/dist/components/ai-elements/task.js +0 -10
  252. package/dist/components/ai-elements/terminal.d.ts +0 -28
  253. package/dist/components/ai-elements/terminal.d.ts.map +0 -1
  254. package/dist/components/ai-elements/terminal.js +0 -55
  255. package/dist/components/ai-elements/test-results.d.ts +0 -59
  256. package/dist/components/ai-elements/test-results.d.ts.map +0 -1
  257. package/dist/components/ai-elements/test-results.js +0 -98
  258. package/dist/components/ai-elements/tool.d.ts +0 -32
  259. package/dist/components/ai-elements/tool.d.ts.map +0 -1
  260. package/dist/components/ai-elements/tool.js +0 -49
  261. package/dist/components/ai-elements/toolbar.d.ts +0 -6
  262. package/dist/components/ai-elements/toolbar.d.ts.map +0 -1
  263. package/dist/components/ai-elements/toolbar.js +0 -5
  264. package/dist/components/ai-elements/transcription.d.ts +0 -17
  265. package/dist/components/ai-elements/transcription.d.ts.map +0 -1
  266. package/dist/components/ai-elements/transcription.js +0 -36
  267. package/dist/components/ai-elements/voice-selector.d.ts +0 -65
  268. package/dist/components/ai-elements/voice-selector.d.ts.map +0 -1
  269. package/dist/components/ai-elements/voice-selector.js +0 -224
  270. package/dist/components/ai-elements/web-preview.d.ts +0 -35
  271. package/dist/components/ai-elements/web-preview.d.ts.map +0 -1
  272. package/dist/components/ai-elements/web-preview.js +0 -66
  273. package/dist/components/artifact-panel.d.ts +0 -130
  274. package/dist/components/artifact-panel.d.ts.map +0 -1
  275. package/dist/components/artifact-panel.js +0 -180
  276. package/dist/components/attachment.d.ts +0 -24
  277. package/dist/components/attachment.d.ts.map +0 -1
  278. package/dist/components/attachment.js +0 -68
  279. package/dist/components/bubble.d.ts +0 -17
  280. package/dist/components/bubble.d.ts.map +0 -1
  281. package/dist/components/bubble.js +0 -59
  282. package/dist/components/demo-surface.d.ts +0 -34
  283. package/dist/components/demo-surface.d.ts.map +0 -1
  284. package/dist/components/demo-surface.js +0 -21
  285. package/dist/components/files-preview.d.ts +0 -36
  286. package/dist/components/files-preview.d.ts.map +0 -1
  287. package/dist/components/files-preview.js +0 -85
  288. package/dist/components/marker.d.ts +0 -11
  289. package/dist/components/marker.d.ts.map +0 -1
  290. package/dist/components/marker.js +0 -34
  291. package/dist/components/message-scroller.d.ts +0 -17
  292. package/dist/components/message-scroller.d.ts.map +0 -1
  293. package/dist/components/message-scroller.js +0 -29
  294. package/dist/components/message.d.ts +0 -11
  295. package/dist/components/message.d.ts.map +0 -1
  296. package/dist/components/message.js +0 -21
  297. package/dist/components/state-notice.d.ts +0 -13
  298. package/dist/components/state-notice.d.ts.map +0 -1
  299. package/dist/components/state-notice.js +0 -8
  300. package/dist/components/watch-it-work-band.d.ts +0 -12
  301. package/dist/components/watch-it-work-band.d.ts.map +0 -1
  302. package/dist/components/watch-it-work-band.js +0 -8
  303. package/dist/hooks/use-controllable-state.d.ts +0 -9
  304. package/dist/hooks/use-controllable-state.d.ts.map +0 -1
  305. package/dist/hooks/use-controllable-state.js +0 -23
  306. package/dist/lib/agent-attachment.d.ts +0 -11
  307. package/dist/lib/agent-attachment.d.ts.map +0 -1
  308. package/dist/lib/agent-attachment.js +0 -19
  309. package/dist/lib/agent-contracts.d.ts +0 -132
  310. package/dist/lib/agent-contracts.d.ts.map +0 -1
  311. package/dist/lib/agent-contracts.js +0 -6
  312. package/dist/lib/agent-state.d.ts +0 -22
  313. package/dist/lib/agent-state.d.ts.map +0 -1
  314. package/dist/lib/agent-state.js +0 -96
  315. package/dist/lib/agent-work-state.d.ts +0 -36
  316. package/dist/lib/agent-work-state.d.ts.map +0 -1
  317. package/dist/lib/agent-work-state.js +0 -36
  318. package/dist/lib/message-scroller-primitive/components.d.ts +0 -17
  319. package/dist/lib/message-scroller-primitive/components.d.ts.map +0 -1
  320. package/dist/lib/message-scroller-primitive/components.js +0 -204
  321. package/dist/lib/message-scroller-primitive/geometry.d.ts +0 -51
  322. package/dist/lib/message-scroller-primitive/geometry.d.ts.map +0 -1
  323. package/dist/lib/message-scroller-primitive/geometry.js +0 -199
  324. package/dist/lib/message-scroller-primitive/index.d.ts +0 -12
  325. package/dist/lib/message-scroller-primitive/index.d.ts.map +0 -1
  326. package/dist/lib/message-scroller-primitive/index.js +0 -12
  327. package/dist/lib/message-scroller-primitive/stores.d.ts +0 -6
  328. package/dist/lib/message-scroller-primitive/stores.d.ts.map +0 -1
  329. package/dist/lib/message-scroller-primitive/stores.js +0 -53
  330. package/dist/lib/message-scroller-primitive/types.d.ts +0 -88
  331. package/dist/lib/message-scroller-primitive/types.d.ts.map +0 -1
  332. package/dist/lib/message-scroller-primitive/types.js +0 -40
  333. package/dist/lib/message-scroller-primitive/use-message-scroller-commands.d.ts +0 -19
  334. package/dist/lib/message-scroller-primitive/use-message-scroller-commands.d.ts.map +0 -1
  335. package/dist/lib/message-scroller-primitive/use-message-scroller-commands.js +0 -188
  336. package/dist/lib/message-scroller-primitive/use-message-scroller-controller.d.ts +0 -7
  337. package/dist/lib/message-scroller-primitive/use-message-scroller-controller.d.ts.map +0 -1
  338. package/dist/lib/message-scroller-primitive/use-message-scroller-controller.js +0 -506
  339. package/dist/lib/message-scroller-primitive/use-message-scroller-refs.d.ts +0 -49
  340. package/dist/lib/message-scroller-primitive/use-message-scroller-refs.d.ts.map +0 -1
  341. package/dist/lib/message-scroller-primitive/use-message-scroller-refs.js +0 -90
  342. package/dist/lib/message-scroller-primitive/use-render.d.ts +0 -22
  343. package/dist/lib/message-scroller-primitive/use-render.d.ts.map +0 -1
  344. package/dist/lib/message-scroller-primitive/use-render.js +0 -113
  345. package/dist/lib/message-scroller-primitive/utils.d.ts +0 -4
  346. package/dist/lib/message-scroller-primitive/utils.d.ts.map +0 -1
  347. package/dist/lib/message-scroller-primitive/utils.js +0 -9
  348. package/docs/agent-work-surfaces.md +0 -132
  349. package/docs/migration/ai-elements-vendoring.md +0 -29
  350. package/docs/terminal-tui-semantics.md +0 -172
@@ -0,0 +1,109 @@
1
+ import {
2
+ classUtilities,
3
+ isPackageOwnedPrimitive,
4
+ staticStringFragments,
5
+ } from "./jsx-class-utility.js";
6
+
7
+ const COLOR_NAMES = new Set([
8
+ "black",
9
+ "white",
10
+ "slate",
11
+ "gray",
12
+ "zinc",
13
+ "neutral",
14
+ "stone",
15
+ "red",
16
+ "orange",
17
+ "amber",
18
+ "yellow",
19
+ "lime",
20
+ "green",
21
+ "emerald",
22
+ "teal",
23
+ "cyan",
24
+ "sky",
25
+ "blue",
26
+ "indigo",
27
+ "violet",
28
+ "purple",
29
+ "fuchsia",
30
+ "pink",
31
+ "rose",
32
+ "nc",
33
+ ]);
34
+ const COLOR_UTILITY =
35
+ /^(?:bg|text|border|outline|ring|fill|stroke|decoration|accent|caret|divide|from|via|to|shadow)-(\[.+\]|[^/]+)(?:\/.*)?$/;
36
+ const COLOR_VALUE_PROPERTIES = new Set([
37
+ "accentColor",
38
+ "background",
39
+ "backgroundColor",
40
+ "borderColor",
41
+ "caretColor",
42
+ "color",
43
+ "fill",
44
+ "outlineColor",
45
+ "stopColor",
46
+ "stroke",
47
+ "textDecorationColor",
48
+ ]);
49
+
50
+ function withoutVariants(utility) {
51
+ return utility.slice(utility.lastIndexOf(":") + 1);
52
+ }
53
+
54
+ function isRawColorUtility(utility) {
55
+ const match = COLOR_UTILITY.exec(withoutVariants(utility));
56
+ if (!match) {
57
+ return false;
58
+ }
59
+ const color = match[1];
60
+ if (color.startsWith("[")) {
61
+ return (
62
+ /var\(--nc-/i.test(color) ||
63
+ /^\[(?:#|(?:rgba?|hsla?|oklch|oklab|hwb|color-mix)\(|(?:red|orange|amber|yellow|lime|green|emerald|teal|cyan|sky|blue|indigo|violet|purple|fuchsia|pink|rose|black|white)\])/i.test(
64
+ color,
65
+ )
66
+ );
67
+ }
68
+ return COLOR_NAMES.has(color.split("-")[0]);
69
+ }
70
+
71
+ function propertyName(node) {
72
+ if (!node || node.computed) return undefined;
73
+ if (node.key.type === "Identifier") return node.key.name;
74
+ if (node.key.type === "Literal" && typeof node.key.value === "string") return node.key.value;
75
+ return undefined;
76
+ }
77
+
78
+ export const noRawColorUtility = {
79
+ meta: {
80
+ type: "problem",
81
+ docs: {
82
+ description:
83
+ "Disallow raw Tailwind colors and canonical color values in app source; use semantic design tokens",
84
+ },
85
+ schema: [],
86
+ messages: {
87
+ rawColorUtility: "Use a semantic color role instead of raw color value {{utility}}.",
88
+ },
89
+ },
90
+ create(context) {
91
+ if (isPackageOwnedPrimitive(context.filename)) return {};
92
+
93
+ return {
94
+ JSXAttribute(node) {
95
+ for (const utility of classUtilities(node, context)) {
96
+ if (!isRawColorUtility(utility)) continue;
97
+ context.report({ node, messageId: "rawColorUtility", data: { utility } });
98
+ }
99
+ },
100
+ Property(node) {
101
+ if (!COLOR_VALUE_PROPERTIES.has(propertyName(node))) return;
102
+ for (const value of staticStringFragments(node.value, context)) {
103
+ if (!/var\(--nc-/i.test(value)) continue;
104
+ context.report({ node, messageId: "rawColorUtility", data: { utility: value } });
105
+ }
106
+ },
107
+ };
108
+ },
109
+ };
@@ -0,0 +1,30 @@
1
+ import { classUtilities } from "./jsx-class-utility.js";
2
+
3
+ function isRawFocusRingWidth(utility) {
4
+ const base = utility.slice(utility.lastIndexOf(":") + 1);
5
+ return utility.includes("focus") && /^ring-(?:[1-9]\d*|px)$/.test(base);
6
+ }
7
+
8
+ export const noRawFocusRingWidth = {
9
+ meta: {
10
+ type: "problem",
11
+ docs: {
12
+ description: "Require the design-system focus-ring width on every focus surface",
13
+ },
14
+ schema: [],
15
+ messages: {
16
+ rawFocusRingWidth:
17
+ "Use ring-[length:var(--ring-width-focus)] instead of raw focus-ring width {{utility}}.",
18
+ },
19
+ },
20
+ create(context) {
21
+ return {
22
+ JSXAttribute(node) {
23
+ for (const utility of classUtilities(node, context)) {
24
+ if (!isRawFocusRingWidth(utility)) continue;
25
+ context.report({ node, messageId: "rawFocusRingWidth", data: { utility } });
26
+ }
27
+ },
28
+ };
29
+ },
30
+ };
@@ -0,0 +1,41 @@
1
+ import { createSrcImportRule } from "./src-import-boundary.js";
2
+
3
+ const BANNED_PATTERNS = [
4
+ "@nadicodeai/design-system/assets/logo-mark",
5
+ "@nadicodeai/design-system/assets/logo-wordmark",
6
+ "@nadicodeai/design-system/assets/logo-geometry",
7
+ "logo-mark.svg",
8
+ "logo-wordmark.svg",
9
+ ];
10
+
11
+ // Only the single brand adapter in @nadicodeai/ui may import the raw logo
12
+ // assets. A bare "/components/brand.tsx" suffix would also whitelist a future
13
+ // website/portal `components/brand.tsx`, letting an app bypass BrandMark —
14
+ // pin the full package-relative path instead.
15
+ const ALLOWED_SUFFIXES = ["@nadicodeai/ui/src/components/brand.tsx"];
16
+
17
+ function isAllowedFile(filename) {
18
+ const normalized = filename.replaceAll("\\", "/");
19
+ return ALLOWED_SUFFIXES.some((suffix) => normalized.endsWith(suffix));
20
+ }
21
+
22
+ function matchesBanned(value) {
23
+ return typeof value === "string" && BANNED_PATTERNS.some((pattern) => value.includes(pattern));
24
+ }
25
+
26
+ const rawLogoImportRule = createSrcImportRule({
27
+ description: "Disallow direct logo asset imports outside the BrandMark/BrandWordmark adapter",
28
+ bannedMessage:
29
+ "Import logo assets only through BrandMark/BrandWordmark from @nadicodeai/ui/components/brand (found {{value}}).",
30
+ isBanned: matchesBanned,
31
+ });
32
+
33
+ export const noRawLogoImport = {
34
+ ...rawLogoImportRule,
35
+ create(context) {
36
+ if (isAllowedFile(context.filename)) {
37
+ return {};
38
+ }
39
+ return rawLogoImportRule.create(context);
40
+ },
41
+ };
@@ -0,0 +1,191 @@
1
+ import {
2
+ classUtilities,
3
+ isPackageOwnedPrimitive,
4
+ openingElementClassUtilities,
5
+ } from "./jsx-class-utility.js";
6
+
7
+ function withoutVariants(utility) {
8
+ return utility.slice(utility.lastIndexOf(":") + 1);
9
+ }
10
+
11
+ function isTypographySize(utility) {
12
+ return /^text-(?:xs|sm|base|lg|xl|[2-9]xl|\[[\d.]+(?:px|rem|em|%|lh)\])$/.test(utility);
13
+ }
14
+
15
+ function isTextLayoutUtility(utility) {
16
+ return /^text-(?:left|center|right|justify|start|end|balance|pretty|clip|ellipsis)$/.test(
17
+ utility,
18
+ );
19
+ }
20
+
21
+ const COLOR_NAMES = new Set([
22
+ "black",
23
+ "white",
24
+ "slate",
25
+ "gray",
26
+ "zinc",
27
+ "neutral",
28
+ "stone",
29
+ "red",
30
+ "orange",
31
+ "amber",
32
+ "yellow",
33
+ "lime",
34
+ "green",
35
+ "emerald",
36
+ "teal",
37
+ "cyan",
38
+ "sky",
39
+ "blue",
40
+ "indigo",
41
+ "violet",
42
+ "purple",
43
+ "fuchsia",
44
+ "pink",
45
+ "rose",
46
+ "nc",
47
+ "background",
48
+ "foreground",
49
+ "card",
50
+ "popover",
51
+ "primary",
52
+ "secondary",
53
+ "muted",
54
+ "accent",
55
+ "destructive",
56
+ "border",
57
+ "input",
58
+ "ring",
59
+ "focus",
60
+ ]);
61
+
62
+ function hasColorValue(utility, prefix) {
63
+ if (!utility.startsWith(prefix)) {
64
+ return false;
65
+ }
66
+ const value = utility.slice(prefix.length).split("/")[0];
67
+ return value.startsWith("[") || COLOR_NAMES.has(value.split("-")[0]);
68
+ }
69
+
70
+ function isBorderMechanic(utility) {
71
+ return /^(?:border(?:-(?:[xy]|[trblse]{1,2}|[0-9]+|px|dashed|dotted|double|hidden|none))?)$/.test(
72
+ utility,
73
+ );
74
+ }
75
+
76
+ function isBorderRemoval(utility) {
77
+ return /^border(?:-[xytrblse]{1,2})?-(?:0|none|\[(?:length:)?0(?:px|rem|em|%)?\])$/.test(utility);
78
+ }
79
+
80
+ function isRingOrOutlineMechanic(utility) {
81
+ return /^(?:ring(?:-(?:[0-9]+|inset|offset(?:-[0-9]+)?))?|outline(?:-(?:none|[0-9]+|offset-[0-9]+))?)$/.test(
82
+ utility,
83
+ );
84
+ }
85
+
86
+ function isAppearanceUtility(utility) {
87
+ const base = withoutVariants(utility);
88
+ return (
89
+ /^appearance-/.test(base) ||
90
+ /^bg-/.test(base) ||
91
+ isBorderRemoval(base) ||
92
+ (base.startsWith("border") && !isBorderMechanic(base) && hasColorValue(base, "border-")) ||
93
+ /^shadow(?:-|$)/.test(base) ||
94
+ /^rounded(?:-|$)/.test(base) ||
95
+ ((base.startsWith("ring") || base.startsWith("outline")) &&
96
+ !isRingOrOutlineMechanic(base) &&
97
+ (hasColorValue(base, "ring-") || hasColorValue(base, "outline-"))) ||
98
+ /^opacity-/.test(base) ||
99
+ (/^text-/.test(base) && !isTypographySize(base) && !isTextLayoutUtility(base))
100
+ );
101
+ }
102
+
103
+ function isProhibitedAppearanceUtility(utility, { cardRoot = false } = {}) {
104
+ const base = withoutVariants(utility);
105
+ return isAppearanceUtility(utility) && (!isBorderRemoval(base) || cardRoot);
106
+ }
107
+
108
+ function targetsSharedSlot(utility) {
109
+ return utility.includes("data-slot") || utility.includes("data-[slot");
110
+ }
111
+
112
+ function targetsCardSlot(utility) {
113
+ return (
114
+ /data-slot=(?:card|["']card["'])(?=\])/.test(utility) ||
115
+ /data-\[slot=(?:card|["']card["'])\]/.test(utility)
116
+ );
117
+ }
118
+
119
+ export const noShadcnAppearanceOverride = {
120
+ meta: {
121
+ type: "problem",
122
+ docs: {
123
+ description:
124
+ "Disallow app callers repainting imported shadcn primitives; compose their structural layout only",
125
+ },
126
+ schema: [],
127
+ messages: {
128
+ appearanceOverride:
129
+ "Do not repaint an imported @nadicodeai/ui primitive with {{utility}}; use its semantic variant or package primitive.",
130
+ },
131
+ },
132
+ create(context) {
133
+ if (isPackageOwnedPrimitive(context.filename)) {
134
+ return {};
135
+ }
136
+
137
+ const sharedPrimitiveNames = new Set();
138
+ const sharedCardRootNames = new Set();
139
+ const isSharedPrimitive = (node) =>
140
+ node?.type === "JSXOpeningElement" &&
141
+ node.name.type === "JSXIdentifier" &&
142
+ sharedPrimitiveNames.has(node.name.name);
143
+ const isSharedCardRoot = (node) =>
144
+ node?.type === "JSXOpeningElement" &&
145
+ node.name.type === "JSXIdentifier" &&
146
+ sharedCardRootNames.has(node.name.name);
147
+ return {
148
+ ImportDeclaration(node) {
149
+ if (
150
+ typeof node.source.value !== "string" ||
151
+ !node.source.value.startsWith("@nadicodeai/ui/components/")
152
+ ) {
153
+ return;
154
+ }
155
+ for (const specifier of node.specifiers) {
156
+ sharedPrimitiveNames.add(specifier.local.name);
157
+ if (
158
+ node.source.value === "@nadicodeai/ui/components/card" &&
159
+ specifier.type === "ImportSpecifier" &&
160
+ specifier.imported.name === "Card"
161
+ ) {
162
+ sharedCardRootNames.add(specifier.local.name);
163
+ }
164
+ }
165
+ },
166
+ JSXOpeningElement(node) {
167
+ if (!isSharedPrimitive(node)) return;
168
+ for (const utility of openingElementClassUtilities(node, context)) {
169
+ if (
170
+ utility &&
171
+ isProhibitedAppearanceUtility(utility, { cardRoot: isSharedCardRoot(node) })
172
+ ) {
173
+ context.report({ node, messageId: "appearanceOverride", data: { utility } });
174
+ }
175
+ }
176
+ },
177
+ JSXAttribute(node) {
178
+ if (isSharedPrimitive(node.parent)) return;
179
+ for (const utility of classUtilities(node, context)) {
180
+ if (
181
+ !targetsSharedSlot(utility) ||
182
+ !isProhibitedAppearanceUtility(utility, { cardRoot: targetsCardSlot(utility) })
183
+ ) {
184
+ continue;
185
+ }
186
+ context.report({ node, messageId: "appearanceOverride", data: { utility } });
187
+ }
188
+ },
189
+ };
190
+ },
191
+ };
@@ -0,0 +1,53 @@
1
+ import { createRequire } from "node:module";
2
+
3
+ import { tokenUtilityVisitors } from "./jsx-class-utility.js";
4
+
5
+ const require = createRequire(import.meta.url);
6
+ const borderRadius = require("@nadicodeai/design-system/tailwind").theme.extend.borderRadius;
7
+ const radiusNameByValue = new Map(
8
+ Object.entries(borderRadius).map(([name, value]) => [value, name]),
9
+ );
10
+ const ARBITRARY_RADIUS = /^(rounded(?:-(?:t|r|b|l|s|e|ss|se|ee|es|tl|tr|br|bl))?)-\[(.+)\]$/;
11
+ const CANONICAL_RADIUS_VARIABLE = /^var\(--(?:nc-rounded|radius)-([a-z0-9-]+)\)$/;
12
+
13
+ function canonicalRadiusReplacement(utility) {
14
+ const variantBoundary = utility.lastIndexOf(":") + 1;
15
+ const variants = utility.slice(0, variantBoundary);
16
+ const unqualified = utility.slice(variantBoundary);
17
+ const match = ARBITRARY_RADIUS.exec(unqualified);
18
+ if (!match) return undefined;
19
+
20
+ const [, prefix, rawValue] = match;
21
+ const value = rawValue.trim();
22
+ const variable = CANONICAL_RADIUS_VARIABLE.exec(value);
23
+ const token = variable?.[1] ?? radiusNameByValue.get(value);
24
+ if (!token || !(token in borderRadius)) return undefined;
25
+
26
+ return `${variants}${prefix}-${token}`;
27
+ }
28
+
29
+ export const noTokenCategoryBypass = {
30
+ meta: {
31
+ type: "problem",
32
+ docs: {
33
+ description:
34
+ "Disallow arbitrary radius values when the generated design system provides an exact utility",
35
+ },
36
+ schema: [],
37
+ messages: {
38
+ canonicalTokenUtility:
39
+ "Replace {{utility}} with the generated design-system utility {{replacement}}.",
40
+ },
41
+ },
42
+ create(context) {
43
+ return tokenUtilityVisitors(context, (node, utility) => {
44
+ const replacement = canonicalRadiusReplacement(utility);
45
+ if (!replacement) return;
46
+ context.report({
47
+ node,
48
+ messageId: "canonicalTokenUtility",
49
+ data: { replacement, utility },
50
+ });
51
+ });
52
+ },
53
+ };
@@ -0,0 +1,10 @@
1
+ import { bannedSourceRootMatcher, createSrcImportRule } from "./src-import-boundary.js";
2
+
3
+ /** @type {import('eslint').Rule.RuleModule} */
4
+ export const noUiSrcImport = createSrcImportRule({
5
+ description: "Disallow deep imports from @nadicodeai/ui/src/* in consumer apps",
6
+ bannedMessage: "Import @nadicodeai/ui through package exports only, not {{value}}.",
7
+ // The package sits at a repo-root dir literally named `@nadicodeai/ui/`, so
8
+ // relative paths carry the full `@nadicodeai/ui/src` marker too.
9
+ isBanned: bannedSourceRootMatcher("@nadicodeai/ui/src"),
10
+ });
@@ -0,0 +1,100 @@
1
+ const PACKAGE_NAME = "@vercel/functions";
2
+
3
+ // Third-party helpers stay behind owned, single-purpose capability seams. Pin
4
+ // the full workspace-relative suffix so a same-named file in another workspace
5
+ // cannot acquire a platform dependency by shadowing an allowed module.
6
+ const ALLOWED_IMPORTS = new Map([
7
+ ["portal/src/lib/server/db.ts", new Set(["attachDatabasePool"])],
8
+ ["portal/src/lib/server/deferred-work.ts", new Set(["waitUntil"])],
9
+ ]);
10
+
11
+ function matchesPackage(value) {
12
+ return (
13
+ typeof value === "string" && (value === PACKAGE_NAME || value.startsWith(`${PACKAGE_NAME}/`))
14
+ );
15
+ }
16
+
17
+ function allowedSymbolsFor(filename) {
18
+ const normalized = filename.replaceAll("\\", "/");
19
+ for (const [suffix, symbols] of ALLOWED_IMPORTS) {
20
+ if (normalized.endsWith(suffix)) {
21
+ return symbols;
22
+ }
23
+ }
24
+ return undefined;
25
+ }
26
+
27
+ function importedName(specifier) {
28
+ if (specifier.type !== "ImportSpecifier") {
29
+ return undefined;
30
+ }
31
+ return specifier.imported.type === "Identifier"
32
+ ? specifier.imported.name
33
+ : specifier.imported.value;
34
+ }
35
+
36
+ /** @type {import('eslint').Rule.RuleModule} */
37
+ export const noUnpinnedVercelFunctionsImport = {
38
+ meta: {
39
+ type: "problem",
40
+ docs: {
41
+ description: "Confine @vercel/functions imports to pinned edge modules and symbols",
42
+ },
43
+ messages: {
44
+ banned:
45
+ "@vercel/functions duck-types its inputs and ipAddress() crashed production once (docs/solutions/portal-device-authorize-vercel-headers-crash.md). Its use is pinned per module and per symbol; amend the allowlist deliberately or keep the dependency out (found {{value}}).",
46
+ },
47
+ schema: [],
48
+ },
49
+ create(context) {
50
+ const allowedSymbols = allowedSymbolsFor(context.filename);
51
+
52
+ function report(node, value) {
53
+ context.report({
54
+ node,
55
+ messageId: "banned",
56
+ data: { value },
57
+ });
58
+ }
59
+
60
+ return {
61
+ ImportDeclaration(node) {
62
+ if (!matchesPackage(node.source.value)) {
63
+ return;
64
+ }
65
+
66
+ const importsOnlyPinnedSymbols =
67
+ allowedSymbols &&
68
+ node.specifiers.length > 0 &&
69
+ node.specifiers.every((specifier) => {
70
+ const name = importedName(specifier);
71
+ return name !== undefined && allowedSymbols.has(name);
72
+ });
73
+
74
+ if (!importsOnlyPinnedSymbols) {
75
+ report(node, node.source.value);
76
+ }
77
+ },
78
+ // Everything except a static import is judged by the quoted reference
79
+ // itself, whatever expression carries it: dynamic import(), require in
80
+ // any callee shape (bare, module.require, createRequire), export ...
81
+ // from, or a bare string that smuggles the specifier to a loader. Only
82
+ // static named imports can prove which symbols they bind, so only they
83
+ // get the allowlist path above.
84
+ Literal(node) {
85
+ if (!matchesPackage(node.value)) {
86
+ return;
87
+ }
88
+ if (node.parent.type === "ImportDeclaration") {
89
+ return;
90
+ }
91
+ report(node, node.value);
92
+ },
93
+ TemplateLiteral(node) {
94
+ if (node.expressions.length === 0 && matchesPackage(node.quasis[0]?.value.cooked)) {
95
+ report(node, node.quasis[0].value.cooked);
96
+ }
97
+ },
98
+ };
99
+ },
100
+ };