@savvy-web/silk-effects 9.5.5 → 10.0.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 (158) hide show
  1. package/_virtual/_rolldown/runtime.js +1 -2
  2. package/changesets/api/categories.js +1 -2
  3. package/changesets/api/changelog.js +1 -2
  4. package/changesets/api/dependency-table.js +13 -14
  5. package/changesets/api/linter.js +24 -21
  6. package/changesets/api/transformer.js +39 -35
  7. package/changesets/categories/index.js +2 -3
  8. package/changesets/categories/types.js +3 -4
  9. package/changesets/changelog/formatting.js +1 -2
  10. package/changesets/changelog/getDependencyReleaseLine.js +2 -3
  11. package/changesets/changelog/getReleaseLine.js +1 -2
  12. package/changesets/changelog/index.js +3 -4
  13. package/changesets/changelog/vanilla.js +1 -2
  14. package/changesets/constants.js +2 -3
  15. package/changesets/errors.js +2 -3
  16. package/changesets/index.js +12 -42
  17. package/changesets/markdownlint/index.js +1 -2
  18. package/changesets/markdownlint/rules/content-structure.js +3 -4
  19. package/changesets/markdownlint/rules/dependency-table-format.js +1 -2
  20. package/changesets/markdownlint/rules/heading-hierarchy.js +3 -4
  21. package/changesets/markdownlint/rules/required-sections.js +3 -4
  22. package/changesets/markdownlint/rules/uncategorized-content.js +3 -4
  23. package/changesets/markdownlint/rules/utils.js +7 -8
  24. package/changesets/rules/content-structure.js +44 -0
  25. package/changesets/rules/dependency-table-format.js +54 -0
  26. package/changesets/rules/heading-hierarchy.js +37 -0
  27. package/changesets/rules/required-sections.js +34 -0
  28. package/changesets/rules/types.js +20 -0
  29. package/changesets/rules/uncategorized-content.js +30 -0
  30. package/changesets/schemas/changeset.js +2 -3
  31. package/changesets/schemas/dependency-table.js +1 -2
  32. package/changesets/schemas/deps-regen.js +1 -2
  33. package/changesets/schemas/git.js +1 -2
  34. package/changesets/schemas/github.js +1 -2
  35. package/changesets/schemas/options.js +1 -2
  36. package/changesets/schemas/package-scope.js +1 -2
  37. package/changesets/schemas/primitives.js +1 -2
  38. package/changesets/schemas/release-plan.js +1 -2
  39. package/changesets/schemas/version-files.js +1 -2
  40. package/changesets/services/branch-analyzer.js +1 -2
  41. package/changesets/services/changelog.js +1 -2
  42. package/changesets/services/config-inspector.js +1 -2
  43. package/changesets/services/deps-regen.js +1 -2
  44. package/changesets/services/github.js +1 -2
  45. package/changesets/services/maintenance-reason.js +1 -2
  46. package/changesets/services/release-planner.js +1 -2
  47. package/changesets/transforms/aggregate-dependency-tables.js +96 -0
  48. package/changesets/transforms/contributor-footnotes.js +290 -0
  49. package/changesets/transforms/deduplicate-items.js +47 -0
  50. package/changesets/transforms/issue-link-refs.js +47 -0
  51. package/changesets/transforms/maintenance-note.js +65 -0
  52. package/changesets/transforms/merge-sections.js +56 -0
  53. package/changesets/transforms/normalize-format.js +53 -0
  54. package/changesets/transforms/reorder-sections.js +53 -0
  55. package/changesets/utils/blocks.js +67 -0
  56. package/changesets/utils/commit-parser.js +1 -2
  57. package/changesets/utils/dep-diff.js +1 -2
  58. package/changesets/utils/dependency-section.js +1 -2
  59. package/changesets/utils/dependency-table.js +30 -38
  60. package/changesets/utils/git.js +1 -2
  61. package/changesets/utils/issue-refs.js +1 -2
  62. package/changesets/utils/jsonpath.js +1 -2
  63. package/changesets/utils/logger.js +1 -2
  64. package/changesets/utils/markdown-emit.js +12 -38
  65. package/changesets/utils/markdown-link.js +1 -2
  66. package/changesets/utils/publishability.js +1 -2
  67. package/changesets/utils/section-parser.js +1 -2
  68. package/changesets/utils/strip-frontmatter.js +1 -2
  69. package/changesets/utils/version-files.js +1 -2
  70. package/changesets/vendor/github-info.js +1 -2
  71. package/commitlint/config/factory.js +1 -2
  72. package/commitlint/config/plugins.js +1 -2
  73. package/commitlint/config/rules.js +1 -2
  74. package/commitlint/config/schema.js +1 -2
  75. package/commitlint/detection/dco.js +1 -2
  76. package/commitlint/detection/scopes.js +1 -2
  77. package/commitlint/formatter/format.js +1 -2
  78. package/commitlint/formatter/messages.js +1 -2
  79. package/commitlint/hook/diagnostics/branch.js +1 -2
  80. package/commitlint/hook/diagnostics/cache.js +1 -2
  81. package/commitlint/hook/diagnostics/commitlint-config.js +1 -2
  82. package/commitlint/hook/diagnostics/open-issues.js +1 -2
  83. package/commitlint/hook/diagnostics/package-manager.js +1 -2
  84. package/commitlint/hook/diagnostics/signing.js +1 -2
  85. package/commitlint/hook/envelope.js +1 -2
  86. package/commitlint/hook/output.js +1 -2
  87. package/commitlint/hook/parse-bash-command.js +1 -2
  88. package/commitlint/hook/rules/closes-trailer.js +1 -2
  89. package/commitlint/hook/rules/forbidden-content.js +1 -2
  90. package/commitlint/hook/rules/plan-leakage.js +1 -2
  91. package/commitlint/hook/rules/signing-flag-conflict.js +1 -2
  92. package/commitlint/hook/rules/soft-wrap.js +1 -2
  93. package/commitlint/hook/rules/types.js +1 -2
  94. package/commitlint/hook/rules/verbosity.js +1 -2
  95. package/commitlint/hook/silence-logger.js +1 -2
  96. package/commitlint/index.js +1 -2
  97. package/commitlint/prompt/config.js +1 -2
  98. package/commitlint/prompt/emojis.js +1 -2
  99. package/commitlint/prompt/prompter.js +1 -2
  100. package/commitlint/static.js +1 -2
  101. package/index.d.ts +141 -1450
  102. package/index.js +2 -2
  103. package/lint/Handler.js +1 -2
  104. package/lint/cli/sections.js +1 -2
  105. package/lint/cli/templates/markdownlint.gen.js +1 -2
  106. package/lint/config/Preset.js +1 -2
  107. package/lint/config/createConfig.js +1 -2
  108. package/lint/handlers/Biome.js +1 -2
  109. package/lint/handlers/Markdown.js +1 -2
  110. package/lint/handlers/PackageJson.js +1 -2
  111. package/lint/handlers/PnpmWorkspace.js +1 -2
  112. package/lint/handlers/ShellScripts.js +1 -2
  113. package/lint/handlers/TextFiles.js +1 -2
  114. package/lint/handlers/TypeScript.js +1 -2
  115. package/lint/handlers/Yaml.js +1 -2
  116. package/lint/index.js +1 -2
  117. package/lint/utils/Command.js +1 -2
  118. package/lint/utils/Filter.js +1 -2
  119. package/lint/utils/Workspace.js +1 -2
  120. package/package.json +15 -22
  121. package/repos/constants.js +1 -2
  122. package/repos/errors.js +1 -2
  123. package/repos/index.js +1 -2
  124. package/repos/schemas/drift.js +1 -2
  125. package/repos/schemas/manifest.js +1 -2
  126. package/repos/schemas/reports.js +1 -2
  127. package/repos/services/config-store.js +1 -2
  128. package/repos/services/drift.js +1 -2
  129. package/repos/services/lockdown.js +1 -2
  130. package/repos/services/manager.js +1 -2
  131. package/services/BiomeSchemaSync.js +1 -2
  132. package/services/ChangesetConfig.js +1 -2
  133. package/services/ChangesetConfigReader.js +1 -2
  134. package/services/ConfigDiscovery.js +1 -2
  135. package/services/SilkPublishability.js +147 -6
  136. package/services/SilkWorkspaceAnalyzer.js +1 -2
  137. package/turbo/digest.js +1 -2
  138. package/turbo/errors.js +1 -2
  139. package/turbo/index.js +1 -2
  140. package/turbo/schemas/DryRun.js +1 -2
  141. package/turbo/schemas/results.js +1 -2
  142. package/turbo/services/TurboInspector.js +1 -2
  143. package/changesets/remark/plugins/aggregate-dependency-tables.js +0 -99
  144. package/changesets/remark/plugins/contributor-footnotes.js +0 -335
  145. package/changesets/remark/plugins/deduplicate-items.js +0 -32
  146. package/changesets/remark/plugins/issue-link-refs.js +0 -58
  147. package/changesets/remark/plugins/maintenance-note.js +0 -75
  148. package/changesets/remark/plugins/merge-sections.js +0 -43
  149. package/changesets/remark/plugins/normalize-format.js +0 -47
  150. package/changesets/remark/plugins/reorder-sections.js +0 -49
  151. package/changesets/remark/presets.js +0 -119
  152. package/changesets/remark/rules/content-structure.js +0 -22
  153. package/changesets/remark/rules/dependency-table-format.js +0 -38
  154. package/changesets/remark/rules/heading-hierarchy.js +0 -19
  155. package/changesets/remark/rules/required-sections.js +0 -17
  156. package/changesets/remark/rules/uncategorized-content.js +0 -31
  157. package/changesets/utils/remark-pipeline.js +0 -36
  158. package/changesets/utils/version-blocks.js +0 -108
@@ -4,7 +4,7 @@ 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
6
 
7
- //#region src/changesets/markdownlint/index.ts
7
+ // src/changesets/markdownlint/index.ts
8
8
  /**
9
9
  * All changeset rules as an array for markdownlint-cli2 `customRules` config.
10
10
  *
@@ -25,5 +25,4 @@ const SilkChangesetsRules = [
25
25
  DependencyTableFormatRule
26
26
  ];
27
27
 
28
- //#endregion
29
28
  export { ContentStructureRule, DependencyTableFormatRule, HeadingHierarchyRule, RequiredSectionsRule, UncategorizedContentRule, SilkChangesetsRules as default };
@@ -1,7 +1,7 @@
1
1
  import { RULE_DOCS } from "../../constants.js";
2
2
  import { getHeadingLevel } from "./utils.js";
3
3
 
4
- //#region src/changesets/markdownlint/rules/content-structure.ts
4
+ // src/changesets/markdownlint/rules/content-structure.ts
5
5
  /**
6
6
  * Check whether any non-blank tokens exist between two indices in the token stream.
7
7
  *
@@ -33,7 +33,7 @@ function hasContentBetween(tokens, currentIdx, nextIdx) {
33
33
  * `content` token before the next prefix or end of list.
34
34
  *
35
35
  * @remarks
36
- * This rule mirrors the remark-lint rule `remarkLintContentStructure` but uses
36
+ * This rule mirrors the kit rule `contentStructure` in `src/changesets/rules/content-structure.ts` but uses
37
37
  * markdownlint's micromark token API so it can run inside markdownlint-cli2 and
38
38
  * the VS Code markdownlint extension.
39
39
  *
@@ -45,7 +45,7 @@ function hasContentBetween(tokens, currentIdx, nextIdx) {
45
45
  * ```
46
46
  *
47
47
  * @see {@link https://github.com/savvy-web/systems/blob/main/packages/silk-effects/docs/rules/CSH003.md | CSH003 rule documentation}
48
- * @see `src/remark/rules/content-structure.ts` for the corresponding remark-lint rule
48
+ * @see `src/changesets/rules/content-structure.ts` for the corresponding kit-node rule
49
49
  *
50
50
  * @public
51
51
  */
@@ -94,5 +94,4 @@ const ContentStructureRule = {
94
94
  }
95
95
  };
96
96
 
97
- //#endregion
98
97
  export { ContentStructureRule };
@@ -3,7 +3,7 @@ import { RULE_DOCS } from "../../constants.js";
3
3
  import { scanDependencySection } from "../../utils/dependency-section.js";
4
4
  import { getHeadingLevel, getHeadingText, unescapeMarkdown } from "./utils.js";
5
5
 
6
- //#region src/changesets/markdownlint/rules/dependency-table-format.ts
6
+ // src/changesets/markdownlint/rules/dependency-table-format.ts
7
7
  const EM_DASH = "—";
8
8
  const VALID_TYPES = /* @__PURE__ */ new Set([
9
9
  "dependency",
@@ -167,5 +167,4 @@ const DependencyTableFormatRule = {
167
167
  }
168
168
  };
169
169
 
170
- //#endregion
171
170
  export { DependencyTableFormatRule };
@@ -1,7 +1,7 @@
1
1
  import { RULE_DOCS } from "../../constants.js";
2
2
  import { getHeadingLevel } from "./utils.js";
3
3
 
4
- //#region src/changesets/markdownlint/rules/heading-hierarchy.ts
4
+ // src/changesets/markdownlint/rules/heading-hierarchy.ts
5
5
  /**
6
6
  * markdownlint rule: `changeset-heading-hierarchy` (CSH001).
7
7
  *
@@ -15,7 +15,7 @@ import { getHeadingLevel } from "./utils.js";
15
15
  * (h2 then h3, not h2 then h4).
16
16
  *
17
17
  * @remarks
18
- * This rule mirrors the remark-lint rule `remarkLintHeadingHierarchy` but uses
18
+ * This rule mirrors the kit rule `headingHierarchy` in `src/changesets/rules/heading-hierarchy.ts` but uses
19
19
  * markdownlint's micromark token API so it can run inside markdownlint-cli2 and
20
20
  * the VS Code markdownlint extension.
21
21
  *
@@ -27,7 +27,7 @@ import { getHeadingLevel } from "./utils.js";
27
27
  * ```
28
28
  *
29
29
  * @see {@link https://github.com/savvy-web/systems/blob/main/packages/silk-effects/docs/rules/CSH001.md | CSH001 rule documentation}
30
- * @see `src/remark/rules/heading-hierarchy.ts` for the corresponding remark-lint rule
30
+ * @see `src/changesets/rules/heading-hierarchy.ts` for the corresponding kit-node rule
31
31
  *
32
32
  * @public
33
33
  */
@@ -57,5 +57,4 @@ const HeadingHierarchyRule = {
57
57
  }
58
58
  };
59
59
 
60
- //#endregion
61
60
  export { HeadingHierarchyRule };
@@ -2,7 +2,7 @@ import { allHeadings, isValidHeading } from "../../categories/index.js";
2
2
  import { RULE_DOCS } from "../../constants.js";
3
3
  import { getHeadingLevel, getHeadingText } from "./utils.js";
4
4
 
5
- //#region src/changesets/markdownlint/rules/required-sections.ts
5
+ // src/changesets/markdownlint/rules/required-sections.ts
6
6
  /**
7
7
  * markdownlint rule: `changeset-required-sections` (CSH002).
8
8
  *
@@ -16,7 +16,7 @@ import { getHeadingLevel, getHeadingText } from "./utils.js";
16
16
  * (`src/categories/index.ts`). This rule inspects `atxHeading` micromark
17
17
  * tokens and extracts their text via the {@link getHeadingText} utility.
18
18
  *
19
- * This rule mirrors the remark-lint rule `remarkLintRequiredSections` but uses
19
+ * This rule mirrors the kit rule `requiredSections` in `src/changesets/rules/required-sections.ts` but uses
20
20
  * markdownlint's micromark token API so it can run inside markdownlint-cli2 and
21
21
  * the VS Code markdownlint extension.
22
22
  *
@@ -28,7 +28,7 @@ import { getHeadingLevel, getHeadingText } from "./utils.js";
28
28
  * ```
29
29
  *
30
30
  * @see {@link https://github.com/savvy-web/systems/blob/main/packages/silk-effects/docs/rules/CSH002.md | CSH002 rule documentation}
31
- * @see `src/remark/rules/required-sections.ts` for the corresponding remark-lint rule
31
+ * @see `src/changesets/rules/required-sections.ts` for the corresponding kit-node rule
32
32
  *
33
33
  * @public
34
34
  */
@@ -50,5 +50,4 @@ const RequiredSectionsRule = {
50
50
  }
51
51
  };
52
52
 
53
- //#endregion
54
53
  export { RequiredSectionsRule };
@@ -1,7 +1,7 @@
1
1
  import { RULE_DOCS } from "../../constants.js";
2
2
  import { getHeadingLevel } from "./utils.js";
3
3
 
4
- //#region src/changesets/markdownlint/rules/uncategorized-content.ts
4
+ // src/changesets/markdownlint/rules/uncategorized-content.ts
5
5
  /**
6
6
  * markdownlint rule: `changeset-uncategorized-content` (CSH004).
7
7
  *
@@ -16,7 +16,7 @@ import { getHeadingLevel } from "./utils.js";
16
16
  * triggers an error. This ensures that changeset content is always grouped
17
17
  * under a recognized category heading.
18
18
  *
19
- * This rule mirrors the remark-lint rule `remarkLintUncategorizedContent` but
19
+ * This rule mirrors the kit rule `uncategorizedContent` in `src/changesets/rules/uncategorized-content.ts` but
20
20
  * uses markdownlint's micromark token API so it can run inside
21
21
  * markdownlint-cli2 and the VS Code markdownlint extension.
22
22
  *
@@ -28,7 +28,7 @@ import { getHeadingLevel } from "./utils.js";
28
28
  * ```
29
29
  *
30
30
  * @see {@link https://github.com/savvy-web/systems/blob/main/packages/silk-effects/docs/rules/CSH004.md | CSH004 rule documentation}
31
- * @see `src/remark/rules/uncategorized-content.ts` for the corresponding remark-lint rule
31
+ * @see `src/changesets/rules/uncategorized-content.ts` for the corresponding kit-node rule
32
32
  *
33
33
  * @public
34
34
  */
@@ -50,5 +50,4 @@ const UncategorizedContentRule = {
50
50
  }
51
51
  };
52
52
 
53
- //#endregion
54
53
  export { UncategorizedContentRule };
@@ -1,12 +1,12 @@
1
1
  import { RULE_DOCS } from "../../constants.js";
2
2
 
3
- //#region src/changesets/markdownlint/rules/utils.ts
3
+ // src/changesets/markdownlint/rules/utils.ts
4
4
  /**
5
5
  * Get the heading level (1-6) from an `atxHeading` or `setextHeading` token.
6
6
  *
7
7
  * @remarks
8
- * remark-parse normalizes setext headings to plain depth-1/2 heading nodes,
9
- * so the remark siblings of these rules see them as ordinary headings. The
8
+ * `@effected/markdown` normalizes setext headings to plain depth-1/2 heading nodes,
9
+ * so the kit siblings of these rules see them as ordinary headings. The
10
10
  * micromark extractors must agree, or the two engines disagree about the
11
11
  * same file (the issue #367 class of drift).
12
12
  *
@@ -33,9 +33,9 @@ const BACKSLASH_ESCAPE_RE = /\\([!-/:-@[-`{-~])/g;
33
33
  * Resolve CommonMark backslash escapes in raw micromark source text.
34
34
  *
35
35
  * @remarks
36
- * Every rule in this directory has a sibling remark implementation that reads
37
- * the parsed mdast tree, where the parser has already resolved escapes, via
38
- * `mdast-util-to-string`. Micromark tokens instead carry RAW source. Comparing
36
+ * Every rule in this directory has a sibling kit implementation that reads
37
+ * the parsed `@effected/markdown` tree, where the parser has already resolved escapes, via
38
+ * `Mdast.toText`. Micromark tokens instead carry RAW source. Comparing
39
39
  * raw text against a value the parsed form would produce makes the two
40
40
  * implementations of one documented rule disagree about the same file
41
41
  * (issue #367).
@@ -54,7 +54,7 @@ function unescapeMarkdown(raw) {
54
54
  *
55
55
  * @remarks
56
56
  * Escape-resolved, so a heading compares equal to the same heading as the
57
- * remark rules see it. `getHeadingLevel` needs no equivalent — it counts
57
+ * the kit rules see it. `getHeadingLevel` needs no equivalent — it counts
58
58
  * sequence characters rather than reading text.
59
59
  *
60
60
  * @param heading - The `atxHeading` or `setextHeading` micromark token
@@ -67,5 +67,4 @@ function getHeadingText(heading) {
67
67
  return textToken ? unescapeMarkdown(textToken.text) : "";
68
68
  }
69
69
 
70
- //#endregion
71
70
  export { RULE_DOCS, getHeadingLevel, getHeadingText, unescapeMarkdown };
@@ -0,0 +1,44 @@
1
+ import { RULE_DOCS } from "../constants.js";
2
+ import { finding } from "./types.js";
3
+ import { MarkdownVisitor, Mdast } from "@effected/markdown";
4
+
5
+ // src/changesets/rules/content-structure.ts
6
+ /**
7
+ * Lint rule: changeset-content-structure (CSH003).
8
+ *
9
+ * @remarks
10
+ * Kit rule. Flags empty h2 sections, code fences
11
+ * without a language, and empty list items. Findings are emitted in three
12
+ * passes (headings, code, list items) to match the markdownlint rule's order.
13
+ *
14
+ * @internal
15
+ */
16
+ const RULE = "changeset-content-structure";
17
+ /**
18
+ * Validate section and block content quality.
19
+ *
20
+ * @internal
21
+ */
22
+ const contentStructure = (root) => {
23
+ const findings = [];
24
+ root.children.forEach((node, index) => {
25
+ if (node.type !== "heading" || node.depth !== 2) return;
26
+ const next = root.children[index + 1];
27
+ if (!next || next.type === "heading" && next.depth === 2) findings.push(finding(RULE, `Empty section: heading has no content before the next section or end of file. Add a list of changes (e.g., "- Added feature X") under this heading, or remove the empty heading. See: ${RULE_DOCS.CSH003}`, node));
28
+ });
29
+ const codes = [];
30
+ const items = [];
31
+ for (const event of MarkdownVisitor.walk(root)) {
32
+ if (event._tag !== "Enter") continue;
33
+ const node = event.node;
34
+ if (node.type === "code" && !node.lang) codes.push(finding(RULE, `Code block is missing a language identifier. Add a language after the opening fence (e.g., \`\`\`ts, \`\`\`json, \`\`\`bash). See: ${RULE_DOCS.CSH003}`, node));
35
+ else if (node.type === "listItem" && !Mdast.toText(node).trim()) items.push(finding(RULE, `Empty list item. Each list item must contain descriptive text (e.g., "- Fixed login timeout issue"). See: ${RULE_DOCS.CSH003}`, node));
36
+ }
37
+ return [
38
+ ...findings,
39
+ ...codes,
40
+ ...items
41
+ ];
42
+ };
43
+
44
+ export { contentStructure };
@@ -0,0 +1,54 @@
1
+ import { parseDependencyTable } from "../utils/dependency-table.js";
2
+ import { RULE_DOCS } from "../constants.js";
3
+ import { finding } from "./types.js";
4
+ import { scanDependencySection } from "../utils/dependency-section.js";
5
+ import { Mdast } from "@effected/markdown";
6
+
7
+ // src/changesets/rules/dependency-table-format.ts
8
+ /**
9
+ * Lint rule: changeset-dependency-table-format (CSH005).
10
+ *
11
+ * @remarks
12
+ * Kit rule. A `## Dependencies` section must
13
+ * contain a table anywhere before the next heading (prose may precede or
14
+ * follow it); a section without one reports at the heading. The table must
15
+ * parse through `parseDependencyTable` (columns, types, actions), and the
16
+ * em-dash rules apply: `from` is `—` when `added`, `to` is `—` when
17
+ * `removed`. Table-level findings anchor at the table.
18
+ *
19
+ * @internal
20
+ */
21
+ const RULE = "changeset-dependency-table-format";
22
+ const EM_DASH = "—";
23
+ /**
24
+ * Validate the structure and semantics of `## Dependencies` tables.
25
+ *
26
+ * @internal
27
+ */
28
+ const dependencyTableFormat = (root) => {
29
+ const findings = [];
30
+ root.children.forEach((node, index) => {
31
+ if (node.type !== "heading" || node.depth !== 2) return;
32
+ if (Mdast.toText(node).toLowerCase() !== "dependencies") return;
33
+ const table = scanDependencySection(root.children, index + 1, {
34
+ isHeading: (n) => n.type === "heading",
35
+ isTable: (n) => n.type === "table"
36
+ }).table;
37
+ if (table === void 0 || table.type !== "table") {
38
+ findings.push(finding(RULE, `Dependencies section must contain a table, not a list or paragraph. See: ${RULE_DOCS.CSH005}`, node));
39
+ return;
40
+ }
41
+ try {
42
+ const rows = parseDependencyTable(table);
43
+ for (const row of rows) {
44
+ if (row.action === "added" && row.from !== EM_DASH) findings.push(finding(RULE, `'from' must be '—' when action is 'added' (got '${row.from}'). See: ${RULE_DOCS.CSH005}`, table));
45
+ if (row.action === "removed" && row.to !== EM_DASH) findings.push(finding(RULE, `'to' must be '—' when action is 'removed' (got '${row.to}'). See: ${RULE_DOCS.CSH005}`, table));
46
+ }
47
+ } catch (error) {
48
+ findings.push(finding(RULE, `${error instanceof Error ? error.message : String(error)}. See: ${RULE_DOCS.CSH005}`, table));
49
+ }
50
+ });
51
+ return findings;
52
+ };
53
+
54
+ export { dependencyTableFormat };
@@ -0,0 +1,37 @@
1
+ import { RULE_DOCS } from "../constants.js";
2
+ import { finding } from "./types.js";
3
+ import { MarkdownVisitor } from "@effected/markdown";
4
+
5
+ // src/changesets/rules/heading-hierarchy.ts
6
+ /**
7
+ * Lint rule: changeset-heading-hierarchy (CSH001).
8
+ *
9
+ * @remarks
10
+ * Kit rule. Forbids h1 headings and sequential
11
+ * depth skips.
12
+ *
13
+ * @internal
14
+ */
15
+ const RULE = "changeset-heading-hierarchy";
16
+ /**
17
+ * Validate heading depth structure.
18
+ *
19
+ * @internal
20
+ */
21
+ const headingHierarchy = (root) => {
22
+ const findings = [];
23
+ let prevDepth = 0;
24
+ for (const event of MarkdownVisitor.walk(root)) {
25
+ if (event._tag !== "Enter" || event.node.type !== "heading") continue;
26
+ const node = event.node;
27
+ if (node.depth === 1) {
28
+ findings.push(finding(RULE, `h1 headings are not allowed in changeset files. Use h2 (##) for top-level sections like "## Features" or "## Bug Fixes". h1 is reserved for the version title generated by the changelog formatter. See: ${RULE_DOCS.CSH001}`, node));
29
+ continue;
30
+ }
31
+ if (prevDepth > 0 && node.depth > prevDepth + 1) findings.push(finding(RULE, `Heading level skipped: expected h${prevDepth + 1} or lower, found h${node.depth}. Headings must increase sequentially (h2 → h3 → h4). Add the missing intermediate level or reduce this heading's depth. See: ${RULE_DOCS.CSH001}`, node));
32
+ prevDepth = node.depth;
33
+ }
34
+ return findings;
35
+ };
36
+
37
+ export { headingHierarchy };
@@ -0,0 +1,34 @@
1
+ import { allHeadings, isValidHeading } from "../categories/index.js";
2
+ import { RULE_DOCS } from "../constants.js";
3
+ import { finding } from "./types.js";
4
+ import { MarkdownVisitor, Mdast } from "@effected/markdown";
5
+
6
+ // src/changesets/rules/required-sections.ts
7
+ /**
8
+ * Lint rule: changeset-required-sections (CSH002).
9
+ *
10
+ * @remarks
11
+ * Kit rule. Every h2 must match a known category
12
+ * heading (case-insensitive).
13
+ *
14
+ * @internal
15
+ */
16
+ const RULE = "changeset-required-sections";
17
+ /**
18
+ * Validate that h2 headings are known categories.
19
+ *
20
+ * @internal
21
+ */
22
+ const requiredSections = (root) => {
23
+ const findings = [];
24
+ for (const event of MarkdownVisitor.walk(root)) {
25
+ if (event._tag !== "Enter" || event.node.type !== "heading") continue;
26
+ const node = event.node;
27
+ if (node.depth !== 2) continue;
28
+ const text = Mdast.toText(node);
29
+ if (!isValidHeading(text)) findings.push(finding(RULE, `Unknown section "${text}". Valid h2 headings are: ${allHeadings().join(", ")}. Heading comparison is case-insensitive. See: ${RULE_DOCS.CSH002}`, node));
30
+ }
31
+ return findings;
32
+ };
33
+
34
+ export { requiredSections };
@@ -0,0 +1,20 @@
1
+ // src/changesets/rules/types.ts
2
+ /**
3
+ * Build a {@link RuleFinding} positioned on a node.
4
+ *
5
+ * @param rule - The rule id
6
+ * @param message - The finding message
7
+ * @param node - The offending node
8
+ * @returns The finding
9
+ *
10
+ * @internal
11
+ */
12
+ function finding(rule, message, node) {
13
+ return {
14
+ rule,
15
+ message,
16
+ position: node.position
17
+ };
18
+ }
19
+
20
+ export { finding };
@@ -0,0 +1,30 @@
1
+ import { RULE_DOCS } from "../constants.js";
2
+ import { finding } from "./types.js";
3
+
4
+ // src/changesets/rules/uncategorized-content.ts
5
+ /**
6
+ * Lint rule: changeset-uncategorized-content (CSH004).
7
+ *
8
+ * @remarks
9
+ * Kit rule. Flags substantive content before
10
+ * the first h2; html nodes (comments) are ignored.
11
+ *
12
+ * @internal
13
+ */
14
+ const RULE = "changeset-uncategorized-content";
15
+ /**
16
+ * Detect content that appears before the first h2 heading.
17
+ *
18
+ * @internal
19
+ */
20
+ const uncategorizedContent = (root) => {
21
+ const findings = [];
22
+ for (const node of root.children) {
23
+ if (node.type === "heading" && node.depth === 2) break;
24
+ if (node.type === "heading" || node.type === "html") continue;
25
+ findings.push(finding(RULE, `Content must be placed under a category heading (## heading). Move this content under an appropriate section like "## Features" or "## Bug Fixes". If it doesn't fit an existing category, use "## Other". See: ${RULE_DOCS.CSH004}`, node));
26
+ }
27
+ return findings;
28
+ };
29
+
30
+ export { uncategorizedContent };
@@ -1,14 +1,14 @@
1
1
  import { CommitHashSchema } from "./git.js";
2
2
  import { Schema } from "effect";
3
3
 
4
- //#region src/changesets/schemas/changeset.ts
4
+ // src/changesets/schemas/changeset.ts
5
5
  /**
6
6
  * Effect schemas for changeset entries and dependency updates.
7
7
  *
8
8
  * @remarks
9
9
  * These schemas define the canonical representation of changeset data
10
10
  * consumed by the changelog formatter (Layer 2) and validated by the
11
- * remark-lint pre-validation layer (Layer 1). They enforce constraints
11
+ * lint pre-validation layer (Layer 1). They enforce constraints
12
12
  * such as summary length limits and valid dependency types at system
13
13
  * boundaries.
14
14
  *
@@ -145,5 +145,4 @@ const DependencyUpdateSchema = Schema.Struct({
145
145
  newVersion: Schema.String
146
146
  });
147
147
 
148
- //#endregion
149
148
  export { ChangesetSchema, ChangesetSummarySchema, DependencyTypeSchema, DependencyUpdateSchema };
@@ -1,7 +1,7 @@
1
1
  import { NonEmptyString } from "./primitives.js";
2
2
  import { Schema } from "effect";
3
3
 
4
- //#region src/changesets/schemas/dependency-table.ts
4
+ // src/changesets/schemas/dependency-table.ts
5
5
  /**
6
6
  * Effect schemas for structured dependency table entries.
7
7
  *
@@ -213,5 +213,4 @@ const DependencyTableRowSchema = Schema.Struct({
213
213
  */
214
214
  const DependencyTableSchema = Schema.Array(DependencyTableRowSchema).check(Schema.isMinLength(1));
215
215
 
216
- //#endregion
217
216
  export { DependencyActionSchema, DependencyTableRowSchema, DependencyTableSchema, DependencyTableTypeSchema, VERSION_RE, VersionOrEmptySchema };
@@ -2,7 +2,7 @@ import { NonEmptyString } from "./primitives.js";
2
2
  import { DependencyActionSchema, DependencyTableTypeSchema } from "./dependency-table.js";
3
3
  import { Schema } from "effect";
4
4
 
5
- //#region src/changesets/schemas/deps-regen.ts
5
+ // src/changesets/schemas/deps-regen.ts
6
6
  /**
7
7
  * Result schemas for DepsRegen: the side-effect-free regen plan and the result
8
8
  * of applying it.
@@ -74,5 +74,4 @@ const RegenResultSchema = Schema.Struct({
74
74
  coexisting: Schema.Array(CoexistingChangesetSchema)
75
75
  }).annotate({ identifier: "RegenResult" });
76
76
 
77
- //#endregion
78
77
  export { CoexistingChangesetSchema, RegenDiffRowSchema, RegenPlanSchema, RegenResultSchema };
@@ -1,6 +1,6 @@
1
1
  import { Schema } from "effect";
2
2
 
3
- //#region src/changesets/schemas/git.ts
3
+ // src/changesets/schemas/git.ts
4
4
  /**
5
5
  * Git-related Effect schemas for commit hashes and version bump types.
6
6
  *
@@ -69,5 +69,4 @@ const VersionTypeSchema = Schema.Literals([
69
69
  "none"
70
70
  ]);
71
71
 
72
- //#endregion
73
72
  export { CommitHashSchema, VersionTypeSchema };
@@ -2,7 +2,7 @@ import { PositiveInteger } from "./primitives.js";
2
2
  import { MARKDOWN_LINK_PATTERN } from "../utils/markdown-link.js";
3
3
  import { Schema } from "effect";
4
4
 
5
- //#region src/changesets/schemas/github.ts
5
+ // src/changesets/schemas/github.ts
6
6
  /**
7
7
  * GitHub-related Effect schemas for usernames, issue numbers, and API responses.
8
8
  *
@@ -170,5 +170,4 @@ const GitHubInfoSchema = Schema.Struct({
170
170
  })
171
171
  });
172
172
 
173
- //#endregion
174
173
  export { GitHubInfoSchema, IssueNumberSchema, UrlOrMarkdownLinkSchema, UsernameSchema };
@@ -3,7 +3,7 @@ import { LegacyVersionFilesSchema } from "./version-files.js";
3
3
  import { PackagesRecordSchema } from "./package-scope.js";
4
4
  import { Effect, Schema } from "effect";
5
5
 
6
- //#region src/changesets/schemas/options.ts
6
+ // src/changesets/schemas/options.ts
7
7
  /**
8
8
  * Changeset configuration option schemas and validation.
9
9
  *
@@ -185,5 +185,4 @@ function validateChangesetOptions(input) {
185
185
  })));
186
186
  }
187
187
 
188
- //#endregion
189
188
  export { ChangesetOptionsSchema, RepoSchema, validateChangesetOptions };
@@ -1,7 +1,7 @@
1
1
  import { VersionFileConfigSchema } from "./version-files.js";
2
2
  import { Schema } from "effect";
3
3
 
4
- //#region src/changesets/schemas/package-scope.ts
4
+ // src/changesets/schemas/package-scope.ts
5
5
  /**
6
6
  * Schemas for the per-package release-surface configuration introduced in
7
7
  * \@savvy-web/changesets 0.9.0.
@@ -120,5 +120,4 @@ const PackageScopeSchema = Schema.Struct({
120
120
  */
121
121
  const PackagesRecordSchema = Schema.Record(Schema.String, PackageScopeSchema);
122
122
 
123
- //#endregion
124
123
  export { GlobSchema, PackageScopeSchema, PackagesRecordSchema };
@@ -1,6 +1,6 @@
1
1
  import { Schema } from "effect";
2
2
 
3
- //#region src/changesets/schemas/primitives.ts
3
+ // src/changesets/schemas/primitives.ts
4
4
  /**
5
5
  * Primitive reusable schemas for common constrained types.
6
6
  *
@@ -67,5 +67,4 @@ const NonEmptyString = Schema.String.check(Schema.isMinLength(1));
67
67
  */
68
68
  const PositiveInteger = Schema.Number.check(Schema.isInt(), Schema.isGreaterThan(0));
69
69
 
70
- //#endregion
71
70
  export { NonEmptyString, PositiveInteger };
@@ -1,6 +1,6 @@
1
1
  import { Schema } from "effect";
2
2
 
3
- //#region src/changesets/schemas/release-plan.ts
3
+ // src/changesets/schemas/release-plan.ts
4
4
  /**
5
5
  * Result schemas for the {@link ReleasePlanner} service — the structured
6
6
  * preview of pending releases and the result of a native apply.
@@ -56,5 +56,4 @@ const AppliedReleaseSchema = Schema.Struct({
56
56
  versionFileUpdates: Schema.Array(VersionFileUpdateRecordSchema)
57
57
  }).annotate({ identifier: "AppliedRelease" });
58
58
 
59
- //#endregion
60
59
  export { AppliedReleaseEntrySchema, AppliedReleaseSchema, BumpTypeSchema, ChangesetPreviewSchema, PendingChangesetSchema, PreviewReleaseSchema, VersionFileUpdateRecordSchema };
@@ -1,6 +1,6 @@
1
1
  import { Schema } from "effect";
2
2
 
3
- //#region src/changesets/schemas/version-files.ts
3
+ // src/changesets/schemas/version-files.ts
4
4
  /**
5
5
  * Schemas for `versionFiles` configuration entries.
6
6
  *
@@ -146,5 +146,4 @@ const LegacyVersionFileConfigSchema = Schema.Struct({
146
146
  */
147
147
  const LegacyVersionFilesSchema = Schema.Array(LegacyVersionFileConfigSchema);
148
148
 
149
- //#endregion
150
149
  export { JsonPathSchema, LegacyVersionFileConfigSchema, LegacyVersionFilesSchema, VersionFileConfigSchema, VersionFilesSchema };
@@ -3,7 +3,7 @@ import { ClassificationReasonSchema, ConfigInspector } from "./config-inspector.
3
3
  import { Context, Effect, Layer, Option, Schema } from "effect";
4
4
  import { Git } from "@effected/git";
5
5
 
6
- //#region src/changesets/services/branch-analyzer.ts
6
+ // src/changesets/services/branch-analyzer.ts
7
7
  /** Git diff status as reported by `--name-status`. @public */
8
8
  const FileStatusSchema = Schema.Literals([
9
9
  "added",
@@ -163,5 +163,4 @@ function makeBranchAnalyzerTest(fixed) {
163
163
  return Layer.succeed(BranchAnalyzer, { analyzeBranch: () => Effect.succeed(fixed) });
164
164
  }
165
165
 
166
- //#endregion
167
166
  export { BranchAnalysisSchema, BranchAnalyzer, BranchFileEntrySchema, FileStatusSchema, makeBranchAnalyzerTest };
@@ -1,6 +1,6 @@
1
1
  import { Context } from "effect";
2
2
 
3
- //#region src/changesets/services/changelog.ts
3
+ // src/changesets/services/changelog.ts
4
4
  /**
5
5
  * Effect service tag for changelog formatting.
6
6
  *
@@ -33,5 +33,4 @@ import { Context } from "effect";
33
33
  */
34
34
  var ChangelogService = class extends Context.Service()("ChangelogService") {};
35
35
 
36
- //#endregion
37
36
  export { ChangelogService };
@@ -9,7 +9,7 @@ import { GlobPattern, GlobPatternOptions } from "@effected/glob";
9
9
  import { compileAndExpand } from "@effected/walker";
10
10
  import { WorkspaceDiscovery } from "@effected/workspaces";
11
11
 
12
- //#region src/changesets/services/config-inspector.ts
12
+ // src/changesets/services/config-inspector.ts
13
13
  /**
14
14
  * `ConfigInspector` service — surface the project's `.changeset/config.json`
15
15
  * in a structured, validated form that agents and tooling can consume.
@@ -580,5 +580,4 @@ function makeConfigInspectorTest(fixed) {
580
580
  });
581
581
  }
582
582
 
583
- //#endregion
584
583
  export { ClassificationReasonSchema, ClassificationSchema, ConfigInspector, InspectedConfigSchema, ResolvedPackageScopeSchema, ResolvedVersionFileSchema, makeConfigInspectorTest };
@@ -13,7 +13,7 @@ import { Git } from "@effected/git";
13
13
  import { LockfileReader, PublishabilityDetector, WorkspaceCatalogs, WorkspaceDiscovery, WorkspaceSnapshots, Workspaces } from "@effected/workspaces";
14
14
  import { Yaml } from "@effected/yaml";
15
15
 
16
- //#region src/changesets/services/deps-regen.ts
16
+ // src/changesets/services/deps-regen.ts
17
17
  /**
18
18
  * `Changesets.DepsRegen` service — lift the `deps regen` / `deps detect`
19
19
  * orchestration out of the CLI into a `Context.Service` with a
@@ -542,5 +542,4 @@ function makeDepsRegenDefault(options) {
542
542
  */
543
543
  const DepsRegenDefault = makeDepsRegenDefault();
544
544
 
545
- //#endregion
546
545
  export { DepsRegen, DepsRegenDefault, depsChangesetFilename, isPureDependencyChangeset, makeDepsRegenDefault, parseChangesetPackages };