@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.
Files changed (159) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +329 -149
  3. package/dist/arrange/analyze.d.ts +10 -0
  4. package/dist/arrange/cli-schema.d.ts +50 -0
  5. package/dist/arrange/command.d.ts +7 -0
  6. package/dist/arrange/domain/analyze-service.d.ts +18 -0
  7. package/dist/arrange/domain/ast/ast-node.d.ts +394 -0
  8. package/dist/arrange/domain/ast/collectors-cn.d.ts +26 -0
  9. package/dist/arrange/domain/ast/collectors-jsx.d.ts +8 -0
  10. package/dist/arrange/domain/ast/collectors-tv.d.ts +34 -0
  11. package/dist/arrange/domain/ast/helpers.d.ts +36 -0
  12. package/dist/arrange/domain/ast/helpers.js +1 -0
  13. package/dist/arrange/domain/ast/simplify-targets.d.ts +22 -0
  14. package/dist/arrange/domain/ast/targets.d.ts +20 -0
  15. package/dist/arrange/domain/constants.d.ts +111 -0
  16. package/dist/arrange/domain/grouping-service.d.ts +100 -0
  17. package/dist/arrange/domain/grouping.d.ts +21 -0
  18. package/dist/arrange/domain/imports.d.ts +14 -0
  19. package/dist/arrange/domain/source-text-formatters.d.ts +33 -0
  20. package/dist/arrange/domain/tailwind-token.d.ts +24 -0
  21. package/dist/arrange/domain/token-classifier.d.ts +47 -0
  22. package/dist/arrange/domain/types.d.ts +208 -0
  23. package/dist/arrange/output.d.ts +26 -0
  24. package/dist/arrange/process-file.d.ts +11 -0
  25. package/dist/arrange/resolve-target.d.ts +10 -0
  26. package/dist/arrange/resolve-target.js +3 -16
  27. package/dist/arrange/scan-target.d.ts +7 -0
  28. package/dist/arrange/simplify-process-file.d.ts +11 -0
  29. package/dist/arrange/simplify-sync.d.ts +13 -0
  30. package/dist/arrange/source-parse.d.ts +7 -0
  31. package/dist/arrange/suggest.d.ts +8 -0
  32. package/dist/arrange/sync.d.ts +11 -0
  33. package/dist/arrange/typescript-ast-translator.d.ts +31 -0
  34. package/dist/arrange/workspace.d.ts +13 -0
  35. package/dist/arrange/workspace.js +2 -2
  36. package/dist/audit/cli-schema.d.ts +93 -0
  37. package/dist/audit/cli-schema.js +3 -3
  38. package/dist/audit/command.d.ts +8 -0
  39. package/dist/audit/command.js +12 -12
  40. package/dist/audit/domain/audit-file.d.ts +7 -0
  41. package/dist/audit/domain/comment-content.d.ts +26 -0
  42. package/dist/audit/domain/comment-dividers.d.ts +62 -0
  43. package/dist/audit/domain/display-names.d.ts +11 -0
  44. package/dist/audit/domain/import-policy.d.ts +34 -0
  45. package/dist/audit/domain/import-policy.js +147 -0
  46. package/dist/audit/domain/link-references.d.ts +40 -0
  47. package/dist/audit/domain/mappings.d.ts +45 -0
  48. package/dist/audit/domain/markdown-links.d.ts +44 -0
  49. package/dist/audit/domain/since-versions.d.ts +26 -0
  50. package/dist/audit/domain/tokenize.d.ts +14 -0
  51. package/dist/audit/domain/tsdoc-syntax.d.ts +20 -0
  52. package/dist/audit/domain/types.d.ts +171 -0
  53. package/dist/audit/output.d.ts +91 -0
  54. package/dist/audit/output.js +11 -11
  55. package/dist/audit/prepare.d.ts +70 -0
  56. package/dist/audit/prepare.js +11 -11
  57. package/dist/audit/run-comments.d.ts +17 -0
  58. package/dist/audit/run-display-names.d.ts +14 -0
  59. package/dist/audit/run-imports.d.ts +14 -0
  60. package/dist/audit/{run-react.js → run-imports.js} +15 -5
  61. package/dist/audit/run-links.d.ts +14 -0
  62. package/dist/audit/run.d.ts +14 -0
  63. package/dist/bin.d.ts +2 -0
  64. package/dist/cli.d.ts +6 -0
  65. package/dist/core/cli/format-error.d.ts +7 -0
  66. package/dist/core/cli/global-options.d.ts +15 -0
  67. package/dist/core/cli/positional.d.ts +6 -0
  68. package/dist/core/cli/result-handle.d.ts +19 -0
  69. package/dist/core/config/define-config.d.ts +7 -0
  70. package/dist/core/config/define-config.js +8 -0
  71. package/dist/core/config/loader.d.ts +18 -0
  72. package/dist/core/config/loader.js +2 -7
  73. package/dist/core/config/schema.d.ts +99 -0
  74. package/dist/core/config/schema.js +7 -85
  75. package/dist/core/config/warnings.d.ts +6 -0
  76. package/dist/core/config.d.ts +12 -0
  77. package/dist/core/errors.d.ts +25 -0
  78. package/dist/core/exit-codes.d.ts +18 -0
  79. package/dist/core/filesystem/node.d.ts +7 -0
  80. package/dist/core/filesystem/node.js +1 -0
  81. package/dist/core/filesystem/port.d.ts +44 -0
  82. package/dist/core/glob.d.ts +19 -0
  83. package/dist/core/logger.d.ts +9 -0
  84. package/dist/core/result.d.ts +30 -0
  85. package/dist/core/schema-parse.d.ts +9 -0
  86. package/dist/core/source-text-edit.d.ts +33 -0
  87. package/dist/core/verbose-diagnostics.d.ts +6 -0
  88. package/dist/core/workspace/ancestor-directories.d.ts +12 -0
  89. package/dist/core/workspace/ancestor-directories.js +30 -0
  90. package/dist/core/workspace/markdown-walk.d.ts +7 -0
  91. package/dist/core/workspace/markdown-walk.js +2 -20
  92. package/dist/core/workspace/package-version.d.ts +9 -0
  93. package/dist/core/workspace/package-version.js +8 -12
  94. package/dist/core/workspace/resolver.d.ts +39 -0
  95. package/dist/core/workspace/resolver.js +58 -75
  96. package/dist/core/workspace/skip-directories.d.ts +6 -0
  97. package/dist/core/workspace/source-walk.d.ts +16 -0
  98. package/dist/core/workspace/source-walk.js +2 -19
  99. package/dist/core/workspace/typescript-walk.d.ts +7 -0
  100. package/dist/core/workspace/typescript-walk.js +2 -23
  101. package/dist/core/workspace/walk-files.d.ts +7 -0
  102. package/dist/core/workspace/walk-files.js +27 -0
  103. package/dist/core/workspace/well-known-files.d.ts +18 -0
  104. package/dist/core/workspace/well-known-files.js +18 -0
  105. package/dist/index.d.ts +6 -0
  106. package/dist/index.js +5 -0
  107. package/dist/mirror/cli-result.d.ts +13 -0
  108. package/dist/mirror/cli-schema.d.ts +8 -0
  109. package/dist/mirror/command.d.ts +7 -0
  110. package/dist/mirror/dist-filesystem-impl.d.ts +8 -0
  111. package/dist/mirror/domain/constants.d.ts +18 -0
  112. package/dist/mirror/domain/constants.js +0 -12
  113. package/dist/mirror/domain/dirent-guard.d.ts +10 -0
  114. package/dist/mirror/domain/dist-filesystem.d.ts +9 -0
  115. package/dist/mirror/domain/errors.d.ts +24 -0
  116. package/dist/mirror/domain/exports.d.ts +36 -0
  117. package/dist/mirror/domain/package-display-name.d.ts +8 -0
  118. package/dist/mirror/domain/path-normalizer.d.ts +6 -0
  119. package/dist/mirror/domain/types.d.ts +131 -0
  120. package/dist/mirror/output.d.ts +23 -0
  121. package/dist/mirror/package-path.d.ts +19 -0
  122. package/dist/mirror/prepare.d.ts +15 -0
  123. package/dist/mirror/prepare.js +2 -2
  124. package/dist/mirror/supplement-exports.d.ts +27 -0
  125. package/dist/mirror/supplement-exports.js +2 -2
  126. package/dist/mirror/sync-reporter.d.ts +60 -0
  127. package/dist/mirror/sync-reporter.js +4 -0
  128. package/dist/mirror/sync-types.d.ts +43 -0
  129. package/dist/mirror/sync-workspace-package.d.ts +9 -0
  130. package/dist/mirror/sync-workspace-package.js +3 -3
  131. package/dist/mirror/sync.d.ts +12 -0
  132. package/dist/mirror/sync.js +5 -3
  133. package/dist/mirror/write-exports.d.ts +15 -0
  134. package/dist/pack-slim/cli-result.d.ts +13 -0
  135. package/dist/pack-slim/cli-schema.d.ts +17 -0
  136. package/dist/pack-slim/command.d.ts +7 -0
  137. package/dist/pack-slim/command.js +2 -2
  138. package/dist/pack-slim/domain/transform.d.ts +69 -0
  139. package/dist/pack-slim/domain/types.d.ts +46 -0
  140. package/dist/pack-slim/output.d.ts +15 -0
  141. package/dist/pack-slim/sync.d.ts +23 -0
  142. package/dist/pack-slim/sync.js +4 -4
  143. package/dist/pack-slim/working-tree.d.ts +20 -0
  144. package/dist/tag/cli-result.d.ts +7 -0
  145. package/dist/tag/cli-schema.d.ts +8 -0
  146. package/dist/tag/command.d.ts +7 -0
  147. package/dist/tag/domain/types.d.ts +111 -0
  148. package/dist/tag/output.d.ts +17 -0
  149. package/dist/tag/prepare.d.ts +13 -0
  150. package/dist/tag/prepare.js +2 -2
  151. package/dist/tag/resolve-target-path.d.ts +10 -0
  152. package/dist/tag/since-writer.d.ts +32 -0
  153. package/dist/tag/sync.d.ts +42 -0
  154. package/dist/tag/target-candidates.d.ts +8 -0
  155. package/dist/tag/target-candidates.js +1 -1
  156. package/dist/tag/target-runner.d.ts +8 -0
  157. package/dist/tag/version-resolver.d.ts +7 -0
  158. package/package.json +12 -1
  159. package/dist/audit/domain/react-imports.js +0 -91
@@ -0,0 +1,44 @@
1
+ /**
2
+ * Extracts the two things a markdown cross-reference can get wrong: where it points and what it lands on.
3
+ */
4
+ /**
5
+ * One `[text](target)` whose target is a path in this repository.
6
+ *
7
+ * @since 0.5.0
8
+ */
9
+ type MarkdownLinkReference = {
10
+ readonly line: number;
11
+ /** The path as written, with any fragment stripped. Empty when the link is fragment-only. */
12
+ readonly targetPath: string;
13
+ /** The `#fragment`, without the hash, or `null`. */
14
+ readonly anchor: string | null;
15
+ };
16
+ /**
17
+ * The anchors a document offers, and the references it makes.
18
+ *
19
+ * @since 0.5.0
20
+ */
21
+ export type MarkdownLinkScan = {
22
+ readonly references: ReadonlyArray<MarkdownLinkReference>;
23
+ readonly anchors: ReadonlySet<string>;
24
+ };
25
+ /**
26
+ * The anchor ids a rendered document exposes: explicit `<a id>` targets plus every heading's slug.
27
+ *
28
+ * @remarks Slugging matches GitHub's — lowercase, drop everything that is not a letter, number, space
29
+ * or hyphen, then hyphenate spaces. Duplicate headings get a `-1` suffix there; this returns the base
30
+ * only, so a link to the second copy reads as dangling rather than being silently accepted.
31
+ *
32
+ * @since 0.5.0
33
+ */
34
+ export declare function collectMarkdownAnchors(content: string): Set<string>;
35
+ /**
36
+ * Every repo-local link a document makes, with the anchors it offers.
37
+ *
38
+ * @remarks Fenced code is stripped first: a fence showing a link is an example, not a reference, and
39
+ * checking it would make the audit fail on documentation that is doing its job.
40
+ *
41
+ * @since 0.5.0
42
+ */
43
+ export declare function scanMarkdownLinks(content: string): MarkdownLinkScan;
44
+ export {};
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Flags `@since` tags naming a version the owning package has not reached.
3
+ */
4
+ /**
5
+ * One impossible `@since` stamp found in a file's comments.
6
+ *
7
+ * @since 0.8.0
8
+ */
9
+ export interface SinceVersionFinding {
10
+ readonly line: number;
11
+ readonly raw: string;
12
+ }
13
+ /**
14
+ * Compares two SemVer strings by precedence — positive when `left` is greater,
15
+ * null when either side is not a SemVer version.
16
+ *
17
+ * @since 0.8.0
18
+ */
19
+ export declare function compareVersionPrecedence(left: string, right: string): number | null;
20
+ /**
21
+ * Scans a file's comments for `@since` tags stamped above the package's current
22
+ * version — a release that has not happened, so the stamp cannot be true.
23
+ *
24
+ * @since 0.8.0
25
+ */
26
+ export declare function scanImpossibleSinceTags(content: string, packageVersion: string): Array<SinceVersionFinding>;
@@ -0,0 +1,14 @@
1
+ import type { RtlClassToken } from "#/audit/domain/types";
2
+ /**
3
+ * Splits a class token into [variant, value, modifier], colon/slash-aware of
4
+ * brackets and parens (arbitrary values like data-[side=left] or calc(...)).
5
+ *
6
+ * @since 0.5.0-canary.6
7
+ */
8
+ export declare function splitClassName(token: string): [string | null, string, string | null];
9
+ /**
10
+ * Collects the parsed class tokens from every string literal in a file's content.
11
+ *
12
+ * @since 0.5.0-canary.6
13
+ */
14
+ export declare function collectTokens(content: string): Array<RtlClassToken>;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Validates every doc block against the official TSDoc grammar, not a regex approximation.
3
+ */
4
+ /**
5
+ * One grammar diagnostic from the TSDoc parser.
6
+ *
7
+ * @since 0.6.0
8
+ */
9
+ export interface TsdocSyntaxFinding {
10
+ readonly line: number;
11
+ /** The parser's stable message id, e.g. `tsdoc-escape-right-brace` — the allowlist key. */
12
+ readonly raw: string;
13
+ readonly reason: string;
14
+ }
15
+ /**
16
+ * Every TSDoc grammar diagnostic in a file's doc blocks, in source order.
17
+ *
18
+ * @since 0.6.0
19
+ */
20
+ export declare function scanTsdocSyntax(content: string): Array<TsdocSyntaxFinding>;
@@ -0,0 +1,171 @@
1
+ /**
2
+ * A class token parsed from a source string literal, split into variant, value, and modifier.
3
+ *
4
+ * @since 0.5.0-canary.6
5
+ */
6
+ export type RtlClassToken = {
7
+ readonly raw: string;
8
+ readonly token: string;
9
+ readonly variant: string | null;
10
+ readonly value: string;
11
+ readonly modifier: string | null;
12
+ readonly line: number;
13
+ };
14
+ /**
15
+ * A physical class occurrence the RTL audit flags, with its suggested logical replacement.
16
+ *
17
+ * @since 0.5.0-canary.6
18
+ */
19
+ export type RtlViolation = {
20
+ readonly line: number;
21
+ readonly raw: string;
22
+ readonly suggestion: string;
23
+ };
24
+ /**
25
+ * The RTL violations found in one file.
26
+ *
27
+ * @since 0.5.0-canary.6
28
+ */
29
+ export type RtlFileViolations = {
30
+ readonly relativePath: string;
31
+ readonly violations: Array<RtlViolation>;
32
+ };
33
+ /**
34
+ * Outcome of one `audit rtl` run.
35
+ *
36
+ * @since 0.5.0-canary.6
37
+ */
38
+ export type RtlAuditResult = {
39
+ readonly files: Array<RtlFileViolations>;
40
+ readonly violationCount: number;
41
+ readonly allowlistedCount: number;
42
+ readonly scannedFileCount: number;
43
+ };
44
+ /**
45
+ * An import-policy violation: a banned import form (namespace / default / named), or an implicit
46
+ * UMD-global type reference under a name nothing in the file imports.
47
+ *
48
+ * @since 0.10.0
49
+ */
50
+ export type ImportPolicyViolation = {
51
+ readonly line: number;
52
+ /** The offending source text — the import statement or the qualified type name. */
53
+ readonly raw: string;
54
+ readonly reason: string;
55
+ };
56
+ /**
57
+ * The import-policy violations found in one file.
58
+ *
59
+ * @since 0.10.0
60
+ */
61
+ export type ImportPolicyFileViolations = {
62
+ readonly relativePath: string;
63
+ readonly violations: Array<ImportPolicyViolation>;
64
+ };
65
+ /**
66
+ * Outcome of one `audit imports` run.
67
+ *
68
+ * @since 0.10.0
69
+ */
70
+ export type ImportsAuditResult = {
71
+ readonly files: Array<ImportPolicyFileViolations>;
72
+ readonly violationCount: number;
73
+ readonly allowlistedCount: number;
74
+ readonly scannedFileCount: number;
75
+ };
76
+ /**
77
+ * A `token()`, `tag()` or module display name that breaks the display-name convention.
78
+ *
79
+ * @since 0.9.0
80
+ */
81
+ export type DisplayNameViolation = {
82
+ readonly line: number;
83
+ /** The call as written, through its closing quote. */
84
+ readonly raw: string;
85
+ readonly reason: string;
86
+ };
87
+ /**
88
+ * The display-name violations found in one file.
89
+ *
90
+ * @since 0.9.0
91
+ */
92
+ export type DisplayNameFileViolations = {
93
+ readonly relativePath: string;
94
+ readonly violations: Array<DisplayNameViolation>;
95
+ };
96
+ /**
97
+ * Outcome of one `audit display-names` run.
98
+ *
99
+ * @since 0.9.0
100
+ */
101
+ export type DisplayNameAuditResult = {
102
+ readonly files: Array<DisplayNameFileViolations>;
103
+ readonly violationCount: number;
104
+ readonly allowlistedCount: number;
105
+ readonly scannedFileCount: number;
106
+ };
107
+ /**
108
+ * A broken link or anchor found by the link audit.
109
+ *
110
+ * @since 0.5.0
111
+ */
112
+ export type LinkBreakage = {
113
+ readonly line: number;
114
+ /** The link target as written, fragment included. */
115
+ readonly raw: string;
116
+ readonly reason: string;
117
+ };
118
+ /**
119
+ * The link breakages found in one markdown file.
120
+ *
121
+ * @since 0.5.0
122
+ */
123
+ export type LinkFileBreakages = {
124
+ readonly relativePath: string;
125
+ readonly breakages: Array<LinkBreakage>;
126
+ };
127
+ /**
128
+ * Outcome of one `audit links` run.
129
+ *
130
+ * @since 0.5.0
131
+ */
132
+ export type LinkAuditResult = {
133
+ readonly files: Array<LinkFileBreakages>;
134
+ readonly breakageCount: number;
135
+ readonly allowlistedCount: number;
136
+ readonly linkCount: number;
137
+ readonly scannedFileCount: number;
138
+ };
139
+ /**
140
+ * A section divider that does not match the repo's one allowed form. Always `--fix`-able.
141
+ *
142
+ * @since 0.6.0
143
+ */
144
+ export type DividerBreakage = {
145
+ readonly line: number;
146
+ /** The divider's opening line as written. */
147
+ readonly raw: string;
148
+ readonly reason: string;
149
+ };
150
+ /**
151
+ * @see DividerBreakage
152
+ *
153
+ * @since 0.6.0
154
+ */
155
+ export type DividerFileBreakages = {
156
+ readonly relativePath: string;
157
+ readonly breakages: Array<DividerBreakage>;
158
+ };
159
+ /**
160
+ * Outcome of one `audit comments` run. `fixedCount` stays `0` unless `--fix` was passed.
161
+ *
162
+ * @since 0.6.0
163
+ */
164
+ export type CommentAuditResult = {
165
+ readonly files: Array<DividerFileBreakages>;
166
+ readonly breakageCount: number;
167
+ readonly allowlistedCount: number;
168
+ readonly fixedCount: number;
169
+ readonly dividerCount: number;
170
+ readonly scannedFileCount: number;
171
+ };
@@ -0,0 +1,91 @@
1
+ import type { CommentAuditResult, ImportsAuditResult, LinkAuditResult, RtlAuditResult, DisplayNameAuditResult } from "#/audit/domain/types";
2
+ /**
3
+ * Exit `1` when any non-allowlisted violation remains.
4
+ *
5
+ * @since 0.5.0-canary.6
6
+ */
7
+ export declare function exitCodeForRtlAuditResult(result: RtlAuditResult): number;
8
+ /**
9
+ * Human-readable RTL audit report (matches the former packages/ui script shape).
10
+ *
11
+ * @since 0.5.0-canary.6
12
+ */
13
+ export declare function presentRtlAuditResult(result: RtlAuditResult): void;
14
+ /**
15
+ * Machine-readable RTL audit summary for `--json`.
16
+ *
17
+ * @since 0.5.0-canary.6
18
+ */
19
+ export declare function formatRtlAuditJsonOutput(result: RtlAuditResult, rootDir: string): string;
20
+ /**
21
+ * Exit `1` when any non-allowlisted broken link remains.
22
+ *
23
+ * @since 0.5.0
24
+ */
25
+ export declare function exitCodeForLinkAuditResult(result: LinkAuditResult): number;
26
+ /**
27
+ * Human-readable link audit report.
28
+ *
29
+ * @since 0.5.0
30
+ */
31
+ export declare function presentLinkAuditResult(result: LinkAuditResult): void;
32
+ /**
33
+ * Machine-readable link audit summary for `--json`.
34
+ *
35
+ * @since 0.5.0
36
+ */
37
+ export declare function formatLinkAuditJsonOutput(result: LinkAuditResult, rootDir: string): string;
38
+ /**
39
+ * Exit `1` when any non-allowlisted import-policy violation remains.
40
+ *
41
+ * @since 0.10.0
42
+ */
43
+ export declare function exitCodeForImportsAuditResult(result: ImportsAuditResult): number;
44
+ /**
45
+ * Human-readable import-policy report.
46
+ *
47
+ * @since 0.10.0
48
+ */
49
+ export declare function presentImportsAuditResult(result: ImportsAuditResult): void;
50
+ /**
51
+ * Machine-readable import-policy summary for `--json`.
52
+ *
53
+ * @since 0.10.0
54
+ */
55
+ export declare function formatImportsAuditJsonOutput(result: ImportsAuditResult, rootDir: string): string;
56
+ /**
57
+ * Exit `1` when any non-allowlisted divider still breaks the convention.
58
+ *
59
+ * @since 0.6.0
60
+ */
61
+ export declare function exitCodeForCommentAuditResult(result: CommentAuditResult): number;
62
+ /**
63
+ * Human-readable comment-divider report.
64
+ *
65
+ * @since 0.6.0
66
+ */
67
+ export declare function presentCommentAuditResult(result: CommentAuditResult): void;
68
+ /**
69
+ * Machine-readable comment-divider summary for `--json`.
70
+ *
71
+ * @since 0.6.0
72
+ */
73
+ export declare function formatCommentAuditJsonOutput(result: CommentAuditResult, rootDir: string): string;
74
+ /**
75
+ * Exit `1` when any non-allowlisted display-name violation remains.
76
+ *
77
+ * @since 0.9.0
78
+ */
79
+ export declare function exitCodeForDisplayNameAuditResult(result: DisplayNameAuditResult): number;
80
+ /**
81
+ * Human-readable display-name report.
82
+ *
83
+ * @since 0.9.0
84
+ */
85
+ export declare function presentDisplayNameAuditResult(result: DisplayNameAuditResult): void;
86
+ /**
87
+ * Machine-readable display-name summary for `--json`.
88
+ *
89
+ * @since 0.9.0
90
+ */
91
+ export declare function formatDisplayNameAuditJsonOutput(result: DisplayNameAuditResult, rootDir: string): string;
@@ -83,19 +83,19 @@ export function formatLinkAuditJsonOutput(result, rootDir) {
83
83
  });
84
84
  }
85
85
  /**
86
- * Exit `1` when any non-allowlisted React import-policy violation remains.
86
+ * Exit `1` when any non-allowlisted import-policy violation remains.
87
87
  *
88
- * @since 0.8.0
88
+ * @since 0.10.0
89
89
  */
90
- export function exitCodeForReactAuditResult(result) {
90
+ export function exitCodeForImportsAuditResult(result) {
91
91
  return result.violationCount > 0 ? CLI_EXIT_GENERAL_ERROR : CLI_EXIT_SUCCESS;
92
92
  }
93
93
  /**
94
- * Human-readable React import-policy report.
94
+ * Human-readable import-policy report.
95
95
  *
96
- * @since 0.8.0
96
+ * @since 0.10.0
97
97
  */
98
- export function presentReactAuditResult(result) {
98
+ export function presentImportsAuditResult(result) {
99
99
  for (const file of result.files) {
100
100
  logger.out(`\n${file.relativePath}`);
101
101
  for (const { line, raw, reason } of file.violations) {
@@ -104,18 +104,18 @@ export function presentReactAuditResult(result) {
104
104
  }
105
105
  const allowlistSuffix = result.allowlistedCount > 0 ? ` (${result.allowlistedCount} allowlisted)` : "";
106
106
  if (result.violationCount > 0) {
107
- logger.out(`\n✖ ${result.violationCount} React import violation(s)${allowlistSuffix}`);
107
+ logger.out(`\n✖ ${result.violationCount} import-policy violation(s)${allowlistSuffix}`);
108
108
  }
109
109
  else {
110
- logger.out(`✓ No namespace/default React imports or React.* UMD globals across ${result.scannedFileCount} file(s)${allowlistSuffix}`);
110
+ logger.out(`✓ No import-policy violations across ${result.scannedFileCount} file(s)${allowlistSuffix}`);
111
111
  }
112
112
  }
113
113
  /**
114
- * Machine-readable React import-policy summary for `--json`.
114
+ * Machine-readable import-policy summary for `--json`.
115
115
  *
116
- * @since 0.8.0
116
+ * @since 0.10.0
117
117
  */
118
- export function formatReactAuditJsonOutput(result, rootDir) {
118
+ export function formatImportsAuditJsonOutput(result, rootDir) {
119
119
  return JSON.stringify({
120
120
  schemaVersion: 1,
121
121
  ok: result.violationCount === 0,
@@ -0,0 +1,70 @@
1
+ import { AppError } from "#/core/errors";
2
+ import type { FilesystemPort } from "#/core/filesystem/port";
3
+ import type { Result } from "#/core/result";
4
+ /**
5
+ * Shared prelude for `audit rtl`: repo root and the canonicalized scan target with its allowlist.
6
+ *
7
+ * @since 0.5.0-canary.6
8
+ */
9
+ export type RtlAuditCommandPrelude = {
10
+ readonly rootDir: string;
11
+ readonly targetPath: string;
12
+ readonly allowlist: ReadonlyArray<string>;
13
+ };
14
+ /**
15
+ * Loads config and resolves the scan target for `audit rtl`.
16
+ *
17
+ * @since 0.5.0-canary.6
18
+ */
19
+ export declare function prepareRtlAudit(fs: FilesystemPort, args: {
20
+ readonly currentWorkingDirectory: string;
21
+ readonly rawTarget: string | undefined;
22
+ }): Promise<Result<RtlAuditCommandPrelude, AppError>>;
23
+ /**
24
+ * Loads config and resolves the scan target for `audit links`.
25
+ *
26
+ * @remarks Defaults to the repo root rather than a configured path: a link audit that only covers one
27
+ * package cannot see the cross-package references that are the ones most likely to rot.
28
+ *
29
+ * @since 0.5.0
30
+ */
31
+ export declare function prepareLinkAudit(fs: FilesystemPort, args: {
32
+ readonly currentWorkingDirectory: string;
33
+ readonly rawTarget: string | undefined;
34
+ }): Promise<Result<RtlAuditCommandPrelude, AppError>>;
35
+ /**
36
+ * Loads config and resolves the scan target for `audit imports`.
37
+ *
38
+ * @remarks Defaults to the repo root: the import policy is repo-wide, and generated or vendored
39
+ * trees are already excluded by the shared walk.
40
+ *
41
+ * @since 0.10.0
42
+ */
43
+ export declare function prepareImportsAudit(fs: FilesystemPort, args: {
44
+ readonly currentWorkingDirectory: string;
45
+ readonly rawTarget: string | undefined;
46
+ }): Promise<Result<RtlAuditCommandPrelude, AppError>>;
47
+ /**
48
+ * Loads config and resolves the scan target for `audit comments`.
49
+ *
50
+ * @remarks Defaults to the repo root: a divider convention that only holds inside one package
51
+ * is not a convention.
52
+ *
53
+ * @since 0.6.0
54
+ */
55
+ export declare function prepareCommentAudit(fs: FilesystemPort, args: {
56
+ readonly currentWorkingDirectory: string;
57
+ readonly rawTarget: string | undefined;
58
+ }): Promise<Result<RtlAuditCommandPrelude, AppError>>;
59
+ /**
60
+ * Loads config and resolves the scan target for `audit display-names`.
61
+ *
62
+ * @remarks Defaults to the repo root: a display name collides across packages, so the convention
63
+ * has to hold across them.
64
+ *
65
+ * @since 0.9.0
66
+ */
67
+ export declare function prepareDisplayNameAudit(fs: FilesystemPort, args: {
68
+ readonly currentWorkingDirectory: string;
69
+ readonly rawTarget: string | undefined;
70
+ }): Promise<Result<RtlAuditCommandPrelude, AppError>>;
@@ -2,7 +2,7 @@ import { resolveRepoRelativePath } from "#/audit/cli-schema";
2
2
  import { loadCodefastConfig } from "#/core/config";
3
3
  import { AppError, messageFrom } from "#/core/errors";
4
4
  import { err, ok } from "#/core/result";
5
- import { findRepoRoot } from "#/core/workspace/resolver";
5
+ import { resolveProjectRoot } from "#/core/workspace/resolver";
6
6
  /**
7
7
  * Loads config and resolves the scan target for `audit rtl`.
8
8
  *
@@ -12,7 +12,7 @@ export async function prepareRtlAudit(fs, args) {
12
12
  let rootDir;
13
13
  try {
14
14
  // Realpath so allowlist keys (`path.relative(rootDir, file)`) stay stable when cwd is a symlink.
15
- rootDir = fs.canonicalPathSync(findRepoRoot(args.currentWorkingDirectory, fs));
15
+ rootDir = fs.canonicalPathSync(resolveProjectRoot(args.currentWorkingDirectory, fs).rootDir);
16
16
  }
17
17
  catch (caughtError) {
18
18
  return err(new AppError("INFRA_FAILURE", messageFrom(caughtError), caughtError));
@@ -50,7 +50,7 @@ export async function prepareRtlAudit(fs, args) {
50
50
  export async function prepareLinkAudit(fs, args) {
51
51
  let rootDir;
52
52
  try {
53
- rootDir = fs.canonicalPathSync(findRepoRoot(args.currentWorkingDirectory, fs));
53
+ rootDir = fs.canonicalPathSync(resolveProjectRoot(args.currentWorkingDirectory, fs).rootDir);
54
54
  }
55
55
  catch (caughtError) {
56
56
  return err(new AppError("INFRA_FAILURE", messageFrom(caughtError), caughtError));
@@ -71,17 +71,17 @@ export async function prepareLinkAudit(fs, args) {
71
71
  });
72
72
  }
73
73
  /**
74
- * Loads config and resolves the scan target for `audit react`.
74
+ * Loads config and resolves the scan target for `audit imports`.
75
75
  *
76
76
  * @remarks Defaults to the repo root: the import policy is repo-wide, and generated or vendored
77
77
  * trees are already excluded by the shared walk.
78
78
  *
79
- * @since 0.8.0
79
+ * @since 0.10.0
80
80
  */
81
- export async function prepareReactAudit(fs, args) {
81
+ export async function prepareImportsAudit(fs, args) {
82
82
  let rootDir;
83
83
  try {
84
- rootDir = fs.canonicalPathSync(findRepoRoot(args.currentWorkingDirectory, fs));
84
+ rootDir = fs.canonicalPathSync(resolveProjectRoot(args.currentWorkingDirectory, fs).rootDir);
85
85
  }
86
86
  catch (caughtError) {
87
87
  return err(new AppError("INFRA_FAILURE", messageFrom(caughtError), caughtError));
@@ -90,7 +90,7 @@ export async function prepareReactAudit(fs, args) {
90
90
  if (!loadedOutcome.ok) {
91
91
  return loadedOutcome;
92
92
  }
93
- const reactConfig = loadedOutcome.value.config.audit?.react ?? {};
93
+ const importsConfig = loadedOutcome.value.config.audit?.imports ?? {};
94
94
  const targetPath = args.rawTarget === undefined ? rootDir : resolveRepoRelativePath(args.currentWorkingDirectory, args.rawTarget);
95
95
  if (!fs.existsSync(targetPath)) {
96
96
  return err(new AppError("NOT_FOUND", `Not found: ${targetPath}`));
@@ -98,7 +98,7 @@ export async function prepareReactAudit(fs, args) {
98
98
  return ok({
99
99
  rootDir,
100
100
  targetPath: fs.canonicalPathSync(targetPath),
101
- allowlist: reactConfig.allowlist ?? [],
101
+ allowlist: importsConfig.allowlist ?? [],
102
102
  });
103
103
  }
104
104
  /**
@@ -112,7 +112,7 @@ export async function prepareReactAudit(fs, args) {
112
112
  export async function prepareCommentAudit(fs, args) {
113
113
  let rootDir;
114
114
  try {
115
- rootDir = fs.canonicalPathSync(findRepoRoot(args.currentWorkingDirectory, fs));
115
+ rootDir = fs.canonicalPathSync(resolveProjectRoot(args.currentWorkingDirectory, fs).rootDir);
116
116
  }
117
117
  catch (caughtError) {
118
118
  return err(new AppError("INFRA_FAILURE", messageFrom(caughtError), caughtError));
@@ -143,7 +143,7 @@ export async function prepareCommentAudit(fs, args) {
143
143
  export async function prepareDisplayNameAudit(fs, args) {
144
144
  let rootDir;
145
145
  try {
146
- rootDir = fs.canonicalPathSync(findRepoRoot(args.currentWorkingDirectory, fs));
146
+ rootDir = fs.canonicalPathSync(resolveProjectRoot(args.currentWorkingDirectory, fs).rootDir);
147
147
  }
148
148
  catch (caughtError) {
149
149
  return err(new AppError("INFRA_FAILURE", messageFrom(caughtError), caughtError));
@@ -0,0 +1,17 @@
1
+ import type { CommentAuditResult } from "#/audit/domain/types";
2
+ import { AppError } from "#/core/errors";
3
+ import type { FilesystemPort } from "#/core/filesystem/port";
4
+ import type { Result } from "#/core/result";
5
+ /**
6
+ * Reports every comment off the repo's conventions: divider form (which `fix` rewrites), banned
7
+ * content — document pointers, JSDoc types, tag misuse — `{@link}` targets nothing declares, and
8
+ * every diagnostic the official TSDoc parser raises against a doc block's grammar.
9
+ *
10
+ * @since 0.6.0
11
+ */
12
+ export declare function runCommentAudit(fs: FilesystemPort, args: {
13
+ readonly rootDir: string;
14
+ readonly targetPath: string;
15
+ readonly allowlist: ReadonlyArray<string>;
16
+ readonly fix: boolean;
17
+ }): Result<CommentAuditResult, AppError>;
@@ -0,0 +1,14 @@
1
+ import type { DisplayNameAuditResult } from "#/audit/domain/types";
2
+ import { AppError } from "#/core/errors";
3
+ import type { FilesystemPort } from "#/core/filesystem/port";
4
+ import type { Result } from "#/core/result";
5
+ /**
6
+ * Scans a target path for `token()`, `tag()` and module display names that break the convention.
7
+ *
8
+ * @since 0.9.0
9
+ */
10
+ export declare function runDisplayNameAudit(fs: FilesystemPort, args: {
11
+ readonly rootDir: string;
12
+ readonly targetPath: string;
13
+ readonly allowlist: ReadonlyArray<string>;
14
+ }): Result<DisplayNameAuditResult, AppError>;
@@ -0,0 +1,14 @@
1
+ import type { ImportsAuditResult } from "#/audit/domain/types";
2
+ import { AppError } from "#/core/errors";
3
+ import type { FilesystemPort } from "#/core/filesystem/port";
4
+ import type { Result } from "#/core/result";
5
+ /**
6
+ * Scans a target path for import-policy violations, applying each rule only to files in its scope.
7
+ *
8
+ * @since 0.10.0
9
+ */
10
+ export declare function runImportsAudit(fs: FilesystemPort, args: {
11
+ readonly rootDir: string;
12
+ readonly targetPath: string;
13
+ readonly allowlist: ReadonlyArray<string>;
14
+ }): Result<ImportsAuditResult, AppError>;
@@ -1,25 +1,35 @@
1
1
  import path from "node:path";
2
- import { auditReactImportSource } from "#/audit/domain/react-imports";
2
+ import { defaultImportPolicyRules } from "#/audit/domain/import-policy";
3
+ import { auditImportPolicySource } from "#/audit/domain/import-policy";
3
4
  import { AppError, messageFrom } from "#/core/errors";
5
+ import { createAnyGlobMatcher } from "#/core/glob";
4
6
  import { err, ok } from "#/core/result";
5
7
  import { walkTsxFiles } from "#/core/workspace/typescript-walk";
6
8
  /**
7
- * Scans a target path for React import-policy violations.
9
+ * Scans a target path for import-policy violations, applying each rule only to files in its scope.
8
10
  *
9
- * @since 0.8.0
11
+ * @since 0.10.0
10
12
  */
11
- export function runReactAudit(fs, args) {
13
+ export function runImportsAudit(fs, args) {
12
14
  try {
13
15
  const allowlist = new Set(args.allowlist);
14
16
  const { rootDir, targetPath } = args;
17
+ const scopedRules = defaultImportPolicyRules.map((rule) => ({
18
+ rule,
19
+ isInScope: rule.scope ? createAnyGlobMatcher(rule.scope, { dot: true }) : () => true,
20
+ }));
15
21
  const filesToScan = collectScanPaths(fs, targetPath);
16
22
  const files = [];
17
23
  let violationCount = 0;
18
24
  let allowlistedCount = 0;
19
25
  for (const absolutePath of filesToScan) {
20
26
  const relativePath = toPosixPath(path.relative(rootDir, absolutePath));
27
+ const applicableRules = scopedRules.filter(({ isInScope }) => isInScope(relativePath)).map(({ rule }) => rule);
28
+ if (applicableRules.length === 0) {
29
+ continue;
30
+ }
21
31
  const content = fs.readFileSync(absolutePath, "utf8");
22
- const remaining = auditReactImportSource(absolutePath, content).filter(({ raw }) => {
32
+ const remaining = auditImportPolicySource(absolutePath, content, applicableRules).filter(({ raw }) => {
23
33
  const isAllowed = allowlist.has(raw) || allowlist.has(`${relativePath}:${raw}`);
24
34
  if (isAllowed) {
25
35
  allowlistedCount++;
@@ -0,0 +1,14 @@
1
+ import type { LinkAuditResult } from "#/audit/domain/types";
2
+ import { AppError } from "#/core/errors";
3
+ import type { FilesystemPort } from "#/core/filesystem/port";
4
+ import type { Result } from "#/core/result";
5
+ /**
6
+ * Reports markdown links that point at nothing — a missing path, or an anchor the target does not offer.
7
+ *
8
+ * @since 0.5.0
9
+ */
10
+ export declare function runLinkAudit(fs: FilesystemPort, args: {
11
+ readonly rootDir: string;
12
+ readonly targetPath: string;
13
+ readonly allowlist: ReadonlyArray<string>;
14
+ }): Result<LinkAuditResult, AppError>;