@codefast/cli 0.3.12 → 0.3.13-canary.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 (225) hide show
  1. package/README.md +206 -51
  2. package/dist/analyze-DvtJ3j9m.mjs +92 -0
  3. package/dist/arrange-Bbh62DrU.mjs +107 -0
  4. package/dist/arrange-BqP2DI3w.mjs +8 -0
  5. package/dist/ast-helpers-MDRYuIAk.mjs +115 -0
  6. package/dist/{bin.js → bin.mjs} +4 -1
  7. package/dist/caught-unknown-message-CRhkDWO7.mjs +20 -0
  8. package/dist/collectors-cn-BS8TTQ8O.mjs +61 -0
  9. package/dist/collectors-jsx-D9tL2ZPM.mjs +20 -0
  10. package/dist/collectors-tv-D2PXZaRt.mjs +170 -0
  11. package/dist/colors-BjdkCfGK.mjs +12 -0
  12. package/dist/commands/arrange.mjs +2 -0
  13. package/dist/commands/mirror.mjs +2 -0
  14. package/dist/commands/mirror.test.mjs +48 -0
  15. package/dist/commands/tag.mjs +2 -0
  16. package/dist/config-DVia_f9a.mjs +3 -0
  17. package/dist/config-reporter-SCcWDZc1.mjs +10 -0
  18. package/dist/constants-AtPhF-Ct.mjs +169 -0
  19. package/dist/constants-Bq5wdyLC.mjs +8 -0
  20. package/dist/dirent-list-BSDeRG5i.mjs +14 -0
  21. package/dist/engine-CcWEHSCq.mjs +287 -0
  22. package/dist/engine-DRTdkc5u.mjs +236 -0
  23. package/dist/errors-CFH4w6ic.mjs +15 -0
  24. package/dist/errors-CpU1ogfA.mjs +19 -0
  25. package/dist/formatters-DGE8jJ53.mjs +52 -0
  26. package/dist/group-file-ClW7XdD6.mjs +113 -0
  27. package/dist/grouping-c1grpCQT.mjs +235 -0
  28. package/dist/imports-DSVq1xhB.mjs +54 -0
  29. package/dist/lib/arrange/application/analyze.mjs +2 -0
  30. package/dist/lib/arrange/application/analyze.test.mjs +171 -0
  31. package/dist/lib/arrange/application/group-file.mjs +2 -0
  32. package/dist/lib/arrange/application/group-file.test.mjs +273 -0
  33. package/dist/lib/arrange/application/run-target.mjs +2 -0
  34. package/dist/lib/arrange/application/run-target.test.mjs +97 -0
  35. package/dist/lib/arrange/domain/ast/ast-helpers.mjs +2 -0
  36. package/dist/lib/arrange/domain/ast/ast-helpers.test.mjs +148 -0
  37. package/dist/lib/arrange/domain/ast/collectors-cn.mjs +2 -0
  38. package/dist/lib/arrange/domain/ast/collectors-cn.test.mjs +58 -0
  39. package/dist/lib/arrange/domain/ast/collectors-jsx.mjs +2 -0
  40. package/dist/lib/arrange/domain/ast/collectors-jsx.test.mjs +20 -0
  41. package/dist/lib/arrange/domain/ast/collectors-tv.mjs +2 -0
  42. package/dist/lib/arrange/domain/ast/collectors-tv.test.mjs +145 -0
  43. package/dist/lib/arrange/domain/ast/targets.mjs +2 -0
  44. package/dist/lib/arrange/domain/ast/targets.test.mjs +50 -0
  45. package/dist/lib/arrange/domain/constants.mjs +2 -0
  46. package/dist/lib/arrange/domain/errors.mjs +2 -0
  47. package/dist/lib/arrange/domain/grouping.mjs +2 -0
  48. package/dist/lib/arrange/domain/grouping.test.mjs +186 -0
  49. package/dist/lib/arrange/domain/imports.mjs +2 -0
  50. package/dist/lib/arrange/domain/imports.test.mjs +48 -0
  51. package/dist/lib/arrange/domain/tokenizer.mjs +2 -0
  52. package/dist/lib/arrange/domain/tokenizer.test.mjs +165 -0
  53. package/dist/lib/arrange/index.mjs +16 -0
  54. package/dist/lib/arrange/infra/walk.mjs +2 -0
  55. package/dist/lib/arrange/infra/walk.test.mjs +50 -0
  56. package/dist/lib/arrange/presentation/formatters.mjs +2 -0
  57. package/dist/lib/arrange/presentation/formatters.test.mjs +73 -0
  58. package/dist/lib/arrange/presentation/report.mjs +2 -0
  59. package/dist/lib/config/domain/schema.mjs +2 -0
  60. package/dist/lib/config/index.mjs +4 -0
  61. package/dist/lib/config/infra/loader.mjs +2 -0
  62. package/dist/lib/config/infra/loader.test.mjs +116 -0
  63. package/dist/lib/infra/caught-unknown-message.mjs +2 -0
  64. package/dist/lib/infra/config-reporter.mjs +2 -0
  65. package/dist/lib/infra/node-io.mjs +2 -0
  66. package/dist/lib/infra/workspace/repo-root.mjs +2 -0
  67. package/dist/lib/infra/workspace/repo-root.test.mjs +45 -0
  68. package/dist/lib/mirror/application/engine.mjs +2 -0
  69. package/dist/lib/mirror/application/sync.mjs +2 -0
  70. package/dist/lib/mirror/application/sync.test.mjs +482 -0
  71. package/dist/lib/mirror/domain/constants.mjs +2 -0
  72. package/dist/lib/mirror/domain/errors.mjs +2 -0
  73. package/dist/lib/mirror/domain/types.mjs +1 -0
  74. package/dist/lib/mirror/index.mjs +3 -0
  75. package/dist/lib/mirror/infra/dirent-list.mjs +2 -0
  76. package/dist/lib/mirror/infra/dirent-list.test.mjs +18 -0
  77. package/dist/lib/mirror/infra/package-filter.mjs +2 -0
  78. package/dist/lib/mirror/infra/package-filter.test.mjs +32 -0
  79. package/dist/lib/mirror/infra/path-normalizer.mjs +2 -0
  80. package/dist/lib/mirror/infra/update-pkg.mjs +2 -0
  81. package/dist/lib/mirror/infra/workspace-packages.mjs +2 -0
  82. package/dist/lib/mirror/infra/workspace-packages.test.mjs +167 -0
  83. package/dist/lib/mirror/presentation/reporter.mjs +2 -0
  84. package/dist/lib/tag/application/engine.mjs +2 -0
  85. package/dist/lib/tag/application/engine.test.mjs +159 -0
  86. package/dist/lib/tag/domain/types.mjs +1 -0
  87. package/dist/lib/tag/index.mjs +5 -0
  88. package/dist/lib/tag/infra/target-resolver.mjs +2 -0
  89. package/dist/lib/tag/presentation/colors.mjs +2 -0
  90. package/dist/lib/tag/presentation/tag-presenter.mjs +2 -0
  91. package/dist/lib/tag/presentation/tag-presenter.test.mjs +29 -0
  92. package/dist/loader-DpN-zl5g.mjs +78 -0
  93. package/dist/mirror-CbGiLXKT.mjs +2 -0
  94. package/dist/mirror-DqJE3ejL.mjs +66 -0
  95. package/dist/node-io-DFRbHO6m.mjs +30 -0
  96. package/dist/package-filter-C_8ryqvz.mjs +26 -0
  97. package/dist/path-normalizer-D4ceBO3l.mjs +7 -0
  98. package/dist/program-DR-H4tH3.mjs +34 -0
  99. package/dist/program.mjs +2 -0
  100. package/dist/repo-root-HmtIEm6J.mjs +22 -0
  101. package/dist/report-DYxvw34T.mjs +24 -0
  102. package/dist/reporter-CwIe_tAM.mjs +108 -0
  103. package/dist/run-target-CJWrqNT4.mjs +65 -0
  104. package/dist/schema-Or8RAARd.mjs +25 -0
  105. package/dist/sync-e1Sp-shi.mjs +157 -0
  106. package/dist/tag-Cd9JujU5.mjs +2 -0
  107. package/dist/tag-hEKVZ_-7.mjs +58 -0
  108. package/dist/tag-presenter-Cs66UBsH.mjs +63 -0
  109. package/dist/target-resolver-CR3FXMTy.mjs +170 -0
  110. package/dist/targets-pCTslnFh.mjs +106 -0
  111. package/dist/tokenizer-CeZx73Zu.mjs +216 -0
  112. package/dist/update-pkg-CnGfjWBy.mjs +37 -0
  113. package/dist/walk-DjgQn66n.mjs +33 -0
  114. package/dist/workspace-packages-K2NYTHJq.mjs +159 -0
  115. package/package.json +11 -11
  116. package/dist/bin.d.ts +0 -3
  117. package/dist/bin.d.ts.map +0 -1
  118. package/dist/commands/arrange.d.ts +0 -3
  119. package/dist/commands/arrange.d.ts.map +0 -1
  120. package/dist/commands/arrange.js +0 -114
  121. package/dist/commands/mirror.d.ts +0 -4
  122. package/dist/commands/mirror.d.ts.map +0 -1
  123. package/dist/commands/mirror.js +0 -63
  124. package/dist/lib/arrange/analyze.d.ts +0 -4
  125. package/dist/lib/arrange/analyze.d.ts.map +0 -1
  126. package/dist/lib/arrange/analyze.js +0 -105
  127. package/dist/lib/arrange/ast/collectors-cn.d.ts +0 -10
  128. package/dist/lib/arrange/ast/collectors-cn.d.ts.map +0 -1
  129. package/dist/lib/arrange/ast/collectors-cn.js +0 -84
  130. package/dist/lib/arrange/ast/collectors-jsx.d.ts +0 -4
  131. package/dist/lib/arrange/ast/collectors-jsx.d.ts.map +0 -1
  132. package/dist/lib/arrange/ast/collectors-jsx.js +0 -18
  133. package/dist/lib/arrange/ast/collectors-tv.d.ts +0 -13
  134. package/dist/lib/arrange/ast/collectors-tv.d.ts.map +0 -1
  135. package/dist/lib/arrange/ast/collectors-tv.js +0 -273
  136. package/dist/lib/arrange/ast/targets.d.ts +0 -8
  137. package/dist/lib/arrange/ast/targets.d.ts.map +0 -1
  138. package/dist/lib/arrange/ast/targets.js +0 -143
  139. package/dist/lib/arrange/ast/utils.d.ts +0 -36
  140. package/dist/lib/arrange/ast/utils.d.ts.map +0 -1
  141. package/dist/lib/arrange/ast/utils.js +0 -138
  142. package/dist/lib/arrange/constants.d.ts +0 -68
  143. package/dist/lib/arrange/constants.d.ts.map +0 -1
  144. package/dist/lib/arrange/constants.js +0 -179
  145. package/dist/lib/arrange/errors.d.ts +0 -14
  146. package/dist/lib/arrange/errors.d.ts.map +0 -1
  147. package/dist/lib/arrange/errors.js +0 -16
  148. package/dist/lib/arrange/formatters.d.ts +0 -16
  149. package/dist/lib/arrange/formatters.d.ts.map +0 -1
  150. package/dist/lib/arrange/formatters.js +0 -57
  151. package/dist/lib/arrange/group-file.d.ts +0 -4
  152. package/dist/lib/arrange/group-file.d.ts.map +0 -1
  153. package/dist/lib/arrange/group-file.js +0 -115
  154. package/dist/lib/arrange/grouping.d.ts +0 -41
  155. package/dist/lib/arrange/grouping.d.ts.map +0 -1
  156. package/dist/lib/arrange/grouping.js +0 -280
  157. package/dist/lib/arrange/imports.d.ts +0 -6
  158. package/dist/lib/arrange/imports.d.ts.map +0 -1
  159. package/dist/lib/arrange/imports.js +0 -74
  160. package/dist/lib/arrange/report.d.ts +0 -4
  161. package/dist/lib/arrange/report.d.ts.map +0 -1
  162. package/dist/lib/arrange/report.js +0 -37
  163. package/dist/lib/arrange/run-target.d.ts +0 -4
  164. package/dist/lib/arrange/run-target.d.ts.map +0 -1
  165. package/dist/lib/arrange/run-target.js +0 -28
  166. package/dist/lib/arrange/tokenizer.d.ts +0 -37
  167. package/dist/lib/arrange/tokenizer.d.ts.map +0 -1
  168. package/dist/lib/arrange/tokenizer.js +0 -390
  169. package/dist/lib/arrange/types.d.ts +0 -104
  170. package/dist/lib/arrange/types.d.ts.map +0 -1
  171. package/dist/lib/arrange/types.js +0 -7
  172. package/dist/lib/arrange/walk.d.ts +0 -4
  173. package/dist/lib/arrange/walk.d.ts.map +0 -1
  174. package/dist/lib/arrange/walk.js +0 -34
  175. package/dist/lib/arrange.d.ts +0 -41
  176. package/dist/lib/arrange.d.ts.map +0 -1
  177. package/dist/lib/arrange.js +0 -38
  178. package/dist/lib/infra/fs-contract.d.ts +0 -28
  179. package/dist/lib/infra/fs-contract.d.ts.map +0 -1
  180. package/dist/lib/infra/node-io.d.ts +0 -4
  181. package/dist/lib/infra/node-io.d.ts.map +0 -1
  182. package/dist/lib/infra/node-io.js +0 -27
  183. package/dist/lib/mirror/config.d.ts +0 -7
  184. package/dist/lib/mirror/config.d.ts.map +0 -1
  185. package/dist/lib/mirror/config.js +0 -146
  186. package/dist/lib/mirror/constants.d.ts +0 -10
  187. package/dist/lib/mirror/constants.d.ts.map +0 -1
  188. package/dist/lib/mirror/constants.js +0 -13
  189. package/dist/lib/mirror/engine.d.ts +0 -12
  190. package/dist/lib/mirror/engine.d.ts.map +0 -1
  191. package/dist/lib/mirror/engine.js +0 -248
  192. package/dist/lib/mirror/errors.d.ts +0 -10
  193. package/dist/lib/mirror/errors.d.ts.map +0 -1
  194. package/dist/lib/mirror/errors.js +0 -12
  195. package/dist/lib/mirror/package-filter.d.ts +0 -8
  196. package/dist/lib/mirror/package-filter.d.ts.map +0 -1
  197. package/dist/lib/mirror/package-filter.js +0 -33
  198. package/dist/lib/mirror/reporter.d.ts +0 -24
  199. package/dist/lib/mirror/reporter.d.ts.map +0 -1
  200. package/dist/lib/mirror/reporter.js +0 -126
  201. package/dist/lib/mirror/sync.d.ts +0 -4
  202. package/dist/lib/mirror/sync.d.ts.map +0 -1
  203. package/dist/lib/mirror/sync.js +0 -135
  204. package/dist/lib/mirror/types.d.ts +0 -81
  205. package/dist/lib/mirror/types.d.ts.map +0 -1
  206. package/dist/lib/mirror/update-pkg.d.ts +0 -13
  207. package/dist/lib/mirror/update-pkg.d.ts.map +0 -1
  208. package/dist/lib/mirror/update-pkg.js +0 -39
  209. package/dist/lib/mirror/workspace-packages.d.ts +0 -26
  210. package/dist/lib/mirror/workspace-packages.d.ts.map +0 -1
  211. package/dist/lib/mirror/workspace-packages.js +0 -160
  212. package/dist/lib/mirror.d.ts +0 -7
  213. package/dist/lib/mirror.d.ts.map +0 -1
  214. package/dist/lib/mirror.js +0 -5
  215. package/dist/lib/repo-root.d.ts +0 -7
  216. package/dist/lib/repo-root.d.ts.map +0 -1
  217. package/dist/lib/repo-root.js +0 -23
  218. package/dist/lib/shared/utils.d.ts +0 -9
  219. package/dist/lib/shared/utils.d.ts.map +0 -1
  220. package/dist/lib/shared/utils.js +0 -12
  221. package/dist/program.d.ts +0 -4
  222. package/dist/program.d.ts.map +0 -1
  223. package/dist/program.js +0 -38
  224. /package/dist/lib/{infra/fs-contract.js → arrange/domain/types.mjs} +0 -0
  225. /package/dist/lib/{mirror/types.js → infra/fs-contract.mjs} +0 -0
@@ -1,390 +0,0 @@
1
- import { COMPATIBLE_BUCKET_SETS, MAX_STRIP_VARIANT_PASSES, RESPONSIVE_PREFIX, STATE_PREFIXES, } from "#lib/arrange/constants";
2
- /**
3
- * Variant stems not covered by a single entry in STATE_PREFIXES (compound `has-*`,
4
- * numbered `nth-*`, media features, v4 `in-[…]`, child selectors `*` / `**`, …).
5
- * When these are missed, `isStateToken` is false and the variant is stripped — the
6
- * utility is then bucketed as if it were unconditional, which breaks preview grouping.
7
- */
8
- function isCompoundOrMediaVariantPrefix(prefix) {
9
- if (prefix === "*" || prefix === "**")
10
- return true;
11
- if (prefix === "inert")
12
- return true;
13
- if (prefix.startsWith("has-"))
14
- return true;
15
- if (prefix.startsWith("in-["))
16
- return true;
17
- if (/^nth(?:-last)?(?:-of-type)?(?:-\d+|-\[)/.test(prefix) ||
18
- /^nth-of-type-\d+$/.test(prefix) ||
19
- /^nth-last-of-type-\d+$/.test(prefix)) {
20
- return true;
21
- }
22
- if (/^(?:user-valid|user-invalid|contrast-more|contrast-less|forced-colors|inverted-colors)$/.test(prefix)) {
23
- return true;
24
- }
25
- if (/^(?:any-)?pointer-(?:fine|coarse|none)$/.test(prefix))
26
- return true;
27
- if (/^(?:portrait|landscape|noscript)$/.test(prefix))
28
- return true;
29
- return false;
30
- }
31
- export function tokenizeClassString(classString) {
32
- return classString.trim().split(/\s+/).filter(Boolean);
33
- }
34
- /**
35
- * Index of the first `:` that separates a Tailwind variant segment from the rest.
36
- * Colons inside `[...]` (at positive bracket depth) are ignored so selectors like
37
- * `[&_a:hover]:text-red-500` split as `[&_a:hover]:` + `text-red-500`.
38
- */
39
- export function indexOfFirstVariantColon(text) {
40
- let depth = 0;
41
- for (let i = 0; i < text.length; i++) {
42
- const ch = text[i];
43
- if (ch === "[") {
44
- depth++;
45
- }
46
- else if (ch === "]") {
47
- depth = Math.max(0, depth - 1);
48
- }
49
- else if (ch === ":" && depth === 0) {
50
- return i;
51
- }
52
- }
53
- return -1;
54
- }
55
- // Strip all variant prefixes to get the bare utility name.
56
- // e.g. "hover:dark:md:text-sm" → "text-sm"
57
- // e.g. "@min-[600px]:flex" → "flex"
58
- // e.g. "[&_a:hover]:text-red-500" → "text-red-500"
59
- export function stripVariants(token) {
60
- let withoutVariants = token;
61
- const MAX_PASSES = MAX_STRIP_VARIANT_PASSES;
62
- for (let i = 0; i < MAX_PASSES; i++) {
63
- const colonIdx = indexOfFirstVariantColon(withoutVariants);
64
- if (colonIdx === -1)
65
- break;
66
- withoutVariants = withoutVariants.slice(colonIdx + 1);
67
- }
68
- return withoutVariants;
69
- }
70
- /** Outermost variant segment: first `:` at bracket depth 0 → text before it. */
71
- function firstLeadingVariantPrefix(token) {
72
- const colonIdx = indexOfFirstVariantColon(token);
73
- if (colonIdx === -1)
74
- return undefined;
75
- return token.slice(0, colonIdx);
76
- }
77
- function isStateToken(token) {
78
- const prefix = firstLeadingVariantPrefix(token);
79
- if (prefix === undefined)
80
- return false;
81
- if (RESPONSIVE_PREFIX.test(token))
82
- return true;
83
- if (STATE_PREFIXES.has(prefix))
84
- return true;
85
- if (prefix.startsWith("data-["))
86
- return true;
87
- if (prefix.startsWith("aria-["))
88
- return true;
89
- if (prefix.startsWith("supports-["))
90
- return true;
91
- // Tailwind v4: style when inside an ancestor with matching `data-*` (e.g. `in-data-side-left:`,
92
- // `in-data-[slot=tooltip-content]:`). The short stem `in` is in STATE_PREFIXES but outer
93
- // prefixes are `in-data-…`, so they must be recognized explicitly.
94
- if (prefix.startsWith("in-data-"))
95
- return true;
96
- if (/^data-(?!\[)/.test(prefix))
97
- return true;
98
- if (/^aria-/.test(prefix))
99
- return true;
100
- if (/^(group|peer)-/.test(prefix))
101
- return true;
102
- if (/^not-/.test(prefix))
103
- return true;
104
- if (isCompoundOrMediaVariantPrefix(prefix))
105
- return true;
106
- if (prefix.startsWith("[") && prefix.endsWith("]")) {
107
- return true;
108
- }
109
- return false;
110
- }
111
- /**
112
- * Secondary sort inside the **composite** bucket: opacity / blend / isolation →
113
- * 3D context → 3D transforms → 2D transforms → filters → will-change.
114
- */
115
- export function compositeSecondaryOrder(bareUtility) {
116
- const b = bareUtility;
117
- if (/^opacity(?:-|$)/.test(b) ||
118
- /^mix-blend-/.test(b) ||
119
- /^isolation(?:-|$)/.test(b) ||
120
- b === "isolate") {
121
- return 0;
122
- }
123
- if (b === "transform-3d" || /^perspective(?:-|$)/.test(b)) {
124
- return 10;
125
- }
126
- if (/^rotate-[xyz](?:-|$)/.test(b) ||
127
- /^translate-z(?:-|$)/.test(b) ||
128
- /^scale-z(?:-|$)/.test(b)) {
129
- return 20;
130
- }
131
- if (/^translate(?:-|$)/.test(b) ||
132
- /^scale(?:-|$)/.test(b) ||
133
- /^rotate(?:-|$)/.test(b) ||
134
- /^skew(?:-|$)/.test(b)) {
135
- return 30;
136
- }
137
- if (/^transform(?:-(?:gpu|cpu|none))?$/.test(b)) {
138
- return 35;
139
- }
140
- if (/^blur(?:-|$)/.test(b) ||
141
- /^backdrop-/.test(b) ||
142
- /^filter(?:-|$)/.test(b) ||
143
- /^brightness-/.test(b) ||
144
- /^contrast-/.test(b) ||
145
- /^grayscale(?:-|$)/.test(b) ||
146
- /^hue-rotate-/.test(b) ||
147
- /^invert(?:-|$)/.test(b) ||
148
- /^saturate-/.test(b) ||
149
- /^sepia(?:-|$)/.test(b)) {
150
- return 40;
151
- }
152
- if (/^will-change/.test(b)) {
153
- return 50;
154
- }
155
- return 99;
156
- }
157
- /** Classify a **bare** utility (no `hover:` / `md:` / … prefixes). */
158
- export function classifyBareUtility(bareUtility) {
159
- const b = bareUtility;
160
- // --- Existence: display roots, containment, named groups/peers ---
161
- if (/^@container(?:\/[a-z][a-z0-9-]*)?$/i.test(b)) {
162
- return "existence";
163
- }
164
- if (/^(?:hidden|contents|sr-only|not-sr-only|list-item|flow-root)$/.test(b) ||
165
- /^(?:block|inline-block|inline)$/.test(b)) {
166
- return "existence";
167
- }
168
- if (/^table(?:$|-)/.test(b)) {
169
- return "existence";
170
- }
171
- if (/^contain-/.test(b)) {
172
- return "existence";
173
- }
174
- if (/^(?:group|peer)(?:\/[a-z][a-z0-9-]*)?$/.test(b)) {
175
- return "existence";
176
- }
177
- // --- Position ---
178
- if (/^(?:static|relative|absolute|fixed|sticky)$/.test(b)) {
179
- return "position";
180
- }
181
- if (/^-?(?:inset|top|right|bottom|left|start|end)(?:-|\/|$)/.test(b) ||
182
- /^-?(?:inset-x|inset-y|inset-s|inset-e)-/.test(b)) {
183
- return "position";
184
- }
185
- if (/^-?z-/.test(b) || b === "z-auto") {
186
- return "position";
187
- }
188
- // --- Layout ---
189
- if (/^(?:flex|inline-flex|grid|inline-grid|subgrid|masonry)(?:$|-)/.test(b) ||
190
- /^(?:items|justify|justify-items|justify-self|content|self|place|place-content|place-items|place-self)-/.test(b) ||
191
- /^-?(?:gap|space-[xy]|col-|row-|grid-|auto-cols|auto-rows|order-|order$)/.test(b) ||
192
- /^-?(?:auto-flow|grid-flow)-/.test(b) ||
193
- /^(?:columns-|break-after|break-before|break-inside)-/.test(b) ||
194
- /^(?:float|clear)-/.test(b) ||
195
- /^(?:wrap-|flex-wrap|flex-nowrap|flex-row|flex-col|flex-auto|flex-initial|flex-none|flex-1|flex-\[)/.test(b) ||
196
- /^container$/.test(b)) {
197
- return "layout";
198
- }
199
- // --- Sizing ---
200
- if (/^-?(?:w|h|min-w|max-w|min-h|max-h|size|aspect|shrink|grow|basis)-/.test(b) ||
201
- /^(?:shrink|grow)(?:$|-)/.test(b) ||
202
- /^-?overflow-/.test(b) ||
203
- /^-?object-/.test(b)) {
204
- return "sizing";
205
- }
206
- // --- Spacing (margin / padding only; gap lives in layout) ---
207
- if (/^-?(?:p|px|py|pt|pb|pl|pr|ps|pe|m|mx|my|mt|mb|ml|mr|ms|me)-/.test(b)) {
208
- return "spacing";
209
- }
210
- // --- Shape & border (no `outline-*` — see Shadow; outline paints in the overlay pass) ---
211
- if (/^-?(?:rounded|border|ring|divide|inset-ring)(?:-|\/|$)/.test(b) ||
212
- /^(?:rounded|border|ring|divide|inset-ring)$/.test(b) ||
213
- /^ring-offset-/.test(b)) {
214
- return "shape";
215
- }
216
- // --- Background & fill ---
217
- if (/^-?bg-/.test(b) ||
218
- /^(?:from|via|to)(?:-|\/|$)/.test(b) ||
219
- /^bg-(?:linear|radial|conic)-/.test(b) ||
220
- /^-?mask-/.test(b) ||
221
- /^-?(?:fill|stroke)-/.test(b)) {
222
- return "background";
223
- }
224
- // --- Shadow & depth (includes `outline-*` — same paint phase as box-shadow overlay) ---
225
- if (/^-?(?:shadow|inset-shadow|drop-shadow|text-shadow)(?:-|\/|$)/.test(b) ||
226
- /^(?:shadow|inset-shadow)$/.test(b) ||
227
- /^-?outline(?:-|\/|$)/.test(b) ||
228
- /^outline$/.test(b)) {
229
- return "shadow";
230
- }
231
- // --- Typography ---
232
- if (/^-?(?:font|leading|tracking|list|indent|align|decoration|underline-offset|text-wrap|text-balance|text-pretty)-/.test(b) ||
233
- /^-?(?:text-(?!shadow))/.test(b) ||
234
- /^-?(?:whitespace|break|line-clamp|hyphens)-/.test(b) ||
235
- /^(?:antialiased|subpixel-antialiased|italic|not-italic|overline|line-through|underline|no-underline|uppercase|lowercase|capitalize|normal-case|truncate|text-wrap|text-balance|text-pretty)$/.test(b) ||
236
- /^text-wrap-/.test(b) ||
237
- /^tabular-nums$|^slashed-zero$|^lining-nums$|^oldstyle-nums$|^proportional-nums$/.test(b)) {
238
- return "typography";
239
- }
240
- // --- Composite & transforms (GPU / filter stack) ---
241
- if (/^opacity(?:-|$)/.test(b) ||
242
- /^mix-blend-/.test(b) ||
243
- /^isolation(?:-|$)/.test(b) ||
244
- b === "isolate" ||
245
- /^transform(?:-(?:gpu|cpu|none))?$/.test(b) ||
246
- /^-?(?:translate|scale|rotate|skew)-/.test(b) ||
247
- /^perspective(?:-|$)/.test(b) ||
248
- b === "transform-3d" ||
249
- /^blur(?:-|$)/.test(b) ||
250
- /^backdrop-/.test(b) ||
251
- /^filter(?:-|$)/.test(b) ||
252
- /^brightness-/.test(b) ||
253
- /^contrast-/.test(b) ||
254
- /^grayscale(?:-|$)/.test(b) ||
255
- /^hue-rotate-/.test(b) ||
256
- /^invert(?:-|$)/.test(b) ||
257
- /^saturate-/.test(b) ||
258
- /^sepia(?:-|$)/.test(b) ||
259
- /^will-change/.test(b)) {
260
- return "composite";
261
- }
262
- // --- Motion ---
263
- if (/^(?:transition|duration|ease|delay|animate)(?:-|$)/.test(b) || /^ease-/.test(b)) {
264
- return "motion";
265
- }
266
- // --- Behavior & interaction ---
267
- if (/^(?:cursor|pointer-events|select|touch|scroll|scroll-m|scroll-p|overscroll|snap|resize|field-sizing|appearance|scheme|color-scheme|accent|caret)(?:-|$)/.test(b) ||
268
- /^(?:cursor|select|resize)$/.test(b) ||
269
- /^scroll-behavior/.test(b) ||
270
- /^scroll-snap/.test(b) ||
271
- /^touch-action/.test(b) ||
272
- b === "inert") {
273
- return "behavior";
274
- }
275
- return "other";
276
- }
277
- /**
278
- * Arbitrary **parent** selectors (`[&…]`, `[&>a]:…`, slot forms with `&` inside the bracket)
279
- * scope utilities like variants — bucket as `state` so they chunk apart from base layout/typography.
280
- * Pure arbitrary **properties** (`[--x]:`, `[color:red]`) have no `&` in the leading `[…]` segment.
281
- */
282
- export function isArbitraryParentSelectorStateToken(token) {
283
- if (/^\[&/.test(token)) {
284
- return true;
285
- }
286
- if (!token.startsWith("[")) {
287
- return false;
288
- }
289
- const colonIdx = indexOfFirstVariantColon(token);
290
- if (colonIdx === -1 || colonIdx === 0 || token[colonIdx - 1] !== "]") {
291
- return false;
292
- }
293
- const selector = token.slice(0, colonIdx);
294
- return selector.includes("&");
295
- }
296
- export function classifyToken(token) {
297
- // Before `[` arbitrary-property handling and `isStateToken`, parent-selector tokens must
298
- // be `state` so they flush into their own chunk after unconditional utilities.
299
- if (isArbitraryParentSelectorStateToken(token)) {
300
- return "state";
301
- }
302
- if (/^@container(?:\/[a-z][a-z0-9-]*)?$/i.test(token)) {
303
- return "existence";
304
- }
305
- if (token.startsWith("[")) {
306
- const splitIdx = indexOfFirstVariantColon(token);
307
- if (splitIdx === -1) {
308
- return "arbitrary";
309
- }
310
- if (splitIdx === 0 || token[splitIdx - 1] !== "]") {
311
- return "arbitrary";
312
- }
313
- }
314
- const outer = firstLeadingVariantPrefix(token);
315
- if (outer === "starting") {
316
- return "starting";
317
- }
318
- if (isStateToken(token)) {
319
- return "state";
320
- }
321
- const bareUtility = stripVariants(token);
322
- return classifyBareUtility(bareUtility);
323
- }
324
- /**
325
- * Stable key for `data-[…]` variants so unrelated selectors stay split, while
326
- * **branching on the full bracket** (e.g. `data-[vaul-drawer-direction=bottom]`
327
- * vs `=left`) keeps direction-specific utilities in separate state groups.
328
- */
329
- function dataAttributeStem(token) {
330
- const match = token.match(/^data-\[([^\]]*)\]/);
331
- return match ? `data-[${match[1]}]` : "data";
332
- }
333
- /** Same idea as {@link dataAttributeStem} for `aria-[…]:` variants. */
334
- function ariaAttributeStem(token) {
335
- const match = token.match(/^aria-\[([^\]]*)\]/);
336
- return match ? `aria-[${match[1]}]` : "aria";
337
- }
338
- /** `in-data-[…]:` — normalize on the full bracket expression like {@link dataAttributeStem}. */
339
- function inDataAttributeStem(token) {
340
- const match = token.match(/^in-data-\[([^\]]*)\]/);
341
- return match ? `in-data-[${match[1]}]` : "in-data";
342
- }
343
- /**
344
- * Stable key for splitting adjacent `state` / `starting` tokens in {@link suggestCnGroups}.
345
- * Uses the **full variant stack** (every `:` segment outside `[…]`), not only the
346
- * outermost prefix, so `@md/foo:[&>*]:w-auto` and `@md/foo:has-[…]:mt-px` stay in
347
- * separate groups while `hover:opacity` still keys as `hover` + `opacity`…
348
- *
349
- * `data-[…]` / `aria-[…]` normalize the first segment via {@link dataAttributeStem} /
350
- * {@link ariaAttributeStem} (full token required for bracket capture).
351
- */
352
- export function stateKey(token) {
353
- const layers = [];
354
- let rest = token;
355
- while (rest.length > 0) {
356
- const colonIdx = indexOfFirstVariantColon(rest);
357
- if (colonIdx === -1)
358
- break;
359
- layers.push(rest.slice(0, colonIdx));
360
- rest = rest.slice(colonIdx + 1);
361
- }
362
- if (layers.length === 0) {
363
- return token;
364
- }
365
- if (layers[0].startsWith("data-[")) {
366
- layers[0] = dataAttributeStem(token);
367
- }
368
- else if (layers[0].startsWith("aria-[")) {
369
- layers[0] = ariaAttributeStem(token);
370
- }
371
- else if (layers[0].startsWith("in-data-[")) {
372
- layers[0] = inDataAttributeStem(token);
373
- }
374
- return layers.join("\u001f");
375
- }
376
- export function bucketsCompatible(a, b) {
377
- if (a === b)
378
- return true;
379
- return COMPATIBLE_BUCKET_SETS.some((bucketSet) => bucketSet.has(a) && bucketSet.has(b));
380
- }
381
- /** Like {@link bucketsCompatible}, but never merge two distinct state / starting variant blobs. */
382
- export function bucketsMergeCompatible(a, b) {
383
- if (a === "state" && b === "state")
384
- return false;
385
- if (a === "starting" && b === "starting")
386
- return false;
387
- if (a === "arbitrary" || b === "arbitrary")
388
- return false;
389
- return bucketsCompatible(a, b);
390
- }
@@ -1,104 +0,0 @@
1
- /**
2
- * Shared types for the arrange pipeline (Tailwind `cn()` / `tv()` tooling).
3
- *
4
- * Buckets follow a **render-pipeline order** (existence → … → conditions), aligned
5
- * with Tailwind v4 utility groupings.
6
- */
7
- import type ts from "typescript";
8
- export type Bucket = "existence" | "position" | "layout" | "sizing" | "spacing" | "shape" | "background" | "shadow" | "typography" | "composite" | "motion" | "starting" | "behavior" | "state" | "arbitrary" | "other";
9
- /** String or no-substitution template literal used as a Tailwind class blob. */
10
- export type TailwindClassLiteral = ts.StringLiteral | ts.NoSubstitutionTemplateLiteral;
11
- export type ForEachStringLiteralInClassExpressionOptions = {
12
- /**
13
- * When `false`, do not visit literals inside `cond ? "a" : "b"`. Used when
14
- * building the cn/tv **apply** pool so mutually exclusive branch classes are
15
- * never merged into one static string (while `analyze` still uses the default).
16
- */
17
- descendIntoConditional?: boolean;
18
- };
19
- export type JsxClassNameStatic = {
20
- lit: TailwindClassLiteral;
21
- /** Replace this node: `StringLiteral` or whole `JsxExpression`. */
22
- valueNode: ts.Node;
23
- };
24
- /**
25
- * A StringNode represents a single "grouping slot" — the full set of static
26
- * string literals that belong to one logical class surface.
27
- */
28
- export type StringNode = {
29
- /** All static string literals belonging to this slot, in source order. */
30
- nodes: TailwindClassLiteral[];
31
- sf: ts.SourceFile;
32
- /** String slots in `tv({ ... })` that are not `cn(...)` arguments — use `formatArray`. */
33
- isTvContext: boolean;
34
- /** When set, the entire cn(...) call is replaced at once. */
35
- cnCall?: ts.CallExpression;
36
- /** Representative node (first in slot) for line-number reporting. */
37
- get node(): TailwindClassLiteral;
38
- };
39
- export type GroupTarget = {
40
- kind: "cnArg";
41
- item: StringNode;
42
- } | {
43
- kind: "jsxClassName";
44
- sf: ts.SourceFile;
45
- lit: TailwindClassLiteral;
46
- valueNode: ts.Node;
47
- };
48
- export type PlannedGroupEdit = {
49
- start: number;
50
- end: number;
51
- replacement: string;
52
- /** Per-chunk bucket labels (same as `arrange group` trailing `// Buckets:` line). */
53
- bucketSummary: string[];
54
- jsxCn: boolean;
55
- lineSf: ts.SourceFile;
56
- reportNode: ts.Node;
57
- label: string;
58
- };
59
- export type AnalyzeReport = {
60
- files: number;
61
- cnCallExpressions: number;
62
- tvCallExpressions: number;
63
- cnInsideTvCalls: Array<{
64
- file: string;
65
- line: number;
66
- argCount: number;
67
- preview: string;
68
- }>;
69
- longCnStringLiterals: Array<{
70
- file: string;
71
- line: number;
72
- tokenCount: number;
73
- preview: string;
74
- }>;
75
- longTvStringLiterals: Array<{
76
- file: string;
77
- line: number;
78
- tokenCount: number;
79
- preview: string;
80
- }>;
81
- longJsxClassNameLiterals: Array<{
82
- file: string;
83
- line: number;
84
- tokenCount: number;
85
- preview: string;
86
- }>;
87
- };
88
- export type GroupFileResult = {
89
- filePath: string;
90
- /**
91
- * Sites worth human review: applied edits plus `cn()` inside `tv` with no args
92
- * (skipped). Matches preview totals when `groupEdits` correspond to the same plan.
93
- */
94
- totalFound: number;
95
- /** Edits actually written in apply mode; always 0 in preview mode. */
96
- changed: number;
97
- };
98
- export type ArrangeGroupFileOptions = {
99
- write: boolean;
100
- withClassName: boolean;
101
- cnImport?: string;
102
- };
103
- export type ArrangeRunOnTargetOptions = ArrangeGroupFileOptions;
104
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/lib/arrange/types.ts"],"names":[],"mappings":"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"}
@@ -1,7 +0,0 @@
1
- /**
2
- * Shared types for the arrange pipeline (Tailwind `cn()` / `tv()` tooling).
3
- *
4
- * Buckets follow a **render-pipeline order** (existence → … → conditions), aligned
5
- * with Tailwind v4 utility groupings.
6
- */
7
- export {};
@@ -1,4 +0,0 @@
1
- import type { CliFs } from "#lib/infra/fs-contract";
2
- export declare const DEFAULT_SKIP_DIRS: Set<string>;
3
- export declare function walkTsxFiles(root: string, fs: CliFs): string[];
4
- //# sourceMappingURL=walk.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"walk.d.ts","sourceRoot":"","sources":["../../../src/lib/arrange/walk.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,wBAAwB,CAAC;AAEpD,eAAO,MAAM,iBAAiB,aAY5B,CAAC;AAEH,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,KAAK,GAAG,MAAM,EAAE,CAgB9D"}
@@ -1,34 +0,0 @@
1
- import path from "node:path";
2
- export const DEFAULT_SKIP_DIRS = new Set([
3
- "node_modules",
4
- "dist",
5
- ".git",
6
- ".turbo",
7
- ".next",
8
- ".cache",
9
- "out",
10
- "build",
11
- "coverage",
12
- ".vercel",
13
- ".output",
14
- ]);
15
- export function walkTsxFiles(root, fs) {
16
- const result = [];
17
- const visit = (entryPath) => {
18
- const entryStats = fs.statSync(entryPath);
19
- if (entryStats.isDirectory()) {
20
- for (const name of fs.readdirSync(entryPath)) {
21
- if (DEFAULT_SKIP_DIRS.has(name))
22
- continue;
23
- visit(path.join(entryPath, name));
24
- }
25
- return;
26
- }
27
- if (entryPath.endsWith(".d.ts"))
28
- return;
29
- if (entryPath.endsWith(".tsx") || entryPath.endsWith(".ts"))
30
- result.push(entryPath);
31
- };
32
- visit(root);
33
- return result;
34
- }
@@ -1,41 +0,0 @@
1
- /**
2
- * Analyze and suggest Tailwind class grouping inside `cn(...)` / `tv(...)`.
3
- *
4
- * Detects literals in cn arguments: direct strings, ternaries, arrays, string concatenation.
5
- * tv: compoundVariants[].className / class; nested cn literals use the same rules.
6
- * Direct `cn(...)` inside tv config is discouraged — analyze/preview/apply may replace it with
7
- * a string (one argument) or an array (≥2 arguments). Literals in bare tv arrays are not split
8
- * by apply (avoids `[ [` artifacts).
9
- *
10
- * Tailwind CSS v4-oriented heuristics (class buckets follow **render-pipeline order**):
11
- * existence → position → layout → sizing → spacing → shape → background → shadow
12
- * → typography → composite → motion → starting → behavior → state (variants).
13
- * - Container queries (@min-* / @max-* / @[…] / @sm / @md / @3xl / @max-3xs, md/sidebar:, …)
14
- * - Logical properties (ps/pe/ms/me/start/end)
15
- * - not-* modifier; has-*; in-[…]; * / **; nth-* (including numeric); media (pointer-*, contrast-* …)
16
- * - Newer utilities: inset-shadow, field-sizing, mask-*, text-shadow-*, scheme-*, …
17
- * - Arbitrary variants [&...] in general forms
18
- *
19
- * Usage (repo root):
20
- * pnpm cli:arrange-analyze [dir|file]
21
- * pnpm exec codefast arrange analyze [dir|file]
22
- * pnpm exec codefast arrange group flex gap-2 rounded-md border px-3
23
- * pnpm exec codefast arrange group -- … --tv
24
- */
25
- export { analyzeDirectory } from "#lib/arrange/analyze";
26
- export { printAnalyzeReport } from "#lib/arrange/report";
27
- export { groupFile } from "#lib/arrange/group-file";
28
- export { runOnTarget } from "#lib/arrange/run-target";
29
- export { createNodeCliFs, createNodeCliLogger } from "#lib/infra/node-io";
30
- export { ArrangeError, ArrangeErrorCode } from "#lib/arrange/errors";
31
- export type { CliFs, CliLogger } from "#lib/infra/fs-contract";
32
- export type { AnalyzeReport, ArrangeGroupFileOptions, ArrangeRunOnTargetOptions, Bucket, ForEachStringLiteralInClassExpressionOptions, GroupFileResult, } from "#lib/arrange/types";
33
- export { DEFAULT_ARRANGE_TARGET, LONG_STRING_TOKEN_THRESHOLD, MAX_STRIP_VARIANT_PASSES, } from "#lib/arrange/constants";
34
- export { cnModuleSpecifierForFile, ensureCnImport } from "#lib/arrange/imports";
35
- export { areCnTailwindPartitionsEquivalent, capGroups, mergeEaseTimingIntoFollowingAnimatedState, mergeSingletons, suggestCnGroups, summarizeGroupBucketLabels, } from "#lib/arrange/grouping";
36
- export { classifyToken, indexOfFirstVariantColon, stripVariants, tokenizeClassString, bucketsCompatible, bucketsMergeCompatible, stateKey, } from "#lib/arrange/tokenizer";
37
- export { forEachStringLiteralInClassExpression, mergeCnUnconditionalLiteralPoolForTest, } from "#lib/arrange/ast/collectors-cn";
38
- export { applyEditsDescending, buildKnownCnTvBindings, isCnOrTvIdentifier, KNOWN_CN_TV_MODULES, lineOf, moduleLooksLikeCnTvReexport, unwrapCnInsideTvCallReplacement, } from "#lib/arrange/ast/utils";
39
- export { escapeTsStringLiteralContent, formatArray, formatCnArguments, formatCnCall, formatJsxCnAttributeValue, } from "#lib/arrange/formatters";
40
- export { DEFAULT_SKIP_DIRS, walkTsxFiles } from "#lib/arrange/walk";
41
- //# sourceMappingURL=arrange.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"arrange.d.ts","sourceRoot":"","sources":["../../src/lib/arrange.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACzD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACrE,YAAY,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAC/D,YAAY,EACV,aAAa,EACb,uBAAuB,EACvB,yBAAyB,EACzB,MAAM,EACN,4CAA4C,EAC5C,eAAe,GAChB,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EACL,sBAAsB,EACtB,2BAA2B,EAC3B,wBAAwB,GACzB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,wBAAwB,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAChF,OAAO,EACL,iCAAiC,EACjC,SAAS,EACT,yCAAyC,EACzC,eAAe,EACf,eAAe,EACf,0BAA0B,GAC3B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,aAAa,EACb,wBAAwB,EACxB,aAAa,EACb,mBAAmB,EACnB,iBAAiB,EACjB,sBAAsB,EACtB,QAAQ,GACT,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,qCAAqC,EACrC,sCAAsC,GACvC,MAAM,gCAAgC,CAAC;AACxC,OAAO,EACL,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,EAClB,mBAAmB,EACnB,MAAM,EACN,2BAA2B,EAC3B,+BAA+B,GAChC,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EACL,4BAA4B,EAC5B,WAAW,EACX,iBAAiB,EACjB,YAAY,EACZ,yBAAyB,GAC1B,MAAM,yBAAyB,CAAC;AAEjC,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
@@ -1,38 +0,0 @@
1
- /**
2
- * Analyze and suggest Tailwind class grouping inside `cn(...)` / `tv(...)`.
3
- *
4
- * Detects literals in cn arguments: direct strings, ternaries, arrays, string concatenation.
5
- * tv: compoundVariants[].className / class; nested cn literals use the same rules.
6
- * Direct `cn(...)` inside tv config is discouraged — analyze/preview/apply may replace it with
7
- * a string (one argument) or an array (≥2 arguments). Literals in bare tv arrays are not split
8
- * by apply (avoids `[ [` artifacts).
9
- *
10
- * Tailwind CSS v4-oriented heuristics (class buckets follow **render-pipeline order**):
11
- * existence → position → layout → sizing → spacing → shape → background → shadow
12
- * → typography → composite → motion → starting → behavior → state (variants).
13
- * - Container queries (@min-* / @max-* / @[…] / @sm / @md / @3xl / @max-3xs, md/sidebar:, …)
14
- * - Logical properties (ps/pe/ms/me/start/end)
15
- * - not-* modifier; has-*; in-[…]; * / **; nth-* (including numeric); media (pointer-*, contrast-* …)
16
- * - Newer utilities: inset-shadow, field-sizing, mask-*, text-shadow-*, scheme-*, …
17
- * - Arbitrary variants [&...] in general forms
18
- *
19
- * Usage (repo root):
20
- * pnpm cli:arrange-analyze [dir|file]
21
- * pnpm exec codefast arrange analyze [dir|file]
22
- * pnpm exec codefast arrange group flex gap-2 rounded-md border px-3
23
- * pnpm exec codefast arrange group -- … --tv
24
- */
25
- export { analyzeDirectory } from "#lib/arrange/analyze";
26
- export { printAnalyzeReport } from "#lib/arrange/report";
27
- export { groupFile } from "#lib/arrange/group-file";
28
- export { runOnTarget } from "#lib/arrange/run-target";
29
- export { createNodeCliFs, createNodeCliLogger } from "#lib/infra/node-io";
30
- export { ArrangeError, ArrangeErrorCode } from "#lib/arrange/errors";
31
- export { DEFAULT_ARRANGE_TARGET, LONG_STRING_TOKEN_THRESHOLD, MAX_STRIP_VARIANT_PASSES, } from "#lib/arrange/constants";
32
- export { cnModuleSpecifierForFile, ensureCnImport } from "#lib/arrange/imports";
33
- export { areCnTailwindPartitionsEquivalent, capGroups, mergeEaseTimingIntoFollowingAnimatedState, mergeSingletons, suggestCnGroups, summarizeGroupBucketLabels, } from "#lib/arrange/grouping";
34
- export { classifyToken, indexOfFirstVariantColon, stripVariants, tokenizeClassString, bucketsCompatible, bucketsMergeCompatible, stateKey, } from "#lib/arrange/tokenizer";
35
- export { forEachStringLiteralInClassExpression, mergeCnUnconditionalLiteralPoolForTest, } from "#lib/arrange/ast/collectors-cn";
36
- export { applyEditsDescending, buildKnownCnTvBindings, isCnOrTvIdentifier, KNOWN_CN_TV_MODULES, lineOf, moduleLooksLikeCnTvReexport, unwrapCnInsideTvCallReplacement, } from "#lib/arrange/ast/utils";
37
- export { escapeTsStringLiteralContent, formatArray, formatCnArguments, formatCnCall, formatJsxCnAttributeValue, } from "#lib/arrange/formatters";
38
- export { DEFAULT_SKIP_DIRS, walkTsxFiles } from "#lib/arrange/walk";
@@ -1,28 +0,0 @@
1
- import type { Dirent } from "node:fs";
2
- /**
3
- * Filesystem surface for CLI packages — inject in tests.
4
- * Sync API supports arrange walk; async API supports mirror + atomic writes.
5
- */
6
- export type CliFs = {
7
- existsSync: (path: string) => boolean;
8
- statSync: (path: string) => {
9
- isDirectory: () => boolean;
10
- isFile: () => boolean;
11
- };
12
- readFileSync: (path: string, encoding: BufferEncoding) => string;
13
- writeFileSync: (path: string, data: string, encoding: BufferEncoding) => void;
14
- readdirSync: (path: string) => string[];
15
- readFile: (path: string, encoding: BufferEncoding) => Promise<string>;
16
- writeFile: (path: string, data: string, encoding: BufferEncoding) => Promise<void>;
17
- readdir: (path: string, options?: {
18
- recursive?: boolean;
19
- withFileTypes?: boolean;
20
- }) => Promise<string[] | Dirent[]>;
21
- rename: (oldPath: string, newPath: string) => Promise<void>;
22
- unlink: (path: string) => Promise<void>;
23
- };
24
- export type CliLogger = {
25
- out: (line: string) => void;
26
- err: (line: string) => void;
27
- };
28
- //# sourceMappingURL=fs-contract.d.ts.map