@codefast/cli 0.3.14 → 0.3.16-canary.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 (189) hide show
  1. package/README.md +8 -3
  2. package/dist/arrange/analyze.mjs +24 -0
  3. package/dist/{lib/arrange/presentation/arrange-cli.schema.mjs → arrange/cli-schema.mjs} +10 -1
  4. package/dist/arrange/command.mjs +106 -0
  5. package/dist/{lib/arrange/domain/arrange-analyze.service.mjs → arrange/domain/analyze-service.mjs} +17 -10
  6. package/dist/{lib/arrange/domain/ast/ast-node.model.mjs → arrange/domain/ast/ast-node.mjs} +57 -3
  7. package/dist/{lib/arrange/domain/ast/collectors-cn.collector.mjs → arrange/domain/ast/collectors-cn.mjs} +21 -9
  8. package/dist/{lib/arrange/domain/ast/collectors-jsx.collector.mjs → arrange/domain/ast/collectors-jsx.mjs} +5 -2
  9. package/dist/{lib/arrange/domain/ast/collectors-tv.collector.mjs → arrange/domain/ast/collectors-tv.mjs} +21 -6
  10. package/dist/{lib/arrange/domain/ast/ast-helpers.helper.mjs → arrange/domain/ast/helpers.mjs} +26 -9
  11. package/dist/{lib/arrange/domain/ast/targets.model.mjs → arrange/domain/ast/targets.mjs} +19 -10
  12. package/dist/{lib/arrange/domain/constants.domain.mjs → arrange/domain/constants.mjs} +63 -18
  13. package/dist/{lib/arrange/domain/arrange-grouping.service.mjs → arrange/domain/grouping-service.mjs} +31 -10
  14. package/dist/{lib/arrange/domain/grouping.domain.mjs → arrange/domain/grouping.mjs} +39 -18
  15. package/dist/{lib/arrange/domain/imports.domain.mjs → arrange/domain/imports.mjs} +7 -3
  16. package/dist/{lib/arrange/domain/source-text-formatters.formatter.mjs → arrange/domain/source-text-formatters.mjs} +22 -5
  17. package/dist/{lib/arrange/domain/tailwind-token.value-object.mjs → arrange/domain/tailwind-token.mjs} +12 -3
  18. package/dist/{lib/arrange/domain/tailwind-token-classifier.domain-service.mjs → arrange/domain/token-classifier.mjs} +40 -15
  19. package/dist/arrange/output.mjs +79 -0
  20. package/dist/arrange/process-file.mjs +42 -0
  21. package/dist/arrange/resolve-target.mjs +24 -0
  22. package/dist/arrange/scan-target.mjs +20 -0
  23. package/dist/arrange/source-parse.mjs +18 -0
  24. package/dist/arrange/suggest.mjs +15 -0
  25. package/dist/arrange/sync.mjs +51 -0
  26. package/dist/arrange/typescript-ast-translator.mjs +354 -0
  27. package/dist/arrange/workspace.mjs +31 -0
  28. package/dist/bin.mjs +1 -1
  29. package/dist/{program.mjs → cli.mjs} +14 -19
  30. package/dist/core/cli/format-error.mjs +15 -0
  31. package/dist/core/cli/global-options.mjs +10 -0
  32. package/dist/core/cli/positional.mjs +11 -0
  33. package/dist/core/cli/result-handle.mjs +51 -0
  34. package/dist/core/config/loader.mjs +79 -0
  35. package/dist/{lib/config/infrastructure/config-schema.adapter.mjs → core/config/schema.mjs} +20 -6
  36. package/dist/core/config/warnings.mjs +12 -0
  37. package/dist/core/config.mjs +19 -0
  38. package/dist/{lib/core/domain/caught-unknown-message.value-object.mjs → core/errors.mjs} +20 -4
  39. package/dist/core/exit-codes.mjs +17 -0
  40. package/dist/core/filesystem/node.mjs +32 -0
  41. package/dist/core/logger.mjs +15 -0
  42. package/dist/{lib/core/domain/result.model.mjs → core/result.mjs} +7 -3
  43. package/dist/{lib/core/application/services/schema-validator.service.mjs → core/schema-parse.mjs} +6 -5
  44. package/dist/{lib/shared/source-code/domain/text-edit.model.mjs → core/source-text-edit.mjs} +15 -14
  45. package/dist/core/verbose-diagnostics.mjs +11 -0
  46. package/dist/core/workspace/resolver.mjs +177 -0
  47. package/dist/core/workspace/typescript-walk.mjs +36 -0
  48. package/dist/mirror/cli-result.mjs +21 -0
  49. package/dist/{lib/mirror/presentation/mirror-cli.schema.mjs → mirror/cli-schema.mjs} +4 -4
  50. package/dist/mirror/command.mjs +57 -0
  51. package/dist/mirror/dist-filesystem-impl.mjs +42 -0
  52. package/dist/{lib/mirror/domain/constants.domain.mjs → mirror/domain/constants.mjs} +16 -1
  53. package/dist/{lib/mirror/infrastructure/dirent-list.guard.mjs → mirror/domain/dirent-guard.mjs} +5 -2
  54. package/dist/{lib/mirror/domain/errors.domain.mjs → mirror/domain/errors.mjs} +7 -1
  55. package/dist/{lib/mirror/application/services/generate-mirror-exports.service.mjs → mirror/domain/exports.mjs} +17 -10
  56. package/dist/{lib/mirror/domain/package-display-name.policy.mjs → mirror/domain/package-display-name.mjs} +5 -2
  57. package/dist/{lib/mirror/domain/path-normalizer.value-object.mjs → mirror/domain/path-normalizer.mjs} +4 -1
  58. package/dist/mirror/output.mjs +45 -0
  59. package/dist/mirror/package-path.mjs +32 -0
  60. package/dist/mirror/prepare.mjs +33 -0
  61. package/dist/mirror/sync-reporter.mjs +104 -0
  62. package/dist/mirror/sync-workspace-package.mjs +103 -0
  63. package/dist/mirror/sync.mjs +87 -0
  64. package/dist/{lib/mirror/infrastructure/package-json-exports.repository.mjs → mirror/write-exports.mjs} +35 -31
  65. package/dist/tag/cli-result.mjs +11 -0
  66. package/dist/{lib/tag/presentation/tag-cli.schema.mjs → tag/cli-schema.mjs} +4 -1
  67. package/dist/tag/command.mjs +56 -0
  68. package/dist/{lib/tag/presentation/tag-sync.presenter.mjs → tag/output.mjs} +54 -28
  69. package/dist/tag/prepare.mjs +29 -0
  70. package/dist/tag/resolve-target-path.mjs +12 -0
  71. package/dist/tag/since-writer.mjs +130 -0
  72. package/dist/tag/sync.mjs +141 -0
  73. package/dist/tag/target-candidates.mjs +68 -0
  74. package/dist/tag/target-runner.mjs +26 -0
  75. package/dist/tag/version-resolver.mjs +25 -0
  76. package/package.json +8 -9
  77. package/dist/lib/arrange/adapters/primary/cli/arrange.command.mjs +0 -324
  78. package/dist/lib/arrange/adapters/primary/cli/arrange.presentation.module.mjs +0 -14
  79. package/dist/lib/arrange/adapters/primary/cli/presentation.tokens.mjs +0 -5
  80. package/dist/lib/arrange/adapters/secondary/domain-source-parser.adapter.mjs +0 -239
  81. package/dist/lib/arrange/adapters/secondary/file-walker.adapter.mjs +0 -241
  82. package/dist/lib/arrange/adapters/secondary/workspace-resolver.adapter.mjs +0 -233
  83. package/dist/lib/arrange/application/requests/suggest-groups.request.mjs +0 -1
  84. package/dist/lib/arrange/application/services/arrange-file-processor.service.mjs +0 -267
  85. package/dist/lib/arrange/application/services/arrange-target-path-resolver.service.mjs +0 -21
  86. package/dist/lib/arrange/application/services/arrange-target-scanner.service.mjs +0 -243
  87. package/dist/lib/arrange/application/use-cases/analyze-directory.use-case.mjs +0 -255
  88. package/dist/lib/arrange/application/use-cases/prepare-arrange-workspace.use-case.mjs +0 -263
  89. package/dist/lib/arrange/application/use-cases/run-arrange-sync.use-case.mjs +0 -274
  90. package/dist/lib/arrange/application/use-cases/suggest-cn-groups.use-case.mjs +0 -237
  91. package/dist/lib/arrange/arrange.module.mjs +0 -31
  92. package/dist/lib/arrange/contracts/analyze-report-presenter.contract.mjs +0 -1
  93. package/dist/lib/arrange/contracts/models.mjs +0 -1
  94. package/dist/lib/arrange/contracts/services.contract.mjs +0 -1
  95. package/dist/lib/arrange/contracts/tokens.mjs +0 -15
  96. package/dist/lib/arrange/domain/tailwind-grouping.service.mjs +0 -231
  97. package/dist/lib/arrange/domain/types.domain.mjs +0 -1
  98. package/dist/lib/arrange/infrastructure/typescript-ast-translator.adapter.mjs +0 -355
  99. package/dist/lib/arrange/presentation/arrange-analyze.presenter.mjs +0 -259
  100. package/dist/lib/arrange/presentation/arrange-sync.presenter.mjs +0 -33
  101. package/dist/lib/arrange/presentation/group-file-preview.presenter.mjs +0 -271
  102. package/dist/lib/bootstrap/composition-root.mjs +0 -33
  103. package/dist/lib/config/application/ports/config-loader.port.mjs +0 -1
  104. package/dist/lib/config/application/ports/config-warning-reporter.port.mjs +0 -1
  105. package/dist/lib/config/application/services/load-config.service.mjs +0 -17
  106. package/dist/lib/config/contracts/tokens.mjs +0 -6
  107. package/dist/lib/config/domain/schema.domain.mjs +0 -1
  108. package/dist/lib/config/infrastructure/config-loader.adapter.mjs +0 -306
  109. package/dist/lib/config/infrastructure/config-warning-reporter.adapter.mjs +0 -234
  110. package/dist/lib/core/application/load-codefast-config.use-case.mjs +0 -245
  111. package/dist/lib/core/application/ports/cli-io.port.mjs +0 -1
  112. package/dist/lib/core/application/ports/path.port.mjs +0 -1
  113. package/dist/lib/core/application/ports/repo-root-resolver.port.mjs +0 -1
  114. package/dist/lib/core/application/ports/runtime.port.mjs +0 -1
  115. package/dist/lib/core/application/services/global-cli-options-parser.service.mjs +0 -9
  116. package/dist/lib/core/contracts/tokens.mjs +0 -10
  117. package/dist/lib/core/core.module.mjs +0 -9
  118. package/dist/lib/core/domain/cli-exit-codes.domain.mjs +0 -11
  119. package/dist/lib/core/domain/errors.domain.mjs +0 -17
  120. package/dist/lib/core/infrastructure/infrastructure.module.mjs +0 -30
  121. package/dist/lib/core/infrastructure/path.adapter.mjs +0 -246
  122. package/dist/lib/core/infrastructure/port-telemetry.decorator.mjs +0 -62
  123. package/dist/lib/core/infrastructure/repo-root-resolver.adapter.mjs +0 -233
  124. package/dist/lib/core/infrastructure/verbose-diagnostics.policy.mjs +0 -9
  125. package/dist/lib/core/presentation/cli-executor.presenter.mjs +0 -42
  126. package/dist/lib/core/presentation/cli-schema.parser.mjs +0 -7
  127. package/dist/lib/core/presentation/format-app-error.presenter.mjs +0 -17
  128. package/dist/lib/core/presentation/presentation.module.mjs +0 -5
  129. package/dist/lib/infrastructure/node-io.adapter.mjs +0 -285
  130. package/dist/lib/infrastructure/workspace/repo-root-resolver.service.mjs +0 -21
  131. package/dist/lib/kernel/contracts/cli-command.contract.mjs +0 -1
  132. package/dist/lib/kernel/contracts/tokens.mjs +0 -5
  133. package/dist/lib/mirror/adapters/primary/cli/mirror.command.mjs +0 -272
  134. package/dist/lib/mirror/adapters/secondary/file-system-service.adapter.mjs +0 -261
  135. package/dist/lib/mirror/adapters/secondary/mirror-sync-reporter.adapter.mjs +0 -243
  136. package/dist/lib/mirror/adapters/secondary/package-repository.adapter.mjs +0 -241
  137. package/dist/lib/mirror/adapters/secondary/sync-workspace-package.adapter.mjs +0 -351
  138. package/dist/lib/mirror/adapters/secondary/workspace-service.adapter.mjs +0 -237
  139. package/dist/lib/mirror/application/mirror-sync-json.format.mjs +0 -12
  140. package/dist/lib/mirror/application/ports/file-system-service.port.mjs +0 -1
  141. package/dist/lib/mirror/application/ports/mirror-sync-reporter.port.mjs +0 -1
  142. package/dist/lib/mirror/application/ports/package-repository.port.mjs +0 -1
  143. package/dist/lib/mirror/application/ports/sync-workspace-package.port.mjs +0 -1
  144. package/dist/lib/mirror/application/ports/workspace-service.port.mjs +0 -1
  145. package/dist/lib/mirror/application/requests/mirror-sync.request.mjs +0 -1
  146. package/dist/lib/mirror/application/services/mirror-package-arg-resolver.service.mjs +0 -20
  147. package/dist/lib/mirror/application/use-cases/prepare-mirror-sync.use-case.mjs +0 -264
  148. package/dist/lib/mirror/application/use-cases/run-mirror-sync.use-case.mjs +0 -302
  149. package/dist/lib/mirror/contracts/models.mjs +0 -1
  150. package/dist/lib/mirror/contracts/tokens.mjs +0 -11
  151. package/dist/lib/mirror/domain/types.domain.mjs +0 -1
  152. package/dist/lib/mirror/infrastructure/mirror-console-reporter.presenter.mjs +0 -99
  153. package/dist/lib/mirror/infrastructure/package-filter-resolver.service.mjs +0 -25
  154. package/dist/lib/mirror/infrastructure/workspace-packages.service.mjs +0 -158
  155. package/dist/lib/mirror/mirror.module.mjs +0 -25
  156. package/dist/lib/shared/source-code/infrastructure/typescript-source-file-walker.service.mjs +0 -33
  157. package/dist/lib/tag/adapters/primary/cli/presentation.tokens.mjs +0 -6
  158. package/dist/lib/tag/adapters/primary/cli/tag.command.mjs +0 -285
  159. package/dist/lib/tag/adapters/primary/cli/tag.presentation.module.mjs +0 -13
  160. package/dist/lib/tag/adapters/secondary/tag-since-writer.adapter.mjs +0 -348
  161. package/dist/lib/tag/adapters/secondary/tag-target-resolver.adapter.mjs +0 -233
  162. package/dist/lib/tag/adapters/secondary/tag-version-resolver.adapter.mjs +0 -249
  163. package/dist/lib/tag/adapters/secondary/typescript-tree-walk.adapter.mjs +0 -233
  164. package/dist/lib/tag/application/ports/tag-since-writer.port.mjs +0 -1
  165. package/dist/lib/tag/application/ports/tag-version-resolver.port.mjs +0 -1
  166. package/dist/lib/tag/application/ports/target-resolver.port.mjs +0 -1
  167. package/dist/lib/tag/application/ports/typescript-tree-walk.port.mjs +0 -1
  168. package/dist/lib/tag/application/requests/tag-sync.request.mjs +0 -1
  169. package/dist/lib/tag/application/services/tag-cli-target-path-resolver.service.mjs +0 -9
  170. package/dist/lib/tag/application/services/tag-target-runner.service.mjs +0 -21
  171. package/dist/lib/tag/application/tag-sync-cli-result.mjs +0 -11
  172. package/dist/lib/tag/application/tag-sync-json.format.mjs +0 -14
  173. package/dist/lib/tag/application/use-cases/prepare-tag-sync.use-case.mjs +0 -264
  174. package/dist/lib/tag/application/use-cases/run-tag-sync.use-case.mjs +0 -381
  175. package/dist/lib/tag/contracts/models.mjs +0 -1
  176. package/dist/lib/tag/contracts/tag-sync-result-presenter.contract.mjs +0 -1
  177. package/dist/lib/tag/contracts/tokens.mjs +0 -10
  178. package/dist/lib/tag/domain/types.domain.mjs +0 -1
  179. package/dist/lib/tag/infrastructure/tag-target-candidates.adapter.mjs +0 -170
  180. package/dist/lib/tag/presentation/colors.presenter.mjs +0 -12
  181. package/dist/lib/tag/presentation/present-tag-sync-result.presenter.mjs +0 -233
  182. package/dist/lib/tag/presentation/tag-sync-progress-listener.presenter.mjs +0 -243
  183. package/dist/lib/tag/tag.module.mjs +0 -23
  184. /package/dist/{lib/arrange/application/ports/domain-source-parser.port.mjs → arrange/domain/types.mjs} +0 -0
  185. /package/dist/{lib/arrange/application/ports/file-walker.port.mjs → core/filesystem/port.mjs} +0 -0
  186. /package/dist/{lib/arrange/application/ports/group-file-preview.port.mjs → mirror/domain/dist-filesystem.mjs} +0 -0
  187. /package/dist/{lib/arrange/application/ports/workspace-resolver.port.mjs → mirror/domain/types.mjs} +0 -0
  188. /package/dist/{lib/arrange/application/requests/analyze-directory.request.mjs → mirror/sync-types.mjs} +0 -0
  189. /package/dist/{lib/arrange/application/requests/arrange-sync.request.mjs → tag/domain/types.mjs} +0 -0
@@ -0,0 +1,104 @@
1
+ import { messageFrom } from "../core/errors.mjs";
2
+ import process from "node:process";
3
+ //#region src/mirror/sync-reporter.ts
4
+ const ANSI = {
5
+ reset: "\x1B[0m",
6
+ bold: "\x1B[1m",
7
+ dim: "\x1B[2m",
8
+ green: "\x1B[32m",
9
+ yellow: "\x1B[33m",
10
+ cyan: "\x1B[36m",
11
+ gray: "\x1B[90m",
12
+ magenta: "\x1B[35m",
13
+ brightGreen: "\x1B[92m",
14
+ brightCyan: "\x1B[96m"
15
+ };
16
+ /**
17
+ * Console implementation: ANSI styling and layout for mirror sync.
18
+ *
19
+ * @since 0.3.16-canary.0
20
+ */
21
+ var MirrorSyncReporter = class {
22
+ colorsAreEnabled = true;
23
+ configureMirrorColors(noColor) {
24
+ this.colorsAreEnabled = !!process.stdout.isTTY && !noColor;
25
+ }
26
+ mirrorBanner(logger) {
27
+ logger.out(`\n${this.paint("📦 Mirror — package exports", ANSI.bold + ANSI.cyan)}`);
28
+ logger.out(`${this.paint("═".repeat(60), ANSI.dim)}\n`);
29
+ }
30
+ mirrorProcessingMode(logger, mode) {
31
+ if (mode.kind === "single") {
32
+ logger.out(`${this.paint("Processing single package...", ANSI.dim)}\n`);
33
+ return;
34
+ }
35
+ if (mode.source === "default-patterns") {
36
+ logger.out(`${this.paint("Discovering workspace packages using default patterns (packages/*)…", ANSI.dim)}\n`);
37
+ return;
38
+ }
39
+ if (mode.source === "pnpm-workspace-yaml") {
40
+ logger.out(`${this.paint("Discovering workspace packages from pnpm-workspace.yaml…", ANSI.dim)}\n`);
41
+ return;
42
+ }
43
+ logger.out(`${this.paint("pnpm-workspace.yaml declares an empty workspace package list.", ANSI.dim)}\n`);
44
+ }
45
+ mirrorNoPackages(logger) {
46
+ logger.out(this.paint("⚠ No packages found", ANSI.yellow));
47
+ }
48
+ logSkippedWorkspacePackage(logger, index, total, displayName, reason) {
49
+ const progress = this.paint(`[${index}/${total}]`, ANSI.dim);
50
+ logger.out(`${progress} ${this.paint("○", ANSI.gray)} ${this.paint(displayName, ANSI.dim)}`);
51
+ logger.out(` ${this.paint("└─", ANSI.dim)} ${this.paint(`Skipped: ${reason}`, ANSI.gray)}`);
52
+ logger.out("");
53
+ }
54
+ logPackageSuccess(logger, index, total, pkgStats, generatedDistAssetCounts, verbose) {
55
+ const progress = this.paint(`[${index}/${total}]`, ANSI.dim);
56
+ logger.out(`${progress} ${this.paint("✓", ANSI.brightGreen)} ${this.paint(pkgStats.name, ANSI.bold)}`);
57
+ if (verbose) {
58
+ logger.out(` ${this.paint("├─", ANSI.dim)} Path: ${pkgStats.path}`);
59
+ if (pkgStats.hasTransform) logger.out(` ${this.paint("├─", ANSI.dim)} ${this.paint("Custom path transformation", ANSI.cyan)}`);
60
+ if (pkgStats.cssConfigStatus) {
61
+ const status = pkgStats.cssConfigStatus === "disabled" ? "CSS disabled" : "CSS configured";
62
+ logger.out(` ${this.paint("├─", ANSI.dim)} ${this.paint(status, ANSI.cyan)}`);
63
+ }
64
+ }
65
+ const breakdown = [];
66
+ if (generatedDistAssetCounts.jsCount > 0) breakdown.push(this.paint(`${generatedDistAssetCounts.jsCount} modules`, ANSI.green));
67
+ if (generatedDistAssetCounts.cssCount > 0) breakdown.push(this.paint(`${generatedDistAssetCounts.cssCount} CSS`, ANSI.magenta));
68
+ if (pkgStats.customExports > 0) breakdown.push(this.paint(`${pkgStats.customExports} custom`, ANSI.yellow));
69
+ const totalExportsText = this.paint(`${pkgStats.totalExports} exports`, ANSI.brightCyan);
70
+ if (breakdown.length === 0) logger.out(` ${this.paint("└─", ANSI.dim)} ${totalExportsText}`);
71
+ else logger.out(` ${this.paint("└─", ANSI.dim)} ${breakdown.join(" + ")} = ${totalExportsText}`);
72
+ logger.out("");
73
+ }
74
+ logPrunedStaleExport(logger, exportSpecifier) {
75
+ logger.out(` ${this.paint("└─", ANSI.dim)} ${this.paint(`Pruned stale export: ${exportSpecifier}`, ANSI.gray)}`);
76
+ }
77
+ logPackageError(logger, index, total, displayName, errorValue, verbose) {
78
+ logger.out(`${this.paint(`[${index}/${total}]`, ANSI.dim)} ${this.paint("✗", ANSI.yellow)} ${this.paint(displayName, ANSI.bold)}`);
79
+ logger.out(` ${this.paint("└─", ANSI.dim)} ${this.paint(`Error: ${messageFrom(errorValue)}`, ANSI.yellow)}\n`);
80
+ if (verbose) logger.err(errorValue instanceof Error && errorValue.stack ? errorValue.stack : messageFrom(errorValue));
81
+ }
82
+ mirrorSummarySeparator(logger) {
83
+ logger.out(this.paint("═".repeat(60), ANSI.dim));
84
+ }
85
+ mirrorSummary(logger, stats, elapsedSeconds) {
86
+ logger.out(`${this.paint("📊 Summary", ANSI.bold)} ${this.paint(`(completed in ${elapsedSeconds.toFixed(2)}s)`, ANSI.dim)}\n`);
87
+ logger.out(` ${this.paint("Packages:", ANSI.bold)}`);
88
+ logger.out(` ${this.paint("├─", ANSI.dim)} Processed: ${this.paint(String(stats.packagesProcessed), ANSI.green)}`);
89
+ if (stats.packagesSkipped > 0) logger.out(` ${this.paint("├─", ANSI.dim)} Skipped: ${this.paint(String(stats.packagesSkipped), ANSI.gray)}`);
90
+ if (stats.packagesErrored > 0) logger.out(` ${this.paint("├─", ANSI.dim)} Errors: ${this.paint(String(stats.packagesErrored), ANSI.yellow)}`);
91
+ logger.out(` ${this.paint("└─", ANSI.dim)} Total found: ${stats.packagesFound}\n`);
92
+ logger.out(` ${this.paint("Exports:", ANSI.bold)}`);
93
+ logger.out(` ${this.paint("├─", ANSI.dim)} JS Modules: ${this.paint(String(stats.totalJsModules), ANSI.cyan)}`);
94
+ logger.out(` ${this.paint("├─", ANSI.dim)} CSS Files: ${this.paint(String(stats.totalCssExports), ANSI.magenta)}`);
95
+ logger.out(` ${this.paint("└─", ANSI.dim)} Total: ${this.paint(String(stats.totalExports), ANSI.brightCyan)}\n`);
96
+ logger.out(`${this.paint("═".repeat(60), ANSI.dim)}\n`);
97
+ }
98
+ paint(text, openSequence) {
99
+ if (!this.colorsAreEnabled) return text;
100
+ return `${openSequence}${text}${ANSI.reset}`;
101
+ }
102
+ };
103
+ //#endregion
104
+ export { MirrorSyncReporter };
@@ -0,0 +1,103 @@
1
+ import { messageFrom } from "../core/errors.mjs";
2
+ import { DIST_DIR, PACKAGE_JSON } from "./domain/constants.mjs";
3
+ import { createPathTransform, generateExports } from "./domain/exports.mjs";
4
+ import { resolvePackageDisplayName } from "./domain/package-display-name.mjs";
5
+ import { writePackageJsonExportsAtomic } from "./write-exports.mjs";
6
+ import { createMirrorDistFilesystem } from "./dist-filesystem-impl.mjs";
7
+ import path from "node:path";
8
+ //#region src/mirror/sync-workspace-package.ts
9
+ /**
10
+ * @since 0.3.16-canary.0
11
+ */
12
+ async function syncExportsForWorkspacePackage(fs, rootDir, packagePathStr, config) {
13
+ const pathJoin = path.join;
14
+ const pathResolve = path.resolve;
15
+ const pathBasename = path.basename;
16
+ const packageDir = pathResolve(rootDir, packagePathStr);
17
+ const distDir = pathJoin(packageDir, DIST_DIR);
18
+ const packageJsonPath = pathJoin(packageDir, PACKAGE_JSON);
19
+ const folderBasename = pathBasename(packageDir);
20
+ const distFilesystem = createMirrorDistFilesystem(fs);
21
+ const pkgStats = {
22
+ name: folderBasename,
23
+ path: packageDir,
24
+ jsModules: 0,
25
+ cssExports: 0,
26
+ customExports: 0,
27
+ totalExports: 0,
28
+ hasTransform: false,
29
+ cssConfigStatus: "",
30
+ skipped: false,
31
+ skipReason: "",
32
+ error: null,
33
+ prunedExportKeys: []
34
+ };
35
+ if (!fs.existsSync(packageJsonPath)) {
36
+ pkgStats.skipped = true;
37
+ pkgStats.skipReason = "package.json not found";
38
+ return pkgStats;
39
+ }
40
+ let packageJsonParseError;
41
+ let parsedPackageJson;
42
+ try {
43
+ const packageContent = await fs.readFile(packageJsonPath, "utf8");
44
+ const rawPackageJson = JSON.parse(packageContent);
45
+ if (rawPackageJson === null || typeof rawPackageJson !== "object" || Array.isArray(rawPackageJson)) throw new SyntaxError("package.json root must be a JSON object");
46
+ parsedPackageJson = rawPackageJson;
47
+ pkgStats.name = resolvePackageDisplayName(parsedPackageJson, folderBasename);
48
+ } catch (caughtError) {
49
+ pkgStats.name = folderBasename;
50
+ packageJsonParseError = caughtError;
51
+ }
52
+ const packageMeta = { packageName: pkgStats.name };
53
+ if (isPackageSkipped(config.skipPackages, packageMeta)) {
54
+ pkgStats.skipped = true;
55
+ pkgStats.skipReason = "configured to skip";
56
+ return pkgStats;
57
+ }
58
+ if (packageJsonParseError !== void 0) {
59
+ if (!fs.existsSync(distDir)) {
60
+ pkgStats.skipped = true;
61
+ pkgStats.skipReason = "dist/ not found";
62
+ return pkgStats;
63
+ }
64
+ pkgStats.error = messageFrom(packageJsonParseError);
65
+ return pkgStats;
66
+ }
67
+ if (!fs.existsSync(distDir)) {
68
+ pkgStats.skipped = true;
69
+ pkgStats.skipReason = "dist/ not found";
70
+ return pkgStats;
71
+ }
72
+ try {
73
+ const pathTransform = createPathTransform(config, packageMeta);
74
+ pkgStats.hasTransform = !!pathTransform;
75
+ const cssConfig = resolvePackageScopedConfig(config.cssExports, packageMeta);
76
+ if (cssConfig === false) pkgStats.cssConfigStatus = "disabled";
77
+ else if (cssConfig !== void 0) pkgStats.cssConfigStatus = "configured";
78
+ const customExports = resolvePackageScopedConfig(config.customExports, packageMeta) || {};
79
+ const generatedExports = await generateExports(distFilesystem, distDir, pathTransform, cssConfig, customExports);
80
+ const { prunedKeys } = await writePackageJsonExportsAtomic(fs, packageJsonPath, {
81
+ generatedExports: generatedExports.exports,
82
+ managedExportSpecifiers: Object.keys(generatedExports.exports),
83
+ originalPathBySpecifier: generatedExports.originalPathBySpecifier
84
+ });
85
+ pkgStats.jsModules = generatedExports.jsCount;
86
+ pkgStats.cssExports = generatedExports.cssCount;
87
+ pkgStats.customExports = Object.keys(customExports).length;
88
+ pkgStats.totalExports = Object.keys(generatedExports.exports).length;
89
+ pkgStats.prunedExportKeys = prunedKeys;
90
+ } catch (caughtError) {
91
+ pkgStats.error = messageFrom(caughtError);
92
+ }
93
+ return pkgStats;
94
+ }
95
+ function resolvePackageScopedConfig(configMap, packageMeta) {
96
+ if (!configMap) return;
97
+ return configMap[packageMeta.packageName];
98
+ }
99
+ function isPackageSkipped(skipPackagesList, packageMeta) {
100
+ return !!skipPackagesList?.includes(packageMeta.packageName);
101
+ }
102
+ //#endregion
103
+ export { syncExportsForWorkspacePackage };
@@ -0,0 +1,87 @@
1
+ import { AppError, messageFrom } from "../core/errors.mjs";
2
+ import { err, ok } from "../core/result.mjs";
3
+ import { listWorkspacePackageDirectories } from "../core/workspace/resolver.mjs";
4
+ import { normalizePath } from "./domain/path-normalizer.mjs";
5
+ import { resolvePackageFilterUnderRoot } from "./package-path.mjs";
6
+ import { syncExportsForWorkspacePackage } from "./sync-workspace-package.mjs";
7
+ import path from "node:path";
8
+ //#region src/mirror/sync.ts
9
+ /**
10
+ * @since 0.3.16-canary.0
11
+ */
12
+ async function runMirrorSync(fs, input) {
13
+ const config = input.config ?? {};
14
+ const { listener } = input;
15
+ listener?.onBanner();
16
+ const startTime = performance.now();
17
+ try {
18
+ let targetPackages = [];
19
+ if (input.packageFilter) {
20
+ const filterOutcome = resolvePackageFilterUnderRoot(fs, input.rootDir, input.packageFilter);
21
+ if (!filterOutcome.ok) return filterOutcome;
22
+ targetPackages = [filterOutcome.value];
23
+ listener?.onProcessingMode({ kind: "single" });
24
+ } else {
25
+ const layoutOutcome = await listWorkspacePackageDirectories(input.rootDir, fs, false);
26
+ const { relPaths, multiSource } = mirrorTargetsFromWorkspaceLayout(input.rootDir, layoutOutcome);
27
+ targetPackages = relPaths;
28
+ listener?.onProcessingMode({
29
+ kind: "multi",
30
+ source: multiSource
31
+ });
32
+ }
33
+ const stats = {
34
+ packagesFound: targetPackages.length,
35
+ packagesProcessed: 0,
36
+ packagesSkipped: 0,
37
+ packagesErrored: 0,
38
+ totalExports: 0,
39
+ totalJsModules: 0,
40
+ totalCssExports: 0,
41
+ packageDetails: []
42
+ };
43
+ if (targetPackages.length === 0) {
44
+ listener?.onNoPackages();
45
+ listener?.onComplete(stats, (performance.now() - startTime) / 1e3);
46
+ return ok(stats);
47
+ }
48
+ let ordinal = 1;
49
+ for (const pkgPath of targetPackages) {
50
+ const pkgStats = await syncExportsForWorkspacePackage(fs, input.rootDir, pkgPath, config);
51
+ stats.packageDetails.push(pkgStats);
52
+ listener?.onPackageComplete(pkgStats, ordinal, targetPackages.length);
53
+ ordinal++;
54
+ accumulateStats(stats, pkgStats);
55
+ }
56
+ const elapsed = (performance.now() - startTime) / 1e3;
57
+ listener?.onComplete(stats, elapsed);
58
+ return ok(stats);
59
+ } catch (caughtError) {
60
+ return err(new AppError("INFRA_FAILURE", messageFrom(caughtError), caughtError));
61
+ }
62
+ }
63
+ function accumulateStats(stats, pkgStats) {
64
+ if (pkgStats.skipped) stats.packagesSkipped++;
65
+ else if (pkgStats.error !== null) stats.packagesErrored++;
66
+ else {
67
+ stats.packagesProcessed++;
68
+ stats.totalExports += pkgStats.totalExports;
69
+ stats.totalJsModules += pkgStats.jsModules;
70
+ stats.totalCssExports += pkgStats.cssExports;
71
+ }
72
+ }
73
+ function mirrorTargetsFromWorkspaceLayout(rootDir, layoutOutcome) {
74
+ if (layoutOutcome.layoutSource === "declared-empty") return {
75
+ relPaths: [],
76
+ multiSource: "declared-empty"
77
+ };
78
+ const multiSource = layoutOutcome.layoutSource;
79
+ const relPaths = layoutOutcome.packageDirectoryPathsAbsolute.map((absolutePath) => normalizePath(path.relative(rootDir, absolutePath))).filter((relativePath) => relativePath.length > 0);
80
+ relPaths.sort((left, right) => left.localeCompare(right));
81
+ return {
82
+ relPaths,
83
+ multiSource
84
+ };
85
+ }
86
+ //#endregion
87
+ export { runMirrorSync };
@@ -1,36 +1,40 @@
1
- import { messageFromCaughtUnknown } from "../../core/domain/caught-unknown-message.value-object.mjs";
2
- import { MirrorError, MirrorErrorCode } from "../domain/errors.domain.mjs";
3
- import { PACKAGE_JSON_EXPORT } from "../domain/constants.domain.mjs";
4
- //#region src/lib/mirror/infrastructure/package-json-exports.repository.ts
5
- function containsDistTarget(value) {
6
- if (typeof value === "string") return value.startsWith("./dist/");
7
- if (Array.isArray(value)) return value.some((entryValue) => containsDistTarget(entryValue));
8
- if (value && typeof value === "object") return Object.values(value).some((entryValue) => containsDistTarget(entryValue));
9
- return false;
10
- }
11
- /**
12
- * Keep `./package.json` at the very end for aesthetics by default.
13
- * If a catch-all `./*` exists, move `./package.json` before wildcards so it remains reachable.
14
- */ function exportSpecifierRank(exportSpecifier, hasCatchAllWildcard) {
15
- if (exportSpecifier === ".") return 0;
16
- if (exportSpecifier === "./package.json") return hasCatchAllWildcard ? 2 : 4;
17
- if (exportSpecifier.includes("*")) return 3;
18
- return 1;
19
- }
20
- function compareExportSpecifiers(leftSpecifier, rightSpecifier, originalPathBySpecifier, hasCatchAllWildcard) {
21
- const leftRank = exportSpecifierRank(leftSpecifier, hasCatchAllWildcard);
22
- const rightRank = exportSpecifierRank(rightSpecifier, hasCatchAllWildcard);
23
- if (leftRank !== rightRank) return leftRank - rightRank;
24
- const leftOriginalPath = originalPathBySpecifier[leftSpecifier] ?? leftSpecifier;
25
- const rightOriginalPath = originalPathBySpecifier[rightSpecifier] ?? rightSpecifier;
26
- const originalPathComparison = leftOriginalPath.localeCompare(rightOriginalPath);
27
- if (originalPathComparison !== 0) return originalPathComparison;
28
- return leftSpecifier.localeCompare(rightSpecifier);
29
- }
1
+ import { messageFrom } from "../core/errors.mjs";
2
+ import { PACKAGE_JSON_EXPORT } from "./domain/constants.mjs";
3
+ import { MirrorError, MirrorErrorCode } from "./domain/errors.mjs";
4
+ //#region src/mirror/write-exports.ts
30
5
  /**
31
6
  * Writes `exports` into `package.json` via a temp file + rename (atomic on same volume).
32
7
  * Preserves a trailing newline after JSON.
33
- */ async function writePackageJsonExportsAtomic(fs, packageJsonPath, mergeInput) {
8
+ *
9
+ * @since 0.3.16-canary.0
10
+ */
11
+ async function writePackageJsonExportsAtomic(fs, packageJsonPath, mergeInput) {
12
+ function containsDistTarget(value) {
13
+ if (typeof value === "string") return value.startsWith("./dist/");
14
+ if (Array.isArray(value)) return value.some((entryValue) => containsDistTarget(entryValue));
15
+ if (value && typeof value === "object") return Object.values(value).some((entryValue) => containsDistTarget(entryValue));
16
+ return false;
17
+ }
18
+ /**
19
+ * Keep `./package.json` at the very end for aesthetics by default.
20
+ * If a catch-all `./*` exists, move `./package.json` before wildcards so it remains reachable.
21
+ */
22
+ function exportSpecifierRank(exportSpecifier, hasCatchAllWildcard) {
23
+ if (exportSpecifier === ".") return 0;
24
+ if (exportSpecifier === "./package.json") return hasCatchAllWildcard ? 2 : 4;
25
+ if (exportSpecifier.includes("*")) return 3;
26
+ return 1;
27
+ }
28
+ function compareExportSpecifiers(leftSpecifier, rightSpecifier, pathBySpecifier, hasCatchAllWildcard) {
29
+ const leftRank = exportSpecifierRank(leftSpecifier, hasCatchAllWildcard);
30
+ const rightRank = exportSpecifierRank(rightSpecifier, hasCatchAllWildcard);
31
+ if (leftRank !== rightRank) return leftRank - rightRank;
32
+ const leftOriginalPath = pathBySpecifier[leftSpecifier] ?? leftSpecifier;
33
+ const rightOriginalPath = pathBySpecifier[rightSpecifier] ?? rightSpecifier;
34
+ const originalPathComparison = leftOriginalPath.localeCompare(rightOriginalPath);
35
+ if (originalPathComparison !== 0) return originalPathComparison;
36
+ return leftSpecifier.localeCompare(rightSpecifier);
37
+ }
34
38
  const raw = await fs.readFile(packageJsonPath, "utf8");
35
39
  const packageJson = JSON.parse(raw);
36
40
  const existingExports = packageJson.exports;
@@ -81,7 +85,7 @@ function compareExportSpecifiers(leftSpecifier, rightSpecifier, originalPathBySp
81
85
  await fs.rename(tmpPath, packageJsonPath);
82
86
  } catch (caughtRenameError) {
83
87
  await fs.unlink(tmpPath).catch(() => {});
84
- throw new MirrorError(MirrorErrorCode.PACKAGE_WRITE, `Failed to atomically update ${packageJsonPath}: ${messageFromCaughtUnknown(caughtRenameError)}`, caughtRenameError instanceof Error ? { cause: caughtRenameError } : void 0);
88
+ throw new MirrorError(MirrorErrorCode.PACKAGE_WRITE, `Failed to atomically update ${packageJsonPath}: ${messageFrom(caughtRenameError)}`, caughtRenameError instanceof Error ? { cause: caughtRenameError } : void 0);
85
89
  }
86
90
  return { prunedKeys };
87
91
  }
@@ -0,0 +1,11 @@
1
+ import "../core/exit-codes.mjs";
2
+ //#region src/tag/cli-result.ts
3
+ /**
4
+ * @since 0.3.16-canary.0
5
+ */
6
+ function exitCodeForTagSyncResult(result) {
7
+ if (result.selectedTargets.length === 0) return 1;
8
+ return result.targetResults.some((targetResult) => targetResult.runError !== null) || result.hookError !== null ? 1 : 0;
9
+ }
10
+ //#endregion
11
+ export { exitCodeForTagSyncResult };
@@ -1,5 +1,8 @@
1
1
  import { z } from "zod";
2
- //#region src/lib/tag/presentation/tag-cli.schema.ts
2
+ //#region src/tag/cli-schema.ts
3
+ /**
4
+ * @since 0.3.16-canary.0
5
+ */
3
6
  const tagSyncRunRequestSchema = z.object({
4
7
  rootDir: z.string().min(1),
5
8
  write: z.boolean(),
@@ -0,0 +1,56 @@
1
+ import { parseWithSchema } from "../core/schema-parse.mjs";
2
+ import { logger } from "../core/logger.mjs";
3
+ import { consumeCliAppError } from "../core/cli/result-handle.mjs";
4
+ import { nodeFilesystem } from "../core/filesystem/node.mjs";
5
+ import { readOptionalPositionalArg } from "../core/cli/positional.mjs";
6
+ import { prepareTagSync } from "./prepare.mjs";
7
+ import { runTagSync } from "./sync.mjs";
8
+ import { tagSyncRunRequestSchema } from "./cli-schema.mjs";
9
+ import { exitCodeForTagSyncResult } from "./cli-result.mjs";
10
+ import { TagSyncProgressPresenter, presentTagSyncResult } from "./output.mjs";
11
+ import process from "node:process";
12
+ import { Command } from "commander";
13
+ //#region src/tag/command.ts
14
+ /**
15
+ * @since 0.3.16-canary.0
16
+ */
17
+ function createTagCommand() {
18
+ return new Command("tag").description("Add @since <version> JSDoc tags to exported declarations").alias("annotate").argument("[target]", "Directory or file to annotate (default: auto-discover workspace packages)").option("--dry-run", "Show summary without writing files", false).option("--json", "Print one JSON summary on stdout (suppresses human progress)", false).action(async (target, opts) => {
19
+ const prelude = await prepareTagSync(nodeFilesystem, {
20
+ currentWorkingDirectory: process.cwd(),
21
+ rawTarget: readOptionalPositionalArg(target)
22
+ });
23
+ if (!consumeCliAppError(prelude)) return;
24
+ const { rootDir, config, resolvedTargetPath } = prelude.value;
25
+ const tagConfig = config.tag ?? {};
26
+ const parsed = parseWithSchema(tagSyncRunRequestSchema, {
27
+ rootDir,
28
+ write: !opts.dryRun,
29
+ json: opts.json,
30
+ targetPath: resolvedTargetPath,
31
+ skipPackages: tagConfig.skipPackages,
32
+ config: tagConfig
33
+ });
34
+ if (!consumeCliAppError(parsed)) return;
35
+ const progressPresenter = new TagSyncProgressPresenter();
36
+ const tagOutcome = await runTagSync(nodeFilesystem, {
37
+ ...parsed.value,
38
+ listener: parsed.value.json ? void 0 : progressPresenter
39
+ });
40
+ if (!consumeCliAppError(tagOutcome)) return;
41
+ if (parsed.value.json) {
42
+ logger.out(formatTagSyncJsonOutput(tagOutcome.value, rootDir));
43
+ process.exitCode = exitCodeForTagSyncResult(tagOutcome.value);
44
+ } else process.exitCode = presentTagSyncResult(tagOutcome.value, rootDir);
45
+ });
46
+ }
47
+ function formatTagSyncJsonOutput(result, rootDir) {
48
+ return JSON.stringify({
49
+ schemaVersion: 1,
50
+ ok: result.hookError === null,
51
+ cwd: rootDir,
52
+ result
53
+ });
54
+ }
55
+ //#endregion
56
+ export { createTagCommand };
@@ -1,14 +1,53 @@
1
- import "../../core/domain/cli-exit-codes.domain.mjs";
2
- import { exitCodeForTagSyncResult } from "../application/tag-sync-cli-result.mjs";
3
- import { TAG_COLORS, withTagColor } from "./colors.presenter.mjs";
4
- //#region src/lib/tag/presentation/tag-sync.presenter.ts
5
- function targetDisplayName(target) {
6
- return target.packageName ?? target.rootRelativeTargetPath;
1
+ import "../core/exit-codes.mjs";
2
+ import { logger } from "../core/logger.mjs";
3
+ import { exitCodeForTagSyncResult } from "./cli-result.mjs";
4
+ //#region src/tag/output.ts
5
+ /**
6
+ * @since 0.3.16-canary.0
7
+ */
8
+ var TagSyncProgressPresenter = class TagSyncProgressPresenter {
9
+ onTargetStarted(target) {
10
+ logger.out(TagSyncProgressPresenter.formatProgress({
11
+ type: "target-started",
12
+ target
13
+ }));
14
+ }
15
+ onTargetCompleted(target, result) {
16
+ logger.out(TagSyncProgressPresenter.formatProgress({
17
+ type: "target-completed",
18
+ target,
19
+ result
20
+ }));
21
+ }
22
+ static formatProgress(event) {
23
+ const targetDisplayName = (target) => target.packageName ?? target.rootRelativeTargetPath;
24
+ if (event.type === "target-started") return `[tag] Processing ${targetDisplayName(event.target)}...`;
25
+ const changedFiles = event.result.result?.filesChanged ?? 0;
26
+ return `[tag] Done ${targetDisplayName(event.target)} (${changedFiles} changes)`;
27
+ }
28
+ };
29
+ const colorReset = "\x1B[0m";
30
+ const colors = {
31
+ red: "\x1B[31m",
32
+ green: "\x1B[32m",
33
+ yellow: "\x1B[33m"
34
+ };
35
+ /**
36
+ * @since 0.3.16-canary.0
37
+ */
38
+ function presentTagSyncResult(result, rootDir) {
39
+ logger.out(formatTargetTable(result.selectedTargets, rootDir));
40
+ if (result.selectedTargets.length === 0) {
41
+ logger.err("No packages found in workspace. Check your pnpm-workspace.yaml or provide an explicit target path.");
42
+ return 1;
43
+ }
44
+ const warningsAndErrorsSection = formatWarningsAndErrors(result);
45
+ if (warningsAndErrorsSection) logger.err(warningsAndErrorsSection);
46
+ logger.out(formatSummary(result));
47
+ return exitCodeForTagSyncResult(result);
7
48
  }
8
- function formatProgress(event) {
9
- if (event.type === "target-started") return `[tag] Processing ${targetDisplayName(event.target)}...`;
10
- const changedFiles = event.result.result?.filesChanged ?? 0;
11
- return `[tag] Done ${targetDisplayName(event.target)} (${changedFiles} changes)`;
49
+ function withColorizedLine(line, colorCode) {
50
+ return `${colorCode}${line}${colorReset}`;
12
51
  }
13
52
  function warningsAndErrorsFromResult(result) {
14
53
  const entries = [];
@@ -31,31 +70,18 @@ function formatTargetTable(targets, rootDir) {
31
70
  function formatWarningsAndErrors(result) {
32
71
  const entries = warningsAndErrorsFromResult(result);
33
72
  if (entries.length === 0) return null;
34
- const lines = [withTagColor("⚠️ Warnings & Errors", TAG_COLORS.YELLOW)];
35
- for (const entry of entries) lines.push(withTagColor(`- ${entry}`, TAG_COLORS.RED));
73
+ const lines = [withColorizedLine("⚠️ Warnings & Errors", colors.yellow)];
74
+ for (const entry of entries) lines.push(withColorizedLine(`- ${entry}`, colors.red));
36
75
  return lines.join("\n");
37
76
  }
38
77
  function formatSummary(result) {
39
78
  const isDryRun = result.mode === "dry-run";
40
79
  const summaryPrefix = isDryRun ? "[tag:dry-run]" : "[tag]";
41
80
  const versionSuffix = result.versionSummary === "mixed" && result.distinctVersions.length > 0 ? ` [${result.distinctVersions.join(", ")}]` : "";
42
- const summaryColor = result.targetResults.some((targetResult) => targetResult.runError !== null) || result.hookError !== null ? TAG_COLORS.RED : isDryRun ? TAG_COLORS.YELLOW : TAG_COLORS.GREEN;
43
- const lines = [withTagColor(`${summaryPrefix} version=${result.versionSummary}${versionSuffix} files=${result.filesChanged}/${result.filesScanned} declarations=${result.taggedDeclarations}`, summaryColor)];
81
+ const summaryColor = result.targetResults.some((targetResult) => targetResult.runError !== null) || result.hookError !== null ? colors.red : isDryRun ? colors.yellow : colors.green;
82
+ const lines = [withColorizedLine(`${summaryPrefix} version=${result.versionSummary}${versionSuffix} files=${result.filesChanged}/${result.filesScanned} declarations=${result.taggedDeclarations}`, summaryColor)];
44
83
  if (result.skippedPackages.length > 0) lines.push(`[tag] Skipped: ${result.skippedPackages.length} package(s)`);
45
84
  return lines.join("\n");
46
85
  }
47
- /**
48
- * Prints tag sync output and returns a process exit code (0 success, 1 when empty targets or hook/run errors).
49
- */ function presentTagSyncCliResult(logger, tagResult, rootDir) {
50
- logger.out(formatTargetTable(tagResult.selectedTargets, rootDir));
51
- if (tagResult.selectedTargets.length === 0) {
52
- logger.err("No packages found in workspace. Check your pnpm-workspace.yaml or provide an explicit target path.");
53
- return 1;
54
- }
55
- const warningsAndErrorsSection = formatWarningsAndErrors(tagResult);
56
- if (warningsAndErrorsSection) logger.err(warningsAndErrorsSection);
57
- logger.out(formatSummary(tagResult));
58
- return exitCodeForTagSyncResult(tagResult);
59
- }
60
86
  //#endregion
61
- export { formatProgress, presentTagSyncCliResult };
87
+ export { TagSyncProgressPresenter, presentTagSyncResult };
@@ -0,0 +1,29 @@
1
+ import { ok } from "../core/result.mjs";
2
+ import { loadCodefastConfig } from "../core/config.mjs";
3
+ import { findRepoRoot } from "../core/workspace/resolver.mjs";
4
+ import { resolveProvidedTagTargetPath } from "./resolve-target-path.mjs";
5
+ //#region src/tag/prepare.ts
6
+ /**
7
+ * @since 0.3.16-canary.0
8
+ */
9
+ async function prepareTagSync(fs, args) {
10
+ let rootDir;
11
+ try {
12
+ rootDir = findRepoRoot(args.currentWorkingDirectory, fs);
13
+ } catch {
14
+ rootDir = args.currentWorkingDirectory;
15
+ }
16
+ const loadedOutcome = await loadCodefastConfig(rootDir, fs);
17
+ if (!loadedOutcome.ok) return loadedOutcome;
18
+ const resolvedTargetPath = resolveProvidedTagTargetPath(fs, {
19
+ currentWorkingDirectory: args.currentWorkingDirectory,
20
+ rawTarget: args.rawTarget
21
+ });
22
+ return ok({
23
+ rootDir,
24
+ config: loadedOutcome.value.config,
25
+ resolvedTargetPath
26
+ });
27
+ }
28
+ //#endregion
29
+ export { prepareTagSync };
@@ -0,0 +1,12 @@
1
+ import path from "node:path";
2
+ //#region src/tag/resolve-target-path.ts
3
+ /**
4
+ * @since 0.3.16-canary.0
5
+ */
6
+ function resolveProvidedTagTargetPath(fs, args) {
7
+ if (args.rawTarget === void 0) return;
8
+ const candidate = path.isAbsolute(args.rawTarget) ? path.resolve(args.rawTarget) : path.resolve(args.currentWorkingDirectory, args.rawTarget);
9
+ return fs.canonicalPathSync(candidate);
10
+ }
11
+ //#endregion
12
+ export { resolveProvidedTagTargetPath };