@codefast/cli 0.8.0 → 0.9.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 (230) hide show
  1. package/CHANGELOG.md +568 -0
  2. package/LICENSE +1 -1
  3. package/README.md +150 -50
  4. package/dist/arrange/analyze.js +1 -2
  5. package/dist/arrange/cli-schema.js +1 -2
  6. package/dist/arrange/command.js +1 -2
  7. package/dist/arrange/domain/analyze-service.js +1 -2
  8. package/dist/arrange/domain/ast/ast-node.js +1 -2
  9. package/dist/arrange/domain/ast/collectors-cn.js +1 -2
  10. package/dist/arrange/domain/ast/collectors-jsx.js +1 -2
  11. package/dist/arrange/domain/ast/collectors-tv.js +1 -2
  12. package/dist/arrange/domain/ast/helpers.js +1 -2
  13. package/dist/arrange/domain/ast/simplify-targets.js +1 -2
  14. package/dist/arrange/domain/ast/targets.js +1 -2
  15. package/dist/arrange/domain/constants.js +1 -2
  16. package/dist/arrange/domain/grouping-service.js +1 -2
  17. package/dist/arrange/domain/grouping.js +1 -2
  18. package/dist/arrange/domain/imports.js +1 -2
  19. package/dist/arrange/domain/source-text-formatters.js +1 -2
  20. package/dist/arrange/domain/tailwind-token.js +1 -2
  21. package/dist/arrange/domain/token-classifier.js +1 -2
  22. package/dist/arrange/domain/types.js +1 -2
  23. package/dist/arrange/output.js +1 -2
  24. package/dist/arrange/process-file.js +1 -2
  25. package/dist/arrange/resolve-target.js +1 -2
  26. package/dist/arrange/scan-target.js +1 -2
  27. package/dist/arrange/simplify-process-file.js +1 -2
  28. package/dist/arrange/simplify-sync.js +1 -2
  29. package/dist/arrange/source-parse.js +1 -2
  30. package/dist/arrange/suggest.js +1 -2
  31. package/dist/arrange/sync.js +1 -2
  32. package/dist/arrange/typescript-ast-translator.js +1 -2
  33. package/dist/arrange/workspace.js +1 -2
  34. package/dist/audit/cli-schema.js +12 -2
  35. package/dist/audit/command.js +44 -5
  36. package/dist/audit/domain/audit-file.js +2 -3
  37. package/dist/audit/domain/comment-content.js +1 -2
  38. package/dist/audit/domain/comment-dividers.js +49 -22
  39. package/dist/audit/domain/display-names.js +71 -0
  40. package/dist/audit/domain/link-references.js +1 -2
  41. package/dist/audit/domain/mappings.js +1 -2
  42. package/dist/audit/domain/markdown-links.js +1 -2
  43. package/dist/audit/domain/react-imports.js +1 -2
  44. package/dist/audit/domain/since-versions.js +1 -2
  45. package/dist/audit/domain/tokenize.js +2 -3
  46. package/dist/audit/domain/tsdoc-syntax.js +1 -2
  47. package/dist/audit/domain/types.js +1 -2
  48. package/dist/audit/output.js +41 -1
  49. package/dist/audit/prepare.js +31 -1
  50. package/dist/audit/run-comments.js +23 -20
  51. package/dist/audit/run-display-names.js +60 -0
  52. package/dist/audit/run-links.js +1 -2
  53. package/dist/audit/run-react.js +1 -2
  54. package/dist/audit/run.js +1 -2
  55. package/dist/bin.js +1 -2
  56. package/dist/cli.js +3 -2
  57. package/dist/core/cli/format-error.js +1 -2
  58. package/dist/core/cli/global-options.js +1 -2
  59. package/dist/core/cli/positional.js +1 -2
  60. package/dist/core/cli/result-handle.js +1 -22
  61. package/dist/core/config/loader.js +1 -2
  62. package/dist/core/config/schema.js +19 -10
  63. package/dist/core/config/warnings.js +1 -2
  64. package/dist/core/config.js +1 -2
  65. package/dist/core/errors.js +1 -2
  66. package/dist/core/exit-codes.js +1 -2
  67. package/dist/core/filesystem/node.js +1 -2
  68. package/dist/core/filesystem/port.js +1 -2
  69. package/dist/core/glob.js +1 -2
  70. package/dist/core/logger.js +1 -2
  71. package/dist/core/result.js +1 -2
  72. package/dist/core/schema-parse.js +1 -2
  73. package/dist/core/source-text-edit.js +1 -2
  74. package/dist/core/verbose-diagnostics.js +1 -2
  75. package/dist/core/workspace/markdown-walk.js +1 -2
  76. package/dist/core/workspace/package-version.js +1 -2
  77. package/dist/core/workspace/resolver.js +1 -2
  78. package/dist/core/workspace/skip-directories.js +1 -2
  79. package/dist/core/workspace/source-walk.js +14 -4
  80. package/dist/core/workspace/typescript-walk.js +1 -2
  81. package/dist/mirror/cli-result.js +1 -2
  82. package/dist/mirror/cli-schema.js +1 -2
  83. package/dist/mirror/command.js +1 -2
  84. package/dist/mirror/dist-filesystem-impl.js +1 -2
  85. package/dist/mirror/domain/constants.js +1 -2
  86. package/dist/mirror/domain/dirent-guard.js +1 -2
  87. package/dist/mirror/domain/dist-filesystem.js +1 -2
  88. package/dist/mirror/domain/errors.js +1 -2
  89. package/dist/mirror/domain/exports.js +1 -2
  90. package/dist/mirror/domain/package-display-name.js +1 -2
  91. package/dist/mirror/domain/path-normalizer.js +1 -2
  92. package/dist/mirror/domain/types.js +1 -2
  93. package/dist/mirror/output.js +1 -2
  94. package/dist/mirror/package-path.js +1 -2
  95. package/dist/mirror/prepare.js +1 -2
  96. package/dist/mirror/supplement-exports.js +1 -2
  97. package/dist/mirror/sync-reporter.js +1 -2
  98. package/dist/mirror/sync-types.js +1 -2
  99. package/dist/mirror/sync-workspace-package.js +1 -2
  100. package/dist/mirror/sync.js +1 -2
  101. package/dist/mirror/write-exports.js +1 -2
  102. package/dist/pack-slim/cli-result.js +23 -0
  103. package/dist/pack-slim/cli-schema.js +11 -0
  104. package/dist/pack-slim/command.js +80 -0
  105. package/dist/pack-slim/domain/transform.js +221 -0
  106. package/dist/pack-slim/domain/types.js +2 -0
  107. package/dist/pack-slim/output.js +62 -0
  108. package/dist/pack-slim/sync.js +157 -0
  109. package/dist/pack-slim/working-tree.js +45 -0
  110. package/dist/tag/cli-result.js +1 -2
  111. package/dist/tag/cli-schema.js +1 -2
  112. package/dist/tag/command.js +1 -2
  113. package/dist/tag/domain/types.js +1 -2
  114. package/dist/tag/output.js +1 -2
  115. package/dist/tag/prepare.js +1 -2
  116. package/dist/tag/resolve-target-path.js +1 -2
  117. package/dist/tag/since-writer.js +1 -2
  118. package/dist/tag/sync.js +1 -2
  119. package/dist/tag/target-candidates.js +1 -2
  120. package/dist/tag/target-runner.js +1 -2
  121. package/dist/tag/version-resolver.js +1 -2
  122. package/package.json +8 -43
  123. package/dist/arrange/analyze.js.map +0 -1
  124. package/dist/arrange/cli-schema.js.map +0 -1
  125. package/dist/arrange/command.js.map +0 -1
  126. package/dist/arrange/domain/analyze-service.js.map +0 -1
  127. package/dist/arrange/domain/ast/ast-node.js.map +0 -1
  128. package/dist/arrange/domain/ast/collectors-cn.js.map +0 -1
  129. package/dist/arrange/domain/ast/collectors-jsx.js.map +0 -1
  130. package/dist/arrange/domain/ast/collectors-tv.js.map +0 -1
  131. package/dist/arrange/domain/ast/helpers.js.map +0 -1
  132. package/dist/arrange/domain/ast/simplify-targets.js.map +0 -1
  133. package/dist/arrange/domain/ast/targets.js.map +0 -1
  134. package/dist/arrange/domain/constants.js.map +0 -1
  135. package/dist/arrange/domain/grouping-service.js.map +0 -1
  136. package/dist/arrange/domain/grouping.js.map +0 -1
  137. package/dist/arrange/domain/imports.js.map +0 -1
  138. package/dist/arrange/domain/source-text-formatters.js.map +0 -1
  139. package/dist/arrange/domain/tailwind-token.js.map +0 -1
  140. package/dist/arrange/domain/token-classifier.js.map +0 -1
  141. package/dist/arrange/domain/types.js.map +0 -1
  142. package/dist/arrange/output.js.map +0 -1
  143. package/dist/arrange/process-file.js.map +0 -1
  144. package/dist/arrange/resolve-target.js.map +0 -1
  145. package/dist/arrange/scan-target.js.map +0 -1
  146. package/dist/arrange/simplify-process-file.js.map +0 -1
  147. package/dist/arrange/simplify-sync.js.map +0 -1
  148. package/dist/arrange/source-parse.js.map +0 -1
  149. package/dist/arrange/suggest.js.map +0 -1
  150. package/dist/arrange/sync.js.map +0 -1
  151. package/dist/arrange/typescript-ast-translator.js.map +0 -1
  152. package/dist/arrange/workspace.js.map +0 -1
  153. package/dist/audit/cli-schema.js.map +0 -1
  154. package/dist/audit/command.js.map +0 -1
  155. package/dist/audit/domain/audit-file.js.map +0 -1
  156. package/dist/audit/domain/comment-content.js.map +0 -1
  157. package/dist/audit/domain/comment-dividers.js.map +0 -1
  158. package/dist/audit/domain/link-references.js.map +0 -1
  159. package/dist/audit/domain/mappings.js.map +0 -1
  160. package/dist/audit/domain/markdown-links.js.map +0 -1
  161. package/dist/audit/domain/react-imports.js.map +0 -1
  162. package/dist/audit/domain/since-versions.js.map +0 -1
  163. package/dist/audit/domain/tokenize.js.map +0 -1
  164. package/dist/audit/domain/tsdoc-syntax.js.map +0 -1
  165. package/dist/audit/domain/types.js.map +0 -1
  166. package/dist/audit/output.js.map +0 -1
  167. package/dist/audit/prepare.js.map +0 -1
  168. package/dist/audit/run-comments.js.map +0 -1
  169. package/dist/audit/run-links.js.map +0 -1
  170. package/dist/audit/run-react.js.map +0 -1
  171. package/dist/audit/run.js.map +0 -1
  172. package/dist/bin.js.map +0 -1
  173. package/dist/cli.js.map +0 -1
  174. package/dist/core/cli/format-error.js.map +0 -1
  175. package/dist/core/cli/global-options.js.map +0 -1
  176. package/dist/core/cli/positional.js.map +0 -1
  177. package/dist/core/cli/result-handle.js.map +0 -1
  178. package/dist/core/config/loader.js.map +0 -1
  179. package/dist/core/config/schema.js.map +0 -1
  180. package/dist/core/config/warnings.js.map +0 -1
  181. package/dist/core/config.js.map +0 -1
  182. package/dist/core/errors.js.map +0 -1
  183. package/dist/core/exit-codes.js.map +0 -1
  184. package/dist/core/filesystem/node.js.map +0 -1
  185. package/dist/core/filesystem/port.js.map +0 -1
  186. package/dist/core/glob.js.map +0 -1
  187. package/dist/core/logger.js.map +0 -1
  188. package/dist/core/result.js.map +0 -1
  189. package/dist/core/schema-parse.js.map +0 -1
  190. package/dist/core/source-text-edit.js.map +0 -1
  191. package/dist/core/verbose-diagnostics.js.map +0 -1
  192. package/dist/core/workspace/markdown-walk.js.map +0 -1
  193. package/dist/core/workspace/package-version.js.map +0 -1
  194. package/dist/core/workspace/resolver.js.map +0 -1
  195. package/dist/core/workspace/skip-directories.js.map +0 -1
  196. package/dist/core/workspace/source-walk.js.map +0 -1
  197. package/dist/core/workspace/typescript-walk.js.map +0 -1
  198. package/dist/mirror/cli-result.js.map +0 -1
  199. package/dist/mirror/cli-schema.js.map +0 -1
  200. package/dist/mirror/command.js.map +0 -1
  201. package/dist/mirror/dist-filesystem-impl.js.map +0 -1
  202. package/dist/mirror/domain/constants.js.map +0 -1
  203. package/dist/mirror/domain/dirent-guard.js.map +0 -1
  204. package/dist/mirror/domain/dist-filesystem.js.map +0 -1
  205. package/dist/mirror/domain/errors.js.map +0 -1
  206. package/dist/mirror/domain/exports.js.map +0 -1
  207. package/dist/mirror/domain/package-display-name.js.map +0 -1
  208. package/dist/mirror/domain/path-normalizer.js.map +0 -1
  209. package/dist/mirror/domain/types.js.map +0 -1
  210. package/dist/mirror/output.js.map +0 -1
  211. package/dist/mirror/package-path.js.map +0 -1
  212. package/dist/mirror/prepare.js.map +0 -1
  213. package/dist/mirror/supplement-exports.js.map +0 -1
  214. package/dist/mirror/sync-reporter.js.map +0 -1
  215. package/dist/mirror/sync-types.js.map +0 -1
  216. package/dist/mirror/sync-workspace-package.js.map +0 -1
  217. package/dist/mirror/sync.js.map +0 -1
  218. package/dist/mirror/write-exports.js.map +0 -1
  219. package/dist/tag/cli-result.js.map +0 -1
  220. package/dist/tag/cli-schema.js.map +0 -1
  221. package/dist/tag/command.js.map +0 -1
  222. package/dist/tag/domain/types.js.map +0 -1
  223. package/dist/tag/output.js.map +0 -1
  224. package/dist/tag/prepare.js.map +0 -1
  225. package/dist/tag/resolve-target-path.js.map +0 -1
  226. package/dist/tag/since-writer.js.map +0 -1
  227. package/dist/tag/sync.js.map +0 -1
  228. package/dist/tag/target-candidates.js.map +0 -1
  229. package/dist/tag/target-runner.js.map +0 -1
  230. package/dist/tag/version-resolver.js.map +0 -1
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 CodeFast Labs
3
+ Copyright (c) 2024 Codefast Labs
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -1,19 +1,31 @@
1
1
  # @codefast/cli
2
2
 
3
- Developer CLI for the [Codefast monorepo](https://github.com/codefastlabs/codefast) — `arrange` Tailwind class strings,
4
- `audit` source conventions (RTL, markdown links, comment dividers, React imports), `mirror` export maps from `dist/`,
5
- and `tag` exported APIs with `@since`.
3
+ The `codefast` command line for the [codefast monorepo](https://github.com/codefastlabs/codefast): `arrange` Tailwind
4
+ class strings, `audit` source conventions, `mirror` export maps from `dist/`, `pack-slim` the publish artifact, and
5
+ `tag` exported APIs with `@since`.
6
6
 
7
7
  [![npm version](https://img.shields.io/npm/v/@codefast/cli)](https://www.npmjs.com/package/@codefast/cli)
8
- [![license](https://img.shields.io/npm/l/@codefast/cli)](https://github.com/codefastlabs/codefast/blob/main/LICENSE)
8
+ [![license](https://img.shields.io/npm/l/@codefast/cli)](./LICENSE)
9
9
 
10
- This package exists to maintain the Codefast repository itself. It is published to npm and works in any pnpm workspace
11
- with a similar layout, but its flags and defaults follow Codefast's conventions — treat it as repo tooling, not a
12
- general-purpose product.
10
+ ## Overview
11
+
12
+ `codefast` is the command line for the [codefast monorepo](https://github.com/codefastlabs/codefast). It has five
13
+ commands: `arrange` regroups Tailwind class strings, `audit` checks source conventions, `mirror` writes
14
+ `package.json#exports` from `dist/`, `pack-slim` slims the publish artifact down to what a consumer reads, and `tag`
15
+ stamps exported APIs with `@since`.
16
+
17
+ This is repo tooling, published to npm. It runs in any pnpm workspace with a similar layout, but its flags and defaults
18
+ follow the codefast conventions rather than aiming to be a general-purpose product.
19
+
20
+ - **Safe by default.** Every writing command has `--dry-run`, and every audit is read-only except
21
+ `audit comments --fix`.
22
+ - **Scriptable.** `--json` prints one JSON object on stdout and suppresses human progress output.
23
+ - **CI-ready.** Audits exit non-zero when findings remain, so they gate a pipeline without extra glue.
24
+ - **Configurable.** An optional `codefast.config.*` file, validated by a strict schema, adjusts every command.
13
25
 
14
26
  ## Installation and usage
15
27
 
16
- Inside the Codefast monorepo, the CLI runs from its built output via root `package.json` scripts:
28
+ Inside the codefast monorepo, the CLI runs from its built output via root `package.json` scripts:
17
29
 
18
30
  ```bash
19
31
  pnpm --filter @codefast/cli build # produce dist/bin.js first
@@ -32,8 +44,11 @@ pnpm run cli:audit:rtl # codefast audit rtl
32
44
  pnpm run cli:audit:links # codefast audit links
33
45
  pnpm run cli:audit:comments # codefast audit comments
34
46
  pnpm run cli:audit:react # codefast audit react
47
+ pnpm run cli:audit:display-names # codefast audit display-names
35
48
  ```
36
49
 
50
+ `pnpm run version-packages` runs `changeset version` and then `codefast tag`, so published APIs are stamped at release.
51
+
37
52
  Standalone install (Node >= 24):
38
53
 
39
54
  ```bash
@@ -42,15 +57,18 @@ pnpm add -g @codefast/cli
42
57
  pnpm dlx @codefast/cli --help
43
58
  ```
44
59
 
45
- Every command writes by default; pass `--dry-run` to preview. The global `--no-color` flag must come before the command
46
- name (`codefast --no-color mirror`). Commands that accept `--json` print a single JSON object on stdout and suppress
47
- human progress output.
60
+ The package is published on 0.x and versioned on its own track: breaking changes ship as minor versions, so pin the
61
+ minor version when you need stability.
62
+
63
+ Every writing command writes by default; pass `--dry-run` to preview. The global `--no-color` flag must come before the
64
+ command name (`codefast --no-color mirror`). Commands that accept `--json` print a single JSON object on stdout and
65
+ suppress human progress output.
48
66
 
49
67
  ## `arrange`
50
68
 
51
- Rewrites Tailwind class strings inside `cn()` and `tv()` calls, regrouping utilities in render-pipeline order
52
- (existence, position, layout, sizing, spacing, shape, background, shadow, typography, composite, motion, behavior,
53
- state, selector) instead of alphabetically.
69
+ Rewrites Tailwind class strings inside `cn()` and `tv()` calls, regrouping utilities in render-pipeline order —
70
+ existence, position, layout, sizing, spacing, shape, background, shadow, typography, composite, motion, starting,
71
+ behavior, state, selector — instead of alphabetically.
54
72
 
55
73
  ```bash
56
74
  codefast arrange inspect packages/ui/src # read-only report
@@ -58,8 +76,9 @@ codefast arrange --dry-run packages/ui/src # preview the rewrite
58
76
  codefast arrange packages/ui/src # write
59
77
  ```
60
78
 
61
- When `[target]` is omitted, `arrange` uses the nearest package directory found by walking up from the current working
62
- directory. Directory scans skip test files (`*.test.*` / `*.spec.*`); pass such a file explicitly to process it.
79
+ When `[target]` is omitted, `arrange` uses the nearest directory with a `package.json` found by walking up from the
80
+ current working directory. Directory scans skip test files (`*.test.*` / `*.spec.*`), because a `cn()` inside an
81
+ assertion is intentional; pass such a file explicitly to process it.
63
82
 
64
83
  | Flag | Description |
65
84
  | -------------------- | ----------------------------------------------------------------------------- |
@@ -68,6 +87,8 @@ directory. Directory scans skip test files (`*.test.*` / `*.spec.*`); pass such
68
87
  | `--cn-import <spec>` | Override the module specifier used when a missing `cn` import is added. |
69
88
  | `--json` | Print one JSON object on stdout (suppresses human progress). |
70
89
 
90
+ Exits `1` when the `arrange.onAfterWrite` hook fails, `0` otherwise.
91
+
71
92
  ### `arrange inspect [target]`
72
93
 
73
94
  Read-only report of long strings, nested `cn` inside `tv()`, and related findings. Accepts `--json`.
@@ -94,9 +115,10 @@ codefast arrange group --tv "flex items-center gap-2"
94
115
 
95
116
  ## `mirror`
96
117
 
97
- Scans each workspace package's built `dist/` tree and writes its `package.json#exports` map (plus top-level `main`,
98
- `module`, `types`, and a `files` entry for `dist`). The workspace root is discovered via `pnpm-workspace.yaml`, so it
99
- runs from anywhere inside the repo. Build first — `mirror` reads `dist/`, and stale output produces stale exports.
118
+ Scans each workspace package's built `dist/` tree and writes its `package.json#exports` map, plus top-level `main`,
119
+ `module`, and `types` mirrored from the root export and a `files` entry for `dist`. The workspace root is the directory
120
+ holding `pnpm-workspace.yaml`, so it runs from anywhere inside the repo. Build first — `mirror` reads `dist/`, and stale
121
+ output produces stale exports.
100
122
 
101
123
  ```bash
102
124
  codefast mirror # all workspace packages
@@ -112,6 +134,36 @@ codefast mirror --dry-run # report changes without writing
112
134
 
113
135
  Exits `1` when any package fails, `0` otherwise.
114
136
 
137
+ ## `pack-slim`
138
+
139
+ Slims published packages down to what a consumer's `tsc` and Node read, so the npm tarball ships `dist` runtime and
140
+ types only and its `package.json` describes nothing else. Where `mirror` writes the full exports — including the
141
+ `source` condition — for repo dev, `pack-slim` removes the development lane for publish: it drops `src` from `files`,
142
+ every `source` condition from `exports`/`imports`, every `imports` entry left pointing outside `files` (the `#/tests/*`
143
+ and `#/examples/*` aliases), every script that is not an install or publish lifecycle hook, `devDependencies`, and the
144
+ `dist` source maps plus their dangling `sourceMappingURL` directives. Private packages are skipped, since
145
+ `changeset publish` never publishes them. It is meant to run on an ephemeral CI checkout right before publish (the
146
+ release workflow runs it as its publish step), so it is never committed.
147
+
148
+ Because its result must never be committed, `pack-slim` refuses to write when the git working tree has uncommitted
149
+ tracked changes — guarding against an accidental local run landing on real work. `--dry-run` is exempt (it writes
150
+ nothing) and `--force` overrides the guard. In CI the check is transparent: `dist` is gitignored, so the tree is clean
151
+ when the release workflow runs it.
152
+
153
+ ```bash
154
+ codefast pack-slim # every published package
155
+ codefast pack-slim packages/ui # one package (path relative to repo root)
156
+ codefast pack-slim --dry-run # report what would be stripped without touching a file
157
+ ```
158
+
159
+ | Flag | Description |
160
+ | ----------- | ----------------------------------------------------------------- |
161
+ | `--dry-run` | Report what would be stripped without touching any file. |
162
+ | `--force` | Run even if the git working tree has uncommitted tracked changes. |
163
+ | `--json` | Print one JSON summary on stdout (suppresses human progress). |
164
+
165
+ Exits `1` when any package fails, `0` otherwise.
166
+
115
167
  ## `audit rtl`
116
168
 
117
169
  Read-only scan for physical-direction Tailwind classes (e.g. `ml-*`, `left-*`, `text-left`) that should use logical
@@ -128,16 +180,17 @@ codefast audit rtl --json # machine-readable summary
128
180
  | -------- | --------------------------------- |
129
181
  | `--json` | Print one JSON summary on stdout. |
130
182
 
131
- Configure intentional exceptions via `audit.rtl.allowlist` in `codefast.config` — each entry is a bare class token or
183
+ With no `[target]`, the scan root is `audit.rtl.target` from the config; when neither is set the command fails.
184
+ Configure intentional exceptions via `audit.rtl.allowlist` — each entry is a bare class token or
132
185
  `repo/relative/path.tsx:token`.
133
186
 
134
187
  ## `audit links`
135
188
 
136
189
  Read-only scan for markdown cross-references that point at nothing: a relative path that does not exist, an in-document
137
190
  anchor with no matching heading or `<a id>`, and an anchor into another document that the target does not offer. That
138
- last one is the reason this exists — it fails silently in a browser by scrolling to the top, so nothing else notices.
139
- External URLs are somebody else's to check and are skipped, as are links inside fenced code, which are examples rather
140
- than references. Exits non-zero when breakages remain so it can gate CI.
191
+ last one is the reason this exists — a browser fails it silently by scrolling to the top. External URLs are not checked,
192
+ and links inside fenced code are treated as examples rather than references. Exits non-zero when breakages remain so it
193
+ can gate CI.
141
194
 
142
195
  ```bash
143
196
  codefast audit links # whole repo
@@ -149,14 +202,16 @@ codefast audit links --json # machine-readable summary
149
202
  | -------- | --------------------------------- |
150
203
  | `--json` | Print one JSON summary on stdout. |
151
204
 
152
- Configure intentional exceptions via `audit.links.allowlist` in `codefast.config` — each entry is a bare link target or
205
+ Configure intentional exceptions via `audit.links.allowlist` — each entry is a bare link target or
153
206
  `repo/relative/doc.md:target`.
154
207
 
155
- ## audit comments
208
+ ## `audit comments`
156
209
 
157
- Scans source doc comments for the repo's comment conventions — chiefly section dividers that are not in the one allowed
158
- form. Everything it reports is mechanical, so `--fix` rewrites every fixable divider in place and a red run is one
159
- `--fix` from green. Exits non-zero when unfixable issues remain so it can gate CI.
210
+ Scans source comments for the repo's comment conventions. Section dividers that are not in the one allowed form are
211
+ mechanical, so `--fix` rewrites them in place. The rest is reported for a person to fix: TSDoc grammar errors, JSDoc
212
+ `{type}` payloads, comments pointing at repo documents, `@param` lists that name some parameters but not all, `@param`
213
+ descriptions without the `-` separator, `@since` tags out of position or naming a version the package has not reached,
214
+ and comment links to missing paths. Exits non-zero when unfixed findings remain so it can gate CI.
160
215
 
161
216
  ```bash
162
217
  codefast audit comments # whole repo
@@ -165,21 +220,24 @@ codefast audit comments --fix # rewrite fixable dividers in place
165
220
  codefast audit comments --json # machine-readable summary
166
221
  ```
167
222
 
168
- | Flag | Description |
169
- | -------- | ------------------------------------------------------------- |
170
- | `--fix` | Rewrite every mechanically fixable divider in place. |
171
- | `--json` | Print one JSON summary on stdout (suppresses human progress). |
223
+ | Flag | Description |
224
+ | -------- | ---------------------------------------------------- |
225
+ | `--fix` | Rewrite every mechanically fixable divider in place. |
226
+ | `--json` | Print one JSON summary on stdout. |
227
+
228
+ Configure intentional exceptions via `audit.comments.allowlist` — each entry is a divider line as written or
229
+ `repo/relative/path.ts:<divider>`.
172
230
 
173
231
  ## `audit react`
174
232
 
175
233
  Read-only scan enforcing the repo's React import policy: members are imported by name. Flags `import * as React` and
176
- default `React` imports (type-only included), plus the sneakiest variant — an implicit `React.*` UMD-global type
177
- reference (`e: React.FormEvent` with no import), which both `tsc` and the linter accept silently through the
178
- `export as namespace React` declaration in `@types/react`. Exits non-zero when violations remain so it can gate CI.
234
+ default `React` imports (type-only included), plus an implicit `React.*` UMD-global type reference (`e: React.FormEvent`
235
+ with no import), which `tsc` accepts silently through the `export as namespace React` declaration in `@types/react`.
236
+ Exits non-zero when violations remain so it can gate CI.
179
237
 
180
238
  ```bash
181
239
  codefast audit react # whole repo
182
- codefast audit react apps/ui/src # explicit target
240
+ codefast audit react apps/web/src # explicit target
183
241
  codefast audit react --json # machine-readable summary
184
242
  ```
185
243
 
@@ -187,14 +245,37 @@ codefast audit react --json # machine-readable summary
187
245
  | -------- | --------------------------------- |
188
246
  | `--json` | Print one JSON summary on stdout. |
189
247
 
190
- Configure intentional exceptions via `audit.react.allowlist` in `codefast.config` — each entry is the offending source
191
- text as written or `repo/relative/path.tsx:<text>`.
248
+ Configure intentional exceptions via `audit.react.allowlist` — each entry is the offending source text as written or
249
+ `repo/relative/path.tsx:<text>`.
250
+
251
+ ## `audit display-names`
252
+
253
+ Read-only scan enforcing the display-name convention for every string a `token()`, `tag()` or module factory takes: a
254
+ name is spelled like the TS symbol it stands for, under its owner's namespace — `<namespace>:<Name>`. The namespace is a
255
+ kebab-case package, app or feature slug (or a scoped package name); a token or module name is PascalCase, because it
256
+ stands for a type or a unit of composition; a tag key is camelCase, because it names an attribute. Scans TypeScript and
257
+ markdown alike, since a doc sample is what a reader copies; skips `tests/`, `benchmarks/`, `.changeset/` and
258
+ `CHANGELOG.md`, where a name is scoped by its file or quoted as it was. Exits non-zero when violations remain so it can
259
+ gate CI.
260
+
261
+ ```bash
262
+ codefast audit display-names # whole repo
263
+ codefast audit display-names packages/di/examples # explicit target
264
+ codefast audit display-names --json # machine-readable summary
265
+ ```
266
+
267
+ | Flag | Description |
268
+ | -------- | --------------------------------- |
269
+ | `--json` | Print one JSON summary on stdout. |
270
+
271
+ Configure intentional exceptions via `audit.displayNames.allowlist` — each entry is the call as written, through its
272
+ closing quote (or parenthesis when the name is the only argument), or `repo/relative/path.ts:<call>`.
192
273
 
193
274
  ## `tag`
194
275
 
195
- Adds `@since <version>` tags to doc comments of exported declarations that lack one, creating the doc block when
196
- missing. The version comes from the nearest `package.json` walking up from each target file. Declarations that already
197
- carry `@since` are left alone.
276
+ Adds `@since <version>` tags to the doc comments of exported declarations that lack one, creating the doc block when
277
+ there is none. The version comes from the nearest `package.json` above each target file. Declarations that already carry
278
+ `@since` are left alone.
198
279
 
199
280
  ```bash
200
281
  codefast tag # auto-discover workspace packages from cwd
@@ -207,15 +288,17 @@ codefast tag --dry-run # summary only, no writes
207
288
  | `--dry-run` | Show summary without writing files. |
208
289
  | `--json` | Print one JSON summary on stdout (suppresses human progress). |
209
290
 
210
- In this repo, `tag` runs as part of the release workflow so published APIs carry accurate version metadata — never
211
- hand-write `@since` tags.
291
+ Exits `1` when no target is selected, when any target fails, or when the `tag.onAfterWrite` hook fails. In this repo,
292
+ `tag` runs inside `pnpm run version-packages` so published APIs carry accurate version metadata — never hand-write
293
+ `@since` tags.
212
294
 
213
295
  ## Configuration
214
296
 
215
297
  An optional `codefast.config.*` file adjusts `mirror`, `tag`, `arrange`, and `audit`. The CLI walks up from the working
216
298
  directory and uses the first match, checking `codefast.config.mjs`, `codefast.config.js`, `codefast.config.cjs`, then
217
299
  `codefast.config.json` in each directory. JS configs are loaded via [jiti](https://github.com/unjs/jiti), so only run
218
- the CLI in repositories you trust; JSON configs cannot define hooks.
300
+ the CLI in repositories you trust; JSON configs cannot define hooks. The schema is strict: an unknown key is a
301
+ configuration error.
219
302
 
220
303
  ```js
221
304
  // codefast.config.js
@@ -226,8 +309,9 @@ export default {
226
309
  mirror: {
227
310
  "@acme/ui": {
228
311
  strip: "./components/", // flatten a dist/ prefix out of public specifiers
312
+ exclude: ["./internal/*"], // specifiers to leave out of the generated map
229
313
  exports: { "./css/*": "./src/css/*" }, // extra or overriding entries
230
- source: true, // add a `source` condition (string overrides the root path)
314
+ source: true, // add a `source` condition (a string overrides the root path)
231
315
  types: true, // add `types` when a .d.ts exists
232
316
  import: true, // add the `import` condition
233
317
  css: true, // boolean or { enabled, forceExportFiles, customExports }
@@ -236,7 +320,7 @@ export default {
236
320
  "@acme/internal": false,
237
321
  },
238
322
  tag: {
239
- skipPackages: ["@acme/internal"],
323
+ skipPackages: ["@acme/internal", "@apps/*"], // glob patterns matched against package names
240
324
  onAfterWrite: ({ files }) => execSync(`oxfmt ${files.join(" ")}`, { stdio: "inherit" }),
241
325
  },
242
326
  arrange: {
@@ -250,12 +334,15 @@ export default {
250
334
  "packages/ui/src/variants/sheet.ts:data-open:slide-in-from-left-10",
251
335
  ],
252
336
  },
337
+ links: { allowlist: [] }, // bare link target, or `repo/relative/doc.md:target`
338
+ comments: { allowlist: [] }, // divider as written, or `repo/relative/path.ts:<divider>`
339
+ react: { allowlist: [] }, // offending text as written, or `repo/relative/path.tsx:<text>`
253
340
  },
254
341
  };
255
342
  ```
256
343
 
257
- The `onAfterWrite` hooks (sync or async) run only when files were actually written — never on `--dry-run`. A hook
258
- failure is reported on stderr and the command exits `1`.
344
+ `source`, `types`, and `import` default to `true`. The `onAfterWrite` hooks (sync or async) run only when files were
345
+ actually written — never on `--dry-run`. A hook failure is reported on stderr and the command exits `1`.
259
346
 
260
347
  ## Exit codes
261
348
 
@@ -263,8 +350,21 @@ failure is reported on stderr and the command exits `1`.
263
350
  | ---- | --------------------------------------------------------------- |
264
351
  | `0` | Success. |
265
352
  | `1` | General failure (missing paths, failed packages, failed hooks). |
266
- | `2` | Invalid invocation or input. |
353
+ | `2` | Invalid arguments or configuration. |
354
+
355
+ ## Documentation
356
+
357
+ - [codefastlabs.com/docs/cli](https://codefastlabs.com/docs/cli) — this document, rendered.
358
+ - [`ARCHITECTURE.md`](./ARCHITECTURE.md) — how the package is laid out: command wiring, the `Result` type, and the
359
+ filesystem port.
360
+ - [`DECISIONS.md`](./DECISIONS.md) — the design decisions that shape the package and the reasons behind them.
361
+ - [`CHANGELOG.md`](./CHANGELOG.md) — release notes for every published version.
362
+
363
+ ## Contributing
364
+
365
+ The package is developed in the [codefast monorepo](https://github.com/codefastlabs/codefast); the repo-wide
366
+ [contributing guide](../../CONTRIBUTING.md) covers setup, the test taxonomy, and the release flow.
267
367
 
268
368
  ## License
269
369
 
270
- [MIT](https://github.com/codefastlabs/codefast/blob/main/LICENSE)
370
+ Released under the [MIT License](./LICENSE).
@@ -23,5 +23,4 @@ export function analyzeDirectory(fs, analyzeRootPath) {
23
23
  catch (caughtError) {
24
24
  return err(new AppError("INFRA_FAILURE", messageFrom(caughtError), caughtError));
25
25
  }
26
- }
27
- //# sourceMappingURL=analyze.js.map
26
+ }
@@ -31,5 +31,4 @@ export const arrangeSuggestGroupsRequestSchema = z.object({
31
31
  .min(1, 'Pass a class string. Example: codefast arrange group "flex gap-2 text-sm rounded-md"'),
32
32
  emitTvStyleArray: z.boolean(),
33
33
  trailingClassName: z.boolean(),
34
- });
35
- //# sourceMappingURL=cli-schema.js.map
34
+ });
@@ -168,5 +168,4 @@ function formatArrangeGroupJsonOutput(output) {
168
168
  }
169
169
  function exitCodeForArrangeSyncResult(result) {
170
170
  return result.hookError !== null ? CLI_EXIT_GENERAL_ERROR : CLI_EXIT_SUCCESS;
171
- }
172
- //# sourceMappingURL=command.js.map
171
+ }
@@ -120,5 +120,4 @@ export function accumulateAnalyzeReportForSourceFile(report, domainSf, sourceTex
120
120
  for (const stmt of domainSf.statements) {
121
121
  visitTypeScriptSubtree(stmt);
122
122
  }
123
- }
124
- //# sourceMappingURL=analyze-service.js.map
123
+ }
@@ -270,5 +270,4 @@ export function lineOfSourcePosition(sourceText, pos) {
270
270
  }
271
271
  }
272
272
  return line;
273
- }
274
- //# sourceMappingURL=ast-node.js.map
273
+ }
@@ -85,5 +85,4 @@ export function collectUnconditionalTailwindLiteralsFromCnArguments(args) {
85
85
  }
86
86
  }
87
87
  return staticLits;
88
- }
89
- //# sourceMappingURL=collectors-cn.js.map
88
+ }
@@ -22,5 +22,4 @@ export function jsxClassNameStaticLiteral(jsxClassNameAttribute) {
22
22
  }
23
23
  }
24
24
  return undefined;
25
- }
26
- //# sourceMappingURL=collectors-jsx.js.map
25
+ }
@@ -325,5 +325,4 @@ export function collectGroupableStringNodes(sourceFile) {
325
325
  visitTypeScriptSubtree(stmt);
326
326
  }
327
327
  return results;
328
- }
329
- //# sourceMappingURL=collectors-tv.js.map
328
+ }
@@ -151,5 +151,4 @@ export function unwrapCnInsideTvCallReplacement(call, sourceText) {
151
151
  }
152
152
  lines.push(`${baseIndent}]`);
153
153
  return lines.join("\n");
154
- }
155
- //# sourceMappingURL=helpers.js.map
154
+ }
@@ -153,5 +153,4 @@ export function collectSimplifyTargets(sourceFile) {
153
153
  visitNode(stmt);
154
154
  }
155
155
  return results;
156
- }
157
- //# sourceMappingURL=simplify-targets.js.map
156
+ }
@@ -184,5 +184,4 @@ export function planGroupEditForTarget(target, textAfterUnwrap, withClassName) {
184
184
  reportNode: target.item.primaryClassLiteral,
185
185
  label: target.item.isTvContext ? "tv" : "cn",
186
186
  };
187
- }
188
- //# sourceMappingURL=targets.js.map
187
+ }
@@ -221,5 +221,4 @@ export const STATE_PREFIXES = new Set([
221
221
  "backdrop",
222
222
  "details-content",
223
223
  "popover-open",
224
- ]);
225
- //# sourceMappingURL=constants.js.map
224
+ ]);
@@ -138,5 +138,4 @@ export function countPersistedGroupFileEdits(work) {
138
138
  */
139
139
  export function groupFileWorkHasNothingToReport(work) {
140
140
  return work.editSitesCount === 0 && work.cnInTvNoReplacement === 0;
141
- }
142
- //# sourceMappingURL=grouping-service.js.map
141
+ }
@@ -433,5 +433,4 @@ export function summarizeGroupBucketLabels(groups) {
433
433
  }
434
434
  return onlyBucket;
435
435
  });
436
- }
437
- //# sourceMappingURL=grouping.js.map
436
+ }
@@ -158,5 +158,4 @@ export function ensureCnImport(sourceFile, cnImportOverride) {
158
158
  insertAt = 0;
159
159
  }
160
160
  return `${sourceText.slice(0, insertAt)}${importLine}\n${sourceText.slice(insertAt)}`;
161
- }
162
- //# sourceMappingURL=imports.js.map
161
+ }
@@ -104,5 +104,4 @@ export function formatJsxCnAttributeValue(groups, source, valueNodeStart) {
104
104
  commaAfterLastGroup: groups.length > 1,
105
105
  });
106
106
  return `{cn(\n${cnArgumentsBlock}\n${baseIndent})}`;
107
- }
108
- //# sourceMappingURL=source-text-formatters.js.map
107
+ }
@@ -50,5 +50,4 @@ export function stripVariants(token) {
50
50
  withoutVariants = withoutVariants.slice(colonIdx + 1);
51
51
  }
52
52
  return withoutVariants;
53
- }
54
- //# sourceMappingURL=tailwind-token.js.map
53
+ }
@@ -448,5 +448,4 @@ export function bucketsMergeCompatible(a, b) {
448
448
  return false;
449
449
  }
450
450
  return bucketsCompatible(a, b);
451
- }
452
- //# sourceMappingURL=token-classifier.js.map
451
+ }
@@ -7,5 +7,4 @@
7
7
  *
8
8
  * `arbitrary` and `other` are non-pipeline tails for `[prop:value]` syntax and unknown utilities.
9
9
  */
10
- export {};
11
- //# sourceMappingURL=types.js.map
10
+ export {};
@@ -124,5 +124,4 @@ function printGroupFilePreviewBody(args) {
124
124
  logger.out(` ${plan.replacement.split("\n").join("\n ")}`);
125
125
  logger.out(` // Buckets: ${JSON.stringify(plan.bucketSummary)}`);
126
126
  }
127
- }
128
- //# sourceMappingURL=output.js.map
127
+ }
@@ -42,5 +42,4 @@ export function processArrangeGroupFile(fs, args) {
42
42
  totalFound: persistedEditCount + work.cnInTvNoReplacement,
43
43
  changed: persistedEditCount,
44
44
  };
45
- }
46
- //# sourceMappingURL=process-file.js.map
45
+ }
@@ -31,5 +31,4 @@ function findNearestPackageDirectory(fs, currentWorkingDirectory) {
31
31
  }
32
32
  currentDir = parentDirectory;
33
33
  }
34
- }
35
- //# sourceMappingURL=resolve-target.js.map
34
+ }
@@ -28,5 +28,4 @@ export function scanArrangeTargets(fs, targetPath) {
28
28
  }
29
29
  }
30
30
  return [resolvedTargetPath];
31
- }
32
- //# sourceMappingURL=scan-target.js.map
31
+ }
@@ -27,5 +27,4 @@ export function processArrangeSimplifyFile(fs, args) {
27
27
  }
28
28
  fs.writeFileSync(filePath, textAfterImportDrop, "utf8");
29
29
  return { filePath, totalFound, changed: totalFound };
30
- }
31
- //# sourceMappingURL=simplify-process-file.js.map
30
+ }
@@ -27,5 +27,4 @@ export async function runArrangeSimplify(fs, args) {
27
27
  hookError: null,
28
28
  previewPlans: [],
29
29
  });
30
- }
31
- //# sourceMappingURL=simplify-sync.js.map
30
+ }
@@ -15,5 +15,4 @@ export function parseDomainSourceFile(filePath, sourceText) {
15
15
  logger.err(`[domain-source-parser] ${messageFrom(caughtError)}`);
16
16
  throw caughtError;
17
17
  }
18
- }
19
- //# sourceMappingURL=source-parse.js.map
18
+ }
@@ -12,5 +12,4 @@ export function suggestCnGroupsFromCli(request) {
12
12
  : formatCnCall(groups, { trailingClassName: request.trailingClassName });
13
13
  const bucketsCommentLine = `// Buckets: ${JSON.stringify(summarizeGroupBucketLabels(groups))}`;
14
14
  return { primaryLine, bucketsCommentLine };
15
- }
16
- //# sourceMappingURL=suggest.js.map
15
+ }
@@ -46,5 +46,4 @@ export async function runArrangeSync(fs, request) {
46
46
  ? await runOnAfterWriteHook(arrangeConfig?.onAfterWrite, modifiedFiles)
47
47
  : null;
48
48
  return ok({ filePaths, modifiedFiles, totalFound, totalChanged, hookError, previewPlans });
49
- }
50
- //# sourceMappingURL=sync.js.map
49
+ }
@@ -453,5 +453,4 @@ export class TypeScriptAstTranslator {
453
453
  statements,
454
454
  };
455
455
  }
456
- }
457
- //# sourceMappingURL=typescript-ast-translator.js.map
456
+ }
@@ -29,5 +29,4 @@ export async function prepareArrangeWorkspace(fs, args) {
29
29
  return loadedOutcome;
30
30
  }
31
31
  return ok({ resolvedTarget, rootDir, config: loadedOutcome.value.config });
32
- }
33
- //# sourceMappingURL=workspace.js.map
32
+ }
@@ -45,6 +45,17 @@ export const reactAuditRunRequestSchema = z.object({
45
45
  allowlist: z.array(z.string()).optional(),
46
46
  json: z.boolean(),
47
47
  });
48
+ /**
49
+ * Zod schema for {@link DisplayNameAuditRunRequest}.
50
+ *
51
+ * @since 0.9.0
52
+ */
53
+ export const displayNameAuditRunRequestSchema = z.object({
54
+ rootDir: z.string().min(1),
55
+ targetPath: z.string().min(1),
56
+ allowlist: z.array(z.string()).optional(),
57
+ json: z.boolean(),
58
+ });
48
59
  /**
49
60
  * Resolves a path that may be absolute or relative to `rootDir`.
50
61
  *
@@ -52,5 +63,4 @@ export const reactAuditRunRequestSchema = z.object({
52
63
  */
53
64
  export function resolveRepoRelativePath(rootDir, maybeRelative) {
54
65
  return path.isAbsolute(maybeRelative) ? path.resolve(maybeRelative) : path.resolve(rootDir, maybeRelative);
55
- }
56
- //# sourceMappingURL=cli-schema.js.map
66
+ }