@devalok/shilp-sutra 0.55.1 → 0.57.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 (270) hide show
  1. package/BREAKING.json +13 -0
  2. package/MIGRATION.md +163 -0
  3. package/README.md +16 -1
  4. package/dist/_chunks/badge-group.js +92 -78
  5. package/dist/_chunks/badge-group.js.map +1 -1
  6. package/dist/_chunks/chat.js +91 -75
  7. package/dist/_chunks/chat.js.map +1 -1
  8. package/dist/_chunks/document-preview.js +1 -1
  9. package/dist/_chunks/document-preview.js.map +1 -1
  10. package/dist/_chunks/emoji-suggestion.js +32 -30
  11. package/dist/_chunks/emoji-suggestion.js.map +1 -1
  12. package/dist/_chunks/mention-suggestion.js +36 -35
  13. package/dist/_chunks/mention-suggestion.js.map +1 -1
  14. package/dist/_chunks/oauth-button.js +1 -1
  15. package/dist/_chunks/oauth-button.js.map +1 -1
  16. package/dist/_chunks/primitives-internal.js +437 -537
  17. package/dist/_chunks/primitives-internal.js.map +1 -1
  18. package/dist/_chunks/success.js +2 -2
  19. package/dist/_chunks/success.js.map +1 -1
  20. package/dist/_chunks/tree-view.js +1 -1
  21. package/dist/_chunks/tree-view.js.map +1 -1
  22. package/dist/_chunks/use-calendar.js +4 -4
  23. package/dist/_chunks/use-calendar.js.map +1 -1
  24. package/dist/ai/blocks/text.js +1 -1
  25. package/dist/ai/blocks/text.js.map +1 -1
  26. package/dist/ai/command-bar.js +9 -9
  27. package/dist/ai/command-bar.js.map +1 -1
  28. package/dist/ai/conversation.js +2 -2
  29. package/dist/ai/conversation.js.map +1 -1
  30. package/dist/composed/activity-feed.js +1 -1
  31. package/dist/composed/activity-feed.js.map +1 -1
  32. package/dist/composed/avatar-group.d.ts +7 -2
  33. package/dist/composed/avatar-group.d.ts.map +1 -1
  34. package/dist/composed/avatar-group.js +3 -3
  35. package/dist/composed/avatar-group.js.map +1 -1
  36. package/dist/composed/command-palette.js +7 -7
  37. package/dist/composed/command-palette.js.map +1 -1
  38. package/dist/composed/content-card.js +20 -20
  39. package/dist/composed/content-card.js.map +1 -1
  40. package/dist/composed/date-picker/index.js +4 -4
  41. package/dist/composed/date-picker/index.js.map +1 -1
  42. package/dist/composed/diff.d.ts +23 -2
  43. package/dist/composed/diff.d.ts.map +1 -1
  44. package/dist/composed/diff.js +341 -260
  45. package/dist/composed/diff.js.map +1 -1
  46. package/dist/composed/emoji-picker.js +3 -3
  47. package/dist/composed/emoji-picker.js.map +1 -1
  48. package/dist/composed/error-boundary.js +2 -2
  49. package/dist/composed/error-boundary.js.map +1 -1
  50. package/dist/composed/extensions/emoji-node.js +8 -7
  51. package/dist/composed/extensions/emoji-node.js.map +1 -1
  52. package/dist/composed/file-preview.js +1 -1
  53. package/dist/composed/file-preview.js.map +1 -1
  54. package/dist/composed/filter-bar.js +1 -1
  55. package/dist/composed/filter-bar.js.map +1 -1
  56. package/dist/composed/inline-edit.js +1 -1
  57. package/dist/composed/inline-edit.js.map +1 -1
  58. package/dist/composed/loading-skeleton.js +3 -3
  59. package/dist/composed/loading-skeleton.js.map +1 -1
  60. package/dist/composed/master-detail.js +1 -1
  61. package/dist/composed/master-detail.js.map +1 -1
  62. package/dist/composed/member-picker.js +1 -1
  63. package/dist/composed/member-picker.js.map +1 -1
  64. package/dist/composed/multi-select-popover.js +1 -1
  65. package/dist/composed/multi-select-popover.js.map +1 -1
  66. package/dist/composed/page-skeletons.js +4 -4
  67. package/dist/composed/page-skeletons.js.map +1 -1
  68. package/dist/composed/responsive-modal.js +1 -1
  69. package/dist/composed/responsive-modal.js.map +1 -1
  70. package/dist/composed/rich-chat-input.js +549 -540
  71. package/dist/composed/rich-chat-input.js.map +1 -1
  72. package/dist/composed/rich-text-editor.js +206 -198
  73. package/dist/composed/rich-text-editor.js.map +1 -1
  74. package/dist/composed/schedule-view.js +5 -5
  75. package/dist/composed/schedule-view.js.map +1 -1
  76. package/dist/hooks/index.d.ts +1 -0
  77. package/dist/hooks/index.d.ts.map +1 -1
  78. package/dist/hooks/index.js +4 -3
  79. package/dist/hooks/use-container-size.d.ts +18 -0
  80. package/dist/hooks/use-container-size.d.ts.map +1 -0
  81. package/dist/hooks/use-container-size.js +28 -0
  82. package/dist/hooks/use-container-size.js.map +1 -0
  83. package/dist/shell/app-shell.d.ts +101 -0
  84. package/dist/shell/app-shell.d.ts.map +1 -0
  85. package/dist/shell/app-shell.js +76 -0
  86. package/dist/shell/app-shell.js.map +1 -0
  87. package/dist/shell/bottom-navbar.js +2 -2
  88. package/dist/shell/bottom-navbar.js.map +1 -1
  89. package/dist/shell/index.d.ts +1 -0
  90. package/dist/shell/index.d.ts.map +1 -1
  91. package/dist/shell/index.js +6 -5
  92. package/dist/shell/notification-center.js +4 -4
  93. package/dist/shell/notification-center.js.map +1 -1
  94. package/dist/shell/notification-preferences.js +1 -1
  95. package/dist/shell/notification-preferences.js.map +1 -1
  96. package/dist/shell/top-bar.js +7 -7
  97. package/dist/shell/top-bar.js.map +1 -1
  98. package/dist/tokens/generate-scale.d.ts +49 -0
  99. package/dist/tokens/generate-scale.d.ts.map +1 -1
  100. package/dist/tokens/primitives.css +29 -26
  101. package/dist/tokens/semantic.css +98 -39
  102. package/dist/tokens/variants.css +1 -1
  103. package/dist/ui/accordion.js +1 -1
  104. package/dist/ui/accordion.js.map +1 -1
  105. package/dist/ui/alert-dialog.js +1 -1
  106. package/dist/ui/alert-dialog.js.map +1 -1
  107. package/dist/ui/alert.d.ts.map +1 -1
  108. package/dist/ui/alert.js +36 -36
  109. package/dist/ui/alert.js.map +1 -1
  110. package/dist/ui/avatar.js +44 -44
  111. package/dist/ui/avatar.js.map +1 -1
  112. package/dist/ui/badge-indicator.js +1 -1
  113. package/dist/ui/badge-indicator.js.map +1 -1
  114. package/dist/ui/badge.d.ts +47 -33
  115. package/dist/ui/badge.d.ts.map +1 -1
  116. package/dist/ui/banner.js +26 -26
  117. package/dist/ui/banner.js.map +1 -1
  118. package/dist/ui/button.js +35 -35
  119. package/dist/ui/button.js.map +1 -1
  120. package/dist/ui/card.js +42 -42
  121. package/dist/ui/card.js.map +1 -1
  122. package/dist/ui/chat/date-separator.d.ts +8 -1
  123. package/dist/ui/chat/date-separator.d.ts.map +1 -1
  124. package/dist/ui/checkbox.js +1 -1
  125. package/dist/ui/checkbox.js.map +1 -1
  126. package/dist/ui/code.js +2 -2
  127. package/dist/ui/code.js.map +1 -1
  128. package/dist/ui/color-input.js +3 -3
  129. package/dist/ui/color-input.js.map +1 -1
  130. package/dist/ui/combobox.js +139 -139
  131. package/dist/ui/combobox.js.map +1 -1
  132. package/dist/ui/context-menu.js +4 -4
  133. package/dist/ui/context-menu.js.map +1 -1
  134. package/dist/ui/data-table-body.d.ts +3 -1
  135. package/dist/ui/data-table-body.d.ts.map +1 -1
  136. package/dist/ui/data-table-body.js +93 -92
  137. package/dist/ui/data-table-body.js.map +1 -1
  138. package/dist/ui/data-table-bulk-actions.d.ts +7 -1
  139. package/dist/ui/data-table-bulk-actions.d.ts.map +1 -1
  140. package/dist/ui/data-table-bulk-actions.js +14 -8
  141. package/dist/ui/data-table-bulk-actions.js.map +1 -1
  142. package/dist/ui/data-table-card.d.ts.map +1 -1
  143. package/dist/ui/data-table-card.js +66 -47
  144. package/dist/ui/data-table-card.js.map +1 -1
  145. package/dist/ui/data-table-context.d.ts +4 -0
  146. package/dist/ui/data-table-context.d.ts.map +1 -1
  147. package/dist/ui/data-table-context.js.map +1 -1
  148. package/dist/ui/data-table-header.d.ts.map +1 -1
  149. package/dist/ui/data-table-header.js +18 -15
  150. package/dist/ui/data-table-header.js.map +1 -1
  151. package/dist/ui/data-table-pagination.js +3 -3
  152. package/dist/ui/data-table-pagination.js.map +1 -1
  153. package/dist/ui/data-table-toolbar.d.ts +11 -1
  154. package/dist/ui/data-table-toolbar.d.ts.map +1 -1
  155. package/dist/ui/data-table-toolbar.js +7 -7
  156. package/dist/ui/data-table-toolbar.js.map +1 -1
  157. package/dist/ui/data-table.d.ts +52 -5
  158. package/dist/ui/data-table.d.ts.map +1 -1
  159. package/dist/ui/data-table.js +181 -169
  160. package/dist/ui/data-table.js.map +1 -1
  161. package/dist/ui/dialog.js +1 -1
  162. package/dist/ui/dialog.js.map +1 -1
  163. package/dist/ui/dot.js +13 -13
  164. package/dist/ui/dot.js.map +1 -1
  165. package/dist/ui/dropdown-menu.js +4 -4
  166. package/dist/ui/dropdown-menu.js.map +1 -1
  167. package/dist/ui/file-upload.js +3 -3
  168. package/dist/ui/file-upload.js.map +1 -1
  169. package/dist/ui/input-otp.js +1 -1
  170. package/dist/ui/input-otp.js.map +1 -1
  171. package/dist/ui/input.js +30 -30
  172. package/dist/ui/input.js.map +1 -1
  173. package/dist/ui/lib/utils.js +2 -1
  174. package/dist/ui/lib/utils.js.map +1 -1
  175. package/dist/ui/menubar.js +5 -5
  176. package/dist/ui/menubar.js.map +1 -1
  177. package/dist/ui/navigation-menu.js +1 -1
  178. package/dist/ui/navigation-menu.js.map +1 -1
  179. package/dist/ui/number-input.js +36 -36
  180. package/dist/ui/number-input.js.map +1 -1
  181. package/dist/ui/pagination.js +1 -1
  182. package/dist/ui/pagination.js.map +1 -1
  183. package/dist/ui/progress-ring.js +2 -2
  184. package/dist/ui/progress-ring.js.map +1 -1
  185. package/dist/ui/progress.d.ts.map +1 -1
  186. package/dist/ui/progress.js +66 -62
  187. package/dist/ui/progress.js.map +1 -1
  188. package/dist/ui/radio.js +1 -1
  189. package/dist/ui/radio.js.map +1 -1
  190. package/dist/ui/select.js +61 -61
  191. package/dist/ui/select.js.map +1 -1
  192. package/dist/ui/sheet.js +47 -47
  193. package/dist/ui/sheet.js.map +1 -1
  194. package/dist/ui/sidebar.js +132 -132
  195. package/dist/ui/sidebar.js.map +1 -1
  196. package/dist/ui/skeleton.js +39 -39
  197. package/dist/ui/slider.js +18 -18
  198. package/dist/ui/slider.js.map +1 -1
  199. package/dist/ui/split-button.js +3 -3
  200. package/dist/ui/split-button.js.map +1 -1
  201. package/dist/ui/stat-card.js +1 -1
  202. package/dist/ui/stat-card.js.map +1 -1
  203. package/dist/ui/stepper.js +2 -2
  204. package/dist/ui/stepper.js.map +1 -1
  205. package/dist/ui/surface.d.ts.map +1 -1
  206. package/dist/ui/surface.js +11 -11
  207. package/dist/ui/surface.js.map +1 -1
  208. package/dist/ui/switch.js +1 -1
  209. package/dist/ui/switch.js.map +1 -1
  210. package/dist/ui/table.js +1 -1
  211. package/dist/ui/table.js.map +1 -1
  212. package/dist/ui/tabs.d.ts.map +1 -1
  213. package/dist/ui/tabs.js +48 -48
  214. package/dist/ui/tabs.js.map +1 -1
  215. package/dist/ui/text.js +8 -8
  216. package/dist/ui/textarea.js +17 -17
  217. package/dist/ui/textarea.js.map +1 -1
  218. package/dist/ui/toast.js +1 -1
  219. package/dist/ui/toast.js.map +1 -1
  220. package/dist/ui/toggle.js +15 -15
  221. package/dist/ui/toggle.js.map +1 -1
  222. package/docs/components/composed/avatar-group.md +4 -4
  223. package/docs/components/composed/diff.md +10 -2
  224. package/docs/components/composed/schedule-view.md +1 -1
  225. package/docs/components/shell/app-shell.md +132 -0
  226. package/docs/components/ui/avatar.md +1 -1
  227. package/docs/components/ui/button.md +1 -1
  228. package/docs/components/ui/chat.md +7 -1
  229. package/docs/components/ui/color-swatch.md +1 -1
  230. package/docs/components/ui/data-table-toolbar.md +6 -2
  231. package/docs/components/ui/data-table.md +41 -7
  232. package/docs/components/ui/dot.md +1 -1
  233. package/docs/components/ui/progress.md +1 -0
  234. package/docs/components/ui/surface.md +3 -3
  235. package/docs/components/ui/table.md +2 -2
  236. package/docs/recipes/install-astro.md +3 -2
  237. package/docs/recipes/install-next-app-router.md +3 -2
  238. package/docs/recipes/install-remix.md +3 -2
  239. package/docs/recipes/install-tanstack-start.md +3 -2
  240. package/docs/recipes/install-vite.md +3 -2
  241. package/docs/recipes/troubleshoot.md +26 -5
  242. package/llms.txt +2 -1
  243. package/make-kit/Guidelines.md +2 -2
  244. package/make-kit/components/button.md +1 -1
  245. package/make-kit/components/card.md +6 -6
  246. package/make-kit/components/surface.md +4 -4
  247. package/make-kit/foundations/color.md +4 -4
  248. package/make-kit/foundations/dark-mode.md +1 -1
  249. package/make-kit/foundations/radius.md +1 -1
  250. package/make-kit/foundations/surfaces.md +9 -9
  251. package/mcp-manifest.json +373 -34
  252. package/package.json +43 -13
  253. package/skill/SKILL.md +12 -6
  254. package/skill/references/components.md +2 -1
  255. package/skill/references/setup-astro.md +3 -2
  256. package/skill/references/setup-next-app-router.md +3 -2
  257. package/skill/references/setup-remix.md +3 -2
  258. package/skill/references/setup-tanstack-start.md +3 -2
  259. package/skill/references/setup-vite.md +3 -2
  260. package/skill/references/troubleshoot.md +26 -5
  261. package/dist/_chunks/tiptap.js +0 -18809
  262. package/dist/_chunks/tiptap.js.map +0 -1
  263. package/dist/_chunks/vendor-utils.js +0 -1766
  264. package/dist/_chunks/vendor-utils.js.map +0 -1
  265. package/dist/primitives/react-toast.d.ts +0 -120
  266. package/dist/ui/charts/_internal/scales.d.ts +0 -5
  267. package/dist/ui/charts/_internal/scales.d.ts.map +0 -1
  268. package/dist/ui/lib/slot.d.ts +0 -8
  269. package/dist/ui/lib/slot.d.ts.map +0 -1
  270. package/scripts/welcome.mjs +0 -312
@@ -1,312 +0,0 @@
1
- #!/usr/bin/env node
2
- /**
3
- * Postinstall welcome banner for @devalok/shilp-sutra.
4
- *
5
- * Runs once per major.minor version on consumer install. Silent under CI,
6
- * non-TTY environments, NO_COLOR, npm silent loglevel, or when the
7
- * SHILP_SUTRA_NO_WELCOME env var is set. Falls back to a compact 6-line
8
- * text block if the terminal is narrower than 70 columns or shorter than
9
- * 28 rows. Never throws — wrapped in a try/catch so an internal error can
10
- * never break the consumer install.
11
- *
12
- * Safety guards (industry best practice — see research notes in
13
- * .changeset/wave-4-install-experience.md):
14
- *
15
- * - process.env.CI → silent (avoid log noise on CI)
16
- * - process.env.SHILP_SUTRA_NO_WELCOME=1 → silent (user opt-out)
17
- * - process.env.NO_COLOR → plain text, no ANSI
18
- * - process.stdout.isTTY === false → silent (piped builds, Docker)
19
- * - npm_config_loglevel === 'silent' → silent (respect pkg manager)
20
- * - !INIT_CWD || INIT_CWD inside the package → silent (dev install, not consumer)
21
- * - Sentinel file with current version → silent on re-install of same ver
22
- * - try/catch around everything → always exit 0
23
- *
24
- * The sentinel encodes the version (`node_modules/.shilp-sutra-welcomed`)
25
- * so version bumps re-fire the banner once.
26
- */
27
-
28
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs'
29
- import { dirname, join, resolve } from 'node:path'
30
- import { fileURLToPath } from 'node:url'
31
-
32
- const __dirname = dirname(fileURLToPath(import.meta.url))
33
- const PKG_DIR = resolve(__dirname, '..')
34
-
35
- // ── Guard rails — bail out early if any condition says "silent". ────────────
36
- function shouldSkip() {
37
- if (process.env.CI) return 'CI environment'
38
- if (process.env.SHILP_SUTRA_NO_WELCOME === '1' || process.env.SHILP_SUTRA_NO_WELCOME === 'true') return 'SHILP_SUTRA_NO_WELCOME set'
39
- if (process.env.npm_config_loglevel === 'silent') return 'npm silent loglevel'
40
- if (!process.stdout.isTTY) return 'not a TTY (piped/Docker/etc.)'
41
- // Dev install — we're inside the design-system repo itself, not a consumer
42
- const initCwd = process.env.INIT_CWD || process.cwd()
43
- const cwd = process.cwd()
44
- const isInsideNodeModules = cwd.includes(`${process.platform === 'win32' ? '\\' : '/'}node_modules${process.platform === 'win32' ? '\\' : '/'}`) || cwd.includes('/node_modules/')
45
- if (!isInsideNodeModules) return 'dev install (not running from node_modules/)'
46
- // INIT_CWD points at the consumer's project root. If absent → odd setup; skip.
47
- if (!initCwd || initCwd === cwd) return 'no INIT_CWD set (unusual install context)'
48
- return null
49
- }
50
-
51
- function readPkgVersion() {
52
- try {
53
- const pkg = JSON.parse(readFileSync(join(PKG_DIR, 'package.json'), 'utf-8'))
54
- return pkg.version
55
- } catch {
56
- return null
57
- }
58
- }
59
-
60
- // Sentinel: re-fire only on version change. Stored at the workspace root's
61
- // node_modules/.shilp-sutra-welcomed so it survives pnpm dedupe rebuilds.
62
- function getSentinelPath() {
63
- // Walk up from PKG_DIR (node_modules/@devalok/shilp-sutra/) to the
64
- // enclosing node_modules/ root, then write inside it.
65
- const parts = PKG_DIR.split(/[/\\]/)
66
- const nmIdx = parts.lastIndexOf('node_modules')
67
- if (nmIdx === -1) return null
68
- const nmRoot = parts.slice(0, nmIdx + 1).join(process.platform === 'win32' ? '\\' : '/')
69
- return join(nmRoot, '.shilp-sutra-welcomed')
70
- }
71
-
72
- function alreadyWelcomed(version) {
73
- const sentinel = getSentinelPath()
74
- if (!sentinel) return false
75
- try {
76
- if (!existsSync(sentinel)) return false
77
- const previousVersion = readFileSync(sentinel, 'utf-8').trim()
78
- return previousVersion === version
79
- } catch {
80
- return false
81
- }
82
- }
83
-
84
- // Returns the version recorded in the sentinel from a prior install, or null
85
- // on first install / unreadable sentinel. Used to detect a version JUMP so the
86
- // banner can point upgraders at MIGRATION.md.
87
- function getPreviousVersion() {
88
- const sentinel = getSentinelPath()
89
- if (!sentinel) return null
90
- try {
91
- if (!existsSync(sentinel)) return null
92
- const prev = readFileSync(sentinel, 'utf-8').trim()
93
- return prev || null
94
- } catch {
95
- return null
96
- }
97
- }
98
-
99
- function markWelcomed(version) {
100
- const sentinel = getSentinelPath()
101
- if (!sentinel) return
102
- try {
103
- mkdirSync(dirname(sentinel), { recursive: true })
104
- writeFileSync(sentinel, version + '\n')
105
- } catch {
106
- // ignored — banner already printed, sentinel write is best-effort
107
- }
108
- }
109
-
110
- // ── ANSI rendering ──────────────────────────────────────────────────────────
111
- const useColor = !process.env.NO_COLOR && process.stdout.isTTY
112
-
113
- // Devalok pink #d946a6 = RGB(217, 70, 166)
114
- const PINK = useColor ? '\x1b[38;2;217;70;166m' : ''
115
- const PINK_DIM = useColor ? '\x1b[38;2;167;55;128m' : ''
116
- const BOLD = useColor ? '\x1b[1m' : ''
117
- const DIM = useColor ? '\x1b[2m' : ''
118
- const RESET = useColor ? '\x1b[0m' : ''
119
-
120
- function colour(text, code) {
121
- return useColor ? `${code}${text}${RESET}` : text
122
- }
123
-
124
- // Lotus — 13 rows × 30 cols Braille. Centered in a 63-col inner box (16 left,
125
- // 17 right padding).
126
- const LOTUS = [
127
- '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣦⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀',
128
- '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣴⠟⠹⣧⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀',
129
- '⠀⠀⠀⠀⠀⠀⠀⠀⣷⣦⣄⣠⣿⠃⢠⣄⠈⢻⣆⣠⣴⡞⡆⠀⠀⠀⠀⠀⠀⠀',
130
- '⠀⠀⠀⠀⠀⢀⣀⣀⣿⠀⠈⢻⣇⢀⣾⢟⡄⣸⡿⠋⠀⡇⣇⣀⣀⠀⠀⠀⠀⠀',
131
- '⠀⣤⣤⣤⣀⣱⢻⠚⠻⣧⣀⠀⢹⡿⠃⠈⢻⣟⠀⢀⣤⠧⠓⣹⣟⣀⣤⣤⣤⡀',
132
- '⠀⠈⠻⣧⠉⠛⣽⠀⠀⠀⠙⣷⡿⠁⠀⠀⠀⢻⣶⠛⠁⠀⠀⡟⠟⠉⣵⡟⠁⠀',
133
- '⠀⠀⠀⠹⣧⡀⠏⡇⠀⠀⠀⣿⠁⠀⠀⠀⠀⠀⣿⡄⠀⠀⢠⢷⠀⣼⡟⠀⠀⠀',
134
- '⠀⠀⠀⠀⠙⣟⢼⡹⡄⠀⠀⣿⡄⠀⠀⠀⠀⢀⣿⡇⠀⢀⣞⣦⢾⠟⠀⠀⠀⠀',
135
- '⠀⠠⢶⣿⣛⠛⢒⣭⢻⣶⣤⣹⣿⣤⣀⣀⣠⣾⣟⣠⣔⡛⢫⣐⠛⢛⣻⣶⠆⠀',
136
- '⠀⠀⠀⠉⣻⡽⠛⠉⠁⠀⠉⢙⣿⠖⠒⠛⠻⣿⡋⠉⠁⠈⠉⠙⢿⣿⠉⠀⠀⠀',
137
- '⠀⠀⠀⠸⠿⠷⠒⣦⣤⣴⣶⢿⣿⡀⠀⠀⠀⣽⡿⢷⣦⠤⢤⡖⠶⠿⠧⠀⠀⠀',
138
- '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠛⢿⣦⣴⡾⠟⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀',
139
- '⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⠟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀',
140
- ]
141
-
142
- const TOP = '╭───────────────────────────────────────────────────────────────╮'
143
- const BOTTOM = '╰───────────────────────────────────────────────────────────────╯'
144
- const EMPTY = '│ │'
145
- const INNER_WIDTH = 63
146
-
147
- function row(content) {
148
- // content is a string of visible chars (ANSI-stripped width assumed equal to char count for ASCII)
149
- // We can't easily measure visible width when ANSI codes are present, so always pad based on the
150
- // PASSED visibleWidth in callers that contain colour. For plain rows, fall back to .length.
151
- const visible = content.replace(/\x1b\[[0-9;]*m/g, '')
152
- const padLen = Math.max(0, INNER_WIDTH - visible.length)
153
- return `│${content}${' '.repeat(padLen)}│`
154
- }
155
-
156
- function centeredLotusRow(braille) {
157
- // 30-col Braille row, 16-left + 17-right padding
158
- return `│ ${colour(braille, PINK)} │`
159
- }
160
-
161
- function buildFullBanner(version, prevVersion) {
162
- const lines = []
163
- lines.push(colour(TOP, PINK_DIM))
164
- lines.push(colour(EMPTY, PINK_DIM))
165
- for (const lotusRow of LOTUS) {
166
- lines.push(`${colour('│', PINK_DIM)} ${colour(lotusRow, PINK)} ${colour('│', PINK_DIM)}`)
167
- }
168
- lines.push(colour(EMPTY, PINK_DIM))
169
- if (prevVersion && prevVersion !== version) {
170
- lines.push(row(` ${colour('✦', PINK)} ${colour('@devalok/shilp-sutra', BOLD)} ${prevVersion} → ${version}`))
171
- lines.push(row(` ${colour('⚠', PINK)} ${colour('Version changed — review breaking changes before deploy:', BOLD)}`))
172
- lines.push(row(` ${colour('node_modules/@devalok/shilp-sutra/MIGRATION.md', DIM)}`))
173
- lines.push(row(` ${colour('+ docs/recipes/upgrading.md (safe-upgrade procedure)', DIM)}`))
174
- } else {
175
- lines.push(row(` ${colour('✦', PINK)} ${colour('@devalok/shilp-sutra', BOLD)} ${version}`))
176
- lines.push(row(` ${colour('Tailwind 4 design system · 120+ components · RSC-safe', DIM)}`))
177
- }
178
- lines.push(colour(EMPTY, PINK_DIM))
179
- lines.push(row(` ${colour('▸', PINK)} Setup recipe (pick your framework):`))
180
- lines.push(row(` ${colour('node_modules/@devalok/shilp-sutra/docs/recipes/', DIM)}`))
181
- lines.push(colour(EMPTY, PINK_DIM))
182
- lines.push(row(` ${colour('▸', PINK)} Theme it in 30 seconds:`))
183
- lines.push(row(` ${colour('https://shilp-sutra.devalok.in/themer', DIM)}`))
184
- lines.push(colour(EMPTY, PINK_DIM))
185
- lines.push(row(` ${colour('▸', PINK)} Wire your AI agent (Claude Code / Cursor / Codex):`))
186
- lines.push(row(` ${colour('live docs MCP added to .mcp.json — approve it to enable', DIM)}`))
187
- lines.push(row(` ${colour('(version-exact setup + peer preflight; beats guessing)', DIM)}`))
188
- lines.push(row(` ${colour('or copy the skill: cp -r node_modules/@devalok/shilp-sutra/skill \\', DIM)}`))
189
- lines.push(row(` ${colour('~/.claude/skills/shilp-sutra', DIM)}`))
190
- lines.push(colour(EMPTY, PINK_DIM))
191
- lines.push(row(` ${colour('Disable this banner: SHILP_SUTRA_NO_WELCOME=1', DIM)}`))
192
- lines.push(colour(EMPTY, PINK_DIM))
193
- lines.push(row(` ${colour('Built by Devalok · devalok.in', PINK)}`))
194
- lines.push(colour(EMPTY, PINK_DIM))
195
- lines.push(colour(BOTTOM, PINK_DIM))
196
- return lines.join('\n')
197
- }
198
-
199
- function buildCompactBanner(version, prevVersion) {
200
- const head =
201
- prevVersion && prevVersion !== version
202
- ? [
203
- `${colour('✦', PINK)} ${colour('@devalok/shilp-sutra', BOLD)} ${prevVersion} → ${version}`,
204
- ` ${colour('⚠', PINK)} Version changed — review ${colour('node_modules/@devalok/shilp-sutra/MIGRATION.md', DIM)} before deploy`,
205
- ]
206
- : [`${colour('✦', PINK)} ${colour('@devalok/shilp-sutra', BOLD)} ${version} ${colour('· Tailwind 4 design system', DIM)}`]
207
- return [
208
- '',
209
- ...head,
210
- ` ${colour('▸', PINK)} Setup: ${colour('node_modules/@devalok/shilp-sutra/docs/recipes/', DIM)}`,
211
- ` ${colour('▸', PINK)} Theme: ${colour('https://shilp-sutra.devalok.in/themer', DIM)}`,
212
- ` ${colour('▸', PINK)} AI: ${colour('cp -r node_modules/@devalok/shilp-sutra/skill ~/.claude/skills/shilp-sutra', DIM)}`,
213
- ` ${colour('Built by Devalok · devalok.in', PINK)} ${colour('(SHILP_SUTRA_NO_WELCOME=1 to disable)', DIM)}`,
214
- '',
215
- ].join('\n')
216
- }
217
-
218
- // ── MCP auto-discovery ───────────────────────────────────────────────────────
219
- // Write a project-scoped `.mcp.json` pointing at the hosted docs MCP so an AI
220
- // coding agent DISCOVERS it right after install. This runs even when stdout is
221
- // piped (unlike the banner) — a config file is not console noise, and the agent
222
- // that just ran `install` is exactly who should find it. It is never silent-
223
- // forced: Claude Code (and peers) still PROMPT the user to approve a project
224
- // MCP server before enabling it. Safety: additive merge (never clobbers other
225
- // servers or an existing shilp-sutra entry), skips CI and dev installs, honours
226
- // opt-out, and a write-once sentinel so a user who deletes it is not re-nagged.
227
- const SEP = process.platform === 'win32' ? '\\' : '/'
228
- const MCP_URL = 'https://shilp-sutra.devalok.in/mcp'
229
-
230
- function tryWriteMcpConfig() {
231
- try {
232
- if (process.env.SHILP_SUTRA_NO_WELCOME === '1' || process.env.SHILP_SUTRA_NO_WELCOME === 'true') return
233
- if (process.env.SHILP_SUTRA_NO_MCP === '1' || process.env.SHILP_SUTRA_NO_MCP === 'true') return
234
- if (process.env.CI) return // writing agent config into a CI checkout is pointless/unwanted
235
-
236
- const initCwd = process.env.INIT_CWD
237
- const cwd = process.cwd()
238
- const isInsideNodeModules = cwd.includes(`${SEP}node_modules${SEP}`) || cwd.includes('/node_modules/')
239
- if (!isInsideNodeModules) return // dev install inside the DS repo itself
240
- if (!initCwd || initCwd === cwd) return // no consumer root → unusual context
241
-
242
- // Write-once-ever sentinel (survives re-installs; respects user deletion of .mcp.json)
243
- const parts = PKG_DIR.split(/[/\\]/)
244
- const nmIdx = parts.lastIndexOf('node_modules')
245
- const sentinel = nmIdx === -1 ? null : join(parts.slice(0, nmIdx + 1).join(SEP), '.shilp-sutra-mcp-written')
246
- if (sentinel && existsSync(sentinel)) return
247
-
248
- const target = join(initCwd, '.mcp.json')
249
- let config = { mcpServers: {} }
250
- if (existsSync(target)) {
251
- try {
252
- config = JSON.parse(readFileSync(target, 'utf-8'))
253
- } catch {
254
- return // existing but unparseable — never clobber a hand-authored config
255
- }
256
- if (!config || typeof config !== 'object') return
257
- if (!config.mcpServers || typeof config.mcpServers !== 'object') config.mcpServers = {}
258
- if (config.mcpServers['shilp-sutra']) {
259
- if (sentinel) writeFileSync(sentinel, MCP_URL + '\n')
260
- return // already declared — leave the consumer's version untouched
261
- }
262
- }
263
- config.mcpServers['shilp-sutra'] = { type: 'http', url: MCP_URL }
264
- writeFileSync(target, JSON.stringify(config, null, 2) + '\n')
265
- if (sentinel) writeFileSync(sentinel, MCP_URL + '\n')
266
- } catch {
267
- // Never break the consumer install — a failed config write is a no-op.
268
- }
269
- }
270
-
271
- // ── Main ────────────────────────────────────────────────────────────────────
272
- function main() {
273
- // --preview / --compact bypass all guards. Used by maintainers + by the
274
- // pre-publish-audit gate to verify the banner renders without ever
275
- // shipping a broken one. Compose only — never writes the sentinel.
276
- const preview = process.argv.includes('--preview')
277
- const forceCompact = process.argv.includes('--compact')
278
-
279
- // MCP auto-discovery runs regardless of TTY — an agent-run (piped) install is
280
- // precisely when the agent should discover the docs MCP. Must come before the
281
- // TTY skip below, which only governs the human-facing banner.
282
- if (!preview) tryWriteMcpConfig()
283
-
284
- if (!preview) {
285
- const skipReason = shouldSkip()
286
- if (skipReason) return // silent
287
- }
288
-
289
- const version = readPkgVersion() || '0.0.0-preview'
290
-
291
- if (!preview && alreadyWelcomed(version)) return
292
-
293
- // Detect a version jump so the banner can route upgraders to MIGRATION.md.
294
- // --preview simulates an upgrade so maintainers can verify the upgrade layout.
295
- const prevVersion = preview ? '0.39.0' : getPreviousVersion()
296
-
297
- const cols = process.stdout.columns || 80
298
- const rows = process.stdout.rows || 40
299
- const fitsFull = !forceCompact && cols >= 70 && rows >= 28
300
-
301
- const banner = fitsFull ? buildFullBanner(version, prevVersion) : buildCompactBanner(version, prevVersion)
302
- process.stdout.write('\n' + banner + '\n')
303
-
304
- if (!preview) markWelcomed(version)
305
- }
306
-
307
- try {
308
- main()
309
- } catch {
310
- // Never crash the consumer install. A failure here is a UX bug, not a
311
- // blocker — pretend nothing happened.
312
- }