@3fn/core 13.0.0 → 14.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 (284) hide show
  1. package/.kiro/agents/ada-prompt.md +80 -132
  2. package/.kiro/agents/ada-prompt.md.attribution.json +45 -0
  3. package/.kiro/agents/ada.json +44 -59
  4. package/.kiro/agents/ada.json.attribution.json +13 -0
  5. package/.kiro/agents/data-prompt.md +83 -74
  6. package/.kiro/agents/data-prompt.md.attribution.json +53 -0
  7. package/.kiro/agents/data.json +31 -38
  8. package/.kiro/agents/data.json.attribution.json +13 -0
  9. package/.kiro/agents/kenya-prompt.md +83 -72
  10. package/.kiro/agents/kenya-prompt.md.attribution.json +53 -0
  11. package/.kiro/agents/kenya.json +27 -35
  12. package/.kiro/agents/kenya.json.attribution.json +13 -0
  13. package/.kiro/agents/leonardo-prompt.md +176 -234
  14. package/.kiro/agents/leonardo-prompt.md.attribution.json +45 -0
  15. package/.kiro/agents/leonardo.json +28 -36
  16. package/.kiro/agents/leonardo.json.attribution.json +13 -0
  17. package/.kiro/agents/lina-prompt.md +110 -151
  18. package/.kiro/agents/lina-prompt.md.attribution.json +53 -0
  19. package/.kiro/agents/lina.json +46 -59
  20. package/.kiro/agents/lina.json.attribution.json +13 -0
  21. package/.kiro/agents/sparky-prompt.md +89 -72
  22. package/.kiro/agents/sparky-prompt.md.attribution.json +53 -0
  23. package/.kiro/agents/sparky.json +37 -37
  24. package/.kiro/agents/sparky.json.attribution.json +13 -0
  25. package/.kiro/agents/stacy-prompt.md +74 -48
  26. package/.kiro/agents/stacy-prompt.md.attribution.json +45 -0
  27. package/.kiro/agents/stacy.json +28 -30
  28. package/.kiro/agents/stacy.json.attribution.json +13 -0
  29. package/.kiro/agents/thurgood-prompt.md +94 -138
  30. package/.kiro/agents/thurgood-prompt.md.attribution.json +45 -0
  31. package/.kiro/agents/thurgood.json +31 -35
  32. package/.kiro/agents/thurgood.json.attribution.json +13 -0
  33. package/.kiro/steering/AI-Collaboration-Principles.md +3 -3
  34. package/.kiro/steering/Civitas-System-Overview.md +7 -16
  35. package/.kiro/steering/DesignerPunk-Systems-Overview.md +6 -6
  36. package/.kiro/steering/Spec-Feedback-Protocol.md +2 -11
  37. package/.kiro/steering/Task-Completion-Protocol.md +98 -17
  38. package/.kiro/steering/core-goals.md +3 -3
  39. package/.kiro/steering/personal-note.md +1 -1
  40. package/.kiro/steering/start-up-tasks.md +17 -6
  41. package/application-mcp-server/src/index.ts +26 -0
  42. package/dist/ComponentTokens.android.kt +12 -12
  43. package/dist/ComponentTokens.ios.swift +12 -12
  44. package/dist/ComponentTokens.web.css +3 -3
  45. package/dist/DesignTokens.android.kt +1 -1
  46. package/dist/DesignTokens.dtcg.json +8 -5
  47. package/dist/DesignTokens.figma.json +2 -2
  48. package/dist/DesignTokens.ios.swift +1 -1
  49. package/dist/DesignTokens.web.css +1 -1
  50. package/dist/android/DesignTokens.android.kt +1 -1
  51. package/dist/blend/OklchBlendCalculator.js +1 -0
  52. package/dist/blend/ThemeAwareBlendUtilities.web.d.ts +13 -2
  53. package/dist/blend/ThemeAwareBlendUtilities.web.js +6 -1
  54. package/dist/browser/designerpunk.esm.js +36 -90
  55. package/dist/browser/designerpunk.esm.min.js +33 -36
  56. package/dist/browser/designerpunk.umd.js +36 -90
  57. package/dist/browser/designerpunk.umd.min.js +47 -50
  58. package/dist/browser/tokens.css +3 -3
  59. package/dist/build/tokens/defineComponentTokens.d.ts +10 -0
  60. package/dist/build/tokens/defineComponentTokens.js +26 -0
  61. package/dist/components/core/Avatar-Base/avatar.tokens.d.ts +21 -26
  62. package/dist/components/core/Avatar-Base/avatar.tokens.js +31 -34
  63. package/dist/components/core/Avatar-Base/index.d.ts +1 -1
  64. package/dist/components/core/Avatar-Base/index.js +2 -2
  65. package/dist/components/core/Avatar-Base/platforms/web/Avatar.web.js +24 -5
  66. package/dist/components/core/Button-CTA/examples/BasicUsage.d.ts +16 -28
  67. package/dist/components/core/Button-CTA/examples/BasicUsage.js +18 -43
  68. package/dist/components/core/Button-CTA/platforms/web/ButtonCTA.web.d.ts +3 -15
  69. package/dist/components/core/Button-CTA/platforms/web/ButtonCTA.web.js +9 -58
  70. package/dist/components/core/Button-CTA/types.d.ts +0 -24
  71. package/dist/components/core/Button-CTA/types.js +6 -0
  72. package/dist/components/core/Button-Icon/buttonIcon.tokens.d.ts +28 -14
  73. package/dist/components/core/Button-Icon/buttonIcon.tokens.js +35 -20
  74. package/dist/components/core/Input-Text-Base/types.d.ts +13 -1
  75. package/dist/components/core/Input-Text-Password/platforms/web/InputTextPassword.web.js +11 -2
  76. package/dist/generators/DTCGFormatGenerator.js +8 -0
  77. package/dist/generators/TokenFileGenerator.js +7 -2
  78. package/dist/integration/BuildErrorHandler.js +2 -2
  79. package/dist/ios/DesignTokens.ios.swift +1 -1
  80. package/dist/mcp/application-mcp.js +24 -0
  81. package/dist/mcp/docs-mcp.js +130 -15
  82. package/dist/mcp/product-mcp.js +25 -0
  83. package/dist/tokens/OpacityTokens.js +1 -1
  84. package/dist/tokens/component/progress.d.ts +65 -5
  85. package/dist/tokens/component/progress.js +79 -18
  86. package/dist/tokens/semantic/BlendTokens.d.ts +10 -3
  87. package/dist/tokens/semantic/BlendTokens.js +17 -5
  88. package/dist/tokens/semantic/OpacityTokens.d.ts +4 -4
  89. package/dist/tokens/semantic/OpacityTokens.js +4 -4
  90. package/dist/types/ComponentTypes.d.ts +1 -1
  91. package/dist/types/generated/TokenTypes.d.ts +1 -1
  92. package/dist/types/generated/TokenTypes.js +1 -1
  93. package/dist/validators/StemmaTokenUsageValidator.js +3 -2
  94. package/dist/web/DesignTokens.web.css +1 -1
  95. package/governance/BUILD-SYSTEM-SETUP.md +1 -2
  96. package/governance/Component-Development-Guide.md +23 -13
  97. package/governance/Component-Development-Standards.md +21 -20
  98. package/governance/Component-Family-Avatar.md +6 -7
  99. package/governance/Component-Family-Badge.md +19 -20
  100. package/governance/Component-Family-Button.md +30 -43
  101. package/governance/Component-Family-Chip.md +14 -15
  102. package/governance/Component-Family-Container.md +12 -13
  103. package/governance/Component-Family-Data-Display.md +1 -2
  104. package/governance/Component-Family-Divider.md +1 -2
  105. package/governance/Component-Family-Form-Inputs.md +65 -65
  106. package/governance/Component-Family-Icon.md +9 -10
  107. package/governance/Component-Family-Loading.md +1 -2
  108. package/governance/Component-Family-Modal.md +1 -2
  109. package/governance/Component-Family-Navigation.md +1 -2
  110. package/governance/Component-Family-Progress.md +0 -1
  111. package/governance/Component-Inheritance-Structures.md +219 -99
  112. package/governance/Component-MCP-Document-Template.md +6 -5
  113. package/governance/Component-Primitive-vs-Semantic-Philosophy.md +1 -1
  114. package/governance/Component-Quick-Reference.md +33 -33
  115. package/governance/Component-Readiness-Status.md +59 -44
  116. package/governance/Component-Templates.md +57 -61
  117. package/governance/Contract-System-Reference.md +7 -7
  118. package/governance/MCP-Integration-Guide.md +1 -1
  119. package/governance/Process-Cross-Reference-Standards.md +31 -13
  120. package/governance/Process-Development-Workflow.md +49 -59
  121. package/governance/Process-File-Organization.md +25 -28
  122. package/governance/Process-Hook-Operations.md +22 -11
  123. package/governance/Process-Orchestration-Model-Selection.md +92 -0
  124. package/governance/Process-Spec-Planning.md +98 -52
  125. package/governance/Process-Task-Type-Definitions.md +80 -4
  126. package/governance/Product-Handoff-Protocol.md +2 -0
  127. package/governance/Rosetta-System-Architecture.md +13 -11
  128. package/governance/Test-Behavioral-Contract-Validation.md +38 -31
  129. package/governance/Test-Failure-Audit-Methodology.md +1 -1
  130. package/governance/Token-Family-Accessibility.md +1 -2
  131. package/governance/Token-Family-Blend.md +18 -16
  132. package/governance/Token-Family-Blur.md +0 -1
  133. package/governance/Token-Family-Border.md +1 -2
  134. package/governance/Token-Family-Color.md +0 -1
  135. package/governance/Token-Family-Glow.md +1 -2
  136. package/governance/Token-Family-Layering.md +0 -1
  137. package/governance/Token-Family-Motion.md +1 -2
  138. package/governance/Token-Family-Opacity.md +0 -1
  139. package/governance/Token-Family-Radius.md +1 -2
  140. package/governance/Token-Family-Responsive.md +1 -2
  141. package/governance/Token-Family-Shadow.md +1 -2
  142. package/governance/Token-Family-Sizing.md +0 -1
  143. package/governance/Token-Family-Spacing.md +1 -2
  144. package/governance/Token-Family-Typography.md +1 -2
  145. package/governance/Token-Governance.md +8 -8
  146. package/governance/Token-Quick-Reference.md +47 -34
  147. package/governance/Token-Resolution-Patterns.md +1 -1
  148. package/governance/Token-Semantic-Structure.md +1 -1
  149. package/governance/Web-Authoring-Standards.md +5 -5
  150. package/governance/browser-distribution-guide.md +1 -4
  151. package/governance/classification-map.md +474 -0
  152. package/governance/completion-documentation-guide.md +23 -37
  153. package/governance/component-meta-authoring-guide.md +1 -1
  154. package/governance/cross-platform-vs-platform-specific-decision-framework.md +1 -1
  155. package/governance/platform-implementation-guidelines.md +2 -3
  156. package/governance/release-management-system.md +28 -63
  157. package/governance/rosetta-system-principles.md +8 -6
  158. package/governance/stemma-system-principles.md +18 -17
  159. package/mcp-server/src/index.ts +24 -6
  160. package/mcp-server/src/indexer/DocumentIndexer.ts +119 -9
  161. package/mcp-server/src/indexer/__tests__/bare-id-crossrefs.test.ts +250 -0
  162. package/mcp-server/src/indexer/cross-ref-parser.ts +29 -1
  163. package/mcp-server/src/indexer/index-health.ts +27 -2
  164. package/mcp-server/src/query/__tests__/find-docs-calibration.test.ts +11 -26
  165. package/mcp-server/src/relocation-integrity-gate/__tests__/relocation-integrity-gate.test.ts +72 -5
  166. package/mcp-server/src/relocation-integrity-gate/relocation-integrity-gate.ts +81 -24
  167. package/mcp-server/src/tools/list-cross-references.ts +2 -2
  168. package/package.json +24 -26
  169. package/src/__tests__/browser-distribution/css-bundling.test.ts +6 -4
  170. package/src/__tests__/console-allowlist.json +14 -0
  171. package/src/__tests__/console-fail-setup.ts +169 -0
  172. package/src/__tests__/integration/Spec107-DesignLanguageContext.test.ts +16 -0
  173. package/src/__tests__/stemma-system/behavioral-contract-validation.test.ts +70 -17
  174. package/src/__tests__/stemma-system/contract-catalog-name-validation.test.ts +28 -0
  175. package/src/__tests__/stemma-system/form-inputs-contracts.test.ts +223 -16
  176. package/src/__tests__/stemma-system/input-text-native-base-call-alignment.test.ts +298 -0
  177. package/src/blend/OklchBlendCalculator.ts +3 -0
  178. package/src/blend/ThemeAwareBlendUtilities.android.kt +3 -0
  179. package/src/blend/ThemeAwareBlendUtilities.ios.swift +3 -0
  180. package/src/blend/ThemeAwareBlendUtilities.web.ts +9 -1
  181. package/src/blend/__tests__/InteractionStateAudit.test.ts +12 -9
  182. package/src/build/errors/__tests__/ErrorHandler.integration.test.ts +8 -0
  183. package/src/build/errors/__tests__/ErrorHandler.test.ts +5 -0
  184. package/src/build/tokens/__tests__/defineComponentTokens.test.ts +113 -0
  185. package/src/build/tokens/defineComponentTokens.ts +43 -1
  186. package/src/build/workflow/__tests__/CICDIntegration.test.ts +12 -1
  187. package/src/cli/__tests__/init.test.ts +45 -11
  188. package/src/components/core/Avatar-Base/Avatar-Base.schema.yaml +1 -1
  189. package/src/components/core/Avatar-Base/__tests__/Avatar.accessibility.test.ts +121 -7
  190. package/src/components/core/Avatar-Base/__tests__/Avatar.image.test.ts +3 -0
  191. package/src/components/core/Avatar-Base/__tests__/Avatar.test.ts +15 -6
  192. package/src/components/core/Avatar-Base/avatar.tokens.ts +31 -34
  193. package/src/components/core/Avatar-Base/contracts.yaml +11 -1
  194. package/src/components/core/Avatar-Base/index.ts +1 -1
  195. package/src/components/core/Avatar-Base/platforms/web/Avatar.web.ts +24 -5
  196. package/src/components/core/Badge-Count-Base/contracts.yaml +1 -1
  197. package/src/components/core/Badge-Label-Base/contracts.yaml +1 -1
  198. package/src/components/core/Button-CTA/Button-CTA.schema.yaml +2 -12
  199. package/src/components/core/Button-CTA/README.md +3 -6
  200. package/src/components/core/Button-CTA/__tests__/ButtonCTA.test.ts +35 -89
  201. package/src/components/core/Button-CTA/__tests__/setup.test.ts +0 -2
  202. package/src/components/core/Button-CTA/__tests__/test-utils.ts +0 -2
  203. package/src/components/core/Button-CTA/contracts.yaml +6 -29
  204. package/src/components/core/Button-CTA/examples/BasicUsage.html +2 -14
  205. package/src/components/core/Button-CTA/examples/BasicUsage.tsx +17 -44
  206. package/src/components/core/Button-CTA/platforms/android/ButtonCTA.android.kt +12 -20
  207. package/src/components/core/Button-CTA/platforms/ios/ButtonCTA.ios.swift +12 -51
  208. package/src/components/core/Button-CTA/platforms/web/ButtonCTA.web.css +2 -26
  209. package/src/components/core/Button-CTA/platforms/web/ButtonCTA.web.ts +18 -71
  210. package/src/components/core/Button-CTA/types.ts +10 -28
  211. package/src/components/core/Button-Icon/buttonIcon.tokens.ts +43 -27
  212. package/src/components/core/Chip-Base/__tests__/ChipBase.test.ts +13 -0
  213. package/src/components/core/Chip-Filter/__tests__/ChipFilter.test.ts +13 -0
  214. package/src/components/core/Chip-Input/__tests__/ChipInput.test.ts +13 -0
  215. package/src/components/core/Input-Text-Base/Input-Text-Base.schema.yaml +30 -2
  216. package/src/components/core/Input-Text-Base/README.md +25 -2
  217. package/src/components/core/Input-Text-Base/__tests__/focusIndicators.test.ts +16 -15
  218. package/src/components/core/Input-Text-Base/contracts.yaml +90 -0
  219. package/src/components/core/Input-Text-Base/platforms/android/InputTextBase.android.kt +26 -12
  220. package/src/components/core/Input-Text-Base/platforms/ios/InputTextBase.ios.swift +195 -59
  221. package/src/components/core/Input-Text-Base/types.ts +13 -1
  222. package/src/components/core/Input-Text-Email/Input-Text-Email.schema.yaml +5 -1
  223. package/src/components/core/Input-Text-Email/README.md +8 -7
  224. package/src/components/core/Input-Text-Email/platforms/android/InputTextEmail.android.kt +1 -4
  225. package/src/components/core/Input-Text-Email/platforms/ios/InputTextEmail.ios.swift +2 -16
  226. package/src/components/core/Input-Text-Password/Input-Text-Password.schema.yaml +10 -3
  227. package/src/components/core/Input-Text-Password/README.md +9 -8
  228. package/src/components/core/Input-Text-Password/contracts.yaml +5 -0
  229. package/src/components/core/Input-Text-Password/platforms/android/InputTextPassword.android.kt +17 -7
  230. package/src/components/core/Input-Text-Password/platforms/ios/InputTextPassword.ios.swift +22 -20
  231. package/src/components/core/Input-Text-Password/platforms/web/InputTextPassword.web.ts +11 -2
  232. package/src/components/core/Input-Text-PhoneNumber/Input-Text-PhoneNumber.schema.yaml +5 -1
  233. package/src/components/core/Input-Text-PhoneNumber/README.md +9 -8
  234. package/src/components/core/Input-Text-PhoneNumber/platforms/android/InputTextPhoneNumber.android.kt +2 -5
  235. package/src/components/core/Input-Text-PhoneNumber/platforms/ios/InputTextPhoneNumber.ios.swift +3 -17
  236. package/src/components/core/Nav-Header-App/contracts.yaml +1 -1
  237. package/src/components/core/Nav-SegmentedChoice-Base/contracts.yaml +1 -1
  238. package/src/components/core/Progress-Indicator-Connector-Base/contracts.yaml +1 -1
  239. package/src/components/core/Progress-Indicator-Label-Base/contracts.yaml +1 -1
  240. package/src/components/core/Progress-Indicator-Node-Base/contracts.yaml +1 -1
  241. package/src/components/core/Progress-Stepper-Base/__tests__/StepperBase.test.ts +5 -2
  242. package/src/components/core/Progress-Stepper-Detailed/__tests__/StepperDetailed.test.ts +5 -2
  243. package/src/generators/DTCGFormatGenerator.ts +6 -0
  244. package/src/generators/TokenFileGenerator.ts +7 -2
  245. package/src/generators/__tests__/DTCGConfigOptions.test.ts +14 -5
  246. package/src/integration/BuildErrorHandler.ts +2 -2
  247. package/src/tokens/OpacityTokens.ts +1 -1
  248. package/src/tokens/__tests__/OpacityTokens.test.ts +3 -1
  249. package/src/tokens/__tests__/ProgressTokenCompliance.test.ts +5 -3
  250. package/src/tokens/__tests__/ProgressTokenFormulas.test.ts +11 -11
  251. package/src/tokens/__tests__/ProgressTokenTranslation.test.ts +22 -20
  252. package/src/tokens/component/progress.ts +83 -21
  253. package/src/tokens/semantic/BlendTokens.ts +26 -5
  254. package/src/tokens/semantic/OpacityTokens.ts +4 -4
  255. package/src/types/ComponentTypes.ts +1 -1
  256. package/src/types/generated/TokenTypes.ts +1 -1
  257. package/src/validators/StemmaTokenUsageValidator.ts +3 -2
  258. package/token-index/components.yaml +8 -8
  259. package/token-index/semantics.yaml +1 -2
  260. package/src/tools/release/__tests__/ChangeClassifier.test.ts +0 -133
  261. package/src/tools/release/__tests__/ChangeExtractor.test.ts +0 -222
  262. package/src/tools/release/__tests__/GitHubPublisher.test.ts +0 -240
  263. package/src/tools/release/__tests__/NotesRenderer.test.ts +0 -142
  264. package/src/tools/release/__tests__/NpmPublisher.test.ts +0 -289
  265. package/src/tools/release/__tests__/PipelineIntegration.test.ts +0 -188
  266. package/src/tools/release/__tests__/ReleasePipeline.test.ts +0 -192
  267. package/src/tools/release/__tests__/SemanticVersionValidator.test.ts +0 -49
  268. package/src/tools/release/__tests__/SummaryScanner.test.ts +0 -141
  269. package/src/tools/release/__tests__/TagResolver.test.ts +0 -91
  270. package/src/tools/release/__tests__/VersionCalculator.test.ts +0 -270
  271. package/src/tools/release/__tests__/helpers/NpmMockHelper.ts +0 -80
  272. package/src/tools/release/cli/ReleasePipeline.ts +0 -165
  273. package/src/tools/release/cli/release-tool.ts +0 -107
  274. package/src/tools/release/pipeline/ChangeClassifier.ts +0 -61
  275. package/src/tools/release/pipeline/ChangeExtractor.ts +0 -87
  276. package/src/tools/release/pipeline/NotesRenderer.ts +0 -66
  277. package/src/tools/release/pipeline/SummaryScanner.ts +0 -70
  278. package/src/tools/release/pipeline/TagResolver.ts +0 -40
  279. package/src/tools/release/pipeline/VersionCalculator.ts +0 -375
  280. package/src/tools/release/publishers/GitHubPublisher.ts +0 -228
  281. package/src/tools/release/publishers/NpmPublisher.ts +0 -196
  282. package/src/tools/release/release-config.json +0 -5
  283. package/src/tools/release/types/index.ts +0 -282
  284. package/src/tools/release/validators/SemanticVersionValidator.ts +0 -67
@@ -1,375 +0,0 @@
1
- /**
2
- * Version Calculator for Release Tool
3
- *
4
- * Semantic version calculation based on extracted changes.
5
- * Extracted from src/release-analysis/versioning/VersionCalculator.ts
6
- * and adapted to use local types.
7
- */
8
-
9
- import {
10
- ExtractedChanges,
11
- BreakingChange,
12
- Feature,
13
- BugFix,
14
- Improvement,
15
- VersionRecommendation,
16
- ChangeEvidence,
17
- PreReleaseInfo,
18
- ValidationResult,
19
- ParsedVersion,
20
- } from '../types';
21
-
22
- export class VersionCalculator {
23
- calculateVersionBump(changes: ExtractedChanges, currentVersion: string): VersionRecommendation {
24
- const parsedVersion = this.parseVersion(currentVersion);
25
- const evidence = this.generateEvidence(changes);
26
- const bumpType = this.determineBumpType(changes);
27
- const recommendedVersion = this.calculateNewVersion(parsedVersion, bumpType);
28
- const rationale = this.generateVersionRationale(changes);
29
- const confidence = this.calculateConfidence(changes, bumpType);
30
-
31
- return {
32
- currentVersion,
33
- recommendedVersion,
34
- bumpType,
35
- rationale,
36
- confidence,
37
- evidence,
38
- preReleaseInfo: this.analyzePreReleaseInfo(parsedVersion, bumpType),
39
- };
40
- }
41
-
42
- validateSemanticVersioning(recommendation: VersionRecommendation): ValidationResult {
43
- const errors: string[] = [];
44
- const warnings: string[] = [];
45
-
46
- if (!this.isValidSemanticVersion(recommendation.currentVersion)) {
47
- errors.push(`Current version "${recommendation.currentVersion}" is not a valid semantic version`);
48
- }
49
- if (!this.isValidSemanticVersion(recommendation.recommendedVersion)) {
50
- errors.push(`Recommended version "${recommendation.recommendedVersion}" is not a valid semantic version`);
51
- }
52
- if (errors.length > 0) {
53
- return { valid: false, errors, warnings };
54
- }
55
-
56
- const currentParsed = this.parseVersion(recommendation.currentVersion);
57
- const recommendedParsed = this.parseVersion(recommendation.recommendedVersion);
58
-
59
- if (!this.isValidVersionProgression(currentParsed, recommendedParsed, recommendation.bumpType)) {
60
- errors.push(
61
- `Version progression from ${recommendation.currentVersion} to ${recommendation.recommendedVersion} is invalid for ${recommendation.bumpType} bump`,
62
- );
63
- }
64
-
65
- const hasBreaking = recommendation.evidence.some((e) => e.type === 'breaking');
66
- const hasFeatures = recommendation.evidence.some((e) => e.type === 'feature');
67
- const hasFixes = recommendation.evidence.some((e) => e.type === 'fix' || e.type === 'improvement');
68
-
69
- let expectedBumpType: 'major' | 'minor' | 'patch' | 'none' = 'none';
70
- if (hasBreaking) expectedBumpType = 'major';
71
- else if (hasFeatures) expectedBumpType = 'minor';
72
- else if (hasFixes) expectedBumpType = 'patch';
73
-
74
- if (recommendation.bumpType !== expectedBumpType && expectedBumpType !== 'none') {
75
- warnings.push(
76
- `Recommended bump type "${recommendation.bumpType}" may not match evidence (expected "${expectedBumpType}")`,
77
- );
78
- }
79
-
80
- if (recommendation.confidence < 0.7) {
81
- warnings.push(`Low confidence score (${recommendation.confidence.toFixed(2)}) - manual review recommended`);
82
- }
83
-
84
- return { valid: errors.length === 0, errors, warnings };
85
- }
86
-
87
- generateVersionRationale(changes: ExtractedChanges): string {
88
- const rationale: string[] = [];
89
-
90
- if (changes.breakingChanges.length > 0) {
91
- rationale.push(`Major version bump required due to ${changes.breakingChanges.length} breaking change(s):`);
92
- changes.breakingChanges.slice(0, 3).forEach((c) => rationale.push(` • ${c.title} (${c.severity} severity)`));
93
- if (changes.breakingChanges.length > 3)
94
- rationale.push(` • ... and ${changes.breakingChanges.length - 3} more breaking changes`);
95
- } else if (changes.newFeatures.length > 0) {
96
- rationale.push(`Minor version bump recommended due to ${changes.newFeatures.length} new feature(s):`);
97
- changes.newFeatures.slice(0, 3).forEach((f) => rationale.push(` • ${f.title}`));
98
- if (changes.newFeatures.length > 3)
99
- rationale.push(` • ... and ${changes.newFeatures.length - 3} more features`);
100
- } else if (changes.bugFixes.length > 0 || changes.improvements.length > 0) {
101
- const total = changes.bugFixes.length + changes.improvements.length;
102
- rationale.push(`Patch version bump recommended due to ${total} fix(es) and improvement(s):`);
103
- changes.bugFixes.slice(0, 2).forEach((f) => rationale.push(` • ${f.title} (bug fix)`));
104
- changes.improvements.slice(0, 2).forEach((i) => rationale.push(` • ${i.title} (${i.type})`));
105
- if (total > 4) rationale.push(` • ... and ${total - 4} more fixes/improvements`);
106
- } else {
107
- rationale.push('No version bump required - only documentation or non-functional changes detected');
108
- }
109
-
110
- return rationale.join('\n');
111
- }
112
-
113
- handlePreReleaseVersions(currentVersion: string, bumpType: 'major' | 'minor' | 'patch' | 'none'): string {
114
- const parsed = this.parseVersion(currentVersion);
115
-
116
- if (parsed.preRelease) {
117
- const match = parsed.preRelease.match(/^(alpha|beta|rc)\.?(\d+)?$/);
118
- if (match) {
119
- const [, type, num] = match;
120
- const nextNum = num ? parseInt(num) + 1 : 1;
121
- return `${parsed.major}.${parsed.minor}.${parsed.patch}-${type}.${nextNum}`;
122
- }
123
- }
124
-
125
- return this.calculateNewVersion(parsed, bumpType);
126
- }
127
-
128
- generatePreReleaseVersion(
129
- baseVersion: string,
130
- preReleaseType: 'alpha' | 'beta' | 'rc',
131
- preReleaseNumber: number = 1,
132
- ): string {
133
- const parsed = this.parseVersion(baseVersion);
134
- return `${parsed.major}.${parsed.minor}.${parsed.patch}-${preReleaseType}.${preReleaseNumber}`;
135
- }
136
-
137
- progressPreReleaseStage(currentVersion: string): string {
138
- const parsed = this.parseVersion(currentVersion);
139
- if (!parsed.preRelease) throw new Error(`Version ${currentVersion} is not a pre-release version`);
140
-
141
- const match = parsed.preRelease.match(/^(alpha|beta|rc)\.?(\d+)?$/);
142
- if (!match) throw new Error(`Invalid pre-release format: ${parsed.preRelease}`);
143
-
144
- const base = `${parsed.major}.${parsed.minor}.${parsed.patch}`;
145
- switch (match[1]) {
146
- case 'alpha': return `${base}-beta.1`;
147
- case 'beta': return `${base}-rc.1`;
148
- case 'rc': return base;
149
- default: throw new Error(`Unknown pre-release type: ${match[1]}`);
150
- }
151
- }
152
-
153
- incrementPreReleaseNumber(currentVersion: string): string {
154
- const parsed = this.parseVersion(currentVersion);
155
- if (!parsed.preRelease) throw new Error(`Version ${currentVersion} is not a pre-release version`);
156
-
157
- const match = parsed.preRelease.match(/^(alpha|beta|rc)\.?(\d+)?$/);
158
- if (!match) throw new Error(`Invalid pre-release format: ${parsed.preRelease}`);
159
-
160
- const [, type, num] = match;
161
- return `${parsed.major}.${parsed.minor}.${parsed.patch}-${type}.${num ? parseInt(num) + 1 : 1}`;
162
- }
163
-
164
- promoteToStable(currentVersion: string): string {
165
- const parsed = this.parseVersion(currentVersion);
166
- if (!parsed.preRelease) throw new Error(`Version ${currentVersion} is already a stable version`);
167
- return `${parsed.major}.${parsed.minor}.${parsed.patch}`;
168
- }
169
-
170
- isPreRelease(version: string): boolean {
171
- try {
172
- return this.parseVersion(version).preRelease !== null;
173
- } catch {
174
- return false;
175
- }
176
- }
177
-
178
- getPreReleaseType(version: string): 'alpha' | 'beta' | 'rc' | null {
179
- try {
180
- const parsed = this.parseVersion(version);
181
- if (!parsed.preRelease) return null;
182
- const match = parsed.preRelease.match(/^(alpha|beta|rc)\.?(\d+)?$/);
183
- return match ? (match[1] as 'alpha' | 'beta' | 'rc') : null;
184
- } catch {
185
- return null;
186
- }
187
- }
188
-
189
- getPreReleaseNumber(version: string): number | null {
190
- try {
191
- const parsed = this.parseVersion(version);
192
- if (!parsed.preRelease) return null;
193
- const match = parsed.preRelease.match(/^(alpha|beta|rc)\.?(\d+)?$/);
194
- if (!match) return null;
195
- return match[2] ? parseInt(match[2]) : 0;
196
- } catch {
197
- return null;
198
- }
199
- }
200
-
201
- parseVersion(version: string): ParsedVersion {
202
- const match = version.match(
203
- /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/,
204
- );
205
- if (!match) throw new Error(`Invalid semantic version: ${version}`);
206
-
207
- return {
208
- major: parseInt(match[1]),
209
- minor: parseInt(match[2]),
210
- patch: parseInt(match[3]),
211
- preRelease: match[4] || null,
212
- build: match[5] || null,
213
- raw: version,
214
- };
215
- }
216
-
217
- private determineBumpType(changes: ExtractedChanges): 'major' | 'minor' | 'patch' | 'none' {
218
- if (changes.breakingChanges.length > 0) return 'major';
219
- if (changes.newFeatures.length > 0) return 'minor';
220
- if (changes.bugFixes.length > 0 || changes.improvements.length > 0) return 'patch';
221
- return 'none';
222
- }
223
-
224
- private calculateNewVersion(parsed: ParsedVersion, bumpType: 'major' | 'minor' | 'patch' | 'none'): string {
225
- switch (bumpType) {
226
- case 'major': return `${parsed.major + 1}.0.0`;
227
- case 'minor': return `${parsed.major}.${parsed.minor + 1}.0`;
228
- case 'patch': return `${parsed.major}.${parsed.minor}.${parsed.patch + 1}`;
229
- case 'none': return parsed.raw;
230
- }
231
- }
232
-
233
- private generateEvidence(changes: ExtractedChanges): ChangeEvidence[] {
234
- const evidence: ChangeEvidence[] = [];
235
-
236
- if (changes.breakingChanges.length > 0) {
237
- evidence.push({
238
- type: 'breaking',
239
- description: `${changes.breakingChanges.length} breaking change(s) detected`,
240
- source: 'completion documents',
241
- impact: this.determineBreakingChangeImpact(changes.breakingChanges),
242
- count: changes.breakingChanges.length,
243
- });
244
- }
245
- if (changes.newFeatures.length > 0) {
246
- evidence.push({
247
- type: 'feature',
248
- description: `${changes.newFeatures.length} new feature(s) added`,
249
- source: 'completion documents',
250
- impact: this.determineFeatureImpact(changes.newFeatures),
251
- count: changes.newFeatures.length,
252
- });
253
- }
254
- if (changes.bugFixes.length > 0) {
255
- evidence.push({
256
- type: 'fix',
257
- description: `${changes.bugFixes.length} bug fix(es) implemented`,
258
- source: 'completion documents',
259
- impact: this.determineBugFixImpact(changes.bugFixes),
260
- count: changes.bugFixes.length,
261
- });
262
- }
263
- if (changes.improvements.length > 0) {
264
- evidence.push({
265
- type: 'improvement',
266
- description: `${changes.improvements.length} improvement(s) made`,
267
- source: 'completion documents',
268
- impact: this.determineImprovementImpact(changes.improvements),
269
- count: changes.improvements.length,
270
- });
271
- }
272
-
273
- return evidence;
274
- }
275
-
276
- private calculateConfidence(changes: ExtractedChanges, bumpType: 'major' | 'minor' | 'patch' | 'none'): number {
277
- let confidence = changes.metadata.extractionConfidence;
278
-
279
- if (changes.metadata.ambiguousItems.length > 0) {
280
- confidence -= Math.min(0.2, changes.metadata.ambiguousItems.length * 0.05);
281
- }
282
-
283
- if (bumpType === 'major' && changes.breakingChanges.length > 0) confidence += 0.1;
284
- else if (bumpType === 'minor' && changes.newFeatures.length > 0 && changes.breakingChanges.length === 0)
285
- confidence += 0.1;
286
- else if (
287
- bumpType === 'patch' &&
288
- (changes.bugFixes.length > 0 || changes.improvements.length > 0) &&
289
- changes.breakingChanges.length === 0 &&
290
- changes.newFeatures.length === 0
291
- )
292
- confidence += 0.1;
293
-
294
- return Math.max(0, Math.min(1, confidence));
295
- }
296
-
297
- private analyzePreReleaseInfo(
298
- parsed: ParsedVersion,
299
- bumpType: 'major' | 'minor' | 'patch' | 'none',
300
- ): PreReleaseInfo | undefined {
301
- if (!parsed.preRelease) return undefined;
302
-
303
- const match = parsed.preRelease.match(/^(alpha|beta|rc)\.?(\d+)?$/);
304
- if (!match) return { isPreRelease: true, canPromote: false };
305
-
306
- const [, type, num] = match;
307
- const preReleaseNumber = num ? parseInt(num) : 0;
308
-
309
- return {
310
- isPreRelease: true,
311
- preReleaseType: type as 'alpha' | 'beta' | 'rc',
312
- preReleaseNumber,
313
- canPromote: type === 'rc' && bumpType !== 'none',
314
- nextPreRelease: `${type}.${preReleaseNumber + 1}`,
315
- };
316
- }
317
-
318
- private isValidSemanticVersion(version: string): boolean {
319
- return /^(\d+)\.(\d+)\.(\d+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?$/.test(
320
- version,
321
- );
322
- }
323
-
324
- private isValidVersionProgression(
325
- current: ParsedVersion,
326
- recommended: ParsedVersion,
327
- bumpType: 'major' | 'minor' | 'patch' | 'none',
328
- ): boolean {
329
- switch (bumpType) {
330
- case 'major':
331
- return recommended.major === current.major + 1 && recommended.minor === 0 && recommended.patch === 0;
332
- case 'minor':
333
- return (
334
- recommended.major === current.major && recommended.minor === current.minor + 1 && recommended.patch === 0
335
- );
336
- case 'patch':
337
- return (
338
- recommended.major === current.major &&
339
- recommended.minor === current.minor &&
340
- recommended.patch === current.patch + 1
341
- );
342
- case 'none':
343
- return (
344
- recommended.major === current.major &&
345
- recommended.minor === current.minor &&
346
- recommended.patch === current.patch
347
- );
348
- }
349
- }
350
-
351
- private determineBreakingChangeImpact(breakingChanges: BreakingChange[]): 'high' | 'medium' | 'low' {
352
- if (breakingChanges.some((c) => c.severity === 'critical')) return 'high';
353
- if (breakingChanges.some((c) => c.severity === 'high') || breakingChanges.length > 3) return 'high';
354
- if (breakingChanges.length > 1) return 'medium';
355
- return 'low';
356
- }
357
-
358
- private determineFeatureImpact(features: Feature[]): 'high' | 'medium' | 'low' {
359
- if (features.length > 5) return 'high';
360
- if (features.length > 2) return 'medium';
361
- return 'low';
362
- }
363
-
364
- private determineBugFixImpact(bugFixes: BugFix[]): 'high' | 'medium' | 'low' {
365
- if (bugFixes.some((f) => f.severity === 'critical')) return 'high';
366
- if (bugFixes.some((f) => f.severity === 'high') || bugFixes.length > 5) return 'medium';
367
- return 'low';
368
- }
369
-
370
- private determineImprovementImpact(improvements: Improvement[]): 'high' | 'medium' | 'low' {
371
- if (improvements.some((i) => i.impact === 'high')) return 'high';
372
- if (improvements.length > 3) return 'medium';
373
- return 'low';
374
- }
375
- }
@@ -1,228 +0,0 @@
1
- /**
2
- * GitHub Publisher for Release Tool
3
- *
4
- * Handles GitHub API interactions for creating releases, tags, and uploading artifacts.
5
- * Extracted from src/release/publishing/GitHubPublisher.ts.
6
- */
7
-
8
- import { Octokit } from '@octokit/rest';
9
- import * as fs from 'fs';
10
- import {
11
- GitHubRelease,
12
- GitTag,
13
- Artifact,
14
- ReleaseResult,
15
- TagResult,
16
- UploadResult,
17
- ReleaseError,
18
- RepositoryInfo,
19
- } from '../types';
20
-
21
- export interface GitHubConfig {
22
- token: string;
23
- owner: string;
24
- repo: string;
25
- baseUrl?: string;
26
- timeout?: number;
27
- maxRetries?: number;
28
- retryDelay?: number;
29
- }
30
-
31
- export class GitHubPublisher {
32
- private octokit: Octokit;
33
- private config: GitHubConfig;
34
- private authenticated: boolean = false;
35
-
36
- constructor(config: GitHubConfig) {
37
- this.config = { timeout: 30000, maxRetries: 3, retryDelay: 1000, ...config };
38
- this.octokit = new Octokit({
39
- auth: this.config.token,
40
- baseUrl: this.config.baseUrl,
41
- request: { timeout: this.config.timeout },
42
- });
43
- }
44
-
45
- async validateAuthentication(): Promise<boolean> {
46
- try {
47
- await this.octokit.rest.users.getAuthenticated();
48
- this.authenticated = true;
49
- return true;
50
- } catch (error) {
51
- this.authenticated = false;
52
- throw new Error(`GitHub authentication failed: ${this.getErrorMessage(error)}`);
53
- }
54
- }
55
-
56
- async getRepositoryInfo(): Promise<RepositoryInfo> {
57
- try {
58
- const { data } = await this.octokit.rest.repos.get({
59
- owner: this.config.owner,
60
- repo: this.config.repo,
61
- });
62
- return {
63
- owner: data.owner.login,
64
- name: data.name,
65
- fullName: data.full_name,
66
- defaultBranch: data.default_branch,
67
- private: data.private,
68
- url: data.html_url,
69
- };
70
- } catch (error) {
71
- throw new Error(`Failed to get repository info: ${this.getErrorMessage(error)}`);
72
- }
73
- }
74
-
75
- async releaseExists(tagName: string): Promise<boolean> {
76
- try {
77
- await this.octokit.rest.repos.getReleaseByTag({
78
- owner: this.config.owner,
79
- repo: this.config.repo,
80
- tag: tagName,
81
- });
82
- return true;
83
- } catch (error: any) {
84
- if (error.status === 404) return false;
85
- throw new Error(`Failed to check if release exists: ${this.getErrorMessage(error)}`);
86
- }
87
- }
88
-
89
- async createTags(tags: GitTag[]): Promise<TagResult[]> {
90
- const results: TagResult[] = [];
91
- for (const tag of tags) {
92
- try {
93
- const { data: commit } = await this.octokit.rest.git.getCommit({
94
- owner: this.config.owner, repo: this.config.repo, commit_sha: tag.commit,
95
- });
96
- const { data: tagObject } = await this.octokit.rest.git.createTag({
97
- owner: this.config.owner, repo: this.config.repo,
98
- tag: tag.name, message: tag.message, object: commit.sha, type: 'commit',
99
- });
100
- await this.octokit.rest.git.createRef({
101
- owner: this.config.owner, repo: this.config.repo,
102
- ref: `refs/tags/${tag.name}`, sha: tagObject.sha,
103
- });
104
- results.push({ success: true, tagName: tag.name });
105
- } catch (error) {
106
- results.push({ success: false, tagName: tag.name, error: this.getErrorMessage(error) });
107
- }
108
- }
109
- return results;
110
- }
111
-
112
- async createRelease(release: GitHubRelease): Promise<ReleaseResult> {
113
- const startTime = Date.now();
114
- const errors: ReleaseError[] = [];
115
-
116
- try {
117
- if (!this.authenticated) await this.validateAuthentication();
118
-
119
- const exists = await this.releaseExists(release.tagName);
120
- if (exists) throw new Error(`Release ${release.tagName} already exists`);
121
-
122
- const { data: githubRelease } = await this.octokit.rest.repos.createRelease({
123
- owner: this.config.owner, repo: this.config.repo,
124
- tag_name: release.tagName, name: release.name, body: release.body,
125
- draft: release.draft, prerelease: release.prerelease,
126
- });
127
-
128
- if (release.artifacts?.length > 0) {
129
- const artifactResults = await this.uploadArtifacts(githubRelease.id.toString(), release.artifacts);
130
- artifactResults.forEach((result) => {
131
- if (!result.success && result.error) {
132
- errors.push({
133
- code: 'ARTIFACT_UPLOAD_FAILED',
134
- message: `Failed to upload artifact ${result.artifactName}: ${result.error}`,
135
- severity: 'warning', step: 'artifact-upload',
136
- });
137
- }
138
- });
139
- }
140
-
141
- return {
142
- success: errors.filter((e) => e.severity === 'error').length === 0,
143
- version: release.tagName, releasedPackages: [this.config.repo],
144
- githubReleaseUrl: githubRelease.html_url, npmPackageUrls: [],
145
- duration: Date.now() - startTime, errors, releasedAt: new Date(),
146
- };
147
- } catch (error) {
148
- errors.push({
149
- code: 'RELEASE_CREATION_FAILED', message: this.getErrorMessage(error),
150
- severity: 'error', step: 'release-creation',
151
- stackTrace: error instanceof Error ? error.stack : undefined,
152
- });
153
- return {
154
- success: false, version: release.tagName, releasedPackages: [],
155
- npmPackageUrls: [], duration: Date.now() - startTime, errors, releasedAt: new Date(),
156
- };
157
- }
158
- }
159
-
160
- async uploadArtifacts(releaseId: string, artifacts: Artifact[]): Promise<UploadResult[]> {
161
- const results: UploadResult[] = [];
162
- for (const artifact of artifacts) {
163
- try {
164
- if (!fs.existsSync(artifact.path)) {
165
- results.push({ success: false, artifactName: artifact.name, error: `Artifact file not found: ${artifact.path}` });
166
- continue;
167
- }
168
- const data = fs.readFileSync(artifact.path);
169
- const uploadResult = await this.uploadArtifactWithRetry(parseInt(releaseId), artifact.name, data, artifact.contentType);
170
- results.push({ success: true, artifactName: artifact.name, url: uploadResult.browser_download_url });
171
- } catch (error) {
172
- results.push({ success: false, artifactName: artifact.name, error: this.getErrorMessage(error) });
173
- }
174
- }
175
- return results;
176
- }
177
-
178
- async deleteRelease(tagName: string): Promise<boolean> {
179
- try {
180
- const { data: release } = await this.octokit.rest.repos.getReleaseByTag({
181
- owner: this.config.owner, repo: this.config.repo, tag: tagName,
182
- });
183
- await this.octokit.rest.repos.deleteRelease({
184
- owner: this.config.owner, repo: this.config.repo, release_id: release.id,
185
- });
186
- return true;
187
- } catch (error) {
188
- throw new Error(`Failed to delete release: ${this.getErrorMessage(error)}`);
189
- }
190
- }
191
-
192
- async deleteTag(tagName: string): Promise<boolean> {
193
- try {
194
- await this.octokit.rest.git.deleteRef({
195
- owner: this.config.owner, repo: this.config.repo, ref: `tags/${tagName}`,
196
- });
197
- return true;
198
- } catch (error) {
199
- throw new Error(`Failed to delete tag: ${this.getErrorMessage(error)}`);
200
- }
201
- }
202
-
203
- private async uploadArtifactWithRetry(
204
- releaseId: number, name: string, data: Buffer, contentType: string, attempt: number = 1,
205
- ): Promise<any> {
206
- try {
207
- const { data: asset } = await this.octokit.rest.repos.uploadReleaseAsset({
208
- owner: this.config.owner, repo: this.config.repo, release_id: releaseId,
209
- name, data: data as any,
210
- headers: { 'content-type': contentType, 'content-length': data.length },
211
- });
212
- return asset;
213
- } catch (error) {
214
- if (attempt < (this.config.maxRetries || 3)) {
215
- await new Promise((r) => setTimeout(r, this.config.retryDelay || 1000));
216
- return this.uploadArtifactWithRetry(releaseId, name, data, contentType, attempt + 1);
217
- }
218
- throw error;
219
- }
220
- }
221
-
222
- private getErrorMessage(error: unknown): string {
223
- if (error instanceof Error) return error.message;
224
- if (typeof error === 'string') return error;
225
- if (error && typeof error === 'object' && 'message' in error) return String((error as any).message);
226
- return 'Unknown error occurred';
227
- }
228
- }