@codefast/cli 0.9.0 → 0.10.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.
- package/CHANGELOG.md +28 -0
- package/README.md +329 -149
- package/dist/arrange/analyze.d.ts +10 -0
- package/dist/arrange/cli-schema.d.ts +50 -0
- package/dist/arrange/command.d.ts +7 -0
- package/dist/arrange/domain/analyze-service.d.ts +18 -0
- package/dist/arrange/domain/ast/ast-node.d.ts +394 -0
- package/dist/arrange/domain/ast/collectors-cn.d.ts +26 -0
- package/dist/arrange/domain/ast/collectors-jsx.d.ts +8 -0
- package/dist/arrange/domain/ast/collectors-tv.d.ts +34 -0
- package/dist/arrange/domain/ast/helpers.d.ts +36 -0
- package/dist/arrange/domain/ast/helpers.js +1 -0
- package/dist/arrange/domain/ast/simplify-targets.d.ts +22 -0
- package/dist/arrange/domain/ast/targets.d.ts +20 -0
- package/dist/arrange/domain/constants.d.ts +111 -0
- package/dist/arrange/domain/grouping-service.d.ts +100 -0
- package/dist/arrange/domain/grouping.d.ts +21 -0
- package/dist/arrange/domain/imports.d.ts +14 -0
- package/dist/arrange/domain/source-text-formatters.d.ts +33 -0
- package/dist/arrange/domain/tailwind-token.d.ts +24 -0
- package/dist/arrange/domain/token-classifier.d.ts +47 -0
- package/dist/arrange/domain/types.d.ts +208 -0
- package/dist/arrange/output.d.ts +26 -0
- package/dist/arrange/process-file.d.ts +11 -0
- package/dist/arrange/resolve-target.d.ts +10 -0
- package/dist/arrange/resolve-target.js +3 -16
- package/dist/arrange/scan-target.d.ts +7 -0
- package/dist/arrange/simplify-process-file.d.ts +11 -0
- package/dist/arrange/simplify-sync.d.ts +13 -0
- package/dist/arrange/source-parse.d.ts +7 -0
- package/dist/arrange/suggest.d.ts +8 -0
- package/dist/arrange/sync.d.ts +11 -0
- package/dist/arrange/typescript-ast-translator.d.ts +31 -0
- package/dist/arrange/workspace.d.ts +13 -0
- package/dist/arrange/workspace.js +2 -2
- package/dist/audit/cli-schema.d.ts +93 -0
- package/dist/audit/cli-schema.js +3 -3
- package/dist/audit/command.d.ts +8 -0
- package/dist/audit/command.js +12 -12
- package/dist/audit/domain/audit-file.d.ts +7 -0
- package/dist/audit/domain/comment-content.d.ts +26 -0
- package/dist/audit/domain/comment-dividers.d.ts +62 -0
- package/dist/audit/domain/display-names.d.ts +11 -0
- package/dist/audit/domain/import-policy.d.ts +34 -0
- package/dist/audit/domain/import-policy.js +147 -0
- package/dist/audit/domain/link-references.d.ts +40 -0
- package/dist/audit/domain/mappings.d.ts +45 -0
- package/dist/audit/domain/markdown-links.d.ts +44 -0
- package/dist/audit/domain/since-versions.d.ts +26 -0
- package/dist/audit/domain/tokenize.d.ts +14 -0
- package/dist/audit/domain/tsdoc-syntax.d.ts +20 -0
- package/dist/audit/domain/types.d.ts +171 -0
- package/dist/audit/output.d.ts +91 -0
- package/dist/audit/output.js +11 -11
- package/dist/audit/prepare.d.ts +70 -0
- package/dist/audit/prepare.js +11 -11
- package/dist/audit/run-comments.d.ts +17 -0
- package/dist/audit/run-display-names.d.ts +14 -0
- package/dist/audit/run-imports.d.ts +14 -0
- package/dist/audit/{run-react.js → run-imports.js} +15 -5
- package/dist/audit/run-links.d.ts +14 -0
- package/dist/audit/run.d.ts +14 -0
- package/dist/bin.d.ts +2 -0
- package/dist/cli.d.ts +6 -0
- package/dist/core/cli/format-error.d.ts +7 -0
- package/dist/core/cli/global-options.d.ts +15 -0
- package/dist/core/cli/positional.d.ts +6 -0
- package/dist/core/cli/result-handle.d.ts +19 -0
- package/dist/core/config/define-config.d.ts +7 -0
- package/dist/core/config/define-config.js +8 -0
- package/dist/core/config/loader.d.ts +18 -0
- package/dist/core/config/loader.js +2 -7
- package/dist/core/config/schema.d.ts +99 -0
- package/dist/core/config/schema.js +7 -85
- package/dist/core/config/warnings.d.ts +6 -0
- package/dist/core/config.d.ts +12 -0
- package/dist/core/errors.d.ts +25 -0
- package/dist/core/exit-codes.d.ts +18 -0
- package/dist/core/filesystem/node.d.ts +7 -0
- package/dist/core/filesystem/node.js +1 -0
- package/dist/core/filesystem/port.d.ts +44 -0
- package/dist/core/glob.d.ts +19 -0
- package/dist/core/logger.d.ts +9 -0
- package/dist/core/result.d.ts +30 -0
- package/dist/core/schema-parse.d.ts +9 -0
- package/dist/core/source-text-edit.d.ts +33 -0
- package/dist/core/verbose-diagnostics.d.ts +6 -0
- package/dist/core/workspace/ancestor-directories.d.ts +12 -0
- package/dist/core/workspace/ancestor-directories.js +30 -0
- package/dist/core/workspace/markdown-walk.d.ts +7 -0
- package/dist/core/workspace/markdown-walk.js +2 -20
- package/dist/core/workspace/package-version.d.ts +9 -0
- package/dist/core/workspace/package-version.js +8 -12
- package/dist/core/workspace/resolver.d.ts +39 -0
- package/dist/core/workspace/resolver.js +58 -75
- package/dist/core/workspace/skip-directories.d.ts +6 -0
- package/dist/core/workspace/source-walk.d.ts +16 -0
- package/dist/core/workspace/source-walk.js +2 -19
- package/dist/core/workspace/typescript-walk.d.ts +7 -0
- package/dist/core/workspace/typescript-walk.js +2 -23
- package/dist/core/workspace/walk-files.d.ts +7 -0
- package/dist/core/workspace/walk-files.js +27 -0
- package/dist/core/workspace/well-known-files.d.ts +18 -0
- package/dist/core/workspace/well-known-files.js +18 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +5 -0
- package/dist/mirror/cli-result.d.ts +13 -0
- package/dist/mirror/cli-schema.d.ts +8 -0
- package/dist/mirror/command.d.ts +7 -0
- package/dist/mirror/dist-filesystem-impl.d.ts +8 -0
- package/dist/mirror/domain/constants.d.ts +18 -0
- package/dist/mirror/domain/constants.js +0 -12
- package/dist/mirror/domain/dirent-guard.d.ts +10 -0
- package/dist/mirror/domain/dist-filesystem.d.ts +9 -0
- package/dist/mirror/domain/errors.d.ts +24 -0
- package/dist/mirror/domain/exports.d.ts +36 -0
- package/dist/mirror/domain/package-display-name.d.ts +8 -0
- package/dist/mirror/domain/path-normalizer.d.ts +6 -0
- package/dist/mirror/domain/types.d.ts +131 -0
- package/dist/mirror/output.d.ts +23 -0
- package/dist/mirror/package-path.d.ts +19 -0
- package/dist/mirror/prepare.d.ts +15 -0
- package/dist/mirror/prepare.js +2 -2
- package/dist/mirror/supplement-exports.d.ts +27 -0
- package/dist/mirror/supplement-exports.js +2 -2
- package/dist/mirror/sync-reporter.d.ts +60 -0
- package/dist/mirror/sync-reporter.js +4 -0
- package/dist/mirror/sync-types.d.ts +43 -0
- package/dist/mirror/sync-workspace-package.d.ts +9 -0
- package/dist/mirror/sync-workspace-package.js +3 -3
- package/dist/mirror/sync.d.ts +12 -0
- package/dist/mirror/sync.js +5 -3
- package/dist/mirror/write-exports.d.ts +15 -0
- package/dist/pack-slim/cli-result.d.ts +13 -0
- package/dist/pack-slim/cli-schema.d.ts +17 -0
- package/dist/pack-slim/command.d.ts +7 -0
- package/dist/pack-slim/command.js +2 -2
- package/dist/pack-slim/domain/transform.d.ts +69 -0
- package/dist/pack-slim/domain/types.d.ts +46 -0
- package/dist/pack-slim/output.d.ts +15 -0
- package/dist/pack-slim/sync.d.ts +23 -0
- package/dist/pack-slim/sync.js +4 -4
- package/dist/pack-slim/working-tree.d.ts +20 -0
- package/dist/tag/cli-result.d.ts +7 -0
- package/dist/tag/cli-schema.d.ts +8 -0
- package/dist/tag/command.d.ts +7 -0
- package/dist/tag/domain/types.d.ts +111 -0
- package/dist/tag/output.d.ts +17 -0
- package/dist/tag/prepare.d.ts +13 -0
- package/dist/tag/prepare.js +2 -2
- package/dist/tag/resolve-target-path.d.ts +10 -0
- package/dist/tag/since-writer.d.ts +32 -0
- package/dist/tag/sync.d.ts +42 -0
- package/dist/tag/target-candidates.d.ts +8 -0
- package/dist/tag/target-candidates.js +1 -1
- package/dist/tag/target-runner.d.ts +8 -0
- package/dist/tag/version-resolver.d.ts +7 -0
- package/package.json +12 -1
- package/dist/audit/domain/react-imports.js +0 -91
package/README.md
CHANGED
|
@@ -1,74 +1,109 @@
|
|
|
1
1
|
# @codefast/cli
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
`codefast` is a small, dependency-light CLI toolkit for TypeScript projects — a **pnpm workspace** or a **single
|
|
4
|
+
package**. It reorders Tailwind classes, generates `package.json#exports` from a package's built `dist/`, slims the npm
|
|
5
|
+
tarball at publish time, stamps `@since` on your public API, and audits a handful of source and documentation
|
|
6
|
+
conventions.
|
|
7
|
+
|
|
8
|
+
It was built for — and is exercised daily by — the [codefast monorepo](https://github.com/codefastlabs/codefast), but
|
|
9
|
+
nothing here is codefast-only: run it in any pnpm workspace, or in a standalone package, and it works. A few audits
|
|
10
|
+
encode an opinionated house style (called out below) that you can adopt, ignore, or narrow with an allowlist.
|
|
6
11
|
|
|
7
12
|
[](https://www.npmjs.com/package/@codefast/cli)
|
|
8
13
|
[](./LICENSE)
|
|
9
14
|
|
|
10
|
-
##
|
|
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`.
|
|
15
|
+
## Design principles
|
|
16
16
|
|
|
17
|
-
|
|
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
|
|
17
|
+
- **Safe by default.** Every writing command supports `--dry-run`, and every audit is read-only except
|
|
21
18
|
`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
|
|
19
|
+
- **Scriptable.** `--json` prints one JSON object on stdout and suppresses the human progress output.
|
|
20
|
+
- **CI-ready.** Audits exit non-zero when findings remain, so they gate a pipeline with no extra glue.
|
|
24
21
|
- **Configurable.** An optional `codefast.config.*` file, validated by a strict schema, adjusts every command.
|
|
25
22
|
|
|
26
|
-
##
|
|
23
|
+
## Requirements
|
|
24
|
+
|
|
25
|
+
- **Node.js ≥ 24** (the CLI is published as ESM).
|
|
26
|
+
- **A project root — workspace or single package.** Commands resolve their root by walking up from the current
|
|
27
|
+
directory: the nearest `pnpm-workspace.yaml` marks a **workspace** (every package under it is in scope), and with no
|
|
28
|
+
workspace file the nearest `package.json` marks a **single package** (that one package is the whole scope). Only
|
|
29
|
+
`arrange group` needs no project at all — it just formats a string you paste in.
|
|
30
|
+
- **pnpm is not required to _run_ the CLI** — npm, npx, or a plain `node` invocation are all fine. pnpm matters only for
|
|
31
|
+
workspace-wide behavior, which is keyed off `pnpm-workspace.yaml`.
|
|
27
32
|
|
|
28
|
-
|
|
33
|
+
## Install
|
|
34
|
+
|
|
35
|
+
Install it globally, or run it once without installing:
|
|
29
36
|
|
|
30
37
|
```bash
|
|
31
|
-
|
|
38
|
+
# global install (pick your package manager)
|
|
39
|
+
pnpm add -g @codefast/cli
|
|
40
|
+
npm install -g @codefast/cli
|
|
32
41
|
|
|
33
|
-
|
|
42
|
+
# one-off, no install
|
|
43
|
+
pnpm dlx @codefast/cli --help
|
|
44
|
+
npx @codefast/cli --help
|
|
45
|
+
```
|
|
34
46
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
pnpm
|
|
39
|
-
pnpm
|
|
40
|
-
pnpm run cli:arrange:simplify:preview
|
|
41
|
-
pnpm run cli:mirror # codefast mirror
|
|
42
|
-
pnpm run cli:mirror:preview # codefast mirror --dry-run
|
|
43
|
-
pnpm run cli:audit:rtl # codefast audit rtl
|
|
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
|
|
47
|
-
pnpm run cli:audit:display-names # codefast audit display-names
|
|
47
|
+
As a project dev dependency:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pnpm add -D @codefast/cli
|
|
51
|
+
pnpm exec codefast --help
|
|
48
52
|
```
|
|
49
53
|
|
|
50
|
-
|
|
54
|
+
The package is published on the `0.x` line and versioned on its own track: **breaking changes ship as minor versions**,
|
|
55
|
+
so pin the minor (`@codefast/cli@~0.9.0`) when you need stability.
|
|
51
56
|
|
|
52
|
-
|
|
57
|
+
## Quick start
|
|
53
58
|
|
|
54
59
|
```bash
|
|
55
|
-
|
|
56
|
-
#
|
|
57
|
-
|
|
60
|
+
codefast --help # list commands
|
|
61
|
+
codefast arrange group "flex h-10 w-full rounded-md bg-primary" # works anywhere, no project needed
|
|
62
|
+
|
|
63
|
+
# in a workspace or a single-package project:
|
|
64
|
+
codefast arrange inspect packages/ui/src # read-only report of arrange findings
|
|
65
|
+
codefast arrange --dry-run packages/ui/src # preview a class reorder
|
|
66
|
+
codefast mirror --dry-run # preview generated exports for each package in scope
|
|
67
|
+
codefast audit links # find broken markdown cross-references
|
|
58
68
|
```
|
|
59
69
|
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
70
|
+
## Global options and conventions
|
|
71
|
+
|
|
72
|
+
- `codefast --help` lists the commands, and `--help` on any command shows its usage; `codefast --version` prints the
|
|
73
|
+
installed version.
|
|
74
|
+
- **The global `--no-color` flag must come _before_ the command name** — `codefast --no-color mirror`, not
|
|
75
|
+
`codefast mirror --no-color`.
|
|
76
|
+
- **Writing commands write by default; pass `--dry-run` to preview.** The audits are read-only — the one exception is
|
|
77
|
+
`audit comments --fix`, which repairs section dividers in place.
|
|
78
|
+
- **`--json` prints a single JSON object on stdout** and suppresses the human-readable progress output, so any command
|
|
79
|
+
can gate a script or a CI job.
|
|
80
|
+
|
|
81
|
+
## Commands at a glance
|
|
82
|
+
|
|
83
|
+
| Command | What it does | Writes? |
|
|
84
|
+
| --------------------- | -------------------------------------------------------------------------- | ----------------- |
|
|
85
|
+
| `arrange` | Regroup Tailwind classes in `cn()` / `tv()` calls in render-pipeline order | yes (`--dry-run`) |
|
|
86
|
+
| `mirror` | Write each package's `package.json#exports` from its built `dist/` | yes (`--dry-run`) |
|
|
87
|
+
| `pack-slim` | Strip the dev-only surface from a package right before publish | yes (`--dry-run`) |
|
|
88
|
+
| `tag` | Stamp `@since <version>` on exported declarations that lack one | yes (`--dry-run`) |
|
|
89
|
+
| `audit links` | Report markdown cross-references that resolve to nothing | no |
|
|
90
|
+
| `audit rtl` | Report physical-direction Tailwind classes that should be logical | no |
|
|
91
|
+
| `audit imports` | Enforce the import policy (React by-name, Zod namespace in front-end) | no (report only) |
|
|
92
|
+
| `audit comments` | Check doc-comment conventions; repair section dividers | `--fix` only |
|
|
93
|
+
| `audit display-names` | Enforce the `namespace:Name` display-name convention | no |
|
|
94
|
+
|
|
95
|
+
**Which of these are for you?** `arrange`, `mirror`, `pack-slim`, `tag`, and `audit links` are general-purpose — they
|
|
96
|
+
work for any pnpm workspace or single package that builds with `tsc`. The other four audits encode codefast's own house
|
|
97
|
+
style (logical Tailwind directions, named React imports, a specific comment/divider grammar, a `namespace:Name` scheme
|
|
98
|
+
for `@codefast/di` tokens). Adopt them if they fit your project; otherwise skip them, or use an allowlist to narrow
|
|
99
|
+
their scope.
|
|
66
100
|
|
|
67
101
|
## `arrange`
|
|
68
102
|
|
|
69
103
|
Rewrites Tailwind class strings inside `cn()` and `tv()` calls, regrouping utilities in render-pipeline order —
|
|
70
104
|
existence, position, layout, sizing, spacing, shape, background, shadow, typography, composite, motion, starting,
|
|
71
|
-
behavior, state, selector —
|
|
105
|
+
behavior, state, selector — rather than alphabetically. (This is codefast's ordering, deliberately different from the
|
|
106
|
+
official Prettier Tailwind plugin's sort.)
|
|
72
107
|
|
|
73
108
|
```bash
|
|
74
109
|
codefast arrange inspect packages/ui/src # read-only report
|
|
@@ -76,9 +111,14 @@ codefast arrange --dry-run packages/ui/src # preview the rewrite
|
|
|
76
111
|
codefast arrange packages/ui/src # write
|
|
77
112
|
```
|
|
78
113
|
|
|
79
|
-
When `[target]` is omitted, `arrange` uses the nearest directory with a `package.json
|
|
80
|
-
|
|
81
|
-
|
|
114
|
+
When `[target]` is omitted, `arrange` uses the nearest directory with a `package.json`, walking up from the current
|
|
115
|
+
directory. Directory scans skip test files (`*.test.*` / `*.spec.*`), because a `cn()` inside an assertion is
|
|
116
|
+
intentional; pass such a file explicitly to process it.
|
|
117
|
+
|
|
118
|
+
`arrange` rewrites a `cn()` / `tv()` call only when its binding is imported from a recognized module — `clsx`,
|
|
119
|
+
`class-variance-authority`, `tailwind-variants`, `@codefast/tailwind-variants`, a `@/lib/utils` / `~/lib/utils` /
|
|
120
|
+
`#lib/utils` re-export, any `…/utils` path, or a dedicated `cn.ts` module — so an unrelated local `cn` is left alone.
|
|
121
|
+
Long static JSX `className` strings are regrouped regardless of where `cn` comes from.
|
|
82
122
|
|
|
83
123
|
| Flag | Description |
|
|
84
124
|
| -------------------- | ----------------------------------------------------------------------------- |
|
|
@@ -100,7 +140,8 @@ Accepts `--dry-run` and `--json`.
|
|
|
100
140
|
|
|
101
141
|
### `arrange group <tokens...>`
|
|
102
142
|
|
|
103
|
-
Groups a pasted class string without touching the filesystem —
|
|
143
|
+
Groups a pasted class string without touching the filesystem — the one command that needs no workspace, useful for
|
|
144
|
+
checking how classes would be bucketed:
|
|
104
145
|
|
|
105
146
|
```bash
|
|
106
147
|
codefast arrange group "relative flex h-10 w-full items-center rounded-md bg-primary"
|
|
@@ -115,10 +156,10 @@ codefast arrange group --tv "flex items-center gap-2"
|
|
|
115
156
|
|
|
116
157
|
## `mirror`
|
|
117
158
|
|
|
118
|
-
Scans each
|
|
119
|
-
`
|
|
120
|
-
|
|
121
|
-
output produces stale exports.
|
|
159
|
+
Scans each package's built `dist/` tree and writes its `package.json#exports` map, plus top-level `main`, `module`, and
|
|
160
|
+
`types` mirrored from the root export and a `files` entry for `dist`. In a workspace it processes every package under
|
|
161
|
+
`pnpm-workspace.yaml`; in a single-package project it processes that one package. **Build first** — `mirror` reads
|
|
162
|
+
`dist/`, and stale output produces stale exports.
|
|
122
163
|
|
|
123
164
|
```bash
|
|
124
165
|
codefast mirror # all workspace packages
|
|
@@ -134,21 +175,45 @@ codefast mirror --dry-run # report changes without writing
|
|
|
134
175
|
|
|
135
176
|
Exits `1` when any package fails, `0` otherwise.
|
|
136
177
|
|
|
178
|
+
### Per-package `mirror` configuration
|
|
179
|
+
|
|
180
|
+
The `mirror` config is a record keyed by package name, set under `mirror` in `codefast.config.*`. Set a package to
|
|
181
|
+
`false` to skip it entirely; omit a package to process it with defaults. For a package you do configure, these keys
|
|
182
|
+
apply (see the [Configuration](#configuration) example for their shape):
|
|
183
|
+
|
|
184
|
+
- **`source`** (`boolean | string`, default `true`) — emit a `source` condition pointing at the original `.ts` so a
|
|
185
|
+
consumer using the `source` condition resolves your `src/`. A string overrides the root-export source path explicitly.
|
|
186
|
+
- **`types`** (`boolean`, default `true`) — emit the `types` condition when a matching `.d.ts` exists.
|
|
187
|
+
- **`import`** (`boolean`, default `true`) — emit the `import` condition.
|
|
188
|
+
- **`preserve`** (`boolean`) — keep the existing `package.json#exports` map as written and only fill in the missing
|
|
189
|
+
`source` / `types` / `import` conditions; no `dist/` scan runs, so the public surface stays exactly what you declared.
|
|
190
|
+
- **`strip`** (`string`) — a `dist/` path prefix to flatten out of the generated specifiers, so `./components/button` is
|
|
191
|
+
published as `./button` rather than leaking the internal folder.
|
|
192
|
+
- **`exclude`** (`string[]`) — specifiers to leave out of the generated map, making a package's public surface a
|
|
193
|
+
decision rather than a consequence of its `dist/` layout. Matched against the specifier as it appears in `exports`
|
|
194
|
+
(after `strip`); a trailing `/*` excludes a whole subtree. The root export and `./package.json` are never excluded.
|
|
195
|
+
- **`exports`** (`Record<string, string>`) — extra or overriding entries merged into the generated map, for specifiers
|
|
196
|
+
the `dist/` scan does not produce (for example a raw CSS source path).
|
|
197
|
+
- **`css`** (`boolean | { enabled?, forceExportFiles?, customExports? }`) — how CSS files in `dist/` become exports:
|
|
198
|
+
`true` enables the default wildcard handling, and the object form tunes it (`enabled` toggles it, `forceExportFiles`
|
|
199
|
+
adds them to `files`, `customExports` sets explicit per-file CSS entries).
|
|
200
|
+
|
|
201
|
+
`source`, `types`, and `import` default to `true`, so an empty config object still emits all three.
|
|
202
|
+
|
|
137
203
|
## `pack-slim`
|
|
138
204
|
|
|
139
|
-
Slims published
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
release workflow runs it as its publish step), so it is never committed.
|
|
205
|
+
Slims a published package down to what a consumer's `tsc` and Node actually read, so the npm tarball ships `dist`
|
|
206
|
+
runtime and types only. Where `mirror` writes the full exports — including the `source` condition — for local
|
|
207
|
+
development, `pack-slim` removes that development lane for publish: it drops `src` from `files`, every `source`
|
|
208
|
+
condition from `exports`/`imports`, every `imports` entry left pointing outside `files`, every script that is not an
|
|
209
|
+
install or publish lifecycle hook, `devDependencies`, and the `dist` source maps plus their dangling `sourceMappingURL`
|
|
210
|
+
directives. Private packages are skipped. It is meant to run on an ephemeral CI checkout right before publish, so its
|
|
211
|
+
result is **never committed**.
|
|
147
212
|
|
|
148
|
-
Because
|
|
149
|
-
tracked changes —
|
|
150
|
-
nothing) and `--force` overrides the guard. In CI the
|
|
151
|
-
when the release workflow runs
|
|
213
|
+
Because that result must never be committed, `pack-slim` refuses to write when the git working tree has uncommitted
|
|
214
|
+
tracked changes — a guard against an accidental local run landing on real work. `--dry-run` is exempt (it writes
|
|
215
|
+
nothing) and `--force` overrides the guard. In CI the guard is invisible: `dist` is gitignored, so the tree is already
|
|
216
|
+
clean when the release workflow runs `pack-slim`.
|
|
152
217
|
|
|
153
218
|
```bash
|
|
154
219
|
codefast pack-slim # every published package
|
|
@@ -164,33 +229,37 @@ codefast pack-slim --dry-run # report what would be stripped without touch
|
|
|
164
229
|
|
|
165
230
|
Exits `1` when any package fails, `0` otherwise.
|
|
166
231
|
|
|
167
|
-
## `
|
|
232
|
+
## `tag`
|
|
168
233
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
234
|
+
Adds `@since <version>` tags to the doc comments of exported declarations that lack one, creating the doc block when
|
|
235
|
+
there is none. The version comes from the nearest `package.json` above each target file, and declarations that already
|
|
236
|
+
carry `@since` are left alone. Run it at release time so published APIs carry accurate version metadata — never
|
|
237
|
+
hand-write `@since`.
|
|
172
238
|
|
|
173
239
|
```bash
|
|
174
|
-
codefast
|
|
175
|
-
codefast
|
|
176
|
-
codefast
|
|
240
|
+
codefast tag # auto-discover packages from cwd (or the single package)
|
|
241
|
+
codefast tag packages/ui/src # tag one directory or file
|
|
242
|
+
codefast tag --dry-run # summary only, no writes
|
|
177
243
|
```
|
|
178
244
|
|
|
179
|
-
| Flag
|
|
180
|
-
|
|
|
181
|
-
| `--
|
|
245
|
+
| Flag | Description |
|
|
246
|
+
| ----------- | ------------------------------------------------------------- |
|
|
247
|
+
| `--dry-run` | Show summary without writing files. |
|
|
248
|
+
| `--json` | Print one JSON summary on stdout (suppresses human progress). |
|
|
249
|
+
|
|
250
|
+
Exits `1` when no target is selected, when any target fails, or when the `tag.onAfterWrite` hook fails.
|
|
182
251
|
|
|
183
|
-
|
|
184
|
-
Configure intentional exceptions via `audit.rtl.allowlist` — each entry is a bare class token or
|
|
185
|
-
`repo/relative/path.tsx:token`.
|
|
252
|
+
## `audit`
|
|
186
253
|
|
|
187
|
-
|
|
254
|
+
Every audit is read-only, exits non-zero when findings remain (so it gates a CI pipeline with no extra glue), and takes
|
|
255
|
+
an optional `[target]` plus `--json`. Each also reads an `allowlist` from configuration for intentional exceptions.
|
|
188
256
|
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
257
|
+
### `audit links`
|
|
258
|
+
|
|
259
|
+
_General-purpose._ Scans markdown for cross-references that point at nothing: a relative path that does not exist, an
|
|
260
|
+
in-document anchor with no matching heading or `<a id>`, and an anchor into another document that the target does not
|
|
261
|
+
offer. That last case is the reason this exists — a browser fails it silently by scrolling to the top. External URLs are
|
|
262
|
+
not checked, and links inside fenced code are treated as examples rather than references.
|
|
194
263
|
|
|
195
264
|
```bash
|
|
196
265
|
codefast audit links # whole repo
|
|
@@ -198,20 +267,48 @@ codefast audit links packages/di # explicit target
|
|
|
198
267
|
codefast audit links --json # machine-readable summary
|
|
199
268
|
```
|
|
200
269
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
270
|
+
Configure exceptions via `audit.links.allowlist` — each entry is a bare link target or `repo/relative/doc.md:target`.
|
|
271
|
+
|
|
272
|
+
### `audit rtl`
|
|
273
|
+
|
|
274
|
+
_House style._ Scans for physical-direction Tailwind classes (e.g. `ml-*`, `left-*`, `text-left`) that should use
|
|
275
|
+
logical equivalents (`ms-*`, `start-*`, `text-start`) or an `rtl:` companion (`translate-x`, `space-x`, resize cursors).
|
|
276
|
+
|
|
277
|
+
```bash
|
|
278
|
+
codefast audit rtl # uses audit.rtl.target from config
|
|
279
|
+
codefast audit rtl packages/ui/src # explicit target
|
|
280
|
+
codefast audit rtl --json # machine-readable summary
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
With no `[target]`, the scan root is `audit.rtl.target` from the config; when neither is set the command fails.
|
|
284
|
+
Configure exceptions via `audit.rtl.allowlist` — each entry is a bare class token or `repo/relative/path.tsx:token`.
|
|
204
285
|
|
|
205
|
-
|
|
206
|
-
`repo/relative/doc.md:target`.
|
|
286
|
+
### `audit imports`
|
|
207
287
|
|
|
208
|
-
|
|
288
|
+
_House style._ Enforces the monorepo's import policy over `.ts`/`.tsx` files:
|
|
209
289
|
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
290
|
+
- **React** — members must be imported by name. Flags `import * as React` and default `React` imports (type-only
|
|
291
|
+
included), plus an implicit `React.*` UMD-global type reference (`e: React.FormEvent` with no import) that `tsc`
|
|
292
|
+
accepts silently through the `export as namespace React` declaration in `@types/react`.
|
|
293
|
+
- **Zod** (front-end packages only) — flags a named `import { z } from "zod"`, which pins Zod's full locale set into the
|
|
294
|
+
bundle; `import * as z from "zod"` lets bundlers tree-shake it.
|
|
295
|
+
|
|
296
|
+
```bash
|
|
297
|
+
codefast audit imports # whole repo
|
|
298
|
+
codefast audit imports apps/web/src # explicit target
|
|
299
|
+
codefast audit imports --json # machine-readable summary
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
Configure exceptions via `audit.imports.allowlist` — each entry is the offending source text as written or
|
|
303
|
+
`repo/relative/path.tsx:<text>`.
|
|
304
|
+
|
|
305
|
+
### `audit comments`
|
|
306
|
+
|
|
307
|
+
_House style._ Checks doc-comment conventions. Section dividers not in the one allowed form are mechanical, so `--fix`
|
|
308
|
+
rewrites them in place. The rest is reported for a person to fix: TSDoc grammar errors, JSDoc `{type}` payloads,
|
|
309
|
+
comments pointing at repo documents, `@param` lists that name some parameters but not all, `@param` descriptions without
|
|
310
|
+
the `-` separator, `@since` tags out of position or naming a version the package has not reached, and comment links to
|
|
311
|
+
missing paths.
|
|
215
312
|
|
|
216
313
|
```bash
|
|
217
314
|
codefast audit comments # whole repo
|
|
@@ -225,80 +322,121 @@ codefast audit comments --json # machine-readable summary
|
|
|
225
322
|
| `--fix` | Rewrite every mechanically fixable divider in place. |
|
|
226
323
|
| `--json` | Print one JSON summary on stdout. |
|
|
227
324
|
|
|
228
|
-
Configure
|
|
325
|
+
Configure exceptions via `audit.comments.allowlist` — each entry is a divider line as written or
|
|
229
326
|
`repo/relative/path.ts:<divider>`.
|
|
230
327
|
|
|
231
|
-
|
|
328
|
+
### `audit display-names`
|
|
232
329
|
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
330
|
+
_House style._ Enforces the display-name convention for every string a `token()`, `tag()`, or module factory takes: a
|
|
331
|
+
name is spelled like the TS symbol it stands for, under its owner's namespace — `namespace:Name`. The namespace is a
|
|
332
|
+
kebab-case package, app, or feature slug (or a scoped package name); a token or module name is PascalCase, a tag key is
|
|
333
|
+
camelCase. It scans TypeScript and markdown alike, since a doc sample is what a reader copies, and skips `tests/`,
|
|
334
|
+
`benchmarks/`, `.changeset/`, and `CHANGELOG.md`.
|
|
237
335
|
|
|
238
336
|
```bash
|
|
239
|
-
codefast audit
|
|
240
|
-
codefast audit
|
|
241
|
-
codefast audit
|
|
337
|
+
codefast audit display-names # whole repo
|
|
338
|
+
codefast audit display-names packages/di/examples # explicit target
|
|
339
|
+
codefast audit display-names --json # machine-readable summary
|
|
242
340
|
```
|
|
243
341
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
| `--json` | Print one JSON summary on stdout. |
|
|
342
|
+
Configure exceptions via `audit.displayNames.allowlist` — each entry is the call as written, through its closing quote
|
|
343
|
+
(or parenthesis when the name is the only argument), or `repo/relative/path.ts:<call>`.
|
|
247
344
|
|
|
248
|
-
|
|
249
|
-
`repo/relative/path.tsx:<text>`.
|
|
345
|
+
## Configuration
|
|
250
346
|
|
|
251
|
-
|
|
347
|
+
**You do not need a config file.** Every command has sensible defaults and works with none. Add a `codefast.config.*`
|
|
348
|
+
file at your project root only to change a default — and add only the sections for the commands you actually use.
|
|
252
349
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
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.
|
|
350
|
+
**Where it goes and how it loads.** The CLI walks up from the working directory and uses the first match, checking
|
|
351
|
+
`codefast.config.mjs`, `codefast.config.js`, `codefast.config.cjs`, then `codefast.config.json` in each directory. JS
|
|
352
|
+
configs are loaded via [jiti](https://github.com/unjs/jiti) — so **only run the CLI in repositories you trust**, and
|
|
353
|
+
note that only a JS config can define `onAfterWrite` hooks (JSON can't hold functions). The schema is **strict**: an
|
|
354
|
+
unknown key is an error, which catches typos immediately.
|
|
260
355
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
356
|
+
### Start small
|
|
357
|
+
|
|
358
|
+
The smallest valid config is empty. Grow it one section at a time — each top-level key configures one command:
|
|
359
|
+
|
|
360
|
+
```js
|
|
361
|
+
// codefast.config.js
|
|
362
|
+
export default {};
|
|
265
363
|
```
|
|
266
364
|
|
|
267
|
-
|
|
|
268
|
-
|
|
|
269
|
-
|
|
|
365
|
+
| Key | Command | What it configures |
|
|
366
|
+
| --------- | --------- | ---------------------------------------------------------------------------------------------- |
|
|
367
|
+
| `mirror` | `mirror` | per-package `exports` generation — see [per-package config](#per-package-mirror-configuration) |
|
|
368
|
+
| `tag` | `tag` | package names to skip, and a hook to run after writing |
|
|
369
|
+
| `arrange` | `arrange` | a hook to run after writing |
|
|
370
|
+
| `audit` | `audit *` | each audit's default scan target and its `allowlist` of accepted exceptions |
|
|
270
371
|
|
|
271
|
-
|
|
272
|
-
closing quote (or parenthesis when the name is the only argument), or `repo/relative/path.ts:<call>`.
|
|
372
|
+
### Author it with types
|
|
273
373
|
|
|
274
|
-
|
|
374
|
+
Don't memorize the shape. Import `defineConfig` (or annotate with the `CodefastConfig` type) and your editor completes
|
|
375
|
+
every key, checks the values, and catches typos **before you run anything** — the types _are_ the reference for what's
|
|
376
|
+
valid, and the strict runtime schema is the backstop.
|
|
275
377
|
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
378
|
+
```ts
|
|
379
|
+
// codefast.config.ts
|
|
380
|
+
import { defineConfig } from "@codefast/cli";
|
|
279
381
|
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
codefast tag --dry-run # summary only, no writes
|
|
382
|
+
export default defineConfig({
|
|
383
|
+
mirror: { "@acme/ui": { strip: "./components/" } }, // autocomplete: strip, exclude, source, types, css, …
|
|
384
|
+
});
|
|
284
385
|
```
|
|
285
386
|
|
|
286
|
-
|
|
287
|
-
| ----------- | ------------------------------------------------------------- |
|
|
288
|
-
| `--dry-run` | Show summary without writing files. |
|
|
289
|
-
| `--json` | Print one JSON summary on stdout (suppresses human progress). |
|
|
387
|
+
A plain `.js` config gets the same help through a JSDoc type — no build step, no `.ts`:
|
|
290
388
|
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
389
|
+
```js
|
|
390
|
+
// codefast.config.js
|
|
391
|
+
/** @type {import("@codefast/cli").CodefastConfig} */
|
|
392
|
+
export default {
|
|
393
|
+
mirror: { "@acme/ui": { strip: "./components/" } },
|
|
394
|
+
};
|
|
395
|
+
```
|
|
294
396
|
|
|
295
|
-
|
|
397
|
+
### Common recipes
|
|
296
398
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
399
|
+
**Run a formatter after a command rewrites files.** `tag` and `arrange` take an `onAfterWrite` hook (sync or async). It
|
|
400
|
+
runs only when files were actually written — never on `--dry-run`:
|
|
401
|
+
|
|
402
|
+
```js
|
|
403
|
+
// codefast.config.js
|
|
404
|
+
import { execSync } from "node:child_process";
|
|
405
|
+
|
|
406
|
+
const format = ({ files }) => execSync(`oxfmt ${files.join(" ")}`, { stdio: "inherit" });
|
|
407
|
+
|
|
408
|
+
export default {
|
|
409
|
+
tag: { onAfterWrite: format },
|
|
410
|
+
arrange: { onAfterWrite: format },
|
|
411
|
+
};
|
|
412
|
+
```
|
|
413
|
+
|
|
414
|
+
**Skip packages.** `tag.skipPackages` takes globs matched against package names; `mirror` skips any package set to
|
|
415
|
+
`false`:
|
|
416
|
+
|
|
417
|
+
```js
|
|
418
|
+
export default {
|
|
419
|
+
tag: { skipPackages: ["@acme/internal", "@apps/*"] },
|
|
420
|
+
mirror: { "@acme/internal": false },
|
|
421
|
+
};
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
**Accept a known audit finding.** Every audit takes an `allowlist`. An entry is the offending text exactly as it
|
|
425
|
+
appears, or `repo/relative/path:<text>` to scope it to a single file:
|
|
426
|
+
|
|
427
|
+
```js
|
|
428
|
+
export default {
|
|
429
|
+
audit: {
|
|
430
|
+
imports: { allowlist: [`packages/legacy/src/x.ts:import { z } from "zod";`] },
|
|
431
|
+
rtl: { allowlist: ["packages/ui/src/variants/sheet.ts:data-open:slide-in-from-left-10"] },
|
|
432
|
+
},
|
|
433
|
+
};
|
|
434
|
+
```
|
|
435
|
+
|
|
436
|
+
### Complete reference
|
|
437
|
+
|
|
438
|
+
Every section together — see [per-package `mirror` configuration](#per-package-mirror-configuration) for the `mirror`
|
|
439
|
+
keys:
|
|
302
440
|
|
|
303
441
|
```js
|
|
304
442
|
// codefast.config.js
|
|
@@ -336,13 +474,15 @@ export default {
|
|
|
336
474
|
},
|
|
337
475
|
links: { allowlist: [] }, // bare link target, or `repo/relative/doc.md:target`
|
|
338
476
|
comments: { allowlist: [] }, // divider as written, or `repo/relative/path.ts:<divider>`
|
|
339
|
-
|
|
477
|
+
imports: { allowlist: [] }, // offending import text as written, or `repo/relative/path.tsx:<text>`
|
|
478
|
+
displayNames: { allowlist: [] }, // call as written, or `repo/relative/path.ts:<call>`
|
|
340
479
|
},
|
|
341
480
|
};
|
|
342
481
|
```
|
|
343
482
|
|
|
344
|
-
`source`, `types`, and `import` default to `true
|
|
345
|
-
actually written — never on `--dry-run
|
|
483
|
+
`source`, `types`, and `import` default to `true`, so an empty `mirror` entry still emits all three. The `onAfterWrite`
|
|
484
|
+
hooks run only when files were actually written — never on `--dry-run`; a hook failure is reported on stderr and the
|
|
485
|
+
command exits `1`.
|
|
346
486
|
|
|
347
487
|
## Exit codes
|
|
348
488
|
|
|
@@ -352,6 +492,46 @@ actually written — never on `--dry-run`. A hook failure is reported on stderr
|
|
|
352
492
|
| `1` | General failure (missing paths, failed packages, failed hooks). |
|
|
353
493
|
| `2` | Invalid arguments or configuration. |
|
|
354
494
|
|
|
495
|
+
## Programmatic use
|
|
496
|
+
|
|
497
|
+
`@codefast/cli` is importable as well as executable. `runCli` runs the same CLI in-process and resolves to the exit code
|
|
498
|
+
it would have exited with — the `codefast` binary is a thin wrapper around it.
|
|
499
|
+
|
|
500
|
+
```ts
|
|
501
|
+
import { runCli } from "@codefast/cli";
|
|
502
|
+
|
|
503
|
+
// `argv` follows the `process.argv` layout: the first two entries are ignored,
|
|
504
|
+
// exactly as when Node runs the binary.
|
|
505
|
+
const exitCode = await runCli(["node", "codefast", "mirror", "--dry-run", "--json"]);
|
|
506
|
+
|
|
507
|
+
if (exitCode !== 0) {
|
|
508
|
+
throw new Error(`codefast exited with ${exitCode}`);
|
|
509
|
+
}
|
|
510
|
+
```
|
|
511
|
+
|
|
512
|
+
The command still writes its human or `--json` output to stdout/stderr; `runCli` does not capture it. Read stdout
|
|
513
|
+
yourself when you need the structured summary.
|
|
514
|
+
|
|
515
|
+
## How the codefast monorepo uses it
|
|
516
|
+
|
|
517
|
+
The tool is general; the codefast monorepo just wires convenience scripts and a release step around it — a good template
|
|
518
|
+
if you adopt the CLI in your own workspace. It runs from the built output via root `package.json` scripts:
|
|
519
|
+
|
|
520
|
+
```bash
|
|
521
|
+
pnpm run codefast <command> # generic entry: node ./packages/cli/dist/bin.js
|
|
522
|
+
|
|
523
|
+
pnpm run cli:arrange # codefast arrange
|
|
524
|
+
pnpm run cli:mirror # codefast mirror
|
|
525
|
+
pnpm run cli:audit:links # codefast audit links
|
|
526
|
+
pnpm run cli:audit:rtl # codefast audit rtl
|
|
527
|
+
pnpm run cli:audit:comments # codefast audit comments
|
|
528
|
+
pnpm run cli:audit:imports # codefast audit imports
|
|
529
|
+
pnpm run cli:audit:display-names # codefast audit display-names
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
`pnpm run version-packages` runs `changeset version` and then `codefast tag`, so published APIs are stamped at release,
|
|
533
|
+
and the release workflow runs `codefast pack-slim` as its publish step on a clean CI checkout.
|
|
534
|
+
|
|
355
535
|
## Documentation
|
|
356
536
|
|
|
357
537
|
- [codefastlabs.com/docs/cli](https://codefastlabs.com/docs/cli) — this document, rendered.
|