@codefast/cli 0.5.0-canary.5 → 1.0.0-canary.7

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 (274) hide show
  1. package/README.md +106 -480
  2. package/dist/arrange/analyze.js +25 -0
  3. package/dist/arrange/analyze.js.map +1 -0
  4. package/dist/arrange/cli-schema.js +29 -0
  5. package/dist/arrange/cli-schema.js.map +1 -0
  6. package/dist/arrange/command.js +170 -0
  7. package/dist/arrange/command.js.map +1 -0
  8. package/dist/arrange/domain/analyze-service.js +122 -0
  9. package/dist/arrange/domain/analyze-service.js.map +1 -0
  10. package/dist/arrange/domain/ast/ast-node.js +240 -0
  11. package/dist/arrange/domain/ast/ast-node.js.map +1 -0
  12. package/dist/arrange/domain/ast/collectors-cn.js +81 -0
  13. package/dist/arrange/domain/ast/collectors-cn.js.map +1 -0
  14. package/dist/arrange/domain/ast/collectors-jsx.js +24 -0
  15. package/dist/arrange/domain/ast/collectors-jsx.js.map +1 -0
  16. package/dist/arrange/domain/ast/collectors-tv.js +319 -0
  17. package/dist/arrange/domain/ast/collectors-tv.js.map +1 -0
  18. package/dist/arrange/domain/ast/helpers.js +151 -0
  19. package/dist/arrange/domain/ast/helpers.js.map +1 -0
  20. package/dist/arrange/domain/ast/simplify-targets.js +161 -0
  21. package/dist/arrange/domain/ast/simplify-targets.js.map +1 -0
  22. package/dist/arrange/domain/ast/targets.js +182 -0
  23. package/dist/arrange/domain/ast/targets.js.map +1 -0
  24. package/dist/arrange/domain/constants.js +225 -0
  25. package/dist/arrange/domain/constants.js.map +1 -0
  26. package/dist/arrange/domain/grouping-service.js +128 -0
  27. package/dist/arrange/domain/grouping-service.js.map +1 -0
  28. package/dist/arrange/domain/grouping.js +435 -0
  29. package/dist/arrange/domain/grouping.js.map +1 -0
  30. package/dist/arrange/domain/imports.js +160 -0
  31. package/dist/arrange/domain/imports.js.map +1 -0
  32. package/dist/arrange/domain/source-text-formatters.js +100 -0
  33. package/dist/arrange/domain/source-text-formatters.js.map +1 -0
  34. package/dist/arrange/domain/tailwind-token.js +50 -0
  35. package/dist/arrange/domain/tailwind-token.js.map +1 -0
  36. package/dist/arrange/domain/token-classifier.js +448 -0
  37. package/dist/arrange/domain/token-classifier.js.map +1 -0
  38. package/dist/arrange/domain/types.js +11 -0
  39. package/dist/arrange/domain/types.js.map +1 -0
  40. package/dist/arrange/output.js +120 -0
  41. package/dist/arrange/output.js.map +1 -0
  42. package/dist/arrange/process-file.js +44 -0
  43. package/dist/arrange/process-file.js.map +1 -0
  44. package/dist/arrange/resolve-target.js +33 -0
  45. package/dist/arrange/resolve-target.js.map +1 -0
  46. package/dist/arrange/scan-target.js +30 -0
  47. package/dist/arrange/scan-target.js.map +1 -0
  48. package/dist/arrange/simplify-process-file.js +29 -0
  49. package/dist/arrange/simplify-process-file.js.map +1 -0
  50. package/dist/arrange/simplify-sync.js +29 -0
  51. package/dist/arrange/simplify-sync.js.map +1 -0
  52. package/dist/arrange/source-parse.js +17 -0
  53. package/dist/arrange/source-parse.js.map +1 -0
  54. package/dist/arrange/suggest.js +14 -0
  55. package/dist/arrange/suggest.js.map +1 -0
  56. package/dist/arrange/sync.js +48 -0
  57. package/dist/arrange/sync.js.map +1 -0
  58. package/dist/arrange/typescript-ast-translator.js +455 -0
  59. package/dist/arrange/typescript-ast-translator.js.map +1 -0
  60. package/dist/arrange/workspace.js +31 -0
  61. package/dist/arrange/workspace.js.map +1 -0
  62. package/dist/audit/cli-schema.js +22 -0
  63. package/dist/audit/cli-schema.js.map +1 -0
  64. package/dist/audit/command.js +60 -0
  65. package/dist/audit/command.js.map +1 -0
  66. package/dist/audit/domain/audit-file.js +101 -0
  67. package/dist/audit/domain/audit-file.js.map +1 -0
  68. package/dist/audit/domain/mappings.js +103 -0
  69. package/dist/audit/domain/mappings.js.map +1 -0
  70. package/dist/audit/domain/tokenize.js +83 -0
  71. package/dist/audit/domain/tokenize.js.map +1 -0
  72. package/dist/audit/domain/types.js +2 -0
  73. package/dist/audit/domain/types.js.map +1 -0
  74. package/dist/audit/output.js +44 -0
  75. package/dist/audit/output.js.map +1 -0
  76. package/dist/audit/prepare.js +42 -0
  77. package/dist/audit/prepare.js.map +1 -0
  78. package/dist/audit/run.js +57 -0
  79. package/dist/audit/run.js.map +1 -0
  80. package/dist/{bin.mjs → bin.js} +2 -4
  81. package/dist/bin.js.map +1 -0
  82. package/dist/cli.js +45 -0
  83. package/dist/cli.js.map +1 -0
  84. package/dist/core/cli/format-error.js +19 -0
  85. package/dist/core/cli/format-error.js.map +1 -0
  86. package/dist/core/cli/global-options.js +10 -0
  87. package/dist/core/cli/global-options.js.map +1 -0
  88. package/dist/core/cli/positional.js +9 -0
  89. package/dist/core/cli/positional.js.map +1 -0
  90. package/dist/core/cli/result-handle.js +69 -0
  91. package/dist/core/cli/result-handle.js.map +1 -0
  92. package/dist/core/config/loader.js +88 -0
  93. package/dist/core/config/loader.js.map +1 -0
  94. package/dist/core/config/schema.js +97 -0
  95. package/dist/core/config/schema.js.map +1 -0
  96. package/dist/core/config/warnings.js +12 -0
  97. package/dist/core/config/warnings.js.map +1 -0
  98. package/dist/core/config.js +18 -0
  99. package/dist/core/config.js.map +1 -0
  100. package/dist/core/errors.js +58 -0
  101. package/dist/core/errors.js.map +1 -0
  102. package/dist/core/exit-codes.js +15 -0
  103. package/dist/core/exit-codes.js.map +1 -0
  104. package/dist/core/filesystem/node.js +33 -0
  105. package/dist/core/filesystem/node.js.map +1 -0
  106. package/dist/core/filesystem/port.js +2 -0
  107. package/dist/core/filesystem/port.js.map +1 -0
  108. package/dist/core/glob.js +20 -0
  109. package/dist/core/glob.js.map +1 -0
  110. package/dist/core/logger.js +13 -0
  111. package/dist/core/logger.js.map +1 -0
  112. package/dist/core/result.js +16 -0
  113. package/dist/core/result.js.map +1 -0
  114. package/dist/core/schema-parse.js +21 -0
  115. package/dist/core/schema-parse.js.map +1 -0
  116. package/dist/core/source-text-edit.js +62 -0
  117. package/dist/core/source-text-edit.js.map +1 -0
  118. package/dist/core/verbose-diagnostics.js +9 -0
  119. package/dist/core/verbose-diagnostics.js.map +1 -0
  120. package/dist/core/workspace/resolver.js +208 -0
  121. package/dist/core/workspace/resolver.js.map +1 -0
  122. package/dist/core/workspace/typescript-walk.js +41 -0
  123. package/dist/core/workspace/typescript-walk.js.map +1 -0
  124. package/dist/mirror/cli-result.js +20 -0
  125. package/dist/mirror/cli-result.js.map +1 -0
  126. package/dist/mirror/cli-schema.js +11 -0
  127. package/dist/mirror/cli-schema.js.map +1 -0
  128. package/dist/mirror/command.js +73 -0
  129. package/dist/mirror/command.js.map +1 -0
  130. package/dist/mirror/dist-filesystem-impl.js +53 -0
  131. package/dist/mirror/dist-filesystem-impl.js.map +1 -0
  132. package/dist/mirror/domain/constants.js +21 -0
  133. package/dist/mirror/domain/constants.js.map +1 -0
  134. package/dist/mirror/domain/dirent-guard.js +16 -0
  135. package/dist/mirror/domain/dirent-guard.js.map +1 -0
  136. package/dist/mirror/domain/dist-filesystem.js +2 -0
  137. package/dist/mirror/domain/dist-filesystem.js.map +1 -0
  138. package/dist/mirror/domain/errors.js +19 -0
  139. package/dist/mirror/domain/errors.js.map +1 -0
  140. package/dist/mirror/domain/exports.js +284 -0
  141. package/dist/mirror/domain/exports.js.map +1 -0
  142. package/dist/mirror/domain/package-display-name.js +10 -0
  143. package/dist/mirror/domain/package-display-name.js.map +1 -0
  144. package/dist/mirror/domain/path-normalizer.js +8 -0
  145. package/dist/mirror/domain/path-normalizer.js.map +1 -0
  146. package/dist/mirror/domain/types.js +2 -0
  147. package/dist/mirror/domain/types.js.map +1 -0
  148. package/dist/mirror/output.js +47 -0
  149. package/dist/mirror/output.js.map +1 -0
  150. package/dist/mirror/package-path.js +40 -0
  151. package/dist/mirror/package-path.js.map +1 -0
  152. package/dist/mirror/prepare.js +37 -0
  153. package/dist/mirror/prepare.js.map +1 -0
  154. package/dist/mirror/supplement-exports.js +157 -0
  155. package/dist/mirror/supplement-exports.js.map +1 -0
  156. package/dist/mirror/sync-reporter.js +125 -0
  157. package/dist/mirror/sync-reporter.js.map +1 -0
  158. package/dist/mirror/sync-types.js +2 -0
  159. package/dist/mirror/sync-types.js.map +1 -0
  160. package/dist/mirror/sync-workspace-package.js +117 -0
  161. package/dist/mirror/sync-workspace-package.js.map +1 -0
  162. package/dist/mirror/sync.js +90 -0
  163. package/dist/mirror/sync.js.map +1 -0
  164. package/dist/mirror/write-exports.js +145 -0
  165. package/dist/mirror/write-exports.js.map +1 -0
  166. package/dist/tag/cli-result.js +12 -0
  167. package/dist/tag/cli-result.js.map +1 -0
  168. package/dist/tag/cli-schema.js +13 -0
  169. package/dist/tag/cli-schema.js.map +1 -0
  170. package/dist/tag/command.js +69 -0
  171. package/dist/tag/command.js.map +1 -0
  172. package/dist/tag/domain/types.js +2 -0
  173. package/dist/tag/domain/types.js.map +1 -0
  174. package/dist/tag/output.js +101 -0
  175. package/dist/tag/output.js.map +1 -0
  176. package/dist/tag/prepare.js +30 -0
  177. package/dist/tag/prepare.js.map +1 -0
  178. package/dist/tag/resolve-target-path.js +14 -0
  179. package/dist/tag/resolve-target-path.js.map +1 -0
  180. package/dist/tag/since-writer.js +231 -0
  181. package/dist/tag/since-writer.js.map +1 -0
  182. package/dist/tag/sync.js +166 -0
  183. package/dist/tag/sync.js.map +1 -0
  184. package/dist/tag/target-candidates.js +79 -0
  185. package/dist/tag/target-candidates.js.map +1 -0
  186. package/dist/tag/target-runner.js +25 -0
  187. package/dist/tag/target-runner.js.map +1 -0
  188. package/dist/tag/version-resolver.js +28 -0
  189. package/dist/tag/version-resolver.js.map +1 -0
  190. package/package.json +27 -21
  191. package/dist/arrange/analyze.mjs +0 -24
  192. package/dist/arrange/cli-schema.mjs +0 -27
  193. package/dist/arrange/command.mjs +0 -130
  194. package/dist/arrange/domain/analyze-service.mjs +0 -102
  195. package/dist/arrange/domain/ast/ast-node.mjs +0 -215
  196. package/dist/arrange/domain/ast/collectors-cn.mjs +0 -64
  197. package/dist/arrange/domain/ast/collectors-jsx.mjs +0 -23
  198. package/dist/arrange/domain/ast/collectors-tv.mjs +0 -189
  199. package/dist/arrange/domain/ast/helpers.mjs +0 -108
  200. package/dist/arrange/domain/ast/simplify-targets.mjs +0 -109
  201. package/dist/arrange/domain/ast/targets.mjs +0 -134
  202. package/dist/arrange/domain/constants.mjs +0 -213
  203. package/dist/arrange/domain/grouping-service.mjs +0 -121
  204. package/dist/arrange/domain/grouping.mjs +0 -338
  205. package/dist/arrange/domain/imports.mjs +0 -107
  206. package/dist/arrange/domain/source-text-formatters.mjs +0 -88
  207. package/dist/arrange/domain/tailwind-token.mjs +0 -40
  208. package/dist/arrange/domain/token-classifier.mjs +0 -218
  209. package/dist/arrange/domain/types.mjs +0 -1
  210. package/dist/arrange/output.mjs +0 -87
  211. package/dist/arrange/process-file.mjs +0 -42
  212. package/dist/arrange/resolve-target.mjs +0 -24
  213. package/dist/arrange/scan-target.mjs +0 -29
  214. package/dist/arrange/simplify-process-file.mjs +0 -35
  215. package/dist/arrange/simplify-sync.mjs +0 -32
  216. package/dist/arrange/source-parse.mjs +0 -18
  217. package/dist/arrange/suggest.mjs +0 -15
  218. package/dist/arrange/sync.mjs +0 -51
  219. package/dist/arrange/typescript-ast-translator.mjs +0 -354
  220. package/dist/arrange/workspace.mjs +0 -31
  221. package/dist/cli.mjs +0 -34
  222. package/dist/core/cli/format-error.mjs +0 -15
  223. package/dist/core/cli/global-options.mjs +0 -10
  224. package/dist/core/cli/positional.mjs +0 -11
  225. package/dist/core/cli/result-handle.mjs +0 -51
  226. package/dist/core/config/loader.mjs +0 -79
  227. package/dist/core/config/schema.mjs +0 -60
  228. package/dist/core/config/warnings.mjs +0 -12
  229. package/dist/core/config.mjs +0 -19
  230. package/dist/core/errors.mjs +0 -35
  231. package/dist/core/exit-codes.mjs +0 -17
  232. package/dist/core/filesystem/node.mjs +0 -32
  233. package/dist/core/filesystem/port.mjs +0 -1
  234. package/dist/core/glob.mjs +0 -20
  235. package/dist/core/logger.mjs +0 -15
  236. package/dist/core/result.mjs +0 -21
  237. package/dist/core/schema-parse.mjs +0 -18
  238. package/dist/core/source-text-edit.mjs +0 -56
  239. package/dist/core/verbose-diagnostics.mjs +0 -11
  240. package/dist/core/workspace/resolver.mjs +0 -177
  241. package/dist/core/workspace/typescript-walk.mjs +0 -36
  242. package/dist/mirror/cli-result.mjs +0 -22
  243. package/dist/mirror/cli-schema.mjs +0 -13
  244. package/dist/mirror/command.mjs +0 -58
  245. package/dist/mirror/dist-filesystem-impl.mjs +0 -42
  246. package/dist/mirror/domain/constants.mjs +0 -31
  247. package/dist/mirror/domain/dirent-guard.mjs +0 -16
  248. package/dist/mirror/domain/dist-filesystem.mjs +0 -1
  249. package/dist/mirror/domain/errors.mjs +0 -21
  250. package/dist/mirror/domain/exports.mjs +0 -226
  251. package/dist/mirror/domain/package-display-name.mjs +0 -12
  252. package/dist/mirror/domain/path-normalizer.mjs +0 -10
  253. package/dist/mirror/domain/types.mjs +0 -1
  254. package/dist/mirror/output.mjs +0 -48
  255. package/dist/mirror/package-path.mjs +0 -32
  256. package/dist/mirror/prepare.mjs +0 -33
  257. package/dist/mirror/supplement-exports.mjs +0 -114
  258. package/dist/mirror/sync-reporter.mjs +0 -107
  259. package/dist/mirror/sync-types.mjs +0 -1
  260. package/dist/mirror/sync-workspace-package.mjs +0 -109
  261. package/dist/mirror/sync.mjs +0 -88
  262. package/dist/mirror/write-exports.mjs +0 -94
  263. package/dist/tag/cli-result.mjs +0 -11
  264. package/dist/tag/cli-schema.mjs +0 -15
  265. package/dist/tag/command.mjs +0 -56
  266. package/dist/tag/domain/types.mjs +0 -1
  267. package/dist/tag/output.mjs +0 -87
  268. package/dist/tag/prepare.mjs +0 -29
  269. package/dist/tag/resolve-target-path.mjs +0 -12
  270. package/dist/tag/since-writer.mjs +0 -131
  271. package/dist/tag/sync.mjs +0 -149
  272. package/dist/tag/target-candidates.mjs +0 -68
  273. package/dist/tag/target-runner.mjs +0 -26
  274. package/dist/tag/version-resolver.mjs +0 -25
package/README.md CHANGED
@@ -1,560 +1,186 @@
1
1
  # @codefast/cli
2
2
 
3
- A small developer CLI for maintenance tasks in a TypeScript monorepo — Tailwind class arranging, `package.json` `exports` mirroring, and `@since` JSDoc tagging.
4
-
5
- [![CI](https://github.com/codefastlabs/codefast/actions/workflows/release.yml/badge.svg)](https://github.com/codefastlabs/codefast/actions/workflows/release.yml)
6
- [![npm version](https://img.shields.io/npm/v/@codefast/cli.svg)](https://www.npmjs.com/package/@codefast/cli)
7
- [![npm downloads](https://img.shields.io/npm/dm/@codefast/cli.svg)](https://www.npmjs.com/package/@codefast/cli)
8
- [![license](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
9
-
10
- ---
11
-
12
- ## Table of Contents
13
-
14
- - [Why @codefast/cli](#why-codefastcli)
15
- - [Requirements](#requirements)
16
- - [Installation](#installation)
17
- - [Quick Start](#quick-start)
18
- - [Global options](#global-options)
19
- - [Exit codes](#exit-codes)
20
- - [`arrange`](#arrange)
21
- - [`mirror`](#mirror)
22
- - [`tag`](#tag)
23
- - [Configuration (`codefast.config.*`)](#configuration-codefastconfig)
24
- - [Full skeleton](#full-skeleton)
25
- - [`mirror` configuration](#mirror-configuration)
26
- - [`tag` configuration](#tag-configuration)
27
- - [`arrange` configuration](#arrange-configuration)
28
- - [Lifecycle hooks](#lifecycle-hooks)
29
- - [Grouping philosophy — Render Pipeline Order](#grouping-philosophy--render-pipeline-order)
30
- - [Troubleshooting](#troubleshooting)
31
- - [Contributing (monorepo setup)](#contributing-monorepo-setup)
32
- - [License](#license)
33
- - [Changelog](#changelog)
34
-
35
- ---
36
-
37
- ## Why @codefast/cli
38
-
39
- Three recurring maintenance chores you don't want to script by hand:
40
-
41
- - **`arrange`** — regroup Tailwind class strings inside `cn()` / `tv()` calls in render-pipeline order.
42
- - **`mirror`** — regenerate `package.json` `exports` fields from built `dist/` trees across a pnpm workspace.
43
- - **`tag`** — add `@since <version>` JSDoc tags to exported declarations that are missing version metadata.
44
-
45
- Each top-level command **performs its action by default** (writing files). Pass `--dry-run` to preview without writing. `arrange` additionally exposes a read-only `inspect` report.
46
-
47
- ```mermaid
48
- flowchart LR
49
- R[codefast]
50
- R --> A[arrange]
51
- R --> M[mirror]
52
- R --> T[tag]
53
-
54
- A --> A0[inspect]
55
- A --> A1[simplify]
56
- A --> A2[group]
57
- ```
58
-
59
- ---
3
+ Developer CLI for the [Codefast monorepo](https://github.com/codefastlabs/codefast) — `arrange` Tailwind class strings, `audit` source conventions (RTL), `mirror` export maps from `dist/`, and `tag` exported APIs with `@since`.
60
4
 
61
- ## Requirements
5
+ [![npm version](https://img.shields.io/npm/v/@codefast/cli)](https://www.npmjs.com/package/@codefast/cli)
6
+ [![license](https://img.shields.io/npm/l/@codefast/cli)](https://github.com/codefastlabs/codefast/blob/main/LICENSE)
62
7
 
63
- - Node.js `>= 24.0.0`
64
- - pnpm (recommended — the CLI discovers workspaces via `pnpm-workspace.yaml`)
8
+ This package exists to maintain the Codefast repository itself. It is published to npm and works in any pnpm workspace with a similar layout, but its flags and defaults follow Codefast's conventions — treat it as repo tooling, not a general-purpose product.
65
9
 
66
- ---
10
+ ## Installation and usage
67
11
 
68
- ## Installation
12
+ Inside the Codefast monorepo, the CLI runs from its built output via root `package.json` scripts:
69
13
 
70
14
  ```bash
71
- # Install globally
72
- pnpm add -g @codefast/cli
73
- # or
74
- npm install -g @codefast/cli
75
- # or
76
- yarn global add @codefast/cli
15
+ pnpm --filter @codefast/cli build # produce dist/bin.mjs first
77
16
 
78
- # Or run without installing
79
- pnpm dlx @codefast/cli --help
80
- # or
81
- npx @codefast/cli --help
82
- ```
17
+ pnpm run codefast <command> # generic entry: node ./packages/cli/dist/bin.mjs
83
18
 
84
- ---
19
+ # Convenience wrappers
20
+ pnpm run cli:arrange # codefast arrange
21
+ pnpm run cli:arrange:inspect # codefast arrange inspect
22
+ pnpm run cli:arrange:preview # codefast arrange --dry-run
23
+ pnpm run cli:arrange:simplify # codefast arrange simplify
24
+ pnpm run cli:arrange:simplify:preview
25
+ pnpm run cli:mirror # codefast mirror
26
+ pnpm run cli:mirror:preview # codefast mirror --dry-run
27
+ pnpm run cli:audit:rtl # codefast audit rtl
28
+ ```
85
29
 
86
- ## Quick Start
30
+ Standalone install (Node >= 24):
87
31
 
88
32
  ```bash
89
- # Inspect Tailwind classes in the nearest package (read-only report)
90
- codefast arrange inspect
91
-
92
- # Preview proposed rewrites — no files written
93
- codefast arrange --dry-run packages/ui/src/components
94
-
95
- # Apply after reviewing
96
- codefast arrange packages/ui/src/components
97
-
98
- # Regenerate every package's `exports` from built dist/
99
- codefast mirror
100
-
101
- # Add @since <version> to exported APIs under ./src
102
- codefast tag
33
+ pnpm add -g @codefast/cli
34
+ # or one-off
35
+ pnpm dlx @codefast/cli --help
103
36
  ```
104
37
 
105
- ---
106
-
107
- ## Global options
108
-
109
- | Flag | Effect |
110
- | ----------------- | ---------------------------------------------------------------------- |
111
- | `--no-color` | Disable ANSI color output (also respected by JSON output suppression). |
112
- | `-V`, `--version` | Print the CLI version and exit. |
113
- | `-h`, `--help` | Show contextual help for the invoked command. |
114
-
115
- > **Placement.** Global flags must come **before** the command name (git-style), e.g. `codefast --no-color mirror`. A flag after the command name binds to that command.
116
-
117
- ---
118
-
119
- ## Exit codes
120
-
121
- | Code | Meaning |
122
- | ---- | --------------------------------------------------------------------------------------------------- |
123
- | `0` | Success. |
124
- | `1` | General failure (missing paths, infrastructure errors, partial failures in `mirror`, failed hooks). |
125
- | `2` | Invalid invocation or input (Zod schema validation on CLI requests — `CLI_EXIT_USAGE`). |
126
-
127
- Diagnostics go to **stderr**; primary command output goes to **stdout**. When a subcommand accepts `--json`, only the JSON object is written to stdout and all human progress is suppressed, so the stream stays pipeline-safe.
128
-
129
- ---
38
+ Every command writes by default; pass `--dry-run` to preview. The global `--no-color` flag must come before the command name (`codefast --no-color mirror`). Commands that accept `--json` print a single JSON object on stdout and suppress human progress output.
130
39
 
131
40
  ## `arrange`
132
41
 
133
- Reads `cn()` and `tv()` call sites, classifies each Tailwind utility, and rewrites the class string in render-pipeline order (see [Grouping philosophy](#grouping-philosophy--render-pipeline-order)).
134
-
135
- ### Target resolution
42
+ Rewrites Tailwind class strings inside `cn()` and `tv()` calls, regrouping utilities in render-pipeline order (existence, position, layout, sizing, spacing, shape, background, shadow, typography, composite, motion, behavior, state, selector) instead of alphabetically.
136
43
 
137
- When `[target]` is omitted, `arrange` auto-detects the **nearest package directory** by walking up from the current working directory until it finds a `package.json`. Pass an explicit path (file or directory) to override.
44
+ ```bash
45
+ codefast arrange inspect packages/ui/src # read-only report
46
+ codefast arrange --dry-run packages/ui/src # preview the rewrite
47
+ codefast arrange packages/ui/src # write
48
+ ```
138
49
 
139
- ### Workflow
50
+ When `[target]` is omitted, `arrange` uses the nearest package directory found by walking up from the current working directory. Directory scans skip test files (`*.test.*` / `*.spec.*`); pass such a file explicitly to process it.
140
51
 
141
- | Step | Command | Effect |
142
- | ---- | ------------------------------------- | ---------------------------------------------- |
143
- | 1 | `codefast arrange inspect [target]` | Report only — no files changed |
144
- | 2 | `codefast arrange --dry-run [target]` | Show exactly what a bare `arrange` would write |
145
- | 3 | `codefast arrange [target]` | Write the changes |
52
+ | Flag | Description |
53
+ | -------------------- | ----------------------------------------------------------------------------- |
54
+ | `--dry-run` | Preview suggested replacements without writing files. |
55
+ | `--with-classname` | Append `className` as the final `cn()` argument (alias: `--with-class-name`). |
56
+ | `--cn-import <spec>` | Override the module specifier used when a missing `cn` import is added. |
57
+ | `--json` | Print one JSON object on stdout (suppresses human progress). |
146
58
 
147
- ### Flags (`arrange`)
59
+ ### `arrange inspect [target]`
148
60
 
149
- | Flag | Description |
150
- | -------------------- | --------------------------------------------------------------------------- |
151
- | `--dry-run` | Preview the rewrite without writing files. |
152
- | `--with-class-name` | Append `className` as the last argument when rewriting a `cn(...)` call. |
153
- | `--cn-import <spec>` | Override the module specifier used when a missing `cn` import is added. |
154
- | `--json` | Print a single JSON object on stdout; suppresses human progress and colors. |
61
+ Read-only report of long strings, nested `cn` inside `tv()`, and related findings. Accepts `--json`.
155
62
 
156
- `inspect` also supports `--json`. `simplify` accepts `--dry-run` and `--json`.
63
+ ### `arrange simplify [target]`
157
64
 
158
- > **Test files are skipped.** Directory scans exclude `*.test.*` / `*.spec.*` files — a `cn(...)` inside an assertion is test data, not styling to reformat. Pass such a file explicitly to override.
65
+ Flattens grouped arrays and static-only `cn()` calls back to plain strings in `tv()` slots — the inverse cleanup pass. Accepts `--dry-run` and `--json`.
159
66
 
160
- ### `arrange group` — one-shot classification
67
+ ### `arrange group <tokens...>`
161
68
 
162
- Groups a class string without touching the filesystem. Useful for checking how classes would be grouped before running `arrange`:
69
+ Groups a pasted class string without touching the filesystem — useful for checking how classes would be bucketed:
163
70
 
164
71
  ```bash
165
- # Quoted string
166
- codefast arrange group "relative flex items-center h-10 w-full rounded-md bg-primary text-white hover:bg-primary/90"
167
-
168
- # Or space-separated tokens (no quotes needed)
169
- codefast arrange group relative flex items-center h-10 w-full rounded-md
170
-
171
- # Emit a tv()-style array instead of a cn() call
72
+ codefast arrange group "relative flex h-10 w-full items-center rounded-md bg-primary"
172
73
  codefast arrange group --tv "flex items-center gap-2"
173
74
  ```
174
75
 
175
- | Flag | Description |
176
- | ------------------- | -------------------------------------------------------------------- |
177
- | `--tv` | Emit a `tv()`-style array literal instead of a `cn(...)` call. |
178
- | `--with-class-name` | Append `className` to the emitted `cn(...)` call. |
179
- | `--json` | Emit `{ schemaVersion, primaryLine, bucketsCommentLine }` on stdout. |
180
-
181
- ### `--json` payloads
182
-
183
- | Subcommand | Payload highlights |
184
- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
185
- | `arrange` | `schemaVersion`, `write`, `ok` (`false` if the `onAfterWrite` hook failed), full `result` (`filePaths`, `modifiedFiles`, `totalFound`, …). |
186
- | `inspect` | `schemaVersion`, `analyzeRootPath`, full `report` (same data as the human report). |
187
- | `simplify` | `schemaVersion`, `write`, `ok`, full `result`. |
188
- | `group` | `schemaVersion`, `primaryLine`, `bucketsCommentLine`. |
189
-
190
- ---
76
+ | Flag | Description |
77
+ | ------------------ | ----------------------------------------------------------------------------- |
78
+ | `--tv` | Emit a `tv()`-style array instead of a `cn()` call. |
79
+ | `--with-classname` | Append `className` as the final `cn()` argument (alias: `--with-class-name`). |
80
+ | `--json` | Emit `{ schemaVersion, primaryLine, bucketsCommentLine }` on stdout. |
191
81
 
192
82
  ## `mirror`
193
83
 
194
- Scans built `dist/` trees and regenerates the `exports` field of every workspace package. Run it from anywhere inside the monorepo — the workspace root is discovered via `pnpm-workspace.yaml`.
84
+ Scans each workspace package's built `dist/` tree and writes its `package.json#exports` map (plus top-level `main`, `module`, `types`, and a `files` entry for `dist`). The workspace root is discovered via `pnpm-workspace.yaml`, so it runs from anywhere inside the repo. Build first — `mirror` reads `dist/`, and stale output produces stale exports.
195
85
 
196
86
  ```bash
197
87
  codefast mirror # all workspace packages
198
88
  codefast mirror packages/ui # one package (path relative to repo root)
199
- codefast mirror --dry-run # preview — report changes without writing
200
- codefast mirror -v # verbose diagnostics
201
- codefast mirror --json # JSON summary for scripts / CI
89
+ codefast mirror --dry-run # report changes without writing
202
90
  ```
203
91
 
204
- | Flag | Description |
205
- | ----------------- | ---------------------------------------------------------------------------- |
206
- | `--dry-run` | Report what would change without writing any `package.json`. |
207
- | `-v`, `--verbose` | Print extra diagnostics. |
208
- | `--json` | Print a single `{ schemaVersion, ok, write, elapsedSeconds, stats }` object. |
209
-
210
- > **Build first.** `mirror` reads from `dist/`. Run your build before syncing or exports will reflect stale output.
92
+ | Flag | Description |
93
+ | ----------------- | ------------------------------------------------------------- |
94
+ | `--dry-run` | Report what would change without writing any `package.json`. |
95
+ | `-v`, `--verbose` | Print extra diagnostics. |
96
+ | `--json` | Print one JSON summary on stdout (suppresses human progress). |
211
97
 
212
- Exit code is `1` when any package fails (`stats.packagesErrored > 0`), `0` otherwise.
98
+ Exits `1` when any package fails, `0` otherwise.
213
99
 
214
- ---
100
+ ## `audit rtl`
215
101
 
216
- ## `tag`
217
-
218
- Scans `.ts` / `.tsx` sources and adds `@since <current-package-version>` to exported declarations that don't already carry one. The version is read from the nearest `package.json` walking up from the target path.
102
+ Read-only scan for physical-direction Tailwind classes (e.g. `ml-*`, `left-*`, `text-left`) that should use logical equivalents (`ms-*`, `start-*`, `text-start`) or an `rtl:` companion (`translate-x`, `space-x`, resize cursors). Exits non-zero when violations remain so it can gate CI.
219
103
 
220
104
  ```bash
221
- codefast tag # auto-discover workspace packages from cwd
222
- codefast tag packages/ui/src # tag a custom target
223
- codefast tag --dry-run # preview only, do not write
224
- codefast tag --json # JSON summary for scripts / CI
105
+ codefast audit rtl # uses audit.rtl.target from config
106
+ codefast audit rtl packages/ui/src # explicit target
107
+ codefast audit rtl --json # machine-readable summary
225
108
  ```
226
109
 
227
- | Flag | Description |
228
- | ----------- | ----------------------------------------------------------------- |
229
- | `--dry-run` | Show summary without writing files. |
230
- | `--json` | Print a single JSON summary on stdout; suppresses human progress. |
231
-
232
- What it updates:
110
+ | Flag | Description |
111
+ | -------- | --------------------------------- |
112
+ | `--json` | Print one JSON summary on stdout. |
233
113
 
234
- - Adds `/** @since <version> */` when an exported declaration has no JSDoc.
235
- - Injects `@since <version>` into an existing JSDoc block that lacks one.
236
- - Leaves declarations alone when `@since` is already present.
114
+ Configure intentional exceptions via `audit.rtl.allowlist` in `codefast.config` — each entry is a bare class token or `repo/relative/path.tsx:token`.
237
115
 
238
- ---
239
-
240
- ## Configuration (`codefast.config.*`)
116
+ ## `tag`
241
117
 
242
- Create a config file at the **monorepo root** (next to `pnpm-workspace.yaml`). Supported names, in priority order:
118
+ Adds `@since <version>` tags to doc comments of exported declarations that lack one, creating the doc block when missing. The version comes from the nearest `package.json` walking up from each target file. Declarations that already carry `@since` are left alone.
243
119
 
244
- | File name | Format |
245
- | ---------------------- | --------------------------------------- |
246
- | `codefast.config.mjs` | ES module — `export default { … }` |
247
- | `codefast.config.js` | ES module (if `"type":"module"`) or CJS |
248
- | `codefast.config.cjs` | CommonJS — `module.exports = { … }` |
249
- | `codefast.config.json` | Plain JSON (no functions — no hooks) |
120
+ ```bash
121
+ codefast tag # auto-discover workspace packages from cwd
122
+ codefast tag packages/ui/src # tag one directory or file
123
+ codefast tag --dry-run # summary only, no writes
124
+ ```
250
125
 
251
- The file is found by walking up from the working directory, so running the CLI from any sub-directory still picks up the root config.
126
+ | Flag | Description |
127
+ | ----------- | ------------------------------------------------------------- |
128
+ | `--dry-run` | Show summary without writing files. |
129
+ | `--json` | Print one JSON summary on stdout (suppresses human progress). |
252
130
 
253
- > **Security.** `.js`, `.mjs`, and `.cjs` files are executed via `import()`. Only run `codefast` inside repositories you trust.
131
+ In this repo, `tag` runs as part of the release workflow so published APIs carry accurate version metadata — never hand-write `@since` tags.
254
132
 
255
- ---
133
+ ## Configuration
256
134
 
257
- ### Full skeleton
135
+ An optional `codefast.config.*` file adjusts `mirror`, `tag`, `arrange`, and `audit`. The CLI walks up from the working directory and uses the first match, checking `codefast.config.mjs`, `codefast.config.js`, `codefast.config.cjs`, then `codefast.config.json` in each directory. JS configs are loaded via [jiti](https://github.com/unjs/jiti), so only run the CLI in repositories you trust; JSON configs cannot define hooks.
258
136
 
259
- ```javascript
260
- // codefast.config.mjs
137
+ ```js
138
+ // codefast.config.js
261
139
  import { execSync } from "node:child_process";
262
140
 
263
141
  export default {
264
- // ─── mirror ────────────────────────────────────────────────────────────────
265
- // Keys are package names (from package.json#name).
266
- // Set a package to `false` to skip it entirely.
267
- // Omit a package to process it with default settings.
142
+ // Keyed by package name; `false` skips the package, omitted packages use defaults.
268
143
  mirror: {
269
144
  "@acme/ui": {
270
- strip: "./components/",
271
- exports: { "./css/*": "./src/css/*" },
272
- source: true, // default: true
273
- types: true, // default: true
274
- import: true, // default: true
275
- css: true,
145
+ strip: "./components/", // flatten a dist/ prefix out of public specifiers
146
+ exports: { "./css/*": "./src/css/*" }, // extra or overriding entries
147
+ source: true, // add a `source` condition (string overrides the root path)
148
+ types: true, // add `types` when a .d.ts exists
149
+ import: true, // add the `import` condition
150
+ css: true, // boolean or { enabled, forceExportFiles, customExports }
276
151
  },
152
+ "@acme/tailwind-variants": { preserve: true }, // keep exports as-is, only fill missing conditions
277
153
  "@acme/internal": false,
278
- "@acme/docs": false,
279
154
  },
280
-
281
- // ─── tag ───────────────────────────────────────────────────────────────────
282
155
  tag: {
283
156
  skipPackages: ["@acme/internal"],
284
- onAfterWrite: ({ files }) => {
285
- execSync(`oxfmt ${files.join(" ")}`, { stdio: "inherit" });
286
- },
157
+ onAfterWrite: ({ files }) => execSync(`oxfmt ${files.join(" ")}`, { stdio: "inherit" }),
287
158
  },
288
-
289
- // ─── arrange ───────────────────────────────────────────────────────────────
290
159
  arrange: {
291
- onAfterWrite: ({ files }) => {
292
- execSync(`oxfmt ${files.join(" ")}`, { stdio: "inherit" });
293
- },
160
+ onAfterWrite: ({ files }) => execSync(`oxfmt ${files.join(" ")}`, { stdio: "inherit" }),
294
161
  },
295
- };
296
- ```
297
-
298
- ---
299
-
300
- ### `mirror` configuration
301
-
302
- `mirror` is a record keyed by **package name** (the `name` field in the package's `package.json`, e.g. `"@acme/ui"`).
303
-
304
- #### Skipping a package
305
-
306
- Set a package to `false` to exclude it from `codefast mirror` entirely:
307
-
308
- ```javascript
309
- mirror: {
310
- "@acme/internal": false,
311
- "@acme/docs": false,
312
- }
313
- ```
314
-
315
- Packages not mentioned in the config are processed with default settings.
316
-
317
- #### Per-package options
318
-
319
- Each package entry is an object with the following fields:
320
-
321
- | Field | Type | Default | Description |
322
- | ---------- | ------------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
323
- | `source` | `boolean \| string` | `true` | Add a `source` condition to each export entry pointing to the original `.ts` file. `true` auto-derives the path (`./src/<module>.ts`). Pass a string to set the root-export path explicitly (`"./src/index.tsx"`). Set to `false` to omit. |
324
- | `types` | `boolean` | `true` | Include the `types` condition when a `.d.ts` file is present. Set to `false` to omit. |
325
- | `import` | `boolean` | `true` | Include the `import` condition. Set to `false` to omit (useful for CJS-only packages). |
326
- | `strip` | `string` | — | Strip a leading path segment from generated export specifiers. See below. |
327
- | `exports` | `Record<string, string>` | — | Add or override specific export specifiers. See below. |
328
- | `preserve` | `boolean` | — | Keep the existing `package.json#exports` and only fill in missing conditions. |
329
- | `css` | `boolean \| CssConfig` | — | Enable CSS export detection. See below. |
330
-
331
- #### `strip`
332
-
333
- Removes a fixed prefix from every generated export specifier. Use this when a package's `dist/` mirrors deep directory structure that you want to flatten in the public API.
334
-
335
- ```javascript
336
- // Without strip, dist/components/button.mjs → "./components/button"
337
- // With strip: "./components/", it becomes → "./button"
338
- "@acme/ui": {
339
- strip: "./components/",
340
- }
341
- ```
342
-
343
- The original file path is preserved for sorting — only the public specifier changes.
344
-
345
- #### `exports`
346
-
347
- Adds or overrides specific specifiers in the final export map. Keys and values are the exact strings written into `package.json#exports`.
348
-
349
- ```javascript
350
- "@acme/ui": {
351
- exports: {
352
- "./css/*": "./src/css/*", // wildcard passthrough to sources
353
- "./tokens": "./dist/tokens.js", // explicit extra entry
354
- },
355
- }
356
- ```
357
-
358
- Extra entries are merged after auto-generation. They win over anything the scanner would produce for the same specifier. `./package.json` cannot be overridden.
359
-
360
- #### `preserve`
361
-
362
- Keeps the existing `package.json#exports` map exactly as-is and only fills in missing conditions (`source`, `types`, `import`) for each entry — no `dist/` scan is performed. Use this when you maintain the exports map by hand and only want the CLI to supplement missing conditions.
363
-
364
- ```javascript
365
- "@acme/tailwind-variants": {
366
- preserve: true,
367
- }
368
- ```
369
-
370
- #### `css`
371
-
372
- Controls CSS file export generation. `mirror` scans `dist/` for `.css` files and writes wildcard or per-file export entries.
373
-
374
- ```javascript
375
- // Shorthand: auto-detect all CSS files in dist/
376
- "@acme/theme": { css: true }
377
-
378
- // Full config:
379
- "@acme/ui": {
380
- css: {
381
- enabled: true,
382
- // Force individual file entries instead of directory wildcards:
383
- forceExportFiles: false,
384
- // Manually add or override individual CSS specifiers:
385
- customExports: {
386
- "./tokens.css": "./dist/tokens.css",
387
- },
388
- },
389
- }
390
-
391
- // Explicitly disable CSS exports for this package:
392
- "@acme/legacy": { css: false }
393
- ```
394
-
395
- When `css` is omitted, CSS files found in `dist/` are still exported by default.
396
-
397
- #### What `mirror` writes
398
-
399
- For a package with `dist/button.mjs`, `dist/button.d.ts`, and `source: true`, the generated export entry looks like:
400
-
401
- ```json
402
- {
403
- "./button": {
404
- "source": "./src/button.ts",
405
- "types": "./dist/button.d.ts",
406
- "import": "./dist/button.mjs"
407
- }
408
- }
409
- ```
410
-
411
- It also updates the top-level `main`, `module`, and `types` fields from the root (`.`) export, and ensures `"dist"` is listed in `files`.
412
-
413
- ---
414
-
415
- ### `tag` configuration
416
-
417
- ```javascript
418
- tag: {
419
- // Package names to skip when running without an explicit target
420
- skipPackages: ["@acme/internal", "@acme/docs"],
421
-
422
- // Called after files are written — use it to format or lint-fix
423
- onAfterWrite: ({ files }) => {
424
- execSync(`prettier --write ${files.join(" ")}`, { stdio: "inherit" });
425
- },
426
- }
427
- ```
428
-
429
- | Field | Type | Description |
430
- | -------------- | ----------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
431
- | `skipPackages` | `string[]` | Package names to skip when `codefast tag` is run without an explicit target. Has no effect when a target path is provided directly. |
432
- | `onAfterWrite` | `(ctx: { files: string[] }) => void \| Promise<void>` | Lifecycle hook — runs after files are written. |
433
-
434
- ---
435
-
436
- ### `arrange` configuration
437
-
438
- ```javascript
439
- arrange: {
440
- // Called after files are written by `codefast arrange`
441
- onAfterWrite: ({ files }) => {
442
- execSync(`oxfmt ${files.join(" ")}`, { stdio: "inherit" });
443
- },
444
- }
445
- ```
446
-
447
- | Field | Type | Description |
448
- | -------------- | ----------------------------------------------------- | -------------------------------------------------------------------------------- |
449
- | `onAfterWrite` | `(ctx: { files: string[] }) => void \| Promise<void>` | Lifecycle hook — runs after `arrange` writes files. Not called with `--dry-run`. |
450
-
451
- ---
452
-
453
- ## Lifecycle hooks
454
-
455
- Both `tag` and `arrange` call `onAfterWrite` immediately after writing files to disk. The hook receives the list of written file paths and can run any synchronous or asynchronous work — formatters, linters, codegen, notifications.
456
-
457
- ```javascript
458
- export default {
459
- tag: {
460
- onAfterWrite: async ({ files }) => {
461
- // async is supported
462
- await runFormatter(files);
463
- },
464
- },
465
- arrange: {
466
- onAfterWrite: ({ files }) => {
467
- // sync is fine too
468
- execSync(`oxfmt ${files.join(" ")}`, { stdio: "inherit" });
162
+ audit: {
163
+ rtl: {
164
+ target: "packages/ui/src", // default scan root when no CLI arg is passed
165
+ allowlist: [
166
+ // bare token, or `repo/relative/path.tsx:token`
167
+ "packages/ui/src/variants/sheet.ts:data-open:slide-in-from-left-10",
168
+ ],
469
169
  },
470
170
  },
471
171
  };
472
172
  ```
473
173
 
474
- Contract:
475
-
476
- - `tag.onAfterWrite` fires after `codefast tag` writes JSDoc annotations.
477
- - `arrange.onAfterWrite` fires after `codefast arrange` rewrites class strings.
478
- - Hook is **not** called on `--dry-run`.
479
- - Hooks may be synchronous or `async` (`void | Promise<void>`).
480
- - If the hook throws or rejects, the command reports the error on stderr and exits with code `1`.
481
-
482
- ---
483
-
484
- ## Grouping philosophy — Render Pipeline Order
485
-
486
- `arrange` does **not** sort classes alphabetically. Instead, it groups utilities in roughly the order the browser applies them — from the box's existence, through its shape and surface, to interactive behavior. This makes class strings easier to scan and diff.
487
-
488
- **Existence → Position → Layout → Sizing → Spacing → Shape → Background → Shadow → Typography → Composite → Motion → Starting → Behavior → State → Selector**
489
-
490
- | Bucket | What it covers | Examples |
491
- | -------------- | --------------------------------------------------- | ------------------------------------------------- |
492
- | **Existence** | Display and containment context | `hidden`, `block`, `@container`, `group`, `peer` |
493
- | **Position** | Where the box sits | `absolute`, `inset-*`, `top-*`, `z-*` |
494
- | **Layout** | How children flow | `flex`, `grid`, `gap-*`, `items-*` |
495
- | **Sizing** | Box dimensions and overflow | `w-*`, `h-*`, `aspect-*`, `overflow-*` |
496
- | **Spacing** | Padding and margin only (gaps stay with Layout) | `p-*`, `m-*` |
497
- | **Shape** | Corners and strokes | `rounded-*`, `border-*`, `ring-*` |
498
- | **Background** | Surfaces and masks | `bg-*`, `from-*`, `via-*`, `to-*`, `mask-*` |
499
- | **Shadow** | Depth | `shadow-*`, `inset-shadow-*`, `text-shadow-*` |
500
- | **Typography** | Text appearance | `font-*`, `text-*`, `leading-*` |
501
- | **Composite** | Layers and transforms (3D context → 3D → 2D) | `opacity-*`, `rotate-x-*`, `translate-*` |
502
- | **Motion** | Time-based change | `transition-*`, `animate-*` |
503
- | **Starting** | Tailwind's `starting:` layer — kept next to Motion | `starting:*` |
504
- | **Behavior** | Input, scrolling, and browser chrome | `cursor-*`, `scroll-*`, `field-sizing-*`, `inert` |
505
- | **State** | Interactive and conditional variants (non-selector) | `hover:`, `md:`, `@md/sidebar:`, `data-[…]:` |
506
- | **Selector** | Selector-driven variants | `[&…]:`, `*:`, `**:`, `has-*`, `group-[…]:` |
507
-
508
- Adjacent buckets may be merged into a single string literal when declared _compatible_ (e.g. Layout + Sizing), which keeps `cn()` calls readable without flattening unrelated concerns.
509
-
510
- To change placement, extend `classifyBareUtility` in `packages/cli/src/arrange/domain/token-classifier.ts` (and cover the new rule with arrange tests if you introduce a new bucket).
511
-
512
- ---
513
-
514
- ## Troubleshooting
174
+ The `onAfterWrite` hooks (sync or async) run only when files were actually written — never on `--dry-run`. A hook failure is reported on stderr and the command exits `1`.
515
175
 
516
- **`codefast: command not found`**
517
- Install globally with `pnpm add -g @codefast/cli`, or run via `pnpm dlx @codefast/cli <command>`.
518
-
519
- **`mirror` writes little or no output**
520
- Packages must be built first. Ensure `dist/` exists by running your build step, then re-run `codefast mirror`.
521
-
522
- **Unexpected class reorder after `arrange`**
523
- Run `arrange --dry-run` first and smoke-test the UI. Some components rely on cascade-sensitive ordering that `arrange` cannot detect automatically.
524
-
525
- **`--json` output mixed with progress lines**
526
- Some shells buffer progress writes on stderr into stdout when piping — redirect stderr explicitly: `codefast mirror --json 2>/dev/null | jq`.
527
-
528
- ---
529
-
530
- ## Contributing (monorepo setup)
531
-
532
- ```bash
533
- # Build the local CLI (produces dist/bin.mjs)
534
- pnpm --filter @codefast/cli build
535
-
536
- # Run the local entrypoint
537
- pnpm exec codefast --help
538
-
539
- # Test + type-check
540
- pnpm --filter @codefast/cli test
541
- pnpm --filter @codefast/cli check-types
542
- ```
543
-
544
- A few naming conventions:
545
-
546
- - **`codefast <command>`** refers to CLI commands exposed via the `bin` entry in `@codefast/cli`.
547
- - **Scripts in `packages/cli/package.json`** (`build`, `test`, …) are package-local dev scripts, not CLI commands.
548
- - The root `package.json` includes optional convenience wrappers (e.g. `cli:mirror`, `cli:arrange-inspect`) for common dev workflows.
176
+ ## Exit codes
549
177
 
550
- ---
178
+ | Code | Meaning |
179
+ | ---- | --------------------------------------------------------------- |
180
+ | `0` | Success. |
181
+ | `1` | General failure (missing paths, failed packages, failed hooks). |
182
+ | `2` | Invalid invocation or input. |
551
183
 
552
184
  ## License
553
185
 
554
- [MIT](https://opensource.org/licenses/MIT) — see [`package.json`](./package.json).
555
-
556
- ---
557
-
558
- ## Changelog
559
-
560
- See [CHANGELOG.md](./CHANGELOG.md) for the full version history. Releases are also published on [npm](https://www.npmjs.com/package/@codefast/cli?activeTab=versions).
186
+ [MIT](https://github.com/codefastlabs/codefast/blob/main/LICENSE)