@codefast/cli 0.11.0 → 0.13.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 (261) hide show
  1. package/CHANGELOG.md +87 -0
  2. package/README.md +152 -56
  3. package/dist/arrange/command.js +24 -25
  4. package/dist/arrange/domain/ast/collectors-cn.d.ts +2 -2
  5. package/dist/arrange/domain/ast/collectors-cn.js +2 -2
  6. package/dist/arrange/domain/ast/collectors-jsx.d.ts +2 -2
  7. package/dist/arrange/domain/ast/collectors-jsx.js +1 -1
  8. package/dist/arrange/domain/ast/collectors-tv.d.ts +2 -2
  9. package/dist/arrange/domain/ast/collectors-tv.js +5 -5
  10. package/dist/arrange/domain/ast/helpers.d.ts +2 -2
  11. package/dist/arrange/domain/ast/helpers.js +3 -4
  12. package/dist/arrange/domain/ast/simplify-targets.d.ts +1 -1
  13. package/dist/arrange/domain/ast/simplify-targets.js +5 -5
  14. package/dist/arrange/domain/ast/targets.d.ts +2 -2
  15. package/dist/arrange/domain/ast/targets.js +9 -9
  16. package/dist/arrange/domain/ast/translator.d.ts +1 -1
  17. package/dist/arrange/domain/ast/translator.js +43 -29
  18. package/dist/arrange/domain/constants.d.ts +1 -1
  19. package/dist/arrange/domain/grouping-service.d.ts +2 -2
  20. package/dist/arrange/domain/grouping-service.js +3 -3
  21. package/dist/arrange/domain/grouping.js +3 -3
  22. package/dist/arrange/domain/imports.d.ts +1 -1
  23. package/dist/arrange/domain/imports.js +2 -2
  24. package/dist/arrange/domain/source-text-formatters.js +1 -1
  25. package/dist/arrange/domain/tailwind-token.js +1 -1
  26. package/dist/arrange/domain/token-classifier.d.ts +1 -1
  27. package/dist/arrange/domain/token-classifier.js +2 -2
  28. package/dist/arrange/domain/types.d.ts +3 -3
  29. package/dist/arrange/group/cli-result.d.ts +1 -1
  30. package/dist/arrange/group/output.d.ts +1 -1
  31. package/dist/arrange/group/output.js +1 -1
  32. package/dist/arrange/group/suggest.d.ts +2 -2
  33. package/dist/arrange/group/suggest.js +2 -2
  34. package/dist/arrange/inspect/cli-result.d.ts +1 -1
  35. package/dist/arrange/inspect/domain/analyze-service.d.ts +2 -2
  36. package/dist/arrange/inspect/domain/analyze-service.js +7 -7
  37. package/dist/arrange/inspect/output.d.ts +1 -1
  38. package/dist/arrange/inspect/output.js +2 -2
  39. package/dist/arrange/inspect/run.d.ts +4 -4
  40. package/dist/arrange/inspect/run.js +6 -6
  41. package/dist/arrange/prepare.d.ts +4 -4
  42. package/dist/arrange/prepare.js +5 -5
  43. package/dist/arrange/regroup/cli-result.d.ts +1 -1
  44. package/dist/arrange/regroup/cli-result.js +1 -1
  45. package/dist/arrange/regroup/output.d.ts +2 -2
  46. package/dist/arrange/regroup/output.js +2 -2
  47. package/dist/arrange/regroup/process-file.d.ts +2 -2
  48. package/dist/arrange/regroup/process-file.js +3 -3
  49. package/dist/arrange/regroup/run.d.ts +5 -5
  50. package/dist/arrange/regroup/run.js +4 -4
  51. package/dist/arrange/resolve-target.d.ts +1 -1
  52. package/dist/arrange/resolve-target.js +2 -2
  53. package/dist/arrange/scan-target.d.ts +1 -1
  54. package/dist/arrange/scan-target.js +3 -3
  55. package/dist/arrange/simplify/cli-result.d.ts +1 -1
  56. package/dist/arrange/simplify/fold-targets.d.ts +3 -3
  57. package/dist/arrange/simplify/fold-targets.js +3 -3
  58. package/dist/arrange/simplify/output.d.ts +1 -1
  59. package/dist/arrange/simplify/output.js +1 -1
  60. package/dist/arrange/simplify/process-file.d.ts +4 -4
  61. package/dist/arrange/simplify/process-file.js +5 -5
  62. package/dist/arrange/simplify/run.d.ts +4 -4
  63. package/dist/arrange/simplify/run.js +4 -4
  64. package/dist/arrange/simplify/variant-classname-probe.js +1 -1
  65. package/dist/arrange/source-parse.d.ts +1 -1
  66. package/dist/arrange/source-parse.js +3 -3
  67. package/dist/audit/assertions/cli-result.d.ts +13 -0
  68. package/dist/audit/assertions/cli-result.js +22 -0
  69. package/dist/audit/assertions/cli-schema.d.ts +18 -0
  70. package/dist/audit/assertions/cli-schema.js +12 -0
  71. package/dist/audit/assertions/domain/double-assertion.d.ts +20 -0
  72. package/dist/audit/assertions/domain/double-assertion.js +122 -0
  73. package/dist/audit/assertions/output.d.ts +7 -0
  74. package/dist/audit/assertions/output.js +21 -0
  75. package/dist/audit/assertions/prepare.d.ts +16 -0
  76. package/dist/audit/assertions/prepare.js +12 -0
  77. package/dist/audit/assertions/run.d.ts +14 -0
  78. package/dist/audit/assertions/run.js +40 -0
  79. package/dist/audit/command.js +89 -28
  80. package/dist/audit/comments/cli-result.d.ts +1 -1
  81. package/dist/audit/comments/cli-result.js +1 -1
  82. package/dist/audit/comments/output.d.ts +1 -1
  83. package/dist/audit/comments/output.js +1 -1
  84. package/dist/audit/comments/prepare.d.ts +4 -4
  85. package/dist/audit/comments/prepare.js +1 -1
  86. package/dist/audit/comments/run.d.ts +4 -4
  87. package/dist/audit/comments/run.js +9 -9
  88. package/dist/audit/constants/cli-result.d.ts +13 -0
  89. package/dist/audit/constants/cli-result.js +22 -0
  90. package/dist/audit/constants/cli-schema.d.ts +18 -0
  91. package/dist/audit/constants/cli-schema.js +12 -0
  92. package/dist/audit/constants/domain/constants.d.ts +8 -0
  93. package/dist/audit/constants/domain/constants.js +66 -0
  94. package/dist/audit/constants/output.d.ts +7 -0
  95. package/dist/audit/constants/output.js +21 -0
  96. package/dist/audit/constants/prepare.d.ts +16 -0
  97. package/dist/audit/constants/prepare.js +37 -0
  98. package/dist/audit/constants/run.d.ts +14 -0
  99. package/dist/audit/constants/run.js +64 -0
  100. package/dist/audit/display-names/cli-result.d.ts +1 -1
  101. package/dist/audit/display-names/cli-result.js +1 -1
  102. package/dist/audit/display-names/domain/display-names.d.ts +1 -1
  103. package/dist/audit/display-names/domain/display-names.js +1 -9
  104. package/dist/audit/display-names/output.d.ts +1 -1
  105. package/dist/audit/display-names/output.js +1 -1
  106. package/dist/audit/display-names/prepare.d.ts +4 -4
  107. package/dist/audit/display-names/prepare.js +1 -1
  108. package/dist/audit/display-names/run.d.ts +4 -4
  109. package/dist/audit/display-names/run.js +5 -5
  110. package/dist/audit/domain/types.d.ts +128 -0
  111. package/dist/audit/imports/cli-result.d.ts +1 -1
  112. package/dist/audit/imports/cli-result.js +1 -1
  113. package/dist/audit/imports/domain/import-policy.d.ts +1 -1
  114. package/dist/audit/imports/domain/import-policy.js +4 -18
  115. package/dist/audit/imports/output.d.ts +1 -1
  116. package/dist/audit/imports/output.js +1 -1
  117. package/dist/audit/imports/prepare.d.ts +4 -4
  118. package/dist/audit/imports/prepare.js +1 -1
  119. package/dist/audit/imports/run.d.ts +4 -4
  120. package/dist/audit/imports/run.js +6 -6
  121. package/dist/audit/links/cli-result.d.ts +1 -1
  122. package/dist/audit/links/cli-result.js +1 -1
  123. package/dist/audit/links/domain/markdown-links.d.ts +3 -3
  124. package/dist/audit/links/domain/markdown-links.js +22 -8
  125. package/dist/audit/links/output.d.ts +1 -1
  126. package/dist/audit/links/output.js +1 -1
  127. package/dist/audit/links/prepare.d.ts +4 -4
  128. package/dist/audit/links/prepare.js +1 -1
  129. package/dist/audit/links/run.d.ts +4 -4
  130. package/dist/audit/links/run.js +4 -4
  131. package/dist/audit/prepare.d.ts +4 -4
  132. package/dist/audit/prepare.js +4 -4
  133. package/dist/audit/publish/cli-result.d.ts +13 -0
  134. package/dist/audit/publish/cli-result.js +25 -0
  135. package/dist/audit/publish/cli-schema.d.ts +18 -0
  136. package/dist/audit/publish/cli-schema.js +12 -0
  137. package/dist/audit/publish/domain/legacy-subpath.d.ts +8 -0
  138. package/dist/audit/publish/domain/legacy-subpath.js +22 -0
  139. package/dist/audit/publish/domain/stylesheet-sources.d.ts +22 -0
  140. package/dist/audit/publish/domain/stylesheet-sources.js +64 -0
  141. package/dist/audit/publish/output.d.ts +7 -0
  142. package/dist/audit/publish/output.js +33 -0
  143. package/dist/audit/publish/prepare.d.ts +16 -0
  144. package/dist/audit/publish/prepare.js +12 -0
  145. package/dist/audit/publish/run.d.ts +15 -0
  146. package/dist/audit/publish/run.js +91 -0
  147. package/dist/audit/publish/shipped-files.d.ts +21 -0
  148. package/dist/audit/publish/shipped-files.js +36 -0
  149. package/dist/audit/rtl/cli-result.d.ts +1 -1
  150. package/dist/audit/rtl/cli-result.js +1 -1
  151. package/dist/audit/rtl/domain/audit-file.d.ts +1 -1
  152. package/dist/audit/rtl/domain/audit-file.js +2 -2
  153. package/dist/audit/rtl/domain/tokenize.d.ts +1 -1
  154. package/dist/audit/rtl/output.d.ts +1 -1
  155. package/dist/audit/rtl/output.js +1 -1
  156. package/dist/audit/rtl/prepare.d.ts +4 -4
  157. package/dist/audit/rtl/prepare.js +5 -5
  158. package/dist/audit/rtl/run.d.ts +4 -4
  159. package/dist/audit/rtl/run.js +4 -4
  160. package/dist/bin.js +1 -1
  161. package/dist/cli.js +5 -5
  162. package/dist/core/cli/command-pipeline.d.ts +4 -5
  163. package/dist/core/cli/command-pipeline.js +7 -7
  164. package/dist/core/cli/format-error.d.ts +1 -1
  165. package/dist/core/cli/resolve-root.d.ts +3 -3
  166. package/dist/core/cli/resolve-root.js +3 -3
  167. package/dist/core/cli/result-handle.d.ts +2 -2
  168. package/dist/core/cli/result-handle.js +4 -4
  169. package/dist/core/config/define-config.d.ts +1 -1
  170. package/dist/core/config/loader.d.ts +2 -2
  171. package/dist/core/config/loader.js +2 -2
  172. package/dist/core/config/schema.d.ts +5 -0
  173. package/dist/core/config/schema.js +2 -0
  174. package/dist/core/config/warnings.js +1 -1
  175. package/dist/core/config.d.ts +4 -4
  176. package/dist/core/config.js +4 -4
  177. package/dist/core/filesystem/filesystem.d.ts +3 -4
  178. package/dist/core/filesystem/node.d.ts +1 -1
  179. package/dist/core/filesystem/node.js +1 -7
  180. package/dist/core/oxc-node.d.ts +32 -0
  181. package/dist/core/oxc-node.js +25 -0
  182. package/dist/core/schema-parse.d.ts +2 -2
  183. package/dist/core/schema-parse.js +2 -2
  184. package/dist/core/source-position.d.ts +15 -0
  185. package/dist/core/source-position.js +26 -0
  186. package/dist/core/workspace/markdown-walk.d.ts +1 -1
  187. package/dist/core/workspace/markdown-walk.js +1 -1
  188. package/dist/core/workspace/package-version.d.ts +1 -1
  189. package/dist/core/workspace/package-version.js +2 -2
  190. package/dist/core/workspace/resolver.d.ts +1 -1
  191. package/dist/core/workspace/resolver.js +5 -5
  192. package/dist/core/workspace/source-walk.d.ts +1 -1
  193. package/dist/core/workspace/source-walk.js +1 -1
  194. package/dist/core/workspace/typescript-walk.d.ts +1 -1
  195. package/dist/core/workspace/typescript-walk.js +1 -1
  196. package/dist/core/workspace/walk-files.d.ts +1 -1
  197. package/dist/core/workspace/walk-files.js +1 -1
  198. package/dist/index.d.ts +3 -3
  199. package/dist/index.js +2 -2
  200. package/dist/mirror/cli-result.d.ts +1 -1
  201. package/dist/mirror/cli-result.js +1 -1
  202. package/dist/mirror/cli-schema.d.ts +1 -1
  203. package/dist/mirror/command.js +7 -7
  204. package/dist/mirror/dist-filesystem-node.d.ts +2 -2
  205. package/dist/mirror/dist-filesystem-node.js +5 -15
  206. package/dist/mirror/domain/exports.d.ts +2 -2
  207. package/dist/mirror/domain/exports.js +1 -1
  208. package/dist/mirror/domain/types.d.ts +2 -2
  209. package/dist/mirror/output.d.ts +1 -1
  210. package/dist/mirror/output.js +2 -2
  211. package/dist/mirror/package-path.d.ts +3 -3
  212. package/dist/mirror/package-path.js +3 -3
  213. package/dist/mirror/prepare.d.ts +5 -5
  214. package/dist/mirror/prepare.js +4 -4
  215. package/dist/mirror/run.d.ts +6 -6
  216. package/dist/mirror/run.js +7 -7
  217. package/dist/mirror/supplement-exports.d.ts +1 -1
  218. package/dist/mirror/supplement-exports.js +2 -2
  219. package/dist/mirror/sync-workspace-package.d.ts +3 -3
  220. package/dist/mirror/sync-workspace-package.js +11 -14
  221. package/dist/mirror/write-exports.d.ts +2 -2
  222. package/dist/mirror/write-exports.js +3 -3
  223. package/dist/pack-slim/cli-result.d.ts +1 -1
  224. package/dist/pack-slim/cli-result.js +1 -1
  225. package/dist/pack-slim/command.js +9 -9
  226. package/dist/pack-slim/domain/transform.d.ts +22 -1
  227. package/dist/pack-slim/domain/transform.js +65 -8
  228. package/dist/pack-slim/output.d.ts +1 -1
  229. package/dist/pack-slim/output.js +1 -1
  230. package/dist/pack-slim/prepare.d.ts +3 -3
  231. package/dist/pack-slim/prepare.js +2 -2
  232. package/dist/pack-slim/run.d.ts +5 -5
  233. package/dist/pack-slim/run.js +6 -6
  234. package/dist/pack-slim/working-tree.d.ts +2 -2
  235. package/dist/pack-slim/working-tree.js +2 -2
  236. package/dist/tag/cli-result.d.ts +1 -1
  237. package/dist/tag/cli-result.js +1 -1
  238. package/dist/tag/cli-schema.d.ts +1 -1
  239. package/dist/tag/command.js +7 -7
  240. package/dist/tag/domain/skip-filter.d.ts +1 -1
  241. package/dist/tag/domain/skip-filter.js +1 -1
  242. package/dist/tag/domain/types.d.ts +1 -1
  243. package/dist/tag/domain/version-summary.d.ts +5 -2
  244. package/dist/tag/output.d.ts +1 -1
  245. package/dist/tag/output.js +1 -1
  246. package/dist/tag/prepare.d.ts +4 -4
  247. package/dist/tag/prepare.js +4 -4
  248. package/dist/tag/run.d.ts +4 -4
  249. package/dist/tag/run.js +7 -7
  250. package/dist/tag/target/candidates.d.ts +2 -2
  251. package/dist/tag/target/candidates.js +2 -2
  252. package/dist/tag/target/resolve-path.d.ts +1 -1
  253. package/dist/tag/target/runner.d.ts +2 -2
  254. package/dist/tag/target/runner.js +3 -3
  255. package/dist/tag/writer/since-writer.d.ts +2 -2
  256. package/dist/tag/writer/since-writer.js +3 -5
  257. package/dist/tag/writer/version-resolver.d.ts +1 -1
  258. package/dist/tag/writer/version-resolver.js +1 -1
  259. package/package.json +7 -7
  260. package/dist/mirror/domain/dirent-guard.d.ts +0 -10
  261. package/dist/mirror/domain/dirent-guard.js +0 -15
package/CHANGELOG.md CHANGED
@@ -1,5 +1,92 @@
1
1
  # @codefast/cli
2
2
 
3
+ ## 0.13.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#951](https://github.com/codefastlabs/codefast/pull/951) Add `codefast audit assertions`, which reports every double type assertion through `unknown` or `any` —
8
+ `x as unknown as T`, `(x as unknown) as T`, `<T><unknown>x` and the `any` spellings — in `.ts`/`.tsx` files, tests
9
+ included. Where the erasure is the point, keep one with `// codefast-allow-double-assertion: <reason>` on its line or
10
+ the line above; a directive with no reason, or one that keeps no assertion, is reported too. Exceptions can also go in
11
+ `audit.assertions.allowlist`.
12
+
13
+ `Filesystem.readdir` is replaced by `readdirEntries(path, { recursive })`, which always returns directory entries: every
14
+ caller asked for them, and the old `string[] | DirectoryEntry[]` union forced each one to cast or guard.
15
+
16
+ - [#894](https://github.com/codefastlabs/codefast/pull/894) `codefast audit constants` reports every upper-case `const` bound to a number in a library's sources whose comment names
17
+ none of the three kinds a number may be — a constant of the machine, a value the contract fixes, or one derived from
18
+ bind-time data. Sentinel values (`0`, `1`, `-1`) are exempt; `audit.constants.target` and `audit.constants.allowlist` in
19
+ `codefast.config` scope and except it.
20
+
21
+ - [#980](https://github.com/codefastlabs/codefast/pull/980) `audit publish` also reports a shipped stylesheet whose Tailwind `@source` paths reach none of the files the slimmed
22
+ tarball ships, naming any `files` entry missing on disk so an unbuilt `dist` reads as such. A workspace resolves those
23
+ paths against `src`, so only the published layout used to show the failure.
24
+
25
+ - [#976](https://github.com/codefastlabs/codefast/pull/976) `engines.node` is now `>=24.0.0`, up from `>=22.12.0`, and Node 22 is no longer supported. Node 24.0.0 is the first
26
+ release with explicit resource management built in (`using`, `await using`, `DisposableStack`, `AsyncDisposableStack`,
27
+ `SuppressedError`) and all of ES2025, so the packages use both as the platform ships them instead of shimming them for
28
+ an older line, and the CI matrix runs the unit suite on 24.0.0 itself. Move to Node 24, or stay on the current minor
29
+ while a deployment still runs Node 22.
30
+
31
+ ### Patch Changes
32
+
33
+ - [#965](https://github.com/codefastlabs/codefast/pull/965) The optional `typescript` peer is now `>=7.0.0`. It was published as the repository's own `^7.0.2` pin, which excluded
34
+ TypeScript 8 and would have risen with each pin bump instead of staying at the supported floor.
35
+
36
+ - [#965](https://github.com/codefastlabs/codefast/pull/965) `README.md` now states TypeScript 7 or later as the floor for the package's types — the one compiler every `@codefast/*`
37
+ package is built and checked with. No code or declaration changed.
38
+
39
+ ## 0.12.0
40
+
41
+ ### Minor Changes
42
+
43
+ - [#892](https://github.com/codefastlabs/codefast/pull/892) [`4c97c5b`](https://github.com/codefastlabs/codefast/commit/4c97c5b8c2314f25ee9df7eac5a4b5dd723d6d90) Thanks [@thevuong](https://github.com/thevuong)! - Add `codefast audit publish`, a static publish-surface check. It flags `#/`-prefixed internal import specifiers — valid
44
+ to the in-repo runners but rejected by Node's ESM resolver on the supported floor, so they break the published package —
45
+ and any `exports`/`imports` target the slimmed publish manifest would not ship. It joins the `audit` family and gates
46
+ CI, replacing an external `publint` step.
47
+
48
+ ### Patch Changes
49
+
50
+ - [#885](https://github.com/codefastlabs/codefast/pull/885) [`8580a2b`](https://github.com/codefastlabs/codefast/commit/8580a2b2dd9f502d7c330e5a2f0a3942041633b6) Thanks [@thevuong](https://github.com/thevuong)! - Match GitHub's heading-slug algorithm in `audit links`, so a cross-reference that resolves on GitHub resolves in the
51
+ audit.
52
+
53
+ Heading anchors are now slugged the way GitHub does: each space becomes its own hyphen with runs left intact,
54
+ underscores are kept as slug characters, and repeated headings gain `-1`, `-2`, … suffixes in heading order. The
55
+ previous slugger collapsed whitespace, dropped underscores, and offered only the base slug for duplicates, so a link a
56
+ browser lands on could be reported as dangling — the `@remarks` already claimed GitHub parity the code did not deliver.
57
+
58
+ - [#892](https://github.com/codefastlabs/codefast/pull/892) [`4c97c5b`](https://github.com/codefastlabs/codefast/commit/4c97c5b8c2314f25ee9df7eac5a4b5dd723d6d90) Thanks [@thevuong](https://github.com/thevuong)! - Lower the monorepo's Node floor from 24 to 22.12, so the packages install and run on the active Node 22 LTS line.
59
+
60
+ `engines.node` becomes `>=22.12.0` across every package — the floor the shared toolchain (oxlint, Vite, Vitest, TanStack
61
+ Start) already requires. Development stays on the latest Node (`.node-version`) for speed, and a CI matrix exercises the
62
+ floor and the active LTS directly, so the floor is a contract CI proves rather than one everyone has to run.
63
+ `@types/node` is pinned to the floor's major (`^22`), with a workspace override holding the whole tree there so a dev
64
+ tool's `@types/node: "*"` peer can no longer pull a newer major and mask an API the floor lacks. The floor stays
65
+ mechanical, not advisory: `@codefast/di` keeps its own `Map` upsert helpers rather than the ES2025
66
+ `Map.prototype.getOrInsert` (which would raise the floor to 26) and its `lib` stays `ES2024`. `@codefast/cli`'s mirror
67
+ step now calls the `node:path` functions directly instead of aliasing them, which the floor's types correctly flag as
68
+ unbound methods.
69
+
70
+ The shared `@codefast/typescript-config` presets pin `lib` and `target` to `ES2024` (was `ESNext`) so the compiler's
71
+ ECMAScript surface matches the Node floor: an ES2025 builtin such as `Map.prototype.getOrInsert` now fails to type-check
72
+ rather than compiling and crashing on Node 22.12. `@codefast/di` and `@codefast/di-testing` already pinned `lib` and are
73
+ unchanged.
74
+
75
+ Internal subpath imports move from a `#/` prefix to a bare `#` (`#core/token`, not `#/core/token`), and the
76
+ `package.json#imports` keys become `#*`/`#tests/*`/`#examples/*` to match. Node's native ESM resolver rejects a
77
+ `#/`-prefixed specifier with `ERR_INVALID_MODULE_SPECIFIER` on the whole Node 22 line (and on Node 24 before 24.14), and
78
+ each package ships those specifiers verbatim inside its published `dist/*.js` for a consumer's Node to resolve — so this
79
+ rename is what actually lets the packages import on the new floor. Purely internal: a consumer's own import paths are
80
+ unchanged.
81
+
82
+ - [#892](https://github.com/codefastlabs/codefast/pull/892) [`4c97c5b`](https://github.com/codefastlabs/codefast/commit/4c97c5b8c2314f25ee9df7eac5a4b5dd723d6d90) Thanks [@thevuong](https://github.com/thevuong)! - Fix `pack-slim` stripping the stylesheet source of packages that export CSS.
83
+
84
+ `codefast pack-slim` removed the whole `src` directory from a package's published `files`, but `@codefast/ui` and
85
+ `@codefast/tracking` ship Tailwind source through `./css/*` → `./src/css/*`, so their published tarballs went out with
86
+ no CSS at all and the `./css/*` export resolved to nothing. pack-slim now keeps the `src` subtrees a surviving
87
+ `exports`/`imports` target still points into (e.g. `src/css`) and drops the rest of `src`, so the stylesheets ship while
88
+ the TypeScript source stays out. Surfaced and now guarded by the new `codefast audit publish` check.
89
+
3
90
  ## 0.11.0
4
91
 
5
92
  ### Minor Changes
package/README.md CHANGED
@@ -16,13 +16,15 @@ encode an opinionated house style (called out below) that you can adopt, ignore,
16
16
 
17
17
  - **Safe by default.** Every writing command supports `--dry-run`, and every audit is read-only except
18
18
  `audit comments --fix`.
19
- - **Scriptable.** `--json` prints one JSON object on stdout and suppresses the human progress output.
19
+ - **Scriptable.** `--json` prints one JSON object on stdout instead of the human-readable output.
20
20
  - **CI-ready.** Audits exit non-zero when findings remain, so they gate a pipeline with no extra glue.
21
21
  - **Configurable.** An optional `codefast.config.*` file, validated by a strict schema, adjusts every command.
22
22
 
23
23
  ## Requirements
24
24
 
25
25
  - **Node.js ≥ 24** (the CLI is published as ESM).
26
+ - **TypeScript ≥ 7** to type-check a config written with `defineConfig`, and for
27
+ `arrange simplify --fold-variant-classname`, the one command that loads `typescript` (an optional peer).
26
28
  - **A project root — workspace or single package.** Commands resolve their root by walking up from the current
27
29
  directory: the nearest `pnpm-workspace.yaml` marks a **workspace** (every package under it is in scope), and with no
28
30
  workspace file the nearest `package.json` marks a **single package** (that one package is the whole scope). Only
@@ -75,28 +77,84 @@ codefast audit links # find broken markdown cross-
75
77
  `codefast mirror --no-color`.
76
78
  - **Writing commands write by default; pass `--dry-run` to preview.** The audits are read-only — the one exception is
77
79
  `audit comments --fix`, which repairs section dividers in place.
78
- - **`--json` prints a single JSON object on stdout** and suppresses the human-readable progress output, so any command
79
- can gate a script or a CI job.
80
+ - **`--json` prints a single JSON object on stdout** instead of the human-readable output, so any command can gate a
81
+ script or a CI job.
82
+ - **Set `CODEFAST_VERBOSE=1` (or `true`) for verbose error diagnostics.** On an unexpected infrastructure failure the
83
+ CLI also prints the underlying stack trace. This is distinct from `mirror --verbose`, which adds per-package progress
84
+ detail to that one command.
80
85
 
81
86
  ## Commands at a glance
82
87
 
88
+ ```text
89
+ codefast # Codefast monorepo developer CLI
90
+ │ ├─ --no-color # disable ANSI color output
91
+ │ └─ --version
92
+ │
93
+ ├─ arrange [target] # regroup Tailwind classes in cn()/tv() in render-pipeline order
94
+ │ │ ├─ --dry-run # preview, without writing files
95
+ │ │ ├─ --with-class-name # append className as the final cn() argument (alias: --with-classname)
96
+ │ │ ├─ --cn-import <spec> # override the module specifier when adding a cn import
97
+ │ │ └─ --json
98
+ │ │
99
+ │ ├─ inspect [target] # report long strings, cn nested in tv() (read-only)
100
+ │ │ └─ --json
101
+ │ ├─ simplify [target] # flatten grouped arrays & static cn() to plain strings in tv() slots
102
+ │ │ ├─ --dry-run
103
+ │ │ └─ --fold-variant-class-name # fold cn() overrides into the variant's className option (uses the TS type server)
104
+ │ └─ group <tokens...> # group a pasted class string (stdout: cn(...) or a tv() array with --tv)
105
+ │ ├─ --tv # emit a tv()-style array instead of a cn() call
106
+ │ ├─ --with-class-name
107
+ │ └─ --json
108
+ │
109
+ ├─ audit # source audits (read-only source scans)
110
+ │ ├─ rtl [target] # physical-direction Tailwind classes to make logical / rtl:-paired
111
+ │ ├─ links [target] # markdown links pointing at a missing path/anchor
112
+ │ ├─ imports [target] # banned import forms (React by-name, Zod namespace in front-end, …)
113
+ │ ├─ assertions [target] # double type assertions through unknown/any (x as unknown as T)
114
+ │ ├─ constants [target] # numeric constants whose comment names none of the three kinds
115
+ │ ├─ display-names [target] # token()/tag()/module names breaking the <namespace>:<Name> convention
116
+ │ ├─ publish [target] # what breaks a consumer's install: #/ imports, unshipped targets, @source paths
117
+ │ └─ comments [target] # section dividers not in the one allowed form
118
+ │ └─ --fix # rewrite every fixable divider in place (the only audit that writes)
119
+ │ (each audit also takes [target] + --json)
120
+ │
121
+ ├─ mirror [package] # write package.json#exports from dist/ for workspace packages
122
+ │ ├─ --dry-run
123
+ │ ├─ -v, --verbose
124
+ │ └─ --json
125
+ │
126
+ ├─ pack-slim [package] # strip src, source conditions, dev-only scripts/devDeps, source maps before publish
127
+ │ ├─ --dry-run
128
+ │ ├─ --force # run even if the git working tree has uncommitted changes
129
+ │ └─ --json
130
+ │
131
+ └─ tag [target] # add @since <version> to exported declarations
132
+ ├─ --dry-run
133
+ └─ --json
134
+ ```
135
+
136
+ Every command also responds to `--help`; each command's section below explains what its flags do.
137
+
83
138
  | Command | What it does | Writes? |
84
139
  | --------------------- | -------------------------------------------------------------------------- | ----------------- |
85
140
  | `arrange` | Regroup Tailwind classes in `cn()` / `tv()` calls in render-pipeline order | yes (`--dry-run`) |
86
141
  | `mirror` | Write each package's `package.json#exports` from its built `dist/` | yes (`--dry-run`) |
87
142
  | `pack-slim` | Strip the dev-only surface from a package right before publish | yes (`--dry-run`) |
88
143
  | `tag` | Stamp `@since <version>` on exported declarations that lack one | yes (`--dry-run`) |
89
- | `audit links` | Report markdown cross-references that resolve to nothing | no |
90
144
  | `audit rtl` | Report physical-direction Tailwind classes that should be logical | no |
145
+ | `audit links` | Report markdown cross-references that resolve to nothing | no |
91
146
  | `audit imports` | Enforce the import policy (React by-name, Zod namespace in front-end) | no (report only) |
92
- | `audit comments` | Check doc-comment conventions; repair section dividers | `--fix` only |
147
+ | `audit assertions` | Report double type assertions through `unknown` / `any`, tests included | no |
148
+ | `audit constants` | Require every tuned numeric constant to name the kind of number it is | no |
93
149
  | `audit display-names` | Enforce the `namespace:Name` display-name convention | no |
150
+ | `audit publish` | Report what would break a consumer's install of a published package | no |
151
+ | `audit comments` | Check doc-comment conventions; repair section dividers | `--fix` only |
94
152
 
95
- **Which of these are for you?** `arrange`, `mirror`, `pack-slim`, `tag`, and `audit links` are general-purpose — they
96
- work for any pnpm workspace or single package that builds with `tsc`. The other four audits encode codefast's own house
97
- style (logical Tailwind directions, named React imports, a specific comment/divider grammar, a `namespace:Name` scheme
98
- for `@codefast/di` tokens). Adopt them if they fit your project; otherwise skip them, or use an allowlist to narrow
99
- their scope.
153
+ **Which of these are for you?** `arrange`, `mirror`, `pack-slim`, `tag`, `audit links`, `audit assertions`, and
154
+ `audit publish` are general-purpose — they work for any pnpm workspace or single package that builds with `tsc`. The
155
+ other five audits encode codefast's own house style (logical Tailwind directions, named React imports, a specific
156
+ comment/divider grammar, a `namespace:Name` scheme for `@codefast/di` tokens, a named kind for every tuned numeric
157
+ constant). Adopt them if they fit your project; otherwise skip them, or use an allowlist to narrow their scope.
100
158
 
101
159
  ## `arrange`
102
160
 
@@ -120,13 +178,6 @@ intentional; pass such a file explicitly to process it.
120
178
  `#lib/utils` re-export, any `…/utils` path, or a dedicated `cn.ts` module — so an unrelated local `cn` is left alone.
121
179
  Long static JSX `className` strings are regrouped regardless of where `cn` comes from.
122
180
 
123
- | Flag | Description |
124
- | -------------------- | ----------------------------------------------------------------------------- |
125
- | `--dry-run` | Preview suggested replacements without writing files. |
126
- | `--with-classname` | Append `className` as the final `cn()` argument (alias: `--with-class-name`). |
127
- | `--cn-import <spec>` | Override the module specifier used when a missing `cn` import is added. |
128
- | `--json` | Print one JSON summary on stdout (suppresses human progress). |
129
-
130
181
  Exits `1` when the `arrange.onAfterWrite` hook fails, `0` otherwise.
131
182
 
132
183
  ### `arrange inspect [target]`
@@ -139,12 +190,6 @@ Flattens grouped arrays and static-only `cn()` calls back to plain strings in `t
139
190
  In a mixed `cn()` call it coalesces only _adjacent_ static literals and keeps argument order, so tailwind-merge
140
191
  precedence is unchanged (a later argument still overrides an earlier one).
141
192
 
142
- | Flag | Description |
143
- | -------------------------- | -------------------------------------------------------------------------------------------------------- |
144
- | `--dry-run` | Show what simplify would change without writing files. |
145
- | `--fold-variant-classname` | Fold `cn()` overrides into a variant function's `className` option (alias: `--fold-variant-class-name`). |
146
- | `--json` | Print one JSON summary on stdout. |
147
-
148
193
  With `--fold-variant-classname`, `cn(buttonVariants({ size: "sm" }), "flex-1")` becomes
149
194
  `buttonVariants({ size: "sm", className: "flex-1" })`, and a dynamic or multi-part override folds into a `className`
150
195
  array. The fold fires only when the native TypeScript type server confirms the callee's options accept a `className` (or
@@ -162,11 +207,7 @@ codefast arrange group "relative flex h-10 w-full items-center rounded-md bg-pri
162
207
  codefast arrange group --tv "flex items-center gap-2"
163
208
  ```
164
209
 
165
- | Flag | Description |
166
- | ------------------ | ----------------------------------------------------------------------------- |
167
- | `--tv` | Emit a `tv()`-style array instead of a `cn()` call. |
168
- | `--with-classname` | Append `className` as the final `cn()` argument (alias: `--with-class-name`). |
169
- | `--json` | Emit `{ schemaVersion, primaryLine, bucketsCommentLine }` on stdout. |
210
+ With `--json`, that object is `{ schemaVersion, primaryLine, bucketsCommentLine }`.
170
211
 
171
212
  ## `mirror`
172
213
 
@@ -181,12 +222,6 @@ codefast mirror packages/ui # one package (path relative to repo root)
181
222
  codefast mirror --dry-run # report changes without writing
182
223
  ```
183
224
 
184
- | Flag | Description |
185
- | ----------------- | ------------------------------------------------------------- |
186
- | `--dry-run` | Report what would change without writing any `package.json`. |
187
- | `-v`, `--verbose` | Print extra diagnostics. |
188
- | `--json` | Print one JSON summary on stdout (suppresses human progress). |
189
-
190
225
  Exits `1` when any package fails, `0` otherwise.
191
226
 
192
227
  ### Per-package `mirror` configuration
@@ -217,12 +252,13 @@ apply (see the [Configuration](#configuration) example for their shape):
217
252
  ## `pack-slim`
218
253
 
219
254
  Slims a published package down to what a consumer's `tsc` and Node actually read, so the npm tarball ships `dist`
220
- runtime and types only. Where `mirror` writes the full exports — including the `source` condition — for local
221
- development, `pack-slim` removes that development lane for publish: it drops `src` from `files`, every `source`
222
- condition from `exports`/`imports`, every `imports` entry left pointing outside `files`, every script that is not an
223
- install or publish lifecycle hook, `devDependencies`, and the `dist` source maps plus their dangling `sourceMappingURL`
224
- directives. Private packages are skipped. It is meant to run on an ephemeral CI checkout right before publish, so its
225
- result is **never committed**.
255
+ runtime and types, plus any `src` subtree an export still points into (a raw stylesheet export such as `./css/*`). Where
256
+ `mirror` writes the full exports — including the `source` condition — for local development, `pack-slim` removes that
257
+ development lane for publish: it drops the rest of `src` from `files`, every `source` condition from
258
+ `exports`/`imports`, every `imports` entry left pointing outside `files`, every script that is not an install or publish
259
+ lifecycle hook, `devDependencies`, and the `dist` source maps plus their dangling `sourceMappingURL` directives. Private
260
+ packages are skipped. It is meant to run on an ephemeral CI checkout right before publish, so its result is **never
261
+ committed**.
226
262
 
227
263
  Because that result must never be committed, `pack-slim` refuses to write when the git working tree has uncommitted
228
264
  tracked changes — a guard against an accidental local run landing on real work. `--dry-run` is exempt (it writes
@@ -235,12 +271,6 @@ codefast pack-slim packages/ui # one package (path relative to repo root)
235
271
  codefast pack-slim --dry-run # report what would be stripped without touching a file
236
272
  ```
237
273
 
238
- | Flag | Description |
239
- | ----------- | ----------------------------------------------------------------- |
240
- | `--dry-run` | Report what would be stripped without touching any file. |
241
- | `--force` | Run even if the git working tree has uncommitted tracked changes. |
242
- | `--json` | Print one JSON summary on stdout (suppresses human progress). |
243
-
244
274
  Exits `1` when any package fails, `0` otherwise.
245
275
 
246
276
  ## `tag`
@@ -256,11 +286,6 @@ codefast tag packages/ui/src # tag one directory or file
256
286
  codefast tag --dry-run # summary only, no writes
257
287
  ```
258
288
 
259
- | Flag | Description |
260
- | ----------- | ------------------------------------------------------------- |
261
- | `--dry-run` | Show summary without writing files. |
262
- | `--json` | Print one JSON summary on stdout (suppresses human progress). |
263
-
264
289
  Exits `1` when no target is selected, when any target fails, or when the `tag.onAfterWrite` hook fails.
265
290
 
266
291
  ## `audit`
@@ -316,6 +341,50 @@ codefast audit imports --json # machine-readable summary
316
341
  Configure exceptions via `audit.imports.allowlist` — each entry is the offending source text as written or
317
342
  `repo/relative/path.tsx:<text>`.
318
343
 
344
+ ### `audit assertions`
345
+
346
+ Reports every double type assertion through `unknown` or `any` in `.ts`/`.tsx` files, tests included —
347
+ `x as unknown as T`, `(x as unknown) as T`, `<T><unknown>x` and the `any` spellings. The pair tells the compiler two
348
+ types are unrelated and silences it anyway; no oxlint rule targets it (`typescript/no-unnecessary-type-assertion`
349
+ catches the redundant ones only). Make the types agree, narrow with a type guard, or — where the erasure is the point —
350
+ keep it with a directive that states why, on the assertion's line or the line above:
351
+
352
+ ```ts
353
+ // codefast-allow-double-assertion: the host stores each plugin's config untyped; the plugin owns its shape
354
+ const config = host.configFor(plugin.id) as unknown as PluginConfig;
355
+ ```
356
+
357
+ A directive with no reason, or one that keeps no assertion, is itself reported, so a kept assertion cannot outlive its
358
+ cause.
359
+
360
+ ```bash
361
+ codefast audit assertions # whole repo
362
+ codefast audit assertions packages/di # explicit target
363
+ codefast audit assertions --json # machine-readable summary
364
+ ```
365
+
366
+ Configure exceptions via `audit.assertions.allowlist` — each entry is the assertion as written or
367
+ `repo/relative/path.ts:<assertion>` — though the inline directive keeps the reason beside the code it excuses.
368
+
369
+ ### `audit publish`
370
+
371
+ Reports what would break a consumer's install of a published package, while it can still be fixed:
372
+
373
+ - a `#/`-prefixed internal import, which Node's ESM resolver rejects on Node 24 before 24.14 while every in-repo runner
374
+ accepts it;
375
+ - an `exports`/`imports` target the slimmed manifest does not ship, found by applying the same slim as `pack-slim`;
376
+ - a shipped stylesheet whose Tailwind `@source` paths reach none of the files the tarball ships. A workspace still
377
+ resolves them against `src`, so only the published layout shows it: the consumer's Tailwind registers no class names
378
+ and the components render unstyled.
379
+
380
+ It reads the built output, so run it after the build; a `files` entry missing on disk, such as an unbuilt `dist`, is
381
+ named in the report. Private packages are skipped, and it takes no allowlist.
382
+
383
+ ```bash
384
+ codefast audit publish # every published package in the workspace
385
+ codefast audit publish --json # machine-readable summary
386
+ ```
387
+
319
388
  ### `audit comments`
320
389
 
321
390
  _House style._ Checks doc-comment conventions. Section dividers not in the one allowed form are mechanical, so `--fix`
@@ -331,11 +400,6 @@ codefast audit comments --fix # rewrite fixable dividers in place
331
400
  codefast audit comments --json # machine-readable summary
332
401
  ```
333
402
 
334
- | Flag | Description |
335
- | -------- | ---------------------------------------------------- |
336
- | `--fix` | Rewrite every mechanically fixable divider in place. |
337
- | `--json` | Print one JSON summary on stdout. |
338
-
339
403
  Configure exceptions via `audit.comments.allowlist` — each entry is a divider line as written or
340
404
  `repo/relative/path.ts:<divider>`.
341
405
 
@@ -356,6 +420,30 @@ codefast audit display-names --json # machine-readable summary
356
420
  Configure exceptions via `audit.displayNames.allowlist` — each entry is the call as written, through its closing quote
357
421
  (or parenthesis when the name is the only argument), or `repo/relative/path.ts:<call>`.
358
422
 
423
+ ### `audit constants`
424
+
425
+ _House style._ Holds library sources to one rule for tuned numbers: a numeric constant says which kind of number it is.
426
+ It flags an upper-case `const NAME = <number>` in a `.ts`/`.tsx` file under a `src` directory — tests, benchmarks, apps,
427
+ and examples are out of scope — unless the comment directly above it, a `/* … */` block or a run of `//` lines, names
428
+ one of three kinds:
429
+
430
+ - `a constant of the machine` — a width of the platform the code runs on;
431
+ - `a value the contract fixes` — a number the documented contract promises;
432
+ - `derived from bind-time data` — a figure computed from what a caller hands in.
433
+
434
+ A count that merely looks reasonable is none of them, so it is reported. `0`, `1`, and `-1` are skipped: they stand for
435
+ absence or identity, not for a tuned size.
436
+
437
+ ```bash
438
+ codefast audit constants # uses audit.constants.target from config
439
+ codefast audit constants packages/di/src # explicit target
440
+ codefast audit constants --json # machine-readable summary
441
+ ```
442
+
443
+ With no `[target]`, the scan root is `audit.constants.target` from the config; when neither is set the command fails.
444
+ Configure exceptions via `audit.constants.allowlist` — each entry is the constant's name or `repo/relative/path.ts:NAME`
445
+ — for a measured policy that has to stay a tuned number.
446
+
359
447
  ## Configuration
360
448
 
361
449
  **You do not need a config file.** Every command has sensible defaults and works with none. Add a `codefast.config.*`
@@ -489,7 +577,12 @@ export default {
489
577
  links: { allowlist: [] }, // bare link target, or `repo/relative/doc.md:target`
490
578
  comments: { allowlist: [] }, // divider as written, or `repo/relative/path.ts:<divider>`
491
579
  imports: { allowlist: [] }, // offending import text as written, or `repo/relative/path.tsx:<text>`
580
+ assertions: { allowlist: [] }, // assertion as written, or `repo/relative/path.ts:<assertion>`
492
581
  displayNames: { allowlist: [] }, // call as written, or `repo/relative/path.ts:<call>`
582
+ constants: {
583
+ target: "packages/core/src", // default scan root when no CLI arg is passed
584
+ allowlist: [], // constant name, or `repo/relative/path.ts:NAME`
585
+ },
493
586
  },
494
587
  };
495
588
  ```
@@ -540,7 +633,10 @@ pnpm run cli:audit:links # codefast audit links
540
633
  pnpm run cli:audit:rtl # codefast audit rtl
541
634
  pnpm run cli:audit:comments # codefast audit comments
542
635
  pnpm run cli:audit:imports # codefast audit imports
636
+ pnpm run cli:audit:assertions # codefast audit assertions
543
637
  pnpm run cli:audit:display-names # codefast audit display-names
638
+ pnpm run cli:audit:constants # codefast audit constants
639
+ pnpm run cli:audit:publish # codefast audit publish
544
640
  ```
545
641
 
546
642
  `pnpm run version-packages` runs `changeset version` and then `codefast tag`, so published APIs are stamped at release,
@@ -1,27 +1,27 @@
1
1
  import { Command } from "commander";
2
- import { formatArrangeGroupJsonOutput } from "#/arrange/group/cli-result";
3
- import { arrangeSuggestGroupsRequestSchema } from "#/arrange/group/cli-schema";
4
- import { presentArrangeGroupResult } from "#/arrange/group/output";
5
- import { suggestCnGroupsFromCli } from "#/arrange/group/suggest";
6
- import { formatArrangeAnalyzeJsonOutput } from "#/arrange/inspect/cli-result";
7
- import { arrangeAnalyzeDirectoryRequestSchema } from "#/arrange/inspect/cli-schema";
8
- import { presentAnalyzeReport } from "#/arrange/inspect/output";
9
- import { runArrangeInspect } from "#/arrange/inspect/run";
10
- import { prepareArrangeWorkspace } from "#/arrange/prepare";
11
- import { exitCodeForArrangeResult, formatArrangeJsonOutput } from "#/arrange/regroup/cli-result";
12
- import { arrangeRunRequestSchema } from "#/arrange/regroup/cli-schema";
13
- import { presentArrangeResult, presentGroupFilePreviewFromWork } from "#/arrange/regroup/output";
14
- import { runArrange } from "#/arrange/regroup/run";
15
- import { formatArrangeSimplifyJsonOutput } from "#/arrange/simplify/cli-result";
16
- import { arrangeSimplifyRunRequestSchema } from "#/arrange/simplify/cli-schema";
17
- import { presentSimplifyResult } from "#/arrange/simplify/output";
18
- import { runArrangeSimplify } from "#/arrange/simplify/run";
19
- import { applyCommandPipeline, registerPipelineSubcommand } from "#/core/cli/command-pipeline";
20
- import { consumeCliAppError } from "#/core/cli/result-handle";
21
- import { CLI_EXIT_SUCCESS } from "#/core/exit-codes";
22
- import { nodeFilesystem } from "#/core/filesystem/node";
23
- import { logger } from "#/core/logger";
24
- import { parseWithSchema } from "#/core/schema-parse";
2
+ import { formatArrangeGroupJsonOutput } from "#arrange/group/cli-result";
3
+ import { arrangeSuggestGroupsRequestSchema } from "#arrange/group/cli-schema";
4
+ import { presentArrangeGroupResult } from "#arrange/group/output";
5
+ import { suggestCnGroupsFromCli } from "#arrange/group/suggest";
6
+ import { formatArrangeAnalyzeJsonOutput } from "#arrange/inspect/cli-result";
7
+ import { arrangeAnalyzeDirectoryRequestSchema } from "#arrange/inspect/cli-schema";
8
+ import { presentAnalyzeReport } from "#arrange/inspect/output";
9
+ import { runArrangeInspect } from "#arrange/inspect/run";
10
+ import { prepareArrangeWorkspace } from "#arrange/prepare";
11
+ import { exitCodeForArrangeResult, formatArrangeJsonOutput } from "#arrange/regroup/cli-result";
12
+ import { arrangeRunRequestSchema } from "#arrange/regroup/cli-schema";
13
+ import { presentArrangeResult, presentGroupFilePreviewFromWork } from "#arrange/regroup/output";
14
+ import { runArrange } from "#arrange/regroup/run";
15
+ import { formatArrangeSimplifyJsonOutput } from "#arrange/simplify/cli-result";
16
+ import { arrangeSimplifyRunRequestSchema } from "#arrange/simplify/cli-schema";
17
+ import { presentSimplifyResult } from "#arrange/simplify/output";
18
+ import { runArrangeSimplify } from "#arrange/simplify/run";
19
+ import { applyCommandPipeline, registerPipelineSubcommand } from "#core/cli/command-pipeline";
20
+ import { consumeCliAppError } from "#core/cli/result-handle";
21
+ import { CLI_EXIT_SUCCESS } from "#core/exit-codes";
22
+ import { nodeFilesystem } from "#core/filesystem/node";
23
+ import { logger } from "#core/logger";
24
+ import { parseWithSchema } from "#core/schema-parse";
25
25
  const targetHelp = "Directory or file (default: nearest package directory from cwd)";
26
26
  const prepareWorkspace = (fs, input) => prepareArrangeWorkspace(fs, { currentWorkingDirectory: input.currentWorkingDirectory, rawTarget: input.rawArg });
27
27
  const regroupPipeline = {
@@ -58,7 +58,6 @@ const inspectPipeline = {
58
58
  name: "inspect",
59
59
  description: "Report long strings, nested cn in tv(), and related findings (read-only)",
60
60
  positional: { name: "[target]", help: targetHelp },
61
- jsonHelp: "Print one JSON object on stdout instead of a human report",
62
61
  schema: arrangeAnalyzeDirectoryRequestSchema,
63
62
  prepare: prepareWorkspace,
64
63
  buildRequest: ({ prelude }) => ({ analyzeRootPath: prelude.resolvedTarget }),
@@ -113,7 +112,7 @@ export function createArrangeCommand() {
113
112
  .argument("<tokens...>", "Class tokens (quote a single string if it contains spaces)")
114
113
  .option("--tv", "Emit tv()-style array instead of cn() call", false)
115
114
  .option("--with-classname, --with-class-name", "Append className as final cn() argument", false)
116
- .option("--json", "Print one JSON object on stdout instead of plain lines", false)
115
+ .option("--json", "Print one JSON object on stdout instead of the human-readable output", false)
117
116
  .action(async (classTokenSeries, opts) => {
118
117
  const parsed = parseWithSchema(arrangeSuggestGroupsRequestSchema, {
119
118
  inlineClasses: classTokenSeries.join(" ").trim(),
@@ -1,5 +1,5 @@
1
- import type { DomainAstNode } from "#/arrange/domain/ast/ast-node";
2
- import type { ForEachStringLiteralInClassExpressionOptions, TailwindClassLiteral } from "#/arrange/domain/types";
1
+ import type { DomainAstNode } from "#arrange/domain/ast/ast-node";
2
+ import type { ForEachStringLiteralInClassExpressionOptions, TailwindClassLiteral } from "#arrange/domain/types";
3
3
  /**
4
4
  * Visits every static class literal reachable inside a class expression.
5
5
  *
@@ -1,5 +1,5 @@
1
- import { DomainBinaryOperator, DomainSyntaxKind, isDomainArrayLiteralExpression, isDomainTailwindClassLiteral, } from "#/arrange/domain/ast/ast-node";
2
- import { MAX_CLASS_EXPR_DEPTH } from "#/arrange/domain/constants";
1
+ import { DomainBinaryOperator, DomainSyntaxKind, isDomainArrayLiteralExpression, isDomainTailwindClassLiteral, } from "#arrange/domain/ast/ast-node";
2
+ import { MAX_CLASS_EXPR_DEPTH } from "#arrange/domain/constants";
3
3
  /**
4
4
  * Visits every static class literal reachable inside a class expression.
5
5
  *
@@ -1,5 +1,5 @@
1
- import type { DomainJsxAttribute } from "#/arrange/domain/ast/ast-node";
2
- import type { JsxClassNameStatic } from "#/arrange/domain/types";
1
+ import type { DomainJsxAttribute } from "#arrange/domain/ast/ast-node";
2
+ import type { JsxClassNameStatic } from "#arrange/domain/types";
3
3
  /**
4
4
  * Extracts the static literal of a JSX `className` attribute, or `undefined` when it is not static.
5
5
  *
@@ -1,4 +1,4 @@
1
- import { isDomainIdentifier, isDomainJsxExpression, isDomainTailwindClassLiteral } from "#/arrange/domain/ast/ast-node";
1
+ import { isDomainIdentifier, isDomainJsxExpression, isDomainTailwindClassLiteral } from "#arrange/domain/ast/ast-node";
2
2
  /**
3
3
  * Extracts the static literal of a JSX `className` attribute, or `undefined` when it is not static.
4
4
  *
@@ -1,5 +1,5 @@
1
- import type { DomainCallExpression, DomainObjectLiteralExpression, DomainSourceFile } from "#/arrange/domain/ast/ast-node";
2
- import type { StringNode, TailwindClassLiteral } from "#/arrange/domain/types";
1
+ import type { DomainCallExpression, DomainObjectLiteralExpression, DomainSourceFile } from "#arrange/domain/ast/ast-node";
2
+ import type { StringNode, TailwindClassLiteral } from "#arrange/domain/types";
3
3
  type StringNodeVisitor = (classLiteral: TailwindClassLiteral, sourceFile: DomainSourceFile, cnCall?: DomainCallExpression) => void;
4
4
  /**
5
5
  * Visits every class literal reachable inside a `tv({ ... })` object, including `cn()` arguments.
@@ -1,8 +1,8 @@
1
- import { isDomainArrayLiteralExpression, isDomainCallExpression, isDomainObjectLiteralExpression, isDomainPropertyAssignment, isDomainSpreadElement, isDomainTailwindClassLiteral, forEachDomainChild, } from "#/arrange/domain/ast/ast-node";
2
- import { CN_APPLY_LITERAL_WALK_OPTS, collectUnconditionalTailwindLiteralsFromCnArguments, forEachStringLiteralInClassExpression, isUnsafeLiteralForCnStyleApplySplit, } from "#/arrange/domain/ast/collectors-cn";
3
- import { buildKnownCnTvBindings, isCnOrTvIdentifier, propertyAssignmentNameText } from "#/arrange/domain/ast/helpers";
4
- import { APPLY_MIN_TOKENS, MAX_OBJECT_DEPTH } from "#/arrange/domain/constants";
5
- import { tokenizeClassString } from "#/arrange/domain/tailwind-token";
1
+ import { isDomainArrayLiteralExpression, isDomainCallExpression, isDomainObjectLiteralExpression, isDomainPropertyAssignment, isDomainSpreadElement, isDomainTailwindClassLiteral, forEachDomainChild, } from "#arrange/domain/ast/ast-node";
2
+ import { CN_APPLY_LITERAL_WALK_OPTS, collectUnconditionalTailwindLiteralsFromCnArguments, forEachStringLiteralInClassExpression, isUnsafeLiteralForCnStyleApplySplit, } from "#arrange/domain/ast/collectors-cn";
3
+ import { buildKnownCnTvBindings, isCnOrTvIdentifier, propertyAssignmentNameText } from "#arrange/domain/ast/helpers";
4
+ import { APPLY_MIN_TOKENS, MAX_OBJECT_DEPTH } from "#arrange/domain/constants";
5
+ import { tokenizeClassString } from "#arrange/domain/tailwind-token";
6
6
  /**
7
7
  * Visits every class literal reachable inside a `tv({ ... })` object, including `cn()` arguments.
8
8
  *
@@ -1,5 +1,5 @@
1
- import type { DomainAstNode, DomainCallExpression, DomainPropertyAssignment, DomainSourceFile } from "#/arrange/domain/ast/ast-node";
2
- import { applyEditsDescending } from "#/core/source-text-edit";
1
+ import type { DomainAstNode, DomainCallExpression, DomainPropertyAssignment, DomainSourceFile } from "#arrange/domain/ast/ast-node";
2
+ import { applyEditsDescending } from "#core/source-text-edit";
3
3
  /**
4
4
  * Builds a set of local binding names that are imported from a known cn/tv
5
5
  * module in `sourceFile`.
@@ -1,6 +1,6 @@
1
- import { isDomainIdentifier, isDomainImportDeclaration, isDomainNamedImports, isDomainNamespaceImport, isDomainPropertyAccessExpression, isDomainStringLiteral, lineOfSourcePosition, } from "#/arrange/domain/ast/ast-node";
2
- import { EMPTY_CN_TV_BINDINGS } from "#/arrange/domain/constants";
3
- import { applyEditsDescending, indentOfLineContaining } from "#/core/source-text-edit";
1
+ import { isDomainIdentifier, isDomainImportDeclaration, isDomainNamedImports, isDomainNamespaceImport, isDomainPropertyAccessExpression, isDomainStringLiteral, lineOfSourcePosition, } from "#arrange/domain/ast/ast-node";
2
+ import { EMPTY_CN_TV_BINDINGS } from "#arrange/domain/constants";
3
+ import { applyEditsDescending, indentOfLineContaining } from "#core/source-text-edit";
4
4
  /**
5
5
  * Known module specifiers that export `cn` / `tv`.
6
6
  */
@@ -12,7 +12,6 @@ const KNOWN_CN_TV_MODULES = new Set([
12
12
  // from "tailwind-variants"; new code should prefer "@codefast/tailwind-variants".
13
13
  "tailwind-variants",
14
14
  "#lib/utils",
15
- "#/lib/utils",
16
15
  "~/lib/utils",
17
16
  "@/lib/utils",
18
17
  ]);
@@ -1,4 +1,4 @@
1
- import type { DomainSourceFile } from "#/arrange/domain/ast/ast-node";
1
+ import type { DomainSourceFile } from "#arrange/domain/ast/ast-node";
2
2
  /**
3
3
  * A planned text replacement produced by the simplify pass.
4
4
  *
@@ -1,8 +1,8 @@
1
- import { forEachDomainChild, isDomainArrayLiteralExpression, isDomainCallExpression, isDomainJsxAttribute, isDomainJsxExpression, isDomainObjectLiteralExpression, isDomainPropertyAssignment, isDomainSpreadElement, isDomainTailwindClassLiteral, } from "#/arrange/domain/ast/ast-node";
2
- import { buildKnownCnTvBindings, isCnOrTvIdentifier } from "#/arrange/domain/ast/helpers";
3
- import { MAX_OBJECT_DEPTH } from "#/arrange/domain/constants";
4
- import { escapeTsStringLiteralContent } from "#/arrange/domain/source-text-formatters";
5
- import { indentOfLineContaining } from "#/core/source-text-edit";
1
+ import { forEachDomainChild, isDomainArrayLiteralExpression, isDomainCallExpression, isDomainJsxAttribute, isDomainJsxExpression, isDomainObjectLiteralExpression, isDomainPropertyAssignment, isDomainSpreadElement, isDomainTailwindClassLiteral, } from "#arrange/domain/ast/ast-node";
2
+ import { buildKnownCnTvBindings, isCnOrTvIdentifier } from "#arrange/domain/ast/helpers";
3
+ import { MAX_OBJECT_DEPTH } from "#arrange/domain/constants";
4
+ import { escapeTsStringLiteralContent } from "#arrange/domain/source-text-formatters";
5
+ import { indentOfLineContaining } from "#core/source-text-edit";
6
6
  function toFlatString(text) {
7
7
  return `"${escapeTsStringLiteralContent(text.trim())}"`;
8
8
  }
@@ -1,5 +1,5 @@
1
- import type { DomainSourceFile } from "#/arrange/domain/ast/ast-node";
2
- import type { GroupTarget, PlannedGroupEdit } from "#/arrange/domain/types";
1
+ import type { DomainSourceFile } from "#arrange/domain/ast/ast-node";
2
+ import type { GroupTarget, PlannedGroupEdit } from "#arrange/domain/types";
3
3
  /**
4
4
  * Resolves the source position where a group target's replacement begins.
5
5
  *