@codefast/cli 0.7.0 → 0.8.1

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 (222) hide show
  1. package/README.md +152 -37
  2. package/dist/arrange/analyze.js +3 -2
  3. package/dist/arrange/cli-schema.js +7 -2
  4. package/dist/arrange/command.js +3 -2
  5. package/dist/arrange/domain/analyze-service.js +3 -2
  6. package/dist/arrange/domain/ast/ast-node.js +35 -2
  7. package/dist/arrange/domain/ast/collectors-cn.js +9 -2
  8. package/dist/arrange/domain/ast/collectors-jsx.js +3 -2
  9. package/dist/arrange/domain/ast/collectors-tv.js +11 -2
  10. package/dist/arrange/domain/ast/helpers.js +5 -2
  11. package/dist/arrange/domain/ast/simplify-targets.js +1 -2
  12. package/dist/arrange/domain/ast/targets.js +7 -2
  13. package/dist/arrange/domain/constants.js +1 -2
  14. package/dist/arrange/domain/grouping-service.js +15 -2
  15. package/dist/arrange/domain/grouping.js +3 -2
  16. package/dist/arrange/domain/imports.js +3 -2
  17. package/dist/arrange/domain/source-text-formatters.js +9 -2
  18. package/dist/arrange/domain/tailwind-token.js +3 -2
  19. package/dist/arrange/domain/token-classifier.js +5 -2
  20. package/dist/arrange/domain/types.js +1 -2
  21. package/dist/arrange/output.js +9 -2
  22. package/dist/arrange/process-file.js +3 -2
  23. package/dist/arrange/resolve-target.js +3 -2
  24. package/dist/arrange/scan-target.js +3 -2
  25. package/dist/arrange/simplify-process-file.js +3 -2
  26. package/dist/arrange/simplify-sync.js +3 -2
  27. package/dist/arrange/source-parse.js +3 -2
  28. package/dist/arrange/suggest.js +3 -2
  29. package/dist/arrange/sync.js +3 -2
  30. package/dist/arrange/typescript-ast-translator.js +3 -2
  31. package/dist/arrange/workspace.js +3 -2
  32. package/dist/audit/cli-schema.js +14 -4
  33. package/dist/audit/command.js +45 -6
  34. package/dist/audit/domain/audit-file.js +4 -5
  35. package/dist/audit/domain/comment-content.js +1 -2
  36. package/dist/audit/domain/comment-dividers.js +1 -2
  37. package/dist/audit/domain/link-references.js +1 -2
  38. package/dist/audit/domain/mappings.js +10 -9
  39. package/dist/audit/domain/markdown-links.js +1 -2
  40. package/dist/audit/domain/react-imports.js +91 -0
  41. package/dist/audit/domain/since-versions.js +85 -0
  42. package/dist/audit/domain/tokenize.js +7 -6
  43. package/dist/audit/domain/tsdoc-syntax.js +1 -2
  44. package/dist/audit/domain/types.js +1 -2
  45. package/dist/audit/output.js +45 -5
  46. package/dist/audit/prepare.js +33 -3
  47. package/dist/audit/run-comments.js +26 -2
  48. package/dist/audit/run-links.js +1 -2
  49. package/dist/audit/run-react.js +55 -0
  50. package/dist/audit/run.js +2 -3
  51. package/dist/bin.js +1 -2
  52. package/dist/cli.js +5 -2
  53. package/dist/core/cli/format-error.js +3 -2
  54. package/dist/core/cli/global-options.js +1 -2
  55. package/dist/core/cli/positional.js +1 -2
  56. package/dist/core/cli/result-handle.js +5 -20
  57. package/dist/core/config/loader.js +3 -2
  58. package/dist/core/config/schema.js +27 -9
  59. package/dist/core/config/warnings.js +3 -2
  60. package/dist/core/config.js +3 -2
  61. package/dist/core/errors.js +3 -2
  62. package/dist/core/exit-codes.js +5 -2
  63. package/dist/core/filesystem/node.js +3 -2
  64. package/dist/core/filesystem/port.js +1 -2
  65. package/dist/core/glob.js +1 -2
  66. package/dist/core/logger.js +3 -2
  67. package/dist/core/result.js +5 -2
  68. package/dist/core/schema-parse.js +3 -2
  69. package/dist/core/source-text-edit.js +9 -2
  70. package/dist/core/verbose-diagnostics.js +3 -2
  71. package/dist/core/workspace/markdown-walk.js +1 -2
  72. package/dist/core/workspace/package-version.js +24 -0
  73. package/dist/core/workspace/resolver.js +3 -2
  74. package/dist/core/workspace/skip-directories.js +3 -2
  75. package/dist/core/workspace/source-walk.js +1 -2
  76. package/dist/core/workspace/typescript-walk.js +3 -2
  77. package/dist/mirror/cli-result.js +5 -2
  78. package/dist/mirror/cli-schema.js +3 -2
  79. package/dist/mirror/command.js +3 -2
  80. package/dist/mirror/dist-filesystem-impl.js +3 -2
  81. package/dist/mirror/domain/constants.js +11 -2
  82. package/dist/mirror/domain/dirent-guard.js +1 -2
  83. package/dist/mirror/domain/dist-filesystem.js +1 -2
  84. package/dist/mirror/domain/errors.js +5 -2
  85. package/dist/mirror/domain/exports.js +5 -2
  86. package/dist/mirror/domain/package-display-name.js +1 -2
  87. package/dist/mirror/domain/path-normalizer.js +3 -2
  88. package/dist/mirror/domain/types.js +1 -2
  89. package/dist/mirror/output.js +3 -2
  90. package/dist/mirror/package-path.js +5 -2
  91. package/dist/mirror/prepare.js +3 -2
  92. package/dist/mirror/supplement-exports.js +3 -2
  93. package/dist/mirror/sync-reporter.js +1 -2
  94. package/dist/mirror/sync-types.js +1 -2
  95. package/dist/mirror/sync-workspace-package.js +3 -2
  96. package/dist/mirror/sync.js +3 -2
  97. package/dist/mirror/write-exports.js +1 -2
  98. package/dist/pack-slim/cli-result.js +23 -0
  99. package/dist/pack-slim/cli-schema.js +11 -0
  100. package/dist/pack-slim/command.js +79 -0
  101. package/dist/pack-slim/domain/transform.js +95 -0
  102. package/dist/pack-slim/domain/types.js +2 -0
  103. package/dist/pack-slim/output.js +53 -0
  104. package/dist/pack-slim/sync.js +151 -0
  105. package/dist/pack-slim/working-tree.js +45 -0
  106. package/dist/tag/cli-result.js +3 -2
  107. package/dist/tag/cli-schema.js +3 -2
  108. package/dist/tag/command.js +3 -2
  109. package/dist/tag/domain/types.js +1 -2
  110. package/dist/tag/output.js +5 -2
  111. package/dist/tag/prepare.js +3 -2
  112. package/dist/tag/resolve-target-path.js +3 -2
  113. package/dist/tag/since-writer.js +3 -2
  114. package/dist/tag/sync.js +3 -2
  115. package/dist/tag/target-candidates.js +3 -2
  116. package/dist/tag/target-runner.js +3 -2
  117. package/dist/tag/version-resolver.js +8 -23
  118. package/package.json +9 -16
  119. package/dist/arrange/analyze.js.map +0 -1
  120. package/dist/arrange/cli-schema.js.map +0 -1
  121. package/dist/arrange/command.js.map +0 -1
  122. package/dist/arrange/domain/analyze-service.js.map +0 -1
  123. package/dist/arrange/domain/ast/ast-node.js.map +0 -1
  124. package/dist/arrange/domain/ast/collectors-cn.js.map +0 -1
  125. package/dist/arrange/domain/ast/collectors-jsx.js.map +0 -1
  126. package/dist/arrange/domain/ast/collectors-tv.js.map +0 -1
  127. package/dist/arrange/domain/ast/helpers.js.map +0 -1
  128. package/dist/arrange/domain/ast/simplify-targets.js.map +0 -1
  129. package/dist/arrange/domain/ast/targets.js.map +0 -1
  130. package/dist/arrange/domain/constants.js.map +0 -1
  131. package/dist/arrange/domain/grouping-service.js.map +0 -1
  132. package/dist/arrange/domain/grouping.js.map +0 -1
  133. package/dist/arrange/domain/imports.js.map +0 -1
  134. package/dist/arrange/domain/source-text-formatters.js.map +0 -1
  135. package/dist/arrange/domain/tailwind-token.js.map +0 -1
  136. package/dist/arrange/domain/token-classifier.js.map +0 -1
  137. package/dist/arrange/domain/types.js.map +0 -1
  138. package/dist/arrange/output.js.map +0 -1
  139. package/dist/arrange/process-file.js.map +0 -1
  140. package/dist/arrange/resolve-target.js.map +0 -1
  141. package/dist/arrange/scan-target.js.map +0 -1
  142. package/dist/arrange/simplify-process-file.js.map +0 -1
  143. package/dist/arrange/simplify-sync.js.map +0 -1
  144. package/dist/arrange/source-parse.js.map +0 -1
  145. package/dist/arrange/suggest.js.map +0 -1
  146. package/dist/arrange/sync.js.map +0 -1
  147. package/dist/arrange/typescript-ast-translator.js.map +0 -1
  148. package/dist/arrange/workspace.js.map +0 -1
  149. package/dist/audit/cli-schema.js.map +0 -1
  150. package/dist/audit/command.js.map +0 -1
  151. package/dist/audit/domain/audit-file.js.map +0 -1
  152. package/dist/audit/domain/comment-content.js.map +0 -1
  153. package/dist/audit/domain/comment-dividers.js.map +0 -1
  154. package/dist/audit/domain/link-references.js.map +0 -1
  155. package/dist/audit/domain/mappings.js.map +0 -1
  156. package/dist/audit/domain/markdown-links.js.map +0 -1
  157. package/dist/audit/domain/tokenize.js.map +0 -1
  158. package/dist/audit/domain/tsdoc-syntax.js.map +0 -1
  159. package/dist/audit/domain/types.js.map +0 -1
  160. package/dist/audit/output.js.map +0 -1
  161. package/dist/audit/prepare.js.map +0 -1
  162. package/dist/audit/run-comments.js.map +0 -1
  163. package/dist/audit/run-links.js.map +0 -1
  164. package/dist/audit/run.js.map +0 -1
  165. package/dist/bin.js.map +0 -1
  166. package/dist/cli.js.map +0 -1
  167. package/dist/core/cli/format-error.js.map +0 -1
  168. package/dist/core/cli/global-options.js.map +0 -1
  169. package/dist/core/cli/positional.js.map +0 -1
  170. package/dist/core/cli/result-handle.js.map +0 -1
  171. package/dist/core/config/loader.js.map +0 -1
  172. package/dist/core/config/schema.js.map +0 -1
  173. package/dist/core/config/warnings.js.map +0 -1
  174. package/dist/core/config.js.map +0 -1
  175. package/dist/core/errors.js.map +0 -1
  176. package/dist/core/exit-codes.js.map +0 -1
  177. package/dist/core/filesystem/node.js.map +0 -1
  178. package/dist/core/filesystem/port.js.map +0 -1
  179. package/dist/core/glob.js.map +0 -1
  180. package/dist/core/logger.js.map +0 -1
  181. package/dist/core/result.js.map +0 -1
  182. package/dist/core/schema-parse.js.map +0 -1
  183. package/dist/core/source-text-edit.js.map +0 -1
  184. package/dist/core/verbose-diagnostics.js.map +0 -1
  185. package/dist/core/workspace/markdown-walk.js.map +0 -1
  186. package/dist/core/workspace/resolver.js.map +0 -1
  187. package/dist/core/workspace/skip-directories.js.map +0 -1
  188. package/dist/core/workspace/source-walk.js.map +0 -1
  189. package/dist/core/workspace/typescript-walk.js.map +0 -1
  190. package/dist/mirror/cli-result.js.map +0 -1
  191. package/dist/mirror/cli-schema.js.map +0 -1
  192. package/dist/mirror/command.js.map +0 -1
  193. package/dist/mirror/dist-filesystem-impl.js.map +0 -1
  194. package/dist/mirror/domain/constants.js.map +0 -1
  195. package/dist/mirror/domain/dirent-guard.js.map +0 -1
  196. package/dist/mirror/domain/dist-filesystem.js.map +0 -1
  197. package/dist/mirror/domain/errors.js.map +0 -1
  198. package/dist/mirror/domain/exports.js.map +0 -1
  199. package/dist/mirror/domain/package-display-name.js.map +0 -1
  200. package/dist/mirror/domain/path-normalizer.js.map +0 -1
  201. package/dist/mirror/domain/types.js.map +0 -1
  202. package/dist/mirror/output.js.map +0 -1
  203. package/dist/mirror/package-path.js.map +0 -1
  204. package/dist/mirror/prepare.js.map +0 -1
  205. package/dist/mirror/supplement-exports.js.map +0 -1
  206. package/dist/mirror/sync-reporter.js.map +0 -1
  207. package/dist/mirror/sync-types.js.map +0 -1
  208. package/dist/mirror/sync-workspace-package.js.map +0 -1
  209. package/dist/mirror/sync.js.map +0 -1
  210. package/dist/mirror/write-exports.js.map +0 -1
  211. package/dist/tag/cli-result.js.map +0 -1
  212. package/dist/tag/cli-schema.js.map +0 -1
  213. package/dist/tag/command.js.map +0 -1
  214. package/dist/tag/domain/types.js.map +0 -1
  215. package/dist/tag/output.js.map +0 -1
  216. package/dist/tag/prepare.js.map +0 -1
  217. package/dist/tag/resolve-target-path.js.map +0 -1
  218. package/dist/tag/since-writer.js.map +0 -1
  219. package/dist/tag/sync.js.map +0 -1
  220. package/dist/tag/target-candidates.js.map +0 -1
  221. package/dist/tag/target-runner.js.map +0 -1
  222. package/dist/tag/version-resolver.js.map +0 -1
package/README.md CHANGED
@@ -1,23 +1,36 @@
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), `mirror` export maps from `dist/`, 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`.
5
6
 
6
7
  [![npm version](https://img.shields.io/npm/v/@codefast/cli)](https://www.npmjs.com/package/@codefast/cli)
7
- [![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)
8
9
 
9
- This package exists to maintain the Codefast repository itself. It is published to npm and works in any pnpm workspace
10
- with a similar layout, but its flags and defaults follow Codefast's conventions — treat it as repo tooling, not a
11
- 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` strips the source lane from the publish artifact, and `tag` stamps
15
+ 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.
12
25
 
13
26
  ## Installation and usage
14
27
 
15
- 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:
16
29
 
17
30
  ```bash
18
- pnpm --filter @codefast/cli build # produce dist/bin.mjs first
31
+ pnpm --filter @codefast/cli build # produce dist/bin.js first
19
32
 
20
- pnpm run codefast <command> # generic entry: node ./packages/cli/dist/bin.mjs
33
+ pnpm run codefast <command> # generic entry: node ./packages/cli/dist/bin.js
21
34
 
22
35
  # Convenience wrappers
23
36
  pnpm run cli:arrange # codefast arrange
@@ -29,8 +42,12 @@ pnpm run cli:mirror # codefast mirror
29
42
  pnpm run cli:mirror:preview # codefast mirror --dry-run
30
43
  pnpm run cli:audit:rtl # codefast audit rtl
31
44
  pnpm run cli:audit:links # codefast audit links
45
+ pnpm run cli:audit:comments # codefast audit comments
46
+ pnpm run cli:audit:react # codefast audit react
32
47
  ```
33
48
 
49
+ `pnpm run version-packages` runs `changeset version` and then `codefast tag`, so published APIs are stamped at release.
50
+
34
51
  Standalone install (Node >= 24):
35
52
 
36
53
  ```bash
@@ -39,15 +56,18 @@ pnpm add -g @codefast/cli
39
56
  pnpm dlx @codefast/cli --help
40
57
  ```
41
58
 
42
- Every command writes by default; pass `--dry-run` to preview. The global `--no-color` flag must come before the command
43
- name (`codefast --no-color mirror`). Commands that accept `--json` print a single JSON object on stdout and suppress
44
- human progress output.
59
+ The package is published on 0.x and versioned on its own track: breaking changes ship as minor versions, so pin the
60
+ minor version when you need stability.
61
+
62
+ Every writing command writes by default; pass `--dry-run` to preview. The global `--no-color` flag must come before the
63
+ command name (`codefast --no-color mirror`). Commands that accept `--json` print a single JSON object on stdout and
64
+ suppress human progress output.
45
65
 
46
66
  ## `arrange`
47
67
 
48
- Rewrites Tailwind class strings inside `cn()` and `tv()` calls, regrouping utilities in render-pipeline order
49
- (existence, position, layout, sizing, spacing, shape, background, shadow, typography, composite, motion, behavior,
50
- state, selector) instead of alphabetically.
68
+ Rewrites Tailwind class strings inside `cn()` and `tv()` calls, regrouping utilities in render-pipeline order —
69
+ existence, position, layout, sizing, spacing, shape, background, shadow, typography, composite, motion, starting,
70
+ behavior, state, selector — instead of alphabetically.
51
71
 
52
72
  ```bash
53
73
  codefast arrange inspect packages/ui/src # read-only report
@@ -55,8 +75,9 @@ codefast arrange --dry-run packages/ui/src # preview the rewrite
55
75
  codefast arrange packages/ui/src # write
56
76
  ```
57
77
 
58
- When `[target]` is omitted, `arrange` uses the nearest package directory found by walking up from the current working
59
- directory. Directory scans skip test files (`*.test.*` / `*.spec.*`); pass such a file explicitly to process it.
78
+ When `[target]` is omitted, `arrange` uses the nearest directory with a `package.json` found by walking up from the
79
+ current working directory. Directory scans skip test files (`*.test.*` / `*.spec.*`), because a `cn()` inside an
80
+ assertion is intentional; pass such a file explicitly to process it.
60
81
 
61
82
  | Flag | Description |
62
83
  | -------------------- | ----------------------------------------------------------------------------- |
@@ -65,6 +86,8 @@ directory. Directory scans skip test files (`*.test.*` / `*.spec.*`); pass such
65
86
  | `--cn-import <spec>` | Override the module specifier used when a missing `cn` import is added. |
66
87
  | `--json` | Print one JSON object on stdout (suppresses human progress). |
67
88
 
89
+ Exits `1` when the `arrange.onAfterWrite` hook fails, `0` otherwise.
90
+
68
91
  ### `arrange inspect [target]`
69
92
 
70
93
  Read-only report of long strings, nested `cn` inside `tv()`, and related findings. Accepts `--json`.
@@ -91,9 +114,10 @@ codefast arrange group --tv "flex items-center gap-2"
91
114
 
92
115
  ## `mirror`
93
116
 
94
- Scans each workspace package's built `dist/` tree and writes its `package.json#exports` map (plus top-level `main`,
95
- `module`, `types`, and a `files` entry for `dist`). The workspace root is discovered via `pnpm-workspace.yaml`, so it
96
- runs from anywhere inside the repo. Build first — `mirror` reads `dist/`, and stale output produces stale exports.
117
+ Scans each workspace package's built `dist/` tree and writes its `package.json#exports` map, plus top-level `main`,
118
+ `module`, and `types` mirrored from the root export and a `files` entry for `dist`. The workspace root is the directory
119
+ holding `pnpm-workspace.yaml`, so it runs from anywhere inside the repo. Build first — `mirror` reads `dist/`, and stale
120
+ output produces stale exports.
97
121
 
98
122
  ```bash
99
123
  codefast mirror # all workspace packages
@@ -109,6 +133,34 @@ codefast mirror --dry-run # report changes without writing
109
133
 
110
134
  Exits `1` when any package fails, `0` otherwise.
111
135
 
136
+ ## `pack-slim`
137
+
138
+ Strips the source lane from published packages so the npm tarball ships `dist` runtime and types only. Where `mirror`
139
+ writes the full exports — including the `source` condition — for repo dev, `pack-slim` removes it for publish: it drops
140
+ `src` from `files`, every `source` condition from `exports`/`imports`, and the `dist` source maps plus their dangling
141
+ `sourceMappingURL` directives. Private packages are skipped, since `changeset publish` never publishes them. It is meant
142
+ to run on an ephemeral CI checkout right before publish (the release workflow runs it as its publish step), so it is
143
+ never committed.
144
+
145
+ Because its result must never be committed, `pack-slim` refuses to write when the git working tree has uncommitted
146
+ tracked changes — guarding against an accidental local run landing on real work. `--dry-run` is exempt (it writes
147
+ nothing) and `--force` overrides the guard. In CI the check is transparent: `dist` is gitignored, so the tree is clean
148
+ when the release workflow runs it.
149
+
150
+ ```bash
151
+ codefast pack-slim # every published package
152
+ codefast pack-slim packages/ui # one package (path relative to repo root)
153
+ codefast pack-slim --dry-run # report what would be stripped without touching a file
154
+ ```
155
+
156
+ | Flag | Description |
157
+ | ----------- | ----------------------------------------------------------------- |
158
+ | `--dry-run` | Report what would be stripped without touching any file. |
159
+ | `--force` | Run even if the git working tree has uncommitted tracked changes. |
160
+ | `--json` | Print one JSON summary on stdout (suppresses human progress). |
161
+
162
+ Exits `1` when any package fails, `0` otherwise.
163
+
112
164
  ## `audit rtl`
113
165
 
114
166
  Read-only scan for physical-direction Tailwind classes (e.g. `ml-*`, `left-*`, `text-left`) that should use logical
@@ -125,16 +177,17 @@ codefast audit rtl --json # machine-readable summary
125
177
  | -------- | --------------------------------- |
126
178
  | `--json` | Print one JSON summary on stdout. |
127
179
 
128
- Configure intentional exceptions via `audit.rtl.allowlist` in `codefast.config` — each entry is a bare class token or
180
+ With no `[target]`, the scan root is `audit.rtl.target` from the config; when neither is set the command fails.
181
+ Configure intentional exceptions via `audit.rtl.allowlist` — each entry is a bare class token or
129
182
  `repo/relative/path.tsx:token`.
130
183
 
131
184
  ## `audit links`
132
185
 
133
186
  Read-only scan for markdown cross-references that point at nothing: a relative path that does not exist, an in-document
134
187
  anchor with no matching heading or `<a id>`, and an anchor into another document that the target does not offer. That
135
- last one is the reason this exists — it fails silently in a browser by scrolling to the top, so nothing else notices.
136
- External URLs are somebody else's to check and are skipped, as are links inside fenced code, which are examples rather
137
- than references. Exits non-zero when breakages remain so it can gate CI.
188
+ last one is the reason this exists — a browser fails it silently by scrolling to the top. External URLs are not checked,
189
+ and links inside fenced code are treated as examples rather than references. Exits non-zero when breakages remain so it
190
+ can gate CI.
138
191
 
139
192
  ```bash
140
193
  codefast audit links # whole repo
@@ -146,14 +199,57 @@ codefast audit links --json # machine-readable summary
146
199
  | -------- | --------------------------------- |
147
200
  | `--json` | Print one JSON summary on stdout. |
148
201
 
149
- Configure intentional exceptions via `audit.links.allowlist` in `codefast.config` — each entry is a bare link target or
202
+ Configure intentional exceptions via `audit.links.allowlist` — each entry is a bare link target or
150
203
  `repo/relative/doc.md:target`.
151
204
 
205
+ ## `audit comments`
206
+
207
+ Scans source comments for the repo's comment conventions. Section dividers that are not in the one allowed form are
208
+ mechanical, so `--fix` rewrites them in place. The rest is reported for a person to fix: TSDoc grammar errors, JSDoc
209
+ `{type}` payloads, comments pointing at repo documents, `@param` lists that name some parameters but not all, `@param`
210
+ descriptions without the `-` separator, `@since` tags out of position or naming a version the package has not reached,
211
+ and comment links to missing paths. Exits non-zero when unfixed findings remain so it can gate CI.
212
+
213
+ ```bash
214
+ codefast audit comments # whole repo
215
+ codefast audit comments packages/di/src # explicit target
216
+ codefast audit comments --fix # rewrite fixable dividers in place
217
+ codefast audit comments --json # machine-readable summary
218
+ ```
219
+
220
+ | Flag | Description |
221
+ | -------- | ---------------------------------------------------- |
222
+ | `--fix` | Rewrite every mechanically fixable divider in place. |
223
+ | `--json` | Print one JSON summary on stdout. |
224
+
225
+ Configure intentional exceptions via `audit.comments.allowlist` — each entry is a divider line as written or
226
+ `repo/relative/path.ts:<divider>`.
227
+
228
+ ## `audit react`
229
+
230
+ Read-only scan enforcing the repo's React import policy: members are imported by name. Flags `import * as React` and
231
+ default `React` imports (type-only included), plus an implicit `React.*` UMD-global type reference (`e: React.FormEvent`
232
+ with no import), which `tsc` accepts silently through the `export as namespace React` declaration in `@types/react`.
233
+ Exits non-zero when violations remain so it can gate CI.
234
+
235
+ ```bash
236
+ codefast audit react # whole repo
237
+ codefast audit react apps/ui/src # explicit target
238
+ codefast audit react --json # machine-readable summary
239
+ ```
240
+
241
+ | Flag | Description |
242
+ | -------- | --------------------------------- |
243
+ | `--json` | Print one JSON summary on stdout. |
244
+
245
+ Configure intentional exceptions via `audit.react.allowlist` — each entry is the offending source text as written or
246
+ `repo/relative/path.tsx:<text>`.
247
+
152
248
  ## `tag`
153
249
 
154
- Adds `@since <version>` tags to doc comments of exported declarations that lack one, creating the doc block when
155
- missing. The version comes from the nearest `package.json` walking up from each target file. Declarations that already
156
- carry `@since` are left alone.
250
+ Adds `@since <version>` tags to the doc comments of exported declarations that lack one, creating the doc block when
251
+ there is none. The version comes from the nearest `package.json` above each target file. Declarations that already carry
252
+ `@since` are left alone.
157
253
 
158
254
  ```bash
159
255
  codefast tag # auto-discover workspace packages from cwd
@@ -166,15 +262,17 @@ codefast tag --dry-run # summary only, no writes
166
262
  | `--dry-run` | Show summary without writing files. |
167
263
  | `--json` | Print one JSON summary on stdout (suppresses human progress). |
168
264
 
169
- In this repo, `tag` runs as part of the release workflow so published APIs carry accurate version metadata — never
170
- hand-write `@since` tags.
265
+ Exits `1` when no target is selected, when any target fails, or when the `tag.onAfterWrite` hook fails. In this repo,
266
+ `tag` runs inside `pnpm run version-packages` so published APIs carry accurate version metadata — never hand-write
267
+ `@since` tags.
171
268
 
172
269
  ## Configuration
173
270
 
174
271
  An optional `codefast.config.*` file adjusts `mirror`, `tag`, `arrange`, and `audit`. The CLI walks up from the working
175
272
  directory and uses the first match, checking `codefast.config.mjs`, `codefast.config.js`, `codefast.config.cjs`, then
176
273
  `codefast.config.json` in each directory. JS configs are loaded via [jiti](https://github.com/unjs/jiti), so only run
177
- the CLI in repositories you trust; JSON configs cannot define hooks.
274
+ the CLI in repositories you trust; JSON configs cannot define hooks. The schema is strict: an unknown key is a
275
+ configuration error.
178
276
 
179
277
  ```js
180
278
  // codefast.config.js
@@ -185,8 +283,9 @@ export default {
185
283
  mirror: {
186
284
  "@acme/ui": {
187
285
  strip: "./components/", // flatten a dist/ prefix out of public specifiers
286
+ exclude: ["./internal/*"], // specifiers to leave out of the generated map
188
287
  exports: { "./css/*": "./src/css/*" }, // extra or overriding entries
189
- source: true, // add a `source` condition (string overrides the root path)
288
+ source: true, // add a `source` condition (a string overrides the root path)
190
289
  types: true, // add `types` when a .d.ts exists
191
290
  import: true, // add the `import` condition
192
291
  css: true, // boolean or { enabled, forceExportFiles, customExports }
@@ -195,7 +294,7 @@ export default {
195
294
  "@acme/internal": false,
196
295
  },
197
296
  tag: {
198
- skipPackages: ["@acme/internal"],
297
+ skipPackages: ["@acme/internal", "@apps/*"], // glob patterns matched against package names
199
298
  onAfterWrite: ({ files }) => execSync(`oxfmt ${files.join(" ")}`, { stdio: "inherit" }),
200
299
  },
201
300
  arrange: {
@@ -209,12 +308,15 @@ export default {
209
308
  "packages/ui/src/variants/sheet.ts:data-open:slide-in-from-left-10",
210
309
  ],
211
310
  },
311
+ links: { allowlist: [] }, // bare link target, or `repo/relative/doc.md:target`
312
+ comments: { allowlist: [] }, // divider as written, or `repo/relative/path.ts:<divider>`
313
+ react: { allowlist: [] }, // offending text as written, or `repo/relative/path.tsx:<text>`
212
314
  },
213
315
  };
214
316
  ```
215
317
 
216
- The `onAfterWrite` hooks (sync or async) run only when files were actually written — never on `--dry-run`. A hook
217
- failure is reported on stderr and the command exits `1`.
318
+ `source`, `types`, and `import` default to `true`. The `onAfterWrite` hooks (sync or async) run only when files were
319
+ actually written — never on `--dry-run`. A hook failure is reported on stderr and the command exits `1`.
218
320
 
219
321
  ## Exit codes
220
322
 
@@ -222,8 +324,21 @@ failure is reported on stderr and the command exits `1`.
222
324
  | ---- | --------------------------------------------------------------- |
223
325
  | `0` | Success. |
224
326
  | `1` | General failure (missing paths, failed packages, failed hooks). |
225
- | `2` | Invalid invocation or input. |
327
+ | `2` | Invalid arguments or configuration. |
328
+
329
+ ## Documentation
330
+
331
+ - [codefastlabs.com/docs/cli](https://codefastlabs.com/docs/cli) — this document, rendered.
332
+ - [`ARCHITECTURE.md`](./ARCHITECTURE.md) — how the package is laid out: command wiring, the `Result` type, and the
333
+ filesystem port.
334
+ - [`DECISIONS.md`](./DECISIONS.md) — the design decisions that shape the package and the reasons behind them.
335
+ - [`CHANGELOG.md`](./CHANGELOG.md) — release notes for every published version.
336
+
337
+ ## Contributing
338
+
339
+ The package is developed in the [codefast monorepo](https://github.com/codefastlabs/codefast); the repo-wide
340
+ [contributing guide](../../CONTRIBUTING.md) covers setup, the test taxonomy, and the release flow.
226
341
 
227
342
  ## License
228
343
 
229
- [MIT](https://github.com/codefastlabs/codefast/blob/main/LICENSE)
344
+ Released under the [MIT License](./LICENSE).
@@ -5,6 +5,8 @@ import { AppError } from "#/core/errors";
5
5
  import { messageFrom } from "#/core/errors";
6
6
  import { err, ok } from "#/core/result";
7
7
  /**
8
+ * Scans a directory's arrange targets and returns the accumulated analyze report.
9
+ *
8
10
  * @since 0.3.16-canary.0
9
11
  */
10
12
  export function analyzeDirectory(fs, analyzeRootPath) {
@@ -21,5 +23,4 @@ export function analyzeDirectory(fs, analyzeRootPath) {
21
23
  catch (caughtError) {
22
24
  return err(new AppError("INFRA_FAILURE", messageFrom(caughtError), caughtError));
23
25
  }
24
- }
25
- //# sourceMappingURL=analyze.js.map
26
+ }
@@ -1,11 +1,15 @@
1
1
  import { z } from "zod";
2
2
  /**
3
+ * The `zod` schema validating an `arrange analyze` request.
4
+ *
3
5
  * @since 0.3.16-canary.0
4
6
  */
5
7
  export const arrangeAnalyzeDirectoryRequestSchema = z.object({
6
8
  analyzeRootPath: z.string().min(1, "analyzeRootPath is required"),
7
9
  });
8
10
  /**
11
+ * The `zod` schema validating an `arrange` run request.
12
+ *
9
13
  * @since 0.3.16-canary.0
10
14
  */
11
15
  export const arrangeSyncRunRequestSchema = z.object({
@@ -17,6 +21,8 @@ export const arrangeSyncRunRequestSchema = z.object({
17
21
  config: z.unknown().optional(),
18
22
  });
19
23
  /**
24
+ * The `zod` schema validating an `arrange group` request.
25
+ *
20
26
  * @since 0.3.16-canary.0
21
27
  */
22
28
  export const arrangeSuggestGroupsRequestSchema = z.object({
@@ -25,5 +31,4 @@ export const arrangeSuggestGroupsRequestSchema = z.object({
25
31
  .min(1, 'Pass a class string. Example: codefast arrange group "flex gap-2 text-sm rounded-md"'),
26
32
  emitTvStyleArray: z.boolean(),
27
33
  trailingClassName: z.boolean(),
28
- });
29
- //# sourceMappingURL=cli-schema.js.map
34
+ });
@@ -14,6 +14,8 @@ import { nodeFilesystem } from "#/core/filesystem/node";
14
14
  import { logger } from "#/core/logger";
15
15
  import { parseWithSchema } from "#/core/schema-parse";
16
16
  /**
17
+ * Creates the `arrange` command and its subcommands.
18
+ *
17
19
  * @since 0.3.16-canary.0
18
20
  */
19
21
  export function createArrangeCommand() {
@@ -166,5 +168,4 @@ function formatArrangeGroupJsonOutput(output) {
166
168
  }
167
169
  function exitCodeForArrangeSyncResult(result) {
168
170
  return result.hookError !== null ? CLI_EXIT_GENERAL_ERROR : CLI_EXIT_SUCCESS;
169
- }
170
- //# sourceMappingURL=command.js.map
171
+ }
@@ -14,6 +14,8 @@ function previewText(text) {
14
14
  return text.length > PREVIEW_MAX_LENGTH ? `${text.slice(0, PREVIEW_MAX_LENGTH)}…` : text;
15
15
  }
16
16
  /**
17
+ * Creates a zeroed analyze report ready for accumulation.
18
+ *
17
19
  * @since 0.3.16-canary.0
18
20
  */
19
21
  export function createEmptyAnalyzeReport() {
@@ -118,5 +120,4 @@ export function accumulateAnalyzeReportForSourceFile(report, domainSf, sourceTex
118
120
  for (const stmt of domainSf.statements) {
119
121
  visitTypeScriptSubtree(stmt);
120
122
  }
121
- }
122
- //# sourceMappingURL=analyze-service.js.map
123
+ }
@@ -32,6 +32,8 @@ export var DomainSyntaxKind;
32
32
  DomainSyntaxKind[DomainSyntaxKind["JsxExpression"] = 24] = "JsxExpression";
33
33
  })(DomainSyntaxKind || (DomainSyntaxKind = {}));
34
34
  /**
35
+ * The binary operators the domain AST distinguishes.
36
+ *
35
37
  * @since 0.3.16-canary.0
36
38
  */
37
39
  export var DomainBinaryOperator;
@@ -40,12 +42,16 @@ export var DomainBinaryOperator;
40
42
  DomainBinaryOperator[DomainBinaryOperator["Other"] = 1] = "Other";
41
43
  })(DomainBinaryOperator || (DomainBinaryOperator = {}));
42
44
  /**
45
+ * Narrows a node to `DomainIdentifier`.
46
+ *
43
47
  * @since 0.3.16-canary.0
44
48
  */
45
49
  export function isDomainIdentifier(node) {
46
50
  return node.kind === DomainSyntaxKind.Identifier;
47
51
  }
48
52
  /**
53
+ * Narrows a node to `DomainStringLiteral`.
54
+ *
49
55
  * @since 0.3.16-canary.0
50
56
  */
51
57
  export function isDomainStringLiteral(node) {
@@ -55,78 +61,104 @@ function isDomainNoSubstitutionTemplateLiteral(node) {
55
61
  return node.kind === DomainSyntaxKind.NoSubstitutionTemplateLiteral;
56
62
  }
57
63
  /**
64
+ * Narrows a node to a literal that can carry Tailwind classes.
65
+ *
58
66
  * @since 0.3.16-canary.0
59
67
  */
60
68
  export function isDomainTailwindClassLiteral(node) {
61
69
  return isDomainStringLiteral(node) || isDomainNoSubstitutionTemplateLiteral(node);
62
70
  }
63
71
  /**
72
+ * Narrows a node to `DomainImportDeclaration`.
73
+ *
64
74
  * @since 0.3.16-canary.0
65
75
  */
66
76
  export function isDomainImportDeclaration(node) {
67
77
  return node.kind === DomainSyntaxKind.ImportDeclaration;
68
78
  }
69
79
  /**
80
+ * Narrows a node to `DomainNamedImports`.
81
+ *
70
82
  * @since 0.3.16-canary.0
71
83
  */
72
84
  export function isDomainNamedImports(node) {
73
85
  return node.kind === DomainSyntaxKind.NamedImports;
74
86
  }
75
87
  /**
88
+ * Narrows a node to `DomainNamespaceImport`.
89
+ *
76
90
  * @since 0.3.16-canary.0
77
91
  */
78
92
  export function isDomainNamespaceImport(node) {
79
93
  return node.kind === DomainSyntaxKind.NamespaceImport;
80
94
  }
81
95
  /**
96
+ * Narrows a node to `DomainCallExpression`.
97
+ *
82
98
  * @since 0.3.16-canary.0
83
99
  */
84
100
  export function isDomainCallExpression(node) {
85
101
  return node.kind === DomainSyntaxKind.CallExpression;
86
102
  }
87
103
  /**
104
+ * Narrows a node to `DomainObjectLiteralExpression`.
105
+ *
88
106
  * @since 0.3.16-canary.0
89
107
  */
90
108
  export function isDomainObjectLiteralExpression(node) {
91
109
  return node.kind === DomainSyntaxKind.ObjectLiteralExpression;
92
110
  }
93
111
  /**
112
+ * Narrows a node to `DomainPropertyAssignment`.
113
+ *
94
114
  * @since 0.3.16-canary.0
95
115
  */
96
116
  export function isDomainPropertyAssignment(node) {
97
117
  return node.kind === DomainSyntaxKind.PropertyAssignment;
98
118
  }
99
119
  /**
120
+ * Narrows a node to `DomainArrayLiteralExpression`.
121
+ *
100
122
  * @since 0.3.16-canary.0
101
123
  */
102
124
  export function isDomainArrayLiteralExpression(node) {
103
125
  return node.kind === DomainSyntaxKind.ArrayLiteralExpression;
104
126
  }
105
127
  /**
128
+ * Narrows a node to `DomainSpreadElement`.
129
+ *
106
130
  * @since 0.3.16-canary.0
107
131
  */
108
132
  export function isDomainSpreadElement(node) {
109
133
  return node.kind === DomainSyntaxKind.SpreadElement;
110
134
  }
111
135
  /**
136
+ * Narrows a node to `DomainPropertyAccessExpression`.
137
+ *
112
138
  * @since 0.3.16-canary.0
113
139
  */
114
140
  export function isDomainPropertyAccessExpression(node) {
115
141
  return node.kind === DomainSyntaxKind.PropertyAccessExpression;
116
142
  }
117
143
  /**
144
+ * Narrows a node to `DomainJsxAttribute`.
145
+ *
118
146
  * @since 0.3.16-canary.0
119
147
  */
120
148
  export function isDomainJsxAttribute(node) {
121
149
  return node.kind === DomainSyntaxKind.JsxAttribute;
122
150
  }
123
151
  /**
152
+ * Narrows a node to `DomainJsxExpression`.
153
+ *
124
154
  * @since 0.3.16-canary.0
125
155
  */
126
156
  export function isDomainJsxExpression(node) {
127
157
  return node.kind === DomainSyntaxKind.JsxExpression;
128
158
  }
129
159
  /**
160
+ * Visits each direct child of a domain node.
161
+ *
130
162
  * @since 0.3.16-canary.0
131
163
  */
132
164
  export function forEachDomainChild(node, visit) {
@@ -225,6 +257,8 @@ export function forEachDomainChild(node, visit) {
225
257
  }
226
258
  }
227
259
  /**
260
+ * Resolves the one-based line number of a position in source text.
261
+ *
228
262
  * @since 0.3.16-canary.0
229
263
  */
230
264
  export function lineOfSourcePosition(sourceText, pos) {
@@ -236,5 +270,4 @@ export function lineOfSourcePosition(sourceText, pos) {
236
270
  }
237
271
  }
238
272
  return line;
239
- }
240
- //# sourceMappingURL=ast-node.js.map
273
+ }
@@ -1,6 +1,8 @@
1
1
  import { DomainBinaryOperator, DomainSyntaxKind, isDomainArrayLiteralExpression, isDomainTailwindClassLiteral, } from "#/arrange/domain/ast/ast-node";
2
2
  import { MAX_CLASS_EXPR_DEPTH } from "#/arrange/domain/constants";
3
3
  /**
4
+ * Visits every static class literal reachable inside a class expression.
5
+ *
4
6
  * @since 0.3.16-canary.0
5
7
  */
6
8
  export function forEachStringLiteralInClassExpression(expr, sink, depth = 0, options) {
@@ -46,18 +48,24 @@ export function forEachStringLiteralInClassExpression(expr, sink, depth = 0, opt
46
48
  }
47
49
  }
48
50
  /**
51
+ * Checks whether a literal sits directly inside an array literal, where splitting it apart is unsafe.
52
+ *
49
53
  * @since 0.3.16-canary.0
50
54
  */
51
55
  export function isUnsafeLiteralForCnStyleApplySplit(classLiteral) {
52
56
  return classLiteral.parent !== null && isDomainArrayLiteralExpression(classLiteral.parent);
53
57
  }
54
58
  /**
59
+ * The walk options for building the `cn` apply pool — conditional branches are never descended into.
60
+ *
55
61
  * @since 0.3.16-canary.0
56
62
  */
57
63
  export const CN_APPLY_LITERAL_WALK_OPTS = {
58
64
  descendIntoConditional: false,
59
65
  };
60
66
  /**
67
+ * Collects the static class literals in `cn()` arguments that are safe to regroup.
68
+ *
61
69
  * @since 0.3.16-canary.0
62
70
  */
63
71
  export function collectUnconditionalTailwindLiteralsFromCnArguments(args) {
@@ -77,5 +85,4 @@ export function collectUnconditionalTailwindLiteralsFromCnArguments(args) {
77
85
  }
78
86
  }
79
87
  return staticLits;
80
- }
81
- //# sourceMappingURL=collectors-cn.js.map
88
+ }
@@ -1,5 +1,7 @@
1
1
  import { isDomainIdentifier, isDomainJsxExpression, isDomainTailwindClassLiteral } from "#/arrange/domain/ast/ast-node";
2
2
  /**
3
+ * Extracts the static literal of a JSX `className` attribute, or `undefined` when it is not static.
4
+ *
3
5
  * @since 0.3.16-canary.0
4
6
  */
5
7
  export function jsxClassNameStaticLiteral(jsxClassNameAttribute) {
@@ -20,5 +22,4 @@ export function jsxClassNameStaticLiteral(jsxClassNameAttribute) {
20
22
  }
21
23
  }
22
24
  return undefined;
23
- }
24
- //# sourceMappingURL=collectors-jsx.js.map
25
+ }
@@ -4,6 +4,8 @@ import { buildKnownCnTvBindings, isCnOrTvIdentifier, propertyAssignmentNameText
4
4
  import { APPLY_MIN_TOKENS, MAX_OBJECT_DEPTH } from "#/arrange/domain/constants";
5
5
  import { tokenizeClassString } from "#/arrange/domain/tailwind-token";
6
6
  /**
7
+ * Visits every class literal reachable inside a `tv({ ... })` object, including `cn()` arguments.
8
+ *
7
9
  * @since 0.3.16-canary.0
8
10
  */
9
11
  export function traverseTvObject(sourceFile, obj, visitor, depth = 0, knownBindings) {
@@ -82,6 +84,8 @@ export function traverseTvObject(sourceFile, obj, visitor, depth = 0, knownBindi
82
84
  }
83
85
  }
84
86
  /**
87
+ * Collects the `cn()` calls nested inside a `tv({ ... })` object.
88
+ *
85
89
  * @since 0.3.16-canary.0
86
90
  */
87
91
  export function collectCnCallsInsideTv(sourceFile, obj, knownBindings, depth = 0) {
@@ -129,6 +133,8 @@ export function collectCnCallsInsideTv(sourceFile, obj, knownBindings, depth = 0
129
133
  return calls;
130
134
  }
131
135
  /**
136
+ * Collects every `cn()` call nested inside any `tv()` call in a source file.
137
+ *
132
138
  * @since 0.3.16-canary.0
133
139
  */
134
140
  export function listAllCnCallsInsideTvInSourceFile(sourceFile, knownBindings) {
@@ -163,6 +169,8 @@ function makeStringNode(nodes, sourceFile, isTvContext, cnCall) {
163
169
  };
164
170
  }
165
171
  /**
172
+ * Joins a slot's literals into one space-separated class string.
173
+ *
166
174
  * @since 0.3.16-canary.0
167
175
  */
168
176
  export function slotClassString(stringNode) {
@@ -281,6 +289,8 @@ function collectTvSlots(sourceFile, obj, knownBindings, results, seenNodePos, de
281
289
  }
282
290
  }
283
291
  /**
292
+ * Collects every groupable `cn()` / `tv()` string slot in a source file.
293
+ *
284
294
  * @since 0.3.16-canary.0
285
295
  */
286
296
  export function collectGroupableStringNodes(sourceFile) {
@@ -315,5 +325,4 @@ export function collectGroupableStringNodes(sourceFile) {
315
325
  visitTypeScriptSubtree(stmt);
316
326
  }
317
327
  return results;
318
- }
319
- //# sourceMappingURL=collectors-tv.js.map
328
+ }