@savvy-web/silk 2.0.0 → 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.
Files changed (155) hide show
  1. package/README.md +7 -5
  2. package/changesets-changelog.cjs +10 -4
  3. package/changesets-changelog.js +54057 -1
  4. package/changesets-markdownlint.cjs +10 -4
  5. package/changesets-markdownlint.js +54057 -1
  6. package/package.json +5 -4
  7. package/tsconfig/node/dist/tsconfig.tsbuildinfo +1 -1
  8. package/_virtual/_rolldown/runtime.cjs +0 -45
  9. package/_virtual/_rolldown/runtime.js +0 -45
  10. package/packages/silk-effects/dist/dev/pkg/_virtual/_rolldown/runtime.cjs +0 -15
  11. package/packages/silk-effects/dist/dev/pkg/_virtual/_rolldown/runtime.js +0 -14
  12. package/packages/silk-effects/dist/dev/pkg/changesets/api/categories.cjs +0 -247
  13. package/packages/silk-effects/dist/dev/pkg/changesets/api/categories.js +0 -247
  14. package/packages/silk-effects/dist/dev/pkg/changesets/api/changelog.cjs +0 -134
  15. package/packages/silk-effects/dist/dev/pkg/changesets/api/changelog.js +0 -134
  16. package/packages/silk-effects/dist/dev/pkg/changesets/api/dependency-table.cjs +0 -163
  17. package/packages/silk-effects/dist/dev/pkg/changesets/api/dependency-table.js +0 -163
  18. package/packages/silk-effects/dist/dev/pkg/changesets/api/linter.cjs +0 -170
  19. package/packages/silk-effects/dist/dev/pkg/changesets/api/linter.js +0 -170
  20. package/packages/silk-effects/dist/dev/pkg/changesets/api/transformer.cjs +0 -134
  21. package/packages/silk-effects/dist/dev/pkg/changesets/api/transformer.js +0 -134
  22. package/packages/silk-effects/dist/dev/pkg/changesets/categories/index.cjs +0 -317
  23. package/packages/silk-effects/dist/dev/pkg/changesets/categories/index.js +0 -299
  24. package/packages/silk-effects/dist/dev/pkg/changesets/categories/types.cjs +0 -65
  25. package/packages/silk-effects/dist/dev/pkg/changesets/categories/types.js +0 -65
  26. package/packages/silk-effects/dist/dev/pkg/changesets/changelog/formatting.cjs +0 -114
  27. package/packages/silk-effects/dist/dev/pkg/changesets/changelog/formatting.js +0 -113
  28. package/packages/silk-effects/dist/dev/pkg/changesets/changelog/getDependencyReleaseLine.cjs +0 -118
  29. package/packages/silk-effects/dist/dev/pkg/changesets/changelog/getDependencyReleaseLine.js +0 -118
  30. package/packages/silk-effects/dist/dev/pkg/changesets/changelog/getReleaseLine.cjs +0 -122
  31. package/packages/silk-effects/dist/dev/pkg/changesets/changelog/getReleaseLine.js +0 -122
  32. package/packages/silk-effects/dist/dev/pkg/changesets/changelog/index.cjs +0 -97
  33. package/packages/silk-effects/dist/dev/pkg/changesets/changelog/index.js +0 -97
  34. package/packages/silk-effects/dist/dev/pkg/changesets/constants.cjs +0 -43
  35. package/packages/silk-effects/dist/dev/pkg/changesets/constants.js +0 -42
  36. package/packages/silk-effects/dist/dev/pkg/changesets/errors.cjs +0 -386
  37. package/packages/silk-effects/dist/dev/pkg/changesets/errors.js +0 -371
  38. package/packages/silk-effects/dist/dev/pkg/changesets/index.cjs +0 -300
  39. package/packages/silk-effects/dist/dev/pkg/changesets/index.js +0 -179
  40. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/index.cjs +0 -34
  41. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/index.js +0 -29
  42. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/content-structure.cjs +0 -98
  43. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/content-structure.js +0 -98
  44. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/dependency-table-format.cjs +0 -170
  45. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/dependency-table-format.js +0 -170
  46. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/heading-hierarchy.cjs +0 -61
  47. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/heading-hierarchy.js +0 -61
  48. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/required-sections.cjs +0 -54
  49. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/required-sections.js +0 -54
  50. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/uncategorized-content.cjs +0 -54
  51. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/uncategorized-content.js +0 -54
  52. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/utils.cjs +0 -31
  53. package/packages/silk-effects/dist/dev/pkg/changesets/markdownlint/rules/utils.js +0 -30
  54. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/aggregate-dependency-tables.cjs +0 -47
  55. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/aggregate-dependency-tables.js +0 -47
  56. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/contributor-footnotes.cjs +0 -123
  57. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/contributor-footnotes.js +0 -123
  58. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/deduplicate-items.cjs +0 -32
  59. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/deduplicate-items.js +0 -32
  60. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/issue-link-refs.cjs +0 -59
  61. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/issue-link-refs.js +0 -59
  62. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/maintenance-note.cjs +0 -61
  63. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/maintenance-note.js +0 -61
  64. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/merge-sections.cjs +0 -43
  65. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/merge-sections.js +0 -43
  66. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/normalize-format.cjs +0 -47
  67. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/normalize-format.js +0 -47
  68. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/reorder-sections.cjs +0 -34
  69. package/packages/silk-effects/dist/dev/pkg/changesets/remark/plugins/reorder-sections.js +0 -34
  70. package/packages/silk-effects/dist/dev/pkg/changesets/remark/presets.cjs +0 -120
  71. package/packages/silk-effects/dist/dev/pkg/changesets/remark/presets.js +0 -119
  72. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/content-structure.cjs +0 -22
  73. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/content-structure.js +0 -22
  74. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/dependency-table-format.cjs +0 -40
  75. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/dependency-table-format.js +0 -40
  76. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/heading-hierarchy.cjs +0 -19
  77. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/heading-hierarchy.js +0 -19
  78. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/required-sections.cjs +0 -17
  79. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/required-sections.js +0 -17
  80. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/uncategorized-content.cjs +0 -31
  81. package/packages/silk-effects/dist/dev/pkg/changesets/remark/rules/uncategorized-content.js +0 -31
  82. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/changeset.cjs +0 -148
  83. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/changeset.js +0 -145
  84. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/dependency-table.cjs +0 -203
  85. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/dependency-table.js +0 -198
  86. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/git.cjs +0 -69
  87. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/git.js +0 -68
  88. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/github.cjs +0 -177
  89. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/github.js +0 -174
  90. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/options.cjs +0 -183
  91. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/options.js +0 -181
  92. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/package-scope.cjs +0 -129
  93. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/package-scope.js +0 -127
  94. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/primitives.cjs +0 -72
  95. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/primitives.js +0 -71
  96. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/release-plan.cjs +0 -62
  97. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/release-plan.js +0 -56
  98. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/version-files.cjs +0 -154
  99. package/packages/silk-effects/dist/dev/pkg/changesets/schemas/version-files.js +0 -150
  100. package/packages/silk-effects/dist/dev/pkg/changesets/services/branch-analyzer.cjs +0 -300
  101. package/packages/silk-effects/dist/dev/pkg/changesets/services/branch-analyzer.js +0 -294
  102. package/packages/silk-effects/dist/dev/pkg/changesets/services/changelog.cjs +0 -50
  103. package/packages/silk-effects/dist/dev/pkg/changesets/services/changelog.js +0 -49
  104. package/packages/silk-effects/dist/dev/pkg/changesets/services/config-inspector.cjs +0 -489
  105. package/packages/silk-effects/dist/dev/pkg/changesets/services/config-inspector.js +0 -481
  106. package/packages/silk-effects/dist/dev/pkg/changesets/services/deps-regen.cjs +0 -375
  107. package/packages/silk-effects/dist/dev/pkg/changesets/services/deps-regen.js +0 -371
  108. package/packages/silk-effects/dist/dev/pkg/changesets/services/github.cjs +0 -160
  109. package/packages/silk-effects/dist/dev/pkg/changesets/services/github.js +0 -157
  110. package/packages/silk-effects/dist/dev/pkg/changesets/services/maintenance-reason.cjs +0 -68
  111. package/packages/silk-effects/dist/dev/pkg/changesets/services/maintenance-reason.js +0 -66
  112. package/packages/silk-effects/dist/dev/pkg/changesets/services/markdown.cjs +0 -87
  113. package/packages/silk-effects/dist/dev/pkg/changesets/services/markdown.js +0 -85
  114. package/packages/silk-effects/dist/dev/pkg/changesets/services/release-planner.cjs +0 -352
  115. package/packages/silk-effects/dist/dev/pkg/changesets/services/release-planner.js +0 -348
  116. package/packages/silk-effects/dist/dev/pkg/changesets/utils/commit-parser.cjs +0 -81
  117. package/packages/silk-effects/dist/dev/pkg/changesets/utils/commit-parser.js +0 -80
  118. package/packages/silk-effects/dist/dev/pkg/changesets/utils/dep-diff.cjs +0 -111
  119. package/packages/silk-effects/dist/dev/pkg/changesets/utils/dep-diff.js +0 -111
  120. package/packages/silk-effects/dist/dev/pkg/changesets/utils/dependency-table.cjs +0 -351
  121. package/packages/silk-effects/dist/dev/pkg/changesets/utils/dependency-table.js +0 -347
  122. package/packages/silk-effects/dist/dev/pkg/changesets/utils/git.cjs +0 -51
  123. package/packages/silk-effects/dist/dev/pkg/changesets/utils/git.js +0 -51
  124. package/packages/silk-effects/dist/dev/pkg/changesets/utils/issue-refs.cjs +0 -102
  125. package/packages/silk-effects/dist/dev/pkg/changesets/utils/issue-refs.js +0 -101
  126. package/packages/silk-effects/dist/dev/pkg/changesets/utils/jsonpath.cjs +0 -178
  127. package/packages/silk-effects/dist/dev/pkg/changesets/utils/jsonpath.js +0 -175
  128. package/packages/silk-effects/dist/dev/pkg/changesets/utils/logger.cjs +0 -51
  129. package/packages/silk-effects/dist/dev/pkg/changesets/utils/logger.js +0 -50
  130. package/packages/silk-effects/dist/dev/pkg/changesets/utils/markdown-link.cjs +0 -59
  131. package/packages/silk-effects/dist/dev/pkg/changesets/utils/markdown-link.js +0 -57
  132. package/packages/silk-effects/dist/dev/pkg/changesets/utils/publishability.cjs +0 -50
  133. package/packages/silk-effects/dist/dev/pkg/changesets/utils/publishability.js +0 -50
  134. package/packages/silk-effects/dist/dev/pkg/changesets/utils/remark-pipeline.cjs +0 -81
  135. package/packages/silk-effects/dist/dev/pkg/changesets/utils/remark-pipeline.js +0 -79
  136. package/packages/silk-effects/dist/dev/pkg/changesets/utils/section-parser.cjs +0 -94
  137. package/packages/silk-effects/dist/dev/pkg/changesets/utils/section-parser.js +0 -94
  138. package/packages/silk-effects/dist/dev/pkg/changesets/utils/strip-frontmatter.cjs +0 -47
  139. package/packages/silk-effects/dist/dev/pkg/changesets/utils/strip-frontmatter.js +0 -46
  140. package/packages/silk-effects/dist/dev/pkg/changesets/utils/version-blocks.cjs +0 -110
  141. package/packages/silk-effects/dist/dev/pkg/changesets/utils/version-blocks.js +0 -108
  142. package/packages/silk-effects/dist/dev/pkg/changesets/utils/version-files.cjs +0 -336
  143. package/packages/silk-effects/dist/dev/pkg/changesets/utils/version-files.js +0 -336
  144. package/packages/silk-effects/dist/dev/pkg/changesets/vendor/github-info.cjs +0 -77
  145. package/packages/silk-effects/dist/dev/pkg/changesets/vendor/github-info.js +0 -77
  146. package/packages/silk-effects/dist/dev/pkg/errors/ChangesetConfigError.cjs +0 -21
  147. package/packages/silk-effects/dist/dev/pkg/errors/ChangesetConfigError.js +0 -21
  148. package/packages/silk-effects/dist/dev/pkg/schemas/VersioningSchemas.cjs +0 -101
  149. package/packages/silk-effects/dist/dev/pkg/schemas/VersioningSchemas.js +0 -99
  150. package/packages/silk-effects/dist/dev/pkg/services/ChangesetConfig.cjs +0 -81
  151. package/packages/silk-effects/dist/dev/pkg/services/ChangesetConfig.js +0 -80
  152. package/packages/silk-effects/dist/dev/pkg/services/ChangesetConfigReader.cjs +0 -109
  153. package/packages/silk-effects/dist/dev/pkg/services/ChangesetConfigReader.js +0 -108
  154. package/packages/silk-effects/dist/dev/pkg/services/SilkPublishability.cjs +0 -238
  155. package/packages/silk-effects/dist/dev/pkg/services/SilkPublishability.js +0 -236
@@ -1,300 +0,0 @@
1
- const require_errors = require('../errors.cjs');
2
- const require_config_inspector = require('./config-inspector.cjs');
3
- let effect = require("effect");
4
- let node_child_process = require("node:child_process");
5
-
6
- //#region ../silk-effects/dist/dev/pkg/changesets/services/branch-analyzer.js
7
- /**
8
- * `BranchAnalyzer` service — combine a git diff against the base branch with
9
- * the per-file classification produced by {@link ConfigInspector}.
10
- *
11
- * @remarks
12
- * This is the single call that the changeset-manager agent uses during its
13
- * inventory step: one invocation returns the diff, the per-file package
14
- * attribution, the set of packages affected by the branch, and the list of
15
- * paths that did not map to any known release surface (so the agent can ask
16
- * the user about them rather than silently excluding).
17
- *
18
- * Base-branch resolution order (highest priority first):
19
- *
20
- * 1. Explicit `opts.baseBranch` passed to {@link BranchAnalyzerShape.analyzeBranch}.
21
- * 2. `baseBranch` from `.changeset/config.json` (surfaced via the inspector).
22
- * 3. The branch `origin/HEAD` points to (`git symbolic-ref refs/remotes/origin/HEAD`).
23
- * 4. `"main"` as a final fallback.
24
- *
25
- * Diff resolution covers everything the user might commit before merging:
26
- *
27
- * 1. `git merge-base <base> HEAD` finds the common ancestor.
28
- * 2. `git diff --name-status <merge-base>` (working tree vs merge-base)
29
- * returns every committed, staged, AND unstaged change since the
30
- * branch diverged. The two-arg `<merge-base>...HEAD` form would miss
31
- * work-in-progress — what the user has open in their editor right
32
- * now is exactly the state the agent needs to document.
33
- * 3. `git ls-files --others --exclude-standard` adds untracked files
34
- * (entirely new files not yet `git add`-ed). Each is reported with
35
- * status `"added"`.
36
- *
37
- * The two results are deduped by path before classification. Renames
38
- * are reported as `"renamed"` with the new path; the old path is
39
- * discarded since the classifier needs a single canonical path per
40
- * file.
41
- *
42
- * @see {@link BranchAnalyzer} for the service tag
43
- * @see {@link BranchAnalyzerLive} for the production layer
44
- * @see {@link ConfigInspector} for the underlying classification service
45
- *
46
- */
47
- /** Git diff status as reported by `--name-status`. @public */
48
- const FileStatusSchema = effect.Schema.Literal("added", "modified", "deleted", "renamed", "copied", "typechange", "unmerged", "unknown").annotations({ identifier: "FileStatus" });
49
- /** One file entry in the branch analysis output. @public */
50
- const BranchFileEntrySchema = effect.Schema.Struct({
51
- path: effect.Schema.String.annotations({ description: "Repo-relative path (the new path in the case of renames)." }),
52
- status: FileStatusSchema,
53
- package: effect.Schema.NullOr(effect.Schema.String).annotations({ description: "Owning package, or null if outside every known release surface." }),
54
- reason: require_config_inspector.ClassificationReasonSchema
55
- }).annotations({ identifier: "BranchFileEntry" });
56
- /** Structured result of analyzing the current branch against its base. @public */
57
- const BranchAnalysisSchema = effect.Schema.Struct({
58
- baseBranch: effect.Schema.String,
59
- mergeBaseSha: effect.Schema.String,
60
- files: effect.Schema.Array(BranchFileEntrySchema),
61
- packagesAffected: effect.Schema.Array(effect.Schema.String),
62
- unmappedFiles: effect.Schema.Array(effect.Schema.String).annotations({ description: "Repo-relative paths whose package is null — candidates for an AskUserQuestion." })
63
- }).annotations({ identifier: "BranchAnalysis" });
64
- /**
65
- * Base class for {@link BranchAnalyzer}.
66
- *
67
- * @privateRemarks
68
- * Effect's `Context.Tag` creates an anonymous base class that api-extractor
69
- * cannot follow without an explicit export. Do not delete.
70
- *
71
- * @internal
72
- */
73
- const BranchAnalyzerBase = effect.Context.Tag("BranchAnalyzer")();
74
- /**
75
- * Effect service tag for {@link BranchAnalyzerShape}.
76
- *
77
- * @example
78
- * ```typescript
79
- * import { Effect } from "effect";
80
- * import { BranchAnalyzer, BranchAnalyzerLive, ConfigInspectorLive } from "@savvy-web/changesets";
81
- *
82
- * const program = Effect.gen(function* () {
83
- * const analyzer = yield* BranchAnalyzer;
84
- * const analysis = yield* analyzer.analyzeBranch(process.cwd());
85
- * return analysis.packagesAffected;
86
- * });
87
- *
88
- * Effect.runPromise(
89
- * program.pipe(
90
- * Effect.provide(BranchAnalyzerLive),
91
- * Effect.provide(ConfigInspectorLive),
92
- * // ... + ChangesetConfigReaderLive + WorkspacesLive + NodeContext.layer
93
- * ),
94
- * );
95
- * ```
96
- *
97
- * @public
98
- */
99
- var BranchAnalyzer = class extends BranchAnalyzerBase {};
100
- /**
101
- * Invoke `git` with the given args under `cwd` and return stdout. On
102
- * non-zero exit (or any throw), maps to a {@link GitError} carrying the
103
- * command, cwd, and captured stderr.
104
- */
105
- function runGit(cwd, args) {
106
- return effect.Effect.try({
107
- try: () => (0, node_child_process.execFileSync)("git", args, {
108
- cwd,
109
- encoding: "utf8",
110
- stdio: [
111
- "ignore",
112
- "pipe",
113
- "pipe"
114
- ]
115
- }),
116
- catch: (error) => {
117
- const e = error;
118
- const stderr = typeof e.stderr === "string" ? e.stderr : e.stderr?.toString() ?? "";
119
- return new require_errors.GitError({
120
- command: `git ${args.join(" ")}`,
121
- cwd,
122
- reason: stderr.trim() || e.message || String(error)
123
- });
124
- }
125
- });
126
- }
127
- const STATUS_MAP = {
128
- A: "added",
129
- M: "modified",
130
- D: "deleted",
131
- R: "renamed",
132
- C: "copied",
133
- T: "typechange",
134
- U: "unmerged"
135
- };
136
- function statusFromCode(code) {
137
- const head = code.charAt(0);
138
- return STATUS_MAP[head] ?? "unknown";
139
- }
140
- /**
141
- * Parse `git diff --name-status -z` output into one entry per changed file.
142
- *
143
- * `-z` separates fields with NUL bytes and avoids the per-record `\n`
144
- * delimiter, so paths containing spaces or special characters round-trip
145
- * cleanly. Rename and copy entries occupy three NUL-separated tokens
146
- * (status, old path, new path) instead of two; everything else is two.
147
- */
148
- function parseNameStatus(output) {
149
- if (output.length === 0) return [];
150
- const tokens = output.split("\0");
151
- if (tokens[tokens.length - 1] === "") tokens.pop();
152
- const entries = [];
153
- for (let i = 0; i < tokens.length;) {
154
- const code = tokens[i] ?? "";
155
- if (code.length === 0) {
156
- /* v8 ignore next 2 -- defensive guard; trailing empties stripped at parse time */
157
- i += 1;
158
- continue;
159
- }
160
- const status = statusFromCode(code);
161
- if (status === "renamed" || status === "copied") {
162
- const newPath = tokens[i + 2] ?? "";
163
- if (newPath.length > 0) entries.push({
164
- path: newPath,
165
- status
166
- });
167
- i += 3;
168
- } else {
169
- const path = tokens[i + 1] ?? "";
170
- if (path.length > 0) entries.push({
171
- path,
172
- status
173
- });
174
- i += 2;
175
- }
176
- }
177
- return entries;
178
- }
179
- /**
180
- * Parse a NUL-separated list of paths (e.g., `git ls-files -z` output) into
181
- * an array of strings, dropping any trailing empty entry left by the final
182
- * NUL byte.
183
- */
184
- function parseNulSeparatedPaths(output) {
185
- if (output.length === 0) return [];
186
- const tokens = output.split("\0");
187
- if (tokens[tokens.length - 1] === "") tokens.pop();
188
- return tokens.filter((t) => t.length > 0);
189
- }
190
- /**
191
- * Resolve the base branch using the documented priority order.
192
- */
193
- function resolveBaseBranch(opts) {
194
- if (opts.explicit && opts.explicit.length > 0) return effect.Effect.succeed(opts.explicit);
195
- if (opts.configBaseBranch && opts.configBaseBranch !== "main") return effect.Effect.succeed(opts.configBaseBranch);
196
- return runGit(opts.cwd, [
197
- "symbolic-ref",
198
- "--quiet",
199
- "--short",
200
- "refs/remotes/origin/HEAD"
201
- ]).pipe(
202
- /* v8 ignore start -- callback only reachable with a remote that exposes origin/HEAD */
203
- effect.Effect.map((stdout) => {
204
- const trimmed = stdout.trim();
205
- return trimmed.length > 0 ? trimmed.replace(/^origin\//, "") : opts.configBaseBranch;
206
- }),
207
- /* v8 ignore stop */
208
- effect.Effect.catchAll(() => effect.Effect.succeed(opts.configBaseBranch))
209
- );
210
- }
211
- function makeShape(inspector) {
212
- const analyzeBranch = (cwd, opts) => effect.Effect.gen(function* () {
213
- const inspected = yield* inspector.inspect(cwd);
214
- const baseBranch = yield* resolveBaseBranch({
215
- explicit: opts?.baseBranch,
216
- configBaseBranch: inspected.baseBranch,
217
- cwd
218
- });
219
- const mergeBaseSha = (yield* runGit(cwd, [
220
- "merge-base",
221
- baseBranch,
222
- "HEAD"
223
- ])).trim();
224
- const diffEntries = parseNameStatus(yield* runGit(cwd, [
225
- "diff",
226
- "--name-status",
227
- "-z",
228
- mergeBaseSha
229
- ]));
230
- const untrackedEntries = parseNulSeparatedPaths(yield* runGit(cwd, [
231
- "ls-files",
232
- "-z",
233
- "--others",
234
- "--exclude-standard"
235
- ])).map((path) => ({
236
- path,
237
- status: "added"
238
- }));
239
- const seen = /* @__PURE__ */ new Set();
240
- const rawEntries = [];
241
- for (const e of diffEntries) {
242
- if (seen.has(e.path)) continue;
243
- seen.add(e.path);
244
- rawEntries.push(e);
245
- }
246
- for (const e of untrackedEntries) {
247
- if (seen.has(e.path)) continue;
248
- seen.add(e.path);
249
- rawEntries.push(e);
250
- }
251
- const paths = rawEntries.map((e) => e.path);
252
- const classifications = yield* inspector.classify(cwd, paths);
253
- const files = rawEntries.map((entry, idx) => {
254
- const c = classifications[idx];
255
- return {
256
- path: entry.path,
257
- status: entry.status,
258
- package: c?.package ?? null,
259
- reason: c?.reason ?? null
260
- };
261
- });
262
- return {
263
- baseBranch,
264
- mergeBaseSha,
265
- files,
266
- packagesAffected: Array.from(new Set(files.map((f) => f.package).filter((p) => p !== null))).sort(),
267
- unmappedFiles: files.filter((f) => f.package === null).map((f) => f.path)
268
- };
269
- });
270
- return { analyzeBranch };
271
- }
272
- /**
273
- * Live layer for {@link BranchAnalyzer}.
274
- *
275
- * Requires {@link ConfigInspector} (which in turn requires
276
- * `ChangesetConfigReader` and `WorkspaceDiscovery`).
277
- *
278
- * @public
279
- */
280
- const BranchAnalyzerLive = effect.Layer.effect(BranchAnalyzer, effect.Effect.gen(function* () {
281
- return makeShape(yield* require_config_inspector.ConfigInspector);
282
- }));
283
- /**
284
- * Test factory — build a {@link BranchAnalyzer} that returns a fixed
285
- * {@link BranchAnalysis} for any input.
286
- *
287
- * @public
288
- */
289
- function makeBranchAnalyzerTest(fixed) {
290
- return effect.Layer.succeed(BranchAnalyzer, { analyzeBranch: () => effect.Effect.succeed(fixed) });
291
- }
292
-
293
- //#endregion
294
- exports.BranchAnalysisSchema = BranchAnalysisSchema;
295
- exports.BranchAnalyzer = BranchAnalyzer;
296
- exports.BranchAnalyzerBase = BranchAnalyzerBase;
297
- exports.BranchAnalyzerLive = BranchAnalyzerLive;
298
- exports.BranchFileEntrySchema = BranchFileEntrySchema;
299
- exports.FileStatusSchema = FileStatusSchema;
300
- exports.makeBranchAnalyzerTest = makeBranchAnalyzerTest;
@@ -1,294 +0,0 @@
1
- import { GitError } from "../errors.js";
2
- import { ClassificationReasonSchema, ConfigInspector } from "./config-inspector.js";
3
- import { Context, Effect, Layer, Schema } from "effect";
4
- import { execFileSync } from "node:child_process";
5
-
6
- //#region ../silk-effects/dist/dev/pkg/changesets/services/branch-analyzer.js
7
- /**
8
- * `BranchAnalyzer` service — combine a git diff against the base branch with
9
- * the per-file classification produced by {@link ConfigInspector}.
10
- *
11
- * @remarks
12
- * This is the single call that the changeset-manager agent uses during its
13
- * inventory step: one invocation returns the diff, the per-file package
14
- * attribution, the set of packages affected by the branch, and the list of
15
- * paths that did not map to any known release surface (so the agent can ask
16
- * the user about them rather than silently excluding).
17
- *
18
- * Base-branch resolution order (highest priority first):
19
- *
20
- * 1. Explicit `opts.baseBranch` passed to {@link BranchAnalyzerShape.analyzeBranch}.
21
- * 2. `baseBranch` from `.changeset/config.json` (surfaced via the inspector).
22
- * 3. The branch `origin/HEAD` points to (`git symbolic-ref refs/remotes/origin/HEAD`).
23
- * 4. `"main"` as a final fallback.
24
- *
25
- * Diff resolution covers everything the user might commit before merging:
26
- *
27
- * 1. `git merge-base <base> HEAD` finds the common ancestor.
28
- * 2. `git diff --name-status <merge-base>` (working tree vs merge-base)
29
- * returns every committed, staged, AND unstaged change since the
30
- * branch diverged. The two-arg `<merge-base>...HEAD` form would miss
31
- * work-in-progress — what the user has open in their editor right
32
- * now is exactly the state the agent needs to document.
33
- * 3. `git ls-files --others --exclude-standard` adds untracked files
34
- * (entirely new files not yet `git add`-ed). Each is reported with
35
- * status `"added"`.
36
- *
37
- * The two results are deduped by path before classification. Renames
38
- * are reported as `"renamed"` with the new path; the old path is
39
- * discarded since the classifier needs a single canonical path per
40
- * file.
41
- *
42
- * @see {@link BranchAnalyzer} for the service tag
43
- * @see {@link BranchAnalyzerLive} for the production layer
44
- * @see {@link ConfigInspector} for the underlying classification service
45
- *
46
- */
47
- /** Git diff status as reported by `--name-status`. @public */
48
- const FileStatusSchema = Schema.Literal("added", "modified", "deleted", "renamed", "copied", "typechange", "unmerged", "unknown").annotations({ identifier: "FileStatus" });
49
- /** One file entry in the branch analysis output. @public */
50
- const BranchFileEntrySchema = Schema.Struct({
51
- path: Schema.String.annotations({ description: "Repo-relative path (the new path in the case of renames)." }),
52
- status: FileStatusSchema,
53
- package: Schema.NullOr(Schema.String).annotations({ description: "Owning package, or null if outside every known release surface." }),
54
- reason: ClassificationReasonSchema
55
- }).annotations({ identifier: "BranchFileEntry" });
56
- /** Structured result of analyzing the current branch against its base. @public */
57
- const BranchAnalysisSchema = Schema.Struct({
58
- baseBranch: Schema.String,
59
- mergeBaseSha: Schema.String,
60
- files: Schema.Array(BranchFileEntrySchema),
61
- packagesAffected: Schema.Array(Schema.String),
62
- unmappedFiles: Schema.Array(Schema.String).annotations({ description: "Repo-relative paths whose package is null — candidates for an AskUserQuestion." })
63
- }).annotations({ identifier: "BranchAnalysis" });
64
- /**
65
- * Base class for {@link BranchAnalyzer}.
66
- *
67
- * @privateRemarks
68
- * Effect's `Context.Tag` creates an anonymous base class that api-extractor
69
- * cannot follow without an explicit export. Do not delete.
70
- *
71
- * @internal
72
- */
73
- const BranchAnalyzerBase = Context.Tag("BranchAnalyzer")();
74
- /**
75
- * Effect service tag for {@link BranchAnalyzerShape}.
76
- *
77
- * @example
78
- * ```typescript
79
- * import { Effect } from "effect";
80
- * import { BranchAnalyzer, BranchAnalyzerLive, ConfigInspectorLive } from "@savvy-web/changesets";
81
- *
82
- * const program = Effect.gen(function* () {
83
- * const analyzer = yield* BranchAnalyzer;
84
- * const analysis = yield* analyzer.analyzeBranch(process.cwd());
85
- * return analysis.packagesAffected;
86
- * });
87
- *
88
- * Effect.runPromise(
89
- * program.pipe(
90
- * Effect.provide(BranchAnalyzerLive),
91
- * Effect.provide(ConfigInspectorLive),
92
- * // ... + ChangesetConfigReaderLive + WorkspacesLive + NodeContext.layer
93
- * ),
94
- * );
95
- * ```
96
- *
97
- * @public
98
- */
99
- var BranchAnalyzer = class extends BranchAnalyzerBase {};
100
- /**
101
- * Invoke `git` with the given args under `cwd` and return stdout. On
102
- * non-zero exit (or any throw), maps to a {@link GitError} carrying the
103
- * command, cwd, and captured stderr.
104
- */
105
- function runGit(cwd, args) {
106
- return Effect.try({
107
- try: () => execFileSync("git", args, {
108
- cwd,
109
- encoding: "utf8",
110
- stdio: [
111
- "ignore",
112
- "pipe",
113
- "pipe"
114
- ]
115
- }),
116
- catch: (error) => {
117
- const e = error;
118
- const stderr = typeof e.stderr === "string" ? e.stderr : e.stderr?.toString() ?? "";
119
- return new GitError({
120
- command: `git ${args.join(" ")}`,
121
- cwd,
122
- reason: stderr.trim() || e.message || String(error)
123
- });
124
- }
125
- });
126
- }
127
- const STATUS_MAP = {
128
- A: "added",
129
- M: "modified",
130
- D: "deleted",
131
- R: "renamed",
132
- C: "copied",
133
- T: "typechange",
134
- U: "unmerged"
135
- };
136
- function statusFromCode(code) {
137
- const head = code.charAt(0);
138
- return STATUS_MAP[head] ?? "unknown";
139
- }
140
- /**
141
- * Parse `git diff --name-status -z` output into one entry per changed file.
142
- *
143
- * `-z` separates fields with NUL bytes and avoids the per-record `\n`
144
- * delimiter, so paths containing spaces or special characters round-trip
145
- * cleanly. Rename and copy entries occupy three NUL-separated tokens
146
- * (status, old path, new path) instead of two; everything else is two.
147
- */
148
- function parseNameStatus(output) {
149
- if (output.length === 0) return [];
150
- const tokens = output.split("\0");
151
- if (tokens[tokens.length - 1] === "") tokens.pop();
152
- const entries = [];
153
- for (let i = 0; i < tokens.length;) {
154
- const code = tokens[i] ?? "";
155
- if (code.length === 0) {
156
- /* v8 ignore next 2 -- defensive guard; trailing empties stripped at parse time */
157
- i += 1;
158
- continue;
159
- }
160
- const status = statusFromCode(code);
161
- if (status === "renamed" || status === "copied") {
162
- const newPath = tokens[i + 2] ?? "";
163
- if (newPath.length > 0) entries.push({
164
- path: newPath,
165
- status
166
- });
167
- i += 3;
168
- } else {
169
- const path = tokens[i + 1] ?? "";
170
- if (path.length > 0) entries.push({
171
- path,
172
- status
173
- });
174
- i += 2;
175
- }
176
- }
177
- return entries;
178
- }
179
- /**
180
- * Parse a NUL-separated list of paths (e.g., `git ls-files -z` output) into
181
- * an array of strings, dropping any trailing empty entry left by the final
182
- * NUL byte.
183
- */
184
- function parseNulSeparatedPaths(output) {
185
- if (output.length === 0) return [];
186
- const tokens = output.split("\0");
187
- if (tokens[tokens.length - 1] === "") tokens.pop();
188
- return tokens.filter((t) => t.length > 0);
189
- }
190
- /**
191
- * Resolve the base branch using the documented priority order.
192
- */
193
- function resolveBaseBranch(opts) {
194
- if (opts.explicit && opts.explicit.length > 0) return Effect.succeed(opts.explicit);
195
- if (opts.configBaseBranch && opts.configBaseBranch !== "main") return Effect.succeed(opts.configBaseBranch);
196
- return runGit(opts.cwd, [
197
- "symbolic-ref",
198
- "--quiet",
199
- "--short",
200
- "refs/remotes/origin/HEAD"
201
- ]).pipe(
202
- /* v8 ignore start -- callback only reachable with a remote that exposes origin/HEAD */
203
- Effect.map((stdout) => {
204
- const trimmed = stdout.trim();
205
- return trimmed.length > 0 ? trimmed.replace(/^origin\//, "") : opts.configBaseBranch;
206
- }),
207
- /* v8 ignore stop */
208
- Effect.catchAll(() => Effect.succeed(opts.configBaseBranch))
209
- );
210
- }
211
- function makeShape(inspector) {
212
- const analyzeBranch = (cwd, opts) => Effect.gen(function* () {
213
- const inspected = yield* inspector.inspect(cwd);
214
- const baseBranch = yield* resolveBaseBranch({
215
- explicit: opts?.baseBranch,
216
- configBaseBranch: inspected.baseBranch,
217
- cwd
218
- });
219
- const mergeBaseSha = (yield* runGit(cwd, [
220
- "merge-base",
221
- baseBranch,
222
- "HEAD"
223
- ])).trim();
224
- const diffEntries = parseNameStatus(yield* runGit(cwd, [
225
- "diff",
226
- "--name-status",
227
- "-z",
228
- mergeBaseSha
229
- ]));
230
- const untrackedEntries = parseNulSeparatedPaths(yield* runGit(cwd, [
231
- "ls-files",
232
- "-z",
233
- "--others",
234
- "--exclude-standard"
235
- ])).map((path) => ({
236
- path,
237
- status: "added"
238
- }));
239
- const seen = /* @__PURE__ */ new Set();
240
- const rawEntries = [];
241
- for (const e of diffEntries) {
242
- if (seen.has(e.path)) continue;
243
- seen.add(e.path);
244
- rawEntries.push(e);
245
- }
246
- for (const e of untrackedEntries) {
247
- if (seen.has(e.path)) continue;
248
- seen.add(e.path);
249
- rawEntries.push(e);
250
- }
251
- const paths = rawEntries.map((e) => e.path);
252
- const classifications = yield* inspector.classify(cwd, paths);
253
- const files = rawEntries.map((entry, idx) => {
254
- const c = classifications[idx];
255
- return {
256
- path: entry.path,
257
- status: entry.status,
258
- package: c?.package ?? null,
259
- reason: c?.reason ?? null
260
- };
261
- });
262
- return {
263
- baseBranch,
264
- mergeBaseSha,
265
- files,
266
- packagesAffected: Array.from(new Set(files.map((f) => f.package).filter((p) => p !== null))).sort(),
267
- unmappedFiles: files.filter((f) => f.package === null).map((f) => f.path)
268
- };
269
- });
270
- return { analyzeBranch };
271
- }
272
- /**
273
- * Live layer for {@link BranchAnalyzer}.
274
- *
275
- * Requires {@link ConfigInspector} (which in turn requires
276
- * `ChangesetConfigReader` and `WorkspaceDiscovery`).
277
- *
278
- * @public
279
- */
280
- const BranchAnalyzerLive = Layer.effect(BranchAnalyzer, Effect.gen(function* () {
281
- return makeShape(yield* ConfigInspector);
282
- }));
283
- /**
284
- * Test factory — build a {@link BranchAnalyzer} that returns a fixed
285
- * {@link BranchAnalysis} for any input.
286
- *
287
- * @public
288
- */
289
- function makeBranchAnalyzerTest(fixed) {
290
- return Layer.succeed(BranchAnalyzer, { analyzeBranch: () => Effect.succeed(fixed) });
291
- }
292
-
293
- //#endregion
294
- export { BranchAnalysisSchema, BranchAnalyzer, BranchAnalyzerBase, BranchAnalyzerLive, BranchFileEntrySchema, FileStatusSchema, makeBranchAnalyzerTest };
@@ -1,50 +0,0 @@
1
- let effect = require("effect");
2
-
3
- //#region ../silk-effects/dist/dev/pkg/changesets/services/changelog.js
4
- /**
5
- * Base class for ChangelogService.
6
- *
7
- * @privateRemarks
8
- * This export is required for api-extractor documentation generation.
9
- * Effect's Context.Tag creates an anonymous base class that must be
10
- * explicitly exported to avoid "forgotten export" warnings. Do not delete.
11
- *
12
- * @internal
13
- */
14
- const ChangelogServiceBase = effect.Context.Tag("ChangelogService")();
15
- /**
16
- * Effect service tag for changelog formatting.
17
- *
18
- * Provides dependency-injected access to the two Changesets API formatter
19
- * functions: `formatReleaseLine` and `formatDependencyReleaseLine`.
20
- *
21
- * @remarks
22
- * This is an abstract service tag — it has no default `Layer`. The concrete
23
- * implementation is the `\@savvy-web/changesets/changelog` subpath export,
24
- * which wires the formatting logic through `Effect.runPromise` for the
25
- * Changesets CLI. For direct Effect usage, build your own layer or use
26
- * the class-based `Changelog` wrapper.
27
- *
28
- * @example
29
- * ```typescript
30
- * import { Effect } from "effect";
31
- * import type { ChangesetOptions } from "\@savvy-web/changesets";
32
- * import { ChangelogService, GitHubLive, MarkdownLive } from "\@savvy-web/changesets";
33
- *
34
- * const program = Effect.gen(function* () {
35
- * const changelog = yield* ChangelogService;
36
- * const line = yield* changelog.formatReleaseLine(changeset, "minor", options);
37
- * return line;
38
- * });
39
- * ```
40
- *
41
- * @see {@link ChangelogServiceShape} for the service interface
42
- * @see {@link ChangelogServiceBase} for the api-extractor base class
43
- *
44
- * @public
45
- */
46
- var ChangelogService = class extends ChangelogServiceBase {};
47
-
48
- //#endregion
49
- exports.ChangelogService = ChangelogService;
50
- exports.ChangelogServiceBase = ChangelogServiceBase;
@@ -1,49 +0,0 @@
1
- import { Context } from "effect";
2
-
3
- //#region ../silk-effects/dist/dev/pkg/changesets/services/changelog.js
4
- /**
5
- * Base class for ChangelogService.
6
- *
7
- * @privateRemarks
8
- * This export is required for api-extractor documentation generation.
9
- * Effect's Context.Tag creates an anonymous base class that must be
10
- * explicitly exported to avoid "forgotten export" warnings. Do not delete.
11
- *
12
- * @internal
13
- */
14
- const ChangelogServiceBase = Context.Tag("ChangelogService")();
15
- /**
16
- * Effect service tag for changelog formatting.
17
- *
18
- * Provides dependency-injected access to the two Changesets API formatter
19
- * functions: `formatReleaseLine` and `formatDependencyReleaseLine`.
20
- *
21
- * @remarks
22
- * This is an abstract service tag — it has no default `Layer`. The concrete
23
- * implementation is the `\@savvy-web/changesets/changelog` subpath export,
24
- * which wires the formatting logic through `Effect.runPromise` for the
25
- * Changesets CLI. For direct Effect usage, build your own layer or use
26
- * the class-based `Changelog` wrapper.
27
- *
28
- * @example
29
- * ```typescript
30
- * import { Effect } from "effect";
31
- * import type { ChangesetOptions } from "\@savvy-web/changesets";
32
- * import { ChangelogService, GitHubLive, MarkdownLive } from "\@savvy-web/changesets";
33
- *
34
- * const program = Effect.gen(function* () {
35
- * const changelog = yield* ChangelogService;
36
- * const line = yield* changelog.formatReleaseLine(changeset, "minor", options);
37
- * return line;
38
- * });
39
- * ```
40
- *
41
- * @see {@link ChangelogServiceShape} for the service interface
42
- * @see {@link ChangelogServiceBase} for the api-extractor base class
43
- *
44
- * @public
45
- */
46
- var ChangelogService = class extends ChangelogServiceBase {};
47
-
48
- //#endregion
49
- export { ChangelogService, ChangelogServiceBase };