specweave 0.6.8 → 0.7.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 (255) hide show
  1. package/.claude-plugin/README.md +1 -1
  2. package/CLAUDE.md +903 -99
  3. package/README.md +143 -207
  4. package/bin/specweave.js +67 -0
  5. package/dist/cli/commands/abandon.d.ts +13 -0
  6. package/dist/cli/commands/abandon.d.ts.map +1 -0
  7. package/dist/cli/commands/abandon.js +15 -0
  8. package/dist/cli/commands/abandon.js.map +1 -0
  9. package/dist/cli/commands/init.d.ts.map +1 -1
  10. package/dist/cli/commands/init.js +90 -18
  11. package/dist/cli/commands/init.js.map +1 -1
  12. package/dist/cli/commands/pause.d.ts +13 -0
  13. package/dist/cli/commands/pause.d.ts.map +1 -0
  14. package/dist/cli/commands/pause.js +15 -0
  15. package/dist/cli/commands/pause.js.map +1 -0
  16. package/dist/cli/commands/qa.d.ts +54 -0
  17. package/dist/cli/commands/qa.d.ts.map +1 -0
  18. package/dist/cli/commands/qa.js +98 -0
  19. package/dist/cli/commands/qa.js.map +1 -0
  20. package/dist/cli/commands/resume.d.ts +12 -0
  21. package/dist/cli/commands/resume.d.ts.map +1 -0
  22. package/dist/cli/commands/resume.js +14 -0
  23. package/dist/cli/commands/resume.js.map +1 -0
  24. package/dist/cli/commands/status.d.ts +12 -0
  25. package/dist/cli/commands/status.d.ts.map +1 -0
  26. package/dist/cli/commands/status.js +23 -0
  27. package/dist/cli/commands/status.js.map +1 -0
  28. package/dist/cli/helpers/issue-tracker/ado.d.ts +57 -0
  29. package/dist/cli/helpers/issue-tracker/ado.d.ts.map +1 -0
  30. package/dist/cli/helpers/issue-tracker/ado.js +223 -0
  31. package/dist/cli/helpers/issue-tracker/ado.js.map +1 -0
  32. package/dist/cli/helpers/issue-tracker/github.d.ts +65 -0
  33. package/dist/cli/helpers/issue-tracker/github.d.ts.map +1 -0
  34. package/dist/cli/helpers/issue-tracker/github.js +284 -0
  35. package/dist/cli/helpers/issue-tracker/github.js.map +1 -0
  36. package/dist/cli/helpers/issue-tracker/index.d.ts +22 -0
  37. package/dist/cli/helpers/issue-tracker/index.d.ts.map +1 -0
  38. package/dist/cli/helpers/issue-tracker/index.js +270 -0
  39. package/dist/cli/helpers/issue-tracker/index.js.map +1 -0
  40. package/dist/cli/helpers/issue-tracker/jira.d.ts +61 -0
  41. package/dist/cli/helpers/issue-tracker/jira.d.ts.map +1 -0
  42. package/dist/cli/helpers/issue-tracker/jira.js +265 -0
  43. package/dist/cli/helpers/issue-tracker/jira.js.map +1 -0
  44. package/dist/cli/helpers/issue-tracker/types.d.ts +86 -0
  45. package/dist/cli/helpers/issue-tracker/types.d.ts.map +1 -0
  46. package/dist/cli/helpers/issue-tracker/types.js +16 -0
  47. package/dist/cli/helpers/issue-tracker/types.js.map +1 -0
  48. package/dist/cli/helpers/issue-tracker/utils.d.ts +103 -0
  49. package/dist/cli/helpers/issue-tracker/utils.d.ts.map +1 -0
  50. package/dist/cli/helpers/issue-tracker/utils.js +240 -0
  51. package/dist/cli/helpers/issue-tracker/utils.js.map +1 -0
  52. package/dist/core/increment/limits.d.ts +68 -0
  53. package/dist/core/increment/limits.d.ts.map +1 -0
  54. package/dist/core/increment/limits.js +224 -0
  55. package/dist/core/increment/limits.js.map +1 -0
  56. package/dist/core/increment/metadata-manager.d.ts +114 -0
  57. package/dist/core/increment/metadata-manager.d.ts.map +1 -0
  58. package/dist/core/increment/metadata-manager.js +320 -0
  59. package/dist/core/increment/metadata-manager.js.map +1 -0
  60. package/dist/core/increment/status-commands.d.ts +43 -0
  61. package/dist/core/increment/status-commands.d.ts.map +1 -0
  62. package/dist/core/increment/status-commands.js +277 -0
  63. package/dist/core/increment/status-commands.js.map +1 -0
  64. package/dist/core/plugin-detector.d.ts +1 -0
  65. package/dist/core/plugin-detector.d.ts.map +1 -1
  66. package/dist/core/plugin-detector.js +25 -0
  67. package/dist/core/plugin-detector.js.map +1 -1
  68. package/dist/core/qa/qa-runner.d.ts +16 -0
  69. package/dist/core/qa/qa-runner.d.ts.map +1 -0
  70. package/dist/core/qa/qa-runner.js +404 -0
  71. package/dist/core/qa/qa-runner.js.map +1 -0
  72. package/dist/core/qa/quality-gate-decider.d.ts +53 -0
  73. package/dist/core/qa/quality-gate-decider.d.ts.map +1 -0
  74. package/dist/core/qa/quality-gate-decider.js +268 -0
  75. package/dist/core/qa/quality-gate-decider.js.map +1 -0
  76. package/dist/core/qa/risk-calculator.d.ts +126 -0
  77. package/dist/core/qa/risk-calculator.d.ts.map +1 -0
  78. package/dist/core/qa/risk-calculator.js +247 -0
  79. package/dist/core/qa/risk-calculator.js.map +1 -0
  80. package/dist/core/qa/types.d.ts +315 -0
  81. package/dist/core/qa/types.d.ts.map +1 -0
  82. package/dist/core/qa/types.js +8 -0
  83. package/dist/core/qa/types.js.map +1 -0
  84. package/dist/core/types/config.d.ts +35 -0
  85. package/dist/core/types/config.d.ts.map +1 -1
  86. package/dist/core/types/config.js +16 -0
  87. package/dist/core/types/config.js.map +1 -1
  88. package/dist/core/types/increment-metadata.d.ts +120 -0
  89. package/dist/core/types/increment-metadata.d.ts.map +1 -0
  90. package/dist/core/types/increment-metadata.js +138 -0
  91. package/dist/core/types/increment-metadata.js.map +1 -0
  92. package/dist/hooks/lib/invoke-translator-skill.d.ts +60 -0
  93. package/dist/hooks/lib/invoke-translator-skill.d.ts.map +1 -0
  94. package/dist/hooks/lib/invoke-translator-skill.js +201 -0
  95. package/dist/hooks/lib/invoke-translator-skill.js.map +1 -0
  96. package/dist/hooks/lib/translate-file.d.ts +59 -0
  97. package/dist/hooks/lib/translate-file.d.ts.map +1 -0
  98. package/dist/hooks/lib/translate-file.js +350 -0
  99. package/dist/hooks/lib/translate-file.js.map +1 -0
  100. package/dist/locales/en/cli.json +3 -1
  101. package/dist/metrics/calculators/change-failure-rate.d.ts +22 -0
  102. package/dist/metrics/calculators/change-failure-rate.d.ts.map +1 -0
  103. package/dist/metrics/calculators/change-failure-rate.js +70 -0
  104. package/dist/metrics/calculators/change-failure-rate.js.map +1 -0
  105. package/dist/metrics/calculators/deployment-frequency.d.ts +20 -0
  106. package/dist/metrics/calculators/deployment-frequency.d.ts.map +1 -0
  107. package/dist/metrics/calculators/deployment-frequency.js +61 -0
  108. package/dist/metrics/calculators/deployment-frequency.js.map +1 -0
  109. package/dist/metrics/calculators/lead-time.d.ts +22 -0
  110. package/dist/metrics/calculators/lead-time.d.ts.map +1 -0
  111. package/dist/metrics/calculators/lead-time.js +82 -0
  112. package/dist/metrics/calculators/lead-time.js.map +1 -0
  113. package/dist/metrics/calculators/mttr.d.ts +21 -0
  114. package/dist/metrics/calculators/mttr.d.ts.map +1 -0
  115. package/dist/metrics/calculators/mttr.js +60 -0
  116. package/dist/metrics/calculators/mttr.js.map +1 -0
  117. package/dist/metrics/dora-calculator.d.ts +24 -0
  118. package/dist/metrics/dora-calculator.d.ts.map +1 -0
  119. package/dist/metrics/dora-calculator.js +104 -0
  120. package/dist/metrics/dora-calculator.js.map +1 -0
  121. package/dist/metrics/github-client.d.ts +51 -0
  122. package/dist/metrics/github-client.d.ts.map +1 -0
  123. package/dist/metrics/github-client.js +133 -0
  124. package/dist/metrics/github-client.js.map +1 -0
  125. package/dist/metrics/types.d.ts +112 -0
  126. package/dist/metrics/types.d.ts.map +1 -0
  127. package/dist/metrics/types.js +10 -0
  128. package/dist/metrics/types.js.map +1 -0
  129. package/dist/metrics/utils/percentile.d.ts +25 -0
  130. package/dist/metrics/utils/percentile.d.ts.map +1 -0
  131. package/dist/metrics/utils/percentile.js +46 -0
  132. package/dist/metrics/utils/percentile.js.map +1 -0
  133. package/dist/metrics/utils/tier-classifier.d.ts +61 -0
  134. package/dist/metrics/utils/tier-classifier.d.ts.map +1 -0
  135. package/dist/metrics/utils/tier-classifier.js +100 -0
  136. package/dist/metrics/utils/tier-classifier.js.map +1 -0
  137. package/dist/utils/auth-helpers.d.ts +58 -0
  138. package/dist/utils/auth-helpers.d.ts.map +1 -0
  139. package/dist/utils/auth-helpers.js +108 -0
  140. package/dist/utils/auth-helpers.js.map +1 -0
  141. package/dist/utils/env-file.d.ts +88 -0
  142. package/dist/utils/env-file.d.ts.map +1 -0
  143. package/dist/utils/env-file.js +180 -0
  144. package/dist/utils/env-file.js.map +1 -0
  145. package/dist/utils/plugin-detection.d.ts +50 -0
  146. package/dist/utils/plugin-detection.d.ts.map +1 -0
  147. package/dist/utils/plugin-detection.js +229 -0
  148. package/dist/utils/plugin-detection.js.map +1 -0
  149. package/dist/utils/secrets-loader.d.ts +88 -0
  150. package/dist/utils/secrets-loader.d.ts.map +1 -0
  151. package/dist/utils/secrets-loader.js +271 -0
  152. package/dist/utils/secrets-loader.js.map +1 -0
  153. package/dist/utils/translation.d.ts +187 -0
  154. package/dist/utils/translation.d.ts.map +1 -0
  155. package/dist/utils/translation.js +414 -0
  156. package/dist/utils/translation.js.map +1 -0
  157. package/package.json +28 -44
  158. package/plugins/specweave/.claude-plugin/plugin.json +3 -3
  159. package/plugins/specweave/agents/pm/AGENT.md +330 -54
  160. package/plugins/specweave/agents/test-aware-planner/AGENT.md +1035 -0
  161. package/plugins/specweave/agents/test-aware-planner/templates/README.md +118 -0
  162. package/plugins/specweave/agents/test-aware-planner/templates/task-non-testable.md.template +24 -0
  163. package/plugins/specweave/agents/test-aware-planner/templates/task-testable.md.template +53 -0
  164. package/plugins/specweave/agents/test-aware-planner/templates/tasks-frontmatter.md.template +11 -0
  165. package/plugins/specweave/commands/README.md +88 -163
  166. package/plugins/specweave/commands/specweave-abandon.md +314 -0
  167. package/plugins/specweave/commands/specweave-check-tests.md +546 -0
  168. package/plugins/specweave/commands/{do.md → specweave-do.md} +5 -7
  169. package/plugins/specweave/commands/{increment.md → specweave-increment.md} +231 -4
  170. package/plugins/specweave/commands/specweave-pause.md +189 -0
  171. package/plugins/specweave/commands/specweave-qa.md +245 -0
  172. package/plugins/specweave/commands/specweave-resume.md +216 -0
  173. package/plugins/specweave/commands/specweave-status.md +397 -0
  174. package/plugins/specweave/commands/specweave-sync-tasks.md +256 -0
  175. package/plugins/specweave/commands/{translate.md → specweave-translate.md} +3 -3
  176. package/plugins/specweave/commands/specweave-update-scope.md +351 -0
  177. package/plugins/specweave/commands/specweave.md +21 -21
  178. package/plugins/specweave/hooks/post-increment-planning.sh +335 -0
  179. package/plugins/specweave/hooks/post-task-completion.sh +141 -0
  180. package/plugins/specweave/skills/SKILLS-INDEX.md +1 -1
  181. package/plugins/specweave/skills/brownfield-analyzer/SKILL.md +9 -9
  182. package/plugins/specweave/skills/increment-planner/SKILL.md +400 -212
  183. package/plugins/specweave/skills/increment-quality-judge-v2/SKILL.md +499 -0
  184. package/plugins/specweave/skills/plugin-detector/SKILL.md +114 -1
  185. package/plugins/specweave/skills/project-kickstarter/SKILL.md +74 -1
  186. package/plugins/specweave/skills/{rfc-generator → spec-generator}/SKILL.md +22 -29
  187. package/plugins/specweave/skills/specweave-detector/SKILL.md +3 -3
  188. package/plugins/specweave/skills/specweave-framework/SKILL.md +2 -2
  189. package/plugins/specweave-ado/.claude-plugin/plugin.json +18 -4
  190. package/plugins/specweave-ado/agents/ado-manager/AGENT.md +426 -0
  191. package/plugins/specweave-ado/commands/close-workitem.md +52 -0
  192. package/plugins/specweave-ado/commands/create-workitem.md +53 -0
  193. package/plugins/specweave-ado/commands/status.md +53 -0
  194. package/plugins/specweave-ado/commands/sync.md +55 -0
  195. package/plugins/specweave-ado/lib/ado-client.ts +361 -0
  196. package/plugins/specweave-ado/reference/ado-specweave-mapping.md +552 -0
  197. package/plugins/specweave-ado/skills/ado-sync/SKILL.md +344 -193
  198. package/plugins/specweave-docs/skills/docusaurus/SKILL.md +73 -0
  199. package/plugins/specweave-github/agents/github-manager/AGENT.md +49 -0
  200. package/plugins/specweave-github/commands/{github-close-issue.md → close-issue.md} +1 -1
  201. package/plugins/specweave-github/commands/{github-create-issue.md → create-issue.md} +1 -1
  202. package/plugins/specweave-github/commands/{github-status.md → status.md} +1 -1
  203. package/plugins/specweave-github/commands/{github-sync-tasks.md → sync-tasks.md} +1 -1
  204. package/plugins/specweave-github/commands/{github-sync.md → sync.md} +1 -1
  205. package/plugins/specweave-github/reference/github-specweave-mapping.md +377 -0
  206. package/plugins/specweave-github/skills/github-sync/SKILL.md +11 -3
  207. package/plugins/specweave-infrastructure/commands/{specweave.monitor-setup.md → monitor-setup.md} +5 -0
  208. package/plugins/specweave-infrastructure/commands/{specweave.slo-implement.md → slo-implement.md} +5 -0
  209. package/plugins/specweave-jira/agents/jira-manager/AGENT.md +380 -0
  210. package/plugins/specweave-jira/commands/{specweave.sync-jira.md → sync.md} +1 -1
  211. package/plugins/specweave-jira/reference/jira-specweave-mapping.md +508 -0
  212. package/plugins/specweave-ml/commands/ml-deploy.md +1 -1
  213. package/plugins/specweave-ml/commands/ml-evaluate.md +1 -1
  214. package/plugins/specweave-ml/commands/ml-explain.md +1 -1
  215. package/plugins/specweave-ml/commands/{specweave.ml-pipeline.md → ml-pipeline.md} +5 -0
  216. package/src/templates/AGENTS.md.template +331 -31
  217. package/src/templates/CLAUDE.md.template +36 -21
  218. package/src/templates/COMPLETION-REPORT.template.md +128 -0
  219. package/src/templates/README.md.template +17 -16
  220. package/src/templates/docs/README.md +11 -9
  221. package/src/templates/docs/spec-template.md +229 -0
  222. package/plugins/specweave/commands/inc.md +0 -85
  223. package/plugins/specweave/commands/list-increments.md +0 -180
  224. package/src/adapters/README.md +0 -275
  225. package/src/adapters/adapter-base.ts +0 -182
  226. package/src/adapters/adapter-interface.ts +0 -166
  227. package/src/adapters/adapter-loader.ts +0 -256
  228. package/src/adapters/agents-md-generator.ts +0 -228
  229. package/src/adapters/claude/README.md +0 -233
  230. package/src/adapters/claude/adapter.ts +0 -468
  231. package/src/adapters/claude-md-generator.ts +0 -377
  232. package/src/adapters/codex/README.md +0 -105
  233. package/src/adapters/codex/adapter.ts +0 -333
  234. package/src/adapters/cursor/.cursor/context/docs-context.md +0 -62
  235. package/src/adapters/cursor/.cursor/context/increments-context.md +0 -71
  236. package/src/adapters/cursor/.cursor/context/strategy-context.md +0 -73
  237. package/src/adapters/cursor/.cursor/context/tests-context.md +0 -89
  238. package/src/adapters/cursor/README.md +0 -283
  239. package/src/adapters/cursor/adapter.ts +0 -451
  240. package/src/adapters/doc-generator.ts +0 -331
  241. package/src/adapters/gemini/README.md +0 -97
  242. package/src/adapters/gemini/adapter.ts +0 -298
  243. package/src/adapters/generic/README.md +0 -277
  244. package/src/adapters/generic/adapter.ts +0 -378
  245. package/src/adapters/registry.yaml +0 -187
  246. /package/plugins/specweave/commands/{costs.md → specweave-costs.md} +0 -0
  247. /package/plugins/specweave/commands/{done.md → specweave-done.md} +0 -0
  248. /package/plugins/specweave/commands/{next.md → specweave-next.md} +0 -0
  249. /package/plugins/specweave/commands/{progress.md → specweave-progress.md} +0 -0
  250. /package/plugins/specweave/commands/{sync-docs.md → specweave-sync-docs.md} +0 -0
  251. /package/plugins/specweave/commands/{tdd-cycle.md → specweave-tdd-cycle.md} +0 -0
  252. /package/plugins/specweave/commands/{tdd-green.md → specweave-tdd-green.md} +0 -0
  253. /package/plugins/specweave/commands/{tdd-red.md → specweave-tdd-red.md} +0 -0
  254. /package/plugins/specweave/commands/{tdd-refactor.md → specweave-tdd-refactor.md} +0 -0
  255. /package/plugins/specweave/commands/{validate.md → specweave-validate.md} +0 -0
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Lead Time for Changes Calculator
3
+ *
4
+ * Calculates time from commit to deployment (DORA metric #2)
5
+ * Data source: Git commits + GitHub Releases API
6
+ */
7
+ import { classifyLeadTime } from '../utils/tier-classifier';
8
+ import { calculatePercentile } from '../utils/percentile';
9
+ /**
10
+ * Calculate Lead Time for Changes
11
+ *
12
+ * Methodology:
13
+ * 1. For each release, find all commits since previous release
14
+ * 2. Calculate time delta (commit date → release date) for each commit
15
+ * 3. Compute average, P50, P90
16
+ * 4. Classify into DORA tier
17
+ *
18
+ * @param releases - Array of GitHub releases (sorted by date desc)
19
+ * @param commits - Array of Git commits
20
+ * @returns Lead time metric
21
+ */
22
+ export function calculateLeadTime(releases, commits) {
23
+ // Handle zero releases
24
+ if (releases.length === 0) {
25
+ return {
26
+ value: 0,
27
+ unit: 'hours',
28
+ tier: 'N/A',
29
+ p50: 0,
30
+ p90: 0,
31
+ };
32
+ }
33
+ // Sort releases by date (newest first)
34
+ const sortedReleases = [...releases].sort((a, b) => new Date(b.published_at).getTime() - new Date(a.published_at).getTime());
35
+ // Calculate lead times for all commits
36
+ const leadTimes = [];
37
+ sortedReleases.forEach((release, index) => {
38
+ const releaseDate = new Date(release.published_at);
39
+ const previousReleaseDate = index < sortedReleases.length - 1
40
+ ? new Date(sortedReleases[index + 1].published_at)
41
+ : new Date(0); // Beginning of time for first release
42
+ // Find commits between previous release and current release
43
+ const releaseCommits = commits.filter(commit => {
44
+ const commitDate = new Date(commit.commit.author.date);
45
+ return commitDate > previousReleaseDate && commitDate <= releaseDate;
46
+ });
47
+ // Calculate lead time for each commit
48
+ releaseCommits.forEach(commit => {
49
+ const commitDate = new Date(commit.commit.author.date);
50
+ const leadTimeMs = releaseDate.getTime() - commitDate.getTime();
51
+ const leadTimeHours = leadTimeMs / (1000 * 60 * 60); // Convert to hours
52
+ leadTimes.push(leadTimeHours);
53
+ });
54
+ });
55
+ // Handle no commits (edge case)
56
+ if (leadTimes.length === 0) {
57
+ return {
58
+ value: 0,
59
+ unit: 'hours',
60
+ tier: 'N/A',
61
+ p50: 0,
62
+ p90: 0,
63
+ };
64
+ }
65
+ // Calculate statistics
66
+ const averageLeadTime = leadTimes.reduce((sum, lt) => sum + lt, 0) / leadTimes.length;
67
+ const p50 = calculatePercentile(leadTimes, 50);
68
+ const p90 = calculatePercentile(leadTimes, 90);
69
+ // Classify tier
70
+ const tier = classifyLeadTime(averageLeadTime);
71
+ // Choose appropriate unit
72
+ const unit = averageLeadTime < 24 ? 'hours' : 'days';
73
+ const value = unit === 'hours' ? averageLeadTime : averageLeadTime / 24;
74
+ return {
75
+ value: Math.round(value * 10) / 10, // Round to 1 decimal
76
+ unit,
77
+ tier,
78
+ p50: Math.round(p50 * 10) / 10,
79
+ p90: Math.round(p90 * 10) / 10,
80
+ };
81
+ }
82
+ //# sourceMappingURL=lead-time.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lead-time.js","sourceRoot":"","sources":["../../../src/metrics/calculators/lead-time.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Mean Time to Recovery (MTTR) Calculator
3
+ *
4
+ * Calculates average time to recover from incidents (DORA metric #4)
5
+ * Data source: GitHub Issues with labels "incident" or "production-bug"
6
+ */
7
+ import { Issue, MTTRMetric } from '../types';
8
+ /**
9
+ * Calculate Mean Time to Recovery (MTTR)
10
+ *
11
+ * Methodology:
12
+ * 1. Find closed issues labeled "incident" or "production-bug"
13
+ * 2. Calculate time from created_at to closed_at for each
14
+ * 3. Compute average, P50, P90
15
+ * 4. Classify into DORA tier
16
+ *
17
+ * @param issues - Array of GitHub issues
18
+ * @returns MTTR metric
19
+ */
20
+ export declare function calculateMTTR(issues: Issue[]): MTTRMetric;
21
+ //# sourceMappingURL=mttr.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mttr.d.ts","sourceRoot":"","sources":["../../../src/metrics/calculators/mttr.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAI7C;;;;;;;;;;;GAWG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,UAAU,CAiDzD"}
@@ -0,0 +1,60 @@
1
+ /**
2
+ * Mean Time to Recovery (MTTR) Calculator
3
+ *
4
+ * Calculates average time to recover from incidents (DORA metric #4)
5
+ * Data source: GitHub Issues with labels "incident" or "production-bug"
6
+ */
7
+ import { classifyMTTR } from '../utils/tier-classifier';
8
+ import { calculatePercentile } from '../utils/percentile';
9
+ /**
10
+ * Calculate Mean Time to Recovery (MTTR)
11
+ *
12
+ * Methodology:
13
+ * 1. Find closed issues labeled "incident" or "production-bug"
14
+ * 2. Calculate time from created_at to closed_at for each
15
+ * 3. Compute average, P50, P90
16
+ * 4. Classify into DORA tier
17
+ *
18
+ * @param issues - Array of GitHub issues
19
+ * @returns MTTR metric
20
+ */
21
+ export function calculateMTTR(issues) {
22
+ // Filter closed incidents
23
+ const closedIncidents = issues.filter(issue => issue.state === 'closed' &&
24
+ issue.closed_at !== null &&
25
+ issue.labels.some(label => label.name === 'incident' || label.name === 'production-bug'));
26
+ // Handle zero closed incidents
27
+ if (closedIncidents.length === 0) {
28
+ return {
29
+ value: 0,
30
+ unit: 'minutes',
31
+ tier: 'N/A',
32
+ p50: 0,
33
+ p90: 0,
34
+ };
35
+ }
36
+ // Calculate recovery times (in minutes)
37
+ const recoveryTimes = closedIncidents.map(incident => {
38
+ const createdAt = new Date(incident.created_at);
39
+ const closedAt = new Date(incident.closed_at);
40
+ const recoveryMs = closedAt.getTime() - createdAt.getTime();
41
+ return recoveryMs / (1000 * 60); // Convert to minutes
42
+ });
43
+ // Calculate statistics
44
+ const averageMTTR = recoveryTimes.reduce((sum, rt) => sum + rt, 0) / recoveryTimes.length;
45
+ const p50 = calculatePercentile(recoveryTimes, 50);
46
+ const p90 = calculatePercentile(recoveryTimes, 90);
47
+ // Classify tier
48
+ const tier = classifyMTTR(averageMTTR);
49
+ // Choose appropriate unit
50
+ const unit = averageMTTR < 60 ? 'minutes' : 'hours';
51
+ const value = unit === 'minutes' ? averageMTTR : averageMTTR / 60;
52
+ return {
53
+ value: Math.round(value * 10) / 10, // Round to 1 decimal
54
+ unit,
55
+ tier,
56
+ p50: Math.round(p50 * 10) / 10,
57
+ p90: Math.round(p90 * 10) / 10,
58
+ };
59
+ }
60
+ //# sourceMappingURL=mttr.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mttr.js","sourceRoot":"","sources":["../../../src/metrics/calculators/mttr.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,aAAa,CAAC,MAAe;IAC3C,0BAA0B;IAC1B,MAAM,eAAe,GAAG,MAAM,CAAC,MAAM,CACnC,KAAK,CAAC,EAAE,CACN,KAAK,CAAC,KAAK,KAAK,QAAQ;QACxB,KAAK,CAAC,SAAS,KAAK,IAAI;QACxB,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CACxB,KAAK,CAAC,IAAI,KAAK,UAAU,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,CAC7D,CACJ,CAAC;IAEF,+BAA+B;IAC/B,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjC,OAAO;YACL,KAAK,EAAE,CAAC;YACR,IAAI,EAAE,SAAS;YACf,IAAI,EAAE,KAAK;YACX,GAAG,EAAE,CAAC;YACN,GAAG,EAAE,CAAC;SACP,CAAC;IACJ,CAAC;IAED,wCAAwC;IACxC,MAAM,aAAa,GAAa,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;QAC7D,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;QAChD,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAU,CAAC,CAAC;QAC/C,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,EAAE,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;QAC5D,OAAO,UAAU,GAAG,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAE,qBAAqB;IACzD,CAAC,CAAC,CAAC;IAEH,uBAAuB;IACvB,MAAM,WAAW,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,EAAE,EAAE,CAAC,GAAG,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC;IAC1F,MAAM,GAAG,GAAG,mBAAmB,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IACnD,MAAM,GAAG,GAAG,mBAAmB,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IAEnD,gBAAgB;IAChB,MAAM,IAAI,GAAG,YAAY,CAAC,WAAW,CAAC,CAAC;IAEvC,0BAA0B;IAC1B,MAAM,IAAI,GAAG,WAAW,GAAG,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC;IACpD,MAAM,KAAK,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,WAAW,GAAG,EAAE,CAAC;IAElE,OAAO;QACL,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,GAAG,EAAE,EAAG,qBAAqB;QAC1D,IAAI;QACJ,IAAI;QACJ,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE;QAC9B,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,EAAE,CAAC,GAAG,EAAE;KAC/B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,24 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * DORA Metrics Calculator
4
+ *
5
+ * Main orchestrator that calculates all 4 DORA metrics
6
+ * Entry point for CLI and GitHub Actions workflow
7
+ */
8
+ import { GitHubClient } from './github-client';
9
+ import { DORAMetrics } from './types';
10
+ /**
11
+ * Calculate all DORA metrics
12
+ *
13
+ * @param client - GitHub API client
14
+ * @returns Complete DORA metrics
15
+ */
16
+ export declare function calculateDORAMetrics(client: GitHubClient): Promise<DORAMetrics>;
17
+ /**
18
+ * Write metrics to JSON file
19
+ *
20
+ * @param metrics - DORA metrics
21
+ * @param filePath - Output file path
22
+ */
23
+ export declare function writeMetricsJSON(metrics: DORAMetrics, filePath: string): void;
24
+ //# sourceMappingURL=dora-calculator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dora-calculator.d.ts","sourceRoot":"","sources":["../../src/metrics/dora-calculator.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAIH,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAK/C,OAAO,EAAE,WAAW,EAAgB,MAAM,SAAS,CAAC;AAEpD;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,CAAC,CAyCrF;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAY7E"}
@@ -0,0 +1,104 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * DORA Metrics Calculator
4
+ *
5
+ * Main orchestrator that calculates all 4 DORA metrics
6
+ * Entry point for CLI and GitHub Actions workflow
7
+ */
8
+ import * as fs from 'fs';
9
+ import * as path from 'path';
10
+ import { GitHubClient } from './github-client';
11
+ import { calculateDeploymentFrequency } from './calculators/deployment-frequency';
12
+ import { calculateLeadTime } from './calculators/lead-time';
13
+ import { calculateChangeFailureRate } from './calculators/change-failure-rate';
14
+ import { calculateMTTR } from './calculators/mttr';
15
+ /**
16
+ * Calculate all DORA metrics
17
+ *
18
+ * @param client - GitHub API client
19
+ * @returns Complete DORA metrics
20
+ */
21
+ export async function calculateDORAMetrics(client) {
22
+ // Query data from GitHub (last 30 days)
23
+ const since = new Date();
24
+ since.setDate(since.getDate() - 30);
25
+ console.log('📊 Fetching data from GitHub API...');
26
+ const releases = await client.getReleases(since);
27
+ console.log(` ✓ Found ${releases.length} releases`);
28
+ const commits = releases.length > 0
29
+ ? await client.getCommits(releases[0].target_commitish, new Date())
30
+ : [];
31
+ console.log(` ✓ Found ${commits.length} commits`);
32
+ const issues = await client.getIssues(['incident', 'production-bug'], since);
33
+ console.log(` ✓ Found ${issues.length} incidents`);
34
+ // Calculate metrics
35
+ console.log('\n🔢 Calculating DORA metrics...');
36
+ const deploymentFrequency = calculateDeploymentFrequency(releases);
37
+ console.log(` ✓ Deployment Frequency: ${deploymentFrequency.value} ${deploymentFrequency.unit} (${deploymentFrequency.tier})`);
38
+ const leadTime = calculateLeadTime(releases, commits);
39
+ console.log(` ✓ Lead Time: ${leadTime.value} ${leadTime.unit} (${leadTime.tier})`);
40
+ const changeFailureRate = calculateChangeFailureRate(releases, issues);
41
+ console.log(` ✓ Change Failure Rate: ${changeFailureRate.value}% (${changeFailureRate.tier})`);
42
+ const mttr = calculateMTTR(issues);
43
+ console.log(` ✓ MTTR: ${mttr.value} ${mttr.unit} (${mttr.tier})`);
44
+ return {
45
+ timestamp: new Date().toISOString(),
46
+ metrics: {
47
+ deploymentFrequency,
48
+ leadTime,
49
+ changeFailureRate,
50
+ mttr,
51
+ },
52
+ };
53
+ }
54
+ /**
55
+ * Write metrics to JSON file
56
+ *
57
+ * @param metrics - DORA metrics
58
+ * @param filePath - Output file path
59
+ */
60
+ export function writeMetricsJSON(metrics, filePath) {
61
+ // Ensure directory exists
62
+ const dir = path.dirname(filePath);
63
+ if (!fs.existsSync(dir)) {
64
+ fs.mkdirSync(dir, { recursive: true });
65
+ }
66
+ // Write JSON with pretty formatting
67
+ const json = JSON.stringify(metrics, null, 2);
68
+ fs.writeFileSync(filePath, json, 'utf-8');
69
+ console.log(`\n✅ Metrics written to ${filePath}`);
70
+ }
71
+ /**
72
+ * CLI Entry Point
73
+ *
74
+ * Run with: npm run metrics:dora
75
+ * Or: ts-node src/metrics/dora-calculator.ts
76
+ */
77
+ async function main() {
78
+ try {
79
+ // Parse GitHub config from environment
80
+ const token = process.env.GITHUB_TOKEN;
81
+ if (!token) {
82
+ throw new Error('GITHUB_TOKEN environment variable is required');
83
+ }
84
+ const repository = process.env.GITHUB_REPOSITORY || 'anton-abyzov/specweave';
85
+ const [owner, repo] = repository.split('/');
86
+ const config = { token, owner, repo };
87
+ // Calculate metrics
88
+ const client = new GitHubClient(config);
89
+ const metrics = await calculateDORAMetrics(client);
90
+ // Write to file
91
+ const outputPath = path.join(process.cwd(), 'metrics', 'dora-latest.json');
92
+ writeMetricsJSON(metrics, outputPath);
93
+ console.log('\n🎉 DORA metrics calculation complete!');
94
+ process.exit(0);
95
+ }
96
+ catch (error) {
97
+ console.error('\n❌ Error calculating DORA metrics:');
98
+ console.error(error);
99
+ process.exit(1);
100
+ }
101
+ }
102
+ // ESM module entry point (always run when executed)
103
+ main();
104
+ //# sourceMappingURL=dora-calculator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dora-calculator.js","sourceRoot":"","sources":["../../src/metrics/dora-calculator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ /**
2
+ * GitHub API Client
3
+ *
4
+ * Wrapper around Octokit for fetching DORA metrics data
5
+ * Handles authentication, rate limiting, and error handling
6
+ */
7
+ import { Release, Commit, Issue, GitHubConfig } from './types';
8
+ /**
9
+ * GitHub API Client for DORA Metrics
10
+ */
11
+ export declare class GitHubClient {
12
+ private octokit;
13
+ private owner;
14
+ private repo;
15
+ constructor(config: GitHubConfig);
16
+ /**
17
+ * Get releases from last N days
18
+ *
19
+ * @param since - Date to fetch releases from
20
+ * @returns Array of releases
21
+ */
22
+ getReleases(since: Date): Promise<Release[]>;
23
+ /**
24
+ * Get commits for a specific SHA range
25
+ *
26
+ * @param sha - Commit SHA to start from
27
+ * @param until - Date to fetch commits until
28
+ * @returns Array of commits
29
+ */
30
+ getCommits(sha: string, until: Date): Promise<Commit[]>;
31
+ /**
32
+ * Get issues with specific labels
33
+ *
34
+ * @param labels - Array of label names to filter by
35
+ * @param since - Date to fetch issues from
36
+ * @returns Array of issues
37
+ */
38
+ getIssues(labels: string[], since: Date): Promise<Issue[]>;
39
+ /**
40
+ * Handle GitHub API rate limit errors
41
+ *
42
+ * Implements exponential backoff:
43
+ * 1. Check X-RateLimit-Reset header
44
+ * 2. Wait until reset time (max 1 minute)
45
+ * 3. Retry request
46
+ *
47
+ * @param error - GitHub API error
48
+ */
49
+ private handleRateLimit;
50
+ }
51
+ //# sourceMappingURL=github-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-client.d.ts","sourceRoot":"","sources":["../../src/metrics/github-client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAS/D;;GAEG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,KAAK,CAAS;IACtB,OAAO,CAAC,IAAI,CAAS;gBAET,MAAM,EAAE,YAAY;IAQhC;;;;;OAKG;IACG,WAAW,CAAC,KAAK,EAAE,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;IAsBlD;;;;;;OAMG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAoB7D;;;;;;OAMG;IACG,SAAS,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC;IAqBhE;;;;;;;;;OASG;YACW,eAAe;CAiB9B"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * GitHub API Client
3
+ *
4
+ * Wrapper around Octokit for fetching DORA metrics data
5
+ * Handles authentication, rate limiting, and error handling
6
+ */
7
+ import { Octokit } from '@octokit/rest';
8
+ /**
9
+ * Sleep utility for exponential backoff
10
+ */
11
+ function sleep(ms) {
12
+ return new Promise(resolve => setTimeout(resolve, ms));
13
+ }
14
+ /**
15
+ * GitHub API Client for DORA Metrics
16
+ */
17
+ export class GitHubClient {
18
+ constructor(config) {
19
+ this.octokit = new Octokit({
20
+ auth: config.token,
21
+ });
22
+ this.owner = config.owner;
23
+ this.repo = config.repo;
24
+ }
25
+ /**
26
+ * Get releases from last N days
27
+ *
28
+ * @param since - Date to fetch releases from
29
+ * @returns Array of releases
30
+ */
31
+ async getReleases(since) {
32
+ try {
33
+ const response = await this.octokit.rest.repos.listReleases({
34
+ owner: this.owner,
35
+ repo: this.repo,
36
+ per_page: 100,
37
+ });
38
+ // Filter by date
39
+ return response.data.filter(release => {
40
+ const publishedAt = new Date(release.published_at);
41
+ return publishedAt >= since;
42
+ });
43
+ }
44
+ catch (error) {
45
+ if (error.status === 403) {
46
+ await this.handleRateLimit(error);
47
+ return this.getReleases(since); // Retry
48
+ }
49
+ throw error;
50
+ }
51
+ }
52
+ /**
53
+ * Get commits for a specific SHA range
54
+ *
55
+ * @param sha - Commit SHA to start from
56
+ * @param until - Date to fetch commits until
57
+ * @returns Array of commits
58
+ */
59
+ async getCommits(sha, until) {
60
+ try {
61
+ const response = await this.octokit.rest.repos.listCommits({
62
+ owner: this.owner,
63
+ repo: this.repo,
64
+ sha,
65
+ per_page: 100,
66
+ until: until.toISOString(),
67
+ });
68
+ return response.data;
69
+ }
70
+ catch (error) {
71
+ if (error.status === 403) {
72
+ await this.handleRateLimit(error);
73
+ return this.getCommits(sha, until); // Retry
74
+ }
75
+ throw error;
76
+ }
77
+ }
78
+ /**
79
+ * Get issues with specific labels
80
+ *
81
+ * @param labels - Array of label names to filter by
82
+ * @param since - Date to fetch issues from
83
+ * @returns Array of issues
84
+ */
85
+ async getIssues(labels, since) {
86
+ try {
87
+ const response = await this.octokit.rest.issues.listForRepo({
88
+ owner: this.owner,
89
+ repo: this.repo,
90
+ labels: labels.join(','),
91
+ state: 'all', // Include open and closed
92
+ per_page: 100,
93
+ since: since.toISOString(),
94
+ });
95
+ return response.data;
96
+ }
97
+ catch (error) {
98
+ if (error.status === 403) {
99
+ await this.handleRateLimit(error);
100
+ return this.getIssues(labels, since); // Retry
101
+ }
102
+ throw error;
103
+ }
104
+ }
105
+ /**
106
+ * Handle GitHub API rate limit errors
107
+ *
108
+ * Implements exponential backoff:
109
+ * 1. Check X-RateLimit-Reset header
110
+ * 2. Wait until reset time (max 1 minute)
111
+ * 3. Retry request
112
+ *
113
+ * @param error - GitHub API error
114
+ */
115
+ async handleRateLimit(error) {
116
+ const resetTime = error.response?.headers?.['x-ratelimit-reset'];
117
+ if (resetTime) {
118
+ const resetDate = new Date(parseInt(resetTime) * 1000);
119
+ const now = new Date();
120
+ const waitMs = resetDate.getTime() - now.getTime();
121
+ if (waitMs > 0) {
122
+ const waitSeconds = Math.min(waitMs / 1000, 60); // Max 1 minute
123
+ console.log(`⏳ GitHub API rate limited. Waiting ${waitSeconds}s...`);
124
+ await sleep(waitMs);
125
+ }
126
+ }
127
+ else {
128
+ // Fallback: wait 10 seconds
129
+ await sleep(10000);
130
+ }
131
+ }
132
+ }
133
+ //# sourceMappingURL=github-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-client.js","sourceRoot":"","sources":["../../src/metrics/github-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,112 @@
1
+ /**
2
+ * DORA Metrics Types
3
+ *
4
+ * TypeScript interfaces for DORA metrics calculation
5
+ * Based on DevOps Research and Assessment (DORA) benchmarks
6
+ *
7
+ * @see https://dora.dev/
8
+ */
9
+ /**
10
+ * DORA Performance Tier
11
+ * Based on industry benchmarks from DORA research
12
+ */
13
+ export type DORAType = 'Elite' | 'High' | 'Medium' | 'Low' | 'N/A';
14
+ /**
15
+ * GitHub Release (from REST API)
16
+ */
17
+ export interface Release {
18
+ id: number;
19
+ tag_name: string;
20
+ name: string;
21
+ created_at: string;
22
+ published_at: string;
23
+ target_commitish: string;
24
+ }
25
+ /**
26
+ * GitHub Commit (from REST API)
27
+ */
28
+ export interface Commit {
29
+ sha: string;
30
+ commit: {
31
+ author: {
32
+ name: string;
33
+ date: string;
34
+ };
35
+ };
36
+ }
37
+ /**
38
+ * GitHub Issue (from REST API)
39
+ */
40
+ export interface Issue {
41
+ id: number;
42
+ number: number;
43
+ title: string;
44
+ state: 'open' | 'closed';
45
+ labels: Array<{
46
+ name: string;
47
+ }>;
48
+ created_at: string;
49
+ closed_at: string | null;
50
+ }
51
+ /**
52
+ * Deployment Frequency Metric
53
+ */
54
+ export interface DeploymentFrequencyMetric {
55
+ value: number;
56
+ unit: 'deploys/month' | 'deploys/week';
57
+ tier: DORAType;
58
+ description: string;
59
+ }
60
+ /**
61
+ * Lead Time for Changes Metric
62
+ */
63
+ export interface LeadTimeMetric {
64
+ value: number;
65
+ unit: 'hours' | 'days';
66
+ tier: DORAType;
67
+ p50: number;
68
+ p90: number;
69
+ }
70
+ /**
71
+ * Change Failure Rate Metric
72
+ */
73
+ export interface ChangeFailureRateMetric {
74
+ value: number;
75
+ unit: 'percentage';
76
+ tier: DORAType;
77
+ failedReleases: number;
78
+ totalReleases: number;
79
+ }
80
+ /**
81
+ * Mean Time to Recovery (MTTR) Metric
82
+ */
83
+ export interface MTTRMetric {
84
+ value: number;
85
+ unit: 'minutes' | 'hours';
86
+ tier: DORAType;
87
+ p50: number;
88
+ p90: number;
89
+ }
90
+ /**
91
+ * Complete DORA Metrics Output
92
+ *
93
+ * This is the JSON structure written to metrics/dora-latest.json
94
+ */
95
+ export interface DORAMetrics {
96
+ timestamp: string;
97
+ metrics: {
98
+ deploymentFrequency: DeploymentFrequencyMetric;
99
+ leadTime: LeadTimeMetric;
100
+ changeFailureRate: ChangeFailureRateMetric;
101
+ mttr: MTTRMetric;
102
+ };
103
+ }
104
+ /**
105
+ * GitHub API Client Configuration
106
+ */
107
+ export interface GitHubConfig {
108
+ token: string;
109
+ owner: string;
110
+ repo: string;
111
+ }
112
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/metrics/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,KAAK,CAAC;AAEnE;;GAEG;AACH,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,MAAM;IACrB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE;QACN,MAAM,EAAE;YACN,IAAI,EAAE,MAAM,CAAC;YACb,IAAI,EAAE,MAAM,CAAC;SACd,CAAC;KACH,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,GAAG,QAAQ,CAAC;IACzB,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,eAAe,GAAG,cAAc,CAAC;IACvC,IAAI,EAAE,QAAQ,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,OAAO,GAAG,MAAM,CAAC;IACvB,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;IACnB,IAAI,EAAE,QAAQ,CAAC;IACf,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,EAAE,MAAM,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC;IAC1B,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;GAIG;AACH,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE;QACP,mBAAmB,EAAE,yBAAyB,CAAC;QAC/C,QAAQ,EAAE,cAAc,CAAC;QACzB,iBAAiB,EAAE,uBAAuB,CAAC;QAC3C,IAAI,EAAE,UAAU,CAAC;KAClB,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;CACd"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * DORA Metrics Types
3
+ *
4
+ * TypeScript interfaces for DORA metrics calculation
5
+ * Based on DevOps Research and Assessment (DORA) benchmarks
6
+ *
7
+ * @see https://dora.dev/
8
+ */
9
+ export {};
10
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/metrics/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}