@codefast/cli 0.10.0 → 0.11.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 (220) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/README.md +16 -2
  3. package/dist/arrange/command.js +96 -132
  4. package/dist/arrange/domain/ast/simplify-targets.js +18 -23
  5. package/dist/arrange/{typescript-ast-translator.d.ts → domain/ast/translator.d.ts} +5 -4
  6. package/dist/arrange/{typescript-ast-translator.js → domain/ast/translator.js} +19 -22
  7. package/dist/arrange/group/cli-result.d.ts +7 -0
  8. package/dist/arrange/group/cli-result.js +12 -0
  9. package/dist/arrange/group/cli-schema.d.ts +17 -0
  10. package/dist/arrange/group/cli-schema.js +13 -0
  11. package/dist/arrange/group/output.d.ts +7 -0
  12. package/dist/arrange/group/output.js +10 -0
  13. package/dist/arrange/{suggest.d.ts → group/suggest.d.ts} +1 -1
  14. package/dist/arrange/inspect/cli-result.d.ts +7 -0
  15. package/dist/arrange/inspect/cli-result.js +8 -0
  16. package/dist/arrange/inspect/cli-schema.d.ts +15 -0
  17. package/dist/arrange/inspect/cli-schema.js +9 -0
  18. package/dist/arrange/inspect/output.d.ts +7 -0
  19. package/dist/arrange/inspect/output.js +42 -0
  20. package/dist/arrange/{analyze.d.ts → inspect/run.d.ts} +2 -2
  21. package/dist/arrange/{analyze.js → inspect/run.js} +2 -2
  22. package/dist/arrange/{workspace.d.ts → prepare.d.ts} +2 -2
  23. package/dist/arrange/{workspace.js → prepare.js} +5 -8
  24. package/dist/arrange/regroup/cli-result.d.ts +13 -0
  25. package/dist/arrange/regroup/cli-result.js +23 -0
  26. package/dist/arrange/regroup/cli-schema.d.ts +20 -0
  27. package/dist/arrange/regroup/cli-schema.js +14 -0
  28. package/dist/arrange/regroup/output.d.ts +14 -0
  29. package/dist/arrange/regroup/output.js +72 -0
  30. package/dist/arrange/{process-file.d.ts → regroup/process-file.d.ts} +2 -2
  31. package/dist/arrange/{sync.d.ts → regroup/run.d.ts} +3 -3
  32. package/dist/arrange/{sync.js → regroup/run.js} +2 -2
  33. package/dist/arrange/resolve-target.d.ts +2 -2
  34. package/dist/arrange/scan-target.d.ts +2 -2
  35. package/dist/arrange/simplify/cli-result.d.ts +7 -0
  36. package/dist/arrange/simplify/cli-result.js +8 -0
  37. package/dist/arrange/simplify/cli-schema.d.ts +17 -0
  38. package/dist/arrange/simplify/cli-schema.js +11 -0
  39. package/dist/arrange/simplify/fold-targets.d.ts +13 -0
  40. package/dist/arrange/simplify/fold-targets.js +139 -0
  41. package/dist/arrange/simplify/output.d.ts +7 -0
  42. package/dist/arrange/simplify/output.js +15 -0
  43. package/dist/arrange/{simplify-process-file.d.ts → simplify/process-file.d.ts} +4 -2
  44. package/dist/arrange/simplify/process-file.js +49 -0
  45. package/dist/arrange/{simplify-sync.d.ts → simplify/run.d.ts} +3 -2
  46. package/dist/arrange/simplify/run.js +38 -0
  47. package/dist/arrange/simplify/variant-classname-probe.d.ts +35 -0
  48. package/dist/arrange/simplify/variant-classname-probe.js +95 -0
  49. package/dist/arrange/source-parse.js +1 -1
  50. package/dist/audit/command.js +134 -211
  51. package/dist/audit/comments/cli-result.d.ts +13 -0
  52. package/dist/audit/comments/cli-result.js +22 -0
  53. package/dist/audit/comments/cli-schema.d.ts +19 -0
  54. package/dist/audit/comments/cli-schema.js +13 -0
  55. package/dist/audit/comments/output.d.ts +7 -0
  56. package/dist/audit/comments/output.js +27 -0
  57. package/dist/audit/comments/prepare.d.ts +16 -0
  58. package/dist/audit/comments/prepare.js +12 -0
  59. package/dist/audit/{run-comments.d.ts → comments/run.d.ts} +2 -2
  60. package/dist/audit/{run-comments.js → comments/run.js} +5 -5
  61. package/dist/audit/display-names/cli-result.d.ts +13 -0
  62. package/dist/audit/display-names/cli-result.js +22 -0
  63. package/dist/audit/display-names/cli-schema.d.ts +18 -0
  64. package/dist/audit/display-names/cli-schema.js +12 -0
  65. package/dist/audit/display-names/output.d.ts +7 -0
  66. package/dist/audit/display-names/output.js +21 -0
  67. package/dist/audit/display-names/prepare.d.ts +16 -0
  68. package/dist/audit/display-names/prepare.js +12 -0
  69. package/dist/audit/{run-display-names.d.ts → display-names/run.d.ts} +2 -2
  70. package/dist/audit/{run-display-names.js → display-names/run.js} +1 -1
  71. package/dist/audit/imports/cli-result.d.ts +13 -0
  72. package/dist/audit/imports/cli-result.js +22 -0
  73. package/dist/audit/imports/cli-schema.d.ts +18 -0
  74. package/dist/audit/imports/cli-schema.js +12 -0
  75. package/dist/audit/{domain → imports/domain}/import-policy.d.ts +2 -2
  76. package/dist/audit/{domain → imports/domain}/import-policy.js +4 -11
  77. package/dist/audit/imports/output.d.ts +7 -0
  78. package/dist/audit/imports/output.js +21 -0
  79. package/dist/audit/imports/prepare.d.ts +16 -0
  80. package/dist/audit/imports/prepare.js +12 -0
  81. package/dist/audit/{run-imports.d.ts → imports/run.d.ts} +2 -2
  82. package/dist/audit/{run-imports.js → imports/run.js} +2 -2
  83. package/dist/audit/links/cli-result.d.ts +13 -0
  84. package/dist/audit/links/cli-result.js +22 -0
  85. package/dist/audit/links/cli-schema.d.ts +18 -0
  86. package/dist/audit/links/cli-schema.js +12 -0
  87. package/dist/audit/links/output.d.ts +7 -0
  88. package/dist/audit/links/output.js +21 -0
  89. package/dist/audit/links/prepare.d.ts +16 -0
  90. package/dist/audit/links/prepare.js +12 -0
  91. package/dist/audit/{run-links.d.ts → links/run.d.ts} +2 -2
  92. package/dist/audit/{run-links.js → links/run.js} +1 -1
  93. package/dist/audit/prepare.d.ts +11 -50
  94. package/dist/audit/prepare.js +9 -132
  95. package/dist/audit/rtl/cli-result.d.ts +13 -0
  96. package/dist/audit/rtl/cli-result.js +22 -0
  97. package/dist/audit/rtl/cli-schema.d.ts +18 -0
  98. package/dist/audit/rtl/cli-schema.js +12 -0
  99. package/dist/audit/{domain → rtl/domain}/audit-file.js +2 -2
  100. package/dist/audit/rtl/output.d.ts +7 -0
  101. package/dist/audit/rtl/output.js +21 -0
  102. package/dist/audit/rtl/prepare.d.ts +13 -0
  103. package/dist/audit/rtl/prepare.js +41 -0
  104. package/dist/audit/{run.d.ts → rtl/run.d.ts} +2 -2
  105. package/dist/audit/{run.js → rtl/run.js} +1 -1
  106. package/dist/core/cli/command-pipeline.d.ts +91 -0
  107. package/dist/core/cli/command-pipeline.js +83 -0
  108. package/dist/core/cli/global-options.d.ts +1 -1
  109. package/dist/core/cli/global-options.js +1 -1
  110. package/dist/core/cli/resolve-root.d.ts +9 -0
  111. package/dist/core/cli/resolve-root.js +16 -0
  112. package/dist/core/cli/result-handle.d.ts +1 -7
  113. package/dist/core/cli/result-handle.js +0 -13
  114. package/dist/core/config/loader.d.ts +2 -2
  115. package/dist/core/config/schema.d.ts +1 -1
  116. package/dist/core/config/schema.js +1 -1
  117. package/dist/core/config.d.ts +2 -2
  118. package/dist/core/filesystem/{port.d.ts → filesystem.d.ts} +1 -1
  119. package/dist/core/filesystem/node.d.ts +3 -3
  120. package/dist/core/filesystem/node.js +1 -1
  121. package/dist/core/source-text-edit.d.ts +14 -0
  122. package/dist/core/source-text-edit.js +22 -0
  123. package/dist/core/workspace/markdown-walk.d.ts +2 -2
  124. package/dist/core/workspace/package-version.d.ts +2 -2
  125. package/dist/core/workspace/resolver.d.ts +3 -3
  126. package/dist/core/workspace/source-walk.d.ts +2 -2
  127. package/dist/core/workspace/typescript-walk.d.ts +2 -2
  128. package/dist/core/workspace/walk-files.d.ts +2 -2
  129. package/dist/mirror/cli-schema.d.ts +2 -2
  130. package/dist/mirror/cli-schema.js +1 -1
  131. package/dist/mirror/command.js +31 -60
  132. package/dist/mirror/{dist-filesystem-impl.d.ts → dist-filesystem-node.d.ts} +3 -3
  133. package/dist/mirror/{dist-filesystem-impl.js → dist-filesystem-node.js} +1 -1
  134. package/dist/mirror/domain/dirent-guard.d.ts +1 -1
  135. package/dist/mirror/domain/types.d.ts +57 -0
  136. package/dist/mirror/output.d.ts +1 -3
  137. package/dist/mirror/output.js +126 -1
  138. package/dist/mirror/package-path.d.ts +3 -3
  139. package/dist/mirror/prepare.d.ts +3 -3
  140. package/dist/mirror/prepare.js +6 -10
  141. package/dist/mirror/run.d.ts +12 -0
  142. package/dist/mirror/supplement-exports.d.ts +3 -3
  143. package/dist/mirror/sync-workspace-package.d.ts +2 -2
  144. package/dist/mirror/sync-workspace-package.js +1 -1
  145. package/dist/mirror/write-exports.d.ts +2 -2
  146. package/dist/pack-slim/cli-schema.d.ts +1 -1
  147. package/dist/pack-slim/cli-schema.js +1 -1
  148. package/dist/pack-slim/command.js +31 -66
  149. package/dist/pack-slim/prepare.d.ts +21 -0
  150. package/dist/pack-slim/prepare.js +14 -0
  151. package/dist/pack-slim/{sync.d.ts → run.d.ts} +2 -2
  152. package/dist/tag/cli-result.d.ts +8 -2
  153. package/dist/tag/cli-result.js +14 -1
  154. package/dist/tag/cli-schema.d.ts +4 -4
  155. package/dist/tag/cli-schema.js +3 -4
  156. package/dist/tag/command.js +33 -60
  157. package/dist/tag/domain/skip-filter.d.ts +13 -0
  158. package/dist/tag/domain/skip-filter.js +29 -0
  159. package/dist/tag/domain/types.d.ts +21 -1
  160. package/dist/tag/domain/version-summary.d.ts +13 -0
  161. package/dist/tag/domain/version-summary.js +24 -0
  162. package/dist/tag/output.d.ts +4 -4
  163. package/dist/tag/output.js +6 -9
  164. package/dist/tag/prepare.d.ts +2 -2
  165. package/dist/tag/prepare.js +2 -2
  166. package/dist/tag/run.d.ts +10 -0
  167. package/dist/tag/{sync.js → run.js} +20 -50
  168. package/dist/tag/{target-candidates.d.ts → target/candidates.d.ts} +2 -2
  169. package/dist/tag/{target-candidates.js → target/candidates.js} +1 -1
  170. package/dist/tag/{resolve-target-path.d.ts → target/resolve-path.d.ts} +2 -2
  171. package/dist/tag/{target-runner.d.ts → target/runner.d.ts} +2 -2
  172. package/dist/tag/{target-runner.js → target/runner.js} +2 -2
  173. package/dist/tag/{since-writer.d.ts → writer/since-writer.d.ts} +2 -2
  174. package/dist/tag/{version-resolver.d.ts → writer/version-resolver.d.ts} +2 -2
  175. package/package.json +10 -2
  176. package/dist/arrange/cli-schema.d.ts +0 -50
  177. package/dist/arrange/cli-schema.js +0 -34
  178. package/dist/arrange/output.d.ts +0 -26
  179. package/dist/arrange/output.js +0 -127
  180. package/dist/arrange/simplify-process-file.js +0 -30
  181. package/dist/arrange/simplify-sync.js +0 -30
  182. package/dist/audit/cli-schema.d.ts +0 -93
  183. package/dist/audit/cli-schema.js +0 -66
  184. package/dist/audit/output.d.ts +0 -91
  185. package/dist/audit/output.js +0 -213
  186. package/dist/mirror/sync-reporter.d.ts +0 -60
  187. package/dist/mirror/sync-reporter.js +0 -128
  188. package/dist/mirror/sync-types.d.ts +0 -43
  189. package/dist/mirror/sync-types.js +0 -1
  190. package/dist/mirror/sync.d.ts +0 -12
  191. package/dist/tag/sync.d.ts +0 -42
  192. /package/dist/arrange/{suggest.js → group/suggest.js} +0 -0
  193. /package/dist/arrange/{domain → inspect/domain}/analyze-service.d.ts +0 -0
  194. /package/dist/arrange/{domain → inspect/domain}/analyze-service.js +0 -0
  195. /package/dist/arrange/{process-file.js → regroup/process-file.js} +0 -0
  196. /package/dist/audit/{domain → comments/domain}/comment-content.d.ts +0 -0
  197. /package/dist/audit/{domain → comments/domain}/comment-content.js +0 -0
  198. /package/dist/audit/{domain → comments/domain}/comment-dividers.d.ts +0 -0
  199. /package/dist/audit/{domain → comments/domain}/comment-dividers.js +0 -0
  200. /package/dist/audit/{domain → comments/domain}/link-references.d.ts +0 -0
  201. /package/dist/audit/{domain → comments/domain}/link-references.js +0 -0
  202. /package/dist/audit/{domain → comments/domain}/since-versions.d.ts +0 -0
  203. /package/dist/audit/{domain → comments/domain}/since-versions.js +0 -0
  204. /package/dist/audit/{domain → comments/domain}/tsdoc-syntax.d.ts +0 -0
  205. /package/dist/audit/{domain → comments/domain}/tsdoc-syntax.js +0 -0
  206. /package/dist/audit/{domain → display-names/domain}/display-names.d.ts +0 -0
  207. /package/dist/audit/{domain → display-names/domain}/display-names.js +0 -0
  208. /package/dist/audit/{domain → links/domain}/markdown-links.d.ts +0 -0
  209. /package/dist/audit/{domain → links/domain}/markdown-links.js +0 -0
  210. /package/dist/audit/{domain → rtl/domain}/audit-file.d.ts +0 -0
  211. /package/dist/audit/{domain → rtl/domain}/mappings.d.ts +0 -0
  212. /package/dist/audit/{domain → rtl/domain}/mappings.js +0 -0
  213. /package/dist/audit/{domain → rtl/domain}/tokenize.d.ts +0 -0
  214. /package/dist/audit/{domain → rtl/domain}/tokenize.js +0 -0
  215. /package/dist/core/filesystem/{port.js → filesystem.js} +0 -0
  216. /package/dist/mirror/{sync.js → run.js} +0 -0
  217. /package/dist/pack-slim/{sync.js → run.js} +0 -0
  218. /package/dist/tag/{resolve-target-path.js → target/resolve-path.js} +0 -0
  219. /package/dist/tag/{since-writer.js → writer/since-writer.js} +0 -0
  220. /package/dist/tag/{version-resolver.js → writer/version-resolver.js} +0 -0
@@ -1,5 +1,5 @@
1
1
  import type { AppError } from "#/core/errors";
2
- import type { FilesystemPort } from "#/core/filesystem/port";
2
+ import type { Filesystem } from "#/core/filesystem/filesystem";
3
3
  import type { Result } from "#/core/result";
4
4
  import type { TagCommandPrelude } from "#/tag/domain/types";
5
5
  /**
@@ -7,7 +7,7 @@ import type { TagCommandPrelude } from "#/tag/domain/types";
7
7
  *
8
8
  * @since 0.3.16-canary.0
9
9
  */
10
- export declare function prepareTagSync(fs: FilesystemPort, args: {
10
+ export declare function prepareTag(fs: Filesystem, args: {
11
11
  readonly currentWorkingDirectory: string;
12
12
  readonly rawTarget: string | undefined;
13
13
  }): Promise<Result<TagCommandPrelude, AppError>>;
@@ -1,13 +1,13 @@
1
1
  import { loadCodefastConfig } from "#/core/config";
2
2
  import { ok } from "#/core/result";
3
3
  import { resolveProjectRoot } from "#/core/workspace/resolver";
4
- import { resolveProvidedTagTargetPath } from "#/tag/resolve-target-path";
4
+ import { resolveProvidedTagTargetPath } from "#/tag/target/resolve-path";
5
5
  /**
6
6
  * Resolves the repo root, config, and optional target path into the prelude a tag run starts from.
7
7
  *
8
8
  * @since 0.3.16-canary.0
9
9
  */
10
- export async function prepareTagSync(fs, args) {
10
+ export async function prepareTag(fs, args) {
11
11
  let rootDir;
12
12
  try {
13
13
  rootDir = resolveProjectRoot(args.currentWorkingDirectory, fs).rootDir;
@@ -0,0 +1,10 @@
1
+ import { AppError } from "#/core/errors";
2
+ import type { Filesystem } from "#/core/filesystem/filesystem";
3
+ import type { Result } from "#/core/result";
4
+ import type { TagExecutionInput, TagResult } from "#/tag/domain/types";
5
+ /**
6
+ * Applies `@since` tags across the selected targets and returns the aggregate result.
7
+ *
8
+ * @since 0.3.16-canary.0
9
+ */
10
+ export declare function runTag(fs: Filesystem, input: TagExecutionInput): Promise<Result<TagResult, AppError>>;
@@ -1,26 +1,37 @@
1
1
  import path from "node:path";
2
2
  import { AppError } from "#/core/errors";
3
3
  import { messageFrom } from "#/core/errors";
4
- import { createAnyGlobMatcher } from "#/core/glob";
5
4
  import { err, ok } from "#/core/result";
6
- import { resolveTagTargetCandidates } from "#/tag/target-candidates";
7
- import { runTagOnTarget } from "#/tag/target-runner";
5
+ import { filterSkippedCandidates } from "#/tag/domain/skip-filter";
6
+ import { extractDistinctVersions, summarizeVersions } from "#/tag/domain/version-summary";
7
+ import { resolveTagTargetCandidates } from "#/tag/target/candidates";
8
+ import { runTagOnTarget } from "#/tag/target/runner";
8
9
  /**
9
- * Runs the tag sync across the selected targets and returns the aggregate result.
10
+ * Applies `@since` tags across the selected targets and returns the aggregate result.
10
11
  *
11
12
  * @since 0.3.16-canary.0
12
13
  */
13
- export async function runTagSync(fs, input) {
14
+ export async function runTag(fs, input) {
14
15
  try {
15
16
  const tagConfig = input.config;
16
17
  const targetCandidates = await resolveTagTargetCandidates(fs, input.rootDir, input.targetPath);
17
18
  const { includedCandidates, skippedPackages } = filterSkippedCandidates(targetCandidates, input.skipPackages);
18
19
  const selectedTargets = includedCandidates.map((candidate) => resolveTargetSelection(fs, candidate, input.rootDir));
19
20
  const targetExecutionResults = await Promise.all(selectedTargets.map((resolvedTarget) => runOnResolvedTarget(fs, resolvedTarget, input.write, input.listener)));
20
- const allFileResults = targetExecutionResults.flatMap((targetResult) => targetResult.result?.fileResults ?? []);
21
- const filesScanned = targetExecutionResults.reduce((sum, targetResult) => sum + (targetResult.result?.filesScanned ?? 0), 0);
22
- const filesChanged = targetExecutionResults.reduce((sum, targetResult) => sum + (targetResult.result?.filesChanged ?? 0), 0);
23
- const taggedDeclarations = targetExecutionResults.reduce((sum, targetResult) => sum + (targetResult.result?.taggedDeclarations ?? 0), 0);
21
+ const allFileResults = [];
22
+ let filesScanned = 0;
23
+ let filesChanged = 0;
24
+ let taggedDeclarations = 0;
25
+ for (const targetResult of targetExecutionResults) {
26
+ const runResult = targetResult.result;
27
+ if (runResult === null) {
28
+ continue;
29
+ }
30
+ allFileResults.push(...runResult.fileResults);
31
+ filesScanned += runResult.filesScanned;
32
+ filesChanged += runResult.filesChanged;
33
+ taggedDeclarations += runResult.taggedDeclarations;
34
+ }
24
35
  const modifiedFiles = allFileResults.filter((entry) => entry.changed).map((entry) => entry.filePath);
25
36
  const hookError = input.write && modifiedFiles.length > 0
26
37
  ? await runTagOnAfterWriteHook(tagConfig?.onAfterWrite, modifiedFiles)
@@ -57,20 +68,6 @@ async function runTagOnAfterWriteHook(hook, modifiedFiles) {
57
68
  return `[tag] onAfterWrite hook failed: ${messageFrom(caughtHookError)}`;
58
69
  }
59
70
  }
60
- function summarizeVersions(distinctVersions) {
61
- if (distinctVersions.size === 0) {
62
- return "none";
63
- }
64
- if (distinctVersions.size > 1) {
65
- return "mixed";
66
- }
67
- return distinctVersions.values().next().value ?? "none";
68
- }
69
- function extractDistinctVersions(targetResults) {
70
- return new Set(targetResults
71
- .map((targetResult) => targetResult.result?.version)
72
- .filter((version) => typeof version === "string" && version.length > 0));
73
- }
74
71
  function chooseWorkspacePackageTargetPath(fs, candidate) {
75
72
  if (candidate.source !== "workspace-package") {
76
73
  return {
@@ -103,33 +100,6 @@ function resolveTargetSelection(fs, candidate, rootDir) {
103
100
  packageName: candidate.packageName,
104
101
  };
105
102
  }
106
- /**
107
- * Partition tag target candidates into those to tag and those to skip, matching
108
- * each candidate's package name against `skipPackages` as glob patterns.
109
- * Candidates without a package name (e.g. an explicit-target path) are never skipped.
110
- *
111
- * @since 0.5.0-canary.0
112
- */
113
- export function filterSkippedCandidates(targetCandidates, skipPackages) {
114
- if (!skipPackages || skipPackages.length === 0) {
115
- return {
116
- includedCandidates: targetCandidates,
117
- skippedPackages: [],
118
- };
119
- }
120
- const isSkipped = createAnyGlobMatcher(skipPackages);
121
- const includedCandidates = [];
122
- const skippedPackages = [];
123
- for (const candidate of targetCandidates) {
124
- const packageName = candidate.packageName;
125
- if (packageName && isSkipped(packageName)) {
126
- skippedPackages.push(packageName);
127
- continue;
128
- }
129
- includedCandidates.push(candidate);
130
- }
131
- return { includedCandidates, skippedPackages };
132
- }
133
103
  async function runOnResolvedTarget(fs, resolvedTarget, write, listener) {
134
104
  listener?.onTargetStarted(resolvedTarget);
135
105
  const absoluteTargetPath = path.resolve(resolvedTarget.targetPath);
@@ -1,8 +1,8 @@
1
- import type { FilesystemPort } from "#/core/filesystem/port";
1
+ import type { Filesystem } from "#/core/filesystem/filesystem";
2
2
  import type { TagTargetCandidate } from "#/tag/domain/types";
3
3
  /**
4
4
  * Resolves the candidate targets for a tag run: the explicit target, or the discovered workspace packages.
5
5
  *
6
6
  * @since 0.3.16-canary.0
7
7
  */
8
- export declare function resolveTagTargetCandidates(fs: FilesystemPort, rootDir: string, explicitTarget: string | undefined): Promise<Array<TagTargetCandidate>>;
8
+ export declare function resolveTagTargetCandidates(fs: Filesystem, rootDir: string, explicitTarget: string | undefined): Promise<Array<TagTargetCandidate>>;
@@ -1,5 +1,5 @@
1
1
  import path from "node:path";
2
- import { z } from "zod";
2
+ import * as z from "zod";
3
3
  import { listWorkspacePackageDirectories } from "#/core/workspace/resolver";
4
4
  import { packageJsonFileName } from "#/core/workspace/well-known-files";
5
5
  const packageJsonNameSchema = z.looseObject({
@@ -1,10 +1,10 @@
1
- import type { FilesystemPort } from "#/core/filesystem/port";
1
+ import type { Filesystem } from "#/core/filesystem/filesystem";
2
2
  /**
3
3
  * Canonicalizes the user-provided target path, or returns `undefined` when none was given.
4
4
  *
5
5
  * @since 0.3.16-canary.0
6
6
  */
7
- export declare function resolveProvidedTagTargetPath(fs: FilesystemPort, args: {
7
+ export declare function resolveProvidedTagTargetPath(fs: Filesystem, args: {
8
8
  readonly currentWorkingDirectory: string;
9
9
  readonly rawTarget: string | undefined;
10
10
  }): string | undefined;
@@ -1,8 +1,8 @@
1
- import type { FilesystemPort } from "#/core/filesystem/port";
1
+ import type { Filesystem } from "#/core/filesystem/filesystem";
2
2
  import type { TagRunOptions, TagRunResult } from "#/tag/domain/types";
3
3
  /**
4
4
  * Stamps `@since` tags across one target's TypeScript files and returns the run result.
5
5
  *
6
6
  * @since 0.3.16-canary.0
7
7
  */
8
- export declare function runTagOnTarget(fs: FilesystemPort, targetPath: string, opts: TagRunOptions): TagRunResult;
8
+ export declare function runTagOnTarget(fs: Filesystem, targetPath: string, opts: TagRunOptions): TagRunResult;
@@ -1,7 +1,7 @@
1
1
  import path from "node:path";
2
2
  import { walkTsxFiles } from "#/core/workspace/typescript-walk";
3
- import { TagSinceWriter } from "#/tag/since-writer";
4
- import { resolveNearestPackageVersion } from "#/tag/version-resolver";
3
+ import { TagSinceWriter } from "#/tag/writer/since-writer";
4
+ import { resolveNearestPackageVersion } from "#/tag/writer/version-resolver";
5
5
  /**
6
6
  * Stamps `@since` tags across one target's TypeScript files and returns the run result.
7
7
  *
@@ -1,4 +1,4 @@
1
- import type { FilesystemPort } from "#/core/filesystem/port";
1
+ import type { Filesystem } from "#/core/filesystem/filesystem";
2
2
  import type { TagFileResult } from "#/tag/domain/types";
3
3
  /**
4
4
  * The writer that adds missing `@since` tags to a file's exported declarations.
@@ -8,7 +8,7 @@ import type { TagFileResult } from "#/tag/domain/types";
8
8
  export declare class TagSinceWriter {
9
9
  private readonly fs;
10
10
  private readonly sinceDocumentationTag;
11
- constructor(fs: FilesystemPort);
11
+ constructor(fs: Filesystem);
12
12
  applySinceTagsToFile(filePath: string, version: string, write: boolean): TagFileResult;
13
13
  /**
14
14
  * The taggable declaration a top-level statement introduces, resolving the
@@ -1,7 +1,7 @@
1
- import type { FilesystemPort } from "#/core/filesystem/port";
1
+ import type { Filesystem } from "#/core/filesystem/filesystem";
2
2
  /**
3
3
  * Returns the `version` of the nearest enclosing `package.json` above a target path.
4
4
  *
5
5
  * @since 0.3.16-canary.0
6
6
  */
7
- export declare function resolveNearestPackageVersion(fs: FilesystemPort, targetPath: string): string;
7
+ export declare function resolveNearestPackageVersion(fs: Filesystem, targetPath: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codefast/cli",
3
- "version": "0.10.0",
3
+ "version": "0.11.0",
4
4
  "description": "Developer CLI for the Codefast monorepo (arrange, audit, mirror, pack-slim, tag)",
5
5
  "keywords": [
6
6
  "cli",
@@ -57,7 +57,15 @@
57
57
  "oxc-parser": "^0.148.0",
58
58
  "picomatch": "^4.0.7",
59
59
  "yaml": "^2.9.0",
60
- "zod": "^4.5.4"
60
+ "zod": "^4.6.2"
61
+ },
62
+ "peerDependencies": {
63
+ "typescript": "^7.0.2"
64
+ },
65
+ "peerDependenciesMeta": {
66
+ "typescript": {
67
+ "optional": true
68
+ }
61
69
  },
62
70
  "engines": {
63
71
  "node": ">=24.0.0"
@@ -1,50 +0,0 @@
1
- import { z } from "zod";
2
- /**
3
- * The request payload for `arrange analyze`.
4
- *
5
- * @since 0.3.16-canary.0
6
- */
7
- export type ArrangeAnalyzeDirectoryRequest = {
8
- analyzeRootPath: string;
9
- };
10
- /**
11
- * The request payload for a top-level `arrange` run.
12
- *
13
- * @since 0.3.16-canary.0
14
- */
15
- export type ArrangeSyncRunRequest = {
16
- rootDir: string;
17
- targetPath: string;
18
- write: boolean;
19
- withClassName?: boolean | undefined;
20
- cnImport?: string | undefined;
21
- config?: unknown;
22
- };
23
- /**
24
- * The request payload for `arrange group`.
25
- *
26
- * @since 0.3.16-canary.0
27
- */
28
- export type ArrangeSuggestGroupsRequest = {
29
- inlineClasses: string;
30
- emitTvStyleArray: boolean;
31
- trailingClassName: boolean;
32
- };
33
- /**
34
- * The `zod` schema validating an `arrange analyze` request.
35
- *
36
- * @since 0.3.16-canary.0
37
- */
38
- export declare const arrangeAnalyzeDirectoryRequestSchema: z.ZodType<ArrangeAnalyzeDirectoryRequest>;
39
- /**
40
- * The `zod` schema validating an `arrange` run request.
41
- *
42
- * @since 0.3.16-canary.0
43
- */
44
- export declare const arrangeSyncRunRequestSchema: z.ZodType<ArrangeSyncRunRequest>;
45
- /**
46
- * The `zod` schema validating an `arrange group` request.
47
- *
48
- * @since 0.3.16-canary.0
49
- */
50
- export declare const arrangeSuggestGroupsRequestSchema: z.ZodType<ArrangeSuggestGroupsRequest>;
@@ -1,34 +0,0 @@
1
- import { z } from "zod";
2
- /**
3
- * The `zod` schema validating an `arrange analyze` request.
4
- *
5
- * @since 0.3.16-canary.0
6
- */
7
- export const arrangeAnalyzeDirectoryRequestSchema = z.object({
8
- analyzeRootPath: z.string().min(1, "analyzeRootPath is required"),
9
- });
10
- /**
11
- * The `zod` schema validating an `arrange` run request.
12
- *
13
- * @since 0.3.16-canary.0
14
- */
15
- export const arrangeSyncRunRequestSchema = z.object({
16
- rootDir: z.string().min(1),
17
- targetPath: z.string().min(1),
18
- write: z.boolean(),
19
- withClassName: z.boolean().optional(),
20
- cnImport: z.string().optional(),
21
- config: z.unknown().optional(),
22
- });
23
- /**
24
- * The `zod` schema validating an `arrange group` request.
25
- *
26
- * @since 0.3.16-canary.0
27
- */
28
- export const arrangeSuggestGroupsRequestSchema = z.object({
29
- inlineClasses: z
30
- .string()
31
- .min(1, 'Pass a class string. Example: codefast arrange group "flex gap-2 text-sm rounded-md"'),
32
- emitTvStyleArray: z.boolean(),
33
- trailingClassName: z.boolean(),
34
- });
@@ -1,26 +0,0 @@
1
- import type { GroupFileWorkPlan } from "#/arrange/domain/grouping-service";
2
- import type { AnalyzeReport, ArrangeRunResult } from "#/arrange/domain/types";
3
- /**
4
- * Prints the human-readable summary of an `arrange analyze` report.
5
- *
6
- * @since 0.3.16-canary.0
7
- */
8
- export declare function printAnalyzeReport(resolvedTargetPath: string, report: AnalyzeReport): void;
9
- /**
10
- * Prints the totals and follow-up hints for an `arrange` run.
11
- *
12
- * @since 0.3.16-canary.0
13
- */
14
- export declare function printSyncResult(result: ArrangeRunResult, write: boolean): void;
15
- /**
16
- * Prints the totals for an `arrange simplify` run.
17
- *
18
- * @since 0.3.16-canary.0
19
- */
20
- export declare function printSimplifyResult(result: ArrangeRunResult, write: boolean): void;
21
- /**
22
- * Prints the per-file preview of a work plan's unwrap and grouping edits.
23
- *
24
- * @since 0.3.16-canary.0
25
- */
26
- export declare function printGroupFilePreviewFromWork(work: GroupFileWorkPlan): void;
@@ -1,127 +0,0 @@
1
- import path from "node:path";
2
- import { lineOf } from "#/arrange/domain/ast/helpers";
3
- import { LONG_STRING_TOKEN_THRESHOLD, MAX_REPORT_LINES } from "#/arrange/domain/constants";
4
- import { logger } from "#/core/logger";
5
- /**
6
- * Prints the human-readable summary of an `arrange analyze` report.
7
- *
8
- * @since 0.3.16-canary.0
9
- */
10
- export function printAnalyzeReport(resolvedTargetPath, report) {
11
- logger.out(`Path: ${path.resolve(resolvedTargetPath)}`);
12
- logger.out(`.ts/.tsx files: ${report.files}`);
13
- logger.out(`cn(...) call sites: ${report.cnCallExpressions}`);
14
- logger.out(`tv(...) call sites: ${report.tvCallExpressions}`);
15
- logger.out(`\nLong cn(...) string literals (≥${LONG_STRING_TOKEN_THRESHOLD} tokens — consider splitting arguments): ${report.longCnStringLiterals.length}`);
16
- for (const findingEntry of report.longCnStringLiterals.slice(0, MAX_REPORT_LINES)) {
17
- logger.out(` ${findingEntry.file}:${findingEntry.line} (${findingEntry.tokenCount} tokens) ${findingEntry.preview}`);
18
- }
19
- if (report.longCnStringLiterals.length > MAX_REPORT_LINES) {
20
- logger.out(` … and ${report.longCnStringLiterals.length - MAX_REPORT_LINES} more`);
21
- }
22
- logger.out(`\nLong tv({...}) string literals in base/variants/… (≥${LONG_STRING_TOKEN_THRESHOLD} tokens): ${report.longTvStringLiterals.length}`);
23
- for (const findingEntry of report.longTvStringLiterals.slice(0, MAX_REPORT_LINES)) {
24
- logger.out(` ${findingEntry.file}:${findingEntry.line} (${findingEntry.tokenCount} tokens) ${findingEntry.preview}`);
25
- }
26
- if (report.longTvStringLiterals.length > MAX_REPORT_LINES) {
27
- logger.out(` … and ${report.longTvStringLiterals.length - MAX_REPORT_LINES} more`);
28
- }
29
- logger.out(`\nJSX className="..." or className={'...'} (static strings, ≥${LONG_STRING_TOKEN_THRESHOLD} tokens): ${report.longJsxClassNameLiterals.length}`);
30
- for (const findingEntry of report.longJsxClassNameLiterals.slice(0, MAX_REPORT_LINES)) {
31
- logger.out(` ${findingEntry.file}:${findingEntry.line} (${findingEntry.tokenCount} tokens) ${findingEntry.preview}`);
32
- }
33
- if (report.longJsxClassNameLiterals.length > MAX_REPORT_LINES) {
34
- logger.out(` … and ${report.longJsxClassNameLiterals.length - MAX_REPORT_LINES} more`);
35
- }
36
- logger.out(`\ncn(...) nested inside tv({...}) (prefer a string or array — preview/apply can rewrite): ${report.cnInsideTvCalls.length}`);
37
- for (const findingEntry of report.cnInsideTvCalls.slice(0, MAX_REPORT_LINES)) {
38
- logger.out(` ${findingEntry.file}:${findingEntry.line} (${findingEntry.argCount} args) ${findingEntry.preview}`);
39
- }
40
- if (report.cnInsideTvCalls.length > MAX_REPORT_LINES) {
41
- logger.out(` … and ${report.cnInsideTvCalls.length - MAX_REPORT_LINES} more`);
42
- }
43
- }
44
- /**
45
- * Prints the totals and follow-up hints for an `arrange` run.
46
- *
47
- * @since 0.3.16-canary.0
48
- */
49
- export function printSyncResult(result, write) {
50
- logger.out(`\nTotal: ${result.filePaths.length} file(s), ${result.totalFound} site(s) (cn/tv/JSX className) to review.`);
51
- if (write) {
52
- logger.out(`Applied: ${result.totalChanged} site(s) updated.`);
53
- }
54
- else {
55
- logger.out(`(Re-run without --dry-run to write changes, or "pnpm cli:arrange" / "pnpm exec codefast arrange")`);
56
- }
57
- const shouldShowCascadeHint = write ? result.totalChanged > 0 : result.totalFound > 0;
58
- if (shouldShowCascadeHint) {
59
- logger.out("Note: class order may change across concern groups — smoke-test the UI if you rely on cascade order.");
60
- }
61
- if (result.hookError !== null) {
62
- logger.err(result.hookError);
63
- }
64
- }
65
- /**
66
- * Prints the totals for an `arrange simplify` run.
67
- *
68
- * @since 0.3.16-canary.0
69
- */
70
- export function printSimplifyResult(result, write) {
71
- logger.out(`\nTotal: ${result.filePaths.length} file(s), ${result.totalFound} site(s) to simplify.`);
72
- if (write) {
73
- logger.out(`Applied: ${result.totalChanged} site(s) updated.`);
74
- }
75
- else {
76
- logger.out(`(Run "simplify" to write changes, or "pnpm cli:arrange-simplify" / "pnpm exec codefast arrange simplify")`);
77
- }
78
- }
79
- /**
80
- * Prints the per-file preview of a work plan's unwrap and grouping edits.
81
- *
82
- * @since 0.3.16-canary.0
83
- */
84
- export function printGroupFilePreviewFromWork(work) {
85
- printGroupFilePreviewBody({
86
- filePath: work.filePath,
87
- reportTotal: work.reportTotal,
88
- cnInTvNoReplacement: work.cnInTvNoReplacement,
89
- cnInTvCalls: work.cnInTvCalls,
90
- unwrapReplacementByCall: work.unwrapReplacementByCall,
91
- sourceText: work.sourceText,
92
- domainSf: work.domainSfForLineNumbers,
93
- unwrapEdits: work.unwrapEdits,
94
- plannedGroupEdits: work.plannedGroupEdits,
95
- });
96
- }
97
- function printGroupFilePreviewBody(args) {
98
- const { filePath, reportTotal, cnInTvNoReplacement, cnInTvCalls, unwrapReplacementByCall, sourceText, domainSf, unwrapEdits, plannedGroupEdits, } = args;
99
- let header = `\n── ${filePath} (${reportTotal} site(s)`;
100
- if (cnInTvNoReplacement > 0) {
101
- header += `; plus ${cnInTvNoReplacement} cn() inside tv left unchanged (0 args)`;
102
- }
103
- header += `) ──`;
104
- logger.out(header);
105
- for (const call of cnInTvCalls) {
106
- const replacement = unwrapReplacementByCall.get(call);
107
- if (replacement === undefined) {
108
- logger.out(` Line ${lineOf(domainSf, call)} [tv ⊃ cn]: cn(...) has no arguments — skipped`);
109
- continue;
110
- }
111
- const start = call.pos;
112
- const end = call.end;
113
- if (sourceText.slice(start, end) === replacement) {
114
- continue;
115
- }
116
- logger.out(` Line ${lineOf(domainSf, call)} [tv ⊃ cn → string/array]:`);
117
- logger.out(` ${replacement.split("\n").join("\n ")}`);
118
- }
119
- if (unwrapEdits.length > 0 && plannedGroupEdits.length > 0) {
120
- logger.out(" ([cn] / [tv] / [JSX className] lines below reflect content after unwrap of cn inside tv.)");
121
- }
122
- for (const plan of plannedGroupEdits) {
123
- logger.out(` Line ${lineOf(plan.lineSf, plan.reportNode)} [${plan.label}]:`);
124
- logger.out(` ${plan.replacement.split("\n").join("\n ")}`);
125
- logger.out(` // Buckets: ${JSON.stringify(plan.bucketSummary)}`);
126
- }
127
- }
@@ -1,30 +0,0 @@
1
- import { collectSimplifyTargets } from "#/arrange/domain/ast/simplify-targets";
2
- import { dropCnImportIfUnused } from "#/arrange/domain/imports";
3
- import { parseDomainSourceFile } from "#/arrange/source-parse";
4
- import { applyEditsDescending } from "#/core/source-text-edit";
5
- /**
6
- * Runs the simplify pass on one file — flattening class expressions and pruning an unused `cn` import.
7
- *
8
- * @since 0.3.16-canary.0
9
- */
10
- export function processArrangeSimplifyFile(fs, args) {
11
- const { filePath, write } = args;
12
- const sourceText = fs.readFileSync(filePath, "utf8");
13
- const domainSf = parseDomainSourceFile(filePath, sourceText);
14
- const edits = collectSimplifyTargets(domainSf);
15
- const meaningful = edits.filter((edit) => sourceText.slice(edit.start, edit.end) !== edit.replacement);
16
- // Apply class-simplification edits first, then prune any cn import that
17
- // became (or was already) unused.
18
- const textAfterEdits = meaningful.length > 0 ? applyEditsDescending(sourceText, meaningful) : sourceText;
19
- const textAfterImportDrop = dropCnImportIfUnused(parseDomainSourceFile(filePath, textAfterEdits));
20
- const importDropped = textAfterImportDrop !== textAfterEdits;
21
- const totalFound = meaningful.length + (importDropped ? 1 : 0);
22
- if (totalFound === 0) {
23
- return { filePath, totalFound: 0, changed: 0 };
24
- }
25
- if (!write) {
26
- return { filePath, totalFound, changed: 0 };
27
- }
28
- fs.writeFileSync(filePath, textAfterImportDrop, "utf8");
29
- return { filePath, totalFound, changed: totalFound };
30
- }
@@ -1,30 +0,0 @@
1
- import { scanArrangeTargets } from "#/arrange/scan-target";
2
- import { processArrangeSimplifyFile } from "#/arrange/simplify-process-file";
3
- import { ok } from "#/core/result";
4
- /**
5
- * Runs the simplify pass over every target file and returns the aggregated result.
6
- *
7
- * @since 0.3.16-canary.0
8
- */
9
- export async function runArrangeSimplify(fs, args) {
10
- const filePaths = scanArrangeTargets(fs, args.targetPath);
11
- const modifiedFiles = [];
12
- let totalFound = 0;
13
- let totalChanged = 0;
14
- for (const filePath of filePaths) {
15
- const result = processArrangeSimplifyFile(fs, { filePath, write: args.write });
16
- totalFound += result.totalFound;
17
- totalChanged += result.changed;
18
- if (result.changed > 0) {
19
- modifiedFiles.push(result.filePath);
20
- }
21
- }
22
- return ok({
23
- filePaths,
24
- modifiedFiles,
25
- totalFound,
26
- totalChanged,
27
- hookError: null,
28
- previewPlans: [],
29
- });
30
- }
@@ -1,93 +0,0 @@
1
- import { z } from "zod";
2
- /**
3
- * Resolved request for a single RTL audit run.
4
- *
5
- * @since 0.5.0-canary.6
6
- */
7
- export type RtlAuditRunRequest = {
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 RtlAuditRunRequest}.
15
- *
16
- * @since 0.5.0-canary.6
17
- */
18
- export declare const rtlAuditRunRequestSchema: z.ZodType<RtlAuditRunRequest>;
19
- /**
20
- * Resolved request for a single link audit run.
21
- *
22
- * @since 0.5.0
23
- */
24
- export type LinkAuditRunRequest = {
25
- readonly rootDir: string;
26
- readonly targetPath: string;
27
- readonly allowlist?: ReadonlyArray<string> | undefined;
28
- readonly json: boolean;
29
- };
30
- /**
31
- * Zod schema for {@link LinkAuditRunRequest}.
32
- *
33
- * @since 0.5.0
34
- */
35
- export declare const linkAuditRunRequestSchema: z.ZodType<LinkAuditRunRequest>;
36
- /**
37
- * Resolved request for a single comment-divider audit run.
38
- *
39
- * @since 0.6.0
40
- */
41
- export type CommentAuditRunRequest = {
42
- readonly rootDir: string;
43
- readonly targetPath: string;
44
- readonly allowlist?: ReadonlyArray<string> | undefined;
45
- readonly fix: boolean;
46
- readonly json: boolean;
47
- };
48
- /**
49
- * Zod schema for {@link CommentAuditRunRequest}.
50
- *
51
- * @since 0.6.0
52
- */
53
- export declare const commentAuditRunRequestSchema: z.ZodType<CommentAuditRunRequest>;
54
- /**
55
- * Resolved request for a single import-policy audit run.
56
- *
57
- * @since 0.10.0
58
- */
59
- export type ImportsAuditRunRequest = {
60
- readonly rootDir: string;
61
- readonly targetPath: string;
62
- readonly allowlist?: ReadonlyArray<string> | undefined;
63
- readonly json: boolean;
64
- };
65
- /**
66
- * Zod schema for {@link ImportsAuditRunRequest}.
67
- *
68
- * @since 0.10.0
69
- */
70
- export declare const importsAuditRunRequestSchema: z.ZodType<ImportsAuditRunRequest>;
71
- /**
72
- * Resolved request for a single display-name audit run.
73
- *
74
- * @since 0.9.0
75
- */
76
- export type DisplayNameAuditRunRequest = {
77
- readonly rootDir: string;
78
- readonly targetPath: string;
79
- readonly allowlist?: ReadonlyArray<string> | undefined;
80
- readonly json: boolean;
81
- };
82
- /**
83
- * Zod schema for {@link DisplayNameAuditRunRequest}.
84
- *
85
- * @since 0.9.0
86
- */
87
- export declare const displayNameAuditRunRequestSchema: z.ZodType<DisplayNameAuditRunRequest>;
88
- /**
89
- * Resolves a path that may be absolute or relative to `rootDir`.
90
- *
91
- * @since 0.5.0-canary.6
92
- */
93
- export declare function resolveRepoRelativePath(rootDir: string, maybeRelative: string): string;