@savvy-web/silk-effects 2.0.1 → 2.1.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.
@@ -1,9 +1,5 @@
1
- import { ContributorFootnotesPlugin } from "../remark/plugins/contributor-footnotes.js";
2
- import { DeduplicateItemsPlugin } from "../remark/plugins/deduplicate-items.js";
3
- import { IssueLinkRefsPlugin } from "../remark/plugins/issue-link-refs.js";
4
- import { MergeSectionsPlugin } from "../remark/plugins/merge-sections.js";
5
- import { NormalizeFormatPlugin } from "../remark/plugins/normalize-format.js";
6
- import { ReorderSectionsPlugin } from "../remark/plugins/reorder-sections.js";
1
+ import { MaintenanceNotePlugin } from "../remark/plugins/maintenance-note.js";
2
+ import { SilkChangesetTransformPreset } from "../remark/presets.js";
7
3
  import remarkGfm from "remark-gfm";
8
4
  import remarkParse from "remark-parse";
9
5
  import remarkStringify from "remark-stringify";
@@ -24,23 +20,13 @@ import { readFileSync, writeFileSync } from "node:fs";
24
20
  * Static class for post-processing CHANGELOG.md files.
25
21
  *
26
22
  * Implements the third layer of the three-layer pipeline by running
27
- * six remark transform plugins in a fixed order to clean up, normalize,
28
- * and enhance changelog output produced by the formatter layer.
23
+ * the {@link SilkChangesetTransformPreset} plugins (currently seven) in a
24
+ * fixed order to clean up, normalize, and enhance changelog output produced
25
+ * by the formatter layer.
29
26
  *
30
27
  * @remarks
31
- * The six plugins run in this order:
32
- *
33
- * 1. **MergeSectionsPlugin** -- merges duplicate section headings (e.g., two
34
- * "Features" sections from separate changesets are combined into one)
35
- * 2. **ReorderSectionsPlugin** -- reorders sections by category priority
36
- * (Breaking Changes first, Other last) using the {@link Categories} priority values
37
- * 3. **DeduplicateItemsPlugin** -- removes duplicate list items within a section
38
- * 4. **ContributorFootnotesPlugin** -- converts inline contributor mentions
39
- * into footnote references for cleaner formatting
40
- * 5. **IssueLinkRefsPlugin** -- converts inline issue/PR links into markdown
41
- * reference-style links collected at the bottom of the document
42
- * 6. **NormalizeFormatPlugin** -- applies consistent formatting (spacing,
43
- * trailing newlines, heading levels)
28
+ * See {@link SilkChangesetTransformPreset} for the ordered plugin list and
29
+ * the rationale behind each plugin's position.
44
30
  *
45
31
  * The transformer operates on the full CHANGELOG.md content (all versions),
46
32
  * not just the latest release block. It is idempotent -- running it multiple
@@ -100,20 +86,27 @@ var ChangelogTransformer = class ChangelogTransformer {
100
86
  /* v8 ignore next -- private constructor prevents direct instantiation */
101
87
  constructor() {}
102
88
  /**
103
- * Transform CHANGELOG markdown content by running all six transform plugins.
89
+ * Transform CHANGELOG markdown content by running the
90
+ * {@link SilkChangesetTransformPreset} plugins.
104
91
  *
105
92
  * @remarks
106
93
  * The input is parsed with `remark-parse` and `remark-gfm` (for table
107
- * support), processed through all six plugins in order, and stringified
108
- * back to markdown. The operation is synchronous and idempotent.
94
+ * support), processed through every plugin in {@link SilkChangesetTransformPreset}
95
+ * in order, and stringified back to markdown. The operation is synchronous
96
+ * and idempotent.
109
97
  *
110
98
  * @param content - Raw CHANGELOG markdown string (may contain multiple
111
99
  * version blocks, GFM tables, footnotes, and reference links)
112
- * @returns The transformed markdown string with sections merged, reordered,
113
- * deduplicated, and normalized
100
+ * @param options - Optional transformation options, including maintenance note configuration
101
+ * @returns The transformed markdown string with dependency tables aggregated,
102
+ * sections merged, reordered, deduplicated, and normalized
114
103
  */
115
- static transformContent(content) {
116
- const file = unified().use(remarkParse).use(remarkGfm).use(MergeSectionsPlugin).use(ReorderSectionsPlugin).use(DeduplicateItemsPlugin).use(ContributorFootnotesPlugin).use(IssueLinkRefsPlugin).use(NormalizeFormatPlugin).use(remarkStringify).processSync(content);
104
+ static transformContent(content, options) {
105
+ const processor = unified().use(remarkParse).use(remarkGfm);
106
+ for (const plugin of SilkChangesetTransformPreset) processor.use(plugin);
107
+ if (options?.maintenance) processor.use(MaintenanceNotePlugin, options.maintenance);
108
+ processor.use(remarkStringify);
109
+ const file = processor.processSync(content);
117
110
  return String(file);
118
111
  }
119
112
  /**
@@ -129,10 +122,11 @@ var ChangelogTransformer = class ChangelogTransformer {
129
122
  * when invoked without the `--dry-run` or `--check` flags.
130
123
  *
131
124
  * @param filePath - Absolute or relative path to the CHANGELOG.md file
125
+ * @param options - Optional transformation options, including maintenance note configuration
132
126
  */
133
- static transformFile(filePath) {
127
+ static transformFile(filePath, options) {
134
128
  const content = readFileSync(filePath, "utf-8");
135
- writeFileSync(filePath, ChangelogTransformer.transformContent(content), "utf-8");
129
+ writeFileSync(filePath, ChangelogTransformer.transformContent(content, options), "utf-8");
136
130
  }
137
131
  };
138
132
 
@@ -26,8 +26,8 @@ const ISSUE_CATEGORIES = [
26
26
  /**
27
27
  * Format a changelog entry into a markdown string with GitHub links.
28
28
  *
29
- * Produces a commit-link prefix (shortened to 7 characters) followed by the
30
- * summary text and any issue references, each rendered as GitHub links.
29
+ * Produces the summary text followed by any issue references, each
30
+ * rendered as GitHub links.
31
31
  *
32
32
  * @remarks
33
33
  * The output does **not** include a leading `- ` list marker — the caller
@@ -37,13 +37,11 @@ const ISSUE_CATEGORIES = [
37
37
  *
38
38
  * Output format examples:
39
39
  *
40
- * With commit: `[short-hash](commit-url) Summary text`
40
+ * Without issues: `Summary text`
41
41
  *
42
42
  * With issues: `Summary text` followed by `Closes: [#1](issue-url)`
43
43
  *
44
- * With both: `[short-hash](commit-url) Summary text` followed by `Fixes: [#2](issue-url)`
45
- *
46
- * @param entry - The changelog entry containing commit, summary, and issue data
44
+ * @param entry - The changelog entry containing summary and issue data
47
45
  * @param options - Must include `repo` in `owner/repo` format for link generation
48
46
  * @returns Formatted markdown string (without leading `- `)
49
47
  *
@@ -51,10 +49,6 @@ const ISSUE_CATEGORIES = [
51
49
  */
52
50
  function formatChangelogEntry(entry, options) {
53
51
  const parts = [];
54
- if (entry.commit) {
55
- const shortHash = entry.commit.substring(0, 7);
56
- parts.push(`[\`${shortHash}\`](https://github.com/${options.repo}/commit/${entry.commit})`);
57
- }
58
52
  parts.push(entry.summary.trim());
59
53
  const issueLinks = [];
60
54
  for (const { key, label } of ISSUE_CATEGORIES) {
@@ -15,11 +15,14 @@ import { Effect } from "effect";
15
15
  * handles the "Updated dependencies" section that Changesets appends
16
16
  * when a package's dependencies are bumped as part of a release.
17
17
  *
18
- * The output is a GFM (GitHub Flavored Markdown) table with columns:
19
- * `Dependency`, `Type`, `Action`, `From`, `To`. The dependency type
20
- * is inferred from the consuming package's `package.json` fields
21
- * (`dependencies`, `devDependencies`, `peerDependencies`,
22
- * `optionalDependencies`) via the {@link inferDependencyType} helper.
18
+ * The output is a `### Dependencies` h3 heading followed by a GFM
19
+ * (GitHub Flavored Markdown) table with columns: `Dependency`, `Type`,
20
+ * `Action`, `From`, `To`. The dependency type is inferred from the
21
+ * consuming package's `package.json` fields (`dependencies`,
22
+ * `devDependencies`, `peerDependencies`, `optionalDependencies`) via
23
+ * the {@link inferDependencyType} helper. Downstream, the heading is
24
+ * consumed by `AggregateDependencyTablesPlugin`, which locates and
25
+ * merges per-package dependency tables during changelog assembly.
23
26
  *
24
27
  * ### Dependency type inference
25
28
  *
@@ -85,7 +88,8 @@ function inferDependencyType(dep) {
85
88
  * The function maps each `ModCompWithPackage` entry to a `DependencyTableRow`,
86
89
  * inferring the dependency type from the consuming package's `package.json`,
87
90
  * then delegates to `serializeDependencyTableToMarkdown` for GFM table
88
- * rendering. Returns an empty string when no dependencies were updated.
91
+ * rendering, prefixed with a `### Dependencies` heading. Returns an empty
92
+ * string when no dependencies were updated.
89
93
  *
90
94
  * The `_changesets` and `_options` parameters are part of the Changesets API
91
95
  * contract but are not used in the table format. They are retained for
@@ -94,19 +98,19 @@ function inferDependencyType(dep) {
94
98
  * @param _changesets - Changesets that caused the dependency updates (unused in table format)
95
99
  * @param dependenciesUpdated - The list of dependencies that were updated, including old/new versions
96
100
  * @param _options - Validated configuration options (unused in table format)
97
- * @returns An `Effect` that resolves to a formatted markdown table string, or empty string if no dependencies were updated
101
+ * @returns An `Effect` that resolves to a `### Dependencies` heading followed by a formatted markdown table string, or empty string if no dependencies were updated
98
102
  */
99
103
  function getDependencyReleaseLine(_changesets, dependenciesUpdated, _options) {
100
104
  return Effect.gen(function* () {
101
105
  if (dependenciesUpdated.length === 0) return "";
102
106
  yield* GitHubService;
103
- return serializeDependencyTableToMarkdown(dependenciesUpdated.map((dep) => ({
107
+ return `### Dependencies\n\n${serializeDependencyTableToMarkdown(dependenciesUpdated.map((dep) => ({
104
108
  dependency: dep.name,
105
109
  type: inferDependencyType(dep),
106
110
  action: "updated",
107
111
  from: dep.oldVersion,
108
112
  to: dep.newVersion
109
- })));
113
+ })))}`;
110
114
  });
111
115
  }
112
116
 
@@ -21,7 +21,7 @@ import { Effect, Schema } from "effect";
21
21
  *
22
22
  * 1. **Section-aware changesets** — When the changeset summary contains h2
23
23
  * headings (e.g., `## Features`, `## Bug Fixes`), each section is rendered
24
- * as an h3 heading with commit-linked list items beneath it. This mode
24
+ * as an h3 heading with list items beneath it. This mode
25
25
  * produces multi-line output suitable for rich changelogs.
26
26
  *
27
27
  * 2. **Flat-text changesets** — When the summary is plain text without section
@@ -31,7 +31,6 @@ import { Effect, Schema } from "effect";
31
31
  *
32
32
  * In both modes, the formatter:
33
33
  * - Fetches GitHub metadata (PR number, author) via {@link GitHubService}
34
- * - Generates shortened commit hash links (`[abc1234](...)`)
35
34
  * - Extracts and renders issue references (Closes, Fixes, Refs)
36
35
  * - Appends PR and user attribution when available
37
36
  *
@@ -62,7 +61,7 @@ import { Effect, Schema } from "effect";
62
61
  * `Fixes #N`, and `Refs #N` patterns.
63
62
  * 5. **Build attribution** — Format PR link and user credit from GitHub info.
64
63
  * 6. **Section-aware output** — If sections were found, render each as an
65
- * h3 heading with commit-linked list items.
64
+ * h3 heading with list items.
66
65
  * 7. **Flat-text fallback** — Otherwise, produce a single `- entry` line
67
66
  * with the resolved category heading.
68
67
  *
@@ -96,14 +95,16 @@ function getReleaseLine(changeset, versionType, options) {
96
95
  for (const section of parsed.sections) {
97
96
  lines.push(`### ${section.category.heading}`);
98
97
  lines.push("");
99
- const commitPrefix = changeset.commit ? `[\`${changeset.commit.substring(0, 7)}\`](https://github.com/${options.repo}/commit/${changeset.commit}) ` : "";
100
98
  if (section.content) {
101
99
  const contentLines = section.content.split("\n");
102
100
  const firstContentLine = contentLines[0];
103
101
  if (firstContentLine.startsWith("- ") || firstContentLine.startsWith("* ")) {
104
- lines.push(`${firstContentLine.substring(0, 2)}${commitPrefix}${firstContentLine.substring(2)}`);
102
+ lines.push(firstContentLine);
105
103
  lines.push(...contentLines.slice(1));
106
- } else lines.push(`- ${commitPrefix}${section.content}`);
104
+ } else {
105
+ lines.push(`- ${firstContentLine}`);
106
+ lines.push(...contentLines.slice(1).map((line) => line.length > 0 ? ` ${line}` : line));
107
+ }
107
108
  }
108
109
  lines.push("");
109
110
  }
@@ -112,8 +113,7 @@ function getReleaseLine(changeset, versionType, options) {
112
113
  return `- ${formatChangelogEntry({
113
114
  type: resolveCommitType(commitMsg.type ?? versionType, commitMsg.scope, commitMsg.breaking).heading,
114
115
  summary: changeset.summary,
115
- issues: issueRefs,
116
- ...changeset.commit ? { commit: changeset.commit } : {}
116
+ issues: issueRefs
117
117
  }, { repo: options.repo })}${attribution}`;
118
118
  });
119
119
  }
@@ -40,7 +40,7 @@ import { Effect, Layer } from "effect";
40
40
  * config is decoded through `ChangesetOptionsSchema`.
41
41
  * 2. **Release line formatting** — each changeset is formatted by
42
42
  * `getReleaseLine`, which resolves GitHub metadata, parses sections,
43
- * and produces structured markdown with commit links and attribution.
43
+ * and produces structured markdown with attribution.
44
44
  * 3. **Dependency table formatting** — bulk dependency updates are
45
45
  * formatted by `getDependencyReleaseLine` into a markdown table.
46
46
  *
@@ -19,12 +19,15 @@ import { HeadingHierarchyRule } from "./remark/rules/heading-hierarchy.js";
19
19
  import { RequiredSectionsRule } from "./remark/rules/required-sections.js";
20
20
  import { UncategorizedContentRule } from "./remark/rules/uncategorized-content.js";
21
21
  import { ChangesetLinter } from "./api/linter.js";
22
+ import { MaintenanceNotePlugin } from "./remark/plugins/maintenance-note.js";
23
+ import { AggregateDependencyTablesPlugin } from "./remark/plugins/aggregate-dependency-tables.js";
22
24
  import { ContributorFootnotesPlugin } from "./remark/plugins/contributor-footnotes.js";
23
25
  import { DeduplicateItemsPlugin } from "./remark/plugins/deduplicate-items.js";
24
26
  import { IssueLinkRefsPlugin } from "./remark/plugins/issue-link-refs.js";
25
27
  import { MergeSectionsPlugin } from "./remark/plugins/merge-sections.js";
26
28
  import { NormalizeFormatPlugin } from "./remark/plugins/normalize-format.js";
27
29
  import { ReorderSectionsPlugin } from "./remark/plugins/reorder-sections.js";
30
+ import { SilkChangesetPreset, SilkChangesetTransformPreset } from "./remark/presets.js";
28
31
  import { ChangelogTransformer } from "./api/transformer.js";
29
32
  import { ClassificationReasonSchema, ClassificationSchema, ConfigInspector, ConfigInspectorBase, ConfigInspectorLive, InspectedConfigSchema, ResolvedPackageScopeSchema, ResolvedVersionFileSchema, makeConfigInspectorTest } from "./services/config-inspector.js";
30
33
  import { BranchAnalysisSchema, BranchAnalyzer, BranchAnalyzerBase, BranchAnalyzerLive, BranchFileEntrySchema, FileStatusSchema, makeBranchAnalyzerTest } from "./services/branch-analyzer.js";
@@ -33,6 +36,7 @@ import { computeWorkspaceDependencyDiffs } from "./utils/dep-diff.js";
33
36
  import { gitMergeBase } from "./utils/git.js";
34
37
  import { listPublishablePackageNames } from "./utils/publishability.js";
35
38
  import { DepsRegen, DepsRegenBase, DepsRegenDefault, DepsRegenLive, isPureDependencyChangeset } from "./services/deps-regen.js";
39
+ import { MaintenanceReasonSchema, MaintenanceTriggerSchema, deriveMaintenanceReason } from "./services/maintenance-reason.js";
36
40
  import { VersionFiles } from "./utils/version-files.js";
37
41
  import { ReleasePlanner, ReleasePlannerBase, ReleasePlannerLive, makeReleasePlannerTest } from "./services/release-planner.js";
38
42
  import { SectionCategorySchema } from "./categories/types.js";
@@ -45,8 +49,6 @@ import { HeadingHierarchyRule as HeadingHierarchyRule$1 } from "./markdownlint/r
45
49
  import { RequiredSectionsRule as RequiredSectionsRule$1 } from "./markdownlint/rules/required-sections.js";
46
50
  import { UncategorizedContentRule as UncategorizedContentRule$1 } from "./markdownlint/rules/uncategorized-content.js";
47
51
  import SilkChangesetsRules from "./markdownlint/index.js";
48
- import { AggregateDependencyTablesPlugin } from "./remark/plugins/aggregate-dependency-tables.js";
49
- import { SilkChangesetPreset, SilkChangesetTransformPreset } from "./remark/presets.js";
50
52
 
51
53
  //#region src/changesets/index.ts
52
54
  var changesets_exports = /* @__PURE__ */ __exportAll({
@@ -113,6 +115,9 @@ var changesets_exports = /* @__PURE__ */ __exportAll({
113
115
  JsonPathSchema: () => JsonPathSchema,
114
116
  LegacyVersionFileConfigSchema: () => LegacyVersionFileConfigSchema,
115
117
  LegacyVersionFilesSchema: () => LegacyVersionFilesSchema,
118
+ MaintenanceNotePlugin: () => MaintenanceNotePlugin,
119
+ MaintenanceReasonSchema: () => MaintenanceReasonSchema,
120
+ MaintenanceTriggerSchema: () => MaintenanceTriggerSchema,
116
121
  MarkdownLive: () => MarkdownLive,
117
122
  MarkdownParseError: () => MarkdownParseError,
118
123
  MarkdownParseErrorBase: () => MarkdownParseErrorBase,
@@ -159,6 +164,7 @@ var changesets_exports = /* @__PURE__ */ __exportAll({
159
164
  VersionTypeSchema: () => VersionTypeSchema,
160
165
  changelogFunctions: () => changelogFunctions,
161
166
  computeWorkspaceDependencyDiffs: () => computeWorkspaceDependencyDiffs,
167
+ deriveMaintenanceReason: () => deriveMaintenanceReason,
162
168
  gitMergeBase: () => gitMergeBase,
163
169
  isPureDependencyChangeset: () => isPureDependencyChangeset,
164
170
  listPublishablePackageNames: () => listPublishablePackageNames,
@@ -170,4 +176,4 @@ var changesets_exports = /* @__PURE__ */ __exportAll({
170
176
  });
171
177
 
172
178
  //#endregion
173
- export { AggregateDependencyTablesPlugin, AppliedReleaseEntrySchema, AppliedReleaseSchema, BranchAnalysisSchema, BranchAnalyzer, BranchAnalyzerBase, BranchAnalyzerLive, BranchFileEntrySchema, BumpTypeSchema, Categories, Changelog, ChangelogService, ChangelogServiceBase, ChangelogTransformer, ChangesetIOError, ChangesetIOErrorBase, ChangesetLinter, ChangesetOptionsSchema, ChangesetPreviewSchema, ChangesetSchema, ChangesetSummarySchema, ChangesetValidationError, ChangesetValidationErrorBase, ClassificationReasonSchema, ClassificationSchema, CommitHashSchema, ConfigInspector, ConfigInspectorBase, ConfigInspectorLive, ConfigurationError, ConfigurationErrorBase, ContentStructureRule, ContributorFootnotesPlugin, DeduplicateItemsPlugin, DependencyActionSchema, DependencyTable, DependencyTableFormatRule, DependencyTableRowSchema, DependencyTableSchema, DependencyTableTypeSchema, DependencyTypeSchema, DependencyUpdateSchema, DepsRegen, DepsRegenBase, DepsRegenDefault, DepsRegenLive, FileStatusSchema, GitError, GitErrorBase, GitHubApiError, GitHubApiErrorBase, GitHubInfoSchema, GitHubLive, GitHubService, GitHubServiceBase, GlobSchema, HeadingHierarchyRule, InspectedConfigSchema, IssueLinkRefsPlugin, IssueNumberSchema, JsonPathSchema, LegacyVersionFileConfigSchema, LegacyVersionFilesSchema, MarkdownLive, MarkdownParseError, MarkdownParseErrorBase, MarkdownService, MarkdownServiceBase, ContentStructureRule$1 as MarkdownlintContentStructureRule, DependencyTableFormatRule$1 as MarkdownlintDependencyTableFormatRule, HeadingHierarchyRule$1 as MarkdownlintHeadingHierarchyRule, RequiredSectionsRule$1 as MarkdownlintRequiredSectionsRule, UncategorizedContentRule$1 as MarkdownlintUncategorizedContentRule, MergeSectionsPlugin, NonEmptyString, NormalizeFormatPlugin, PackageScopeSchema, PackagesRecordSchema, PendingChangesetSchema, PositiveInteger, PreviewReleaseSchema, ReleasePlanError, ReleasePlanErrorBase, ReleasePlanner, ReleasePlannerBase, ReleasePlannerLive, ReorderSectionsPlugin, RepoSchema, RequiredSectionsRule, ResolvedPackageScopeSchema, ResolvedVersionFileSchema, SectionCategorySchema, SilkChangesetPreset, SilkChangesetTransformPreset, SilkChangesetsRules, UncategorizedContentRule, UrlOrMarkdownLinkSchema, UsernameSchema, VERSION_RE, VersionFileConfigSchema, VersionFileError, VersionFileErrorBase, VersionFileUpdateRecordSchema, VersionFiles, VersionFilesSchema, VersionOrEmptySchema, VersionTypeSchema, changelogFunctions, changesets_exports, computeWorkspaceDependencyDiffs, gitMergeBase, isPureDependencyChangeset, listPublishablePackageNames, makeBranchAnalyzerTest, makeConfigInspectorTest, makeGitHubTest, makeReleasePlannerTest, serializeDependencyTableToMarkdown };
179
+ export { AggregateDependencyTablesPlugin, AppliedReleaseEntrySchema, AppliedReleaseSchema, BranchAnalysisSchema, BranchAnalyzer, BranchAnalyzerBase, BranchAnalyzerLive, BranchFileEntrySchema, BumpTypeSchema, Categories, Changelog, ChangelogService, ChangelogServiceBase, ChangelogTransformer, ChangesetIOError, ChangesetIOErrorBase, ChangesetLinter, ChangesetOptionsSchema, ChangesetPreviewSchema, ChangesetSchema, ChangesetSummarySchema, ChangesetValidationError, ChangesetValidationErrorBase, ClassificationReasonSchema, ClassificationSchema, CommitHashSchema, ConfigInspector, ConfigInspectorBase, ConfigInspectorLive, ConfigurationError, ConfigurationErrorBase, ContentStructureRule, ContributorFootnotesPlugin, DeduplicateItemsPlugin, DependencyActionSchema, DependencyTable, DependencyTableFormatRule, DependencyTableRowSchema, DependencyTableSchema, DependencyTableTypeSchema, DependencyTypeSchema, DependencyUpdateSchema, DepsRegen, DepsRegenBase, DepsRegenDefault, DepsRegenLive, FileStatusSchema, GitError, GitErrorBase, GitHubApiError, GitHubApiErrorBase, GitHubInfoSchema, GitHubLive, GitHubService, GitHubServiceBase, GlobSchema, HeadingHierarchyRule, InspectedConfigSchema, IssueLinkRefsPlugin, IssueNumberSchema, JsonPathSchema, LegacyVersionFileConfigSchema, LegacyVersionFilesSchema, MaintenanceNotePlugin, MaintenanceReasonSchema, MaintenanceTriggerSchema, MarkdownLive, MarkdownParseError, MarkdownParseErrorBase, MarkdownService, MarkdownServiceBase, ContentStructureRule$1 as MarkdownlintContentStructureRule, DependencyTableFormatRule$1 as MarkdownlintDependencyTableFormatRule, HeadingHierarchyRule$1 as MarkdownlintHeadingHierarchyRule, RequiredSectionsRule$1 as MarkdownlintRequiredSectionsRule, UncategorizedContentRule$1 as MarkdownlintUncategorizedContentRule, MergeSectionsPlugin, NonEmptyString, NormalizeFormatPlugin, PackageScopeSchema, PackagesRecordSchema, PendingChangesetSchema, PositiveInteger, PreviewReleaseSchema, ReleasePlanError, ReleasePlanErrorBase, ReleasePlanner, ReleasePlannerBase, ReleasePlannerLive, ReorderSectionsPlugin, RepoSchema, RequiredSectionsRule, ResolvedPackageScopeSchema, ResolvedVersionFileSchema, SectionCategorySchema, SilkChangesetPreset, SilkChangesetTransformPreset, SilkChangesetsRules, UncategorizedContentRule, UrlOrMarkdownLinkSchema, UsernameSchema, VERSION_RE, VersionFileConfigSchema, VersionFileError, VersionFileErrorBase, VersionFileUpdateRecordSchema, VersionFiles, VersionFilesSchema, VersionOrEmptySchema, VersionTypeSchema, changelogFunctions, changesets_exports, computeWorkspaceDependencyDiffs, deriveMaintenanceReason, gitMergeBase, isPureDependencyChangeset, listPublishablePackageNames, makeBranchAnalyzerTest, makeConfigInspectorTest, makeGitHubTest, makeReleasePlannerTest, serializeDependencyTableToMarkdown };
@@ -7,16 +7,18 @@ const DeduplicateItemsPlugin = () => {
7
7
  const blocks = getVersionBlocks(tree);
8
8
  for (const block of blocks) {
9
9
  const sections = getBlockSections(tree, block);
10
- for (const section of sections) for (const node of section.contentNodes) {
11
- if (node.type !== "list") continue;
12
- const list = node;
10
+ for (const section of sections) {
13
11
  const seen = /* @__PURE__ */ new Set();
14
- list.children = list.children.filter((item) => {
15
- const text = toString(item);
16
- if (seen.has(text)) return false;
17
- seen.add(text);
18
- return true;
19
- });
12
+ for (const node of section.contentNodes) {
13
+ if (node.type !== "list") continue;
14
+ const list = node;
15
+ list.children = list.children.filter((item) => {
16
+ const text = toString(item);
17
+ if (seen.has(text)) return false;
18
+ seen.add(text);
19
+ return true;
20
+ });
21
+ }
20
22
  }
21
23
  }
22
24
  tree.children = tree.children.filter((node) => {
@@ -0,0 +1,61 @@
1
+ import { getHeadingText, getVersionBlocks } from "../../utils/version-blocks.js";
2
+
3
+ //#region src/changesets/remark/plugins/maintenance-note.ts
4
+ function buildNoteChildren(reason) {
5
+ if (reason.kind === "unspecified" || reason.triggers.length === 0) return [{
6
+ type: "text",
7
+ value: "Version-only release to keep workspace versions consistent; no changes to this package."
8
+ }];
9
+ const label = reason.kind === "fixed" ? "fixed version group" : "linked version group";
10
+ const children = [{
11
+ type: "text",
12
+ value: "Released in lockstep with "
13
+ }];
14
+ reason.triggers.forEach((trigger, index) => {
15
+ if (index > 0) children.push({
16
+ type: "text",
17
+ value: ", "
18
+ });
19
+ children.push({
20
+ type: "inlineCode",
21
+ value: `${trigger.name}@${trigger.version}`
22
+ });
23
+ });
24
+ children.push({
25
+ type: "text",
26
+ value: ` (${label}).`
27
+ });
28
+ return children;
29
+ }
30
+ const MaintenanceNotePlugin = (options) => {
31
+ return (tree) => {
32
+ const block = getVersionBlocks(tree).find((b) => getHeadingText(tree.children[b.headingIndex]) === options.version);
33
+ if (!block) return;
34
+ if (block.endIndex > block.startIndex) return;
35
+ const heading = {
36
+ type: "heading",
37
+ depth: 3,
38
+ children: [{
39
+ type: "text",
40
+ value: "Maintenance"
41
+ }]
42
+ };
43
+ const list = {
44
+ type: "list",
45
+ ordered: false,
46
+ spread: false,
47
+ children: [{
48
+ type: "listItem",
49
+ spread: false,
50
+ children: [{
51
+ type: "paragraph",
52
+ children: buildNoteChildren(options.reason)
53
+ }]
54
+ }]
55
+ };
56
+ tree.children.splice(block.startIndex, 0, heading, list);
57
+ };
58
+ };
59
+
60
+ //#endregion
61
+ export { MaintenanceNotePlugin };
@@ -3,13 +3,13 @@ import { DependencyTableFormatRule } from "./rules/dependency-table-format.js";
3
3
  import { HeadingHierarchyRule } from "./rules/heading-hierarchy.js";
4
4
  import { RequiredSectionsRule } from "./rules/required-sections.js";
5
5
  import { UncategorizedContentRule } from "./rules/uncategorized-content.js";
6
+ import { AggregateDependencyTablesPlugin } from "./plugins/aggregate-dependency-tables.js";
6
7
  import { ContributorFootnotesPlugin } from "./plugins/contributor-footnotes.js";
7
8
  import { DeduplicateItemsPlugin } from "./plugins/deduplicate-items.js";
8
9
  import { IssueLinkRefsPlugin } from "./plugins/issue-link-refs.js";
9
10
  import { MergeSectionsPlugin } from "./plugins/merge-sections.js";
10
11
  import { NormalizeFormatPlugin } from "./plugins/normalize-format.js";
11
12
  import { ReorderSectionsPlugin } from "./plugins/reorder-sections.js";
12
- import { AggregateDependencyTablesPlugin } from "./plugins/aggregate-dependency-tables.js";
13
13
 
14
14
  //#region src/changesets/remark/presets.ts
15
15
  /**
@@ -0,0 +1,66 @@
1
+ import { ChangesetConfig } from "../../services/ChangesetConfig.js";
2
+ import { Schema } from "effect";
3
+
4
+ //#region src/changesets/services/maintenance-reason.ts
5
+ /**
6
+ * A group co-member whose own changesets forced this release.
7
+ *
8
+ * @public
9
+ */
10
+ const MaintenanceTriggerSchema = Schema.Struct({
11
+ /** Package name of the triggering co-member. */
12
+ name: Schema.String,
13
+ /** The co-member's new version in the same release plan. */
14
+ version: Schema.String
15
+ });
16
+ /**
17
+ * Why a package is releasing with no changesets of its own.
18
+ *
19
+ * @public
20
+ */
21
+ const MaintenanceReasonSchema = Schema.Struct({
22
+ /** Coupling that forced the release; `"unspecified"` when undetermined. */
23
+ kind: Schema.Literal("fixed", "linked", "unspecified"),
24
+ /** Triggering co-members; empty for `"unspecified"`. */
25
+ triggers: Schema.Array(MaintenanceTriggerSchema)
26
+ });
27
+ /**
28
+ * Derive the {@link MaintenanceReason} for a release, or `undefined` when the
29
+ * release has its own changesets (not a maintenance release).
30
+ *
31
+ * @param release - The release to classify.
32
+ * @param plan - The full release plan (source of group co-members).
33
+ * @param config - Resolved changesets config (`fixed` / `linked` groups).
34
+ * @returns The reason, or `undefined` for releases with their own changesets.
35
+ *
36
+ * @remarks
37
+ * Group entries are matched with {@link ChangesetConfig.matches} — exact names
38
+ * and trailing `"@scope/*"` prefixes only, a subset of the micromatch globs
39
+ * changesets accepts. A group entry using richer glob syntax (e.g. `"pkg-*"`)
40
+ * will not match here; the release then degrades gracefully to the
41
+ * `"unspecified"` fallback sentence instead of naming its triggers.
42
+ *
43
+ * @public
44
+ */
45
+ function deriveMaintenanceReason(release, plan, config) {
46
+ if (release.changesets.length > 0) return void 0;
47
+ const groupKinds = [["fixed", config.fixed], ["linked", config.linked]];
48
+ for (const [kind, groups] of groupKinds) for (const group of groups) {
49
+ if (!group.some((pattern) => ChangesetConfig.matches(release.name, pattern))) continue;
50
+ const triggers = plan.releases.filter((r) => r.name !== release.name && r.changesets.length > 0 && group.some((pattern) => ChangesetConfig.matches(r.name, pattern))).map((r) => ({
51
+ name: r.name,
52
+ version: r.newVersion
53
+ }));
54
+ if (triggers.length > 0) return {
55
+ kind,
56
+ triggers
57
+ };
58
+ }
59
+ return {
60
+ kind: "unspecified",
61
+ triggers: []
62
+ };
63
+ }
64
+
65
+ //#endregion
66
+ export { MaintenanceReasonSchema, MaintenanceTriggerSchema, deriveMaintenanceReason };
@@ -1,9 +1,10 @@
1
1
  import { ReleasePlanError } from "../errors.js";
2
2
  import { ChangelogTransformer } from "../api/transformer.js";
3
3
  import { ConfigInspector } from "./config-inspector.js";
4
+ import { deriveMaintenanceReason } from "./maintenance-reason.js";
4
5
  import { VersionFiles } from "../utils/version-files.js";
5
6
  import { Context, Effect, Layer } from "effect";
6
- import { isAbsolute, join, relative } from "node:path";
7
+ import { dirname, isAbsolute, join, relative } from "node:path";
7
8
  import { FileSystem } from "@effect/platform";
8
9
  import applyReleasePlan from "@changesets/apply-release-plan";
9
10
  import { read } from "@changesets/config";
@@ -23,8 +24,36 @@ import { getPackages } from "@manypkg/get-packages";
23
24
  * (e.g. `getChangelogEntry`) is re-implemented.
24
25
  *
25
26
  */
26
- /** Single workspace-discovery seam; swap to an Effect-native stack later here. */
27
- const buildPackages = (root) => getPackages(root);
27
+ const V1_TOOLS = /* @__PURE__ */ new Set([
28
+ "yarn",
29
+ "bolt",
30
+ "pnpm",
31
+ "lerna",
32
+ "root"
33
+ ]);
34
+ /**
35
+ * Single workspace-discovery seam; swap to an Effect-native stack later here.
36
+ *
37
+ * Discovers with `@manypkg/get-packages@3.x` and adapts to the v1 shape:
38
+ * `tool` collapses to its type string (tools unknown to v1 map to `"root"` —
39
+ * the engine never reads `tool` at runtime, only `root.dir`), and
40
+ * `rootDir`/`rootPackage` fold back into `root`.
41
+ */
42
+ const buildPackages = async (root) => {
43
+ const { tool, rootDir, rootPackage, packages } = await getPackages(root);
44
+ if (!rootPackage) throw new Error(`Workspace root has no package.json: ${rootDir}`);
45
+ return {
46
+ tool: V1_TOOLS.has(tool.type) ? tool.type : "root",
47
+ root: {
48
+ dir: rootPackage.dir,
49
+ packageJson: rootPackage.packageJson
50
+ },
51
+ packages: packages.map((p) => ({
52
+ dir: p.dir,
53
+ packageJson: p.packageJson
54
+ }))
55
+ };
56
+ };
28
57
  const errMsg = (e) => e instanceof Error ? e.message : String(e);
29
58
  const _tag = Context.Tag("ReleasePlanner");
30
59
  /**
@@ -86,6 +115,16 @@ function extractVersionBlock(changelog, version) {
86
115
  }
87
116
  return lines.slice(start, end).join("\n").trim();
88
117
  }
118
+ /** Maintenance reasons for every changeset-less release in the plan, keyed by package name. */
119
+ function maintenanceReasons(plan, config) {
120
+ const reasons = /* @__PURE__ */ new Map();
121
+ for (const r of plan.releases) {
122
+ if (r.type === "none") continue;
123
+ const reason = deriveMaintenanceReason(r, plan, config);
124
+ if (reason) reasons.set(r.name, reason);
125
+ }
126
+ return reasons;
127
+ }
89
128
  /**
90
129
  * Render a non-destructive preview by redirecting every write into a
91
130
  * scope-managed temp directory (cleaned up automatically when the scope
@@ -107,6 +146,7 @@ function previewEffect(root, fs) {
107
146
  reason: errMsg(e)
108
147
  })
109
148
  });
149
+ const reasonByName = maintenanceReasons(plan, config);
110
150
  const preMode = plan.preState ? plan.preState.mode : null;
111
151
  const changesets = plan.changesets.map((cs) => ({
112
152
  id: cs.id,
@@ -175,8 +215,12 @@ function previewEffect(root, fs) {
175
215
  if (!dir) continue;
176
216
  const clPath = join(dir, "CHANGELOG.md");
177
217
  if (!(yield* fs.exists(clPath))) continue;
218
+ const reason = reasonByName.get(r.name);
178
219
  yield* Effect.try({
179
- try: () => ChangelogTransformer.transformFile(clPath),
220
+ try: () => ChangelogTransformer.transformFile(clPath, reason ? { maintenance: {
221
+ version: r.newVersion,
222
+ reason
223
+ } } : void 0),
180
224
  catch: (e) => new ReleasePlanError({
181
225
  phase: "preview",
182
226
  reason: errMsg(e)
@@ -230,17 +274,33 @@ function applyEffect(root, dryRun, inspector, fs) {
230
274
  newVersion: r.newVersion
231
275
  }));
232
276
  let touchedFiles = [];
233
- if (!dryRun) touchedFiles = yield* Effect.tryPromise({
234
- try: async () => {
235
- const touched = await applyReleasePlan(plan, packages, config);
236
- for (const f of touched) if (f.endsWith("CHANGELOG.md")) ChangelogTransformer.transformFile(f);
237
- return touched;
238
- },
239
- catch: (e) => new ReleasePlanError({
240
- phase: "apply",
241
- reason: errMsg(e)
242
- })
243
- });
277
+ if (!dryRun) {
278
+ const reasonByName = maintenanceReasons(plan, config);
279
+ const versionByPkgName = new Map(plan.releases.map((r) => [r.name, r.newVersion]));
280
+ const nameByDir = /* @__PURE__ */ new Map();
281
+ for (const p of packages.packages) nameByDir.set(p.dir, p.packageJson.name);
282
+ if (packages.root.packageJson.name) nameByDir.set(packages.root.dir, packages.root.packageJson.name);
283
+ touchedFiles = yield* Effect.tryPromise({
284
+ try: async () => {
285
+ const touched = await applyReleasePlan(plan, packages, config);
286
+ for (const f of touched) {
287
+ if (!f.endsWith("CHANGELOG.md")) continue;
288
+ const pkgName = nameByDir.get(dirname(f));
289
+ const reason = pkgName ? reasonByName.get(pkgName) : void 0;
290
+ const newVersion = pkgName ? versionByPkgName.get(pkgName) : void 0;
291
+ ChangelogTransformer.transformFile(f, reason && newVersion ? { maintenance: {
292
+ version: newVersion,
293
+ reason
294
+ } } : void 0);
295
+ }
296
+ return touched;
297
+ },
298
+ catch: (e) => new ReleasePlanError({
299
+ phase: "apply",
300
+ reason: errMsg(e)
301
+ })
302
+ });
303
+ }
244
304
  const newVersionByName = new Map(plan.releases.map((r) => [r.name, r.newVersion]));
245
305
  const inspected = yield* inspector.inspect(root).pipe(Effect.catchAll((error) => Effect.logWarning(`Skipping versionFiles update: ${errMsg(error)}`).pipe(Effect.as(null))));
246
306
  let versionFileUpdates = [];
package/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Context, Data, Effect, Equal, Hash, Layer, Option, Schema, Stream } from "effect";
2
+ import { Plugin } from "unified";
2
3
  import { Command, CommandExecutor, FileSystem, Path } from "@effect/platform";
3
4
  import { PackageManagerDetector, PointInTimeReadError, PointInTimeWorkspace, PublishConfig, PublishTarget, PublishabilityDetector, TopologicalSorter, WorkspaceDiscovery, WorkspaceDiscoveryError, WorkspacePackage, WorkspaceRoot, WorkspaceStateSnapshot } from "workspaces-effect";
4
- import { Plugin } from "unified";
5
5
  import { PlatformError } from "@effect/platform/Error";
6
6
 
7
7
  //#region \0rolldown/runtime.js
@@ -335,6 +335,37 @@ type PackageJSON = {
335
335
  registry?: string;
336
336
  };
337
337
  };
338
+ type PackageGroup = ReadonlyArray<string>;
339
+ type Fixed = ReadonlyArray<PackageGroup>;
340
+ type Linked = ReadonlyArray<PackageGroup>;
341
+ interface PrivatePackages {
342
+ version: boolean;
343
+ tag: boolean;
344
+ }
345
+ type Config = {
346
+ changelog: false | readonly [string, any];
347
+ commit: false | readonly [string, any];
348
+ fixed: Fixed;
349
+ linked: Linked;
350
+ access: AccessType;
351
+ baseBranch: string;
352
+ changedFilePatterns: readonly string[]; /** When false, Changesets won't format with Prettier */
353
+ prettier: boolean; /** Features enabled for Private packages */
354
+ privatePackages: PrivatePackages; /** The minimum bump type to trigger automatic update of internal dependencies that are part of the same release */
355
+ updateInternalDependencies: "patch" | "minor";
356
+ ignore: ReadonlyArray<string>; /** This is supposed to be used with pnpm's `link-workspace-packages: false` and Berry's `enableTransparentWorkspaces: false` */
357
+ bumpVersionsWithWorkspaceProtocolOnly?: boolean;
358
+ ___experimentalUnsafeOptions_WILL_CHANGE_IN_PATCH: Omit<Required<ExperimentalOptions>, "useCalculatedVersionForSnapshots">;
359
+ snapshot: {
360
+ useCalculatedVersion: boolean;
361
+ prereleaseTemplate: string | null;
362
+ };
363
+ };
364
+ type ExperimentalOptions = {
365
+ onlyUpdatePeerDependentsWhenOutOfRange?: boolean;
366
+ updateInternalDependents?: "always" | "out-of-range"; /** @deprecated Since snapshot feature is now stable, you should migrate to use "snapshot.useCalculatedVersion". */
367
+ useCalculatedVersionForSnapshots?: boolean;
368
+ };
338
369
  type NewChangesetWithCommit = NewChangeset & {
339
370
  commit?: string;
340
371
  };
@@ -2056,37 +2087,95 @@ declare class ChangesetLinter {
2056
2087
  static validate(dir: string): LintMessage[];
2057
2088
  }
2058
2089
  //#endregion
2059
- //#region src/changesets/api/transformer.d.ts
2090
+ //#region src/changesets/services/maintenance-reason.d.ts
2060
2091
  /**
2061
- * Class-based API wrapper for changelog transformation.
2092
+ * A group co-member whose own changesets forced this release.
2062
2093
  *
2063
- * Provides a static class interface that runs all remark transform
2064
- * plugins against CHANGELOG markdown content as the post-processing
2065
- * layer of the three-layer pipeline.
2094
+ * @public
2095
+ */
2096
+ declare const MaintenanceTriggerSchema: Schema.Struct<{
2097
+ /** Package name of the triggering co-member. */name: typeof Schema.String; /** The co-member's new version in the same release plan. */
2098
+ version: typeof Schema.String;
2099
+ }>;
2100
+ /**
2101
+ * A group co-member whose own changesets forced this release.
2066
2102
  *
2067
- * @internal
2103
+ * @public
2104
+ */
2105
+ type MaintenanceTrigger = typeof MaintenanceTriggerSchema.Type;
2106
+ /**
2107
+ * Why a package is releasing with no changesets of its own.
2108
+ *
2109
+ * @public
2110
+ */
2111
+ declare const MaintenanceReasonSchema: Schema.Struct<{
2112
+ /** Coupling that forced the release; `"unspecified"` when undetermined. */kind: Schema.Literal<["fixed", "linked", "unspecified"]>; /** Triggering co-members; empty for `"unspecified"`. */
2113
+ triggers: Schema.Array$<Schema.Struct<{
2114
+ /** Package name of the triggering co-member. */name: typeof Schema.String; /** The co-member's new version in the same release plan. */
2115
+ version: typeof Schema.String;
2116
+ }>>;
2117
+ }>;
2118
+ /**
2119
+ * Why a package is releasing with no changesets of its own.
2120
+ *
2121
+ * @public
2122
+ */
2123
+ type MaintenanceReason = typeof MaintenanceReasonSchema.Type;
2124
+ /**
2125
+ * Derive the {@link MaintenanceReason} for a release, or `undefined` when the
2126
+ * release has its own changesets (not a maintenance release).
2127
+ *
2128
+ * @param release - The release to classify.
2129
+ * @param plan - The full release plan (source of group co-members).
2130
+ * @param config - Resolved changesets config (`fixed` / `linked` groups).
2131
+ * @returns The reason, or `undefined` for releases with their own changesets.
2132
+ *
2133
+ * @remarks
2134
+ * Group entries are matched with {@link ChangesetConfig.matches} — exact names
2135
+ * and trailing `"@scope/*"` prefixes only, a subset of the micromatch globs
2136
+ * changesets accepts. A group entry using richer glob syntax (e.g. `"pkg-*"`)
2137
+ * will not match here; the release then degrades gracefully to the
2138
+ * `"unspecified"` fallback sentence instead of naming its triggers.
2139
+ *
2140
+ * @public
2068
2141
  */
2142
+ declare function deriveMaintenanceReason(release: ComprehensiveRelease, plan: ReleasePlan, config: Config): MaintenanceReason | undefined;
2143
+ //#endregion
2144
+ //#region src/changesets/remark/plugins/maintenance-note.d.ts
2145
+ /**
2146
+ * Options for {@link MaintenanceNotePlugin}.
2147
+ *
2148
+ * @public
2149
+ */
2150
+ interface MaintenanceNoteOptions {
2151
+ /** Version heading text to target (e.g. `"2.3.1"`). */
2152
+ readonly version: string;
2153
+ /** Why the package released with no changesets of its own. */
2154
+ readonly reason: MaintenanceReason;
2155
+ }
2156
+ declare const MaintenanceNotePlugin: Plugin<[MaintenanceNoteOptions], Root>;
2157
+ //#endregion
2158
+ //#region src/changesets/api/transformer.d.ts
2159
+ /**
2160
+ * Optional per-file behavior for {@link ChangelogTransformer}.
2161
+ *
2162
+ * @public
2163
+ */
2164
+ interface TransformOptions {
2165
+ /** Insert a Maintenance note into this version block when it ends up empty. */
2166
+ readonly maintenance?: MaintenanceNoteOptions;
2167
+ }
2069
2168
  /**
2070
2169
  * Static class for post-processing CHANGELOG.md files.
2071
2170
  *
2072
2171
  * Implements the third layer of the three-layer pipeline by running
2073
- * six remark transform plugins in a fixed order to clean up, normalize,
2074
- * and enhance changelog output produced by the formatter layer.
2172
+ * the {@link SilkChangesetTransformPreset} plugins (currently seven) in a
2173
+ * fixed order to clean up, normalize, and enhance changelog output produced
2174
+ * by the formatter layer.
2075
2175
  *
2076
2176
  * @remarks
2077
- * The six plugins run in this order:
2078
- *
2079
- * 1. **MergeSectionsPlugin** -- merges duplicate section headings (e.g., two
2080
- * "Features" sections from separate changesets are combined into one)
2081
- * 2. **ReorderSectionsPlugin** -- reorders sections by category priority
2082
- * (Breaking Changes first, Other last) using the {@link Categories} priority values
2083
- * 3. **DeduplicateItemsPlugin** -- removes duplicate list items within a section
2084
- * 4. **ContributorFootnotesPlugin** -- converts inline contributor mentions
2085
- * into footnote references for cleaner formatting
2086
- * 5. **IssueLinkRefsPlugin** -- converts inline issue/PR links into markdown
2087
- * reference-style links collected at the bottom of the document
2088
- * 6. **NormalizeFormatPlugin** -- applies consistent formatting (spacing,
2089
- * trailing newlines, heading levels)
2177
+ * See {@link SilkChangesetTransformPreset} for the ordered plugin list and
2178
+ * the rationale behind each plugin's position.
2090
2179
  *
2091
2180
  * The transformer operates on the full CHANGELOG.md content (all versions),
2092
2181
  * not just the latest release block. It is idempotent -- running it multiple
@@ -2145,19 +2234,22 @@ declare class ChangesetLinter {
2145
2234
  declare class ChangelogTransformer {
2146
2235
  private constructor();
2147
2236
  /**
2148
- * Transform CHANGELOG markdown content by running all six transform plugins.
2237
+ * Transform CHANGELOG markdown content by running the
2238
+ * {@link SilkChangesetTransformPreset} plugins.
2149
2239
  *
2150
2240
  * @remarks
2151
2241
  * The input is parsed with `remark-parse` and `remark-gfm` (for table
2152
- * support), processed through all six plugins in order, and stringified
2153
- * back to markdown. The operation is synchronous and idempotent.
2242
+ * support), processed through every plugin in {@link SilkChangesetTransformPreset}
2243
+ * in order, and stringified back to markdown. The operation is synchronous
2244
+ * and idempotent.
2154
2245
  *
2155
2246
  * @param content - Raw CHANGELOG markdown string (may contain multiple
2156
2247
  * version blocks, GFM tables, footnotes, and reference links)
2157
- * @returns The transformed markdown string with sections merged, reordered,
2158
- * deduplicated, and normalized
2248
+ * @param options - Optional transformation options, including maintenance note configuration
2249
+ * @returns The transformed markdown string with dependency tables aggregated,
2250
+ * sections merged, reordered, deduplicated, and normalized
2159
2251
  */
2160
- static transformContent(content: string): string;
2252
+ static transformContent(content: string, options?: TransformOptions): string;
2161
2253
  /**
2162
2254
  * Transform a CHANGELOG file in-place.
2163
2255
  *
@@ -2171,8 +2263,9 @@ declare class ChangelogTransformer {
2171
2263
  * when invoked without the `--dry-run` or `--check` flags.
2172
2264
  *
2173
2265
  * @param filePath - Absolute or relative path to the CHANGELOG.md file
2266
+ * @param options - Optional transformation options, including maintenance note configuration
2174
2267
  */
2175
- static transformFile(filePath: string): void;
2268
+ static transformFile(filePath: string, options?: TransformOptions): void;
2176
2269
  }
2177
2270
  //#endregion
2178
2271
  //#region src/changesets/changelog/index.d.ts
@@ -5477,7 +5570,7 @@ declare const RequiredSectionsRule: import("unified-lint-rule").Plugin<Root, unk
5477
5570
  //#region src/changesets/remark/rules/uncategorized-content.d.ts
5478
5571
  declare const UncategorizedContentRule: import("unified-lint-rule").Plugin<Root, unknown>;
5479
5572
  declare namespace index_d_exports {
5480
- export { AggregateDependencyTablesPlugin, AppliedRelease, AppliedReleaseEntrySchema, AppliedReleaseSchema, BranchAnalysis, BranchAnalysisSchema, BranchAnalyzer, BranchAnalyzerBase, BranchAnalyzerLive, BranchAnalyzerShape, BranchFileEntry, BranchFileEntrySchema, BumpType, BumpTypeSchema, Categories, Changelog, ChangelogService, ChangelogServiceBase, ChangelogServiceShape, ChangelogTransformer, Changeset, ChangesetIOError, ChangesetIOErrorBase, ChangesetLinter, ChangesetOptions, ChangesetOptionsSchema, ChangesetPreview, ChangesetPreviewSchema, ChangesetSchema, ChangesetSummarySchema, ChangesetValidationError, ChangesetValidationErrorBase, Classification, ClassificationReason, ClassificationReasonSchema, ClassificationSchema, CommitHashSchema, ConfigInspector, ConfigInspectorBase, ConfigInspectorLive, ConfigInspectorShape, ConfigurationError, ConfigurationErrorBase, ContentStructureRule, ContributorFootnotesPlugin, DeduplicateItemsPlugin, DependencyAction, DependencyActionSchema, DependencyTable, DependencyTableFormatRule, DependencyTableRow, DependencyTableRowSchema, DependencyTableSchema, DependencyTableType, DependencyTableTypeSchema, DependencyType, DependencyTypeSchema, DependencyUpdate, DependencyUpdateSchema, DepsRegen, DepsRegenBase, DepsRegenDefault, DepsRegenLive, DepsRegenOptions, DepsRegenShape, FileStatus, FileStatusSchema, GitError, GitErrorBase, GitHubApiError, GitHubApiErrorBase, GitHubCommitInfo, GitHubInfo, GitHubInfoSchema, GitHubLive, GitHubService, GitHubServiceBase, GitHubServiceShape, GlobSchema, HeadingHierarchyRule, InspectedConfig, InspectedConfigSchema, IssueLinkRefsPlugin, IssueNumberSchema, JsonPathSchema, LegacyVersionFileConfig, LegacyVersionFileConfigSchema, LegacyVersionFilesSchema, LintMessage, MarkdownLive, MarkdownParseError, MarkdownParseErrorBase, MarkdownService, MarkdownServiceBase, MarkdownServiceShape, ContentStructureRule$1 as MarkdownlintContentStructureRule, DependencyTableFormatRule$1 as MarkdownlintDependencyTableFormatRule, HeadingHierarchyRule$1 as MarkdownlintHeadingHierarchyRule, RequiredSectionsRule$1 as MarkdownlintRequiredSectionsRule, UncategorizedContentRule$1 as MarkdownlintUncategorizedContentRule, MergeSectionsPlugin, NonEmptyString, NormalizeFormatPlugin, PackageScope, PackageScopeSchema, PackagesRecordSchema, PendingChangeset, PendingChangesetSchema, PositiveInteger, PreviewRelease, PreviewReleaseSchema, RegenPlan, RegenResult, ReleasePlanError, ReleasePlanErrorBase, ReleasePlanner, ReleasePlannerBase, ReleasePlannerLive, ReleasePlannerShape, ReorderSectionsPlugin, RepoSchema, RequiredSectionsRule, ResolvedPackageScope, ResolvedPackageScopeSchema, ResolvedVersionFile, ResolvedVersionFileSchema, SectionCategory, SectionCategorySchema, SilkChangesetPreset, SilkChangesetTransformPreset, SilkChangesetsRules, UncategorizedContentRule, UrlOrMarkdownLinkSchema, UsernameSchema, VERSION_RE, VersionFileConfig, VersionFileConfigSchema, VersionFileError, VersionFileErrorBase, VersionFileUpdate, VersionFileUpdateRecordSchema, VersionFiles, VersionFilesSchema, VersionOrEmptySchema, VersionType, VersionTypeSchema, WorkspaceDependencyDiff, WorkspaceVersion, changelogFunctions, computeWorkspaceDependencyDiffs, gitMergeBase, isPureDependencyChangeset, listPublishablePackageNames, makeBranchAnalyzerTest, makeConfigInspectorTest, makeGitHubTest, makeReleasePlannerTest, serializeDependencyTableToMarkdown };
5573
+ export { AggregateDependencyTablesPlugin, AppliedRelease, AppliedReleaseEntrySchema, AppliedReleaseSchema, BranchAnalysis, BranchAnalysisSchema, BranchAnalyzer, BranchAnalyzerBase, BranchAnalyzerLive, BranchAnalyzerShape, BranchFileEntry, BranchFileEntrySchema, BumpType, BumpTypeSchema, Categories, Changelog, ChangelogService, ChangelogServiceBase, ChangelogServiceShape, ChangelogTransformer, Changeset, ChangesetIOError, ChangesetIOErrorBase, ChangesetLinter, ChangesetOptions, ChangesetOptionsSchema, ChangesetPreview, ChangesetPreviewSchema, ChangesetSchema, ChangesetSummarySchema, ChangesetValidationError, ChangesetValidationErrorBase, Classification, ClassificationReason, ClassificationReasonSchema, ClassificationSchema, CommitHashSchema, ConfigInspector, ConfigInspectorBase, ConfigInspectorLive, ConfigInspectorShape, ConfigurationError, ConfigurationErrorBase, ContentStructureRule, ContributorFootnotesPlugin, DeduplicateItemsPlugin, DependencyAction, DependencyActionSchema, DependencyTable, DependencyTableFormatRule, DependencyTableRow, DependencyTableRowSchema, DependencyTableSchema, DependencyTableType, DependencyTableTypeSchema, DependencyType, DependencyTypeSchema, DependencyUpdate, DependencyUpdateSchema, DepsRegen, DepsRegenBase, DepsRegenDefault, DepsRegenLive, DepsRegenOptions, DepsRegenShape, FileStatus, FileStatusSchema, GitError, GitErrorBase, GitHubApiError, GitHubApiErrorBase, GitHubCommitInfo, GitHubInfo, GitHubInfoSchema, GitHubLive, GitHubService, GitHubServiceBase, GitHubServiceShape, GlobSchema, HeadingHierarchyRule, InspectedConfig, InspectedConfigSchema, IssueLinkRefsPlugin, IssueNumberSchema, JsonPathSchema, LegacyVersionFileConfig, LegacyVersionFileConfigSchema, LegacyVersionFilesSchema, LintMessage, MaintenanceNoteOptions, MaintenanceNotePlugin, MaintenanceReason, MaintenanceReasonSchema, MaintenanceTrigger, MaintenanceTriggerSchema, MarkdownLive, MarkdownParseError, MarkdownParseErrorBase, MarkdownService, MarkdownServiceBase, MarkdownServiceShape, ContentStructureRule$1 as MarkdownlintContentStructureRule, DependencyTableFormatRule$1 as MarkdownlintDependencyTableFormatRule, HeadingHierarchyRule$1 as MarkdownlintHeadingHierarchyRule, RequiredSectionsRule$1 as MarkdownlintRequiredSectionsRule, UncategorizedContentRule$1 as MarkdownlintUncategorizedContentRule, MergeSectionsPlugin, NonEmptyString, NormalizeFormatPlugin, PackageScope, PackageScopeSchema, PackagesRecordSchema, PendingChangeset, PendingChangesetSchema, PositiveInteger, PreviewRelease, PreviewReleaseSchema, RegenPlan, RegenResult, ReleasePlanError, ReleasePlanErrorBase, ReleasePlanner, ReleasePlannerBase, ReleasePlannerLive, ReleasePlannerShape, ReorderSectionsPlugin, RepoSchema, RequiredSectionsRule, ResolvedPackageScope, ResolvedPackageScopeSchema, ResolvedVersionFile, ResolvedVersionFileSchema, SectionCategory, SectionCategorySchema, SilkChangesetPreset, SilkChangesetTransformPreset, SilkChangesetsRules, TransformOptions, UncategorizedContentRule, UrlOrMarkdownLinkSchema, UsernameSchema, VERSION_RE, VersionFileConfig, VersionFileConfigSchema, VersionFileError, VersionFileErrorBase, VersionFileUpdate, VersionFileUpdateRecordSchema, VersionFiles, VersionFilesSchema, VersionOrEmptySchema, VersionType, VersionTypeSchema, WorkspaceDependencyDiff, WorkspaceVersion, changelogFunctions, computeWorkspaceDependencyDiffs, deriveMaintenanceReason, gitMergeBase, isPureDependencyChangeset, listPublishablePackageNames, makeBranchAnalyzerTest, makeConfigInspectorTest, makeGitHubTest, makeReleasePlannerTest, serializeDependencyTableToMarkdown };
5481
5574
  }
5482
5575
  //#endregion
5483
5576
  //#region src/commitlint/config/schema.d.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@savvy-web/silk-effects",
3
- "version": "2.0.1",
3
+ "version": "2.1.0",
4
4
  "private": false,
5
5
  "description": "Shared Effect library for Silk Suite conventions",
6
6
  "homepage": "https://github.com/savvy-web/systems/tree/main/packages/silk-effects",
@@ -32,7 +32,7 @@
32
32
  "@changesets/config": "^3.1.4",
33
33
  "@changesets/get-github-info": "^0.8.0",
34
34
  "@changesets/get-release-plan": "^4.0.16",
35
- "@manypkg/get-packages": "^1.1.3",
35
+ "@manypkg/get-packages": "^3.1.0",
36
36
  "jsonc-effect": "^0.3.0",
37
37
  "mdast-util-heading-range": "^4.0.0",
38
38
  "mdast-util-to-string": "^4.0.0",