@savvy-web/silk-effects 1.3.1 → 1.5.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 (62) hide show
  1. package/changesets/categories/types.js +0 -1
  2. package/changesets/changelog/index.js +0 -2
  3. package/changesets/constants.js +0 -1
  4. package/changesets/errors.js +25 -2
  5. package/changesets/index.js +17 -2
  6. package/changesets/markdownlint/rules/dependency-table-format.js +2 -2
  7. package/changesets/remark/rules/uncategorized-content.js +1 -1
  8. package/changesets/schemas/changeset.js +0 -1
  9. package/changesets/schemas/dependency-table.js +0 -1
  10. package/changesets/schemas/git.js +0 -1
  11. package/changesets/schemas/github.js +0 -1
  12. package/changesets/schemas/options.js +0 -1
  13. package/changesets/schemas/package-scope.js +0 -1
  14. package/changesets/schemas/primitives.js +0 -1
  15. package/changesets/schemas/release-plan.js +56 -0
  16. package/changesets/schemas/version-files.js +0 -1
  17. package/changesets/services/branch-analyzer.js +0 -1
  18. package/changesets/services/config-inspector.js +1 -2
  19. package/changesets/services/release-planner.js +251 -0
  20. package/changesets/services/workspace-snapshot.js +0 -1
  21. package/changesets/utils/publishability.js +2 -3
  22. package/changesets/utils/worktree-snapshot.js +1 -1
  23. package/commitlint/config/factory.js +1 -1
  24. package/commitlint/hook/diagnostics/package-manager.js +1 -1
  25. package/commitlint/index.js +0 -1
  26. package/errors/BiomeSyncError.js +2 -1
  27. package/errors/ChangesetConfigError.js +2 -1
  28. package/errors/ConfigNotFoundError.js +2 -1
  29. package/errors/SectionParseError.js +1 -0
  30. package/errors/SectionValidationError.js +1 -0
  31. package/errors/SectionWriteError.js +1 -0
  32. package/errors/TagFormatError.js +2 -1
  33. package/errors/ToolNotFoundError.js +1 -0
  34. package/errors/ToolResolutionError.js +1 -0
  35. package/errors/ToolVersionMismatchError.js +1 -0
  36. package/errors/VersioningDetectionError.js +2 -1
  37. package/errors/WorkspaceAnalysisError.js +2 -1
  38. package/index.d.ts +420 -85
  39. package/lint/handlers/PnpmWorkspace.js +1 -1
  40. package/package.json +5 -1
  41. package/schemas/CommentStyle.js +1 -0
  42. package/schemas/ResolvedTool.js +2 -1
  43. package/schemas/SavvySections.js +6 -1
  44. package/schemas/SectionBlock.js +3 -2
  45. package/schemas/SectionDefinition.js +4 -2
  46. package/schemas/SectionResults.js +12 -3
  47. package/schemas/TagStrategySchemas.js +2 -1
  48. package/schemas/ToolDefinition.js +2 -1
  49. package/schemas/ToolResults.js +18 -4
  50. package/schemas/VersioningSchemas.js +7 -3
  51. package/schemas/WorkspaceAnalysisSchemas.js +3 -0
  52. package/services/BiomeSchemaSync.js +4 -0
  53. package/services/ChangesetConfig.js +2 -0
  54. package/services/ChangesetConfigReader.js +4 -2
  55. package/services/ConfigDiscovery.js +2 -0
  56. package/services/ManagedSection.js +2 -0
  57. package/services/SilkPublishability.js +16 -12
  58. package/services/SilkWorkspaceAnalyzer.js +4 -2
  59. package/services/TagStrategy.js +3 -1
  60. package/services/ToolDiscovery.js +2 -0
  61. package/services/VersioningStrategy.js +2 -0
  62. package/utils/ToolCommand.js +2 -1
@@ -16,7 +16,6 @@ import { Schema } from "effect";
16
16
  * @see {@link resolveCommitType} for mapping commit types to categories
17
17
  * @see {@link https://effect.website/docs/schema/introduction | Effect Schema documentation}
18
18
  *
19
- * @packageDocumentation
20
19
  */
21
20
  /**
22
21
  * Schema for a section category that defines how changes are grouped in release notes.
@@ -56,8 +56,6 @@ import { Effect, Layer } from "effect";
56
56
  *
57
57
  * @see {@link getReleaseLine} in `./getReleaseLine.ts` for individual changeset formatting
58
58
  * @see {@link getDependencyReleaseLine} in `./getDependencyReleaseLine.ts` for dependency table formatting
59
- *
60
- * @packageDocumentation
61
59
  */
62
60
  /**
63
61
  * Combined layer providing all services needed by the formatters.
@@ -16,7 +16,6 @@
16
16
  * - `CSH005` -- Frontmatter validation
17
17
  *
18
18
  * @internal
19
- * @packageDocumentation
20
19
  */
21
20
  /** Base URL for rule documentation on GitHub. */
22
21
  const DOCS_BASE = "https://github.com/savvy-web/changesets/blob/main/docs/rules";
@@ -16,7 +16,6 @@ import { Data } from "effect";
16
16
  *
17
17
  * @see {@link https://effect.website/docs/data-types/data#taggerror | Effect TaggedError documentation}
18
18
  *
19
- * @packageDocumentation
20
19
  */
21
20
  /**
22
21
  * Base class for {@link ChangesetValidationError}.
@@ -300,6 +299,30 @@ var GitError = class extends GitErrorBase {
300
299
  return `git command failed in ${this.cwd}: ${this.command}\n${this.reason}`;
301
300
  }
302
301
  };
302
+ /**
303
+ * Base class for {@link ReleasePlanError}.
304
+ *
305
+ * @privateRemarks
306
+ * Required export for api-extractor (anonymous Data.TaggedError base). Do not delete.
307
+ *
308
+ * @internal
309
+ */
310
+ const ReleasePlanErrorBase = Data.TaggedError("ReleasePlanError");
311
+ /**
312
+ * Release planning, preview, or apply failure.
313
+ *
314
+ * @remarks
315
+ * Wraps any failure from the underlying `@changesets/*` machinery
316
+ * (`getReleasePlan`, `applyReleasePlan`, config resolution) into a typed
317
+ * Effect error, tagged with the phase that failed.
318
+ *
319
+ * @public
320
+ */
321
+ var ReleasePlanError = class extends ReleasePlanErrorBase {
322
+ get message() {
323
+ return `Release plan error (${this.phase}): ${this.reason}`;
324
+ }
325
+ };
303
326
 
304
327
  //#endregion
305
- export { ChangesetValidationError, ChangesetValidationErrorBase, ConfigurationError, ConfigurationErrorBase, GitError, GitErrorBase, GitHubApiError, GitHubApiErrorBase, MarkdownParseError, MarkdownParseErrorBase, VersionFileError, VersionFileErrorBase };
328
+ export { ChangesetValidationError, ChangesetValidationErrorBase, ConfigurationError, ConfigurationErrorBase, GitError, GitErrorBase, GitHubApiError, GitHubApiErrorBase, MarkdownParseError, MarkdownParseErrorBase, ReleasePlanError, ReleasePlanErrorBase, VersionFileError, VersionFileErrorBase };
@@ -1,6 +1,6 @@
1
1
  import { __exportAll } from "../_virtual/_rolldown/runtime.js";
2
2
  import { Categories } from "./api/categories.js";
3
- import { ChangesetValidationError, ChangesetValidationErrorBase, ConfigurationError, ConfigurationErrorBase, GitError, GitErrorBase, GitHubApiError, GitHubApiErrorBase, MarkdownParseError, MarkdownParseErrorBase, VersionFileError, VersionFileErrorBase } from "./errors.js";
3
+ import { ChangesetValidationError, ChangesetValidationErrorBase, ConfigurationError, ConfigurationErrorBase, GitError, GitErrorBase, GitHubApiError, GitHubApiErrorBase, MarkdownParseError, MarkdownParseErrorBase, ReleasePlanError, ReleasePlanErrorBase, VersionFileError, VersionFileErrorBase } from "./errors.js";
4
4
  import { JsonPathSchema, LegacyVersionFileConfigSchema, LegacyVersionFilesSchema, VersionFileConfigSchema, VersionFilesSchema } from "./schemas/version-files.js";
5
5
  import { GlobSchema, PackageScopeSchema, PackagesRecordSchema } from "./schemas/package-scope.js";
6
6
  import { ChangesetOptionsSchema, RepoSchema } from "./schemas/options.js";
@@ -28,13 +28,15 @@ import { ChangelogTransformer } from "./api/transformer.js";
28
28
  import { ClassificationReasonSchema, ClassificationSchema, ConfigInspector, ConfigInspectorBase, ConfigInspectorLive, InspectedConfigSchema, ResolvedPackageScopeSchema, ResolvedVersionFileSchema, makeConfigInspectorTest } from "./services/config-inspector.js";
29
29
  import { BranchAnalysisSchema, BranchAnalyzer, BranchAnalyzerBase, BranchAnalyzerLive, BranchFileEntrySchema, FileStatusSchema, makeBranchAnalyzerTest } from "./services/branch-analyzer.js";
30
30
  import { ChangelogService, ChangelogServiceBase } from "./services/changelog.js";
31
+ import { VersionFiles } from "./utils/version-files.js";
32
+ import { ReleasePlanner, ReleasePlannerBase, ReleasePlannerLive, makeReleasePlannerTest } from "./services/release-planner.js";
31
33
  import { WorkspaceSnapshotReader, WorkspaceSnapshotReaderBase, WorkspaceSnapshotReaderLive } from "./services/workspace-snapshot.js";
32
34
  import { SectionCategorySchema } from "./categories/types.js";
33
35
  import { CommitHashSchema, VersionTypeSchema } from "./schemas/git.js";
34
36
  import { ChangesetSchema, ChangesetSummarySchema, DependencyTypeSchema, DependencyUpdateSchema } from "./schemas/changeset.js";
37
+ import { AppliedReleaseEntrySchema, AppliedReleaseSchema, BumpTypeSchema, ChangesetPreviewSchema, PendingChangesetSchema, PreviewReleaseSchema, VersionFileUpdateRecordSchema } from "./schemas/release-plan.js";
35
38
  import { computeWorkspaceDependencyDiffs } from "./utils/dep-diff.js";
36
39
  import { listPublishablePackageNames } from "./utils/publishability.js";
37
- import { VersionFiles } from "./utils/version-files.js";
38
40
  import { gitMergeBase, snapshotFromWorktree } from "./utils/worktree-snapshot.js";
39
41
  import { ContentStructureRule as ContentStructureRule$1 } from "./markdownlint/rules/content-structure.js";
40
42
  import { DependencyTableFormatRule } from "./markdownlint/rules/dependency-table-format.js";
@@ -49,11 +51,14 @@ import { SilkChangesetPreset, SilkChangesetTransformPreset } from "./remark/pres
49
51
  //#region src/changesets/index.ts
50
52
  var changesets_exports = /* @__PURE__ */ __exportAll({
51
53
  AggregateDependencyTablesPlugin: () => AggregateDependencyTablesPlugin,
54
+ AppliedReleaseEntrySchema: () => AppliedReleaseEntrySchema,
55
+ AppliedReleaseSchema: () => AppliedReleaseSchema,
52
56
  BranchAnalysisSchema: () => BranchAnalysisSchema,
53
57
  BranchAnalyzer: () => BranchAnalyzer,
54
58
  BranchAnalyzerBase: () => BranchAnalyzerBase,
55
59
  BranchAnalyzerLive: () => BranchAnalyzerLive,
56
60
  BranchFileEntrySchema: () => BranchFileEntrySchema,
61
+ BumpTypeSchema: () => BumpTypeSchema,
57
62
  Categories: () => Categories,
58
63
  Changelog: () => Changelog,
59
64
  ChangelogService: () => ChangelogService,
@@ -61,6 +66,7 @@ var changesets_exports = /* @__PURE__ */ __exportAll({
61
66
  ChangelogTransformer: () => ChangelogTransformer,
62
67
  ChangesetLinter: () => ChangesetLinter,
63
68
  ChangesetOptionsSchema: () => ChangesetOptionsSchema,
69
+ ChangesetPreviewSchema: () => ChangesetPreviewSchema,
64
70
  ChangesetSchema: () => ChangesetSchema,
65
71
  ChangesetSummarySchema: () => ChangesetSummarySchema,
66
72
  ChangesetValidationError: () => ChangesetValidationError,
@@ -116,7 +122,14 @@ var changesets_exports = /* @__PURE__ */ __exportAll({
116
122
  NormalizeFormatPlugin: () => NormalizeFormatPlugin,
117
123
  PackageScopeSchema: () => PackageScopeSchema,
118
124
  PackagesRecordSchema: () => PackagesRecordSchema,
125
+ PendingChangesetSchema: () => PendingChangesetSchema,
119
126
  PositiveInteger: () => PositiveInteger,
127
+ PreviewReleaseSchema: () => PreviewReleaseSchema,
128
+ ReleasePlanError: () => ReleasePlanError,
129
+ ReleasePlanErrorBase: () => ReleasePlanErrorBase,
130
+ ReleasePlanner: () => ReleasePlanner,
131
+ ReleasePlannerBase: () => ReleasePlannerBase,
132
+ ReleasePlannerLive: () => ReleasePlannerLive,
120
133
  ReorderSectionsPlugin: () => ReorderSectionsPlugin,
121
134
  RepoSchema: () => RepoSchema,
122
135
  RequiredSectionsRule: () => RequiredSectionsRule,
@@ -132,6 +145,7 @@ var changesets_exports = /* @__PURE__ */ __exportAll({
132
145
  VersionFileConfigSchema: () => VersionFileConfigSchema,
133
146
  VersionFileError: () => VersionFileError,
134
147
  VersionFileErrorBase: () => VersionFileErrorBase,
148
+ VersionFileUpdateRecordSchema: () => VersionFileUpdateRecordSchema,
135
149
  VersionFiles: () => VersionFiles,
136
150
  VersionFilesSchema: () => VersionFilesSchema,
137
151
  VersionOrEmptySchema: () => VersionOrEmptySchema,
@@ -146,6 +160,7 @@ var changesets_exports = /* @__PURE__ */ __exportAll({
146
160
  makeBranchAnalyzerTest: () => makeBranchAnalyzerTest,
147
161
  makeConfigInspectorTest: () => makeConfigInspectorTest,
148
162
  makeGitHubTest: () => makeGitHubTest,
163
+ makeReleasePlannerTest: () => makeReleasePlannerTest,
149
164
  serializeDependencyTableToMarkdown: () => serializeDependencyTableToMarkdown,
150
165
  snapshotFromWorktree: () => snapshotFromWorktree
151
166
  });
@@ -3,7 +3,7 @@ import { getHeadingLevel, getHeadingText } from "./utils.js";
3
3
 
4
4
  //#region src/changesets/markdownlint/rules/dependency-table-format.ts
5
5
  const EM_DASH = "—";
6
- const VALID_TYPES = new Set([
6
+ const VALID_TYPES = /* @__PURE__ */ new Set([
7
7
  "dependency",
8
8
  "devDependency",
9
9
  "peerDependency",
@@ -11,7 +11,7 @@ const VALID_TYPES = new Set([
11
11
  "workspace",
12
12
  "config"
13
13
  ]);
14
- const VALID_ACTIONS = new Set([
14
+ const VALID_ACTIONS = /* @__PURE__ */ new Set([
15
15
  "added",
16
16
  "updated",
17
17
  "removed"
@@ -7,7 +7,7 @@ import { lintRule } from "unified-lint-rule";
7
7
  *
8
8
  * @internal
9
9
  */
10
- const IGNORED_TYPES = new Set(["html"]);
10
+ const IGNORED_TYPES = /* @__PURE__ */ new Set(["html"]);
11
11
  /**
12
12
  * Determine whether a node is substantive content (not a heading or ignored type).
13
13
  *
@@ -16,7 +16,6 @@ import { Schema } from "effect";
16
16
  * @see {@link https://github.com/changesets/changesets | Changesets documentation}
17
17
  * @see {@link https://effect.website/docs/schema/introduction | Effect Schema documentation}
18
18
  *
19
- * @packageDocumentation
20
19
  */
21
20
  /**
22
21
  * Schema for a changeset summary (1--1000 characters).
@@ -21,7 +21,6 @@ import { Schema } from "effect";
21
21
  * @see {@link DependencyUpdateSchema} for the simpler Changesets API format
22
22
  * @see {@link https://effect.website/docs/schema/introduction | Effect Schema documentation}
23
23
  *
24
- * @packageDocumentation
25
24
  */
26
25
  /**
27
26
  * Valid dependency table actions.
@@ -6,7 +6,6 @@ import { Schema } from "effect";
6
6
  *
7
7
  * @see {@link https://effect.website/docs/schema/introduction | Effect Schema documentation}
8
8
  *
9
- * @packageDocumentation
10
9
  */
11
10
  /**
12
11
  * Schema for a git commit hash (at least 7 lowercase hex characters).
@@ -13,7 +13,6 @@ import { Schema } from "effect";
13
13
  *
14
14
  * @see {@link https://effect.website/docs/schema/introduction | Effect Schema documentation}
15
15
  *
16
- * @packageDocumentation
17
16
  */
18
17
  /**
19
18
  * Test whether a string is a valid URL.
@@ -21,7 +21,6 @@ import { Effect, Schema } from "effect";
21
21
  * @see {@link https://github.com/changesets/changesets/blob/main/docs/config-file-options.md | Changesets config docs}
22
22
  * @see {@link https://effect.website/docs/schema/introduction | Effect Schema documentation}
23
23
  *
24
- * @packageDocumentation
25
24
  */
26
25
  /** Regex for `owner/repo` format, shared between schema and validation. */
27
26
  const REPO_PATTERN = /^[a-zA-Z0-9._-]+\/[a-zA-Z0-9._-]+$/;
@@ -40,7 +40,6 @@ import { Schema } from "effect";
40
40
  * @see {@link VersionFileConfigSchema} for the version-file entry shape
41
41
  * @see {@link https://effect.website/docs/schema/introduction | Effect Schema documentation}
42
42
  *
43
- * @packageDocumentation
44
43
  */
45
44
  /**
46
45
  * Schema for a single repo-relative glob pattern.
@@ -12,7 +12,6 @@ import { Schema } from "effect";
12
12
  *
13
13
  * @see {@link https://effect.website/docs/schema/introduction | Effect Schema documentation}
14
14
  *
15
- * @packageDocumentation
16
15
  */
17
16
  /**
18
17
  * A non-empty string schema.
@@ -0,0 +1,56 @@
1
+ import { Schema } from "effect";
2
+
3
+ //#region src/changesets/schemas/release-plan.ts
4
+ /**
5
+ * Result schemas for the {@link ReleasePlanner} service — the structured
6
+ * preview of pending releases and the result of a native apply.
7
+ *
8
+ */
9
+ /** A semantic-version bump level (the `"none"` plan type is filtered out upstream). @public */
10
+ const BumpTypeSchema = Schema.Literal("major", "minor", "patch");
11
+ /** One package's previewed release: version transition + rendered changelog block. @public */
12
+ const PreviewReleaseSchema = Schema.Struct({
13
+ name: Schema.String,
14
+ type: BumpTypeSchema,
15
+ oldVersion: Schema.String,
16
+ newVersion: Schema.String,
17
+ changesetIds: Schema.Array(Schema.String),
18
+ changelogEntry: Schema.String
19
+ }).annotations({ identifier: "PreviewRelease" });
20
+ /** A parsed pending changeset (id + summary + the packages it bumps). @public */
21
+ const PendingChangesetSchema = Schema.Struct({
22
+ id: Schema.String,
23
+ summary: Schema.String,
24
+ releases: Schema.Array(Schema.Struct({
25
+ name: Schema.String,
26
+ type: BumpTypeSchema
27
+ }))
28
+ }).annotations({ identifier: "PendingChangeset" });
29
+ /** Read-only preview of what the next release would produce. @public */
30
+ const ChangesetPreviewSchema = Schema.Struct({
31
+ preMode: Schema.NullOr(Schema.Literal("exit", "pre")),
32
+ releases: Schema.Array(PreviewReleaseSchema),
33
+ changesets: Schema.Array(PendingChangesetSchema)
34
+ }).annotations({ identifier: "ChangesetPreview" });
35
+ /** One applied package release (version transition). @public */
36
+ const AppliedReleaseEntrySchema = Schema.Struct({
37
+ name: Schema.String,
38
+ type: BumpTypeSchema,
39
+ oldVersion: Schema.String,
40
+ newVersion: Schema.String
41
+ }).annotations({ identifier: "AppliedReleaseEntry" });
42
+ /** A single versionFiles update applied (or planned, when dry). @public */
43
+ const VersionFileUpdateRecordSchema = Schema.Struct({
44
+ filePath: Schema.String,
45
+ version: Schema.String
46
+ }).annotations({ identifier: "VersionFileUpdateRecord" });
47
+ /** Result of {@link ReleasePlanner.apply}. @public */
48
+ const AppliedReleaseSchema = Schema.Struct({
49
+ dryRun: Schema.Boolean,
50
+ touchedFiles: Schema.Array(Schema.String),
51
+ releases: Schema.Array(AppliedReleaseEntrySchema),
52
+ versionFileUpdates: Schema.Array(VersionFileUpdateRecordSchema)
53
+ }).annotations({ identifier: "AppliedRelease" });
54
+
55
+ //#endregion
56
+ export { AppliedReleaseEntrySchema, AppliedReleaseSchema, BumpTypeSchema, ChangesetPreviewSchema, PendingChangesetSchema, PreviewReleaseSchema, VersionFileUpdateRecordSchema };
@@ -26,7 +26,6 @@ import { Schema } from "effect";
26
26
  * @see {@link PackageScopeSchema} for the new per-package container
27
27
  * @see {@link https://effect.website/docs/schema/introduction | Effect Schema documentation}
28
28
  *
29
- * @packageDocumentation
30
29
  */
31
30
  /**
32
31
  * Schema for a JSONPath expression starting with `$.`.
@@ -43,7 +43,6 @@ import { execFileSync } from "node:child_process";
43
43
  * @see {@link BranchAnalyzerLive} for the production layer
44
44
  * @see {@link ConfigInspector} for the underlying classification service
45
45
  *
46
- * @packageDocumentation
47
46
  */
48
47
  /** Git diff status as reported by `--name-status`. @public */
49
48
  const FileStatusSchema = Schema.Literal("added", "modified", "deleted", "renamed", "copied", "typechange", "unmerged", "unknown").annotations({ identifier: "FileStatus" });
@@ -41,7 +41,6 @@ import { WorkspaceDiscovery } from "workspaces-effect";
41
41
  * @see {@link ConfigInspector} for the Effect service tag
42
42
  * @see {@link ConfigInspectorLive} for the production layer
43
43
  *
44
- * @packageDocumentation
45
44
  */
46
45
  /** A `versionFiles` entry expanded to its absolute target paths. @public */
47
46
  const ResolvedVersionFileSchema = Schema.Struct({
@@ -454,7 +453,7 @@ function classifyOne(inspected, path) {
454
453
  /**
455
454
  * Live layer for {@link ConfigInspector}.
456
455
  *
457
- * Requires {@link ChangesetConfigReader} and {@link WorkspaceDiscovery}
456
+ * Requires {@link ChangesetConfigReader} and `WorkspaceDiscovery`
458
457
  * in the environment.
459
458
  *
460
459
  * @public
@@ -0,0 +1,251 @@
1
+ import { ReleasePlanError } from "../errors.js";
2
+ import { ChangelogTransformer } from "../api/transformer.js";
3
+ import { ConfigInspector } from "./config-inspector.js";
4
+ import { VersionFiles } from "../utils/version-files.js";
5
+ import { Context, Effect, Layer } from "effect";
6
+ import { cpSync, existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync } from "node:fs";
7
+ import { isAbsolute, join, relative } from "node:path";
8
+ import { tmpdir } from "node:os";
9
+ import applyReleasePlan from "@changesets/apply-release-plan";
10
+ import { read } from "@changesets/config";
11
+ import getReleasePlan from "@changesets/get-release-plan";
12
+ import { getPackages } from "@manypkg/get-packages";
13
+
14
+ //#region src/changesets/services/release-planner.ts
15
+ /**
16
+ * `ReleasePlanner` service — drive the genuine changesets release engine to
17
+ * compute a plan, render a read-only preview, or natively apply a release.
18
+ *
19
+ * @remarks
20
+ * `preview` and `apply` both run the real `@changesets/apply-release-plan`;
21
+ * `preview` redirects every write into a throwaway temp directory by handing
22
+ * the engine a `@manypkg`-shaped `Packages` object whose `dir`s point at temp,
23
+ * then reads the generated CHANGELOG blocks back. No changesets-internal logic
24
+ * (e.g. `getChangelogEntry`) is re-implemented.
25
+ *
26
+ */
27
+ /** Single workspace-discovery seam; swap to an Effect-native stack later here. */
28
+ const buildPackages = (root) => getPackages(root);
29
+ const errMsg = (e) => e instanceof Error ? e.message : String(e);
30
+ const _tag = Context.Tag("ReleasePlanner");
31
+ /**
32
+ * Base class for {@link ReleasePlanner}.
33
+ *
34
+ * @privateRemarks Required export for api-extractor (anonymous Context.Tag base). Do not delete.
35
+ * @internal
36
+ */
37
+ const ReleasePlannerBase = _tag();
38
+ /** Effect service tag for the release planner. @public */
39
+ var ReleasePlanner = class extends ReleasePlannerBase {};
40
+ /** Build the service shape over a resolved {@link ConfigInspector}. */
41
+ function makeShape(inspector) {
42
+ const plan = (root) => Effect.tryPromise({
43
+ try: () => getReleasePlan(root),
44
+ catch: (e) => new ReleasePlanError({
45
+ phase: "plan",
46
+ reason: errMsg(e)
47
+ })
48
+ });
49
+ const preview = (root) => Effect.tryPromise({
50
+ try: () => previewImpl(root),
51
+ catch: (e) => new ReleasePlanError({
52
+ phase: "preview",
53
+ reason: errMsg(e)
54
+ })
55
+ });
56
+ const apply = (root, options) => applyEffect(root, options?.dryRun ?? false, inspector);
57
+ return {
58
+ plan,
59
+ preview,
60
+ apply
61
+ };
62
+ }
63
+ /** Production layer. Requires {@link ConfigInspector} (used by `apply`). @public */
64
+ const ReleasePlannerLive = Layer.effect(ReleasePlanner, Effect.gen(function* () {
65
+ return makeShape(yield* ConfigInspector);
66
+ }));
67
+ /**
68
+ * Test factory — supply fixed results for any subset of methods. Unsupplied
69
+ * methods fail with a `ReleasePlanError`.
70
+ *
71
+ * @public
72
+ */
73
+ function makeReleasePlannerTest(fixed) {
74
+ const fail = (phase) => Effect.fail(new ReleasePlanError({
75
+ phase,
76
+ reason: "not provided in test layer"
77
+ }));
78
+ return Layer.succeed(ReleasePlanner, {
79
+ plan: () => fixed.plan ? Effect.succeed(fixed.plan) : fail("plan"),
80
+ preview: () => fixed.preview ? Effect.succeed(fixed.preview) : fail("preview"),
81
+ apply: () => fixed.apply ? Effect.succeed(fixed.apply) : fail("apply")
82
+ });
83
+ }
84
+ /** Extract the `## <version>` block (down to the next H2 or EOF) from a changelog. */
85
+ function extractVersionBlock(changelog, version) {
86
+ const lines = changelog.split("\n");
87
+ const start = lines.findIndex((l) => l.trim() === `## ${version}`);
88
+ if (start === -1) return "";
89
+ let end = lines.length;
90
+ for (let i = start + 1; i < lines.length; i++) if (/^## /.test(lines[i])) {
91
+ end = i;
92
+ break;
93
+ }
94
+ return lines.slice(start, end).join("\n").trim();
95
+ }
96
+ async function previewImpl(root) {
97
+ const [plan, packages] = await Promise.all([getReleasePlan(root), buildPackages(root)]);
98
+ const config = await read(root, packages);
99
+ const preMode = plan.preState ? plan.preState.mode : null;
100
+ const changesets = plan.changesets.map((cs) => ({
101
+ id: cs.id,
102
+ summary: cs.summary,
103
+ releases: cs.releases.filter((r) => r.type !== "none").map((r) => ({
104
+ name: r.name,
105
+ type: r.type
106
+ }))
107
+ }));
108
+ const releasesToRender = plan.releases.filter((r) => r.type !== "none");
109
+ if (releasesToRender.length === 0) return {
110
+ preMode,
111
+ releases: [],
112
+ changesets
113
+ };
114
+ const tempRoot = mkdtempSync(join(tmpdir(), "silk-preview-"));
115
+ try {
116
+ const mapDir = (dir) => {
117
+ const rel = relative(packages.root.dir, dir);
118
+ if (rel.startsWith("..") || isAbsolute(rel)) throw new Error(`Package directory is outside the workspace root: ${dir}`);
119
+ return join(tempRoot, rel);
120
+ };
121
+ const tempPackages = {
122
+ tool: packages.tool,
123
+ root: {
124
+ ...packages.root,
125
+ dir: tempRoot,
126
+ packageJson: structuredClone(packages.root.packageJson)
127
+ },
128
+ packages: packages.packages.map((p) => ({
129
+ ...p,
130
+ dir: mapDir(p.dir),
131
+ packageJson: structuredClone(p.packageJson)
132
+ }))
133
+ };
134
+ mkdirSync(join(tempRoot, ".changeset"), { recursive: true });
135
+ cpSync(join(root, "package.json"), join(tempRoot, "package.json"));
136
+ const preJson = join(root, ".changeset", "pre.json");
137
+ if (existsSync(preJson)) cpSync(preJson, join(tempRoot, ".changeset", "pre.json"));
138
+ for (const p of packages.packages) {
139
+ const tDir = mapDir(p.dir);
140
+ mkdirSync(tDir, { recursive: true });
141
+ cpSync(join(p.dir, "package.json"), join(tDir, "package.json"));
142
+ const realCl = join(p.dir, "CHANGELOG.md");
143
+ if (existsSync(realCl)) cpSync(realCl, join(tDir, "CHANGELOG.md"));
144
+ }
145
+ const rootCl = join(packages.root.dir, "CHANGELOG.md");
146
+ if (existsSync(rootCl)) cpSync(rootCl, join(tempRoot, "CHANGELOG.md"));
147
+ await applyReleasePlan(plan, tempPackages, config, void 0, root);
148
+ const dirByName = /* @__PURE__ */ new Map();
149
+ for (const p of tempPackages.packages) dirByName.set(p.packageJson.name, p.dir);
150
+ if (tempPackages.root.packageJson.name) dirByName.set(tempPackages.root.packageJson.name, tempRoot);
151
+ const releases = [];
152
+ for (const r of releasesToRender) {
153
+ const dir = dirByName.get(r.name);
154
+ if (!dir) continue;
155
+ const clPath = join(dir, "CHANGELOG.md");
156
+ if (!existsSync(clPath)) continue;
157
+ ChangelogTransformer.transformFile(clPath);
158
+ const content = readFileSync(clPath, "utf-8");
159
+ releases.push({
160
+ name: r.name,
161
+ type: r.type,
162
+ oldVersion: r.oldVersion,
163
+ newVersion: r.newVersion,
164
+ changesetIds: [...r.changesets],
165
+ changelogEntry: extractVersionBlock(content, r.newVersion)
166
+ });
167
+ }
168
+ return {
169
+ preMode,
170
+ releases,
171
+ changesets
172
+ };
173
+ } finally {
174
+ rmSync(tempRoot, {
175
+ recursive: true,
176
+ force: true
177
+ });
178
+ }
179
+ }
180
+ /** Re-read a package's version from disk (post-bump) to feed versionFiles. */
181
+ function diskVersion(workspaceDir, fallback) {
182
+ try {
183
+ return JSON.parse(readFileSync(join(workspaceDir, "package.json"), "utf-8")).version ?? fallback;
184
+ } catch {
185
+ return fallback;
186
+ }
187
+ }
188
+ function applyEffect(root, dryRun, inspector) {
189
+ return Effect.gen(function* () {
190
+ const { plan, packages, config } = yield* Effect.tryPromise({
191
+ try: async () => {
192
+ const [plan, packages] = await Promise.all([getReleasePlan(root), buildPackages(root)]);
193
+ return {
194
+ plan,
195
+ packages,
196
+ config: await read(root, packages)
197
+ };
198
+ },
199
+ catch: (e) => new ReleasePlanError({
200
+ phase: "apply",
201
+ reason: errMsg(e)
202
+ })
203
+ });
204
+ const releases = plan.releases.filter((r) => r.type !== "none").map((r) => ({
205
+ name: r.name,
206
+ type: r.type,
207
+ oldVersion: r.oldVersion,
208
+ newVersion: r.newVersion
209
+ }));
210
+ let touchedFiles = [];
211
+ if (!dryRun) touchedFiles = yield* Effect.tryPromise({
212
+ try: async () => {
213
+ const touched = await applyReleasePlan(plan, packages, config);
214
+ for (const f of touched) if (f.endsWith("CHANGELOG.md")) ChangelogTransformer.transformFile(f);
215
+ return touched;
216
+ },
217
+ catch: (e) => new ReleasePlanError({
218
+ phase: "apply",
219
+ reason: errMsg(e)
220
+ })
221
+ });
222
+ const newVersionByName = new Map(plan.releases.map((r) => [r.name, r.newVersion]));
223
+ const inspected = yield* inspector.inspect(root).pipe(Effect.catchAll((error) => Effect.logWarning(`Skipping versionFiles update: ${errMsg(error)}`).pipe(Effect.as(null))));
224
+ let versionFileUpdates = [];
225
+ if (inspected) versionFileUpdates = yield* Effect.try({
226
+ try: () => {
227
+ const scopes = inspected.packages.filter((p) => p.versionFiles.length > 0).map((p) => {
228
+ const fresh = dryRun ? newVersionByName.get(p.name) ?? p.version : diskVersion(p.workspaceDir, p.version);
229
+ return fresh !== p.version ? {
230
+ ...p,
231
+ version: fresh
232
+ } : p;
233
+ });
234
+ return scopes.length > 0 ? VersionFiles.processResolvedVersionFiles(scopes, dryRun) : [];
235
+ },
236
+ catch: (e) => new ReleasePlanError({
237
+ phase: "apply",
238
+ reason: errMsg(e)
239
+ })
240
+ });
241
+ return {
242
+ dryRun,
243
+ touchedFiles,
244
+ releases,
245
+ versionFileUpdates
246
+ };
247
+ });
248
+ }
249
+
250
+ //#endregion
251
+ export { ReleasePlanner, ReleasePlannerBase, ReleasePlannerLive, makeReleasePlannerTest };
@@ -22,7 +22,6 @@ import { execFileSync } from "node:child_process";
22
22
  * @see {@link WorkspaceSnapshotReader} for the service tag
23
23
  * @see {@link WorkspaceSnapshotReaderLive} for the production layer
24
24
  *
25
- * @packageDocumentation
26
25
  */
27
26
  const _tag = Context.Tag("WorkspaceSnapshotReader");
28
27
  /**
@@ -7,18 +7,17 @@ import { PublishabilityDetector } from "workspaces-effect";
7
7
  *
8
8
  * @remarks
9
9
  * Provides `listPublishablePackageNames`, a convenience wrapper around
10
- * {@link PublishabilityDetector} that returns a `Set<string>` of
10
+ * {@link SilkPublishability} that returns a `Set<string>` of
11
11
  * publishable package names. Used by the `deps detect` and `deps regen`
12
12
  * commands to filter out workspace packages whose dependency changes
13
13
  * would never reach a release.
14
14
  *
15
- * @packageDocumentation
16
15
  */
17
16
  /**
18
17
  * Compute the set of currently-publishable workspace package names.
19
18
  *
20
19
  * @remarks
21
- * Uses the currently-active {@link PublishabilityDetector} — wire the
20
+ * Uses the currently-active {@link SilkPublishability} — wire the
22
21
  * {@link SilkPublishabilityDetectorLive} layer to get silk semantics.
23
22
  *
24
23
  * @param packages - The workspace packages to evaluate
@@ -81,7 +81,7 @@ function normalizeWorkspaceGlob(glob) {
81
81
  */
82
82
  function snapshotFromWorktree(cwd) {
83
83
  const snapshots = [];
84
- const dirs = new Set([cwd]);
84
+ const dirs = /* @__PURE__ */ new Set([cwd]);
85
85
  for (const dir of expandWorkspaceDirs(cwd)) dirs.add(dir);
86
86
  for (const dir of dirs) try {
87
87
  const pkgJson = JSON.parse(readFileSync(join(dir, "package.json"), "utf8"));
@@ -26,7 +26,7 @@ function createConfig(options) {
26
26
  const cwd = options.cwd ?? process.cwd();
27
27
  const dco = process.env.COMMITLINT_SKIP_DCO === "1" || process.env.COMMITLINT_SKIP_DCO === "true" ? false : options.dco ?? detectDCO(cwd);
28
28
  const scopes = options.scopes ?? [];
29
- const allScopes = [...new Set([...scopes, ...options.additionalScopes ?? []])].sort();
29
+ const allScopes = [.../* @__PURE__ */ new Set([...scopes, ...options.additionalScopes ?? []])].sort();
30
30
  const rules = {
31
31
  "body-max-line-length": [
32
32
  2,
@@ -11,7 +11,7 @@ import { readFile } from "node:fs/promises";
11
11
  *
12
12
  * @internal
13
13
  */
14
- const VALID_PMS = new Set([
14
+ const VALID_PMS = /* @__PURE__ */ new Set([
15
15
  "pnpm",
16
16
  "yarn",
17
17
  "bun",
@@ -41,7 +41,6 @@ import { verbosityRule } from "./hook/rules/verbosity.js";
41
41
  * const config = Commitlint.CommitlintConfig.silk();
42
42
  * ```
43
43
  *
44
- * @packageDocumentation
45
44
  */
46
45
  var commitlint_exports = /* @__PURE__ */ __exportAll({
47
46
  COMMIT_TYPES: () => COMMIT_TYPES,