@codefast/cli 0.10.0 → 0.12.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 (303) hide show
  1. package/CHANGELOG.md +84 -0
  2. package/README.md +66 -41
  3. package/dist/arrange/command.js +99 -136
  4. package/dist/arrange/domain/ast/collectors-cn.d.ts +2 -2
  5. package/dist/arrange/domain/ast/collectors-cn.js +2 -2
  6. package/dist/arrange/domain/ast/collectors-jsx.d.ts +2 -2
  7. package/dist/arrange/domain/ast/collectors-jsx.js +1 -1
  8. package/dist/arrange/domain/ast/collectors-tv.d.ts +2 -2
  9. package/dist/arrange/domain/ast/collectors-tv.js +5 -5
  10. package/dist/arrange/domain/ast/helpers.d.ts +2 -2
  11. package/dist/arrange/domain/ast/helpers.js +3 -4
  12. package/dist/arrange/domain/ast/simplify-targets.d.ts +1 -1
  13. package/dist/arrange/domain/ast/simplify-targets.js +23 -28
  14. package/dist/arrange/domain/ast/targets.d.ts +2 -2
  15. package/dist/arrange/domain/ast/targets.js +9 -9
  16. package/dist/arrange/{typescript-ast-translator.d.ts → domain/ast/translator.d.ts} +6 -5
  17. package/dist/arrange/{typescript-ast-translator.js → domain/ast/translator.js} +20 -23
  18. package/dist/arrange/domain/constants.d.ts +1 -1
  19. package/dist/arrange/domain/grouping-service.d.ts +2 -2
  20. package/dist/arrange/domain/grouping-service.js +3 -3
  21. package/dist/arrange/domain/grouping.js +3 -3
  22. package/dist/arrange/domain/imports.d.ts +1 -1
  23. package/dist/arrange/domain/imports.js +2 -2
  24. package/dist/arrange/domain/source-text-formatters.js +1 -1
  25. package/dist/arrange/domain/tailwind-token.js +1 -1
  26. package/dist/arrange/domain/token-classifier.d.ts +1 -1
  27. package/dist/arrange/domain/token-classifier.js +2 -2
  28. package/dist/arrange/domain/types.d.ts +3 -3
  29. package/dist/arrange/group/cli-result.d.ts +7 -0
  30. package/dist/arrange/group/cli-result.js +12 -0
  31. package/dist/arrange/group/cli-schema.d.ts +17 -0
  32. package/dist/arrange/group/cli-schema.js +13 -0
  33. package/dist/arrange/group/output.d.ts +7 -0
  34. package/dist/arrange/group/output.js +10 -0
  35. package/dist/arrange/group/suggest.d.ts +8 -0
  36. package/dist/arrange/{suggest.js → group/suggest.js} +2 -2
  37. package/dist/arrange/inspect/cli-result.d.ts +7 -0
  38. package/dist/arrange/inspect/cli-result.js +8 -0
  39. package/dist/arrange/inspect/cli-schema.d.ts +15 -0
  40. package/dist/arrange/inspect/cli-schema.js +9 -0
  41. package/dist/arrange/{domain → inspect/domain}/analyze-service.d.ts +2 -2
  42. package/dist/arrange/{domain → inspect/domain}/analyze-service.js +7 -7
  43. package/dist/arrange/inspect/output.d.ts +7 -0
  44. package/dist/arrange/inspect/output.js +42 -0
  45. package/dist/arrange/inspect/run.d.ts +10 -0
  46. package/dist/arrange/{analyze.js → inspect/run.js} +7 -7
  47. package/dist/arrange/prepare.d.ts +13 -0
  48. package/dist/arrange/{workspace.js → prepare.js} +9 -12
  49. package/dist/arrange/regroup/cli-result.d.ts +13 -0
  50. package/dist/arrange/regroup/cli-result.js +23 -0
  51. package/dist/arrange/regroup/cli-schema.d.ts +20 -0
  52. package/dist/arrange/regroup/cli-schema.js +14 -0
  53. package/dist/arrange/regroup/output.d.ts +14 -0
  54. package/dist/arrange/regroup/output.js +72 -0
  55. package/dist/arrange/{process-file.d.ts → regroup/process-file.d.ts} +3 -3
  56. package/dist/arrange/{process-file.js → regroup/process-file.js} +3 -3
  57. package/dist/arrange/regroup/run.d.ts +11 -0
  58. package/dist/arrange/{sync.js → regroup/run.js} +5 -5
  59. package/dist/arrange/resolve-target.d.ts +2 -2
  60. package/dist/arrange/resolve-target.js +2 -2
  61. package/dist/arrange/scan-target.d.ts +2 -2
  62. package/dist/arrange/scan-target.js +3 -3
  63. package/dist/arrange/simplify/cli-result.d.ts +7 -0
  64. package/dist/arrange/simplify/cli-result.js +8 -0
  65. package/dist/arrange/simplify/cli-schema.d.ts +17 -0
  66. package/dist/arrange/simplify/cli-schema.js +11 -0
  67. package/dist/arrange/simplify/fold-targets.d.ts +13 -0
  68. package/dist/arrange/simplify/fold-targets.js +139 -0
  69. package/dist/arrange/simplify/output.d.ts +7 -0
  70. package/dist/arrange/simplify/output.js +15 -0
  71. package/dist/arrange/simplify/process-file.d.ts +13 -0
  72. package/dist/arrange/simplify/process-file.js +49 -0
  73. package/dist/arrange/simplify/run.d.ts +14 -0
  74. package/dist/arrange/simplify/run.js +38 -0
  75. package/dist/arrange/simplify/variant-classname-probe.d.ts +35 -0
  76. package/dist/arrange/simplify/variant-classname-probe.js +95 -0
  77. package/dist/arrange/source-parse.d.ts +1 -1
  78. package/dist/arrange/source-parse.js +3 -3
  79. package/dist/audit/command.js +152 -212
  80. package/dist/audit/comments/cli-result.d.ts +13 -0
  81. package/dist/audit/comments/cli-result.js +22 -0
  82. package/dist/audit/comments/cli-schema.d.ts +19 -0
  83. package/dist/audit/comments/cli-schema.js +13 -0
  84. package/dist/audit/comments/output.d.ts +7 -0
  85. package/dist/audit/comments/output.js +27 -0
  86. package/dist/audit/comments/prepare.d.ts +16 -0
  87. package/dist/audit/comments/prepare.js +12 -0
  88. package/dist/audit/{run-comments.d.ts → comments/run.d.ts} +5 -5
  89. package/dist/audit/{run-comments.js → comments/run.js} +9 -9
  90. package/dist/audit/display-names/cli-result.d.ts +13 -0
  91. package/dist/audit/display-names/cli-result.js +22 -0
  92. package/dist/audit/display-names/cli-schema.d.ts +18 -0
  93. package/dist/audit/display-names/cli-schema.js +12 -0
  94. package/dist/audit/{domain → display-names/domain}/display-names.d.ts +1 -1
  95. package/dist/audit/display-names/output.d.ts +7 -0
  96. package/dist/audit/display-names/output.js +21 -0
  97. package/dist/audit/display-names/prepare.d.ts +16 -0
  98. package/dist/audit/display-names/prepare.js +12 -0
  99. package/dist/audit/display-names/run.d.ts +14 -0
  100. package/dist/audit/{run-display-names.js → display-names/run.js} +5 -5
  101. package/dist/audit/domain/types.d.ts +43 -0
  102. package/dist/audit/imports/cli-result.d.ts +13 -0
  103. package/dist/audit/imports/cli-result.js +22 -0
  104. package/dist/audit/imports/cli-schema.d.ts +18 -0
  105. package/dist/audit/imports/cli-schema.js +12 -0
  106. package/dist/audit/{domain → imports/domain}/import-policy.d.ts +3 -3
  107. package/dist/audit/{domain → imports/domain}/import-policy.js +4 -11
  108. package/dist/audit/imports/output.d.ts +7 -0
  109. package/dist/audit/imports/output.js +21 -0
  110. package/dist/audit/imports/prepare.d.ts +16 -0
  111. package/dist/audit/imports/prepare.js +12 -0
  112. package/dist/audit/imports/run.d.ts +14 -0
  113. package/dist/audit/{run-imports.js → imports/run.js} +6 -6
  114. package/dist/audit/links/cli-result.d.ts +13 -0
  115. package/dist/audit/links/cli-result.js +22 -0
  116. package/dist/audit/links/cli-schema.d.ts +18 -0
  117. package/dist/audit/links/cli-schema.js +12 -0
  118. package/dist/audit/{domain → links/domain}/markdown-links.d.ts +3 -3
  119. package/dist/audit/{domain → links/domain}/markdown-links.js +22 -8
  120. package/dist/audit/links/output.d.ts +7 -0
  121. package/dist/audit/links/output.js +21 -0
  122. package/dist/audit/links/prepare.d.ts +16 -0
  123. package/dist/audit/links/prepare.js +12 -0
  124. package/dist/audit/links/run.d.ts +14 -0
  125. package/dist/audit/{run-links.js → links/run.js} +4 -4
  126. package/dist/audit/prepare.d.ts +13 -52
  127. package/dist/audit/prepare.js +13 -136
  128. package/dist/audit/publish/cli-result.d.ts +13 -0
  129. package/dist/audit/publish/cli-result.js +22 -0
  130. package/dist/audit/publish/cli-schema.d.ts +18 -0
  131. package/dist/audit/publish/cli-schema.js +12 -0
  132. package/dist/audit/publish/domain/legacy-subpath.d.ts +8 -0
  133. package/dist/audit/publish/domain/legacy-subpath.js +22 -0
  134. package/dist/audit/publish/output.d.ts +7 -0
  135. package/dist/audit/publish/output.js +24 -0
  136. package/dist/audit/publish/prepare.d.ts +16 -0
  137. package/dist/audit/publish/prepare.js +12 -0
  138. package/dist/audit/publish/run.d.ts +14 -0
  139. package/dist/audit/publish/run.js +62 -0
  140. package/dist/audit/rtl/cli-result.d.ts +13 -0
  141. package/dist/audit/rtl/cli-result.js +22 -0
  142. package/dist/audit/rtl/cli-schema.d.ts +18 -0
  143. package/dist/audit/rtl/cli-schema.js +12 -0
  144. package/dist/audit/{domain → rtl/domain}/audit-file.d.ts +1 -1
  145. package/dist/audit/{domain → rtl/domain}/audit-file.js +2 -2
  146. package/dist/audit/{domain → rtl/domain}/tokenize.d.ts +1 -1
  147. package/dist/audit/rtl/output.d.ts +7 -0
  148. package/dist/audit/rtl/output.js +21 -0
  149. package/dist/audit/rtl/prepare.d.ts +13 -0
  150. package/dist/audit/rtl/prepare.js +41 -0
  151. package/dist/audit/rtl/run.d.ts +14 -0
  152. package/dist/audit/{run.js → rtl/run.js} +4 -4
  153. package/dist/bin.js +1 -1
  154. package/dist/cli.js +5 -5
  155. package/dist/core/cli/command-pipeline.d.ts +90 -0
  156. package/dist/core/cli/command-pipeline.js +83 -0
  157. package/dist/core/cli/format-error.d.ts +1 -1
  158. package/dist/core/cli/global-options.d.ts +1 -1
  159. package/dist/core/cli/global-options.js +1 -1
  160. package/dist/core/cli/resolve-root.d.ts +9 -0
  161. package/dist/core/cli/resolve-root.js +16 -0
  162. package/dist/core/cli/result-handle.d.ts +3 -9
  163. package/dist/core/cli/result-handle.js +4 -17
  164. package/dist/core/config/define-config.d.ts +1 -1
  165. package/dist/core/config/loader.d.ts +3 -3
  166. package/dist/core/config/loader.js +2 -2
  167. package/dist/core/config/schema.d.ts +1 -1
  168. package/dist/core/config/schema.js +1 -1
  169. package/dist/core/config/warnings.js +1 -1
  170. package/dist/core/config.d.ts +5 -5
  171. package/dist/core/config.js +4 -4
  172. package/dist/core/filesystem/{port.d.ts → filesystem.d.ts} +1 -1
  173. package/dist/core/filesystem/node.d.ts +3 -3
  174. package/dist/core/filesystem/node.js +1 -1
  175. package/dist/core/schema-parse.d.ts +2 -2
  176. package/dist/core/schema-parse.js +2 -2
  177. package/dist/core/source-text-edit.d.ts +14 -0
  178. package/dist/core/source-text-edit.js +22 -0
  179. package/dist/core/workspace/markdown-walk.d.ts +2 -2
  180. package/dist/core/workspace/markdown-walk.js +1 -1
  181. package/dist/core/workspace/package-version.d.ts +2 -2
  182. package/dist/core/workspace/package-version.js +2 -2
  183. package/dist/core/workspace/resolver.d.ts +3 -3
  184. package/dist/core/workspace/resolver.js +5 -5
  185. package/dist/core/workspace/source-walk.d.ts +2 -2
  186. package/dist/core/workspace/source-walk.js +1 -1
  187. package/dist/core/workspace/typescript-walk.d.ts +2 -2
  188. package/dist/core/workspace/typescript-walk.js +1 -1
  189. package/dist/core/workspace/walk-files.d.ts +2 -2
  190. package/dist/core/workspace/walk-files.js +1 -1
  191. package/dist/index.d.ts +3 -3
  192. package/dist/index.js +2 -2
  193. package/dist/mirror/cli-result.d.ts +1 -1
  194. package/dist/mirror/cli-result.js +1 -1
  195. package/dist/mirror/cli-schema.d.ts +2 -2
  196. package/dist/mirror/cli-schema.js +1 -1
  197. package/dist/mirror/command.js +36 -65
  198. package/dist/mirror/dist-filesystem-node.d.ts +8 -0
  199. package/dist/mirror/{dist-filesystem-impl.js → dist-filesystem-node.js} +3 -3
  200. package/dist/mirror/domain/dirent-guard.d.ts +1 -1
  201. package/dist/mirror/domain/exports.d.ts +2 -2
  202. package/dist/mirror/domain/exports.js +1 -1
  203. package/dist/mirror/domain/types.d.ts +59 -2
  204. package/dist/mirror/output.d.ts +1 -3
  205. package/dist/mirror/output.js +127 -2
  206. package/dist/mirror/package-path.d.ts +5 -5
  207. package/dist/mirror/package-path.js +3 -3
  208. package/dist/mirror/prepare.d.ts +6 -6
  209. package/dist/mirror/prepare.js +8 -12
  210. package/dist/mirror/run.d.ts +12 -0
  211. package/dist/mirror/{sync.js → run.js} +7 -7
  212. package/dist/mirror/supplement-exports.d.ts +3 -3
  213. package/dist/mirror/supplement-exports.js +2 -2
  214. package/dist/mirror/sync-workspace-package.d.ts +4 -4
  215. package/dist/mirror/sync-workspace-package.js +11 -14
  216. package/dist/mirror/write-exports.d.ts +3 -3
  217. package/dist/mirror/write-exports.js +3 -3
  218. package/dist/pack-slim/cli-result.d.ts +1 -1
  219. package/dist/pack-slim/cli-result.js +1 -1
  220. package/dist/pack-slim/cli-schema.d.ts +1 -1
  221. package/dist/pack-slim/cli-schema.js +1 -1
  222. package/dist/pack-slim/command.js +36 -71
  223. package/dist/pack-slim/domain/transform.d.ts +22 -1
  224. package/dist/pack-slim/domain/transform.js +65 -8
  225. package/dist/pack-slim/output.d.ts +1 -1
  226. package/dist/pack-slim/output.js +1 -1
  227. package/dist/pack-slim/prepare.d.ts +21 -0
  228. package/dist/pack-slim/prepare.js +14 -0
  229. package/dist/pack-slim/{sync.d.ts → run.d.ts} +6 -6
  230. package/dist/pack-slim/{sync.js → run.js} +5 -5
  231. package/dist/pack-slim/working-tree.d.ts +2 -2
  232. package/dist/pack-slim/working-tree.js +2 -2
  233. package/dist/tag/cli-result.d.ts +8 -2
  234. package/dist/tag/cli-result.js +15 -2
  235. package/dist/tag/cli-schema.d.ts +4 -4
  236. package/dist/tag/cli-schema.js +3 -4
  237. package/dist/tag/command.js +34 -61
  238. package/dist/tag/domain/skip-filter.d.ts +13 -0
  239. package/dist/tag/domain/skip-filter.js +29 -0
  240. package/dist/tag/domain/types.d.ts +22 -2
  241. package/dist/tag/domain/version-summary.d.ts +13 -0
  242. package/dist/tag/domain/version-summary.js +24 -0
  243. package/dist/tag/output.d.ts +4 -4
  244. package/dist/tag/output.js +7 -10
  245. package/dist/tag/prepare.d.ts +5 -5
  246. package/dist/tag/prepare.js +5 -5
  247. package/dist/tag/run.d.ts +10 -0
  248. package/dist/tag/{sync.js → run.js} +23 -53
  249. package/dist/tag/target/candidates.d.ts +8 -0
  250. package/dist/tag/{target-candidates.js → target/candidates.js} +3 -3
  251. package/dist/tag/{resolve-target-path.d.ts → target/resolve-path.d.ts} +2 -2
  252. package/dist/tag/target/runner.d.ts +8 -0
  253. package/dist/tag/{target-runner.js → target/runner.js} +3 -3
  254. package/dist/tag/{since-writer.d.ts → writer/since-writer.d.ts} +3 -3
  255. package/dist/tag/{since-writer.js → writer/since-writer.js} +1 -1
  256. package/dist/tag/{version-resolver.d.ts → writer/version-resolver.d.ts} +2 -2
  257. package/dist/tag/{version-resolver.js → writer/version-resolver.js} +1 -1
  258. package/package.json +15 -7
  259. package/dist/arrange/analyze.d.ts +0 -10
  260. package/dist/arrange/cli-schema.d.ts +0 -50
  261. package/dist/arrange/cli-schema.js +0 -34
  262. package/dist/arrange/output.d.ts +0 -26
  263. package/dist/arrange/output.js +0 -127
  264. package/dist/arrange/simplify-process-file.d.ts +0 -11
  265. package/dist/arrange/simplify-process-file.js +0 -30
  266. package/dist/arrange/simplify-sync.d.ts +0 -13
  267. package/dist/arrange/simplify-sync.js +0 -30
  268. package/dist/arrange/suggest.d.ts +0 -8
  269. package/dist/arrange/sync.d.ts +0 -11
  270. package/dist/arrange/workspace.d.ts +0 -13
  271. package/dist/audit/cli-schema.d.ts +0 -93
  272. package/dist/audit/cli-schema.js +0 -66
  273. package/dist/audit/output.d.ts +0 -91
  274. package/dist/audit/output.js +0 -213
  275. package/dist/audit/run-display-names.d.ts +0 -14
  276. package/dist/audit/run-imports.d.ts +0 -14
  277. package/dist/audit/run-links.d.ts +0 -14
  278. package/dist/audit/run.d.ts +0 -14
  279. package/dist/mirror/dist-filesystem-impl.d.ts +0 -8
  280. package/dist/mirror/sync-reporter.d.ts +0 -60
  281. package/dist/mirror/sync-reporter.js +0 -128
  282. package/dist/mirror/sync-types.d.ts +0 -43
  283. package/dist/mirror/sync-types.js +0 -1
  284. package/dist/mirror/sync.d.ts +0 -12
  285. package/dist/tag/sync.d.ts +0 -42
  286. package/dist/tag/target-candidates.d.ts +0 -8
  287. package/dist/tag/target-runner.d.ts +0 -8
  288. /package/dist/audit/{domain → comments/domain}/comment-content.d.ts +0 -0
  289. /package/dist/audit/{domain → comments/domain}/comment-content.js +0 -0
  290. /package/dist/audit/{domain → comments/domain}/comment-dividers.d.ts +0 -0
  291. /package/dist/audit/{domain → comments/domain}/comment-dividers.js +0 -0
  292. /package/dist/audit/{domain → comments/domain}/link-references.d.ts +0 -0
  293. /package/dist/audit/{domain → comments/domain}/link-references.js +0 -0
  294. /package/dist/audit/{domain → comments/domain}/since-versions.d.ts +0 -0
  295. /package/dist/audit/{domain → comments/domain}/since-versions.js +0 -0
  296. /package/dist/audit/{domain → comments/domain}/tsdoc-syntax.d.ts +0 -0
  297. /package/dist/audit/{domain → comments/domain}/tsdoc-syntax.js +0 -0
  298. /package/dist/audit/{domain → display-names/domain}/display-names.js +0 -0
  299. /package/dist/audit/{domain → rtl/domain}/mappings.d.ts +0 -0
  300. /package/dist/audit/{domain → rtl/domain}/mappings.js +0 -0
  301. /package/dist/audit/{domain → rtl/domain}/tokenize.js +0 -0
  302. /package/dist/core/filesystem/{port.js → filesystem.js} +0 -0
  303. /package/dist/tag/{resolve-target-path.js → target/resolve-path.js} +0 -0
@@ -1,7 +1,7 @@
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";
1
+ import type { CommentAuditResult } from "#audit/domain/types";
2
+ import { AppError } from "#core/errors";
3
+ import type { Filesystem } from "#core/filesystem/filesystem";
4
+ import type { Result } from "#core/result";
5
5
  /**
6
6
  * Reports every comment off the repo's conventions: divider form (which `fix` rewrites), banned
7
7
  * content — document pointers, JSDoc types, tag misuse — `{@link}` targets nothing declares, and
@@ -9,7 +9,7 @@ import type { Result } from "#/core/result";
9
9
  *
10
10
  * @since 0.6.0
11
11
  */
12
- export declare function runCommentAudit(fs: FilesystemPort, args: {
12
+ export declare function runCommentAudit(fs: Filesystem, args: {
13
13
  readonly rootDir: string;
14
14
  readonly targetPath: string;
15
15
  readonly allowlist: ReadonlyArray<string>;
@@ -1,13 +1,13 @@
1
1
  import path from "node:path";
2
- import { scanCommentContent } from "#/audit/domain/comment-content";
3
- import { applyCommentDividerFixes, DIVIDER_COLUMN, scanCommentDividers } from "#/audit/domain/comment-dividers";
4
- import { countHeadMentions, isPathLinkTarget, linkTargetHead, scanLinkReferences, } from "#/audit/domain/link-references";
5
- import { scanImpossibleSinceTags } from "#/audit/domain/since-versions";
6
- import { scanTsdocSyntax } from "#/audit/domain/tsdoc-syntax";
7
- import { AppError, messageFrom } from "#/core/errors";
8
- import { err, ok } from "#/core/result";
9
- import { findNearestPackageVersion } from "#/core/workspace/package-version";
10
- import { sourceCommentLanguage, walkSourceFiles } from "#/core/workspace/source-walk";
2
+ import { scanCommentContent } from "#audit/comments/domain/comment-content";
3
+ import { applyCommentDividerFixes, DIVIDER_COLUMN, scanCommentDividers } from "#audit/comments/domain/comment-dividers";
4
+ import { countHeadMentions, isPathLinkTarget, linkTargetHead, scanLinkReferences, } from "#audit/comments/domain/link-references";
5
+ import { scanImpossibleSinceTags } from "#audit/comments/domain/since-versions";
6
+ import { scanTsdocSyntax } from "#audit/comments/domain/tsdoc-syntax";
7
+ import { AppError, messageFrom } from "#core/errors";
8
+ import { err, ok } from "#core/result";
9
+ import { findNearestPackageVersion } from "#core/workspace/package-version";
10
+ import { sourceCommentLanguage, walkSourceFiles } from "#core/workspace/source-walk";
11
11
  const reasonByDefect = {
12
12
  "bad-width": `rule does not end at column ${DIVIDER_COLUMN}`,
13
13
  "dead-link": "{@link} target has no mention outside links — likely renamed",
@@ -0,0 +1,13 @@
1
+ import type { DisplayNameAuditResult } from "#audit/domain/types";
2
+ /**
3
+ * Exit `1` when any non-allowlisted display-name violation remains.
4
+ *
5
+ * @since 0.9.0
6
+ */
7
+ export declare function exitCodeForDisplayNameAuditResult(result: DisplayNameAuditResult): number;
8
+ /**
9
+ * Machine-readable display-name summary for `--json`.
10
+ *
11
+ * @since 0.9.0
12
+ */
13
+ export declare function formatDisplayNameAuditJsonOutput(result: DisplayNameAuditResult, rootDir: string): string;
@@ -0,0 +1,22 @@
1
+ import { CLI_EXIT_GENERAL_ERROR, CLI_EXIT_SUCCESS } from "#core/exit-codes";
2
+ /**
3
+ * Exit `1` when any non-allowlisted display-name violation remains.
4
+ *
5
+ * @since 0.9.0
6
+ */
7
+ export function exitCodeForDisplayNameAuditResult(result) {
8
+ return result.violationCount > 0 ? CLI_EXIT_GENERAL_ERROR : CLI_EXIT_SUCCESS;
9
+ }
10
+ /**
11
+ * Machine-readable display-name summary for `--json`.
12
+ *
13
+ * @since 0.9.0
14
+ */
15
+ export function formatDisplayNameAuditJsonOutput(result, rootDir) {
16
+ return JSON.stringify({
17
+ schemaVersion: 1,
18
+ ok: result.violationCount === 0,
19
+ cwd: rootDir,
20
+ result,
21
+ });
22
+ }
@@ -0,0 +1,18 @@
1
+ import * as z from "zod";
2
+ /**
3
+ * Resolved request for a single display-name audit run.
4
+ *
5
+ * @since 0.9.0
6
+ */
7
+ export type DisplayNameAuditRunRequest = {
8
+ readonly rootDir: string;
9
+ readonly targetPath: string;
10
+ readonly allowlist?: ReadonlyArray<string> | undefined;
11
+ readonly json: boolean;
12
+ };
13
+ /**
14
+ * Zod schema for {@link DisplayNameAuditRunRequest}.
15
+ *
16
+ * @since 0.9.0
17
+ */
18
+ export declare const displayNameAuditRunRequestSchema: z.ZodType<DisplayNameAuditRunRequest>;
@@ -0,0 +1,12 @@
1
+ import * as z from "zod";
2
+ /**
3
+ * Zod schema for {@link DisplayNameAuditRunRequest}.
4
+ *
5
+ * @since 0.9.0
6
+ */
7
+ export const displayNameAuditRunRequestSchema = z.object({
8
+ rootDir: z.string().min(1),
9
+ targetPath: z.string().min(1),
10
+ allowlist: z.array(z.string()).optional(),
11
+ json: z.boolean(),
12
+ });
@@ -1,5 +1,5 @@
1
1
  /** The display-name convention: a name is spelled like the TS symbol it stands for, under its owner's namespace. */
2
- import type { DisplayNameViolation } from "#/audit/domain/types";
2
+ import type { DisplayNameViolation } from "#audit/domain/types";
3
3
  /**
4
4
  * Scans one source or markdown text for `token()`, `tag()` and module display names that break the convention.
5
5
  *
@@ -0,0 +1,7 @@
1
+ import type { DisplayNameAuditResult } from "#audit/domain/types";
2
+ /**
3
+ * Human-readable display-name report.
4
+ *
5
+ * @since 0.9.0
6
+ */
7
+ export declare function presentDisplayNameAuditResult(result: DisplayNameAuditResult): void;
@@ -0,0 +1,21 @@
1
+ import { logger } from "#core/logger";
2
+ /**
3
+ * Human-readable display-name report.
4
+ *
5
+ * @since 0.9.0
6
+ */
7
+ export function presentDisplayNameAuditResult(result) {
8
+ for (const file of result.files) {
9
+ logger.out(`\n${file.relativePath}`);
10
+ for (const { line, raw, reason } of file.violations) {
11
+ logger.out(` ${line}: ${raw} → ${reason}`);
12
+ }
13
+ }
14
+ const allowlistSuffix = result.allowlistedCount > 0 ? ` (${result.allowlistedCount} allowlisted)` : "";
15
+ if (result.violationCount > 0) {
16
+ logger.out(`\n✖ ${result.violationCount} display name(s) off the convention${allowlistSuffix}`);
17
+ }
18
+ else {
19
+ logger.out(`✓ Every token, tag and module display name follows <namespace>:<Name> across ${result.scannedFileCount} file(s)${allowlistSuffix}`);
20
+ }
21
+ }
@@ -0,0 +1,16 @@
1
+ import type { AuditCommandPrelude } from "#audit/prepare";
2
+ import type { AppError } from "#core/errors";
3
+ import type { Filesystem } from "#core/filesystem/filesystem";
4
+ import type { Result } from "#core/result";
5
+ /**
6
+ * Loads config and resolves the scan target for `audit display-names`.
7
+ *
8
+ * @remarks Defaults to the repo root: a display name collides across packages, so the convention
9
+ * has to hold across them.
10
+ *
11
+ * @since 0.9.0
12
+ */
13
+ export declare function prepareDisplayNameAudit(fs: Filesystem, args: {
14
+ readonly currentWorkingDirectory: string;
15
+ readonly rawTarget: string | undefined;
16
+ }): Promise<Result<AuditCommandPrelude, AppError>>;
@@ -0,0 +1,12 @@
1
+ import { prepareRepoRootAudit } from "#audit/prepare";
2
+ /**
3
+ * Loads config and resolves the scan target for `audit display-names`.
4
+ *
5
+ * @remarks Defaults to the repo root: a display name collides across packages, so the convention
6
+ * has to hold across them.
7
+ *
8
+ * @since 0.9.0
9
+ */
10
+ export async function prepareDisplayNameAudit(fs, args) {
11
+ return prepareRepoRootAudit(fs, args, (config) => config.audit?.displayNames?.allowlist ?? []);
12
+ }
@@ -0,0 +1,14 @@
1
+ import type { DisplayNameAuditResult } from "#audit/domain/types";
2
+ import { AppError } from "#core/errors";
3
+ import type { Filesystem } from "#core/filesystem/filesystem";
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: Filesystem, args: {
11
+ readonly rootDir: string;
12
+ readonly targetPath: string;
13
+ readonly allowlist: ReadonlyArray<string>;
14
+ }): Result<DisplayNameAuditResult, AppError>;
@@ -1,9 +1,9 @@
1
1
  import path from "node:path";
2
- import { auditDisplayNames } from "#/audit/domain/display-names";
3
- import { AppError, messageFrom } from "#/core/errors";
4
- import { err, ok } from "#/core/result";
5
- import { walkMarkdownFiles } from "#/core/workspace/markdown-walk";
6
- import { walkTsxFiles } from "#/core/workspace/typescript-walk";
2
+ import { auditDisplayNames } from "#audit/display-names/domain/display-names";
3
+ import { AppError, messageFrom } from "#core/errors";
4
+ import { err, ok } from "#core/result";
5
+ import { walkMarkdownFiles } from "#core/workspace/markdown-walk";
6
+ import { walkTsxFiles } from "#core/workspace/typescript-walk";
7
7
  /**
8
8
  * Trees the convention does not reach: a test or benchmark token is scoped by its file and never
9
9
  * meets another author's, and a changelog quotes names as they were.
@@ -168,4 +168,47 @@ export type CommentAuditResult = {
168
168
  readonly fixedCount: number;
169
169
  readonly dividerCount: number;
170
170
  readonly scannedFileCount: number;
171
+ };
172
+ /**
173
+ * A `#/`-prefixed internal import specifier — valid to the in-repo runners but rejected by Node's ESM
174
+ * resolver on the supported floor, so it breaks the published package.
175
+ *
176
+ * @since 0.12.0
177
+ */
178
+ export type LegacySubpathImport = {
179
+ readonly line: number;
180
+ /** The specifier as written, quotes included. */
181
+ readonly raw: string;
182
+ };
183
+ /**
184
+ * The `#/` imports found in one source file.
185
+ *
186
+ * @since 0.12.0
187
+ */
188
+ export type LegacySubpathFile = {
189
+ readonly relativePath: string;
190
+ readonly imports: Array<LegacySubpathImport>;
191
+ };
192
+ /**
193
+ * A published package whose slimmed manifest exports or imports a target it does not ship.
194
+ *
195
+ * @since 0.12.0
196
+ */
197
+ export type UnshippedTargetViolation = {
198
+ readonly packageName: string;
199
+ readonly field: string;
200
+ readonly subpath: string;
201
+ readonly target: string;
202
+ };
203
+ /**
204
+ * Outcome of one `audit publish` run.
205
+ *
206
+ * @since 0.12.0
207
+ */
208
+ export type PublishAuditResult = {
209
+ readonly legacyImportFiles: Array<LegacySubpathFile>;
210
+ readonly unshipped: Array<UnshippedTargetViolation>;
211
+ readonly legacyImportCount: number;
212
+ readonly scannedFileCount: number;
213
+ readonly packageCount: number;
171
214
  };
@@ -0,0 +1,13 @@
1
+ import type { ImportsAuditResult } from "#audit/domain/types";
2
+ /**
3
+ * Exit `1` when any non-allowlisted import-policy violation remains.
4
+ *
5
+ * @since 0.10.0
6
+ */
7
+ export declare function exitCodeForImportsAuditResult(result: ImportsAuditResult): number;
8
+ /**
9
+ * Machine-readable import-policy summary for `--json`.
10
+ *
11
+ * @since 0.10.0
12
+ */
13
+ export declare function formatImportsAuditJsonOutput(result: ImportsAuditResult, rootDir: string): string;
@@ -0,0 +1,22 @@
1
+ import { CLI_EXIT_GENERAL_ERROR, CLI_EXIT_SUCCESS } from "#core/exit-codes";
2
+ /**
3
+ * Exit `1` when any non-allowlisted import-policy violation remains.
4
+ *
5
+ * @since 0.10.0
6
+ */
7
+ export function exitCodeForImportsAuditResult(result) {
8
+ return result.violationCount > 0 ? CLI_EXIT_GENERAL_ERROR : CLI_EXIT_SUCCESS;
9
+ }
10
+ /**
11
+ * Machine-readable import-policy summary for `--json`.
12
+ *
13
+ * @since 0.10.0
14
+ */
15
+ export function formatImportsAuditJsonOutput(result, rootDir) {
16
+ return JSON.stringify({
17
+ schemaVersion: 1,
18
+ ok: result.violationCount === 0,
19
+ cwd: rootDir,
20
+ result,
21
+ });
22
+ }
@@ -0,0 +1,18 @@
1
+ import * as z from "zod";
2
+ /**
3
+ * Resolved request for a single import-policy audit run.
4
+ *
5
+ * @since 0.10.0
6
+ */
7
+ export type ImportsAuditRunRequest = {
8
+ readonly rootDir: string;
9
+ readonly targetPath: string;
10
+ readonly allowlist?: ReadonlyArray<string> | undefined;
11
+ readonly json: boolean;
12
+ };
13
+ /**
14
+ * Zod schema for {@link ImportsAuditRunRequest}.
15
+ *
16
+ * @since 0.10.0
17
+ */
18
+ export declare const importsAuditRunRequestSchema: z.ZodType<ImportsAuditRunRequest>;
@@ -0,0 +1,12 @@
1
+ import * as z from "zod";
2
+ /**
3
+ * Zod schema for {@link ImportsAuditRunRequest}.
4
+ *
5
+ * @since 0.10.0
6
+ */
7
+ export const importsAuditRunRequestSchema = z.object({
8
+ rootDir: z.string().min(1),
9
+ targetPath: z.string().min(1),
10
+ allowlist: z.array(z.string()).optional(),
11
+ json: z.boolean(),
12
+ });
@@ -1,4 +1,4 @@
1
- import type { ImportPolicyViolation } from "#/audit/domain/types";
1
+ import type { ImportPolicyViolation } from "#audit/domain/types";
2
2
  /**
3
3
  * One library's import policy: which forms of importing `module` are banned, optionally limited to
4
4
  * files whose repo-relative path matches `scope`, plus an optional UMD-global name to flag when the
@@ -16,8 +16,8 @@ export interface ImportPolicyRule {
16
16
  }
17
17
  /**
18
18
  * The import policies enforced across the monorepo: React members by name (never a namespace,
19
- * default, or implicit `React.*` UMD global), and Zod as a namespace in front-end packages so
20
- * bundlers can tree-shake it (a named `import { z }` pins Zod's full locale set into the bundle).
19
+ * default, or implicit `React.*` UMD global), and Zod as a namespace repo-wide — the house form,
20
+ * so a named `import { z }` never pins Zod's full locale set into a package that ships bundled.
21
21
  *
22
22
  * @since 0.10.0
23
23
  */
@@ -1,8 +1,8 @@
1
1
  import { parseSync } from "oxc-parser";
2
2
  /**
3
3
  * The import policies enforced across the monorepo: React members by name (never a namespace,
4
- * default, or implicit `React.*` UMD global), and Zod as a namespace in front-end packages so
5
- * bundlers can tree-shake it (a named `import { z }` pins Zod's full locale set into the bundle).
4
+ * default, or implicit `React.*` UMD global), and Zod as a namespace repo-wide — the house form,
5
+ * so a named `import { z }` never pins Zod's full locale set into a package that ships bundled.
6
6
  *
7
7
  * @since 0.10.0
8
8
  */
@@ -16,15 +16,8 @@ export const defaultImportPolicyRules = [
16
16
  {
17
17
  module: "zod",
18
18
  ban: ["named:z"],
19
- scope: [
20
- "packages/theme/**",
21
- "packages/ui/**",
22
- "packages/tailwind-variants/**",
23
- "apps/web/**",
24
- "examples/*/**",
25
- "internal/benchmark-viewer/**",
26
- ],
27
- message: 'import Zod as a namespace so bundlers can tree-shake it: import * as z from "zod"',
19
+ message: 'import Zod as a namespace: import * as z from "zod" (repo house form; a named import { z } pins Zod\'s full ' +
20
+ "locale set into any bundle that reaches it)",
28
21
  },
29
22
  ];
30
23
  function isOxcNode(value) {
@@ -0,0 +1,7 @@
1
+ import type { ImportsAuditResult } from "#audit/domain/types";
2
+ /**
3
+ * Human-readable import-policy report.
4
+ *
5
+ * @since 0.10.0
6
+ */
7
+ export declare function presentImportsAuditResult(result: ImportsAuditResult): void;
@@ -0,0 +1,21 @@
1
+ import { logger } from "#core/logger";
2
+ /**
3
+ * Human-readable import-policy report.
4
+ *
5
+ * @since 0.10.0
6
+ */
7
+ export function presentImportsAuditResult(result) {
8
+ for (const file of result.files) {
9
+ logger.out(`\n${file.relativePath}`);
10
+ for (const { line, raw, reason } of file.violations) {
11
+ logger.out(` ${line}: ${raw} → ${reason}`);
12
+ }
13
+ }
14
+ const allowlistSuffix = result.allowlistedCount > 0 ? ` (${result.allowlistedCount} allowlisted)` : "";
15
+ if (result.violationCount > 0) {
16
+ logger.out(`\n✖ ${result.violationCount} import-policy violation(s)${allowlistSuffix}`);
17
+ }
18
+ else {
19
+ logger.out(`✓ No import-policy violations across ${result.scannedFileCount} file(s)${allowlistSuffix}`);
20
+ }
21
+ }
@@ -0,0 +1,16 @@
1
+ import type { AuditCommandPrelude } from "#audit/prepare";
2
+ import type { AppError } from "#core/errors";
3
+ import type { Filesystem } from "#core/filesystem/filesystem";
4
+ import type { Result } from "#core/result";
5
+ /**
6
+ * Loads config and resolves the scan target for `audit imports`.
7
+ *
8
+ * @remarks Defaults to the repo root: the import policy is repo-wide, and generated or vendored
9
+ * trees are already excluded by the shared walk.
10
+ *
11
+ * @since 0.10.0
12
+ */
13
+ export declare function prepareImportsAudit(fs: Filesystem, args: {
14
+ readonly currentWorkingDirectory: string;
15
+ readonly rawTarget: string | undefined;
16
+ }): Promise<Result<AuditCommandPrelude, AppError>>;
@@ -0,0 +1,12 @@
1
+ import { prepareRepoRootAudit } from "#audit/prepare";
2
+ /**
3
+ * Loads config and resolves the scan target for `audit imports`.
4
+ *
5
+ * @remarks Defaults to the repo root: the import policy is repo-wide, and generated or vendored
6
+ * trees are already excluded by the shared walk.
7
+ *
8
+ * @since 0.10.0
9
+ */
10
+ export async function prepareImportsAudit(fs, args) {
11
+ return prepareRepoRootAudit(fs, args, (config) => config.audit?.imports?.allowlist ?? []);
12
+ }
@@ -0,0 +1,14 @@
1
+ import type { ImportsAuditResult } from "#audit/domain/types";
2
+ import { AppError } from "#core/errors";
3
+ import type { Filesystem } from "#core/filesystem/filesystem";
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: Filesystem, args: {
11
+ readonly rootDir: string;
12
+ readonly targetPath: string;
13
+ readonly allowlist: ReadonlyArray<string>;
14
+ }): Result<ImportsAuditResult, AppError>;
@@ -1,10 +1,10 @@
1
1
  import path from "node:path";
2
- import { defaultImportPolicyRules } from "#/audit/domain/import-policy";
3
- import { auditImportPolicySource } from "#/audit/domain/import-policy";
4
- import { AppError, messageFrom } from "#/core/errors";
5
- import { createAnyGlobMatcher } from "#/core/glob";
6
- import { err, ok } from "#/core/result";
7
- import { walkTsxFiles } from "#/core/workspace/typescript-walk";
2
+ import { defaultImportPolicyRules } from "#audit/imports/domain/import-policy";
3
+ import { auditImportPolicySource } from "#audit/imports/domain/import-policy";
4
+ import { AppError, messageFrom } from "#core/errors";
5
+ import { createAnyGlobMatcher } from "#core/glob";
6
+ import { err, ok } from "#core/result";
7
+ import { walkTsxFiles } from "#core/workspace/typescript-walk";
8
8
  /**
9
9
  * Scans a target path for import-policy violations, applying each rule only to files in its scope.
10
10
  *
@@ -0,0 +1,13 @@
1
+ import type { LinkAuditResult } from "#audit/domain/types";
2
+ /**
3
+ * Exit `1` when any non-allowlisted broken link remains.
4
+ *
5
+ * @since 0.5.0
6
+ */
7
+ export declare function exitCodeForLinkAuditResult(result: LinkAuditResult): number;
8
+ /**
9
+ * Machine-readable link audit summary for `--json`.
10
+ *
11
+ * @since 0.5.0
12
+ */
13
+ export declare function formatLinkAuditJsonOutput(result: LinkAuditResult, rootDir: string): string;
@@ -0,0 +1,22 @@
1
+ import { CLI_EXIT_GENERAL_ERROR, CLI_EXIT_SUCCESS } from "#core/exit-codes";
2
+ /**
3
+ * Exit `1` when any non-allowlisted broken link remains.
4
+ *
5
+ * @since 0.5.0
6
+ */
7
+ export function exitCodeForLinkAuditResult(result) {
8
+ return result.breakageCount > 0 ? CLI_EXIT_GENERAL_ERROR : CLI_EXIT_SUCCESS;
9
+ }
10
+ /**
11
+ * Machine-readable link audit summary for `--json`.
12
+ *
13
+ * @since 0.5.0
14
+ */
15
+ export function formatLinkAuditJsonOutput(result, rootDir) {
16
+ return JSON.stringify({
17
+ schemaVersion: 1,
18
+ ok: result.breakageCount === 0,
19
+ cwd: rootDir,
20
+ result,
21
+ });
22
+ }
@@ -0,0 +1,18 @@
1
+ import * as z from "zod";
2
+ /**
3
+ * Resolved request for a single link audit run.
4
+ *
5
+ * @since 0.5.0
6
+ */
7
+ export type LinkAuditRunRequest = {
8
+ readonly rootDir: string;
9
+ readonly targetPath: string;
10
+ readonly allowlist?: ReadonlyArray<string> | undefined;
11
+ readonly json: boolean;
12
+ };
13
+ /**
14
+ * Zod schema for {@link LinkAuditRunRequest}.
15
+ *
16
+ * @since 0.5.0
17
+ */
18
+ export declare const linkAuditRunRequestSchema: z.ZodType<LinkAuditRunRequest>;
@@ -0,0 +1,12 @@
1
+ import * as z from "zod";
2
+ /**
3
+ * Zod schema for {@link LinkAuditRunRequest}.
4
+ *
5
+ * @since 0.5.0
6
+ */
7
+ export const linkAuditRunRequestSchema = z.object({
8
+ rootDir: z.string().min(1),
9
+ targetPath: z.string().min(1),
10
+ allowlist: z.array(z.string()).optional(),
11
+ json: z.boolean(),
12
+ });
@@ -25,9 +25,9 @@ export type MarkdownLinkScan = {
25
25
  /**
26
26
  * The anchor ids a rendered document exposes: explicit `<a id>` targets plus every heading's slug.
27
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.
28
+ * @remarks Slugs follow GitHub's own algorithm so a link that resolves on GitHub resolves here.
29
+ * Repeated slugs take a `-1`, `-2`, … suffix in heading order, exactly as GitHub disambiguates them,
30
+ * so a link to the second copy of a heading resolves instead of reading as dangling.
31
31
  *
32
32
  * @since 0.5.0
33
33
  */
@@ -6,9 +6,9 @@ const EXTERNAL = /^(?:[a-z][a-z0-9+.-]*:|\/\/)/i;
6
6
  /**
7
7
  * The anchor ids a rendered document exposes: explicit `<a id>` targets plus every heading's slug.
8
8
  *
9
- * @remarks Slugging matches GitHub's — lowercase, drop everything that is not a letter, number, space
10
- * or hyphen, then hyphenate spaces. Duplicate headings get a `-1` suffix there; this returns the base
11
- * only, so a link to the second copy reads as dangling rather than being silently accepted.
9
+ * @remarks Slugs follow GitHub's own algorithm so a link that resolves on GitHub resolves here.
10
+ * Repeated slugs take a `-1`, `-2`, … suffix in heading order, exactly as GitHub disambiguates them,
11
+ * so a link to the second copy of a heading resolves instead of reading as dangling.
12
12
  *
13
13
  * @since 0.5.0
14
14
  */
@@ -17,15 +17,29 @@ export function collectMarkdownAnchors(content) {
17
17
  for (const match of content.matchAll(/<a\s+id="([^"]+)"\s*><\/a>/g)) {
18
18
  anchors.add(match[1]);
19
19
  }
20
+ const occurrences = new Map();
20
21
  for (const match of content.matchAll(/^#{1,6}\s+(.+?)\s*$/gm)) {
21
- anchors.add(match[1]
22
- .toLowerCase()
23
- .replaceAll(/[^\p{L}\p{N} -]/gu, "")
24
- .trim()
25
- .replaceAll(/\s+/g, "-"));
22
+ const base = slugifyHeading(match[1]);
23
+ let result = base;
24
+ while (occurrences.has(result)) {
25
+ occurrences.set(base, (occurrences.get(base) ?? 0) + 1);
26
+ result = `${base}-${occurrences.get(base)}`;
27
+ }
28
+ occurrences.set(result, 0);
29
+ anchors.add(result);
26
30
  }
27
31
  return anchors;
28
32
  }
33
+ /**
34
+ * A heading's GitHub slug: lowercased, stripped to letters, numbers, marks, underscore and hyphen,
35
+ * with each remaining space turned into a hyphen — runs are kept, not collapsed, matching GitHub.
36
+ */
37
+ function slugifyHeading(heading) {
38
+ return heading
39
+ .toLowerCase()
40
+ .replaceAll(/[^\p{L}\p{N}\p{M} _-]/gu, "")
41
+ .replaceAll(" ", "-");
42
+ }
29
43
  /**
30
44
  * Every repo-local link a document makes, with the anchors it offers.
31
45
  *
@@ -0,0 +1,7 @@
1
+ import type { LinkAuditResult } from "#audit/domain/types";
2
+ /**
3
+ * Human-readable link audit report.
4
+ *
5
+ * @since 0.5.0
6
+ */
7
+ export declare function presentLinkAuditResult(result: LinkAuditResult): void;