@contractspec/bundle.workspace 1.45.4 → 1.45.6

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 (66) hide show
  1. package/dist/adapters/fs.d.ts +2 -1
  2. package/dist/adapters/fs.d.ts.map +1 -1
  3. package/dist/adapters/fs.js +1 -1
  4. package/dist/adapters/fs.js.map +1 -1
  5. package/dist/adapters/git.js +29 -0
  6. package/dist/adapters/git.js.map +1 -1
  7. package/dist/adapters/index.d.ts +1 -1
  8. package/dist/adapters/index.js +1 -1
  9. package/dist/index.d.ts +12 -7
  10. package/dist/index.js +5 -2
  11. package/dist/ports/git.d.ts +14 -1
  12. package/dist/ports/git.d.ts.map +1 -1
  13. package/dist/ports/index.d.ts +3 -2
  14. package/dist/ports/rulesync.d.ts +38 -0
  15. package/dist/ports/rulesync.d.ts.map +1 -0
  16. package/dist/services/doctor/checks/cli.js +9 -0
  17. package/dist/services/doctor/checks/cli.js.map +1 -1
  18. package/dist/services/doctor/checks/config.js +132 -0
  19. package/dist/services/doctor/checks/config.js.map +1 -1
  20. package/dist/services/doctor/checks/deps.js +13 -0
  21. package/dist/services/doctor/checks/deps.js.map +1 -1
  22. package/dist/services/doctor/checks/workspace.js +20 -1
  23. package/dist/services/doctor/checks/workspace.js.map +1 -1
  24. package/dist/services/hooks/hooks-service.d.ts +24 -0
  25. package/dist/services/hooks/hooks-service.d.ts.map +1 -0
  26. package/dist/services/hooks/hooks-service.js +126 -0
  27. package/dist/services/hooks/hooks-service.js.map +1 -0
  28. package/dist/services/hooks/index.d.ts +10 -0
  29. package/dist/services/hooks/index.d.ts.map +1 -0
  30. package/dist/services/hooks/index.js +12 -0
  31. package/dist/services/hooks/index.js.map +1 -0
  32. package/dist/services/hooks/types.d.ts +56 -0
  33. package/dist/services/hooks/types.d.ts.map +1 -0
  34. package/dist/services/index.d.ts +5 -1
  35. package/dist/services/index.js +3 -0
  36. package/dist/services/rulesync.d.ts +17 -0
  37. package/dist/services/rulesync.d.ts.map +1 -0
  38. package/dist/services/rulesync.js +71 -0
  39. package/dist/services/rulesync.js.map +1 -0
  40. package/dist/services/setup/config-generators.d.ts.map +1 -1
  41. package/dist/services/setup/config-generators.js +14 -0
  42. package/dist/services/setup/config-generators.js.map +1 -1
  43. package/dist/services/upgrade/index.d.ts +10 -0
  44. package/dist/services/upgrade/index.d.ts.map +1 -0
  45. package/dist/services/upgrade/index.js +15 -0
  46. package/dist/services/upgrade/index.js.map +1 -0
  47. package/dist/services/upgrade/types.d.ts +78 -0
  48. package/dist/services/upgrade/types.d.ts.map +1 -0
  49. package/dist/services/upgrade/upgrade-service.d.ts +38 -0
  50. package/dist/services/upgrade/upgrade-service.d.ts.map +1 -0
  51. package/dist/services/upgrade/upgrade-service.js +201 -0
  52. package/dist/services/upgrade/upgrade-service.js.map +1 -0
  53. package/dist/services/versioning/conventional-commits.d.ts +95 -0
  54. package/dist/services/versioning/conventional-commits.d.ts.map +1 -0
  55. package/dist/services/versioning/conventional-commits.js +184 -0
  56. package/dist/services/versioning/conventional-commits.js.map +1 -0
  57. package/dist/services/versioning/index.d.ts +4 -3
  58. package/dist/services/versioning/index.js +13 -2
  59. package/dist/services/versioning/index.js.map +1 -1
  60. package/dist/services/versioning/types.d.ts +9 -7
  61. package/dist/services/versioning/types.d.ts.map +1 -1
  62. package/dist/services/versioning/versioning-service.d.ts +43 -1
  63. package/dist/services/versioning/versioning-service.d.ts.map +1 -1
  64. package/dist/services/versioning/versioning-service.js +144 -2
  65. package/dist/services/versioning/versioning-service.js.map +1 -1
  66. package/package.json +7 -7
@@ -0,0 +1,184 @@
1
+ //#region src/services/versioning/conventional-commits.ts
2
+ /**
3
+ * Default mapping of commit types to version bump types.
4
+ *
5
+ * - `feat` → minor (new feature)
6
+ * - `fix` → patch (bug fix)
7
+ * - `perf` → patch (performance improvement)
8
+ * - `refactor` → patch (code refactoring)
9
+ * - `docs` → null (no version bump)
10
+ * - `style` → null (no version bump)
11
+ * - `test` → null (no version bump)
12
+ * - `chore` → null (no version bump)
13
+ * - `ci` → null (no version bump)
14
+ * - `build` → null (no version bump)
15
+ */
16
+ const DEFAULT_COMMIT_TYPE_MAP = {
17
+ feat: "minor",
18
+ fix: "patch",
19
+ perf: "patch",
20
+ refactor: "patch",
21
+ docs: null,
22
+ style: null,
23
+ test: null,
24
+ chore: null,
25
+ ci: null,
26
+ build: null,
27
+ revert: "patch"
28
+ };
29
+ /**
30
+ * Regex pattern for parsing conventional commit messages.
31
+ *
32
+ * Matches: type(scope)!: description
33
+ * Groups:
34
+ * 1. type
35
+ * 2. scope (optional)
36
+ * 3. breaking indicator (optional !)
37
+ * 4. description
38
+ */
39
+ const CONVENTIONAL_COMMIT_PATTERN = /^(\w+)(?:\(([^)]+)\))?(!)?\s*:\s*(.+)$/;
40
+ /**
41
+ * Pattern for detecting BREAKING CHANGE in commit body/footer.
42
+ */
43
+ const BREAKING_CHANGE_PATTERN = /^BREAKING[ -]CHANGE:\s*(.+)$/im;
44
+ /**
45
+ * Parse a conventional commit message.
46
+ *
47
+ * @param message - Full commit message (may include body)
48
+ * @returns Parsed commit or null if not a valid conventional commit
49
+ */
50
+ function parseConventionalCommit(message) {
51
+ const lines = message.split("\n");
52
+ const firstLine = lines[0]?.trim();
53
+ if (!firstLine) return null;
54
+ const match = firstLine.match(CONVENTIONAL_COMMIT_PATTERN);
55
+ if (!match) return null;
56
+ const [, type, scope, breakingIndicator, description] = match;
57
+ if (!type || !description) return null;
58
+ const body = lines.slice(1).join("\n").trim() || void 0;
59
+ const breakingMatch = body?.match(BREAKING_CHANGE_PATTERN);
60
+ const breakingDescription = breakingMatch?.[1];
61
+ return {
62
+ type: type.toLowerCase(),
63
+ scope: scope?.toLowerCase(),
64
+ breaking: !!breakingIndicator || !!breakingMatch,
65
+ description: description.trim(),
66
+ body,
67
+ breakingDescription,
68
+ raw: message
69
+ };
70
+ }
71
+ /**
72
+ * Check if a commit message follows conventional commit format.
73
+ */
74
+ function isConventionalCommit(message) {
75
+ return parseConventionalCommit(message) !== null;
76
+ }
77
+ /**
78
+ * Determine the version bump type from a conventional commit.
79
+ *
80
+ * @param commit - Parsed conventional commit
81
+ * @param typeMap - Optional custom type-to-bump mapping
82
+ * @returns Version bump type or null if no bump needed
83
+ */
84
+ function getBumpTypeFromCommit(commit, typeMap = DEFAULT_COMMIT_TYPE_MAP) {
85
+ if (commit.breaking) return "major";
86
+ return typeMap[commit.type] ?? null;
87
+ }
88
+ /**
89
+ * Determine the highest bump type from multiple commits.
90
+ *
91
+ * @param commits - Array of parsed conventional commits
92
+ * @param typeMap - Optional custom type-to-bump mapping
93
+ * @returns Highest version bump type or null if no bump needed
94
+ */
95
+ function getHighestBumpType(commits, typeMap = DEFAULT_COMMIT_TYPE_MAP) {
96
+ const bumpOrder = [
97
+ "major",
98
+ "minor",
99
+ "patch"
100
+ ];
101
+ let highest = null;
102
+ for (const commit of commits) {
103
+ const bumpType = getBumpTypeFromCommit(commit, typeMap);
104
+ if (!bumpType) continue;
105
+ if (!highest) {
106
+ highest = bumpType;
107
+ continue;
108
+ }
109
+ const currentIndex = bumpOrder.indexOf(highest);
110
+ if (bumpOrder.indexOf(bumpType) < currentIndex) highest = bumpType;
111
+ }
112
+ return highest;
113
+ }
114
+ /**
115
+ * Convert a conventional commit to a changelog ChangeEntry.
116
+ *
117
+ * @param commit - Parsed conventional commit
118
+ * @returns ChangeEntry for changelog
119
+ */
120
+ function commitToChangeEntry(commit) {
121
+ if (commit.breaking) return {
122
+ type: "breaking",
123
+ description: commit.breakingDescription ?? commit.description,
124
+ path: commit.scope
125
+ };
126
+ switch (commit.type) {
127
+ case "feat": return {
128
+ type: "added",
129
+ description: commit.description,
130
+ path: commit.scope
131
+ };
132
+ case "fix": return {
133
+ type: "fixed",
134
+ description: commit.description,
135
+ path: commit.scope
136
+ };
137
+ case "deprecate": return {
138
+ type: "deprecated",
139
+ description: commit.description,
140
+ path: commit.scope
141
+ };
142
+ case "remove": return {
143
+ type: "removed",
144
+ description: commit.description,
145
+ path: commit.scope
146
+ };
147
+ case "security": return {
148
+ type: "security",
149
+ description: commit.description,
150
+ path: commit.scope
151
+ };
152
+ default: return {
153
+ type: "changed",
154
+ description: commit.description,
155
+ path: commit.scope
156
+ };
157
+ }
158
+ }
159
+ /**
160
+ * Convert multiple commits to an array of ChangeEntries.
161
+ */
162
+ function commitsToChangeEntries(commits) {
163
+ return commits.map(commitToChangeEntry);
164
+ }
165
+ /**
166
+ * Filter commits by scope (for spec-level changes).
167
+ *
168
+ * @param commits - Array of parsed conventional commits
169
+ * @param scope - Scope to filter by (e.g., "auth", "api")
170
+ * @returns Commits matching the scope
171
+ */
172
+ function filterCommitsByScope(commits, scope) {
173
+ return commits.filter((c) => c.scope?.toLowerCase() === scope.toLowerCase());
174
+ }
175
+ /**
176
+ * Filter commits that trigger version bumps.
177
+ */
178
+ function filterBumpableCommits(commits, typeMap = DEFAULT_COMMIT_TYPE_MAP) {
179
+ return commits.filter((c) => getBumpTypeFromCommit(c, typeMap) !== null);
180
+ }
181
+
182
+ //#endregion
183
+ export { DEFAULT_COMMIT_TYPE_MAP, commitToChangeEntry, commitsToChangeEntries, filterBumpableCommits, filterCommitsByScope, getBumpTypeFromCommit, getHighestBumpType, isConventionalCommit, parseConventionalCommit };
184
+ //# sourceMappingURL=conventional-commits.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"conventional-commits.js","names":["DEFAULT_COMMIT_TYPE_MAP: CommitTypeBumpMap","bumpOrder: VersionBumpType[]","highest: VersionBumpType | null"],"sources":["../../../src/services/versioning/conventional-commits.ts"],"sourcesContent":["/**\n * Conventional commits parser and utilities.\n *\n * Parses conventional commit messages to determine version bump types\n * and extract change information for changelog generation.\n *\n * Supports:\n * - Standard conventional commits (feat, fix, chore, etc.)\n * - Breaking change detection (BREAKING CHANGE: or !)\n * - Scope extraction for spec-level changes\n *\n * @module versioning/conventional-commits\n */\n\nimport type { VersionBumpType, ChangeEntry } from '@contractspec/lib.contracts';\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Types\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Parsed conventional commit message.\n */\nexport interface ConventionalCommit {\n /** Commit type (feat, fix, chore, etc.) */\n type: string;\n /** Optional scope (e.g., auth, api) */\n scope?: string;\n /** Whether this is a breaking change */\n breaking: boolean;\n /** Commit description */\n description: string;\n /** Commit body (optional) */\n body?: string;\n /** Breaking change description (if any) */\n breakingDescription?: string;\n /** Full original message */\n raw: string;\n}\n\n/**\n * Commit type to bump type mapping.\n */\nexport type CommitTypeBumpMap = Record<string, VersionBumpType | null>;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Constants\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Default mapping of commit types to version bump types.\n *\n * - `feat` → minor (new feature)\n * - `fix` → patch (bug fix)\n * - `perf` → patch (performance improvement)\n * - `refactor` → patch (code refactoring)\n * - `docs` → null (no version bump)\n * - `style` → null (no version bump)\n * - `test` → null (no version bump)\n * - `chore` → null (no version bump)\n * - `ci` → null (no version bump)\n * - `build` → null (no version bump)\n */\nexport const DEFAULT_COMMIT_TYPE_MAP: CommitTypeBumpMap = {\n feat: 'minor',\n fix: 'patch',\n perf: 'patch',\n refactor: 'patch',\n docs: null,\n style: null,\n test: null,\n chore: null,\n ci: null,\n build: null,\n revert: 'patch',\n};\n\n/**\n * Regex pattern for parsing conventional commit messages.\n *\n * Matches: type(scope)!: description\n * Groups:\n * 1. type\n * 2. scope (optional)\n * 3. breaking indicator (optional !)\n * 4. description\n */\nconst CONVENTIONAL_COMMIT_PATTERN = /^(\\w+)(?:\\(([^)]+)\\))?(!)?\\s*:\\s*(.+)$/;\n\n/**\n * Pattern for detecting BREAKING CHANGE in commit body/footer.\n */\nconst BREAKING_CHANGE_PATTERN = /^BREAKING[ -]CHANGE:\\s*(.+)$/im;\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Parser\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Parse a conventional commit message.\n *\n * @param message - Full commit message (may include body)\n * @returns Parsed commit or null if not a valid conventional commit\n */\nexport function parseConventionalCommit(\n message: string\n): ConventionalCommit | null {\n const lines = message.split('\\n');\n const firstLine = lines[0]?.trim();\n\n if (!firstLine) {\n return null;\n }\n\n const match = firstLine.match(CONVENTIONAL_COMMIT_PATTERN);\n if (!match) {\n return null;\n }\n\n const [, type, scope, breakingIndicator, description] = match;\n\n if (!type || !description) {\n return null;\n }\n\n // Extract body (everything after first line)\n const body = lines.slice(1).join('\\n').trim() || undefined;\n\n // Check for breaking change in body\n const breakingMatch = body?.match(BREAKING_CHANGE_PATTERN);\n const breakingDescription = breakingMatch?.[1];\n\n return {\n type: type.toLowerCase(),\n scope: scope?.toLowerCase(),\n breaking: !!breakingIndicator || !!breakingMatch,\n description: description.trim(),\n body,\n breakingDescription,\n raw: message,\n };\n}\n\n/**\n * Check if a commit message follows conventional commit format.\n */\nexport function isConventionalCommit(message: string): boolean {\n return parseConventionalCommit(message) !== null;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Bump Type Determination\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Determine the version bump type from a conventional commit.\n *\n * @param commit - Parsed conventional commit\n * @param typeMap - Optional custom type-to-bump mapping\n * @returns Version bump type or null if no bump needed\n */\nexport function getBumpTypeFromCommit(\n commit: ConventionalCommit,\n typeMap: CommitTypeBumpMap = DEFAULT_COMMIT_TYPE_MAP\n): VersionBumpType | null {\n // Breaking changes always trigger major bump\n if (commit.breaking) {\n return 'major';\n }\n\n // Use type mapping\n return typeMap[commit.type] ?? null;\n}\n\n/**\n * Determine the highest bump type from multiple commits.\n *\n * @param commits - Array of parsed conventional commits\n * @param typeMap - Optional custom type-to-bump mapping\n * @returns Highest version bump type or null if no bump needed\n */\nexport function getHighestBumpType(\n commits: ConventionalCommit[],\n typeMap: CommitTypeBumpMap = DEFAULT_COMMIT_TYPE_MAP\n): VersionBumpType | null {\n const bumpOrder: VersionBumpType[] = ['major', 'minor', 'patch'];\n\n let highest: VersionBumpType | null = null;\n\n for (const commit of commits) {\n const bumpType = getBumpTypeFromCommit(commit, typeMap);\n\n if (!bumpType) continue;\n\n if (!highest) {\n highest = bumpType;\n continue;\n }\n\n // Check if this bump is higher precedence\n const currentIndex = bumpOrder.indexOf(highest);\n const newIndex = bumpOrder.indexOf(bumpType);\n\n if (newIndex < currentIndex) {\n highest = bumpType;\n }\n }\n\n return highest;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Change Entry Conversion\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Convert a conventional commit to a changelog ChangeEntry.\n *\n * @param commit - Parsed conventional commit\n * @returns ChangeEntry for changelog\n */\nexport function commitToChangeEntry(commit: ConventionalCommit): ChangeEntry {\n if (commit.breaking) {\n return {\n type: 'breaking',\n description: commit.breakingDescription ?? commit.description,\n path: commit.scope,\n };\n }\n\n switch (commit.type) {\n case 'feat':\n return {\n type: 'added',\n description: commit.description,\n path: commit.scope,\n };\n case 'fix':\n return {\n type: 'fixed',\n description: commit.description,\n path: commit.scope,\n };\n case 'deprecate':\n return {\n type: 'deprecated',\n description: commit.description,\n path: commit.scope,\n };\n case 'remove':\n return {\n type: 'removed',\n description: commit.description,\n path: commit.scope,\n };\n case 'security':\n return {\n type: 'security',\n description: commit.description,\n path: commit.scope,\n };\n default:\n return {\n type: 'changed',\n description: commit.description,\n path: commit.scope,\n };\n }\n}\n\n/**\n * Convert multiple commits to an array of ChangeEntries.\n */\nexport function commitsToChangeEntries(\n commits: ConventionalCommit[]\n): ChangeEntry[] {\n return commits.map(commitToChangeEntry);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────\n// Filtering\n// ─────────────────────────────────────────────────────────────────────────────\n\n/**\n * Filter commits by scope (for spec-level changes).\n *\n * @param commits - Array of parsed conventional commits\n * @param scope - Scope to filter by (e.g., \"auth\", \"api\")\n * @returns Commits matching the scope\n */\nexport function filterCommitsByScope(\n commits: ConventionalCommit[],\n scope: string\n): ConventionalCommit[] {\n return commits.filter((c) => c.scope?.toLowerCase() === scope.toLowerCase());\n}\n\n/**\n * Filter commits that trigger version bumps.\n */\nexport function filterBumpableCommits(\n commits: ConventionalCommit[],\n typeMap: CommitTypeBumpMap = DEFAULT_COMMIT_TYPE_MAP\n): ConventionalCommit[] {\n return commits.filter((c) => getBumpTypeFromCommit(c, typeMap) !== null);\n}\n"],"mappings":";;;;;;;;;;;;;;;AA+DA,MAAaA,0BAA6C;CACxD,MAAM;CACN,KAAK;CACL,MAAM;CACN,UAAU;CACV,MAAM;CACN,OAAO;CACP,MAAM;CACN,OAAO;CACP,IAAI;CACJ,OAAO;CACP,QAAQ;CACT;;;;;;;;;;;AAYD,MAAM,8BAA8B;;;;AAKpC,MAAM,0BAA0B;;;;;;;AAYhC,SAAgB,wBACd,SAC2B;CAC3B,MAAM,QAAQ,QAAQ,MAAM,KAAK;CACjC,MAAM,YAAY,MAAM,IAAI,MAAM;AAElC,KAAI,CAAC,UACH,QAAO;CAGT,MAAM,QAAQ,UAAU,MAAM,4BAA4B;AAC1D,KAAI,CAAC,MACH,QAAO;CAGT,MAAM,GAAG,MAAM,OAAO,mBAAmB,eAAe;AAExD,KAAI,CAAC,QAAQ,CAAC,YACZ,QAAO;CAIT,MAAM,OAAO,MAAM,MAAM,EAAE,CAAC,KAAK,KAAK,CAAC,MAAM,IAAI;CAGjD,MAAM,gBAAgB,MAAM,MAAM,wBAAwB;CAC1D,MAAM,sBAAsB,gBAAgB;AAE5C,QAAO;EACL,MAAM,KAAK,aAAa;EACxB,OAAO,OAAO,aAAa;EAC3B,UAAU,CAAC,CAAC,qBAAqB,CAAC,CAAC;EACnC,aAAa,YAAY,MAAM;EAC/B;EACA;EACA,KAAK;EACN;;;;;AAMH,SAAgB,qBAAqB,SAA0B;AAC7D,QAAO,wBAAwB,QAAQ,KAAK;;;;;;;;;AAc9C,SAAgB,sBACd,QACA,UAA6B,yBACL;AAExB,KAAI,OAAO,SACT,QAAO;AAIT,QAAO,QAAQ,OAAO,SAAS;;;;;;;;;AAUjC,SAAgB,mBACd,SACA,UAA6B,yBACL;CACxB,MAAMC,YAA+B;EAAC;EAAS;EAAS;EAAQ;CAEhE,IAAIC,UAAkC;AAEtC,MAAK,MAAM,UAAU,SAAS;EAC5B,MAAM,WAAW,sBAAsB,QAAQ,QAAQ;AAEvD,MAAI,CAAC,SAAU;AAEf,MAAI,CAAC,SAAS;AACZ,aAAU;AACV;;EAIF,MAAM,eAAe,UAAU,QAAQ,QAAQ;AAG/C,MAFiB,UAAU,QAAQ,SAAS,GAE7B,aACb,WAAU;;AAId,QAAO;;;;;;;;AAaT,SAAgB,oBAAoB,QAAyC;AAC3E,KAAI,OAAO,SACT,QAAO;EACL,MAAM;EACN,aAAa,OAAO,uBAAuB,OAAO;EAClD,MAAM,OAAO;EACd;AAGH,SAAQ,OAAO,MAAf;EACE,KAAK,OACH,QAAO;GACL,MAAM;GACN,aAAa,OAAO;GACpB,MAAM,OAAO;GACd;EACH,KAAK,MACH,QAAO;GACL,MAAM;GACN,aAAa,OAAO;GACpB,MAAM,OAAO;GACd;EACH,KAAK,YACH,QAAO;GACL,MAAM;GACN,aAAa,OAAO;GACpB,MAAM,OAAO;GACd;EACH,KAAK,SACH,QAAO;GACL,MAAM;GACN,aAAa,OAAO;GACpB,MAAM,OAAO;GACd;EACH,KAAK,WACH,QAAO;GACL,MAAM;GACN,aAAa,OAAO;GACpB,MAAM,OAAO;GACd;EACH,QACE,QAAO;GACL,MAAM;GACN,aAAa,OAAO;GACpB,MAAM,OAAO;GACd;;;;;;AAOP,SAAgB,uBACd,SACe;AACf,QAAO,QAAQ,IAAI,oBAAoB;;;;;;;;;AAczC,SAAgB,qBACd,SACA,OACsB;AACtB,QAAO,QAAQ,QAAQ,MAAM,EAAE,OAAO,aAAa,KAAK,MAAM,aAAa,CAAC;;;;;AAM9E,SAAgB,sBACd,SACA,UAA6B,yBACP;AACtB,QAAO,QAAQ,QAAQ,MAAM,sBAAsB,GAAG,QAAQ,KAAK,KAAK"}
@@ -1,10 +1,11 @@
1
- import { ChangeEntry, ChangelogDocBlock, ChangelogEntry, ChangelogGenerateOptions, ChangelogGenerateResult, ChangelogJsonExport, ChangelogTier, LibraryChangelogJson, SpecChangelogJson, SpecVersionAnalysis, VersionAnalyzeOptions, VersionAnalyzeResult, VersionBumpOptions, VersionBumpResult, VersionBumpType } from "./types.js";
2
- import { analyzeVersions, applyVersionBump, generateChangelogs } from "./versioning-service.js";
1
+ import { ChangeEntry, ChangelogDocBlock, ChangelogEntry, ChangelogGenerateOptions, ChangelogGenerateResult, ChangelogJsonExport, ChangelogTier, LibraryChangelogJson, SpecChangelogJson, SpecVersionAnalysis, VersionAnalyzeOptions, VersionAnalyzeResult, VersionBumpOptions, VersionBumpResult, VersionBumpType, VersioningConfig } from "./types.js";
2
+ import { analyzeVersions, analyzeVersionsFromCommits, applyVersionBump, generateChangelogs } from "./versioning-service.js";
3
3
  import { formatChangelogJson, formatConventionalChangelog, formatKeepAChangelog } from "./changelog-formatter.js";
4
+ import { CommitTypeBumpMap, ConventionalCommit, DEFAULT_COMMIT_TYPE_MAP, commitToChangeEntry, commitsToChangeEntries, filterBumpableCommits, filterCommitsByScope, getBumpTypeFromCommit, getHighestBumpType, isConventionalCommit, parseConventionalCommit } from "./conventional-commits.js";
4
5
 
5
6
  //#region src/services/versioning/index.d.ts
6
7
  declare namespace index_d_exports {
7
- export { ChangeEntry, ChangelogDocBlock, ChangelogEntry, ChangelogGenerateOptions, ChangelogGenerateResult, ChangelogJsonExport, ChangelogTier, LibraryChangelogJson, SpecChangelogJson, SpecVersionAnalysis, VersionAnalyzeOptions, VersionAnalyzeResult, VersionBumpOptions, VersionBumpResult, VersionBumpType, analyzeVersions, applyVersionBump, formatChangelogJson, formatConventionalChangelog, formatKeepAChangelog, generateChangelogs };
8
+ export { ChangeEntry, ChangelogDocBlock, ChangelogEntry, ChangelogGenerateOptions, ChangelogGenerateResult, ChangelogJsonExport, ChangelogTier, CommitTypeBumpMap, ConventionalCommit, DEFAULT_COMMIT_TYPE_MAP, LibraryChangelogJson, SpecChangelogJson, SpecVersionAnalysis, VersionAnalyzeOptions, VersionAnalyzeResult, VersionBumpOptions, VersionBumpResult, VersionBumpType, VersioningConfig, analyzeVersions, analyzeVersionsFromCommits, applyVersionBump, commitToChangeEntry, commitsToChangeEntries, filterBumpableCommits, filterCommitsByScope, formatChangelogJson, formatConventionalChangelog, formatKeepAChangelog, generateChangelogs, getBumpTypeFromCommit, getHighestBumpType, isConventionalCommit, parseConventionalCommit };
8
9
  }
9
10
  //#endregion
10
11
  export { index_d_exports };
@@ -1,15 +1,26 @@
1
1
  import { __exportAll } from "../../_virtual/rolldown_runtime.js";
2
2
  import { formatChangelogJson, formatConventionalChangelog, formatKeepAChangelog } from "./changelog-formatter.js";
3
- import { analyzeVersions, applyVersionBump, generateChangelogs } from "./versioning-service.js";
3
+ import { DEFAULT_COMMIT_TYPE_MAP, commitToChangeEntry, commitsToChangeEntries, filterBumpableCommits, filterCommitsByScope, getBumpTypeFromCommit, getHighestBumpType, isConventionalCommit, parseConventionalCommit } from "./conventional-commits.js";
4
+ import { analyzeVersions, analyzeVersionsFromCommits, applyVersionBump, generateChangelogs } from "./versioning-service.js";
4
5
 
5
6
  //#region src/services/versioning/index.ts
6
7
  var versioning_exports = /* @__PURE__ */ __exportAll({
8
+ DEFAULT_COMMIT_TYPE_MAP: () => DEFAULT_COMMIT_TYPE_MAP,
7
9
  analyzeVersions: () => analyzeVersions,
10
+ analyzeVersionsFromCommits: () => analyzeVersionsFromCommits,
8
11
  applyVersionBump: () => applyVersionBump,
12
+ commitToChangeEntry: () => commitToChangeEntry,
13
+ commitsToChangeEntries: () => commitsToChangeEntries,
14
+ filterBumpableCommits: () => filterBumpableCommits,
15
+ filterCommitsByScope: () => filterCommitsByScope,
9
16
  formatChangelogJson: () => formatChangelogJson,
10
17
  formatConventionalChangelog: () => formatConventionalChangelog,
11
18
  formatKeepAChangelog: () => formatKeepAChangelog,
12
- generateChangelogs: () => generateChangelogs
19
+ generateChangelogs: () => generateChangelogs,
20
+ getBumpTypeFromCommit: () => getBumpTypeFromCommit,
21
+ getHighestBumpType: () => getHighestBumpType,
22
+ isConventionalCommit: () => isConventionalCommit,
23
+ parseConventionalCommit: () => parseConventionalCommit
13
24
  });
14
25
 
15
26
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../../../src/services/versioning/index.ts"],"sourcesContent":["/**\n * Versioning service module exports.\n *\n * Provides version analysis, version bumping, and changelog generation.\n */\n\nexport * from './types';\nexport {\n analyzeVersions,\n applyVersionBump,\n generateChangelogs,\n} from './versioning-service';\nexport {\n formatKeepAChangelog,\n formatConventionalChangelog,\n formatChangelogJson,\n} from './changelog-formatter';\n"],"mappings":""}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../src/services/versioning/index.ts"],"sourcesContent":["/**\n * Versioning service module exports.\n *\n * Provides version analysis, version bumping, and changelog generation.\n */\n\nexport * from './types';\nexport {\n analyzeVersions,\n applyVersionBump,\n generateChangelogs,\n analyzeVersionsFromCommits,\n} from './versioning-service';\nexport {\n formatKeepAChangelog,\n formatConventionalChangelog,\n formatChangelogJson,\n} from './changelog-formatter';\nexport * from './conventional-commits';\n"],"mappings":""}
@@ -1,4 +1,4 @@
1
- import { ChangeEntry, ChangelogDocBlock, ChangelogEntry as ChangelogEntry$1, ChangelogTier, VersionBumpType } from "@contractspec/lib.contracts";
1
+ import { ChangeEntry as ChangeEntry$1, ChangelogDocBlock, ChangelogEntry as ChangelogEntry$1, ChangelogTier, VersionBumpType as VersionBumpType$1, VersioningConfig } from "@contractspec/lib.contracts";
2
2
 
3
3
  //#region src/services/versioning/types.d.ts
4
4
 
@@ -20,13 +20,15 @@ interface VersionBumpOptions {
20
20
  /** Spec file path to bump */
21
21
  specPath: string;
22
22
  /** Bump type (auto-detected if not specified) */
23
- bumpType?: VersionBumpType;
23
+ bumpType?: VersionBumpType$1;
24
24
  /** Change description for changelog entry */
25
25
  changeDescription?: string;
26
26
  /** Additional change entries */
27
- changes?: ChangeEntry[];
27
+ changes?: ChangeEntry$1[];
28
28
  /** Dry run (don't write changes) */
29
29
  dryRun?: boolean;
30
+ /** Versioning config (for changesets integration) */
31
+ config?: VersioningConfig;
30
32
  }
31
33
  /** Options for changelog generation */
32
34
  interface ChangelogGenerateOptions {
@@ -52,9 +54,9 @@ interface SpecVersionAnalysis {
52
54
  /** Suggested new version based on changes */
53
55
  suggestedVersion: string;
54
56
  /** Suggested bump type */
55
- bumpType: VersionBumpType;
57
+ bumpType: VersionBumpType$1;
56
58
  /** Detected changes requiring version bump */
57
- changes: ChangeEntry[];
59
+ changes: ChangeEntry$1[];
58
60
  /** Whether breaking changes were detected */
59
61
  hasBreaking: boolean;
60
62
  /** Whether the spec needs a version bump */
@@ -88,7 +90,7 @@ interface VersionBumpResult {
88
90
  /** New version */
89
91
  newVersion: string;
90
92
  /** Bump type applied */
91
- bumpType: VersionBumpType;
93
+ bumpType: VersionBumpType$1;
92
94
  /** Changelog entry created */
93
95
  changelogEntry: ChangelogEntry$1;
94
96
  /** Error message if failed */
@@ -129,5 +131,5 @@ interface LibraryChangelogJson {
129
131
  entries: ChangelogEntry$1[];
130
132
  }
131
133
  //#endregion
132
- export { type ChangeEntry, type ChangelogDocBlock, type ChangelogEntry$1 as ChangelogEntry, ChangelogGenerateOptions, ChangelogGenerateResult, ChangelogJsonExport, type ChangelogTier, LibraryChangelogJson, SpecChangelogJson, SpecVersionAnalysis, VersionAnalyzeOptions, VersionAnalyzeResult, VersionBumpOptions, VersionBumpResult, type VersionBumpType };
134
+ export { type ChangeEntry$1 as ChangeEntry, type ChangelogDocBlock, type ChangelogEntry$1 as ChangelogEntry, ChangelogGenerateOptions, ChangelogGenerateResult, ChangelogJsonExport, type ChangelogTier, LibraryChangelogJson, SpecChangelogJson, SpecVersionAnalysis, VersionAnalyzeOptions, VersionAnalyzeResult, VersionBumpOptions, VersionBumpResult, type VersionBumpType$1 as VersionBumpType, type VersioningConfig };
133
135
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/services/versioning/types.ts"],"sourcesContent":[],"mappings":";;;;AA8GA;AAoBiB,UAtGA,qBAAA,CAsGuB;EAEtB;EAEC,QAAA,CAAA,EAAA,MAAA;EAIX;EAAmB,OAAA,CAAA,EAAA,MAAA;EAMV;EAQA,aAAA,CAAA,EAAA,MAAiB;EAQjB;;;;;;UAtHA,kBAAA;;;;aAIJ;;;;YAID;;;;;UAMK,wBAAA;;;;;;UAMP;;;;;;;UAYO,mBAAA;;;;;;;;;;YAUL;;WAED;;;;;;;UAQM,oBAAA;;YAEL;;;;;;;;;;;;;UAcK,iBAAA;;;;;;;;;;;;YAYL;;kBAEM;;;;;UAMD,uBAAA;;kBAEC;;mBAEC;;;;QAIX;;;;;UAMS,mBAAA;;;SAGR;aACI;;;UAII,iBAAA;;;;WAIN;;;UAIM,oBAAA;;;;WAIN"}
1
+ {"version":3,"file":"types.d.ts","names":[],"sources":["../../../src/services/versioning/types.ts"],"sourcesContent":[],"mappings":";;;;;AA4DiB,UA9BA,qBAAA,CA8BwB;EAkBxB;EAoBA,QAAA,CAAA,EAAA,MAAA;EAgBA;EAoBA,OAAA,CAAA,EAAA,MAAA;EAEC;EAEC,aAAA,CAAA,EAAA,MAAA;EAIX;EAAmB,OAAA,CAAA,EAAA,MAAA,EAAA;EAMV;EAQA,OAAA,CAAA,EAAA,MAAA,EAAA;AAQjB;;UAxHiB,kBAAA;;;;aAIJ;;;;YAID;;;;WAID;;;UAIM,wBAAA;;;;;;UAMP;;;;;;;UAYO,mBAAA;;;;;;;;;;YAUL;;WAED;;;;;;;UAQM,oBAAA;;YAEL;;;;;;;;;;;;;UAcK,iBAAA;;;;;;;;;;;;YAYL;;kBAEM;;;;;UAMD,uBAAA;;kBAEC;;mBAEC;;;;QAIX;;;;;UAMS,mBAAA;;;SAGR;aACI;;;UAII,iBAAA;;;;WAIN;;;UAIM,oBAAA;;;;WAIN"}
@@ -2,6 +2,7 @@ import { FsAdapter } from "../../ports/fs.js";
2
2
  import { GitAdapter } from "../../ports/git.js";
3
3
  import { LoggerAdapter } from "../../ports/logger.js";
4
4
  import { ChangelogGenerateOptions, ChangelogGenerateResult, VersionAnalyzeOptions, VersionAnalyzeResult, VersionBumpOptions, VersionBumpResult } from "./types.js";
5
+ import { ChangeEntry, VersionBumpType } from "@contractspec/lib.contracts";
5
6
 
6
7
  //#region src/services/versioning/versioning-service.d.ts
7
8
 
@@ -17,6 +18,47 @@ interface ServiceAdapters {
17
18
  * which specs need version bumps based on detected changes.
18
19
  */
19
20
  declare function analyzeVersions(adapters: ServiceAdapters, options?: VersionAnalyzeOptions): Promise<VersionAnalyzeResult>;
21
+ /**
22
+ * Options for commit-based version analysis.
23
+ */
24
+ interface CommitAnalyzeOptions {
25
+ /** Git ref to compare against (branch, tag, commit) */
26
+ baseline?: string;
27
+ /** Workspace root directory */
28
+ workspaceRoot?: string;
29
+ /** Include commits matching these paths (glob patterns) */
30
+ include?: string[];
31
+ /** Exclude commits matching these paths (glob patterns) */
32
+ exclude?: string[];
33
+ }
34
+ /**
35
+ * Result of commit-based version analysis.
36
+ */
37
+ interface CommitAnalyzeResult {
38
+ /** Suggested bump type based on commits */
39
+ suggestedBumpType: VersionBumpType | null;
40
+ /** Parsed conventional commits */
41
+ commits: {
42
+ hash: string;
43
+ message: string;
44
+ type: string;
45
+ scope?: string;
46
+ breaking: boolean;
47
+ }[];
48
+ /** Change entries for changelog */
49
+ changes: ChangeEntry[];
50
+ /** Total commits analyzed */
51
+ totalCommits: number;
52
+ /** Breaking commits count */
53
+ breakingCommits: number;
54
+ }
55
+ /**
56
+ * Analyze version bump based on git commits.
57
+ *
58
+ * Parses conventional commits since the baseline and determines
59
+ * the appropriate version bump type.
60
+ */
61
+ declare function analyzeVersionsFromCommits(adapters: ServiceAdapters, options?: CommitAnalyzeOptions): Promise<CommitAnalyzeResult>;
20
62
  /**
21
63
  * Apply a version bump to a spec file.
22
64
  *
@@ -28,5 +70,5 @@ declare function applyVersionBump(adapters: ServiceAdapters, options: VersionBum
28
70
  */
29
71
  declare function generateChangelogs(adapters: ServiceAdapters, options?: ChangelogGenerateOptions): Promise<ChangelogGenerateResult>;
30
72
  //#endregion
31
- export { analyzeVersions, applyVersionBump, generateChangelogs };
73
+ export { analyzeVersions, analyzeVersionsFromCommits, applyVersionBump, generateChangelogs };
32
74
  //# sourceMappingURL=versioning-service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"versioning-service.d.ts","names":[],"sources":["../../../src/services/versioning/versioning-service.ts"],"sourcesContent":[],"mappings":";;;;;;;UAmCU,eAAA,CAGa;EAaD,EAAA,EAfhB,SAegB;EACV,GAAA,EAfL,UAeK;EACD,MAAA,EAfD,aAeC;;;;AAwGX;;;;AAGG,iBA7GmB,eAAA,CA6GnB,QAAA,EA5GS,eA4GT,EAAA,OAAA,CAAA,EA3GQ,qBA2GR,CAAA,EA1GA,OA0GA,CA1GQ,oBA0GR,CAAA;;AAiGH;;;;AAGG,iBAvGmB,gBAAA,CAuGnB,QAAA,EAtGS,eAsGT,EAAA,OAAA,EArGQ,kBAqGR,CAAA,EApGA,OAoGA,CApGQ,iBAoGR,CAAA;;;;iBAHmB,kBAAA,WACV,2BACD,2BACR,QAAQ"}
1
+ {"version":3,"file":"versioning-service.d.ts","names":[],"sources":["../../../src/services/versioning/versioning-service.ts"],"sourcesContent":[],"mappings":";;;;;;;;UA0CU,eAAA,CAGa;EAaD,EAAA,EAfhB,SAegB;EACV,GAAA,EAfL,UAeK;EACD,MAAA,EAfD,aAeC;;;;AAsGX;AAcA;AAyBA;;AAEW,iBAjJW,eAAA,CAiJX,QAAA,EAhJC,eAgJD,EAAA,OAAA,CAAA,EA/IA,qBA+IA,CAAA,EA9IR,OA8IQ,CA9IA,oBA8IA,CAAA;;;;AAsEW,UA/GL,oBAAA,CA+GqB;EAC1B;EACD,QAAA,CAAA,EAAA,MAAA;EACA;EAAR,aAAA,CAAA,EAAA,MAAA;EAAO;EA6GY,OAAA,CAAA,EAAA,MAAA,EAAA;EACV;EACD,OAAA,CAAA,EAAA,MAAA,EAAA;;;;;UAnNM,mBAAA;;qBAEI;;;;;;;;;;WAUV;;;;;;;;;;;;iBAaW,0BAAA,WACV,2BACD,uBACR,QAAQ;;;;;;iBAqEW,gBAAA,WACV,0BACD,qBACR,QAAQ;;;;iBA6GW,kBAAA,WACV,2BACD,2BACR,QAAQ"}
@@ -1,4 +1,6 @@
1
+ import { findPackageRoot, getPackageName } from "../../adapters/workspace.js";
1
2
  import { formatChangelogJson, formatKeepAChangelog } from "./changelog-formatter.js";
3
+ import { commitsToChangeEntries, getHighestBumpType, parseConventionalCommit } from "./conventional-commits.js";
2
4
  import { bumpVersion, determineBumpType } from "@contractspec/lib.contracts";
3
5
 
4
6
  //#region src/services/versioning/versioning-service.ts
@@ -75,13 +77,66 @@ async function analyzeVersions(adapters, options = {}) {
75
77
  };
76
78
  }
77
79
  /**
80
+ * Analyze version bump based on git commits.
81
+ *
82
+ * Parses conventional commits since the baseline and determines
83
+ * the appropriate version bump type.
84
+ */
85
+ async function analyzeVersionsFromCommits(adapters, options = {}) {
86
+ const { git, logger } = adapters;
87
+ const baseline = options.baseline ?? "HEAD~10";
88
+ logger.info("Analyzing commits for version bump...", { baseline });
89
+ try {
90
+ const commitLog = await git.log(baseline);
91
+ const parsedCommits = [];
92
+ const conventionalCommits = [];
93
+ for (const commit of commitLog) {
94
+ const parsed = parseConventionalCommit(commit.message);
95
+ if (parsed) {
96
+ parsedCommits.push({
97
+ hash: commit.hash,
98
+ message: commit.message,
99
+ type: parsed.type,
100
+ scope: parsed.scope,
101
+ breaking: parsed.breaking
102
+ });
103
+ conventionalCommits.push(parsed);
104
+ }
105
+ }
106
+ const suggestedBumpType = getHighestBumpType(conventionalCommits);
107
+ const changes = commitsToChangeEntries(conventionalCommits);
108
+ const breakingCommits = parsedCommits.filter((c) => c.breaking).length;
109
+ logger.info("Commit analysis complete", {
110
+ totalCommits: parsedCommits.length,
111
+ breakingCommits,
112
+ suggestedBumpType
113
+ });
114
+ return {
115
+ suggestedBumpType,
116
+ commits: parsedCommits,
117
+ changes,
118
+ totalCommits: parsedCommits.length,
119
+ breakingCommits
120
+ };
121
+ } catch (error) {
122
+ logger.warn("Failed to analyze commits", { error: error instanceof Error ? error.message : String(error) });
123
+ return {
124
+ suggestedBumpType: null,
125
+ commits: [],
126
+ changes: [],
127
+ totalCommits: 0,
128
+ breakingCommits: 0
129
+ };
130
+ }
131
+ }
132
+ /**
78
133
  * Apply a version bump to a spec file.
79
134
  *
80
135
  * Updates the version in the spec file and creates a changelog entry.
81
136
  */
82
137
  async function applyVersionBump(adapters, options) {
83
138
  const { fs, logger } = adapters;
84
- const { specPath, dryRun = false } = options;
139
+ const { specPath, dryRun = false, config } = options;
85
140
  logger.info("Applying version bump...", {
86
141
  specPath,
87
142
  bumpType: options.bumpType
@@ -122,6 +177,12 @@ async function applyVersionBump(adapters, options) {
122
177
  previousVersion: meta.version,
123
178
  newVersion
124
179
  });
180
+ if (config?.integrateWithChangesets) await generateChangeset(adapters, {
181
+ specPath,
182
+ bumpType,
183
+ summary: options.changeDescription ?? `Bump ${meta.key} to ${newVersion}`,
184
+ dryRun
185
+ });
125
186
  return {
126
187
  success: true,
127
188
  specPath,
@@ -353,7 +414,88 @@ function specToChangelogEntry(spec) {
353
414
  breakingChanges: spec.changes.filter((c) => c.type === "breaking")
354
415
  };
355
416
  }
417
+ /**
418
+ * Generate a changeset file for a spec update.
419
+ */
420
+ async function generateChangeset(adapters, options) {
421
+ const { fs, logger } = adapters;
422
+ const { specPath, bumpType, summary, dryRun } = options;
423
+ try {
424
+ const pkgRoot = findPackageRoot(specPath);
425
+ const pkgName = getPackageName(pkgRoot);
426
+ if (!pkgName) {
427
+ logger.warn("Could not determine package name for changeset", { specPath });
428
+ return;
429
+ }
430
+ let currentDir = pkgRoot;
431
+ let changesetDir = null;
432
+ while (true) {
433
+ const candidate = fs.join(currentDir, ".changeset");
434
+ if (await fs.exists(candidate)) {
435
+ changesetDir = candidate;
436
+ break;
437
+ }
438
+ const parent = fs.dirname(currentDir);
439
+ if (parent === currentDir) break;
440
+ currentDir = parent;
441
+ }
442
+ if (!changesetDir) {
443
+ logger.warn("No .changeset directory found, skipping changeset generation");
444
+ return;
445
+ }
446
+ const fileName = `${generateRandomName()}.md`;
447
+ const filePath = fs.join(changesetDir, fileName);
448
+ const content = `---
449
+ "${pkgName}": ${bumpType}
450
+ ---
451
+
452
+ ${summary}
453
+ `;
454
+ if (!dryRun) {
455
+ await fs.writeFile(filePath, content);
456
+ logger.info("Generated changeset", { filePath });
457
+ } else logger.info("Would generate changeset", {
458
+ filePath,
459
+ content
460
+ });
461
+ } catch (error) {
462
+ logger.error("Failed to generate changeset", { error: error instanceof Error ? error.message : String(error) });
463
+ }
464
+ }
465
+ /**
466
+ * Generate a random human-readable-ish name (simplified).
467
+ */
468
+ function generateRandomName() {
469
+ const adjectives = [
470
+ "neat",
471
+ "calm",
472
+ "wild",
473
+ "soft",
474
+ "bold",
475
+ "fair",
476
+ "cool"
477
+ ];
478
+ const nouns = [
479
+ "fox",
480
+ "cat",
481
+ "dog",
482
+ "bat",
483
+ "ant",
484
+ "elk",
485
+ "owl"
486
+ ];
487
+ const verbs = [
488
+ "run",
489
+ "fly",
490
+ "hop",
491
+ "eat",
492
+ "nap",
493
+ "cry",
494
+ "sing"
495
+ ];
496
+ return `${adjectives[Math.floor(Math.random() * adjectives.length)]}-${nouns[Math.floor(Math.random() * nouns.length)]}-${verbs[Math.floor(Math.random() * verbs.length)]}-${Math.floor(Math.random() * 1e3)}`;
497
+ }
356
498
 
357
499
  //#endregion
358
- export { analyzeVersions, applyVersionBump, generateChangelogs };
500
+ export { analyzeVersions, analyzeVersionsFromCommits, applyVersionBump, generateChangelogs };
359
501
  //# sourceMappingURL=versioning-service.js.map