stackvitals 0.1.0__py3-none-any.whl

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 (465) hide show
  1. mergescout/__init__.py +1 -0
  2. mergescout/archive/__init__.py +0 -0
  3. mergescout/archive/__main__.py +30 -0
  4. mergescout/archive/convert.py +83 -0
  5. mergescout/archive/events.py +55 -0
  6. mergescout/archive/manifest.py +45 -0
  7. mergescout/archive/stream.py +83 -0
  8. mergescout/bench/__init__.py +1 -0
  9. mergescout/bench/__main__.py +135 -0
  10. mergescout/bench/ci.py +257 -0
  11. mergescout/bench/deploys.py +115 -0
  12. mergescout/bench/matched.py +22 -0
  13. mergescout/bench/prior.py +42 -0
  14. mergescout/bench/report.py +230 -0
  15. mergescout/bench/shared.py +112 -0
  16. mergescout/bench/stars.py +57 -0
  17. mergescout/cli.py +89 -0
  18. mergescout/config.py +35 -0
  19. mergescout/crawl/__init__.py +0 -0
  20. mergescout/crawl/__main__.py +97 -0
  21. mergescout/crawl/chain.py +34 -0
  22. mergescout/crawl/fetch.py +146 -0
  23. mergescout/crawl/outcomes.py +69 -0
  24. mergescout/crawl/queries.py +250 -0
  25. mergescout/crawl/runner.py +176 -0
  26. mergescout/crawl/seed.py +77 -0
  27. mergescout/crawl/state.py +169 -0
  28. mergescout/crawl/writer.py +87 -0
  29. mergescout/discover/__init__.py +0 -0
  30. mergescout/discover/__main__.py +58 -0
  31. mergescout/discover/sweep.py +286 -0
  32. mergescout/github/__init__.py +0 -0
  33. mergescout/github/graphql.py +202 -0
  34. mergescout/github/identities.py +35 -0
  35. mergescout/github/releases.py +137 -0
  36. mergescout/labels.py +20 -0
  37. mergescout/mcp_server.py +228 -0
  38. mergescout/measure/__init__.py +0 -0
  39. mergescout/measure/__main__.py +75 -0
  40. mergescout/measure/api_cost.py +91 -0
  41. mergescout/measure/count_repos.py +30 -0
  42. mergescout/measure/jsonl.py +14 -0
  43. mergescout/measure/report.py +56 -0
  44. mergescout/measure/sample.py +37 -0
  45. mergescout/owners.py +22 -0
  46. mergescout/setup_check.py +64 -0
  47. mergescout/signals/__init__.py +0 -0
  48. mergescout/signals/__main__.py +96 -0
  49. mergescout/signals/bump_ledger.py +258 -0
  50. mergescout/signals/bumps.py +104 -0
  51. mergescout/signals/check.py +141 -0
  52. mergescout/signals/community_bench.py +149 -0
  53. mergescout/signals/delivery_bench.py +103 -0
  54. mergescout/signals/deps_map.py +261 -0
  55. mergescout/signals/deps_trends.py +117 -0
  56. mergescout/signals/evidence.py +94 -0
  57. mergescout/signals/exploits.py +43 -0
  58. mergescout/signals/flow_bench.py +258 -0
  59. mergescout/signals/identity.py +73 -0
  60. mergescout/signals/issues.py +76 -0
  61. mergescout/signals/labels.py +79 -0
  62. mergescout/signals/osv.py +232 -0
  63. mergescout/signals/owners_watch.py +80 -0
  64. mergescout/signals/repo_stats.py +96 -0
  65. mergescout/signals/rules.py +70 -0
  66. mergescout/signals/silver.py +33 -0
  67. mergescout/signals/top_packages.py +26 -0
  68. mergescout/signals/triage.py +71 -0
  69. mergescout/signals/triage_math.py +120 -0
  70. mergescout/signals/walls.py +91 -0
  71. mergescout/snapshot/__init__.py +0 -0
  72. mergescout/snapshot/__main__.py +215 -0
  73. mergescout/snapshot/build.py +147 -0
  74. mergescout/snapshot/publish.py +70 -0
  75. mergescout/snapshot/schema.py +34 -0
  76. mergescout/snapshot/score.py +30 -0
  77. mergescout/store/__init__.py +0 -0
  78. mergescout/store/__main__.py +46 -0
  79. mergescout/store/sync.py +148 -0
  80. mergescout/timeutil.py +11 -0
  81. mergescout/tool/__init__.py +0 -0
  82. mergescout/tool/action_pack.py +62 -0
  83. mergescout/tool/live.py +201 -0
  84. mergescout/tool/queries.py +293 -0
  85. mergescout/tool/refs.py +31 -0
  86. mergescout/tool/store.py +129 -0
  87. mergescout/tool/tracking.py +83 -0
  88. stackvitals/__init__.py +2 -0
  89. stackvitals/__main__.py +4 -0
  90. stackvitals/ci/__init__.py +1 -0
  91. stackvitals/ci/action.py +574 -0
  92. stackvitals/ci/analyze.py +577 -0
  93. stackvitals/ci/api.py +218 -0
  94. stackvitals/ci/automation.py +212 -0
  95. stackvitals/ci/bench.py +195 -0
  96. stackvitals/ci/burnin.py +102 -0
  97. stackvitals/ci/cli.py +570 -0
  98. stackvitals/ci/collect.py +239 -0
  99. stackvitals/ci/cost.py +107 -0
  100. stackvitals/ci/coverage.py +155 -0
  101. stackvitals/ci/feedback.py +699 -0
  102. stackvitals/ci/fingerprint.py +220 -0
  103. stackvitals/ci/gitlab.py +121 -0
  104. stackvitals/ci/gitlab_action.py +125 -0
  105. stackvitals/ci/impact.py +125 -0
  106. stackvitals/ci/investigate.py +59 -0
  107. stackvitals/ci/kinds.py +52 -0
  108. stackvitals/ci/monitors.py +105 -0
  109. stackvitals/ci/owners.py +116 -0
  110. stackvitals/ci/quarantine_runtime.py +90 -0
  111. stackvitals/ci/report.py +435 -0
  112. stackvitals/ci/retry.py +67 -0
  113. stackvitals/ci/selfheal.py +102 -0
  114. stackvitals/ci/shards.py +120 -0
  115. stackvitals/ci/share.py +59 -0
  116. stackvitals/ci/store.py +93 -0
  117. stackvitals/ci/testreports.py +351 -0
  118. stackvitals/ci/tickets.py +106 -0
  119. stackvitals/ci/track_record.json +11 -0
  120. stackvitals/ci/triage.py +130 -0
  121. stackvitals/ci/triggers.py +147 -0
  122. stackvitals/ci/upload.py +85 -0
  123. stackvitals/ci/validate.py +91 -0
  124. stackvitals/cli.py +111 -0
  125. stackvitals/codeowners.py +69 -0
  126. stackvitals/community/__init__.py +0 -0
  127. stackvitals/community/action.py +140 -0
  128. stackvitals/community/affiliation.py +51 -0
  129. stackvitals/community/analyze.py +507 -0
  130. stackvitals/community/build.py +56 -0
  131. stackvitals/community/chaoss.py +70 -0
  132. stackvitals/community/cli.py +79 -0
  133. stackvitals/community/collect.py +240 -0
  134. stackvitals/community/context.py +54 -0
  135. stackvitals/community/report.py +250 -0
  136. stackvitals/connectors/__init__.py +244 -0
  137. stackvitals/connectors/ai_spend.py +190 -0
  138. stackvitals/connectors/base.py +82 -0
  139. stackvitals/connectors/check.py +686 -0
  140. stackvitals/connectors/copilot.py +104 -0
  141. stackvitals/connectors/discord.py +103 -0
  142. stackvitals/connectors/discourse.py +117 -0
  143. stackvitals/connectors/incident_io.py +106 -0
  144. stackvitals/connectors/jira.py +210 -0
  145. stackvitals/connectors/linear.py +140 -0
  146. stackvitals/connectors/pagerduty.py +96 -0
  147. stackvitals/connectors/slack.py +110 -0
  148. stackvitals/connectors/sonar.py +77 -0
  149. stackvitals/connectors/store.py +120 -0
  150. stackvitals/connectors/tracker.py +108 -0
  151. stackvitals/connectors/writeback.py +105 -0
  152. stackvitals/contribute/__init__.py +1 -0
  153. stackvitals/contribute/brief.py +297 -0
  154. stackvitals/contribute/cli.py +64 -0
  155. stackvitals/core/__init__.py +1 -0
  156. stackvitals/core/actors.py +103 -0
  157. stackvitals/core/agent_ledger.py +120 -0
  158. stackvitals/core/agreements.py +95 -0
  159. stackvitals/core/ai_outcomes.py +276 -0
  160. stackvitals/core/alerts.py +224 -0
  161. stackvitals/core/appdata.py +112 -0
  162. stackvitals/core/bucket.py +190 -0
  163. stackvitals/core/bugs.py +43 -0
  164. stackvitals/core/calendar.py +34 -0
  165. stackvitals/core/capex.py +57 -0
  166. stackvitals/core/change_risk.py +181 -0
  167. stackvitals/core/changes.py +133 -0
  168. stackvitals/core/chat.py +143 -0
  169. stackvitals/core/config.py +373 -0
  170. stackvitals/core/dataflow.py +168 -0
  171. stackvitals/core/decisions.py +275 -0
  172. stackvitals/core/delivery.py +954 -0
  173. stackvitals/core/delivery_peers.py +98 -0
  174. stackvitals/core/delivery_report.py +429 -0
  175. stackvitals/core/deliverycli.py +147 -0
  176. stackvitals/core/devlake_dora.sql +485 -0
  177. stackvitals/core/digest.py +333 -0
  178. stackvitals/core/explaincli.py +107 -0
  179. stackvitals/core/explore.py +296 -0
  180. stackvitals/core/export.py +342 -0
  181. stackvitals/core/exportcli.py +117 -0
  182. stackvitals/core/findings.py +350 -0
  183. stackvitals/core/health.py +94 -0
  184. stackvitals/core/identity.py +82 -0
  185. stackvitals/core/insights.py +365 -0
  186. stackvitals/core/insightscli.py +43 -0
  187. stackvitals/core/installdoc.py +69 -0
  188. stackvitals/core/investment.py +187 -0
  189. stackvitals/core/joins.py +43 -0
  190. stackvitals/core/llmsdoc.py +40 -0
  191. stackvitals/core/merge_queue.py +70 -0
  192. stackvitals/core/metrics.py +109 -0
  193. stackvitals/core/model.py +285 -0
  194. stackvitals/core/projectcli.py +66 -0
  195. stackvitals/core/propose.py +86 -0
  196. stackvitals/core/pulse.py +85 -0
  197. stackvitals/core/recorded.py +145 -0
  198. stackvitals/core/releases.py +39 -0
  199. stackvitals/core/requests.py +528 -0
  200. stackvitals/core/resync.py +35 -0
  201. stackvitals/core/schema.py +205 -0
  202. stackvitals/core/services.py +203 -0
  203. stackvitals/core/settings.py +96 -0
  204. stackvitals/core/sqlcli.py +111 -0
  205. stackvitals/core/stats.py +222 -0
  206. stackvitals/core/store.py +125 -0
  207. stackvitals/core/summary.py +104 -0
  208. stackvitals/core/time.py +29 -0
  209. stackvitals/core/tomledit.py +149 -0
  210. stackvitals/core/uicli.py +138 -0
  211. stackvitals/core/webapp.py +79 -0
  212. stackvitals/core/what_changed.py +76 -0
  213. stackvitals/core/workspace.py +194 -0
  214. stackvitals/deps/__init__.py +1 -0
  215. stackvitals/deps/action.py +299 -0
  216. stackvitals/deps/actions_vulns.py +89 -0
  217. stackvitals/deps/cli.py +77 -0
  218. stackvitals/deps/dossier.py +341 -0
  219. stackvitals/deps/evidence.py +44 -0
  220. stackvitals/deps/fixplan.py +40 -0
  221. stackvitals/deps/guarddog.py +32 -0
  222. stackvitals/deps/hygiene.py +47 -0
  223. stackvitals/deps/imports.py +113 -0
  224. stackvitals/deps/lockfiles.py +198 -0
  225. stackvitals/deps/lookalike.py +80 -0
  226. stackvitals/deps/reach.py +59 -0
  227. stackvitals/deps/release.py +110 -0
  228. stackvitals/deps/runtimes.py +161 -0
  229. stackvitals/deps/supply.py +454 -0
  230. stackvitals/deps/vulns.py +588 -0
  231. stackvitals/editors/__init__.py +40 -0
  232. stackvitals/editors/vscode/extension.js +101 -0
  233. stackvitals/editors/vscode/marks.js +92 -0
  234. stackvitals/editors/vscode/package.json +26 -0
  235. stackvitals/flow/__init__.py +1 -0
  236. stackvitals/flow/action.py +178 -0
  237. stackvitals/flow/analyze.py +418 -0
  238. stackvitals/flow/automate.py +72 -0
  239. stackvitals/flow/build.py +46 -0
  240. stackvitals/flow/cli.py +93 -0
  241. stackvitals/flow/code_hosts.py +146 -0
  242. stackvitals/flow/collect.py +451 -0
  243. stackvitals/flow/gitlab_mr.py +75 -0
  244. stackvitals/flow/knowledge.py +202 -0
  245. stackvitals/flow/peers.py +90 -0
  246. stackvitals/flow/preflight.py +210 -0
  247. stackvitals/flow/report.py +253 -0
  248. stackvitals/flow/rules.py +135 -0
  249. stackvitals/flow/store.py +108 -0
  250. stackvitals/flow/survival.py +84 -0
  251. stackvitals/flow/triage.py +62 -0
  252. stackvitals/mcp_server.py +670 -0
  253. stackvitals/portal/__init__.py +0 -0
  254. stackvitals/portal/action.py +205 -0
  255. stackvitals/portal/batch.py +80 -0
  256. stackvitals/portal/campaigns.py +104 -0
  257. stackvitals/portal/catalog.py +104 -0
  258. stackvitals/portal/checks.py +63 -0
  259. stackvitals/portal/cli.py +172 -0
  260. stackvitals/portal/descriptor.py +105 -0
  261. stackvitals/portal/export.py +43 -0
  262. stackvitals/portal/github.py +48 -0
  263. stackvitals/portal/golden.py +95 -0
  264. stackvitals/portal/history.py +30 -0
  265. stackvitals/portal/inventory.py +264 -0
  266. stackvitals/portal/owners.py +78 -0
  267. stackvitals/portal/pages.py +153 -0
  268. stackvitals/portal/rollup.py +32 -0
  269. stackvitals/portal/scorecard.py +366 -0
  270. stackvitals/security/__init__.py +2 -0
  271. stackvitals/security/probes.py +154 -0
  272. stackvitals/security/repo_checks.py +132 -0
  273. stackvitals/security/workflows.py +111 -0
  274. stackvitals/shell.py +107 -0
  275. stackvitals/site.py +51 -0
  276. stackvitals/web/app/LICENSES.md +428 -0
  277. stackvitals/web/app/boot.js +1 -0
  278. stackvitals/web/app/chunks/AddRepo-KRPZXWCY.js +1 -0
  279. stackvitals/web/app/chunks/SetupRunning-XWFQAKRZ.js +1 -0
  280. stackvitals/web/app/chunks/accuracy-data-OQTDXI7Y.js +1 -0
  281. stackvitals/web/app/chunks/agents-data-BAL6QAOF.js +11 -0
  282. stackvitals/web/app/chunks/chunk-24LFKFZ6.js +1 -0
  283. stackvitals/web/app/chunks/chunk-3G4SQNUC.js +1 -0
  284. stackvitals/web/app/chunks/chunk-3IXWEOIJ.js +154 -0
  285. stackvitals/web/app/chunks/chunk-3ROQFHPV.js +1 -0
  286. stackvitals/web/app/chunks/chunk-45PGAQRO.js +8 -0
  287. stackvitals/web/app/chunks/chunk-4H53OYLG.js +1 -0
  288. stackvitals/web/app/chunks/chunk-4LUI7O5P.js +1 -0
  289. stackvitals/web/app/chunks/chunk-4SQPQ5TB.js +1 -0
  290. stackvitals/web/app/chunks/chunk-4WKQTWUC.js +2 -0
  291. stackvitals/web/app/chunks/chunk-576YHDEK.js +8 -0
  292. stackvitals/web/app/chunks/chunk-6BDBXA6V.js +1 -0
  293. stackvitals/web/app/chunks/chunk-6RLVD2DT.js +1 -0
  294. stackvitals/web/app/chunks/chunk-763NH7PP.js +1 -0
  295. stackvitals/web/app/chunks/chunk-76WAVKUG.js +1 -0
  296. stackvitals/web/app/chunks/chunk-7II2BD5F.js +1 -0
  297. stackvitals/web/app/chunks/chunk-7TJCBOAY.js +1 -0
  298. stackvitals/web/app/chunks/chunk-ASYNLVOP.js +1 -0
  299. stackvitals/web/app/chunks/chunk-CTKDYZMG.js +1 -0
  300. stackvitals/web/app/chunks/chunk-CVB26NMC.js +1 -0
  301. stackvitals/web/app/chunks/chunk-G7NGB5UX.js +1 -0
  302. stackvitals/web/app/chunks/chunk-GPVLJRZD.js +1 -0
  303. stackvitals/web/app/chunks/chunk-GQYFN4PE.js +75 -0
  304. stackvitals/web/app/chunks/chunk-GT4EAKAO.js +2 -0
  305. stackvitals/web/app/chunks/chunk-IYMBFPCV.js +1 -0
  306. stackvitals/web/app/chunks/chunk-LAAGCPU3.js +1 -0
  307. stackvitals/web/app/chunks/chunk-MAPYGK3P.js +1 -0
  308. stackvitals/web/app/chunks/chunk-P5TXDD45.js +1 -0
  309. stackvitals/web/app/chunks/chunk-PABICGBL.js +1 -0
  310. stackvitals/web/app/chunks/chunk-RPXHAG6F.js +1 -0
  311. stackvitals/web/app/chunks/chunk-RQZPSJ2Y.js +1 -0
  312. stackvitals/web/app/chunks/chunk-S2ZBMEVA.js +1 -0
  313. stackvitals/web/app/chunks/chunk-S654BBEP.js +6 -0
  314. stackvitals/web/app/chunks/chunk-T7QVTNXF.js +1 -0
  315. stackvitals/web/app/chunks/chunk-THFUOCPC.js +273 -0
  316. stackvitals/web/app/chunks/chunk-TO4VVRZ7.js +1 -0
  317. stackvitals/web/app/chunks/chunk-VQ5YXO54.js +1 -0
  318. stackvitals/web/app/chunks/chunk-VWKSMFWJ.js +1 -0
  319. stackvitals/web/app/chunks/chunk-Y6LUXDM6.js +1 -0
  320. stackvitals/web/app/chunks/chunk-YTANGYYH.js +1 -0
  321. stackvitals/web/app/chunks/connect-KONYWYTT.js +1 -0
  322. stackvitals/web/app/chunks/connections-data-2DYS4UVW.js +32 -0
  323. stackvitals/web/app/chunks/logos-N5IINUAM.js +1 -0
  324. stackvitals/web/app/chunks/more-KMJMJQD3.js +10 -0
  325. stackvitals/web/app/chunks/more-PC6FVS3P.js +1 -0
  326. stackvitals/web/app/chunks/more-RCIVCUDE.js +2 -0
  327. stackvitals/web/app/chunks/more-ZKKRY6NO.css +1 -0
  328. stackvitals/web/app/chunks/sealbox-35YL4EUH.js +3 -0
  329. stackvitals/web/app/chunks/session-DYYTOE2K.js +1 -0
  330. stackvitals/web/app/chunks/settingsApply-2HRJEZYM.js +1 -0
  331. stackvitals/web/app/chunks/settingsReview-GX2FZQ4M.js +3 -0
  332. stackvitals/web/app/chunks/uPlot.esm-OIWT3AHJ.js +3 -0
  333. stackvitals/web/app/demo/ci/impact.json +1 -0
  334. stackvitals/web/app/demo/ci/quarantine.json +1 -0
  335. stackvitals/web/app/demo/ci/tickets.json +1 -0
  336. stackvitals/web/app/demo/mobile/alerts.json +1 -0
  337. stackvitals/web/app/demo/mobile/app.json +1 -0
  338. stackvitals/web/app/demo/mobile/community.json +1 -0
  339. stackvitals/web/app/demo/mobile/connectors.json +1 -0
  340. stackvitals/web/app/demo/mobile/data.json +1 -0
  341. stackvitals/web/app/demo/mobile/decisions.json +1 -0
  342. stackvitals/web/app/demo/mobile/delivery.json +1 -0
  343. stackvitals/web/app/demo/mobile/deps.json +1 -0
  344. stackvitals/web/app/demo/mobile/flow.json +1 -0
  345. stackvitals/web/app/demo/mobile/health.json +1 -0
  346. stackvitals/web/app/demo/mobile/insights.json +1 -0
  347. stackvitals/web/app/demo/mobile/pulse.json +1 -0
  348. stackvitals/web/app/demo/mobile/security.json +1 -0
  349. stackvitals/web/app/demo/mobile/summary/ci_jobs.jsonl +5 -0
  350. stackvitals/web/app/demo/mobile/summary/devlake_project_pr_metrics.jsonl +14 -0
  351. stackvitals/web/app/demo/mobile/summary/devlake_pull_requests.jsonl +14 -0
  352. stackvitals/web/app/demo/mobile/summary/manifest.json +1 -0
  353. stackvitals/web/app/demo/mobile/summary/prs.jsonl +19 -0
  354. stackvitals/web/app/demo/mobile/summary/tests.jsonl +1 -0
  355. stackvitals/web/app/demo/mobile/supply.json +1 -0
  356. stackvitals/web/app/demo/mobile/vulns.json +1 -0
  357. stackvitals/web/app/demo/payments-api/alerts.json +1 -0
  358. stackvitals/web/app/demo/payments-api/app.json +1 -0
  359. stackvitals/web/app/demo/payments-api/community.json +1 -0
  360. stackvitals/web/app/demo/payments-api/connectors.json +1 -0
  361. stackvitals/web/app/demo/payments-api/data.json +1 -0
  362. stackvitals/web/app/demo/payments-api/decisions.json +1 -0
  363. stackvitals/web/app/demo/payments-api/delivery.json +1 -0
  364. stackvitals/web/app/demo/payments-api/deps.json +1 -0
  365. stackvitals/web/app/demo/payments-api/flow.json +1 -0
  366. stackvitals/web/app/demo/payments-api/health.json +1 -0
  367. stackvitals/web/app/demo/payments-api/insights.json +1 -0
  368. stackvitals/web/app/demo/payments-api/pulse.json +1 -0
  369. stackvitals/web/app/demo/payments-api/security.json +1 -0
  370. stackvitals/web/app/demo/payments-api/summary/ci_jobs.jsonl +5 -0
  371. stackvitals/web/app/demo/payments-api/summary/devlake_project_pr_metrics.jsonl +14 -0
  372. stackvitals/web/app/demo/payments-api/summary/devlake_pull_requests.jsonl +14 -0
  373. stackvitals/web/app/demo/payments-api/summary/manifest.json +1 -0
  374. stackvitals/web/app/demo/payments-api/summary/prs.jsonl +22 -0
  375. stackvitals/web/app/demo/payments-api/summary/tests.jsonl +3 -0
  376. stackvitals/web/app/demo/payments-api/supply.json +1 -0
  377. stackvitals/web/app/demo/payments-api/vulns.json +1 -0
  378. stackvitals/web/app/demo/portal.json +1 -0
  379. stackvitals/web/app/demo/settings.json +1 -0
  380. stackvitals/web/app/demo/web-app/alerts.json +1 -0
  381. stackvitals/web/app/demo/web-app/app.json +1 -0
  382. stackvitals/web/app/demo/web-app/community.json +1 -0
  383. stackvitals/web/app/demo/web-app/connectors.json +1 -0
  384. stackvitals/web/app/demo/web-app/data.json +1 -0
  385. stackvitals/web/app/demo/web-app/decisions.json +1 -0
  386. stackvitals/web/app/demo/web-app/delivery.json +1 -0
  387. stackvitals/web/app/demo/web-app/deps.json +1 -0
  388. stackvitals/web/app/demo/web-app/flow.json +1 -0
  389. stackvitals/web/app/demo/web-app/health.json +1 -0
  390. stackvitals/web/app/demo/web-app/insights.json +1 -0
  391. stackvitals/web/app/demo/web-app/pulse.json +1 -0
  392. stackvitals/web/app/demo/web-app/security.json +1 -0
  393. stackvitals/web/app/demo/web-app/summary/ci_jobs.jsonl +5 -0
  394. stackvitals/web/app/demo/web-app/summary/devlake_project_pr_metrics.jsonl +14 -0
  395. stackvitals/web/app/demo/web-app/summary/devlake_pull_requests.jsonl +14 -0
  396. stackvitals/web/app/demo/web-app/summary/manifest.json +1 -0
  397. stackvitals/web/app/demo/web-app/summary/prs.jsonl +18 -0
  398. stackvitals/web/app/demo/web-app/summary/tests.jsonl +2 -0
  399. stackvitals/web/app/demo/web-app/supply.json +1 -0
  400. stackvitals/web/app/demo/web-app/vulns.json +1 -0
  401. stackvitals/web/app/fonts/plex-mono-400.woff2 +0 -0
  402. stackvitals/web/app/fonts/plex-sans-400.woff2 +0 -0
  403. stackvitals/web/app/fonts/plex-sans-600.woff2 +0 -0
  404. stackvitals/web/app/fonts/plex-sans-condensed-700.woff2 +0 -0
  405. stackvitals/web/app/help/accuracy.json +1 -0
  406. stackvitals/web/app/help/connectors.json +1 -0
  407. stackvitals/web/app/help/getting-started.json +1 -0
  408. stackvitals/web/app/help/index.json +1 -0
  409. stackvitals/web/app/help/modules.json +1 -0
  410. stackvitals/web/app/help/privacy-and-security.json +1 -0
  411. stackvitals/web/app/help/reference.json +1 -0
  412. stackvitals/web/app/main.css +1 -0
  413. stackvitals/web/app/main.js +1 -0
  414. stackvitals/web/app/pages/about.css +1 -0
  415. stackvitals/web/app/pages/about.js +1 -0
  416. stackvitals/web/app/pages/activity.css +1 -0
  417. stackvitals/web/app/pages/activity.js +1 -0
  418. stackvitals/web/app/pages/agents.css +1 -0
  419. stackvitals/web/app/pages/agents.js +2 -0
  420. stackvitals/web/app/pages/ci.css +1 -0
  421. stackvitals/web/app/pages/ci.js +1 -0
  422. stackvitals/web/app/pages/community.css +1 -0
  423. stackvitals/web/app/pages/community.js +1 -0
  424. stackvitals/web/app/pages/connections.css +1 -0
  425. stackvitals/web/app/pages/connections.js +6 -0
  426. stackvitals/web/app/pages/delivery.css +1 -0
  427. stackvitals/web/app/pages/delivery.js +45 -0
  428. stackvitals/web/app/pages/deps.css +1 -0
  429. stackvitals/web/app/pages/deps.js +7 -0
  430. stackvitals/web/app/pages/explore.css +1 -0
  431. stackvitals/web/app/pages/explore.js +7 -0
  432. stackvitals/web/app/pages/health.css +1 -0
  433. stackvitals/web/app/pages/health.js +1 -0
  434. stackvitals/web/app/pages/help.css +1 -0
  435. stackvitals/web/app/pages/help.js +6 -0
  436. stackvitals/web/app/pages/insights.css +1 -0
  437. stackvitals/web/app/pages/insights.js +1 -0
  438. stackvitals/web/app/pages/investment.css +1 -0
  439. stackvitals/web/app/pages/investment.js +3 -0
  440. stackvitals/web/app/pages/overview.css +1 -0
  441. stackvitals/web/app/pages/overview.js +1 -0
  442. stackvitals/web/app/pages/portal.css +1 -0
  443. stackvitals/web/app/pages/portal.js +51 -0
  444. stackvitals/web/app/pages/prs.css +1 -0
  445. stackvitals/web/app/pages/prs.js +4 -0
  446. stackvitals/web/app/pages/settings.css +1 -0
  447. stackvitals/web/app/pages/settings.js +1 -0
  448. stackvitals/web/app/pages/setup.css +1 -0
  449. stackvitals/web/app/pages/setup.js +2 -0
  450. stackvitals/web/app/pages/standing.css +1 -0
  451. stackvitals/web/app/pages/standing.js +1 -0
  452. stackvitals/web/app/pages/welcome-sheet.js +1 -0
  453. stackvitals/web/app/pages/welcome.js +1 -0
  454. stackvitals/web/app/settings-workflow.json +1 -0
  455. stackvitals/web/index.html +34 -0
  456. stackvitals/web/site/index.html +108 -0
  457. stackvitals/web/site/integrations.html +15 -0
  458. stackvitals/web/site/setup.html +15 -0
  459. stackvitals/web/site/site.css +68 -0
  460. stackvitals-0.1.0.dist-info/METADATA +134 -0
  461. stackvitals-0.1.0.dist-info/RECORD +465 -0
  462. stackvitals-0.1.0.dist-info/WHEEL +4 -0
  463. stackvitals-0.1.0.dist-info/entry_points.txt +3 -0
  464. stackvitals-0.1.0.dist-info/licenses/LICENSE +202 -0
  465. stackvitals-0.1.0.dist-info/licenses/NOTICE +16 -0
@@ -0,0 +1 @@
1
+ .help-search{display:block;flex:none;max-width:680px;margin:4px 0 26px}.help-search .ic{left:14px;width:19px;height:19px}.help-search .input{font-size:16px;min-height:50px;padding-left:44px;border-radius:16px;background:var(--surface);border-color:var(--line);box-shadow:var(--shadow-1)}.help-search .input:focus{border-color:var(--focus)}.help-results{max-width:780px;animation:help-in var(--dur-2) var(--ease-out) both}.help-where{font-weight:650;color:var(--ink-2)}.help-results mark,.help-grid mark{background:color-mix(in srgb,var(--accent) 22%,transparent);color:inherit;border-radius:3px;padding:0 1px}.help-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:28px 28px;align-items:start}.help-group{min-width:0;display:flex;flex-direction:column;gap:8px;animation:help-in var(--dur-3) var(--spring) both}.help-group:nth-child(2){animation-delay:40ms}.help-group:nth-child(3){animation-delay:80ms}.help-group:nth-child(n+4){animation-delay:.12s}@keyframes help-in{0%{opacity:0;transform:translateY(8px)}}.help-group-h{font-size:19px;font-weight:750;letter-spacing:-.015em;display:flex;align-items:baseline;gap:8px;margin:0 4px}.help-group-h span{font-size:13px;font-weight:700;color:var(--ink-3)}.help-group .row-sub{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.help-cta{margin-top:32px;max-width:680px}.help-crumb{display:inline-flex;align-items:center;gap:4px;font-size:14px;font-weight:650}.help-crumb a{text-decoration:none}.help-crumb .ic{width:15px;height:15px;color:var(--ink-3)}.help-article{display:block;min-width:0;animation:help-in var(--dur-3) var(--spring) both}.help-article.has-toc{display:grid;grid-template-columns:minmax(0,1fr) 240px;gap:0 40px;align-items:start}.help-article.has-toc .help-toc{grid-column:2;grid-row:1 / span 2;position:sticky;top:calc(var(--top-h) + 16px);max-height:calc(100dvh - var(--top-h) - 32px);overflow-y:auto;overscroll-behavior:contain}.help-article.has-toc .md,.help-article.has-toc .help-foot{grid-column:1}.help-toc summary{font-size:14px;font-weight:650;color:var(--ink-2);cursor:pointer;padding:4px 0 8px;list-style:none;display:flex;align-items:center;gap:6px}.help-toc summary::-webkit-details-marker{display:none}.help-toc summary:after{content:"";width:7px;height:7px;border-right:2px solid currentColor;border-bottom:2px solid currentColor;transform:rotate(45deg) translateY(-2px);transition:transform var(--dur-2) var(--spring);margin-left:2px}.help-toc details[open] summary:after{transform:rotate(225deg) translate(-2px)}.help-toc ul{list-style:none;margin:0;padding:0 0 0 2px;border-left:2px solid var(--line);display:flex;flex-direction:column}.help-toc li a{display:block;padding:5px 10px;margin-left:-2px;border-left:2px solid transparent;color:var(--ink-2);text-decoration:none;font-size:13.5px;font-weight:600;line-height:1.35;transition:color var(--dur-1),border-color var(--dur-1)}.help-toc li.is-sub a{padding-left:22px;font-weight:500;font-size:13px}.help-toc li a:hover{color:var(--ink)}.help-toc li a[aria-current]{color:var(--accent);border-left-color:var(--accent)}.md{max-width:74ch;font-size:16px;line-height:1.65;min-width:0;overflow-wrap:anywhere}.md>:first-child{margin-top:0}.md h2{font-size:23px;line-height:1.25;font-weight:800;letter-spacing:-.02em;margin:38px 0 10px;padding-bottom:8px;border-bottom:1px solid var(--line)}.md h3{font-size:18.5px;font-weight:750;letter-spacing:-.01em;margin:28px 0 8px}.md h4,.md h5,.md h6{font-size:16px;font-weight:750;margin:22px 0 6px}.md h2,.md h3,.md h4{scroll-margin-top:calc(var(--top-h) + 16px);border-radius:6px}.md .is-flash{animation:md-flash 1.6s var(--ease-out)}@keyframes md-flash{0%,35%{background:color-mix(in srgb,var(--accent) 16%,transparent);box-shadow:0 0 0 6px color-mix(in srgb,var(--accent) 16%,transparent)}}.md p{margin:0 0 14px}.md ul,.md ol{margin:0 0 14px;padding-left:24px}.md li{margin:4px 0}.md li>ul,.md li>ol{margin:4px 0 0}.md li>p{margin:0 0 6px}.md code{font-size:.86em}.md a{overflow-wrap:anywhere}.md a[target=_blank]:after{content:"\2197";font-size:.8em;margin-left:2px;color:var(--ink-3)}.md strong{font-weight:750}.md blockquote{margin:0 0 14px;padding:10px 16px;border-left:3px solid var(--accent);background:var(--accent-soft);border-radius:0 12px 12px 0}.md blockquote>:last-child{margin-bottom:0}.md hr{border:0;height:1px;background:var(--line);margin:26px 0}.md-code{margin:0 0 16px;padding:13px 15px;border-radius:14px;background:var(--code-bg);color:var(--code-ink);font:500 13px/1.6 var(--mono);overflow-x:auto;overscroll-behavior-x:contain}.md-code code{background:none;padding:0;color:inherit;font-size:inherit;overflow-wrap:normal;white-space:pre}.md-table{margin:0 0 16px;overflow-x:auto;overscroll-behavior-x:contain;border:1px solid var(--line);border-radius:14px;background:var(--surface)}.md-table table{border-collapse:collapse;width:100%;font-size:14px;line-height:1.45}.md-table th{text-align:left;background:var(--surface-2);font-size:13px;color:var(--ink-2);font-weight:750;padding:9px 12px;white-space:nowrap}.md-table td{padding:9px 12px;border-top:1px solid var(--line);vertical-align:top;min-width:96px;overflow-wrap:normal;word-break:normal}.md-table td code{overflow-wrap:anywhere}.md-table td:not(:last-child) code{white-space:nowrap;overflow-wrap:normal}.md-table .is-right{text-align:right}.md-table .is-center{text-align:center}.help-foot{display:flex;justify-content:space-between;align-items:center;gap:12px;flex-wrap:wrap;margin-top:18px;padding-top:16px;border-top:1px solid var(--line);max-width:74ch}.help-back{display:inline-flex;align-items:center;gap:4px;font-weight:700;text-decoration:none}@media(max-width:1100px){.help-grid{grid-template-columns:minmax(0,1fr)}.help-article.has-toc{display:block}.help-article.has-toc .help-toc{margin-bottom:16px}.help-article.has-toc .help-toc{position:static;max-height:none;background:var(--surface);border:1px solid var(--line);border-radius:16px;padding:8px 14px}.help-toc summary{padding:6px 0}.help-toc details[open] ul{margin:4px 0 8px}}@media(max-width:640px){.md{font-size:15.5px}.md h2{font-size:20px;margin-top:30px}.md h3{font-size:17px}.md-code{margin-left:-4px;margin-right:-4px}}.md-alt{color:var(--ink-2);font-style:italic}.help-cta.help-ref{max-width:none;gap:10px}.help-desc{margin:0 4px 4px;font-size:14.5px;color:var(--ink-2);max-width:90ch}.hp-cmd{display:flex;align-items:flex-start;gap:10px;min-width:0}.hp-cmd code{flex:1 1 auto;min-width:0;font:400 13.5px/1.5 var(--mono);overflow-wrap:anywhere;white-space:pre-wrap;padding:2px 0}.hp-cmd .btn{flex:none}.hp-cmd{min-width:280px}.hp-id{font:400 13px/1.45 var(--mono);overflow-wrap:normal;word-break:normal}.hp-app{display:flex;flex-direction:column;gap:2px}.hp-go{font-weight:650}.hp-same{font-size:13px;color:var(--ink-2)}@media(max-width:640px){.hp-cmd{min-width:0}}[data-design=sheet][data-page=help] .help-search .input{background:var(--surface);border:1.5px solid var(--line-strong);min-height:50px}[data-design=sheet][data-page=help] .help-search .input:focus{border-color:var(--focus)}[data-design=sheet][data-page=help] .help-search .ic{color:var(--ink-2)}[data-design=sheet][data-page=help] .help-where{font-weight:600}[data-design=sheet][data-page=help] :is(.help-results,.help-grid) mark{background:var(--sv-yellow);color:#000;padding:0 1px}[data-design=sheet][data-page=help] .help-grid{gap:28px 24px}[data-design=sheet][data-page=help] .help-group{gap:12px;animation:svFade var(--dur-3) var(--sv-ease) both}[data-design=sheet][data-page=help] .help-group-h{width:fit-content;max-width:100%;margin:0;font-weight:700;font-size:21px;letter-spacing:-.005em;gap:10px;border-bottom:3px solid var(--mod);padding-bottom:4px}[data-design=sheet][data-page=help] .help-group-h span{font:700 14.5px var(--font);font-variant-numeric:tabular-nums;color:var(--ink-2)}[data-design=sheet][data-page=help] .help-group-h:has(+.glist){width:auto;margin-bottom:-12px;padding:9px 16px;min-height:44px;align-items:center;justify-content:space-between;font-size:17px;background:var(--strip);border:1.5px solid var(--frame);border-bottom:1px solid var(--line-strong)}[data-design=sheet][data-page=help] .help-group-h:has(+.glist) span{font-size:14.5px}[data-design=sheet][data-page=help] .help-group .glist.card{border:1.5px solid var(--frame)}[data-design=sheet][data-page=help] .help-group-h+.glist.card{border-top:0}[data-design=sheet][data-page=help] .help-cta{margin-top:44px}[data-design=sheet][data-page=help] .help-cta>.sub-h{margin:14px 0 0;font-size:16.5px}[data-design=sheet][data-page=help] .help-crumb{font-weight:600;font-size:15px}[data-design=sheet][data-page=help] .help-toc summary{font:700 13.5px/1.3 var(--font);letter-spacing:.04em;text-transform:uppercase;color:var(--ink-2)}[data-design=sheet][data-page=help] .help-toc summary:after{border-width:0 1.5px 1.5px 0}[data-design=sheet][data-page=help] .help-toc ul{border-left:1.5px solid var(--line-strong);padding-left:0}[data-design=sheet][data-page=help] .help-toc li a{font-weight:400;font-size:14.5px;color:var(--ink-2);margin-left:-1.5px;border-left-width:4px;padding:6px 10px}[data-design=sheet][data-page=help] .help-toc li.is-sub a{font-weight:400;font-size:14px;padding-left:22px}[data-design=sheet][data-page=help] .help-toc li a:hover{color:var(--ink)}[data-design=sheet][data-page=help] .help-toc li a[aria-current]{color:var(--ink);font-weight:600;border-left-color:var(--sv-blue);background:var(--accent-soft)}[data-design=sheet][data-page=help] .md{font-size:17px;line-height:1.6}[data-design=sheet][data-page=help] .md h2{width:fit-content;max-width:100%;font-weight:700;font-size:25px;line-height:1.25;letter-spacing:-.01em;border-bottom:3px solid var(--mod);padding-bottom:4px;margin:44px 0 14px}[data-design=sheet][data-page=help] .md h3{font-weight:700;font-size:20px;letter-spacing:0}[data-design=sheet][data-page=help] .md :is(h4,h5,h6){font-weight:700;font-size:17px}[data-design=sheet][data-page=help] .md .is-flash{animation:svMdFlash 1.6s var(--sv-ease)}@keyframes svMdFlash{0%,35%{outline:2px solid var(--focus);outline-offset:4px}to{outline:2px solid transparent;outline-offset:4px}}[data-design=sheet][data-page=help] .md strong{font-weight:700}[data-design=sheet][data-page=help] .md a[target=_blank]:after{color:var(--ink-2)}[data-design=sheet][data-page=help] .md blockquote{background:var(--accent-soft);border-left:4px solid var(--sv-blue);padding:10px 16px}[data-design=sheet][data-page=help] .md hr{background:var(--line-strong)}[data-design=sheet][data-page=help] .md-code{background:var(--code-bg);border:1px solid var(--line-strong);font:400 14px/1.6 var(--mono)}[data-design=sheet][data-page=help] .md-code code{border:0;padding:0}[data-design=sheet][data-page=help] .md-table{background:var(--surface);border:1.5px solid var(--frame)}[data-design=sheet][data-page=help] .md-table table{font-size:15px}[data-design=sheet][data-page=help] .md-table th{background:var(--strip);color:var(--ink);font-weight:700;font-size:14.5px;border-bottom:1px solid var(--line-strong)}[data-design=sheet][data-page=help] .md-table td{border-top-color:var(--line)}[data-design=sheet][data-page=help] .md-table tr:first-child td{border-top:0}[data-design=sheet][data-page=help] .help-foot{border-top:1px solid var(--line-strong)}[data-design=sheet][data-page=help] .help-back{font-weight:600}@media(max-width:1100px){[data-design=sheet][data-page=help] .help-article.has-toc .help-toc{background:var(--surface-2);border:1.5px solid var(--frame)}}@media(max-width:640px){[data-design=sheet][data-page=help] .md{font-size:16px}[data-design=sheet][data-page=help] .md h2{font-size:22px;margin-top:34px}[data-design=sheet][data-page=help] .md h3{font-size:18px}}@media(prefers-reduced-motion:reduce){[data-design=sheet][data-page=help] :is(.help-group,.md .is-flash){animation:none}}[data-design=sheet][data-page=help] .help-desc{font-size:15.5px;margin:0}[data-design=sheet][data-page=help] .help-ref .table-wrap{border:1.5px solid var(--frame)}[data-design=sheet][data-page=help] .hp-cmd code{font-size:14px;border:0;background:none;padding:2px 0}[data-design=sheet][data-page=help] .hp-id{font-size:14px;border:0;background:none;padding:0}[data-design=sheet][data-page=help] .hp-go{font-weight:600;color:var(--sv-blue-ink)}[data-design=sheet][data-page=help] .hp-same{font-size:14px}
@@ -0,0 +1,6 @@
1
+ import{b}from"../chunks/chunk-763NH7PP.js";import{a as W}from"../chunks/chunk-6RLVD2DT.js";import{b as E,f as q,g as R}from"../chunks/chunk-76WAVKUG.js";import"../chunks/chunk-VWKSMFWJ.js";import{N as ie,P as j,Q as D,a as S,c as F,d as L,f as ne,g as H,h as se,i as oe,w as r,x as O,z as M}from"../chunks/chunk-GT4EAKAO.js";import{d as z}from"../chunks/chunk-G7NGB5UX.js";z();z();var ye="https://github.com/stackvitals/stackvitals/blob/main/",v=e=>e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#39;"),Ce=e=>e.replace(/&quot;/g,'"').replace(/&#39;/g,"'").replace(/&lt;/g,"<").replace(/&gt;/g,">").replace(/&amp;/g,"&"),Se=e=>e.trim().toLowerCase().replace(/[^\p{L}\p{N}\p{M}\s_-]/gu,"").replace(/\s/g,"-"),$e=e=>e.replace(/!?\[([^\]]*)\]\([^)]*\)/g,"$1").replace(/`+([^`]*)`+/g,"$1").replace(/\*\*|__|~~/g,"").replace(/(^|\W)[*_](\S[^*_]*?)[*_](?=\W|$)/g,"$1$2").replace(/\\(.)/g,"$1").trim(),Te=e=>e.replace(/^docs\//,"").replace(/\.md$/,"").replace(/\//g,"-");function Ae(e,t){let n=e.trim();if(/^(https?:|mailto:)/i.test(n))return{href:n,external:!0};if(n.startsWith("#"))return{href:`#/help/${Te(t.file)}${n}`,external:!1};if(/^[a-z][\w+.-]*:/i.test(n)||n.startsWith("//")||!n)return null;let[a="",s]=n.split("#"),c=["docs",...t.file.split("/").slice(0,-1)];for(let i of a.split("/"))i===".."?c.pop():i&&i!=="."&&c.push(i);let p=c.join("/"),o=p.startsWith("docs/")?p.slice(5):null;return o&&t.docs[o]?{href:`#/help/${t.docs[o]}${s?"#"+s:""}`,external:!1}:{href:(t.blob||ye)+p+(s?"#"+s:""),external:!0}}function G(e,t){let n=[],a=o=>`\0${n.push(o)-1}\0`,s=e.replace(/\\([\\`*_{}[\]()#+\-.!|<>~])/g,(o,i)=>a(v(i)));s=s.replace(/(`+)([^`]|[^`][\s\S]*?[^`])\1(?!`)/g,(o,i,l)=>a(`<code>${v(l.replace(/^ (.*) $/,"$1"))}</code>`)),s=s.replace(/<(https?:\/\/[^\s<>]+)>/g,(o,i)=>a(`<a href="${v(i)}" target="_blank" rel="noopener noreferrer">${v(i)}</a>`)),s=v(s);let c=(o,i)=>{let l=Ae(Ce(i),t),h=o.replace(/^\u0000(\d+)\u0000$/,(k,A)=>n[+A].replace(/^<code>(.*)<\/code>$/,"$1")),g=l&&!l.external&&/^[\w./-]+\.md(#[\w-]*)?$/.test(h)?t.titles?.[l.href.slice(7).split("#")[0]]:void 0,f=g?v(g):le(o);return f?l?a(`<a href="${v(l.href)}"${l.external?' target="_blank" rel="noopener noreferrer"':""}>${f}</a>`):f:""},p=String.raw`((?:[^()\s]|\([^()\s]*\))+)(?:\s+&quot;.*?&quot;)?\)`;for(s=s.replace(new RegExp(String.raw`!\[([^\]]*)\]\(`+p,"g"),(o,i)=>i?a(`<span class="md-alt">${i}</span>`):""),s=s.replace(new RegExp(String.raw`\[((?:[^[\]]|\[[^\]]*\])*)\]\(`+p,"g"),(o,i,l)=>c(i,l)),s=le(s);/\u0000\d+\u0000/.test(s);)s=s.replace(/\u0000(\d+)\u0000/g,(o,i)=>n[+i]);return s}function le(e){return e.replace(/\*\*(?=\S)([\s\S]*?\S)\*\*/g,"<strong>$1</strong>").replace(/__(?=\S)([\s\S]*?\S)__/g,"<strong>$1</strong>").replace(/~~(?=\S)([\s\S]*?\S)~~/g,"<del>$1</del>").replace(/(^|[^\w*])\*(?=\S)([^*]*?\S)\*(?![\w*])/g,"$1<em>$2</em>").replace(/(^|[^\w])_(?=\S)([^_]*?\S)_(?!\w)/g,"$1<em>$2</em>")}var ce=/^\s*(`{3,}|~{3,})\s*([\w+-]*)/,de=/^(#{1,6})\s+(.*?)\s*#*\s*$/,he=/^\s*([-*_])(\s*\1){2,}\s*$/,w=/^(\s*)([-*+]|\d{1,9}[.)])\s+(.*)$/,ge=/^\s*\|?\s*:?-+:?\s*(\|\s*:?-+:?\s*)*\|?\s*$/,C=e=>e.length-e.trimStart().length,J=(e,t)=>ce.test(e)||de.test(e)||he.test(e)||w.test(e)||/^\s*>/.test(e)||e.includes("|")&&!!t&&ge.test(t);function V(e){let t=[],n="",a=!1,s=e.trim().replace(/^\|/,"").replace(/\|$/,"");for(let c=0;c<s.length;c++){let p=s[c];if(p==="\\"&&s[c+1]==="|"){n+="|",c++;continue}p==="`"&&(a=!a),p==="|"&&!a?(t.push(n.trim()),n=""):n+=p}return t.push(n.trim()),t}var U=class{constructor(t){this.seen=new Map;this.headings=[];this.ctx=t}id(t){let n=Se(t),a=this.seen.get(n);return this.seen.set(n,(a??-1)+1),a===void 0?n:`${n}-${a+1}`}blocks(t){let n=[],a=0;for(;a<t.length;){let s=t[a];if(!s.trim()){a++;continue}let c=ce.exec(s);if(c){let i=c[1],l=C(s),h=[];a++;let g=new RegExp(`^\\s*${i[0]==="`"?"`":"~"}{${i.length},}\\s*$`);for(;a<t.length&&!g.test(t[a]);){let f=t[a++];h.push(f.slice(Math.min(l,C(f))))}a++,n.push(`<pre class="md-code"${c[2]?` data-lang="${v(c[2])}"`:""}><code>${v(h.join(`
2
+ `))}</code></pre>`);continue}let p=de.exec(s);if(p){let i=p[1].length,l=$e(p[2]),h=this.id(l),g=`h${Math.max(2,i)}`;this.headings.push({level:i,text:l,id:h}),n.push(`<${g} id="h-${v(h)}">${G(p[2],this.ctx)}</${g}>`),a++;continue}if(he.test(s)){n.push("<hr>"),a++;continue}if(s.includes("|")&&a+1<t.length&&ge.test(t[a+1])){let i=V(t[a+1]).map(f=>/^:-+:$/.test(f)?"center":/-:$/.test(f)?"right":""),l=(f,k,A)=>`<${f}${i[A]?` class="is-${i[A]}"`:""}>${G(k,this.ctx)}</${f}>`,h=V(s).map((f,k)=>l("th",f,k)).join(""),g=[];for(a+=2;a<t.length&&t[a].trim()&&t[a].includes("|");)g.push(`<tr>${V(t[a++]).map((f,k)=>l("td",f,k)).join("")}</tr>`);n.push(`<div class="md-table"><table><thead><tr>${h}</tr></thead><tbody>${g.join("")}</tbody></table></div>`);continue}if(/^\s*>/.test(s)){let i=[];for(;a<t.length&&t[a].trim()&&(/^\s*>/.test(t[a])||!J(t[a]));)i.push(t[a++].replace(/^\s*> ?/,""));n.push(`<blockquote>${this.blocks(i)}</blockquote>`);continue}if(w.test(s)){let i=C(s),l=[],h=a;for(;a<t.length;){let g=t[a];if(g.trim()){if(C(g)<=i&&!w.test(g)&&(J(g)||!t[a-1].trim()))break;if(C(g)<i&&w.test(g))break;if(C(g)===i&&w.test(g)&&/\d/.test(w.exec(g)[2])!==/\d/.test(w.exec(t[h])[2]))break}else{let f=t.slice(a+1).find(k=>k.trim());if(!f||C(f)<=i&&!w.test(f))break}l.push(g),a++}n.push(this.list(l,i));continue}let o=[];for(;a<t.length&&t[a].trim()&&!(o.length&&J(t[a],t[a+1]));)o.push(t[a++].trim());n.push(`<p>${G(o.join(`
3
+ `),this.ctx)}</p>`)}return n.join(`
4
+ `)}list(t,n){let a=w.exec(t[0]),s=/\d/.test(a[2]),c=[],p=0;for(let l of t){let h=w.exec(l);if(h&&C(l)===n&&/\d/.test(h[2])===s)c.push({lines:[h[3]],loose:!1}),p=h[1].length+h[2].length+1;else if(c.length){let g=c[c.length-1];l.trim()||(g.loose=!0),g.lines.push(C(l)>=p?l.slice(p):l.trimStart())}}let o=s?parseInt(a[2],10):1,i=c.map(l=>{for(;l.lines.length&&!l.lines[l.lines.length-1].trim();)l.lines.pop();let h=this.blocks(l.lines);return`<li>${l.loose?h:h.replace(/^<p>([\s\S]*?)<\/p>/,"$1")}</li>`}).join("");return s?`<ol${o!==1?` start="${o}"`:""}>${i}</ol>`:`<ul>${i}</ul>`}};function me(e,t){let n=new U(t);return{html:n.blocks(e.replace(/\r\n?/g,`
5
+ `).replace(/\u0000/g,"").split(`
6
+ `)),headings:n.headings}}z();var m={setup:{label:"Setup",to:b("setup")},decide:{label:"Overview, Make a decision",to:b("overview")+"?at=ov-decide"},ciSetup:{label:"CI Health, Set up in your CI",to:b("ci")+"?at=ci-setup"},settings:{label:"Settings",to:b("settings")},connections:{label:"Connections, Test connection",to:b("connections")},explore:{label:"Explore",to:b("explore")},agents:{label:"Agents",to:b("agents")},ci:{label:"CI Health",to:b("ci")},prs:{label:"Pull Requests",to:b("prs")},delivery:{label:"Delivery",to:b("delivery")},community:{label:"Community",to:b("community")},insights:{label:"Insights",to:b("insights")},portal:{label:"Portal",to:b("portal")}},d=(e,t,n,a,s,c)=>({id:n,cmd:n,what:a,area:e,where:t,app:s,same:c}),y="Read a repo",T="Test step",B="Before a change",$="Data in and out",P="Set up and connect",Y="the same for this repo",K=[d(y,"Your machine","stackvitals ci report owner/repo --days 14","CI Health: flaky, failing and slow jobs and tests",m.ci,Y),d(y,"Your machine","stackvitals flow report owner/repo","Team Flow: who acts next on each pull request",m.prs,Y),d(y,"Your machine","stackvitals delivery owner/repo","Cycle time, DORA and stuck pull requests",m.delivery,Y),d(y,"Your machine","stackvitals delivery group/project --gitlab","The same from GitLab merge requests and deployments"),d(y,"Your machine","stackvitals delivery workspace/repo --bitbucket","The same from Bitbucket Cloud (BITBUCKET_TOKEN for private repos)"),d(y,"Your machine","stackvitals delivery org/project/repo --azure","The same from Azure DevOps (AZURE_DEVOPS_TOKEN for private projects)"),d(y,"Your machine","stackvitals community report owner/repo","Newcomer funnel and first answers",m.community,Y),d(y,"Your machine","stackvitals insights owner/repo","What to fix first, across modules",m.insights,Y),d(y,"Your machine","stackvitals portal report my-org","Every repo of an org and its owners, with evidence",m.portal,"when the org's Portal runs"),d(y,"Your machine","stackvitals contribute brief owner/repo","How changes get merged in a repo you want to contribute to",m.agents,"repo_brief, from your agent"),d(T,"Your CI's test step",'stackvitals ci quarantine --reports "out/*.xml" -- pytest --junitxml out/results.xml',"Pass when only known-flaky tests failed",m.ciSetup,"generates the step"),d(T,"Your CI's test step","stackvitals ci retry --reports 'out/*.xml' -- pytest --junitxml out/results.xml","Re-run only the failed tests, never known-broken ones",m.ciSetup,"generates the step"),d(T,"Your CI's test step","stackvitals ci burn-in --base origin/main --times 5 -- pytest {files}","Run the tests a PR adds or changes several times; fail on a flip",m.ciSetup,"generates the step"),d(T,"Your CI's test step","stackvitals ci impact --base origin/main --tests 'tests/**/*.py'","The test files a change can affect, from names and past failures",m.ciSetup,"generates the step"),d(T,"Your CI's test step","stackvitals ci shards owner/repo --n 4","Split test files into shards that take about the same time",m.ciSetup,"generates the step"),d(T,"Your CI's test step","stackvitals ci validate 'build/test-results/**/*.xml'","Check test reports are read as you expect",m.ciSetup,"generates the step"),d(T,"Jenkins, CircleCI or Buildkite",'stackvitals ci upload --repo owner/name --sha "$SHA" --provider jenkins test-results/*.xml',"Send reports from Jenkins, CircleCI or Buildkite"),d(B,"Your machine","stackvitals deps check requests","One package's evidence: use, monitor or investigate",m.agents,"check_package, from your agent"),d(B,"Your machine","stackvitals deps scan package-lock.json","Every package in a lockfile, the ones to look at first"),d(B,"Your machine","stackvitals flow preflight owner/repo --paths src/db/pool.py --lines 120","What merged PRs here usually include, and what yours is missing",m.agents,"preflight, from your agent"),d(B,"Your machine","stackvitals flow triage owner/repo","Chance each open outside PR gets merged, and why"),d($,"Your CD tool or pager",'stackvitals record deployment owner/repo --id argo-1287 --sha "$GIT_SHA" --tool argo-cd',"Send a deployment from any CD tool"),d($,"Your CD tool or pager","stackvitals record incident owner/repo --id INC-42 --at 2026-10-29T09:12:00Z","Send an incident from any pager",m.connections,"pager connectors"),d($,"Your machine","stackvitals project web org/frontend org/api org/worker","DORA for one project across several repos"),d($,"Your machine","stackvitals explain owner/repo lead-time","What a headline number was counted from"),d($,"Your machine",'stackvitals sql --repo owner/name "select role, count(*) from prs group by role"',"SQL over a repo's summaries",m.explore,"SQL in the browser"),d($,"Your machine","stackvitals export owner/repo --format devlake","DevLake tables (also ctrf, otel --tests, postgres)",m.explore,"each table as a download"),d($,"Your machine","stackvitals propose owner/repo --set alerts.pickup_p75_hours=6","A link proposing a settings change that a person submits",m.settings,"edit and send"),d($,"Your machine","stackvitals ui owner/repo","Open a repo's pages and Explore from a local copy"),d(P,"Your machine","stackvitals ci init owner/repo > .github/workflows/stackvitals.yml","The workflow file, with this repo's names filled in",m.setup,"commits it for you"),d(P,"Your machine","stackvitals portal check my-org","What your token can read in an org, before the first run"),d(P,"Your machine","stackvitals connectors check --all","Test each connector's key",m.connections,"one connector at a time"),d(P,"Your machine","stackvitals serve","The MCP server for AI agents",m.agents,"config to copy"),d(P,"Your machine","stackvitals editor vscode","Mark flaky tests in VS Code, Cursor or VSCodium",m.agents,"Editor section")],ue=e=>r("a",{class:"hp-go",href:e.to,children:e.label}),Ie=[{key:"cmd",label:"Command",primary:!0,raw:e=>e.cmd,render:e=>r("span",{class:"hp-cmd",children:[r("code",{children:e.cmd}),r(ie,{text:e.cmd,small:!0,label:"Copy"})]})},{key:"what",label:"What it does"},{key:"area",label:"Use",filter:!0},{key:"where",label:"Where it runs",filter:!0},{key:"app",label:"In the app",raw:e=>e.app?.label||"",render:e=>e.app?r("span",{class:"hp-app",children:[ue(e.app),e.same?r("span",{class:"hp-same",children:e.same}):null]}):r("span",{class:"muted",children:"Command only"})}];function fe(){return r(W,{rows:K,columns:Ie,name:"stackvitals-commands",caption:"Commands",limit:60})}var ze=[{id:"install",task:"Add StackVitals to a repo",at:m.setup,replaces:"stackvitals ci init",noToken:"The workflow file opens on GitHub, ready to commit",withToken:"Commits it, starts the first run, turns on Pages"},{id:"decide",task:"Quarantine, mute, snooze or acknowledge",at:m.decide,replaces:"stackvitals propose --decide",noToken:"A prefilled issue you submit on GitHub",withToken:"Starts the workflow, which checks your access and records it"},{id:"ci",task:"Add retry, burn-in, impact, shards or quarantine to your tests",at:m.ciSetup,replaces:"stackvitals ci retry, burn-in, impact, ...",noToken:"The test workflow opens on GitHub as a new file",withToken:"Opens a pull request with the file"},{id:"settings",task:"Change a setting",at:m.settings,replaces:"stackvitals propose --set",noToken:"A prefilled issue, or the TOML to paste",withToken:"Commits it or opens a pull request"},{id:"connect",task:"Test a connector's key",at:m.connections,replaces:"stackvitals connectors check",noToken:"Not available: the check runs in your workflow",withToken:"Runs the workflow's check and shows the result"},{id:"sql",task:"Query the summaries",at:m.explore,replaces:"stackvitals sql, stackvitals export",noToken:"Runs in your browser; tables download as CSV",withToken:"Not needed"}],Ee=[{key:"task",label:"Task",primary:!0},{key:"at",label:"Where in the app",raw:e=>e.at.label,render:e=>ue(e.at)},{key:"replaces",label:"Instead of",render:e=>r("code",{class:"hp-id",children:e.replaces})},{key:"noToken",label:"Without a token"},{key:"withToken",label:"With a GitHub token"}];function be(){return r(W,{rows:ze,columns:Ee,name:"done-in-the-app",caption:"Done in the app",search:!1})}var _e={"ci.html":"CI Health","flow.html":"Team Flow","delivery.html":"Delivery","insights.html":"Insights","community.html":"Community","portal.html":"Portal","explore.html":"Explore"};function xe(e){return(e?.pages||[]).filter(t=>t.endsWith(".html")).map(t=>({id:t,title:_e[t]||t,file:t,note:t==="explore.html"?"SQL over the summaries in your browser":"One page, no JavaScript needed; ready to print or attach"}))}function ke({rows:e}){return r(W,{rows:e,name:"printable-pages",caption:"Printable pages",search:!1,columns:[{key:"title",label:"Page",primary:!0,render:t=>r("a",{href:t.file,target:"_blank",rel:"noopener noreferrer",children:t.title})},{key:"file",label:"File",nowrap:!0,render:t=>r("code",{class:"hp-id",children:t.file})},{key:"note",label:"What it is"}]})}var Z="https://github.com/stackvitals/stackvitals/blob/main/docs/",He=document.querySelector('script[type="module"][src]')?.src||location.href,Q=new Map,ae=e=>(Q.has(e)||Q.set(e,fetch(new URL(e,He).href).then(t=>t.ok?t.json():null,()=>null)),Q.get(e)),we=se("");function re(e,t){let[n,a]=F(null),s=JSON.stringify(t);return L(()=>{let c=!0;return e().then(p=>{c&&a({k:s,v:p})}),()=>{c=!1}},[s]),n&&n.k===s?n.v:void 0}function X({id:e,title:t,count:n,desc:a,children:s}){return r("section",{class:"help-group help-cta help-ref","aria-labelledby":e,children:[r("h2",{id:e,class:"help-group-h",children:[t,n?r("span",{children:n}):null]}),r("p",{class:"help-desc",children:a}),s]})}function Re({app:e}){let t=xe(e);return r(S,{children:[r(X,{id:"hg-a",title:"Done in the app",desc:"These used to need a command. Now they take a click here; the last two columns say what each path does.",children:r(be,{})}),r(X,{id:"hg-c",title:"Commands",count:K.length,desc:r(S,{children:["Everything else runs where the table says, after ",r("code",{class:"code-inline",children:"pip install stackvitals"}),"; every command takes ",r("code",{class:"code-inline",children:"--help"}),". Filter by use or by where it runs."]}),children:r(fe,{})}),t.length?r(X,{id:"hg-p",title:"Printable pages",count:t.length,desc:"Written beside the app by the last run. Weekly snapshots stay in the history folder beside them on the data branch.",children:r(ke,{rows:t})}):null]})}var ee=(e,t)=>`#/help/${e}${t?"#"+t:""}`,te=(e,t=110)=>e.length<=t?e:e.slice(0,e.lastIndexOf(" ",t))+"\u2026";function ve({text:e,q:t}){let n=t?e.toLowerCase().indexOf(t):-1;return n<0?r(S,{children:e}):r(S,{children:[e.slice(0,n),r("mark",{children:e.slice(n,n+t.length)}),e.slice(n+t.length)]})}function Pe(e,t,n){let a=[],s=new Set,c=o=>e.docs.find(i=>i.id===o)?.title||o,p=o=>{let i=o.doc+"#"+(o.h||"");s.has(i)||(s.add(i),a.push(o))};for(let o of e.entries)o.title.toLowerCase().includes(n)&&p({doc:o.doc,...o.h?{h:o.h}:{},title:o.title,where:e.groups[o.group]||"",text:te(o.summary),rank:0});for(let o of e.docs)for(let[,i,l]of o.headings)i.toLowerCase().includes(n)&&p({doc:o.id,h:l,title:i,where:c(o.id),text:"",rank:1});for(let o of e.entries)o.summary.toLowerCase().includes(n)&&p({doc:o.doc,...o.h?{h:o.h}:{},title:o.title,where:e.groups[o.group]||"",text:te(o.summary),rank:2});for(let[o,i]of Object.entries(t||{})){let l=i.toLowerCase().indexOf(n);if(l<0||s.has(o+"#"))continue;let h=i.slice(Math.max(0,l-70),l+110).replace(/\]\([^)]*\)|[`*#>|[\]]|-{3,}/g,"").replace(/\s+/g," ").trim();p({doc:o,title:c(o),where:"In the text",text:(l>70?"\u2026":"")+h+"\u2026",rank:3})}return a.sort((o,i)=>o.rank-i.rank).slice(0,40)}function Ye({ix:e,app:t}){let n=oe(we),a=n.trim().toLowerCase(),s=re(async()=>a.length<2?null:Object.assign({},...await Promise.all([...new Set(e.docs.map(p=>p.chunk))].map(p=>ae(`help/${p}.json`)))),[a.length>=2]),c=H(()=>a?Pe(e,s??null,a):[],[a,s]);return r(E,{title:"Help",subtitle:`${e.docs.length} guides and references, from install to how each number is worked out.`,children:[r("label",{class:"search-field help-search",children:[r(O,{name:"search"}),r("input",{class:"input",type:"search",placeholder:"Search the docs","aria-label":"Search the docs",value:n,onInput:p=>we.set(p.currentTarget.value)})]}),a?r("section",{class:"help-results","aria-live":"polite","aria-label":"Search results",children:c.length?r(q,{label:"Results",children:c.map(p=>r(R,{href:ee(p.doc,p.h),title:r(ve,{text:p.title,q:a}),subtitle:r(S,{children:[r("span",{class:"help-where",children:p.where}),p.text?r(S,{children:[" \xB7 ",r(ve,{text:p.text,q:a})]}):null]})}))}):s===void 0?r(D,{lines:3}):r(j,{icon:"search",title:`Nothing matches "${n.trim()}"`,children:"Try a module name, a connector or a setting."})}):r(S,{children:[r("div",{class:"help-grid",children:e.groups.map((p,o)=>{let i=e.entries.filter(l=>l.group===o);return i.length?r("section",{class:"help-group","aria-labelledby":`hg-${o}`,children:[r("h2",{id:`hg-${o}`,class:"help-group-h",children:[p,r("span",{children:i.length})]}),r(q,{label:p,children:i.map(l=>r(R,{href:ee(l.doc,l.h),title:l.title,subtitle:te(l.summary,96)}))})]}):null})}),r(Re,{app:t}),r("section",{class:"help-group help-cta","aria-labelledby":"hg-x",children:[r("h2",{id:"hg-x",class:"help-group-h",children:"Still stuck?"}),r(q,{label:"Still stuck?",children:[r(R,{icon:"setup",href:"#/setup",title:"Run setup again",subtitle:"Five short steps; it checks what is already there."}),r(R,{icon:"help",href:"https://github.com/stackvitals/stackvitals/issues",external:!0,title:"Ask on GitHub",subtitle:"Open an issue; questions are welcome."})]})]})]})]})}function Le({ix:e,id:t,anchor:n}){let a=e.docs.find(u=>u.id===t),s=re(()=>a?ae(`help/${a.chunk}.json`):Promise.resolve(null),[a?.chunk]),c=ne(null),[p,o]=F(""),i=H(()=>Object.fromEntries(e.docs.map(u=>[u.file,u.id])),[e]),l=H(()=>Object.fromEntries(e.docs.map(u=>[u.id,u.title])),[e]),h=H(()=>a&&s?.[a.id]!==void 0?me(s[a.id],{file:a.file,docs:i,titles:l}):null,[s,a?.id]),g=(h?.headings||[]).filter(u=>u.level===2||u.level===3),f=(u,I=!0)=>{let x=document.getElementById("h-"+u);x&&(x.scrollIntoView({behavior:I?"smooth":"auto",block:"start"}),x.classList.remove("is-flash"),x.offsetWidth,x.classList.add("is-flash"))};L(()=>{h&&n&&requestAnimationFrame(()=>f(n,!1))},[h,n]),L(()=>{if(!h)return;let u=0,I=()=>{cancelAnimationFrame(u),u=requestAnimationFrame(()=>{let x="";for(let _ of g){let N=document.getElementById("h-"+_.id);if(N&&N.getBoundingClientRect().top<140)x=_.id;else if(N)break}o(x)})};return I(),addEventListener("scroll",I,{passive:!0}),()=>{removeEventListener("scroll",I),cancelAnimationFrame(u)}},[h]);let k=u=>{let x=u.target.closest("a")?.getAttribute("href")||"",_=`#/help/${t}#`;!x.startsWith(_)||u.metaKey||u.ctrlKey||(u.preventDefault(),history.replaceState(history.state,"",x),f(x.slice(_.length)))};if(!a)return r(E,{title:"Not found",children:r(j,{icon:"search",title:"There's no doc by that name.",action:r(M,{variant:"filled",href:"#/help",children:"All help"})})});let A=u=>r("li",{class:u.level===3?"is-sub":"",children:r("a",{href:ee(t,u.id),"aria-current":p===u.id?"location":void 0,children:u.text})});return r(E,{title:a.title,subtitle:r("span",{class:"help-crumb",children:[r("a",{href:"#/help",children:"Help"}),r(O,{name:"right"}),e.groups[a.group]]}),toolbar:r(M,{variant:"plain",icon:"external",href:Z+a.file+(n?"#"+n:""),external:!0,children:"Open on GitHub"}),children:h?r("div",{class:"help-article"+(g.length>2?" has-toc":""),onClick:k,children:[g.length>2?r("nav",{class:"help-toc","aria-label":"On this page",children:r("details",{open:matchMedia("(min-width: 1101px)").matches,children:[r("summary",{children:"On this page"}),r("ul",{children:g.map(A)})]})}):null,r("article",{class:"md",ref:c,dangerouslySetInnerHTML:{__html:h.html}}),r("footer",{class:"help-foot",children:[r("a",{class:"help-back",href:"#/help",children:[r(O,{name:"left"}),"All help"]}),r(M,{variant:"plain",icon:"external",href:Z+a.file,external:!0,children:"Open on GitHub"})]})]}):r(D,{lines:8})})}function Oe({app:e,route:t}){let n=re(()=>ae("help/index.json"),[]),[a="",s=""]=(t.rest[0]||"").split("#");return n===void 0?r(E,{title:"Help",children:r(D,{lines:6})}):n?a?r(Le,{ix:n,id:a,anchor:s}):r(Ye,{ix:n,app:e}):r(E,{title:"Help",children:r(j,{icon:"warn",title:"The docs didn't load.",children:["Reload the page, or read them on ",r("a",{href:Z,target:"_blank",rel:"noopener noreferrer",children:"GitHub"}),"."]})})}export{Oe as default};
@@ -0,0 +1 @@
1
+ .ins-k{margin:0;font-size:13px;font-weight:700;color:var(--ink-2)}.ins-k .ins-dim{font-weight:500;margin-left:6px}.ins-dim{color:var(--ink-2)}.ins-link{background:none;border:0;padding:0;font:inherit;font-weight:700;color:var(--accent);text-align:left;cursor:pointer;text-decoration:underline;text-underline-offset:3px;overflow-wrap:anywhere}.ins-link:hover{text-decoration-thickness:2px}.ins-sum{padding:0;overflow:hidden}.ins-sum>*{padding:16px 18px}.ins-sum>*+*{border-top:1px solid var(--line)}.ins-sum-top{display:grid;grid-template-columns:minmax(220px,1fr) minmax(0,2fr);gap:16px 24px;align-items:stretch}.ins-head .ins-dim{margin:4px 0 0;font-size:13.5px;max-width:40ch}.ins-big{margin:2px 0 0;font-size:56px;line-height:1.05;font-weight:800;letter-spacing:-.03em;white-space:nowrap}.ins-big small{font-size:.4em;font-weight:700;letter-spacing:0;color:var(--ink-2);margin-left:6px}.ins-cells{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));margin:0;align-content:start}.ins-cell{padding:4px 16px;border-left:1px solid var(--line);min-width:0}.ins-cell dd{margin:0}.ins-cell-k{font-size:13px;font-weight:700;color:var(--ink-2)}.ins-cell-v{font-size:28px;font-weight:800;letter-spacing:-.02em;line-height:1.2;margin:2px 0}.ins-cell-note{font-size:13px;color:var(--ink-2)}.ins-track{display:grid;grid-template-columns:minmax(220px,1fr) minmax(0,2fr);gap:8px 24px;align-items:start}.ins-first{display:grid;grid-template-columns:minmax(220px,1fr) minmax(0,2fr);gap:4px 24px;align-items:baseline}.ins-first-v{margin:0;font-size:15.5px}.ins-bars .ins-k{margin-bottom:8px}.ins-pick{margin:8px 0 0;font-size:14px;min-height:1.5em;overflow-wrap:anywhere}.ins-list{list-style:none;margin:0;padding:0;display:grid;gap:12px}.ins-f{background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden;scroll-margin-top:80px;animation:pageIn var(--dur-3) var(--spring) backwards}.ins-f:focus{outline:none}.ins-f:focus-visible{outline:2px solid var(--focus);outline-offset:2px}.ins-f-head{display:grid;grid-template-columns:36px minmax(0,1fr) auto;gap:12px 14px;align-items:start;padding:16px 18px 0}.ins-rank{width:34px;height:34px;border-radius:50%;display:grid;place-items:center;background:var(--accent-soft);color:var(--accent);font-weight:800}.ins-f.is-aside .ins-rank{background:var(--surface-2);color:var(--ink-2)}.ins-rank .ic{width:17px;height:17px}.ins-f-title{margin:4px 0 0;font-size:16.5px;font-weight:700;line-height:1.35;overflow-wrap:anywhere}.ins-f-kind{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:6px}.ins-f-kind-note{font-size:13px;color:var(--ink-2)}.ins-f-hours{text-align:right}.ins-f-num{display:block;font-size:30px;font-weight:800;letter-spacing:-.02em;line-height:1}.ins-f-unit{font-size:12.5px;font-weight:600;color:var(--ink-2);white-space:nowrap}.ins-f-action{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:4px 12px;align-items:baseline;margin:12px 18px 0 68px;padding:10px 12px;background:var(--accent-soft);border-radius:var(--r-md)}.ins-f-action .ins-k{color:var(--accent)}.ins-f-action p{margin:0;font-size:14.5px;overflow-wrap:anywhere}.ins-facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));margin:14px 0 0;border-top:1px solid var(--line);overflow:hidden}.ins-fact{padding:9px 18px;border-right:1px solid var(--line);border-bottom:1px solid var(--line);margin:0 -1px -1px 0;min-width:0}.ins-fact dt{font-size:12.5px;font-weight:700;color:var(--ink-2)}.ins-fact dd{margin:2px 0 0;font-size:14px;overflow-wrap:anywhere}.ins-facts-dec{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:4px 16px;margin:0;border:0;overflow:visible}.ins-facts-dec .ins-fact{display:contents}.ins-facts-dec .ins-fact dd{margin:0}.ins-dec{margin:12px 18px 0;padding:12px 14px;border:1px solid var(--line);border-radius:var(--r-md);background:var(--surface-2)}.ins-dec-h{margin:0 0 8px}.ins-bar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:14px;padding:10px 18px;border-top:1px solid var(--line);background:var(--surface-2)}.ins-f .ins-facts+.ins-bar{margin-top:0}.ins-cmds{padding:12px 18px 16px;animation:pageIn var(--dur-2) var(--spring) backwards}.ins-chains{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,440px),1fr));gap:12px}.ins-chain{display:flex;flex-direction:column;overflow:hidden}.ins-chain-head{display:flex;gap:10px 14px;align-items:center;justify-content:space-between;flex-wrap:wrap;padding:11px 16px;background:var(--surface-2);border-bottom:1px solid var(--line)}.ins-chain-test{margin:0;font:600 14px/1.4 var(--mono, ui-monospace, monospace);overflow-wrap:anywhere;min-width:0}.ins-steps{list-style:none;margin:0;padding:2px 16px 6px}.ins-steps>li{display:grid;grid-template-columns:140px minmax(0,1fr);gap:4px 14px;padding:10px 0;font-size:14px;overflow-wrap:anywhere}.ins-steps>li+li{border-top:1px solid var(--line)}.ins-step-k{display:flex;gap:8px;align-items:center;font-weight:700;color:var(--ink)}.ins-step-k .ic{width:18px;height:18px;flex:none;color:var(--accent)}.ins-step-sub{margin-top:3px;color:var(--ink-2);font-size:13.5px}.ins-chain .ins-bar{margin-top:auto}.ins-range{margin:10px 0 0;color:var(--ink-2);font-size:13.5px}.ins-tbl{margin-top:22px}.ins-tbl-h{display:flex;gap:4px 12px;align-items:baseline;flex-wrap:wrap;padding:10px 14px;background:var(--surface);border:1px solid var(--line);border-bottom:0;border-radius:var(--r-lg) var(--r-lg) 0 0}.ins-tbl-h h3{margin:0;font-size:15.5px;font-weight:700}.ins-tbl-note{font-size:13px;color:var(--ink-2)}.ins-tbl .table-wrap{border-top-left-radius:0;border-top-right-radius:0}.ins-prs{overflow-wrap:anywhere}@media(min-width:641px){.ins-tbl .table :is(th,td)+:is(th,td){border-left:1px solid var(--line)}}@media(max-width:720px){.ins-sum-top,.ins-track,.ins-first{grid-template-columns:minmax(0,1fr)}.ins-cell:first-child{border-left:0;padding-left:0}}@media(max-width:480px){.ins-sum>*{padding:14px}.ins-big{font-size:46px}.ins-f-head{grid-template-columns:30px minmax(0,1fr);padding:14px 14px 0}.ins-rank{width:28px;height:28px;font-size:13px}.ins-f-hours{grid-column:2;text-align:left;display:flex;align-items:baseline;gap:6px}.ins-f-action{grid-template-columns:minmax(0,1fr);margin:12px 14px 0}.ins-fact{padding:9px 14px}.ins-facts{grid-template-columns:repeat(2,minmax(0,1fr))}.ins-facts>.ins-fact:last-child:nth-child(odd){grid-column:span 2}.ins-sum-top .ins-cells{grid-template-columns:repeat(2,minmax(0,1fr))}.ins-track .ins-cells{grid-template-columns:repeat(3,minmax(0,1fr))}.ins-cell{padding:2px 10px}.ins-dec{margin:12px 14px 0}.ins-bar{padding:10px 14px}.ins-steps>li{grid-template-columns:minmax(0,1fr)}}[data-design=sheet][data-page=insights] .ins-k{font:700 14px/1.3 var(--font);letter-spacing:.04em;text-transform:uppercase;color:var(--ink-2)}[data-design=sheet][data-page=insights] .ins-k .ins-dim{font-weight:400;text-transform:none;letter-spacing:0}[data-design=sheet][data-page=insights] .ins-dim{color:var(--ink-2)}[data-design=sheet][data-page=insights] .ins-link{font-weight:600;color:var(--accent)}[data-design=sheet][data-page=insights] .ins-sum{border:1.5px solid var(--frame)}[data-design=sheet][data-page=insights] .ins-sum>*+*{border-top-color:var(--line-strong)}[data-design=sheet][data-page=insights] .ins-sum>*{padding:18px 20px}[data-design=sheet][data-page=insights] .ins-head .ins-dim{font-size:15px}[data-design=sheet][data-page=insights] .ins-big{font-family:var(--display);font-weight:700;font-size:76px;letter-spacing:-.01em;line-height:1;margin-top:8px}[data-design=sheet][data-page=insights] .ins-big small{font:600 20px var(--font);color:var(--ink-2)}[data-design=sheet][data-page=insights] .ins-cell{border-left-color:var(--line-strong);padding:2px 18px}[data-design=sheet][data-page=insights] .ins-cell-k{font-size:14px;font-weight:600}[data-design=sheet][data-page=insights] .ins-cell-v{font-family:var(--display);font-weight:700;font-size:36px;letter-spacing:0;line-height:1.1;margin:4px 0 2px}[data-design=sheet][data-page=insights] .ins-cell-note{font-size:14px}[data-design=sheet][data-page=insights] .ins-first{background:var(--strip)}[data-design=sheet][data-page=insights] .ins-first-v{font-size:17px}[data-design=sheet][data-page=insights] .ins-first-v .ins-link{font-weight:700}[data-design=sheet][data-page=insights] .ins-pick{font-size:15px}[data-design=sheet][data-page=insights] .ins-pick b{font-weight:700}[data-design=sheet][data-page=insights] .ins-list{gap:16px}[data-design=sheet][data-page=insights] .ins-f{border:1.5px solid var(--frame);animation-name:svFade;animation-timing-function:var(--sv-ease)}[data-design=sheet][data-page=insights] .ins-f.is-aside{border-style:dashed}[data-design=sheet][data-page=insights] .ins-f-head{grid-template-columns:40px minmax(0,1fr) auto;gap:12px 16px;padding:18px 20px 0}[data-design=sheet][data-page=insights] .ins-rank{width:36px;height:36px;background:none;border:1.5px solid var(--ink);color:var(--ink);font:700 20px/1 var(--display)}[data-design=sheet][data-page=insights] .ins-f.is-aside .ins-rank{background:none;border-style:dashed;border-color:var(--ink-2);color:var(--ink-2)}[data-design=sheet][data-page=insights] .ins-rank .ic{width:16px;height:16px;stroke-width:2}[data-design=sheet][data-page=insights] .ins-f-title{font-size:18px;font-weight:700;margin-top:5px}[data-design=sheet][data-page=insights] .ins-f-kind-note{font-size:14px}[data-design=sheet][data-page=insights] .ins-f-num{font-family:var(--display);font-weight:700;font-size:40px;letter-spacing:-.01em}[data-design=sheet][data-page=insights] .ins-f-unit{font-size:14px;font-weight:600}[data-design=sheet][data-page=insights] .ins-f-action{margin:14px 20px 0 76px;padding:0 0 0 14px;background:none;border-left:3px solid var(--sv-blue)}[data-design=sheet][data-page=insights] .ins-f-action .ins-k{color:var(--ink-2)}[data-design=sheet][data-page=insights] .ins-f-action p{font-size:16px;color:var(--ink)}[data-design=sheet][data-page=insights] .ins-facts{margin-top:16px;border-top:1px solid var(--line-strong)}[data-design=sheet][data-page=insights] .ins-fact{padding:10px 20px;border-color:var(--line-strong)}[data-design=sheet][data-page=insights] .ins-fact dt{font-size:14px;font-weight:600}[data-design=sheet][data-page=insights] .ins-fact dd{font-size:15px}[data-design=sheet][data-page=insights] .ins-facts-dec{border:0;margin:0}[data-design=sheet][data-page=insights] .ins-dec{margin:14px 20px 0;padding:0;background:var(--surface);border:1px solid var(--line-strong)}[data-design=sheet][data-page=insights] .ins-dec-h{margin:0;padding:8px 14px;background:var(--strip);border-bottom:1px solid var(--line-strong)}[data-design=sheet][data-page=insights] .ins-dec .ins-facts-dec{padding:10px 14px;gap:6px 18px}[data-design=sheet][data-page=insights] .ins-bar{margin-top:16px;padding:10px 20px;background:var(--strip);border-top:1px solid var(--line-strong)}[data-design=sheet][data-page=insights] .ins-f .ins-facts+.ins-bar{margin-top:0}[data-design=sheet][data-page=insights] .ins-cmds{padding:14px 20px 18px;animation-name:svFade}[data-design=sheet][data-page=insights] .ins-chains{gap:16px}[data-design=sheet][data-page=insights] .ins-chain.card{border:1.5px solid var(--frame)}[data-design=sheet][data-page=insights] .ins-chain-head{background:var(--strip);border-bottom-color:var(--line-strong);padding:10px 16px}[data-design=sheet][data-page=insights] .ins-chain-test{font:400 14.5px/1.4 var(--mono);color:var(--ink)}[data-design=sheet][data-page=insights] .ins-steps{padding:0 16px 4px;counter-reset:step}[data-design=sheet][data-page=insights] .ins-steps>li{font-size:15px;padding:12px 0;grid-template-columns:150px minmax(0,1fr)}[data-design=sheet][data-page=insights] .ins-steps>li+li{border-top-color:var(--line-strong)}[data-design=sheet][data-page=insights] .ins-step-k{font-size:15px;font-weight:700;align-items:flex-start}[data-design=sheet][data-page=insights] .ins-step-k .ic{color:var(--ink);stroke-width:1.75;margin-top:2px}[data-design=sheet][data-page=insights] .ins-step-v b{font-weight:700}[data-design=sheet][data-page=insights] .ins-step-sub{font-size:14px}[data-design=sheet][data-page=insights] .ins-chain .ins-bar{margin-top:auto;padding:10px 16px}[data-design=sheet][data-page=insights] .ins-range{font-size:15px}[data-design=sheet][data-page=insights] .ins-tbl{margin-top:28px}[data-design=sheet][data-page=insights] .ins-tbl-h{background:var(--strip);border:1.5px solid var(--frame);border-bottom:1px solid var(--line-strong);padding:10px 14px}[data-design=sheet][data-page=insights] .ins-tbl-h h3{font-size:16px;font-weight:700}[data-design=sheet][data-page=insights] .ins-tbl-note{font-size:14px}[data-design=sheet][data-page=insights] .ins-tbl .table-wrap{border:1.5px solid var(--frame);border-top:0}@media(min-width:641px){[data-design=sheet][data-page=insights] .ins-tbl .table :is(th,td)+:is(th,td){border-left:1px solid var(--line-strong)}[data-design=sheet][data-page=insights] .ins-tbl .table td{padding:10px 14px}[data-design=sheet][data-page=insights] .ins-tbl .th-btn{padding:9px 14px}}@media(max-width:720px){[data-design=sheet][data-page=insights] .ins-cell:first-child{padding-left:0}}@media(max-width:480px){[data-design=sheet][data-page=insights] .ins-sum>*{padding:16px 14px}[data-design=sheet][data-page=insights] .ins-big{font-size:60px}[data-design=sheet][data-page=insights] .ins-cell{padding:2px 10px}[data-design=sheet][data-page=insights] .ins-cell-note{font-size:14px}[data-design=sheet][data-page=insights] .ins-cell-v{font-size:30px}[data-design=sheet][data-page=insights] .ins-f-head{grid-template-columns:32px minmax(0,1fr);padding:16px 14px 0;gap:8px 12px}[data-design=sheet][data-page=insights] .ins-rank{width:30px;height:30px;font-size:17px}[data-design=sheet][data-page=insights] .ins-f-num{font-size:34px}[data-design=sheet][data-page=insights] .ins-f-action{margin:14px 14px 0}[data-design=sheet][data-page=insights] .ins-fact{padding:10px 14px}[data-design=sheet][data-page=insights] .ins-dec{margin:14px 14px 0}[data-design=sheet][data-page=insights] .ins-bar{padding:10px 14px}[data-design=sheet][data-page=insights] .ins-steps>li{grid-template-columns:minmax(0,1fr)}}
@@ -0,0 +1 @@
1
+ import{h as X}from"../chunks/chunk-4LUI7O5P.js";import{a as ee}from"../chunks/chunk-3ROQFHPV.js";import{g as O,h as Z}from"../chunks/chunk-CVB26NMC.js";import"../chunks/chunk-S2ZBMEVA.js";import"../chunks/chunk-ASYNLVOP.js";import{b as W}from"../chunks/chunk-763NH7PP.js";import"../chunks/chunk-24LFKFZ6.js";import{a as R}from"../chunks/chunk-6RLVD2DT.js";import{a as B}from"../chunks/chunk-45PGAQRO.js";import{d as K}from"../chunks/chunk-4WKQTWUC.js";import"../chunks/chunk-VQ5YXO54.js";import{b as q,c as y,e as D,h as Y,i as _}from"../chunks/chunk-76WAVKUG.js";import"../chunks/chunk-VWKSMFWJ.js";import{I as m,L as H,P as C,R as Q,a as c,c as $,k as l,m as k,n as b,o as h,w as e,x as w,z as u}from"../chunks/chunk-GT4EAKAO.js";import{d as E}from"../chunks/chunk-G7NGB5UX.js";E();E();var ne={ci:"CI Health",prs:"Pull Requests",community:"Community",deps:"Dependencies",delivery:"Delivery"},re={snooze:"Snoozed",acknowledge:"Acknowledged",quarantine:"Quarantined",reopen:"Reopened",mute:"Muted"},j=i=>re[i]||i.charAt(0).toUpperCase()+i.slice(1);function J({rows:i,class:n}){return e("dl",{class:"ins-facts"+(n?" "+n:""),children:i.filter(a=>!!a).map(([a,p])=>e("div",{class:"ins-fact",children:[e("dt",{children:a}),e("dd",{children:p})]}))})}var F=i=>`ins-f-${i}`;function M(i){let n=document.getElementById(i);n&&(n.scrollIntoView({behavior:matchMedia("(prefers-reduced-motion: reduce)").matches?"auto":"smooth",block:"start"}),n.focus({preventScroll:!0}))}var oe=(i,n)=>i.map((a,p)=>e(c,{children:[p?", ":"",e("a",{href:`https://github.com/${n}/pull/${a}`,target:"_blank",rel:"noopener noreferrer",children:["#",a]})]}));function U({app:i,f:n,rank:a}){let[p,o]=$(!1),g=n.key||n.kind,d=X[n.kind],f=(n.evidence||[]).slice(0,8),r=n.decision;return e("li",{class:"ins-f"+(r?" is-aside":""),id:a?F(a):void 0,tabIndex:a?-1:void 0,children:[e("div",{class:"ins-f-head",children:[e("span",{class:"ins-rank num","aria-label":a===null?"Decided":`Rank ${a}`,children:a??e(w,{name:"check"})}),e("div",{class:"ins-f-titles",children:[e("h3",{class:"ins-f-title",children:n.title}),n.structural?e("span",{class:"ins-f-kind",children:[e(m,{tone:"watch",icon:"clock",children:"Structural"}),e("span",{class:"ins-f-kind-note",children:"keeps coming back, not a one-off"})]}):null]}),e("div",{class:"ins-f-hours",children:[e("span",{class:"ins-f-num num",children:n.hours}),e("span",{class:"ins-f-unit",children:"hours at stake"})]})]}),n.action?e("div",{class:"ins-f-action",children:[e("span",{class:"ins-k",children:"Action"}),e("p",{children:n.action})]}):null,e(J,{rows:[["Hours at stake",e("span",{class:"num",children:[l(n.hours),n.part_of==="red_ci"?e("span",{class:"ins-dim",children:" (inside the red-check hours below)"}):null]})],["How sure","Estimated"],["Sample",e("span",{class:"num",children:["n = ",n.n]})],["Open since",e("span",{class:"num",children:h(n.open_since)})],n.active_share_90d!==void 0&&["Active",e("span",{class:"num",children:[k(n.active_share_90d)," of the last 90 days"]})],["Area",d?e("a",{href:W(d),children:ne[d]||d}):"\u2013"],f.length>0&&["Evidence",f.map((v,I)=>e(c,{children:[I?", ":"",e("a",{href:v.url,target:"_blank",rel:"noopener noreferrer",children:v.label})]}))]]}),r?e("div",{class:"ins-dec",children:[e("p",{class:"ins-dec-h",children:e(m,{tone:"accent",icon:"check",children:j(r.verb)})}),e(J,{class:"ins-facts-dec",rows:[["Who",r.by||"\u2013"],["Until",e("span",{class:"num",children:r.until?h(r.until):"Reopened by hand"})],["Why",r.reason||"No reason given"],!!r.at&&["Decided on",e("span",{class:"num",children:h(r.at)})]]})]}):null,e("div",{class:"ins-bar",role:"group","aria-label":"Actions",children:[e(O,{app:i,kind:"finding",id:g,verbs:r?["reopen","snooze","acknowledge"]:["snooze","acknowledge"]}),d?e(u,{size:"sm",variant:"plain",href:W(d),iconEnd:"right",children:["Open ",ne[d]||"the area"]}):null,e(u,{size:"sm",variant:"plain",expanded:p,onClick:()=>o(!p),iconEnd:p?"up":"down",children:"As a comment"})]}),p?e("div",{class:"ins-cmds",children:e(Z,{list:[{text:`/stackvitals snooze ${B("finding",g)} for 14d because `,note:"Off the list for two weeks, then back if it still holds."},{text:`/stackvitals acknowledge ${B("finding",g)} because `,note:"The team accepts it; it stays off the list until reopened."}]})}):null]})}function se({app:i,c:n}){let a=n.pr_list||[],p=`select * from tests where test_id = '${n.test.replace(/'/g,"''")}'`,o=n.decision,g=n.state==="flaky";return e("li",{class:"ins-chain card",children:[e("div",{class:"ins-chain-head",children:[e("h3",{class:"ins-chain-test",children:n.test}),o?e(m,{tone:"accent",icon:"check",children:j(o.verb)}):e(m,{tone:"watch",icon:"clock",children:"No decision yet"})]}),e("ol",{class:"ins-steps",children:[e("li",{children:[e("span",{class:"ins-step-k",children:[e(w,{name:"ci"}),g?"Flaky":"Re-run passed"]}),e("div",{class:"ins-step-v",children:g?e(c,{children:["Failed, then passed on the same code ",e("b",{class:"num",children:n.flake_events})," times in ",e("b",{class:"num",children:n.runs})," runs"]}):e(c,{children:["Failed, then passed on a re-run (CI Health calls it ",n.state||"not tracked",")"]})})]}),e("li",{children:[e("span",{class:"ins-step-k",children:[e(w,{name:"prs"}),"Held PRs red"]}),e("div",{class:"ins-step-v",children:[e("b",{class:"num",children:l(n.hours)})," across ",b(n.prs,"merged PR"),", until a re-run passed",a.length?e("div",{class:"ins-step-sub",children:["Pull requests: ",oe(a,i.repo)]}):null]})]}),e("li",{children:[e("span",{class:"ins-step-k",children:[e(w,{name:"community"}),"Owner"]}),e("div",{class:"ins-step-v",children:n.owners?.length?e(c,{children:[n.owners.map((d,f)=>e(c,{children:[f?", ":"",e("code",{class:"code-inline",children:d})]})),e("div",{class:"ins-step-sub",children:["From ",n.owners_from||"CODEOWNERS"]})]}):"Nobody: CODEOWNERS names no one for its file"})]}),e("li",{children:[e("span",{class:"ins-step-k",children:[e(w,{name:o?"check":"clock"}),"Decision"]}),e("div",{class:"ins-step-v",children:o?e(J,{class:"ins-facts-dec",rows:[["What",j(o.verb)],["Who",o.by||"\u2013"],["When",e("span",{class:"num",children:h(o.at)})],["Until",e("span",{class:"num",children:o.until?h(o.until):"Reopened by hand"})],["Why",o.reason||"No reason given"]]}):"None yet: quarantine it or acknowledge it"})]})]}),e("div",{class:"ins-bar",role:"group","aria-label":`Actions for ${n.test}`,children:[o?null:e(O,{app:i,kind:"test",id:n.test,verbs:["quarantine","acknowledge"]}),e(u,{size:"sm",variant:"plain",href:`#/ci/test/${encodeURIComponent(n.test)}`,iconEnd:"right",children:"Its CI page"}),i.pages?.includes("explore.html")?e(u,{size:"sm",variant:"plain",href:`explore.html#sql=${encodeURIComponent(p)}`,iconEnd:"external",children:"Query it in Explore"}):e(u,{size:"sm",variant:"plain",href:"#/explore",iconEnd:"right",children:"Explore"})]})]})}var de={push:"a new commit",rerun:"a passing re-run",merged:"the merge",closed:"closing it",open:"still red"},le={title:"Hours at stake",body:"Waiting or outage time each finding causes, estimated from CI and pull request history. Each hour is counted once, so overlapping findings don't add up twice. It is what fixing could win back, not hours proven lost. People are never ranked.",doc:"methods.md"};function P({label:i,value:n,note:a}){return e("div",{class:"ins-cell",children:[e("dt",{class:"ins-cell-k",children:i}),e("dd",{class:"ins-cell-v num",children:n}),a?e("dd",{class:"ins-cell-note",children:a}):null]})}function A({title:i,note:n,children:a}){return e("div",{class:"ins-tbl",children:[e("div",{class:"ins-tbl-h",children:[e("h3",{children:i}),n?e("span",{class:"ins-tbl-note",children:n}):null]}),a]})}var V=(i,n)=>e("a",{href:`https://github.com/${i}/pull/${n}`,target:"_blank",rel:"noopener noreferrer",children:["#",n]});function pe({app:i}){let n=K({ins:"insights.json"}),[a,p]=$(null),o="Insights",g="What to fix first, ranked by the estimated hours of waiting or outage at stake. People are never ranked.";if(!i)return e(q,{title:o,subtitle:g,children:e(C,{icon:"setup",title:"No StackVitals data here yet",action:e(u,{variant:"filled",href:"#/setup",children:"Set it up"})})});if(!n.ready)return e(Q,{});let d=n.ins;if(!d)return e(q,{title:o,subtitle:g,children:e(C,{icon:"insights",title:"Insights haven't run here yet.",children:"They join CI Health and Pull Requests history after each run."})});let f=d.findings||[],r=f.filter(s=>!s.decision),v=f.filter(s=>s.decision),I=d.opportunity,z=d.track_record,t=d.red_ci,ie=I?.hours??r.reduce((s,x)=>s+x.hours,0),N=a===null?null:r[a],G=d.chains||[],L=t?.open_red||[],S=I?.inside_another??0,T=r[0];return e(q,{title:o,subtitle:g,toolbar:i.modules?.insights?.page?e(u,{variant:"plain",href:i.modules.insights.page,iconEnd:"external",children:"Printable page"}):null,children:[e(y,{title:"Summary",description:"What fixing the open findings could win back, and how earlier top findings turned out.",info:e(H,{info:le}),children:e("div",{class:"ins-sum card",children:[e("div",{class:"ins-sum-top",children:[e("div",{class:"ins-head",children:[e("p",{class:"ins-k",children:"Could be won back"}),e("p",{class:"ins-big num",children:[Math.round(ie),e("small",{children:"hours"})]}),e("p",{class:"ins-dim",children:"Estimated waiting or outage time across the open findings."})]}),e("dl",{class:"ins-cells",children:[e(P,{label:"Open findings",value:r.length,note:r.length?"ranked below by hours":"nothing to fix now"}),e(P,{label:"Counted once",value:S?`${S} overlap`:"Yes",note:S?`${b(S,"flaky-CI finding")} inside the red-check hours, not added twice`:"no hour is added twice"})]})]}),z?.top_findings?e("div",{class:"ins-track",children:[e("p",{class:"ins-k",children:["Track record ",e("span",{class:"ins-dim",children:["since ",h(z.since)]})]}),e("dl",{class:"ins-cells",children:[e(P,{label:"Ranked first",value:z.top_findings,note:"findings at the top of this list"}),e(P,{label:"Shrank by half",value:z.shrank_by_half,note:"later at half the hours or less"}),e(P,{label:"Cleared",value:z.cleared,note:"not seen for a week"})]})]}):null,e("div",{class:"ins-first",children:[e("p",{class:"ins-k",children:"Fix this first"}),T?e("p",{class:"ins-first-v",children:[e("button",{type:"button",class:"ins-link",onClick:()=>M(F(1)),children:T.title}),e("span",{class:"ins-dim num",children:[" \xB7 ",l(T.hours)," at stake, the most of any finding"]})]}):e("p",{class:"ins-first-v ins-dim",children:"Nothing open. Findings appear when CI and pull request history show hours worth winning back."})]}),r.length>1?e("div",{class:"ins-bars",children:[e("p",{class:"ins-k",children:["Hours by finding ",e("span",{class:"ins-dim",children:"pick a bar to read it"})]}),e(ee,{label:"Hours at stake by finding",kind:"hours",height:180,onPick:p,bars:r.map((s,x)=>({label:`#${x+1}`,value:s.hours,tone:s.structural?"watch":"accent"}))}),e("p",{class:"ins-pick","aria-live":"polite",children:N?e(c,{children:[e("b",{class:"num",children:["#",(a??0)+1]})," ",N.title," ",e("span",{class:"ins-dim num",children:["\xB7 ",l(N.hours)]})," ",e("button",{type:"button",class:"ins-link",onClick:()=>M(F((a??0)+1)),children:"Go to it"})]}):e("span",{class:"ins-dim",children:"No bar picked."})})]}):null]})}),e(y,{title:"What to fix first",description:"Biggest wait first. Decide in one click: snooze for a while or acknowledge for good.",action:e(m,{tone:r.length?"watch":"good",icon:null,children:b(r.length,"open finding")}),children:r.length?e("ol",{class:"ins-list",children:r.map((s,x)=>e(U,{app:i,f:s,rank:x+1}))}):e(D,{children:e(C,{icon:"check",title:"Nothing stands out.",children:"Findings appear when CI and pull request history show hours worth winning back."})})}),v.length?e(y,{title:"Acknowledged or snoozed",description:"Off the list until the decision ends or someone reopens it.",action:e(m,{tone:"neutral",icon:null,children:b(v.length,"decided finding")}),children:e("ol",{class:"ins-list",children:v.map(s=>e(U,{app:i,f:s,rank:null}))})}):null,G.length?e(y,{title:"From flaky test to decision",description:"Tests whose failures held merged pull requests red until a re-run passed, traced to an owner and a decision.",children:e("ul",{class:"ins-chains",children:G.map(s=>e(se,{app:i,c:s}))})}):null,t?e(y,{title:"Red checks on pull requests",description:"How long ready pull requests sat with a failing check.",info:t.definition?e(H,{info:{title:"Red checks",body:t.definition,doc:"methods.md"}}):null,children:[t.prs?e(Y,{children:[e(_,{label:"Merged PRs that sat red",value:`${t.red_prs} of ${t.prs}`,note:`${k(t.prs?t.red_prs/t.prs:null)} of merged PRs`}),e(_,{label:"Hours red in all",value:l(t.red_hours_total),note:"across the merged PRs"}),e(_,{label:"Cleared only by a re-run",value:l(t.rerun_hours_total),note:b(t.rerun_waits,"wait")}),e(_,{label:"Merged without any check",value:t.without_checks,note:"merged PRs"}),t.cycle_hours?.red?.median!=null?e(_,{label:"Ready to merge, red PRs",value:l(t.cycle_hours.red.median),note:t.cycle_hours.clear?.median!=null?`vs ${l(t.cycle_hours.clear.median)} for PRs never red (n = ${t.cycle_hours.red.n} and ${t.cycle_hours.clear.n})`:`n = ${t.cycle_hours.red.n}`}):null]}):e(D,{children:e(C,{icon:"prs",title:"No merged pull request to measure yet.",children:"Hours red show once ready pull requests merge."})}),t.measures?.["insight.red_ci_share"]?.low!=null?e("p",{class:"ins-range",children:["The share of merged pull requests that sat red is likely between ",k(t.measures["insight.red_ci_share"].low)," and ",k(t.measures["insight.red_ci_share"].high)," (n = ",t.measures["insight.red_ci_share"].n,")."]}):null,t.rerun_jobs?.length?e(A,{title:"Jobs a re-run cleared",note:"sorted by hours red",children:e(R,{name:"rerun-jobs",search:!1,rows:t.rerun_jobs,initialSort:{key:"hours",desc:!0},columns:[{key:"job",label:"Job",primary:!0},{key:"workflow",label:"Workflow"},{key:"hours",label:"Hours red",num:!0,render:s=>l(s.hours)},{key:"prs",label:"Pull requests",num:!0}]})}):null,t.rerun_tests?.length?e(A,{title:"Tests a re-run cleared",note:"sorted by hours red",children:e(R,{name:"rerun-tests",search:!1,rows:t.rerun_tests,initialSort:{key:"hours",desc:!0},columns:[{key:"test",label:"Test",primary:!0,render:s=>e("a",{class:"mono-soft",href:`#/ci/test/${encodeURIComponent(s.test)}`,children:s.test})},{key:"hours",label:"Hours red",num:!0,render:s=>l(s.hours)},{key:"prs",label:"Pull requests",num:!0},{key:"list",label:"Which",raw:s=>(s.pr_list||[]).join(" "),render:s=>s.pr_list?.length?e("span",{class:"ins-prs",children:s.pr_list.map((x,te)=>e(c,{children:[te?", ":"",V(i.repo,x)]}))}):"\u2013"}]})}):null,t.top?.length?e(A,{title:"Merged pull requests red the longest",children:e(R,{name:"red-top",search:!1,rows:t.top,initialSort:{key:"hours",desc:!0},columns:[{key:"pr",label:"Pull request",primary:!0,render:s=>V(i.repo,s.pr)},{key:"hours",label:"Hours red",num:!0,render:s=>l(s.hours)},{key:"waits",label:"Times it went red",num:!0,raw:s=>(s.waits||[]).length},{key:"end",label:"Last cleared by",raw:s=>de[(s.waits||[]).slice(-1)[0]?.ended_by||""]||"\u2013"}]})}):null,L.length?e(A,{title:"Open and red right now",children:e(R,{name:"open-red",search:!1,rows:L,initialSort:{key:"hours",desc:!0},columns:[{key:"pr",label:"Pull request",primary:!0,render:s=>V(i.repo,s.pr)},{key:"since",label:"Red since",raw:s=>h(s.since)},{key:"hours",label:"Hours red",num:!0,render:s=>l(s.hours)}]})}):null]}):null]})}export{pe as default};
@@ -0,0 +1 @@
1
+ :root{--inv-sec: #7041C2}@media(prefers-color-scheme:dark){:root:not([data-theme=light]){--inv-sec: #B79CFF}}:root[data-theme=dark]{--inv-sec: #B79CFF}.inv-c-feature{background:var(--accent)}.inv-c-fix{background:var(--bad)}.inv-c-maintenance{background:var(--watch)}.inv-c-security{background:var(--inv-sec)}.inv-c-docs{background:var(--good)}.inv-c-other{background:var(--line-strong)}.inv-dot{display:inline-block;width:10px;height:10px;border-radius:3px;margin-right:6px;vertical-align:0;flex:none}.inv-legend{list-style:none;margin:0 0 14px;padding:0;display:flex;flex-wrap:wrap;gap:6px 16px;font-size:13.5px;font-weight:600}.inv-legend li{display:inline-flex;align-items:center;gap:2px}.inv-legend .muted{margin-left:4px}.inv-stack{display:flex;gap:10px;height:220px;padding:4px 2px 0;border-radius:14px}.inv-col{flex:1;min-width:0;display:flex;flex-direction:column;align-items:center;gap:6px;cursor:pointer}.inv-n{font-size:13px;font-weight:700;color:var(--ink-2)}.inv-track{flex:1;width:100%;max-width:64px;display:flex;align-items:flex-end}.inv-fill{width:100%;display:flex;flex-direction:column-reverse;gap:2px;border-radius:10px;overflow:hidden;transform-origin:bottom;animation:barGrow .6s var(--spring) backwards;transition:opacity var(--dur-1)}.inv-fill i{display:block;min-height:2px}.inv-stack:has(.inv-col.is-on) .inv-col:not(.is-on) .inv-fill{opacity:.45}.inv-label{font-size:12.5px;font-weight:650;color:var(--ink-2);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}.inv-pick{margin-top:12px;font-size:14.5px;min-height:1.5em}.inv-toggle{display:inline-flex;align-items:center;gap:10px;font-size:14px;font-weight:600;color:var(--ink-2)}.inv-text{font-size:14px;margin:0 0 10px;max-width:75ch}.inv-sorted{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,360px),1fr));gap:14px;align-items:start}.inv-rules{margin-top:14px}.inv-facts{margin-bottom:14px}.inv-nums{margin-top:14px}.inv-after{margin-top:10px}.section-body>.inv-text{margin-top:10px}@media(max-width:480px){.inv-stack{gap:6px;height:190px}.inv-label{font-size:11px}}[data-design=sheet][data-page=investment] .inv-c-feature{background:var(--chart-1)}[data-design=sheet][data-page=investment] .inv-c-fix{background:var(--chart-2)}[data-design=sheet][data-page=investment] .inv-c-maintenance{background:var(--chart-3)}[data-design=sheet][data-page=investment] .inv-c-security{background:repeating-linear-gradient(45deg,var(--chart-2) 0 1.5px,transparent 1.5px 5px);outline:1px solid var(--chart-2);outline-offset:-1px}[data-design=sheet][data-page=investment] .inv-c-docs{background:repeating-linear-gradient(-45deg,var(--chart-1) 0 1.5px,transparent 1.5px 5px);outline:1px solid var(--chart-1);outline-offset:-1px}[data-design=sheet][data-page=investment] .inv-c-other{background:transparent;outline:1px solid var(--ink-3);outline-offset:-1px}[data-design=sheet][data-page=investment] .card{border:1.5px solid var(--frame)}[data-design=sheet][data-page=investment] .card>.table-wrap.card{border:0}[data-design=sheet][data-page=investment] :is(.inv-text,.inv-pick){font-size:15px}[data-design=sheet][data-page=investment] .inv-legend{margin:-18px -18px 16px;padding:10px 18px;gap:8px 22px;background:var(--strip);border-bottom:1px solid var(--line-strong);font:600 15px/1.35 var(--font);color:var(--ink)}[data-design=sheet][data-page=investment] .inv-legend li{gap:0}[data-design=sheet][data-page=investment] .inv-dot{width:13px;height:13px;margin-right:8px;vertical-align:-1px}[data-design=sheet][data-page=investment] .inv-legend .muted{margin-left:6px;font:400 15px var(--font);font-variant-numeric:tabular-nums;color:var(--ink-2)}[data-design=sheet][data-page=investment] .inv-stack{padding:4px 0 0;border-bottom:0}[data-design=sheet][data-page=investment] .inv-track{max-width:40px;border-bottom:1px solid var(--ink)}[data-design=sheet][data-page=investment] .inv-col{position:relative}[data-design=sheet][data-page=investment] .inv-n{font:700 14px/1.2 var(--font);font-variant-numeric:tabular-nums;color:var(--ink)}[data-design=sheet][data-page=investment] .inv-label{padding:1px 6px;font:600 14px/1.3 var(--font);color:var(--ink-2)}[data-design=sheet][data-page=investment] .inv-col.is-on .inv-label{background:var(--ink);color:var(--bg)}[data-design=sheet][data-page=investment] .inv-stack:focus-visible{outline:2px solid var(--focus);outline-offset:4px}@media(prefers-reduced-motion:no-preference){[data-design=sheet][data-page=investment] .inv-fill{animation:invGrow .6s var(--sv-ease) backwards}}@keyframes invGrow{0%{transform:scaleY(0)}}[data-design=sheet][data-page=investment] .inv-pick{padding-top:12px;border-top:1px solid var(--line-strong)}[data-design=sheet][data-page=investment] .inv-pick b{font-weight:700}[data-design=sheet][data-page=investment] .inv-toggle{font-weight:600;font-size:15px;color:var(--ink)}@media(max-width:480px){[data-design=sheet][data-page=investment] .inv-label{padding:1px 3px}}.blk-tbl{min-width:0}.blk-tbl+.blk-tbl,.stats+.blk-tbl,.blk-tbl+.stats,.blk-facts+.blk-tbl,.blk-tbl+.blk-facts,.blk-panel+.blk-tbl,.blk-tbl+.blk-panel,.dl-strip+.blk-tbl,.blk-tbl+.blk-grid,.blk-grid+.blk-tbl,.stats+.blk-panel,.blk-panel+.blk-panel,.stats+.blk-grid{margin-top:18px}.blk-tbl-h{display:flex;gap:4px 12px;align-items:baseline;flex-wrap:wrap;padding:10px 14px;background:var(--surface);border:1px solid var(--line);border-bottom:0;border-radius:var(--r-lg) var(--r-lg) 0 0}.blk-tbl-h h3{margin:0;font-size:15.5px;font-weight:700}.blk-tbl-note{font-size:13px;color:var(--ink-2)}.blk-tbl-act{margin-left:auto;display:inline-flex;gap:8px;align-items:center}.blk-tbl .table-wrap{border-top-left-radius:0;border-top-right-radius:0}.blk-tbl>.card:not(.table-wrap){border-top-left-radius:0;border-top-right-radius:0}@media(min-width:641px){.blk-tbl .table :is(th,td)+:is(th,td){border-left:1px solid var(--line)}}.blk-h{display:flex;gap:4px 12px;align-items:baseline;flex-wrap:wrap;margin:26px 0 10px;font-size:16px;font-weight:700}.blk-h:first-child{margin-top:0}.blk-h-note{font-size:13.5px;font-weight:400;color:var(--ink-2)}.blk-panel{display:flex;flex-direction:column;min-width:0;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden}.blk-panel-h{display:flex;gap:6px 12px;align-items:center;justify-content:space-between;flex-wrap:wrap;min-height:44px;padding:10px 16px;background:var(--surface-2);border-bottom:1px solid var(--line)}.blk-panel-h h3{margin:0;font-size:15.5px;font-weight:700;overflow-wrap:anywhere;min-width:0}.blk-panel-state{font-size:14px;font-weight:600}.blk-panel-b{flex:1;display:flex;flex-direction:column;gap:14px;padding:14px 16px 16px;min-width:0}.blk-panel-b>*{margin:0}.blk-bar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;padding:10px 16px;border-top:1px solid var(--line);background:var(--surface-2)}.blk-panel.blk-good{border-top:4px solid var(--good)}.blk-panel.blk-watch{border-top:4px solid var(--watch)}.blk-panel.blk-bad{border-top:4px solid var(--bad)}.blk-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,320px),1fr));gap:12px;align-items:stretch}.blk-grid>:is(.blk-tbl,.blk-panel){margin-top:0}.blk-facts{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:8px 18px;margin:0;font-size:14px}.blk-fact{display:contents}.blk-fact dt{font-weight:650;color:var(--ink-2)}.blk-fact dd{margin:0;min-width:0;overflow-wrap:anywhere}@media(max-width:520px){.blk-facts{grid-template-columns:minmax(0,1fr);gap:2px}.blk-fact dd{margin-bottom:8px}}.blk-mark{display:inline-flex;align-items:center;gap:7px;font-weight:650;white-space:nowrap}.blk-mark i{width:9px;height:9px;border-radius:50%;flex:none;background:var(--ink-3)}.blk-mark-good i{background:var(--good)}.blk-mark-watch i{background:var(--watch)}.blk-mark-bad i{background:var(--bad)}.blk-mark-accent i{background:var(--accent)}.blk-mark-neutral i{background:none;border:1.5px solid var(--ink-2)}.blk-mark-good{color:var(--good)}.blk-mark-bad{color:var(--bad)}.blk-mark-watch{color:var(--watch)}.blk-mark-neutral{color:var(--ink-2)}.blk-machine .blk-machine-cmd{display:flex;flex-direction:column;gap:10px;min-width:0}.blk-form{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr));gap:12px 16px;align-items:start}.blk-form .field{min-width:0}.blk-form textarea.input{min-height:96px;padding:10px 12px;resize:vertical;font:400 14px/1.5 var(--mono);width:100%}.blk-note{font-size:13.5px;color:var(--ink-2);margin:0;max-width:80ch}.blk-list{margin:0;padding-left:20px;display:grid;gap:4px;font-size:14px}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-tbl-h{min-height:42px;padding:9px 14px;background:var(--strip);border:1.5px solid var(--frame);border-bottom:1px solid var(--line-strong);border-radius:0}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-tbl-h h3{font-size:15.5px;font-weight:700;color:var(--ink)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-tbl-note{font-size:14px;color:var(--ink-2)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-tbl>:is(.table-wrap,.card){border:1.5px solid var(--frame);border-top:0}@media(min-width:641px){[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-tbl .table :is(th,td)+:is(th,td){border-left-color:var(--line)}}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-panel{border:1.5px solid var(--frame);border-radius:0}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-panel.blk-good{border-top:5px solid var(--sv-mint)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-panel.blk-watch{border-top:5px solid var(--sv-amber)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-panel.blk-bad{border-top:5px solid var(--sv-coral)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-panel-h{min-height:42px;padding:9px 14px;background:var(--strip);border-bottom:1px solid var(--line-strong)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-panel-h h3{font-size:15.5px;color:var(--ink)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-panel-state{font-size:15px}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-panel-b{padding:14px;font-size:15px}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-bar{padding:10px 14px;background:var(--surface);border-top:1px solid var(--line-strong)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-facts{font-size:15px;gap:8px 20px}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-fact dt{font-weight:600;color:var(--ink-2)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark{font-size:15px;font-weight:700;color:var(--ink)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark i{width:13px;height:13px;border:0;border-radius:0;background:center / contain no-repeat}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-good i{background-image:var(--mark-good)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-watch i{background-image:var(--mark-watch)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-bad i{background-image:var(--mark-bad)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-good{color:var(--good)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-bad{color:var(--bad)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-watch{color:var(--watch)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-neutral{color:var(--ink-2)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-neutral i{width:10px;height:10px;border:1.5px solid currentColor}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-accent i{width:10px;height:10px;background:var(--sv-blue)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-note{font-size:15px}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-list{font-size:15px}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-form textarea.input{border-radius:0}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-h{padding-bottom:6px;border-bottom:1.5px solid var(--frame);font-size:17px;color:var(--ink)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-h-note{font-size:15px}
@@ -0,0 +1,3 @@
1
+ import{a as x,c as C,d as q}from"../chunks/chunk-4H53OYLG.js";import{a as U,b as V,c as W,d as G}from"../chunks/chunk-3G4SQNUC.js";import"../chunks/chunk-LAAGCPU3.js";import"../chunks/chunk-24LFKFZ6.js";import"../chunks/chunk-6BDBXA6V.js";import"../chunks/chunk-MAPYGK3P.js";import{a as k}from"../chunks/chunk-6RLVD2DT.js";import{d as z}from"../chunks/chunk-4WKQTWUC.js";import{g as B,s as I}from"../chunks/chunk-VQ5YXO54.js";import{b as f,c as b,d as N,e as A}from"../chunks/chunk-76WAVKUG.js";import{b as O}from"../chunks/chunk-VWKSMFWJ.js";import{L as E,O as L,P as R,R as _,S as j,a as F,c as P,m as g,s as $,w as e,z as v}from"../chunks/chunk-GT4EAKAO.js";import{d as D}from"../chunks/chunk-G7NGB5UX.js";D();var w=[["feature","Feature"],["fix","Fix"],["maintenance","Maintenance"],["security","Security"],["docs","Docs"],["other","Not sorted"]],Y=`[investment.labels]
2
+ feature = ["kind/feature"]
3
+ maintenance = ["area: platform"]`,Q={label:"A label",issue:"The linked issue's type",changelog:"A changelog fragment",title:"The title",only:"The files changed",other:"Nothing matched"},X=[["Your own label rules","[investment.labels] in .github/stackvitals.toml"],["A security label","security, vulnerability"],["The linked Jira or Linear issue's type","Story, Bug, Task"],["Common labels","bug, enhancement, chore, documentation"],["The title's prefix","fix:, feat(api):, docs:, Release 2.1"],["A changelog fragment","news/123.bugfix.rst"],["The files changed","only docs, tests, or CI and dependency files"],["The title's first verb","Fix, Add, Update"],["The title mentions a fix","crash, regression, bug"]],y=r=>`${$(r)} ${r.slice(0,4)}`;function Z({months:r}){let[i,s]=P(null),m=Math.max(1,...r.map(n=>n.n)),c=r[i??r.length-1];return e("div",{children:[e("div",{class:"inv-stack",role:"listbox","aria-label":"Merged pull requests by month and kind of work",tabIndex:0,onKeyDown:n=>{if(n.key!=="ArrowLeft"&&n.key!=="ArrowRight")return;n.preventDefault();let o=n.key==="ArrowRight"?1:-1;s(Math.max(0,Math.min(r.length-1,(i??r.length-1)+o)))},children:r.map((n,o)=>e("div",{role:"option","aria-selected":i===o,class:"inv-col"+(i===o?" is-on":""),onClick:()=>s(o),onMouseEnter:()=>s(o),"aria-label":`${y(n.month)}: ${n.n} merged; ${w.filter(([p])=>n.counts[p]).map(([p,h])=>`${h} ${n.counts[p]}`).join(", ")}`,children:[e("span",{class:"inv-n num","aria-hidden":"true",children:n.n}),e("span",{class:"inv-track","aria-hidden":"true",children:e("span",{class:"inv-fill",style:{height:`${n.n/m*100}%`,animationDelay:`${o*50}ms`},children:w.map(([p])=>n.counts[p]?e("i",{class:`inv-c-${p}`,style:{flexGrow:n.counts[p]}}):null)})}),e("span",{class:"inv-label","aria-hidden":"true",children:$(n.month)})]}))}),c?e("p",{class:"inv-pick","aria-live":"polite",children:[e("b",{children:y(c.month)}),": ",c.n," merged",w.filter(([n])=>c.counts[n]).map(([n,o])=>`, ${o.toLowerCase()} ${c.counts[n]}`).join(""),"."]}):null]})}function ee({app:r}){let i=z({d:"delivery.json"}),[s,m]=U(),[c,n]=P(null),[o,p]=P(!1),h="Investment",S="Where engineering time goes: features, fixes, upkeep, security and docs, from merged pull requests.";if(!r)return e(f,{title:h,subtitle:S,children:e(R,{icon:"setup",title:"No StackVitals data here yet",action:e(v,{variant:"filled",href:"#/setup",children:"Set it up"})})});if(!i.ready)return e(_,{});if(!i.d)return e(f,{title:h,subtitle:S,children:e(R,{icon:"investment",title:"Delivery hasn't run here yet.",action:e(v,{variant:"filled",href:"#/settings",icon:"settings",children:"Turn it on"}),children:"The mix comes with Delivery, which runs with Team Flow on the schedule."})});let a=i.d.investment,d=i.d.epics;if(a===void 0)return e(f,{title:h,subtitle:S,children:e(R,{icon:"clock",title:"Not measured yet.",children:"The next run with this version fills it in."})});if(!a)return e(f,{title:h,subtitle:S,children:e(R,{icon:"investment",title:"No merged pull requests by people in the last six months.",children:"The mix shows once people's work merges."})});let M=w.filter(([t])=>a.counts[t]).map(([t,l])=>({id:t,name:l,sub:`${a.counts[t]} of ${a.n} merged PRs`,kind:"share",better:null,period:"month",points:a.months.map(u=>({label:$(u.month),value:u.n?(u.counts[t]||0)/u.n:0,n:u.n})),meaning:(u,K)=>`${g(u)} of ${K.n??"the"} pull requests merged that month were ${t==="other"?"not sorted":`${l.toLowerCase()} work`}.`})),T=M.find(t=>t.id===c)||M[0],J=Object.entries(a.decided_by);return e(f,{title:h,subtitle:S,children:[T?e(b,{title:"Mix of work",description:`Each kind's share of merged pull requests by month, since ${y(a.since)}. Pick a row to chart it.`,info:e(E,{info:{title:"Mix of work",body:"Merged pull requests into the default branch by people and AI agents, sorted into one kind of work each. Update bots' pull requests are counted apart.",facts:[["Merged PRs",String(a.n)],["Update-bot PRs, apart",String(a.bots)]]}}),children:e(N,{ratio:"lead",children:[e(A,{children:e(V,{metric:T,ranges:s,setRange:m})}),e(G,{label:"Kinds of work",items:M.map(t=>({...W(t,s[t.period]||6),value:g(a.shares[t.id]),sub:e(F,{children:[e("i",{class:`inv-dot inv-c-${t.id}`}),a.counts[t.id]," of ",a.n," merged PRs"]})})),selected:T.id,onSelect:n})]})}):null,e(b,{title:"Month by month",description:`People and AI agents; ${a.bots} update-bot pull requests counted apart. Tap a month to read its mix.`,action:e("label",{class:"inv-toggle",children:[e("span",{children:"Show numbers"}),e(O,{checked:o,onChange:p,label:"Show numbers"})]}),children:[e(A,{children:[e("ul",{class:"inv-legend",children:w.map(([t,l])=>e("li",{children:[e("i",{class:`inv-dot inv-c-${t}`}),l," ",e("span",{class:"muted num",children:a.counts[t]||0})]}))}),e(Z,{months:a.months})]}),o?e(x,{title:"The numbers behind the bars",note:"merged pull requests by month and kind",class:"inv-nums",children:e(k,{name:"investment-months",caption:"Merged pull requests by month and kind",search:!1,rows:a.months.map(t=>({...t,...t.counts})),columns:[{key:"month",label:"Month",primary:!0,raw:t=>y(t.month)},...w.map(([t,l])=>({key:t,label:l,num:!0})),{key:"n",label:"All",num:!0}]})}):null]}),e(b,{title:"How each pull request was sorted",description:"The first rule that matches decides; your own label rules come first.",children:[e("div",{class:"inv-sorted",children:[e(x,{title:"What decided each one",note:`${a.n} merged pull requests`,children:e(k,{name:"investment-decided",search:!1,rows:J.map(([t,l])=>({k:t,n:l,share:a.n?l/a.n:null})),initialSort:{key:"n",desc:!0},columns:[{key:"k",label:"Decided by",primary:!0,raw:t=>Q[t.k]||t.k},{key:"n",label:"PRs",num:!0},{key:"share",label:"Share",num:!0,render:t=>g(t.share)}]})}),e(x,{title:"The order the rules are tried",note:"the first match wins",children:e(k,{name:"investment-order",search:!1,rows:X.map(([t,l],u)=>({i:u+1,rule:t,example:l})),columns:[{key:"i",label:"Step",num:!0},{key:"rule",label:"Rule",primary:!0},{key:"example",label:"For example"}]})})]}),e(C,{title:"Sort your own labels",class:"inv-rules",bar:e(v,{size:"sm",variant:"tinted",href:"#/settings?module=delivery",iconEnd:"right",children:"Open Settings"}),children:[e("p",{class:"blk-note",children:["Name the labels that mean each kind of work in Settings (Delivery, labels per kind of work), or paste this into ",e("code",{children:".github/stackvitals.toml"})," with your own labels; the next run sorts again."]}),e(L,{code:Y,title:".github/stackvitals.toml"})]})]}),d?e(b,{title:"By epic or project",description:`Merged pull requests linked to Jira or Linear issues since ${y(d.since)}.`,children:[e(C,{title:"Linked work",class:"inv-facts",children:e(q,{rows:[["Linked pull requests",String(d.linked)],["Without an epic or project",String(d.no_epic)],["On feature issues",e(F,{children:[g(d.feature_share)," ",e("span",{class:"muted",children:"(the part teams often capitalise; an estimate from issue types, not an accounting figure)"})]})]]})}),e(x,{title:"Epics and projects",note:"largest first",children:e(k,{name:"epics",caption:"By epic or project",search:!1,rows:[...d.epics.map(t=>({...t,name:t.title||(t.epic.startsWith("linear:project:")?"A Linear project (names hidden on public repos)":t.epic)})),...d.no_epic?[{epic:"",name:"No epic or project",prs:d.no_epic,share:d.no_epic/d.linked}]:[]],columns:[{key:"name",label:"Epic or project",primary:!0},{key:"prs",label:"PRs",num:!0},{key:"share",label:"Share",num:!0,render:t=>g(t.share)}]})})]}):null,i.d.capex?e(te,{c:i.d.capex}):null]})}async function H(){let r=await B(I.get().source,"capex.csv");if(!r){j("The CSV isn't published here; the next Delivery run writes it","bad");return}let i=document.createElement("a");i.href=URL.createObjectURL(new Blob([r],{type:"text/csv"})),i.download="stackvitals-capex.csv",i.click(),URL.revokeObjectURL(i.href)}function te({c:r}){let i=[...r.months||[]].reverse();return e(b,{title:"For finance",description:"Author-weeks by kind of work each month, and a CSV of every merged pull request an auditor can follow back to GitHub.",action:e(v,{size:"sm",variant:"tinted",icon:"down",onClick:()=>{H()},children:"Download CSV"}),children:[e(C,{title:"What the CSV holds",class:"inv-facts",bar:e(v,{size:"sm",variant:"tinted",icon:"down",onClick:()=>{H()},children:"Download CSV"}),children:e(q,{rows:[["Rows in the CSV",`${r.rows} merged pull requests, last 12 months`],["Each row has","month, merge time, link, kind of work, how that was decided, epic, and whether a person or a coding agent wrote it"],["An author-week","one person's pull requests of one kind in one ISO week"],["Names","none: the file names no one"]]})}),e(x,{title:"Author-weeks by kind of work",note:"newest month first",children:e(k,{name:"capex",caption:"Author-weeks by kind of work",search:!1,rows:i,columns:[{key:"month",label:"Month",primary:!0,raw:s=>y(s.month)},{key:"prs",label:"Merged PRs",num:!0},{key:"feature",label:"Feature author-weeks",num:!0,raw:s=>s.author_weeks?.feature??0},{key:"other",label:"Other author-weeks",num:!0,raw:s=>Object.entries(s.author_weeks||{}).filter(([m])=>m!=="feature").reduce((m,[,c])=>m+c,0)},{key:"feature_share",label:"Feature share",num:!0,render:s=>s.feature_share==null?"\u2013":`${Math.round(s.feature_share*100)}%`},{key:"agent_prs",label:"By agents",num:!0}]})}),e("p",{class:"blk-note inv-after",children:"Feature work is what teams usually capitalise; the rule stays yours and your auditor's."})]})}export{ee as default};
@@ -0,0 +1 @@
1
+ .conditions{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:8px 32px;align-items:end;padding:26px 2px 4px}.cond-word{font-size:46px;line-height:1.05;font-weight:800;letter-spacing:-.03em}.cond-line{margin-top:8px;font-size:19px;font-weight:650;max-width:52ch;letter-spacing:-.005em;overflow-wrap:anywhere}.cond-sub{margin-top:6px;color:var(--ink-2);font-size:14.5px}.stake{text-align:right}.stake b{display:block;font-size:56px;line-height:1;font-weight:800;letter-spacing:-.035em}.stake span{color:var(--ink-2);font-size:14px;font-weight:650;display:inline-flex;align-items:center;gap:6px}.tiles{display:grid;grid-template-columns:repeat(auto-fill,minmax(180px,1fr));gap:12px}.tile{display:flex;flex-direction:column;gap:4px;min-height:168px;padding:14px 15px;border-radius:var(--r-md);background:var(--surface);border:1px solid var(--line);color:var(--ink);text-decoration:none;text-align:left;animation:tileIn var(--dur-3) var(--spring) backwards;min-width:0}.tile:hover{border-color:var(--line-strong)}@keyframes tileIn{0%{opacity:0;transform:translateY(8px) scale(.98)}}.tile.tone-good{background:var(--good-soft);border-color:transparent}.tile.tone-ok{background:var(--watch-soft);border-color:transparent}.tile.tone-bad{background:var(--bad-soft);border-color:transparent}.tile.tone-off{background:var(--surface-2);border-style:dashed;border-color:var(--line-strong)}.tile-top{display:flex;align-items:center;gap:8px;font-size:13.5px;font-weight:650;color:var(--ink-2)}.tile-top .ic{width:22px;height:22px}.tile.tone-good .tile-top .ic{color:var(--good)}.tile.tone-ok .tile-top .ic{color:var(--watch)}.tile.tone-bad .tile-top .ic{color:var(--bad)}.tile-word{font-size:21px;font-weight:750;letter-spacing:-.015em}.tile-value{font-size:26px;font-weight:800;letter-spacing:-.02em;line-height:1.1}.tile.tone-off .tile-value{display:none}.tile-note{font-size:12.5px;color:var(--ink-2);line-height:1.4;overflow-wrap:anywhere}.tile-alarm{margin-top:auto;display:inline-flex;align-items:center;gap:5px;font-size:12.5px;font-weight:700;color:var(--bad)}.tile-alarm .ic{width:15px;height:15px}.sub-when:before{content:"\b7 "}@media(max-width:640px){.sub-when{flex-basis:100%}.sub-when:before{content:none}}@media(max-width:820px){.conditions{grid-template-columns:minmax(0,1fr);padding-top:18px;gap:10px}.cond-word{font-size:36px}.cond-line{font-size:17px}.stake{text-align:left;display:flex;align-items:baseline;gap:10px;flex-wrap:wrap}.stake b{font-size:40px}.tiles{display:flex;overflow-x:auto;scroll-snap-type:x mandatory;gap:10px;margin:0 calc(-1 * var(--gutter));padding:2px var(--gutter) 6px;scrollbar-width:none;overscroll-behavior-x:contain}.tiles::-webkit-scrollbar{display:none}.tile{flex:0 0 168px;scroll-snap-align:start;scroll-margin-left:var(--gutter)}}[data-design=sheet][data-page=overview] .conditions{margin-top:20px;padding:0;gap:0;align-items:stretch;border:1.5px solid var(--frame);background:var(--surface)}[data-design=sheet][data-page=overview] .cond-text{padding:22px 26px}[data-design=sheet][data-page=overview] .cond-word{font-family:var(--display);font-weight:700;font-size:clamp(42px,4.6vw,56px);line-height:1;letter-spacing:-.01em}[data-design=sheet][data-page=overview] .cond-line{margin-top:12px;font-size:19px;font-weight:600;letter-spacing:0}[data-design=sheet][data-page=overview] .cond-sub{margin-top:6px;font-size:15.5px;color:var(--ink-2)}[data-design=sheet][data-page=overview] .stake{display:flex;flex-direction:column;justify-content:space-between;align-items:flex-start;min-width:200px;padding:0 0 18px;text-align:left;background:var(--strip);border-left:1.5px solid var(--frame)}[data-design=sheet][data-page=overview] .stake:before{content:"Readout";align-self:stretch;padding:8px 18px;border-bottom:1px solid var(--line-strong);font-size:13.5px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-2)}[data-design=sheet][data-page=overview] .stake b{padding:14px 18px 0;font-family:var(--display);font-weight:700;font-size:72px;line-height:.95;letter-spacing:-.01em}[data-design=sheet][data-page=overview] .stake>span{padding:4px 18px 0;font-size:15px;font-weight:600;color:var(--ink-2)}[data-design=sheet][data-page=overview] .tiles{grid-template-columns:repeat(3,minmax(0,1fr));gap:14px}@media(max-width:1200px){[data-design=sheet][data-page=overview] .tiles{grid-template-columns:repeat(2,minmax(0,1fr))}}[data-design=sheet][data-page=overview] .tile,[data-design=sheet][data-page=overview] .tile:is(.tone-good,.tone-ok,.tone-bad){display:grid;grid-template-columns:minmax(0,1fr) auto;grid-template-rows:auto auto auto 1fr;align-content:start;gap:0;min-height:0;padding:0;background:var(--surface);border:1.5px solid var(--frame);border-top-width:5px}[data-design=sheet][data-page=overview] .tile.tone-good,[data-design=sheet][data-page=overview] .tile.tone-good:hover{border-top-color:var(--sv-mint)}[data-design=sheet][data-page=overview] .tile.tone-ok,[data-design=sheet][data-page=overview] .tile.tone-ok:hover{border-top-color:var(--sv-amber)}[data-design=sheet][data-page=overview] .tile.tone-bad,[data-design=sheet][data-page=overview] .tile.tone-bad:hover{border-top-color:var(--sv-coral)}[data-design=sheet][data-page=overview] .tile.tone-off{background:var(--surface);border-style:dashed;border-color:var(--line-strong);border-top-width:1.5px}[data-design=sheet][data-page=overview] .tile:hover{border-color:var(--ink)}[data-design=sheet][data-page=overview] :is(.tile-top,.tile-word){grid-row:1;background:var(--strip);border-bottom:1px solid var(--line-strong);padding:9px 14px;min-height:42px}[data-design=sheet][data-page=overview] .tile-top{grid-column:1;font-size:15.5px;font-weight:700;color:var(--ink);gap:0;min-width:0;padding-right:6px}[data-design=sheet][data-page=overview] .tile-top .ic{display:none}[data-design=sheet][data-page=overview] .tile-word{grid-column:2;display:flex;align-items:center;gap:7px;font-size:15px;font-weight:700;letter-spacing:0;padding-left:6px}[data-design=sheet][data-page=overview] .tile-word:before{content:"";width:13px;height:13px;flex:none;background:center / contain no-repeat}[data-design=sheet][data-page=overview] .tone-good .tile-word{color:var(--good)}[data-design=sheet][data-page=overview] .tone-good .tile-word:before{background-image:var(--mark-good)}[data-design=sheet][data-page=overview] .tone-ok .tile-word{color:var(--watch)}[data-design=sheet][data-page=overview] .tone-ok .tile-word:before{background-image:var(--mark-watch)}[data-design=sheet][data-page=overview] .tone-bad .tile-word{color:var(--bad)}[data-design=sheet][data-page=overview] .tone-bad .tile-word:before{background-image:var(--mark-bad)}[data-design=sheet][data-page=overview] .tone-off .tile-word{color:var(--ink-2)}[data-design=sheet][data-page=overview] .tone-off .tile-word:before{width:10px;height:10px;border:1.5px dashed currentColor}[data-design=sheet][data-page=overview] .tile-value{grid-column:1 / -1;padding:12px 14px 0;font-family:var(--display);font-weight:700;font-size:46px;line-height:1;letter-spacing:-.01em}[data-design=sheet][data-page=overview] .tile-note{grid-column:1 / -1;padding:6px 14px 14px;font-size:15px;line-height:1.45;color:var(--ink-2)}[data-design=sheet][data-page=overview] .tile-alarm{grid-column:1 / -1;align-self:end;margin:0;padding:9px 14px;gap:7px;border-top:1px solid var(--line-strong);font-size:15px;font-weight:700;color:var(--bad)}[data-design=sheet][data-page=overview] .tile-alarm .ic{display:none}[data-design=sheet][data-page=overview] .tile-alarm:before{content:"";width:13px;height:13px;flex:none;background:var(--mark-bad) center / contain no-repeat}@media(max-width:820px){[data-design=sheet][data-page=overview] .conditions{grid-template-columns:minmax(0,1fr);margin-top:16px}[data-design=sheet][data-page=overview] .cond-text{padding:18px 16px}[data-design=sheet][data-page=overview] .cond-word{font-size:42px}[data-design=sheet][data-page=overview] .cond-line{font-size:17.5px}[data-design=sheet][data-page=overview] .stake{flex-direction:row;flex-wrap:wrap;align-items:baseline;justify-content:flex-start;min-width:0;padding:0 0 14px;border-left:0;border-top:1.5px solid var(--frame)}[data-design=sheet][data-page=overview] .stake:before{flex-basis:100%;padding:7px 16px}[data-design=sheet][data-page=overview] .stake b{padding:10px 0 0 16px;font-size:52px}[data-design=sheet][data-page=overview] .stake>span{padding:0 16px 0 10px}[data-design=sheet][data-page=overview] .tiles{display:grid;grid-template-columns:minmax(0,1fr);overflow:visible;margin:0;padding:0;gap:12px}[data-design=sheet][data-page=overview] .tile{flex:none}[data-design=sheet][data-page=overview] .tile-value{font-size:42px}}@media(min-width:520px)and (max-width:820px){[data-design=sheet][data-page=overview] .tiles{grid-template-columns:repeat(2,minmax(0,1fr))}}.ov-where{font-weight:650;overflow-wrap:anywhere;text-decoration:none}.ov-where:hover{text-decoration:underline}.ov-needs .table td:last-child .btn{white-space:nowrap}.ov-where.is-id,.ov-what-id{font-family:var(--mono);font-size:.9em;overflow-wrap:anywhere}.ov-what{display:flex;flex-direction:column;gap:1px;min-width:0}.ov-what-kind{font-size:12.5px;font-weight:650;color:var(--ink-2)}.ov-sub{margin:20px 0 8px;font-size:15px;font-weight:700}.ov-decisions>.ov-sub:first-child{margin-top:0}.ov-fixes{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(auto-fit,minmax(270px,1fr));gap:12px}.ov-fix{display:flex;flex-direction:column;min-width:0;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-md)}.ov-fix-head{display:flex;align-items:center;gap:10px;padding:12px 16px 0}.ov-fix-head .pill{margin-left:auto}.ov-fix-rank{width:30px;height:30px;flex:none;border-radius:50%;display:grid;place-items:center;background:var(--accent-soft);color:var(--accent);font-weight:800}.ov-fix-kicker{font-size:13px;font-weight:650;color:var(--ink-2)}.ov-fix-body{flex:1;display:flex;flex-direction:column;padding:10px 16px 0}.ov-fix-body:last-child{padding-bottom:14px}.ov-fix-title{margin:0;font-size:16px;font-weight:700;line-height:1.35;overflow-wrap:anywhere}.ov-fix-action{margin:4px 0 0;font-size:14px;color:var(--ink-2);overflow-wrap:anywhere}.ov-facts{margin:auto 0 0;padding-top:14px;display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:10px}.ov-facts>div{min-width:0}.ov-facts dt{font-size:12.5px;font-weight:650;color:var(--ink-2)}.ov-facts dd{margin:2px 0 0;font-size:15px;font-weight:700;overflow-wrap:anywhere}.ov-fix-foot{padding:12px 16px 14px}.ov-builder{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg)}.ov-build-strip{grid-column:1 / -1;display:flex;justify-content:space-between;gap:10px;flex-wrap:wrap;padding:12px 18px;border-bottom:1px solid var(--line);font-weight:700}.ov-build-strip span+span{font-weight:600;color:var(--ink-2);font-size:14px}.ov-build-form{padding:18px;min-width:0}.ov-build-send{display:flex;flex-direction:column;gap:12px;padding:18px;min-width:0;border-left:1px solid var(--line)}.ov-build-h{font-weight:700;font-size:15px}.ov-build-sum{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:6px 16px;margin:0;font-size:14px}.ov-build-sum>div{display:contents}.ov-build-sum dt{color:var(--ink-2);font-weight:650}.ov-build-sum dd{margin:0;min-width:0;overflow-wrap:anywhere}.ov-build-send .cmd-wrap{min-width:0}.ov-build-send .cmd code{overflow-wrap:anywhere}.ov-build-note{font-size:13px;color:var(--ink-2)}@media(max-width:900px){.ov-builder{grid-template-columns:minmax(0,1fr)}.ov-build-send{border-left:0;border-top:1px solid var(--line)}}@media(max-width:480px){.ov-facts{grid-template-columns:minmax(0,1fr);gap:0}.ov-facts>div{display:flex;justify-content:space-between;align-items:baseline;gap:12px;padding:6px 0;border-top:1px solid var(--line)}.ov-facts dd{margin:0;text-align:right}.ov-build-form,.ov-build-send{padding:16px 14px}}[data-design=sheet][data-page=overview] .ov-needs .table-wrap,[data-design=sheet][data-page=overview] .ov-decisions .table-wrap{border:1.5px solid var(--frame)}[data-design=sheet][data-page=overview] .ov-where{font-weight:600;color:var(--sv-blue-ink);text-decoration:none}[data-design=sheet][data-page=overview] .ov-where:hover{text-decoration:underline}[data-design=sheet][data-page=overview] .ov-needs .table td:last-child .btn{white-space:nowrap}[data-design=sheet][data-page=overview] .ov-what-kind{font-size:14px;font-weight:600}[data-design=sheet][data-page=overview] :is(.ov-what-id,.ov-where.is-id){font-size:14px}[data-design=sheet][data-page=overview] .ov-needs .table td[data-label=Detail]{color:var(--ink-2)}[data-design=sheet][data-page=overview] .ov-sub{margin:24px 0 0;padding:9px 14px;min-height:42px;background:var(--strip);border:1.5px solid var(--frame);border-bottom:1px solid var(--line-strong);font-size:15.5px;font-weight:700;color:var(--ink)}[data-design=sheet][data-page=overview] .ov-decisions>.ov-sub:first-child{margin-top:0}[data-design=sheet][data-page=overview] .ov-decisions .ov-sub+:is(.table-wrap,.card){border:1.5px solid var(--frame);border-top:0}[data-design=sheet][data-page=overview] .ov-fixes{gap:14px}[data-design=sheet][data-page=overview] .ov-fix{border:1.5px solid var(--frame)}[data-design=sheet][data-page=overview] .ov-fix.is-structural{border-top:5px solid var(--sv-amber)}[data-design=sheet][data-page=overview] .ov-fix-head{min-height:44px;padding:7px 14px;background:var(--strip);border-bottom:1px solid var(--line-strong)}[data-design=sheet][data-page=overview] .ov-fix-rank{width:28px;height:28px;background:none;border:1.5px solid var(--ink);border-radius:50%!important;color:var(--ink);font-family:var(--display);font-weight:700;font-size:16px}[data-design=sheet][data-page=overview] .ov-fix-kicker{font-size:14px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-2)}[data-design=sheet][data-page=overview] .ov-fix-body{padding:14px 14px 0}[data-design=sheet][data-page=overview] .ov-fix-body:last-child{padding-bottom:0}[data-design=sheet][data-page=overview] .ov-fix-title{font-size:18px;font-weight:700;line-height:1.3}[data-design=sheet][data-page=overview] .ov-fix-action{margin-top:6px;font-size:15px}[data-design=sheet][data-page=overview] .ov-facts{margin:auto -14px 0;padding:0;gap:0;border-top:1px solid var(--line-strong)}[data-design=sheet][data-page=overview] .ov-facts>div{padding:10px 14px 12px}[data-design=sheet][data-page=overview] .ov-facts>div+div{border-left:1px solid var(--line)}[data-design=sheet][data-page=overview] .ov-facts dt{font-size:14px;font-weight:600;color:var(--ink-2)}[data-design=sheet][data-page=overview] .ov-facts dd{margin-top:4px;font-family:var(--display);font-weight:700;font-size:24px;line-height:1;font-variant-numeric:tabular-nums}[data-design=sheet][data-page=overview] .ov-fix-foot{padding:10px 14px;border-top:1px solid var(--line-strong)}[data-design=sheet][data-page=overview] .ov-builder{border:1.5px solid var(--frame)}[data-design=sheet][data-page=overview] .ov-build-strip{min-height:42px;padding:9px 14px;background:var(--strip);border-bottom:1px solid var(--line-strong);font-size:15.5px}[data-design=sheet][data-page=overview] .ov-build-strip span+span{font-size:15px}[data-design=sheet][data-page=overview] .ov-build-send{border-left:1px solid var(--line-strong)}[data-design=sheet][data-page=overview] .ov-build-h{font-size:14px;font-weight:700;letter-spacing:.04em;text-transform:uppercase;color:var(--ink-2)}[data-design=sheet][data-page=overview] .ov-build-sum{font-size:15px}[data-design=sheet][data-page=overview] .ov-build-sum dt{font-weight:600}[data-design=sheet][data-page=overview] .ov-build-note{font-size:14px}@media(max-width:900px){[data-design=sheet][data-page=overview] .ov-build-send{border-left:0;border-top:1px solid var(--line-strong)}}@media(max-width:480px){[data-design=sheet][data-page=overview] .ov-facts>div{padding:8px 14px}[data-design=sheet][data-page=overview] .ov-facts>div+div{border-left:0;border-top:1px solid var(--line)}[data-design=sheet][data-page=overview] .ov-facts dd{font-size:20px;margin-top:0}}.ov-facts dd.ov-date{white-space:nowrap}[data-design=sheet][data-page=overview] .ov-facts dd.ov-date{font-family:var(--font);font-size:16px;line-height:1.25}#ov-decide{scroll-margin-top:calc(var(--top-h, 56px) + 16px)}
@@ -0,0 +1 @@
1
+ import{b as ie}from"../chunks/chunk-4SQPQ5TB.js";import{a as se}from"../chunks/chunk-YTANGYYH.js";import{a as ge,c as ve,d as he,e as fe,f as me,g as ue,h as V}from"../chunks/chunk-4LUI7O5P.js";import{a as q,b as U,c as we,d as xe,e as be,f as ke,g as ye}from"../chunks/chunk-CVB26NMC.js";import"../chunks/chunk-S2ZBMEVA.js";import"../chunks/chunk-ASYNLVOP.js";import{b as T}from"../chunks/chunk-763NH7PP.js";import{a as re,b as de,c as le,d as pe,e as ce}from"../chunks/chunk-3G4SQNUC.js";import"../chunks/chunk-LAAGCPU3.js";import"../chunks/chunk-24LFKFZ6.js";import"../chunks/chunk-6BDBXA6V.js";import"../chunks/chunk-MAPYGK3P.js";import{a as E}from"../chunks/chunk-6RLVD2DT.js";import"../chunks/chunk-45PGAQRO.js";import{d as X,f as Z,g as ee}from"../chunks/chunk-4WKQTWUC.js";import"../chunks/chunk-VQ5YXO54.js";import{b as _,c as k,d as te,e as x}from"../chunks/chunk-76WAVKUG.js";import{a as ae,d as N,e as ne,f as oe,h as H}from"../chunks/chunk-VWKSMFWJ.js";import{I as u,L as K,O as L,P as w,R as Y,a as R,c as m,k as C,n as b,o as G,p as W,q as F,w as e,x as B,z as f}from"../chunks/chunk-GT4EAKAO.js";import{d as J}from"../chunks/chunk-G7NGB5UX.js";J();J();var M=a=>{let i=W(a);return Number.isNaN(i)?null:Math.max(0,(Date.now()-i)/864e5)},Ae={test:"Test",job:"Job",package:"Package",finding:"Finding",pr:"Pull request",issue:"Issue"},Q=a=>a.charAt(0).toUpperCase()+a.slice(1),Je=a=>(q[a]||Q(a)).split(":")[0],$e=a=>Ae[a]||a.charAt(0).toUpperCase()+a.slice(1);function Se(a,i){let l={},o=n=>l[n]=(l[n]??-1)+1;return a.map((n,t)=>{let c={id:`${n.kind}-${t}`,item:n,whereHref:n.href,external:n.external};if(n.decide?.kind==="test"){let r=(i.ci?.tests||[]).find(v=>v.id===n.decide.id);return{...c,where:n.decide.id,mono:!0,wait:M(r?.since),detail:r?`${r.state==="flaky"?r.flake_events:r.failures} of ${r.runs} runs ${r.state==="flaky"?"flaked":"failed"}`:n.meta||""}}if(n.decide?.kind==="job"){let r=(i.ci?.jobs||[]).find(v=>ge(v)===n.decide.id);return{...c,where:n.decide.id,mono:!0,wait:M(r?.since),detail:n.meta||""}}if(n.kind==="prs"){let r=i.delivery?.stuck?.hanging_review?.[o("prs")];return{...c,where:`PR #${r?.pr??"?"}`,wait:M(r?.since),detail:`Review asked ${F(r?.since)}, nobody has started`}}if(n.kind==="deps"){let r=i.deps?.security_overdue?.[o("deps")];return{...c,where:r?.package||n.title,mono:!0,wait:r?r.age_hours/24:null,detail:r?`${r.from||"?"} to ${r.to||"?"} in PR #${r.pr}, open ${C(r.age_hours)}`:n.meta||""}}let d=i.community?.waiting?.[o("community")];return{...c,where:`${d?.kind==="issue"?"Issue":"PR"} #${d?.n??"?"}`,wait:d?d.days:null,detail:d?`Opened by a newcomer, no answer for ${b(d.days,"day")}`:n.meta||""}})}var Re=a=>a===null?"\u2013":C(a*24);function De({app:a,rows:i}){return e("div",{class:"ov-needs",children:e(E,{rows:i,columns:[{key:"kind",label:"Kind",filter:!0,raw:o=>o.item.what,render:o=>e(u,{tone:o.item.tone,children:o.item.what})},{key:"where",label:"Where",primary:!0,raw:o=>o.where,render:o=>e("a",{class:"ov-where"+(o.mono?" is-id":""),href:o.whereHref,...o.external?{target:"_blank",rel:"noopener noreferrer"}:{},children:o.where})},{key:"detail",label:"Detail",raw:o=>o.detail},{key:"wait",label:"Waiting",num:!0,raw:o=>o.wait,render:o=>Re(o.wait)},{key:"act",label:"Action",nowrap:!0,raw:()=>"",render:o=>o.item.decide?e(ye,{app:a,kind:o.item.decide.kind,id:o.item.decide.id,verbs:o.item.decide.verbs,label:"Decide"}):e(f,{size:"sm",variant:"tinted",href:o.item.href,external:o.item.external,iconEnd:o.item.external?"external":void 0,children:"Open"})}],name:"needs-a-decision",caption:"Waiting for a decision",limit:8})})}function Pe({fixes:a}){return a.length?e("ol",{class:"ov-fixes",children:a.map((i,l)=>e("li",{class:"ov-fix"+(i.structural?" is-structural":""),children:[e("div",{class:"ov-fix-head",children:[e("span",{class:"ov-fix-rank num","aria-hidden":"true",children:l+1}),e("span",{class:"ov-fix-kicker",children:["Rank ",l+1]}),i.structural?e(u,{tone:"watch",icon:"clock",children:"Structural"}):null]}),e("div",{class:"ov-fix-body",children:[e("h3",{class:"ov-fix-title",children:i.title}),i.action?e("p",{class:"ov-fix-action",children:i.action}):null,e("dl",{class:"ov-facts",children:[e("div",{children:[e("dt",{children:"Hours at stake"}),e("dd",{class:"num",children:i.hours})]}),e("div",{children:[e("dt",{children:"Sample"}),e("dd",{class:"num",children:["n = ",i.n]})]}),e("div",{children:[e("dt",{children:"Open since"}),e("dd",{class:"num ov-date",children:i.open_since||"\u2013"})]})]})]}),V[i.kind]?e("div",{class:"ov-fix-foot",children:e(f,{size:"sm",variant:"tinted",href:T(V[i.kind]),iconEnd:"right",children:"Open the area"})}):null]}))}):e(x,{children:e(w,{icon:"insights",title:"Nothing stands out.",children:"Findings appear once there is enough history to rank them."})})}var ze=a=>e("span",{class:"ov-what",children:[e("span",{class:"ov-what-kind",children:$e(a.d.kind)}),e("span",{class:"ov-what-id",children:a.d.id})]}),Te=a=>{let i=Math.ceil((W(a)-Date.now())/864e5);return a?Number.isNaN(i)?String(a):`${G(a)}${i>=0?`, in ${b(i,"day")}`:""}`:"\u2013"};function Ce({soon:a,log:i}){let l=[{key:"what",label:"What",primary:!0,raw:t=>`${t.d.kind}:${t.d.id}`,render:ze},{key:"verb",label:"Decision",raw:t=>t.d.verb,render:t=>e(u,{tone:"accent",icon:null,children:Q(t.d.verb)})},{key:"until",label:"Until",raw:t=>t.d.until,render:t=>Te(t.d.until)},{key:"by",label:"By",raw:t=>t.d.by||""},{key:"reason",label:"Reason",raw:t=>t.d.reason||"",render:t=>t.d.reason||e("span",{class:"muted",children:"No reason given"})}],o=[{key:"what",label:"What",primary:!0,raw:t=>`${t.d.kind}:${t.d.id}`,render:ze},{key:"verb",label:"Decision",raw:t=>t.d.verb,render:t=>e(u,{tone:"neutral",icon:null,children:Q(t.d.verb)})},{key:"by",label:"By",raw:t=>t.d.by||""},{key:"at",label:"When",raw:t=>t.d.at,render:t=>F(t.d.at)},{key:"source",label:"Source",raw:t=>t.d.source||"",render:t=>Ee[t.d.source||""]||t.d.source||"\u2013"}],n=t=>t.map((c,d)=>({id:String(d),d:c}));return e("div",{class:"ov-decisions",children:[e("h3",{class:"ov-sub",children:"Ending soon"}),e(E,{rows:n(a),columns:l,name:"decisions-ending-soon",caption:"Decisions ending soon",search:!1,empty:e(x,{children:e(w,{icon:"clock",title:"No decision has an end date coming up.",children:"Quarantines, mutes and snoozes show here a week before they end."})})}),e("h3",{class:"ov-sub",children:"Latest decisions"}),e(E,{rows:n(i),columns:o,name:"latest-decisions",caption:"Latest decisions",search:!1,empty:e(x,{children:e(w,{icon:"check",title:"No decisions made yet.",children:"Each decision made here, in a comment or in the app, lands in this log."})})})]})}var Ee={app:"The app",comment:"A comment",issue:"An issue",dispatch:"Workflow run"};function Fe(a,i,l){let o=[];for(let n of a)n.decide&&o.push({key:`${n.decide.kind}:${n.decide.id}`,kind:n.decide.kind,id:n.decide.id,label:`${n.what}: ${n.decide.id}`,verbs:n.decide.verbs});for(let n of l){let t=n.key||n.kind;o.push({key:`finding:${t}`,kind:"finding",id:t,label:`Finding: ${n.title}`,verbs:["snooze","acknowledge"]})}for(let n of i.delivery?.stuck?.hanging_review||[])o.push({key:`pr:${n.pr}`,kind:"pr",id:String(n.pr),label:`Pull request #${n.pr} (review not started)`,verbs:["exclude"]});return o}function Ne({app:a,items:i,newcomers:l}){let[o,n]=m(i[0]?.key||""),t=i.find(p=>p.key===o)||i[0],[c,d]=m(t?.verbs[0]||""),[r,v]=m(String(U[t?.verbs[0]||""]||0)),[S,D]=m(""),[y,I]=m("");if(!t)return e(x,{children:e(w,{icon:"check",title:"Nothing to decide on right now.",children:"Flaky tests and jobs, findings, security updates and stuck reviews show up here when they need a decision."})});let z=t.verbs.includes(c)?c:t.verbs[0],$=p=>{d(p),v(String(U[p]||0))},h=xe(t.kind,t.id,z,r,S,y),j=!(h.lasts&&r==="date"&&!S);return e("div",{class:"ov-builder",children:[e("div",{class:"ov-build-strip",children:[e("span",{children:"Decision builder"}),e("span",{children:[b(i.length,"item")," to choose from"]})]}),e("div",{class:"ov-build-form form",children:[e(N,{label:"1. What to decide on",hint:"Flaky tests and jobs, security updates, findings and stuck reviews from this page.",children:p=>e(H,{id:p,value:t.key,onChange:g=>{let O=i.find(A=>A.key===g);n(g),$(O.verbs[0])},options:i.map(g=>({value:g.key,label:g.label}))})}),e(N,{label:"2. The decision",hint:t.verbs.length>1?"Only the decisions that apply to this kind of item.":"The one decision that applies to this kind of item.",children:p=>e(H,{id:p,value:z,onChange:$,options:t.verbs.map(g=>({value:g,label:q[g]||g}))})}),h.lasts?e("div",{class:"field",children:[e("span",{class:"field-label",children:"3. For how long"}),e(ae,{label:"For how long",value:r,onChange:v,scroll:!0,options:[...["7","14","30","90"].map(p=>({value:p,label:`${p} days`})),{value:"date",label:"Until a date"}]})]}):null,h.lasts&&r==="date"?e(N,{label:"Until",children:p=>e(oe,{id:p,value:S,min:we(1),onInput:D})}):null,e(N,{label:`${h.lasts?4:3}. Why`,hint:"Kept in the decisions log.",children:p=>e(ne,{id:p,value:y,onInput:I,maxLength:200,placeholder:"A short reason"})})]}),e("div",{class:"ov-build-send",children:[e("p",{class:"ov-build-h",children:"What gets sent"}),e("dl",{class:"ov-build-sum",children:[e("div",{children:[e("dt",{children:"Item"}),e("dd",{children:e("span",{class:"ov-what",children:[e("span",{class:"ov-what-kind",children:$e(t.kind)}),e("span",{class:"ov-what-id",children:t.id})]})})]}),e("div",{children:[e("dt",{children:"Decision"}),e("dd",{children:[Je(z),h.end?`, until ${h.end}`:""]})]})]}),e(L,{inline:!0,code:h.snippet,note:"The same decision as a comment: paste it on any issue or pull request in this repo."}),j?e(ke,{app:a,title:h.title,req:h.req,...be}):e("p",{class:"field-hint",children:"Pick the date it ends, then send it."}),e("p",{class:"ov-build-note",children:["Nothing is posted from this page. The GitHub button opens a prefilled issue that you submit there; the token path starts the workflow, which checks your access first.",l?` Newcomers waiting for a first answer (${l}) have no decision to record: answer them on GitHub.`:""]})]})]})}var je=e(w,{icon:"setup",title:"No StackVitals data here yet",action:e(R,{children:[e(f,{variant:"filled",href:"#/setup",icon:"setup",children:"Set it up"}),e(f,{variant:"tinted",href:"?demo=1",icon:"play",children:"Try the demo"})]}),children:"The first run of the StackVitals workflow writes it. Already installed? Open your repo from the switcher at the top right, by name or Pages address."});function Oe({app:a}){se();let i=X({ci:"data.json",flow:"flow.json",delivery:"delivery.json",community:"community.json",deps:"deps.json",portal:"portal.json",insights:"insights.json",decisions:"decisions.json",alerts:"alerts.json",vulns:"vulns.json"}),[l,o]=re(),[n,t]=m(null);if(!a)return e(_,{title:"Overview",subtitle:"Your repository's vital signs at a glance.",children:je});if(!i.ready)return e(Y,{});let c=i,d=he(c,a),r=me(c,d),v=ve(c),S=v.filter(s=>s.points.length>1),D=v.find(s=>s.id===n)||S[0]||v[0],y=i.insights?.findings||[],I=y.filter(s=>!s.decision).slice(0,3),z=i.insights?i.insights.opportunity?.hours??y.filter(s=>!s.decision).reduce((s,P)=>s+P.hours,0):null,$=Object.values(i.decisions?.state||{}).filter(ee),h=$.filter(s=>s.until).sort((s,P)=>String(s.until).localeCompare(String(P.until))).slice(0,6),j=(i.decisions?.log||[]).slice(0,6),p=ue(r),g=r.find(s=>s.tone==="bad"),O=I[0]?.title||(g?`${g.name}: ${g.value} ${g.note.split(";")[0]}.`:d.length?`${b(d.length,"thing")} waiting for a decision.`:"Nothing waits for you right now."),A=Z(a);return e(_,{title:"Overview",subtitle:e(R,{children:[a.repo,a.visibility==="private"?e(R,{children:[" \xB7 ",e(u,{tone:"neutral",icon:"lock",children:"Private"})]}):null,e("span",{class:"sub-when",children:A?`updated ${F(A)}`:"no data written yet"})]}),children:[e(ie,{app:a}),e("div",{class:"conditions","aria-label":"Conditions",children:[e("div",{class:"cond-text",children:[e("p",{class:"cond-word",children:[p,"."]}),e("p",{class:"cond-line",children:O}),e("p",{class:"cond-sub",children:[$.length?`${b($.length,"decision")} in force`:"No decisions in force",d.length?`, ${d.length} waiting for one`:", nothing waiting","."]})]}),z!==null?e("div",{class:"stake",children:[e("b",{class:"num",children:Math.round(z)}),e("span",{children:["hours at stake ",e(K,{info:{title:"Hours at stake",body:"Waiting time you could win back across the open findings, each hour counted once. An estimate of what fixing could win back, not hours proven lost.",facts:i.insights?.opportunity?[["Findings",String(i.insights.opportunity.findings)],["Hours",C(i.insights.opportunity.hours)]]:[],doc:"methods.md"}})]})]}):null]}),e(k,{title:"Areas",description:"One reading per module. Tap an area to open it.",children:e("div",{class:"tiles",children:r.map((s,P)=>e("a",{class:`tile tone-${s.tone} press`,href:s.tone==="off"?"#/setup":T(s.id),style:{animationDelay:`${P*40}ms`},"aria-label":`${s.name}: ${s.word}. ${s.value} ${s.note}${s.alarm?`. ${s.alarm}`:""}`,children:[e("span",{class:"tile-top",children:[e(B,{name:fe[s.tone]}),s.name]}),e("span",{class:"tile-word",children:s.word}),e("span",{class:"tile-value num",children:s.value}),e("span",{class:"tile-note",children:s.note}),s.alarm?e("span",{class:"tile-alarm",children:[e(B,{name:"warn"}),s.alarm]}):null]}))})}),D?e(k,{title:"Trends",description:"Drag across the chart, or focus it and use the arrow keys. Pick a row to chart it.",children:e(te,{ratio:"lead",children:[e(x,{children:e(de,{metric:D,ranges:l,setRange:o})}),e(pe,{label:"Vital signs",items:v.map(s=>le(s,l[s.period]||12)),selected:D.id,onSelect:t,tones:ce(v,l)})]})}):null,e(k,{title:"Needs a decision",description:"New flaky tests, stuck reviews, security updates and newcomers. Sort by a column or filter by kind; Decide lands in the decisions log.",action:e(u,{tone:d.length?"watch":"good",children:d.length?`${d.length} waiting`:"All clear"}),children:d.length?e(De,{app:a,rows:Se(d,c)}):e(x,{children:e(w,{icon:"check",title:"Nothing waits for a decision.",children:"New flaky tests, stuck reviews, security updates and newcomers show up here."})})}),e(k,{title:"Fix first",description:"The open findings with the most hours of waiting at stake, ranked.",action:e(f,{size:"sm",variant:"plain",href:"#/insights",iconEnd:"right",children:"All findings"}),children:e(Pe,{fixes:I})}),e(k,{title:"Decisions",description:"Quarantines, mutes and snoozes ending soon, and the latest decisions made.",action:e(f,{size:"sm",variant:"plain",href:"#/activity",iconEnd:"right",children:"Activity"}),children:e(Ce,{soon:h,log:j})}),e(k,{id:"ov-decide",title:"Make a decision",description:"Pick an item this page knows, the decision and a reason. It goes to GitHub as a prefilled issue, through the workflow with your token, or as a comment you paste.",action:a.links?.new_issue?e(f,{size:"sm",variant:"plain",href:a.links.new_issue,external:!0,iconEnd:"external",children:"Open an issue"}):null,children:e(Ne,{app:a,items:Fe(d,c,y.filter(s=>!s.decision)),newcomers:d.filter(s=>s.kind==="community").length})})]})}export{Oe as default};
@@ -0,0 +1 @@
1
+ .pt-tabs{display:flex;min-width:0}.pt-tabs .seg{max-width:100%}.pt-panel{display:flex;flex-direction:column;gap:12px;animation:pageIn var(--dur-2) var(--spring) backwards;min-width:0}.pt-figure{font-size:52px;font-weight:800;line-height:1;letter-spacing:-.03em}.pt-figure-note{margin:0;font-size:15px;color:var(--ink-2)}.pt-meter{display:inline-flex;align-items:center;gap:8px;min-width:120px}.pt-track{display:block;width:72px;height:8px;border-radius:4px;background:var(--surface-2);overflow:hidden;flex:none}.pt-track i{display:block;height:100%;border-radius:4px;background:var(--good)}.pt-meter span{font-size:14px;color:var(--ink-2)}.pt-leaders{display:grid;grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px}.pt-grid{display:flex;flex-direction:column;gap:16px;min-width:0}.pt-h4{font-size:14.5px;font-weight:700;margin:0 0 8px}.pt-fail{margin:0;padding-left:18px;font-size:14.5px;display:flex;flex-direction:column;gap:4px;overflow-wrap:anywhere}.pt-plain{margin:0;padding:0;list-style:none;display:flex;flex-direction:column;gap:6px}.pt-form{display:grid;grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:12px 16px}.pt-form .field{margin:0}.pt-result-h{margin:4px 0 8px;font-size:15px;font-weight:700}.pt-mini{width:100%;border-collapse:collapse;font-size:14.5px}.pt-mini th{text-align:left;font-size:14px;font-weight:600;color:var(--ink-2);padding:8px 16px;border-bottom:1px solid var(--line)}.pt-mini td{padding:8px 16px;border-bottom:1px solid var(--line);overflow-wrap:anywhere}.pt-mini tr:last-child td{border-bottom:0}.pt-mini .is-num{text-align:right;white-space:nowrap}[data-design=sheet][data-page=portal] .bar-fill.tone-neutral{background:transparent;border:1px solid var(--ink);border-bottom:0}[data-design=sheet][data-page=portal] .bar-label:before{content:"";display:inline-block;width:11px;height:11px;margin-right:5px;vertical-align:-1px;background:center / contain no-repeat}[data-design=sheet][data-page=portal] .bar:has(.tone-bad) .bar-label:before{background-image:var(--mark-bad)}[data-design=sheet][data-page=portal] .bar:has(.tone-watch) .bar-label:before{background-image:var(--mark-watch)}[data-design=sheet][data-page=portal] .bar:has(.tone-good) .bar-label:before{background-image:var(--mark-good)}[data-design=sheet][data-page=portal] .bar:has(.tone-neutral) .bar-label:before{width:9px;height:9px;border:1px solid currentColor}[data-design=sheet][data-page=portal] .bar:has(.tone-accent) .bar-label:before{display:none}[data-design=sheet][data-page=portal] .bar-label{font-size:14px;font-weight:600;color:var(--ink)}[data-design=sheet][data-page=portal] .bar-value{font-size:14px}[data-design=sheet][data-page=portal] .pt-panel{animation:svFade var(--dur-2) var(--sv-ease) backwards}[data-design=sheet][data-page=portal] .pt-figure{font-family:var(--display);font-weight:700;font-size:64px;letter-spacing:-.01em}[data-design=sheet][data-page=portal] .pt-figure-note{font-size:15.5px}[data-design=sheet][data-page=portal] .columns>.stats.card{border:1.5px solid var(--frame)}[data-design=sheet][data-page=portal] .pt-h4{font-weight:700;font-size:15px;border-bottom:1.5px solid var(--ink);padding-bottom:6px;margin-bottom:0}[data-design=sheet][data-page=portal] .pt-fail{list-style:none;padding:0;gap:0;font-size:15px}[data-design=sheet][data-page=portal] .pt-fail li{display:flex;align-items:center;gap:8px;padding:7px 0;border-bottom:1px solid var(--line)}[data-design=sheet][data-page=portal] .pt-fail li:before{content:"";width:13px;height:13px;flex:none;background:var(--mark-bad) center / contain no-repeat}[data-design=sheet][data-page=portal] .pt-mini th{color:var(--ink);border-bottom:1.5px solid var(--ink);padding:8px 14px}[data-design=sheet][data-page=portal] .pt-mini td{padding:8px 14px;font-size:15px}[data-design=sheet][data-page=portal] .pt-mini td.is-num{font-weight:700;font-variant-numeric:tabular-nums}[data-design=sheet][data-page=portal] .pt-track{width:72px;height:10px;background:transparent;border:1px solid var(--ink)}[data-design=sheet][data-page=portal] .pt-track i{background:var(--sv-mint);border-right:1px solid var(--ink)}[data-design=sheet][data-page=portal] .pt-meter span{font-size:14.5px;font-weight:600;color:var(--ink);font-variant-numeric:tabular-nums}[data-design=sheet][data-page=portal] .sheet .sheet-sec{margin-top:16px;border:1.5px solid var(--frame)}[data-design=sheet][data-page=portal] .sheet .sheet-sec:first-child{margin-top:4px}[data-design=sheet][data-page=portal] .sheet .sheet-sec>h3{margin:0;padding:9px 14px;background:var(--strip);border-bottom:1px solid var(--line-strong);font-weight:700;font-size:16px}[data-design=sheet][data-page=portal] .sheet .kv{gap:0;font-size:15px;padding:0 14px}[data-design=sheet][data-page=portal] .sheet .kv>:is(dt,dd){padding:8px 0;border-top:1px solid var(--line)}[data-design=sheet][data-page=portal] .sheet .kv>:is(dt,dd):nth-child(-n+2){border-top:0}[data-design=sheet][data-page=portal] .sheet .kv>dd{padding-left:16px}[data-design=sheet][data-page=portal] .sheet .kv dt{color:var(--ink);font-weight:600}[data-design=sheet][data-page=portal] .sheet p.sheet-sec{border:0}[data-design=sheet][data-page=portal] .sheet .note{margin-bottom:12px}@media(max-width:480px){[data-design=sheet][data-page=portal] .sheet .kv>dd{border-top:0;padding-top:0;padding-left:0}}@media(max-width:480px){[data-design=sheet][data-page=portal] .bar-label{flex:none}[data-design=sheet][data-page=portal] .bar-label:before{display:block;margin:0 auto 3px}}.pn{min-width:0;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden}.pn-strip{display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap;gap:4px 12px;min-height:42px;padding:9px 16px;background:var(--surface-2);border-bottom:1px solid var(--line)}.pn-title{margin:0;font-size:15.5px;font-weight:700;line-height:1.35;overflow-wrap:anywhere;display:flex;align-items:center;gap:8px;flex-wrap:wrap}.pn-meta{font-size:14px;font-weight:600;color:var(--ink-2);display:inline-flex;align-items:center;gap:10px;flex-wrap:wrap}.pn-body{padding:14px 16px;display:flex;flex-direction:column;gap:12px;min-width:0}.pn-body.is-flush{padding:0;gap:0}.pn-body>p{margin:0;font-size:15px;line-height:1.5}.pn-foot{display:flex;align-items:center;gap:8px 10px;flex-wrap:wrap;padding:10px 16px;border-top:1px solid var(--line)}.pn-foot .pn-hint{font-size:14px;color:var(--ink-2);flex-basis:100%}.pn .table-wrap.card{border:0;border-radius:0;box-shadow:none;background:transparent}.pn-good{border-top:4px solid var(--good)}.pn-watch{border-top:4px solid var(--watch)}.pn-bad{border-top:4px solid var(--bad)}.pn-facts{display:grid;grid-template-columns:repeat(auto-fit,minmax(150px,1fr));gap:0;margin:0}.pn-facts.cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.pn-fact{padding:8px 12px 8px 0;border-bottom:1px solid var(--line);min-width:0}.pn-fact dt{font-size:14px;font-weight:600;color:var(--ink-2)}.pn-fact dd{margin:2px 0 0;font-size:15.5px;font-weight:600;color:var(--ink);overflow-wrap:anywhere}.pn-steps{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}.pn-steps>li{display:grid;grid-template-columns:32px minmax(0,1fr) auto;gap:4px 14px;align-items:start;padding:14px 16px;border-top:1px solid var(--line)}.pn-steps>li:first-child{border-top:0}.pn-step-n{width:28px;height:28px;border-radius:50%;display:grid;place-items:center;background:var(--accent-soft);color:var(--accent);font-weight:700}.pn-step-h{margin:0;font-size:15.5px;font-weight:700}.pn-step-p{margin-top:3px;font-size:14.5px;line-height:1.5;color:var(--ink-2)}.pn-step-act{display:flex;gap:8px;flex-wrap:wrap;align-items:center;justify-content:flex-end}@media(max-width:640px){.pn-steps>li{grid-template-columns:28px minmax(0,1fr)}.pn-step-act{grid-column:2;justify-content:flex-start}.pn-facts.cols-2{grid-template-columns:minmax(0,1fr)}}[data-design=sheet] .pn{border:1.5px solid var(--frame);border-radius:2px}[data-design=sheet] .pn-strip{background:var(--strip);border-bottom:1px solid var(--line-strong);padding:9px 14px}[data-design=sheet] .pn-title{font-size:16px;font-weight:700;color:var(--ink)}[data-design=sheet] .pn-meta{font-size:14.5px;color:var(--ink-2)}[data-design=sheet] .pn-body{padding:14px}[data-design=sheet] .pn-body.is-flush{padding:0}[data-design=sheet] .pn-foot{padding:10px 14px;border-top:1px solid var(--line-strong)}[data-design=sheet] .pn-good{border-top:5px solid var(--sv-mint)}[data-design=sheet] .pn-watch{border-top:5px solid var(--sv-amber)}[data-design=sheet] .pn-bad{border-top:5px solid var(--sv-coral)}[data-design=sheet] .pn-fact dt{font-size:14px;font-weight:600;color:var(--ink-2)}[data-design=sheet] .pn-fact dd{font-size:16px;font-weight:600}[data-design=sheet] .pn-step-n{border-radius:2px;background:var(--ink);color:var(--bg);font-family:var(--display)}[data-design=sheet] .pn-steps>li.is-done .pn-step-n{background:var(--sv-mint);color:#000}
@@ -0,0 +1,51 @@
1
+ import{a as y,b as ee,c as _e}from"../chunks/chunk-TO4VVRZ7.js";import{a as ke}from"../chunks/chunk-GQYFN4PE.js";import{a as Q}from"../chunks/chunk-3ROQFHPV.js";import{f as ve}from"../chunks/chunk-CVB26NMC.js";import"../chunks/chunk-S2ZBMEVA.js";import{a as Z,b as z,d as D,e as we}from"../chunks/chunk-ASYNLVOP.js";import{c as ie,d as K}from"../chunks/chunk-763NH7PP.js";import{a as P}from"../chunks/chunk-6RLVD2DT.js";import{a as ye,f as X}from"../chunks/chunk-RPXHAG6F.js";import"../chunks/chunk-45PGAQRO.js";import{d as be}from"../chunks/chunk-4WKQTWUC.js";import{k as fe}from"../chunks/chunk-VQ5YXO54.js";import{b as le,c as E,d as J,e as I,h as S,i as f}from"../chunks/chunk-76WAVKUG.js";import{a as H,d as v,e as _,h as q}from"../chunks/chunk-VWKSMFWJ.js";import{G as he,I as w,J as re,L as me,O as L,P as T,R as ge,a as m,c as x,i as ce,l as se,m as $,n as k,o as N,r as Y,s as ue,w as e,z as b}from"../chunks/chunk-GT4EAKAO.js";import{d as R}from"../chunks/chunk-G7NGB5UX.js";R();R();R();var ae=".github/workflows/stackvitals-portal.yml",Ye=`name: StackVitals Portal
2
+ on:
3
+ schedule:
4
+ - cron: "41 5 * * *" # once a day
5
+ workflow_dispatch:
6
+ inputs:
7
+ request:
8
+ description: "A request from the StackVitals app, like a golden path (leave empty for a normal run)"
9
+ required: false
10
+ default: ""
11
+ issues:
12
+ types: [opened] # golden path requests from the app, run at once
13
+ issue_comment:
14
+ types: [created] # "/stackvitals approve" on a golden path that needs an approval
15
+ permissions:
16
+ contents: write # keeps the catalog, its history and the pages in this repo's stackvitals-data branch
17
+ issues: write # one tracking issue per campaign, and answers to requests, in this repo only
18
+ concurrency:
19
+ group: stackvitals-portal
20
+ cancel-in-progress: false
21
+ jobs:
22
+ portal:
23
+ # Request issues start a run only when someone with access to this repo opened one with a StackVitals block.
24
+ if: >-
25
+ (github.event_name != 'issues' ||
26
+ (contains(github.event.issue.body, '\`\`\`stackvitals') &&
27
+ contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.issue.author_association))) &&
28
+ (github.event_name != 'issue_comment' ||
29
+ (startsWith(github.event.comment.body, '/stackvitals approve') &&
30
+ contains(fromJSON('["OWNER", "MEMBER", "COLLABORATOR"]'), github.event.comment.author_association)))
31
+ runs-on: ubuntu-latest
32
+ timeout-minutes: 30
33
+ steps:
34
+ # Private repos: create an org-owned read-only GitHub App (see docs/modules.md), store its client ID and key, then switch on.
35
+ # - uses: actions/create-github-app-token@64ab729a6294000f5aa4a4bc0b73d1f32bc45510 # v3
36
+ # id: app
37
+ # with:
38
+ # client-id: \${{ vars.PORTAL_CLIENT_ID }}
39
+ # private-key: \${{ secrets.PORTAL_PRIVATE_KEY }}
40
+ # owner: \${{ github.repository_owner }}
41
+ - uses: {ref}
42
+ with:
43
+ modules: portal
44
+ # portal-token: \${{ steps.app.outputs.token }}
45
+ `;function pe(t={}){let n=Ye.replace("{ref}",t.ref||ke);return t.app?n.split(`
46
+ `).map(o=>/^ *# (- uses: actions\/create-github-app-token| {2}id: app| {2}with:| {4}(client-id|private-key|owner):|portal-token:)/.test(o)?o.replace("# ",""):o).join(`
47
+ `).replace("Private repos: create an org-owned read-only GitHub App (see docs/modules.md), store its client ID and key, then switch on.","Private repos: the org App's token (its client ID in the variable PORTAL_CLIENT_ID, its key in the secret PORTAL_PRIVATE_KEY)."):n}function B(t,n=!1){let o=[["name",`${t} portal ${n?"":"reader"}`.trim().slice(0,34)],["description","StackVitals Portal: the org catalog, owners and scorecards"+(n?"; required checks and golden paths.":" (read-only).")],["url",`https://github.com/${t}`],["public","false"],["webhook_active","false"],["actions","read"],["contents",n?"write":"read"],["metadata","read"],["members","read"],["organization_custom_properties","read"]];return n&&o.push(["checks","write"],["pull_requests","write"],["administration","write"],["workflows","write"]),`https://github.com/organizations/${encodeURIComponent(t)}/settings/apps/new?${o.map(([s,r])=>`${s}=${Je(r)}`).join("&")}`}var Je=t=>encodeURIComponent(t).replace(/[!'()*]/g,n=>"%"+n.charCodeAt(0).toString(16).toUpperCase()).replace(/%20/g,"+");function xe(t,n="portal"){return`https://github.com/new?owner=${encodeURIComponent(t)}&name=${encodeURIComponent(n)}&visibility=private&description=${encodeURIComponent("StackVitals Portal: the org's catalog, owners and scorecards")}`}function Pe(t){return`# Owners suggested by StackVitals Portal from recent activity; narrow the paths as teams take parts over.
48
+ * ${t.map(n=>n.startsWith("@")?n:"@"+n).join(" ")}
49
+ `}function Re(t){let n=s=>/^[A-Za-z0-9][A-Za-z0-9 _./:@-]*$/.test(s)&&!/: |\s$/.test(s)&&!/^(true|false|null|yes|no|on|off|~)$/i.test(s)?s:JSON.stringify(s),o=["apiVersion: backstage.io/v1alpha1","kind: Component","metadata:",` name: ${n(t.name)}`];return t.title?.trim()&&o.push(` title: ${n(t.title.trim())}`),t.description?.trim()&&o.push(` description: ${n(t.description.trim())}`),o.push("spec:",` type: ${n(t.type)}`,` lifecycle: ${n(t.lifecycle)}`,` owner: ${n(t.owner)}`),t.system?.trim()&&o.push(` system: ${n(t.system.trim())}`),o.join(`
50
+ `)+`
51
+ `}var Ce=t=>t.toLowerCase().replace(/[^a-z0-9._-]+/g,"-").replace(/^[^a-z0-9]+|[^a-z0-9]+$/g,"").slice(0,63)||"component";function $e(t){if(!t)return"";let n=t.replace(/^@/,"");return n.includes("/")?`group:${n.split("/").pop()}`:`user:${n}`}var G={target:"_blank",rel:"noopener noreferrer"},j=t=>e("a",{href:`https://github.com/${t}`,...G,children:t}),M=t=>t===!0?e(w,{tone:"good",children:"Yes"}):t===!1?e(w,{tone:"bad",children:"No"}):e(w,{tone:"neutral",icon:null,children:"Can't read"}),U=t=>e(w,{tone:t==="valid"?"good":t==="weak"?"watch":t==="none"?"bad":"neutral",children:t?t[0].toUpperCase()+t.slice(1):"Not checked"}),V=t=>t?e(re,{value:t}):e(w,{tone:"bad",children:"Below bronze"}),Ee={readme:"README",license:"Licence",contributing:"Contributing guide",code_of_conduct:"Code of conduct"},ne=t=>[...(t.provides_apis||[]).map(n=>`provides ${n.split("/").pop()}`),...(t.consumes_apis||[]).map(n=>`uses ${n.split("/").pop()}`)].join(", "),Ke=t=>t>=7?"good":t>=4?"watch":"bad",A=({rows:t})=>e("dl",{class:"kv",children:t.filter(n=>!!n).map(([n,o])=>e(m,{children:[e("dt",{children:n}),e("dd",{children:o})]}))});function Oe({r:t,onClose:n}){if(!t)return null;let o=t.owners,s=t.docs||{},r=t.openssf?.checks,a=t.descriptor?.entities||[],i=Array.isArray(s.org_defaults)?s.org_defaults:[],p=t.modules?.ci_first_try||(t.ci?.first_try_share!=null?`${$(t.ci.first_try_share)} of ${t.ci.pushes??"?"} pushes`:null),u=t.modules?.flow?.first_review_median_s??t.reviews?.first_review_median_s,g=(t.score?.results||[]).filter(d=>d.result==="fail");return e(he,{open:!0,onClose:n,title:t.name,size:"md",footer:e(m,{children:[e(b,{variant:"plain",href:`https://github.com/${t.name}`,external:!0,iconEnd:"external",children:"Open on GitHub"}),e(b,{variant:"filled",onClick:n,children:"Done"})]}),children:[t.error?e("div",{class:"note note-watch",children:e("span",{children:["The last check stopped on this repo (",t.error,"); these are the facts from the check before."]})}):null,e("section",{class:"sheet-sec",children:[e("h3",{children:"Level"}),e(A,{rows:[["Level",V(t.score?.level)],["Rules failing",g.length?e("ul",{class:"pt-plain",children:g.map(d=>e("li",{children:[e("span",{class:"mono-soft",children:d.id}),d.evidence?e("div",{class:"muted small",children:d.evidence}):null]}))}):"None"],!!t.score?.not_available&&["Can't be read",`${k(t.score.not_available,"rule")}, usually a published Scorecard check on a private repo`],!!t.checked&&["Checked",N(t.checked)]]})]}),e("section",{class:"sheet-sec",children:[e("h3",{children:"Owners"}),e(A,{rows:[["CODEOWNERS",e(m,{children:[U(o?.status),o?.file?e("div",{class:"muted small mono-soft",children:o.file}):null]})],!!o?.owners?.length&&["Owners",e("span",{class:"mono-soft",children:o.owners.join(", ")})],!!o?.reasons?.length&&["Why",o.reasons.join("; ")],!!o?.suggested?.length&&["Suggested",e(m,{children:[e("span",{class:"mono-soft",children:o.suggested.join(", ")}),e("div",{class:"muted small",children:["from ",o.suggested_from||"recent activity"]})]})]]})]}),e("section",{class:"sheet-sec",children:[e("h3",{children:"Default branch and files"}),e(A,{rows:[["Branch protected",M(t.protected)],!!t.rules&&["Ruleset rules",e("span",{class:"mono-soft",children:t.rules.join(", ")||"none"})],...Object.keys(Ee).filter(d=>d in s).map(d=>[Ee[d],e(m,{children:[M(s[d]),i.includes(d)?e("div",{class:"muted small",children:"from the org's .github repo"}):null]})]),...Object.entries(t.files||{}).map(([d,c])=>[d,e(m,{children:[M(c.present),Object.entries(c).filter(([h])=>h!=="present").map(([h,l])=>e("div",{class:"muted small",children:[h.replace(":"," "),": ",l?"yes":"no"]}))]})])]})]}),e("section",{class:"sheet-sec",children:[e("h3",{children:"CI and reviews"}),e(A,{rows:[["CI passes first try",e(m,{children:[p||"\u2013",t.ci?.median_s!=null?e("div",{class:"muted small",children:["a push's CI took ",se(t.ci.median_s)," at the median"]}):null]})],["First review, median",e(m,{children:[u!=null?se(u):"\u2013",t.reviews?.prs?e("div",{class:"muted small",children:["over ",k(t.reviews.prs,"PR")]}):null]})],!!t.modules?.flow&&["Open PRs",e(m,{children:[t.modules.flow.open??"\u2013",t.modules.flow.stale?e("div",{class:"muted small",children:[t.modules.flow.stale," stale"]}):null]})]]})]}),r?e("section",{class:"sheet-sec",children:[e("h3",{children:["OpenSSF Scorecard",t.openssf?.date?`, ${N(t.openssf.date)}`:""]}),e(A,{rows:Object.entries(r).sort((d,c)=>(d[1]??11)-(c[1]??11)).map(([d,c])=>[d,c==null||c<0?e(w,{tone:"neutral",icon:null,children:"Not scored"}):e(w,{tone:Ke(c),children:[c," of 10"]})])})]}):t.private?e("p",{class:"muted small sheet-sec",children:"OpenSSF publishes Scorecards for public repos only."}):null,a.length?e("section",{class:"sheet-sec",children:[e("h3",{children:"Catalog"}),e(A,{rows:a.map(d=>[d.title||d.name,e(m,{children:[d.kind,d.system?`, system ${d.system}`:"",d.lifecycle?`, ${d.lifecycle}`:"",ne(d)?e("div",{class:"small",children:ne(d)}):null,d.tags?.length?e("div",{class:"muted small",children:["tags: ",d.tags.join(", ")]}):null]})])})]}):null,t.properties&&Object.keys(t.properties).length?e("section",{class:"sheet-sec",children:[e("h3",{children:"Custom properties"}),e(A,{rows:Object.entries(t.properties).map(([d,c])=>[d,Array.isArray(c)?c.join(", "):String(c)])})]}):null]})}var Ze=["service","website","library","mobile-app","tool","documentation"],Qe=["production","experimental","deprecated"];function Xe({repos:t}){let[n,o]=x(t[0]?.name||""),s=t.find(c=>c.name===n)||t[0],[r,a]=x({});if(!s)return null;let i=s.name.split("/")[1]||s.name,p={name:Ce(r.name??i),title:r.title??"",description:r.description??"",type:r.type||"service",lifecycle:r.lifecycle||"production",owner:r.owner??$e(s.owners?.owners?.[0]),system:r.system??""},u=c=>h=>a({...r,[c]:h}),g=Re(p),d=z(s.name,s.default_branch||"main","catalog-info.yaml",g);return e(y,{title:"Add a catalog file",meta:`${k(t.length,"repo")} without one`,foot:e(m,{children:[e(b,{variant:"filled",href:d.url,external:!0,icon:"external",disabled:!p.owner,onClick:D(d,"Opened on GitHub: press Commit changes there"),children:["Add catalog-info.yaml to ",i," on GitHub"]}),e("span",{class:"pn-hint",children:[d.paste?Z:"Opens GitHub's editor with the file filled in."," It goes on ",s.default_branch||"main",", or propose it as a pull request. No token needed here; GitHub asks for write access."]})]}),children:[e("p",{children:"Backstage's format, so Backstage, Port and Cortex read the same file. The owner comes from the repo's CODEOWNERS when it names one."}),e("div",{class:"pt-form",children:[e(v,{label:"Repo",children:c=>e(q,{id:c,value:s.name,onChange:h=>{o(h),a({})},options:t.map(h=>({value:h.name,label:h.name}))})}),e(v,{label:"Name",hint:"Lowercase letters, digits and dashes.",children:c=>e(_,{id:c,mono:!0,value:p.name,onInput:u("name")})}),e(v,{label:"Title",children:c=>e(_,{id:c,value:p.title,onInput:u("title"),placeholder:i})}),e(v,{label:"Description",children:c=>e(_,{id:c,value:p.description,onInput:u("description"),maxLength:200})}),e(v,{label:"Type",children:c=>e(q,{id:c,value:p.type,onChange:u("type"),options:Ze.map(h=>({value:h,label:h}))})}),e(v,{label:"Lifecycle",children:c=>e(q,{id:c,value:p.lifecycle,onChange:u("lifecycle"),options:Qe.map(h=>({value:h,label:h}))})}),e(v,{label:"Owner",hint:"group:team or user:name",error:p.owner?null:"Name an owner",children:c=>e(_,{id:c,mono:!0,value:p.owner,onInput:u("owner"),placeholder:"group:team"})}),e(v,{label:"System",hint:"Optional: the larger thing it belongs to.",children:c=>e(_,{id:c,mono:!0,value:p.system,onInput:u("system")})})]}),e(L,{title:"catalog-info.yaml",code:g})]})}function Ae({repos:t}){let n=t.filter(a=>a.descriptor?.present),o=t.filter(a=>!a.descriptor?.present&&!a.name.toLowerCase().endsWith("/.github")),s=n.flatMap(a=>(a.descriptor.entities||[]).map(i=>({...i,repo:a.name}))),r=n.flatMap(a=>(a.descriptor.problems||[]).map(i=>({repo:a.name,problem:i})));return e(m,{children:[e(S,{children:[e(f,{label:"Entities",value:s.length}),e(f,{label:"Repos with a catalog file",value:`${n.length} of ${t.length}`}),e(f,{label:"Problems in catalog files",value:r.length})]}),s.length?e(P,{name:"catalog",caption:"Catalog",rows:s,columns:[{key:"name",label:"Entity",primary:!0,render:a=>e(m,{children:[e("b",{children:a.title||a.name}),a.description?e("div",{class:"muted small",children:Y(a.description,90)}):null]})},{key:"kind",label:"Kind",filter:!0,raw:a=>a.kind||""},{key:"system",label:"System",filter:!0,raw:a=>a.system||"",render:a=>a.system||"\u2013"},{key:"type",label:"Type",filter:!0,raw:a=>a.type||"",render:a=>a.type||"\u2013"},{key:"lifecycle",label:"Lifecycle",filter:!0,raw:a=>a.lifecycle||"",render:a=>a.lifecycle||"\u2013"},{key:"owner",label:"Owner",raw:a=>a.owner||"",render:a=>e(m,{children:[e("span",{class:"mono-soft",children:a.owner||"\u2013"}),a.owner_check?e("div",{children:e(w,{tone:a.owner_check[0]==="pass"?"good":"watch",children:a.owner_check[0]==="pass"?"In CODEOWNERS":"Not in CODEOWNERS"})}):null]})},{key:"depends_on",label:"Depends on",raw:a=>(a.depends_on||[]).join(" "),render:a=>Y((a.depends_on||[]).map(i=>i.split("/").pop()).join(", "),60)||"\u2013"},{key:"apis",label:"APIs",raw:a=>ne(a),render:a=>Y(ne(a),60)||"\u2013"},{key:"tags",label:"Tags",filter:!0,raw:a=>(a.tags||[]).join(" "),render:a=>(a.tags||[]).join(", ")||"\u2013"},{key:"repo",label:"Repo",render:a=>j(a.repo)}]}):e(I,{children:e(T,{icon:"portal",title:"No repo has a catalog-info.yaml yet."})}),r.length?e(m,{children:[e("h3",{class:"sub-h",children:"Problems in catalog files"}),e(P,{name:"catalog-problems",caption:"Catalog problems",search:!1,rows:r,columns:[{key:"repo",label:"Repo",primary:!0,render:a=>j(a.repo)},{key:"problem",label:"Problem"}]})]}):null,o.length?e(Xe,{repos:o}):null]})}var Se=/\.(md|mdx|rst|adoc|txt)$/i;function Fe({repos:t}){let n=t.flatMap(o=>(o.doc_pages||[]).filter(s=>Se.test(s)||!s.includes(".")).map(s=>({page:s.replace(Se,"").replace(/[-_]+/g," ").replace(/^./,r=>r.toUpperCase()),file:s,repo:o.name,folder:!s.includes(".")})));return n.length?e(m,{children:[e(S,{children:[e(f,{label:"Pages and folders",value:n.length}),e(f,{label:"Repos with docs/",value:`${new Set(n.map(o=>o.repo)).size} of ${t.length}`})]}),e(P,{name:"docs",caption:"Docs pages",rows:n,columns:[{key:"page",label:"Page",primary:!0,render:o=>e("a",{href:`https://github.com/${o.repo}/${o.folder?"tree":"blob"}/HEAD/docs/${o.file}`,...G,children:o.page})},{key:"kind",label:"Kind",filter:!0,raw:o=>o.folder?"Folder":"Page"},{key:"file",label:"File",nowrap:!0,render:o=>e("span",{class:"mono-soft",children:["docs/",o.file]})},{key:"repo",label:"Repo",filter:!0}]})]}):e(I,{children:e(T,{icon:"portal",title:"No repo has a docs/ folder yet.",children:["Pages in each repo's ",e("code",{class:"code-inline",children:"docs/"})," folder are listed here once the next run reads them."]})})}function Ne({repos:t}){var o;let n={};for(let s of t)for(let r of s.score?.results||[]){let a=n[o=r.id]||(n[o]={id:r.id,level:r.level,pass:0,fail:0,exempt:0,preview:0,na:0});a[["pass","fail","exempt","preview"].includes(r.result||"")?r.result:"na"]++}return e(P,{name:"rules",caption:"Rules",rows:Object.values(n),initialSort:{key:"fail",desc:!0},columns:[{key:"id",label:"Rule",primary:!0,nowrap:!0,render:s=>e("span",{class:"mono-soft",children:s.id})},{key:"level",label:"Level",filter:!0,render:s=>e(re,{value:s.level})},{key:"fail",label:"Failing",num:!0,render:s=>e("b",{children:s.fail})},{key:"pass",label:"Passing",num:!0},{key:"exempt",label:"Exempt",num:!0},{key:"preview",label:"Not counted yet",num:!0},{key:"na",label:"Can't check",num:!0},{key:"share",label:"Passing share",num:!0,raw:s=>s.pass+s.fail?s.pass/(s.pass+s.fail):null,render:s=>{let r=s.pass/Math.max(1,s.pass+s.fail);return e("span",{class:"pt-meter",role:"img","aria-label":$(r),children:[e("span",{class:"pt-track",children:e("i",{style:{width:`${r*100}%`}})}),e("span",{class:"num",children:$(r)})]})}}]})}function Le({app:t,p:n,repos:o}){let[s,r]=x({}),a=n.golden||[];if(!a.length)return e(I,{children:e(T,{icon:"setup",title:"No golden paths.",children:["Add ",e("code",{class:"code-inline",children:"[[golden_path]]"})," entries to the portal repo's ",e("code",{class:"code-inline",children:"portal.toml"}),": a template repo to start from, or a folder of standard files to add to a repo."]})});let i=(p,u,g)=>r({...s,[p]:{...s[p]||{},[u]:g}});return e("div",{class:"pt-grid",children:[n.golden_ready?null:e(y,{title:"Golden paths need the org App",tone:"watch",foot:e(b,{variant:"tinted",href:B(n.org||t.repo.split("/")[0],!0),external:!0,icon:"external",children:"Create the App on GitHub"}),children:e("p",{children:"Golden paths create repos and open pull requests, so they run with an org App that may write. The button opens GitHub's App form with the permissions filled in; then save its client ID as the variable PORTAL_CLIENT_ID, its key as the secret PORTAL_PRIVATE_KEY, and switch on the token step (Portal outside the app, below, has the file)."})}),a.map(p=>{let u=s[p.id]||{},g=p.kind==="repo"?/^[A-Za-z0-9._-]{1,100}$/.test(u.name||""):!!u.repo,d={version:1,changes:[],settings:{},golden:{path:p.id,inputs:u}};return e(y,{title:p.title,meta:p.kind==="repo"?`Creates a new ${p.private?"private":"public"} repo`:"Opens a pull request",children:[p.description?e("p",{children:p.description}):null,e("div",{class:"pt-form",children:p.kind==="repo"?e(m,{children:[e(v,{label:"Name",hint:"Letters, numbers, dots, dashes and underscores.",children:c=>e(_,{id:c,value:u.name||"",onInput:h=>i(p.id,"name",h)})}),e(v,{label:"Description",children:c=>e(_,{id:c,value:u.description||"",onInput:h=>i(p.id,"description",h)})})]}):e(v,{label:"Repo",children:c=>e(q,{id:c,value:u.repo||"",onChange:h=>i(p.id,"repo",h),options:[{value:"",label:"Choose a repo"},...o.map(h=>({value:h.name,label:h.name}))]})})}),g?e(ve,{app:t,title:`Golden path: ${p.title}`,req:d,who:"people with write access to the portal repo",lands:p.kind==="repo"?`a new repo in ${n.org}`:`a pull request in ${u.repo}`,when:"on the next portal run, a minute or two"}):e("p",{class:"field-hint",children:p.kind==="repo"?"Name the new repo to send the request.":"Choose the repo to send the request."})]})})]})}var et={ci_flaky:"Flaky checks",ci_broken:"Broken checks",stale_prs:"Stale PRs",findings:"Open findings",newcomers_waiting:"Newcomers waiting",pickup_p75_h:"Pickup, P75 hours",review_p75_h:"Review, P75 hours",cycle_p75_h:"Cycle to merge, P75 hours",change_failure_rate:"Change fail rate",vulns_serious:"Critical or high vulnerabilities, or malware"};function Te({o:t}){if(!t||!t.running)return e(I,{children:e(T,{icon:"portal",title:"No repo here runs the suite yet.",children:"Once repos run StackVitals, their CI, review and delivery numbers roll up here."})});let n=t.medians,o=t.totals,s=a=>a==null?"\u2013":`${Math.round(a*10)/10} h`,r=(a,i)=>a==="change_failure_rate"?$(i):a.endsWith("_h")?s(i):i;return e(m,{children:[e(S,{children:[e(f,{label:"Repos running the suite",value:`${t.running} of ${t.repos}`}),e(f,{label:"First-try green, median repo",value:$(n.ci_first_try),note:`${t.counts.ci_first_try??0} repos`}),e(f,{label:"Flaky checks",value:o.ci_flaky??"\u2013",note:`${o.ci_broken??0} broken`}),e(f,{label:"Open PRs",value:o.open_prs??"\u2013",note:`${o.stale_prs??0} stale`}),e(f,{label:"Pickup, median repo's P75",value:s(n.pickup_p75_h),note:`review ${s(n.review_p75_h)}`}),e(f,{label:"Deployments",value:o.deployments??"\u2013",note:n.change_failure_rate===null||n.change_failure_rate===void 0?null:`change fail rate ${$(n.change_failure_rate)} (median repo)`}),e(f,{label:"Known vulnerabilities",value:o.vulns_open??"\u2013",note:o.vulns_serious===null||o.vulns_serious===void 0?null:`${o.vulns_serious} critical, high or malware`})]}),e("h3",{class:"sub-h",children:"Where each number is highest"}),e("div",{class:"pt-leaders",children:Object.entries(et).filter(([a])=>(t.leaders[a]||[]).length).map(([a,i])=>e(y,{title:i,meta:k(t.leaders[a].length,"repo"),flush:!0,children:e("table",{class:"pt-mini",children:[e("thead",{children:e("tr",{children:[e("th",{scope:"col",children:"Repo"}),e("th",{scope:"col",class:"is-num",children:a==="change_failure_rate"?"Rate":a.endsWith("_h")?"Hours":"Count"})]})}),e("tbody",{children:t.leaders[a].map(p=>e("tr",{children:[e("td",{children:j(p.repo)}),e("td",{class:"is-num num",children:r(a,p.value)})]}))})]})}))})]})}function Ie({list:t}){return t.length?e("div",{class:"pt-grid",children:t.map(n=>{let o=n.passing===n.targets,s=n.days_left!=null&&n.days_left<0,r=n.days_left==null?"\u2013":n.days_left<0?`Ended ${k(-n.days_left,"day")} ago`:n.days_left===0?"Ends today":k(n.days_left,"day");return e(y,{title:n.title,tone:o?"good":s?"bad":"watch",meta:o?e(w,{tone:"good",children:"Every repo passes"}):e(w,{tone:s?"bad":"watch",children:[k((n.targets??0)-(n.passing??0),"repo")," still failing"]}),children:[e(ee,{rows:[["Passing",e("span",{class:"num",children:[n.passing??"\u2013"," of ",n.targets??"\u2013"]})],["Until",n.until?N(n.until):"No date"],["Days left",r]]}),e(J,{children:[e("div",{children:[e("h4",{class:"pt-h4",children:"Repos still failing, by day"}),e(Q,{label:`${n.title}: repos still failing by day`,height:160,bars:(n.burn_down||[]).map(([a,i])=>({label:ue(a),value:i,tone:"accent"}))})]}),e("div",{children:[e("h4",{class:"pt-h4",children:"Still failing"}),(n.failing||[]).length?e("ul",{class:"pt-fail",children:(n.failing||[]).slice(0,30).map(a=>e("li",{children:j(a)}))}):e("p",{class:"muted",children:"None."})]})]})]})})}):e(I,{children:e(T,{icon:"portal",title:"No campaigns.",children:["A campaign is a set of rules, the repos it targets and a date, in the portal repo's ",e("code",{class:"code-inline",children:"portal.toml"}),"."]})})}R();R();async function W(t,n){let o=await t.call("GET",n);if(o.ok)return o.data;if([401,403,404,451].includes(o.status)&&!(o.status===403&&o.headers.get("x-ratelimit-remaining")==="0"))return null;throw new Error(o.status===403||o.status===429?"GitHub's rate limit is used up; try again later or with a token":`GitHub answered ${o.status}`)}async function tt(t,n,o){let s=[],r=`/orgs/${encodeURIComponent(n)}/repos?type=all`;for(let a=1;a<=o;a++){let i=await W(t,`${r}&per_page=100&page=${a}`);i===null&&a===1&&(r=`/users/${encodeURIComponent(n)}/repos?type=owner`,i=await W(t,`${r}&per_page=100&page=${a}`));let p=(i||[]).filter(u=>u&&u.full_name);if(s.push(...p),p.length<100)return{list:s,more:!1}}return{list:s,more:!0}}async function ze(t,n,o=10){let{list:s,more:r}=await tt(t,n,o),a=s.filter(d=>d.private),i=[{what:"Repos",ok:s.length>0,detail:`${s.length}${r?"+":""} visible (${a.length} private)${r?`; stopped after ${o*100}`:""}`}],p=a[0]||s[0];if(p){let d=p.default_branch?`?ref=${encodeURIComponent(p.default_branch)}`:"",c=!1;for(let l of[".github/CODEOWNERS","CODEOWNERS","docs/CODEOWNERS"])if(await W(t,`/repos/${X(p.full_name)}/contents/${X(l)}${d}`)!==null){c=!0;break}i.push({what:"CODEOWNERS",ok:c,detail:c?`readable (tried ${p.full_name})`:`none found in ${p.full_name}`});let h=p.default_branch?await W(t,`/repos/${X(p.full_name)}/rules/branches/${encodeURIComponent(p.default_branch)}`):null;i.push({what:"Branch rules",ok:h!==null,detail:h!==null?"readable":"not available"})}let u=await W(t,`/orgs/${encodeURIComponent(n)}/teams?per_page=1`);i.push({what:"Teams",ok:u!==null,detail:u!==null?"readable":"not available"});let g=await W(t,`/orgs/${encodeURIComponent(n)}/properties/values?per_page=1`);return i.push({what:"Custom properties",ok:g!==null,detail:g!==null?"readable":"not available"}),i}var F=t=>t.name.split("/").pop().toLowerCase()===".github";function De({repos:t}){let n=t.filter(a=>!a.archived&&!a.fork),o=n.filter(a=>!F(a)),s=a=>o.filter(i=>i.owners?.status===a).length,r=a=>{let i=a.owners;if(i?.status==="none"&&i.suggested?.length){let p=z(a.name,a.default_branch||"main",".github/CODEOWNERS",Pe(i.suggested));return{label:"Add CODEOWNERS",href:p.url,link:p}}return i?.status==="weak"&&i.file?{label:"Edit CODEOWNERS",href:`https://github.com/${a.name}/edit/${encodeURIComponent(a.default_branch||"main")}/${i.file}`}:null};return e(m,{children:[e(S,{children:[e(f,{label:"Active repos",value:n.length,note:`${t.length-n.length} archived or forks, listed but not checked`}),e(f,{label:"Owners valid",value:s("valid")}),e(f,{label:"Owners weak",value:s("weak")}),e(f,{label:"No owners",value:s("none")})]}),e(P,{name:"owners-report",caption:"Owners report",rows:n,initialSort:{key:"owners",desc:!1},columns:[{key:"name",label:"Repo",primary:!0,render:a=>j(a.name)},{key:"level",label:"Level",filter:!0,raw:a=>F(a)?"not judged":a.score?.level||"below bronze",render:a=>F(a)?e("span",{class:"muted",children:"Not judged"}):V(a.score?.level)},{key:"owners",label:"Owners",filter:!0,raw:a=>F(a)?"not judged":a.owners?.status||"not checked",render:a=>F(a)?e("span",{class:"muted",children:"Not judged"}):U(a.owners?.status)},{key:"who",label:"Named in CODEOWNERS",raw:a=>(a.owners?.owners||[]).join(" "),render:a=>a.owners?.owners?.length?e("span",{class:"mono-soft",children:a.owners.owners.join(", ")}):"\u2013"},{key:"why",label:"Evidence",raw:a=>F(a)?"the org's shared settings repo":(a.owners?.reasons||[]).join("; "),render:a=>F(a)?"The org's shared settings repo":(a.owners?.reasons||[]).join("; ")||(a.owners?.file?`${a.owners.file} names an owner for every file`:"\u2013")},{key:"suggested",label:"Suggested",raw:a=>(a.owners?.suggested||[]).join(" "),render:a=>a.owners?.suggested?.length?e(m,{children:[e("span",{class:"mono-soft",children:a.owners.suggested.join(", ")}),e("div",{class:"muted small",children:["from ",a.owners.suggested_from||"recent commits"]})]}):"\u2013"},{key:"fix",label:"Fix",raw:()=>"",render:a=>{let i=r(a);return i?e(b,{size:"sm",variant:"tinted",href:i.href,external:!0,iconEnd:"external",...i.link?{onClick:D(i.link,"Opened on GitHub: press Commit changes there")}:{},children:i.label}):"\u2013"}}]}),e("p",{class:"muted small",children:"Add CODEOWNERS opens GitHub's editor with a file naming the suggested people; Edit opens the existing file. Either way you commit on GitHub, with your own access."})]})}function at({p:t,repos:n}){let o=n.filter(d=>d.private).length,s=n.filter(d=>d.owners?.status).length,r=n.filter(d=>d.protected!==null&&d.protected!==void 0).length,a=n.filter(d=>d.properties&&Object.keys(d.properties).length).length,i=n.reduce((d,c)=>d+(c.score?.not_available||0),0),p=n.filter(d=>d.error),u=(d,c,h)=>({what:d,ok:c,detail:h}),g=[u("Repos",n.length>0,`${n.length} read (${o} private), ${t.mode||"?"} mode${t.mode==="public"?": public repos only":""}`),u("CODEOWNERS",s===n.length,`checked in ${s} of ${n.length}`),u("Branch protection",r===n.length?!0:r?null:!1,`readable in ${r} of ${n.length}`),u("Custom properties",a?!0:null,a?`set on ${a} repos`:"none read (none set, or not readable)"),u("Scorecard rules",i?null:!0,i?`${k(i,"rule")} couldn't be read (published Scorecards cover public repos only)`:"every rule could be read"),u("Finished",p.length||t.complete===!1?null:!0,p.length?`stopped on ${p.map(d=>d.name).join(", ")}; their facts are from the run before`:t.complete===!1?"not every repo was checked yet; the next run continues":"every repo was checked")];return e(Be,{rows:g,name:"portal-last-run"})}var Be=({rows:t,name:n})=>e(P,{name:n,search:!1,rows:t.map((o,s)=>({...o,id:s})),columns:[{key:"what",label:"What",primary:!0},{key:"ok",label:"Result",raw:o=>o.ok?"readable":o.ok===!1?"not readable":"partly",render:o=>e(w,{tone:o.ok?"good":o.ok===!1?"bad":"watch",children:o.ok?"Readable":o.ok===!1?"Not readable":"Partly"})},{key:"detail",label:"Detail"}]});function de({org:t,p:n,repos:o}){let s=ce(fe),[r,a]=x(t),[i,p]=x(s?"account":"paste"),[u,g]=x(""),[d,c]=x(null),h=i==="account"?s?.token:i==="paste"?u:void 0,l=async()=>{c({busy:!0});try{let O=await ze(ye(h||null),r.trim());c({lines:O,as:i==="none"?"without a token":i==="account"?`as ${s?.login||"your account"}`:"with the pasted token"})}catch(O){c({error:O.message})}},C=/^[A-Za-z0-9-]{1,39}$/.test(r.trim())&&(i!=="paste"||!!u);return e("div",{class:"pt-grid",children:[n?e(y,{title:"What the last run could read",meta:"from catalog.json, no token needed",flush:!0,children:e(at,{p:n,repos:o})}):null,e(y,{title:"Check a token's access",meta:"what stackvitals portal check does",foot:e(m,{children:[e(b,{variant:"filled",icon:"check",loading:d?.busy,disabled:!C,onClick:l,children:["Check ",r.trim()||"the org"]}),e("span",{class:"pn-hint",children:"Read-only: about six requests to api.github.com from this browser; nothing is written and the token isn't kept."})]}),children:[e("p",{children:"Before a first run, or after changing the org App: see what a token can read in the org. The portal workflow reads with its own token (the built-in one for public repos, the org App's for private ones), so check with a token like the one it will use."}),e("div",{class:"pt-form",children:[e(v,{label:"Org or user",children:O=>e(_,{id:O,mono:!0,value:r,onInput:oe=>a(oe.trim())})}),e("div",{class:"field",children:[e("span",{class:"field-label",children:"Read as"}),e(H,{label:"Read as",value:i,onChange:p,scroll:!0,options:[...s?[{value:"account",label:`Signed in${s.login?` (${s.login})`:""}`}]:[],{value:"paste",label:"A token"},{value:"none",label:"No token"}]})]}),i==="paste"?e(v,{label:"Token",hint:"A fine-grained token for the org with read access to Contents, Metadata, Members and Custom properties, or a classic one with repo and read:org. Kept only until you leave the page.",children:O=>e(_,{id:O,type:"password",mono:!0,value:u,onInput:oe=>g(oe.trim()),placeholder:"github_pat_\u2026"})}):null,i==="none"?e("p",{class:"field-hint",children:"Without a token GitHub shows public data only, 60 requests an hour."}):null]}),e("div",{role:"status",children:d?.lines?e(m,{children:[e("p",{class:"pt-result-h",children:[r," ",d.as]}),e(Be,{rows:d.lines,name:"portal-check"})]}):null}),e("div",{role:"alert",children:d?.error?e("p",{class:"note note-bad",children:e("span",{children:["Not checked: ",d.error,"."]})}):null})]})]})}function je({org:t,repo:n,branch:o,exists:s,workflow:r}){let[a,i]=x("public"),p=pe({app:a==="private"}),u=r&&/portal/i.test(r)?`.github/workflows/${r}`:ae,g=z(n,o,ae,p);return e(y,{title:s?"The portal workflow":"The portal workflow file",meta:e("span",{class:"mono-soft",children:u}),foot:e(m,{children:[s?e(b,{variant:"tinted",href:`https://github.com/${n}/edit/${encodeURIComponent(o)}/${u}`,external:!0,icon:"external",children:"Edit it on GitHub"}):e(b,{variant:"filled",href:g.url,external:!0,icon:"external",onClick:D(g,"Opened on GitHub: press Commit changes there"),children:["Add it to ",n]}),a==="private"?e(b,{variant:"plain",href:B(t),external:!0,iconEnd:"external",children:"Create the read-only App"}):null,e("span",{class:"pn-hint",children:s?"Copy the file below, then paste it over the old one in GitHub's editor and commit; the next run uses it.":g.paste?"No token needed here.":"Opens GitHub's editor with the file filled in; commit it there. No token needed here."})]}),children:[s?null:e(we,{link:g}),e("div",{class:"field",children:[e("span",{class:"field-label",children:"Repos to read"}),e(H,{label:"Repos to read",value:a,onChange:i,options:[{value:"public",label:"Public repos"},{value:"private",label:"Private repos too"}]})]}),e("p",{children:a==="public"?"With the built-in token the workflow reads the org's public repos; nothing else to set up.":"Private repos need an org-owned GitHub App with read-only permissions: create it, install it on the org's repos, save its client ID as the variable PORTAL_CLIENT_ID and a private key as the secret PORTAL_PRIVATE_KEY in the portal repo. This file already has the App's token step switched on."}),e(L,{title:u,code:p})]})}function Ge({app:t}){let[n,o]=x(t?.repo?.split("/")[0]||""),[s,r]=x("portal"),a=/^[A-Za-z0-9-]{1,39}$/.test(n)&&/^[A-Za-z0-9._-]{1,100}$/.test(s),i=`${n||"my-org"}/${s}`,p=z(i,"main",ae,pe());return e("div",{class:"pt-grid",children:[e(y,{title:"Set up Portal for an org",meta:"about five minutes, no token here",children:[e("p",{children:"Portal runs once a day in a repo of its own and keeps the org's catalog, owners and scorecards on that repo's stackvitals-data branch, which only people who can read the repo can open."}),e("div",{class:"pt-form",children:[e(v,{label:"Org",children:u=>e(_,{id:u,mono:!0,value:n,onInput:g=>o(g.trim()),placeholder:"my-org"})}),e(v,{label:"Portal repo name",hint:"Private is best.",children:u=>e(_,{id:u,mono:!0,value:s,onInput:g=>r(g.trim())})})]})]}),e(y,{title:"Steps",flush:!0,children:e(_e,{items:[{title:"Create the portal repo",text:e(m,{children:["GitHub's new-repo form, filled in: ",e("span",{class:"mono-soft",children:i}),', private. Tick "Add a README" so it has a main branch.']}),action:e(b,{variant:"filled",disabled:!a,href:xe(n,s),external:!0,icon:"external",children:"Create it on GitHub"})},{title:"Add the workflow",text:e(m,{children:[p.paste?Z:"GitHub's editor opens with the portal workflow in it; commit it on main."," For private repos, use the file in the next panel instead."]}),action:e(b,{variant:"tinted",disabled:!a,href:p.url,external:!0,icon:"external",onClick:D(p,"Opened on GitHub: press Commit changes there"),children:"Add the workflow"})},{title:"Run it",text:"It runs daily; start the first run from the Actions tab (Run workflow). Then open this app on the portal repo.",action:e(b,{variant:"plain",disabled:!a,href:`https://github.com/${i}/actions`,external:!0,iconEnd:"external",children:"Open Actions"})}]})}),a?e(je,{org:n,repo:i,branch:"main",exists:!1}):null,e(de,{org:n,p:null,repos:[]}),e(He,{org:n||"my-org"})]})}function We({app:t,p:n}){let o=n.org||t.repo.split("/")[0],s=a=>`https://github.com/${t.repo}/blob/stackvitals-data/portal/${a}`,r=[["catalog.json","Every fact on this page, one record per repo"],["README.md","The same as a Markdown table, readable on GitHub"],["entities.yaml","A Backstage Component for each repo without its own catalog file: register its URL as one location"],["history/","One file a day; the campaign bars are drawn from it"]].map(([a,i])=>({id:a,file:a,what:i}));return e("div",{class:"pt-grid",children:[e(y,{title:"Files the portal workflow writes",meta:e(m,{children:["on the ",e("span",{class:"mono-soft",children:"stackvitals-data"})," branch, ",e("span",{class:"mono-soft",children:"portal/"})]}),flush:!0,children:e(P,{name:"portal-files",search:!1,rows:r,columns:[{key:"file",label:"File",primary:!0,nowrap:!0,render:a=>e("a",{class:"mono-soft",href:a.file.endsWith("/")?s(a.file).replace("/blob/","/tree/"):s(a.file),...G,children:["portal/",a.file]})},{key:"what",label:"What it holds"}]})}),e(je,{org:o,repo:t.repo,branch:t.default_branch||"main",exists:!0,workflow:t.links?.workflow}),e(y,{title:"Org App",meta:n.mode==="private"?e(w,{tone:"good",children:"Private mode is on"}):e(w,{tone:"neutral",icon:null,children:"Public repos only"}),foot:e(m,{children:[e(b,{variant:"tinted",href:B(o),external:!0,icon:"external",children:"Read-only App"}),e(b,{variant:"plain",href:B(o,!0),external:!0,iconEnd:"external",children:"App that may write"}),e("span",{class:"pn-hint",children:["Each opens GitHub's App form for ",o," with the permissions filled in; an org owner creates it there."]})]}),children:e(ee,{rows:[["Read-only","Private repos in the catalog: Actions, Contents, Metadata, Members and Custom properties, all read"],["May write","Also golden paths and required checks: checks, contents, pull requests, administration and workflows"]],cols:2})}),e(He,{org:o})]})}function He({org:t}){return e(y,{title:"From your machine",meta:"pip install stackvitals",children:[e("p",{children:"The same check and report with your own token, for any org you can read, before a portal repo exists or for an org this page doesn't show. These need a terminal because they read with your token and keep a copy on your computer."}),e(L,{inline:!0,code:`stackvitals portal check ${t}`,note:"What your token can read in the org (repos, CODEOWNERS, branch rules, teams, custom properties)."}),e(L,{inline:!0,code:`stackvitals portal report ${t}`,note:"Every repo and its owners, with evidence; --json for the whole catalog, --budget to cap API requests, --no-scorecard to skip OpenSSF."})]})}var qe=["gold","silver","bronze"],nt=t=>t.score?.level||"below bronze",Me=t=>t[0].toUpperCase()+t.slice(1),Ue=["repos","owners","rules","catalog","docs"],Ve={repos:"Repos",owners:"Owners",rules:"Rules",catalog:"Catalog",docs:"Docs"};function ot({app:t,route:n}){let o=be({p:"portal.json"});if(!o.ready)return e(ge,{});let s=o.p;return!s||!t?e(le,{title:"Portal",subtitle:"Every repo in an organisation with its owners, scorecard and catalog.",children:e(E,{title:"Set up Portal",description:"Portal runs from a repo of its own in the org. Create it and its workflow here, each one click on GitHub.",children:e(Ge,{app:t||null})})}):e(st,{app:t,p:s,route:n})}function st({app:t,p:n,route:o}){let s=Ue.includes(o.query.get("tab")||"")?o.query.get("tab"):"repos",r=(n.repos||[]).filter(l=>!l.archived),a=r.filter(l=>!l.fork),i=l=>r.filter(C=>C.score?.level===l).length,p=r.filter(l=>!l.score?.level).length,u={repos:r.length,owners:a.length,rules:new Set(r.flatMap(l=>(l.score?.results||[]).map(C=>C.id))).size,catalog:r.reduce((l,C)=>l+(C.descriptor?.entities?.length||0),0),docs:r.reduce((l,C)=>l+(C.doc_pages?.length||0),0)},g=r.filter(l=>l.owners?.status==="valid").length,d=n.org||t.repo.split("/")[0],c=o.query.get("repo"),h=l=>K(o,"repo",l);return e(le,{title:`Portal: ${d}`,subtitle:`${k(r.length,"repo")}, ${n.mode} mode, checked ${String(n.built_at||"").slice(0,16).replace("T"," ")}.`,toolbar:t.modules?.portal?.page||t.pages?.includes("portal.html")?e(b,{variant:"plain",href:t.modules?.portal?.page||"portal.html",iconEnd:"external",children:"Printable page"}):null,children:[e(E,{title:"Levels",description:"Each repo's level from the scorecard rules: bronze, silver, gold.",info:e(me,{info:{title:"Levels",doc:"modules.md#portal",body:"A repo reaches a level when it passes every rule at that level and the ones below. Exempt rules don't count against it; rules in preview aren't counted yet."}}),children:e(J,{ratio:"lead",children:[e(y,{title:"At bronze or better",meta:`${r.length-p} of ${k(r.length,"repo")}`,tone:p?"watch":"good",children:[e("div",{class:"pt-figure num",children:r.length?$((r.length-p)/r.length):"\u2013"}),e("p",{class:"pt-figure-note",children:p?`${p} below bronze; the Rules tab shows what fails most.`:"Every repo reaches bronze or better."}),e(Q,{label:"Repos by level",height:170,bars:[...qe.map(l=>({label:Me(l),value:i(l),tone:l==="gold"?"good":l==="bronze"?"watch":"neutral"})),{label:"Below bronze",value:p,tone:"bad"}]})]}),e(S,{children:[qe.map(l=>e(f,{label:Me(l),value:i(l)})),e(f,{label:"Below bronze",value:p}),e(f,{label:"Owners valid",value:g,note:`${r.filter(l=>l.owners?.status==="none").length} without CODEOWNERS`})]})]})}),e(E,{title:"Across the org",description:"The numbers each repo running StackVitals publishes, summed or as medians, and the repos that lead.",children:e(Te,{o:n.org_view})}),e(E,{title:"Repositories",description:"Every repo with its level, owners with evidence, the rules that fail most, the catalog and docs.",children:[e("div",{class:"pt-tabs",children:e(H,{label:"Show",scroll:!0,value:s,onChange:l=>ie(K(o,"tab",l==="repos"?null:l)),options:Ue.map(l=>({value:l,label:e(m,{children:[Ve[l],e("span",{class:"seg-count num",children:u[l]})]}),aria:`${Ve[l]}, ${u[l]}`}))})}),e("div",{class:"pt-panel",children:[s==="repos"?e(P,{name:"repos",caption:"Repos",rows:r,columns:[{key:"name",label:"Repo",primary:!0,render:l=>e(m,{children:[e("a",{href:h(l.name),title:"What Portal read about this repo",children:l.name}),l.modules?e("div",{class:"small",children:e("a",{href:`https://${l.name.split("/")[0].toLowerCase()}.github.io/${l.name.split("/")[1]}/`,...G,children:"Its StackVitals app"})}):null]})},{key:"visibility",label:"Visibility",filter:!0,raw:l=>l.private?"Private":"Public"},{key:"level",label:"Level",filter:!0,raw:nt,render:l=>V(l.score?.level)},{key:"owners",label:"Owners",filter:!0,raw:l=>l.owners?.status||"",render:l=>U(l.owners?.status)},{key:"protected",label:"Protected",filter:!0,raw:l=>String(l.protected??"can't read"),render:l=>M(l.protected)},{key:"language",label:"Language",filter:!0,render:l=>l.language||"\u2013"},{key:"runtime",label:"Runs on",filter:!0,raw:l=>(l.runtime||[]).join(" "),render:l=>(l.runtime||[]).join(", ")||"\u2013"},{key:"ci",label:"CI first try",num:!0,raw:l=>l.modules?.ci_first_try_share??null,render:l=>l.modules?.ci_first_try||"\u2013"},{key:"since",label:"At this level since",raw:l=>String((typeof l.since=="object"?l.since?.level:l.since)||""),render:l=>N(String((typeof l.since=="object"?l.since?.level:l.since)||""))}]}):null,s==="owners"?e(De,{repos:r}):null,s==="rules"?e(Ne,{repos:r}):null,s==="catalog"?e(Ae,{repos:a}):null,s==="docs"?e(Fe,{repos:a}):null]},s)]}),e(E,{title:"Campaigns",description:"A set of rules, the repos it targets and a date; the bars show repos still failing, day by day.",action:(n.campaigns||[]).length?e(w,{tone:"neutral",icon:null,children:k((n.campaigns||[]).length,"campaign")}):null,children:e(Ie,{list:n.campaigns||[]})}),e(E,{title:"Golden paths",description:"Start a new repo from a template, or open a pull request that adds standard files. One click sends it to the portal workflow.",children:e(Le,{app:t,p:n,repos:a})}),e(E,{title:"Access",description:"What the portal could read on its last run, and a check of any token's access to the org from this page.",children:e(de,{org:d,p:n,repos:r})}),e(E,{title:"Portal outside the app",description:"The files the portal workflow writes, the workflow itself, the org App and the terminal commands.",children:e(We,{app:t,p:n})}),e(Oe,{r:c&&r.find(l=>l.name===c)||null,onClose:()=>ie(K(o,"repo",null))})]})}export{ot as default};
@@ -0,0 +1 @@
1
+ .pr-me{display:flex;gap:6px;align-items:center}.pr-me .input{width:210px;max-width:100%}.pr-weeks{display:grid;grid-template-columns:repeat(auto-fill,minmax(min(100%,340px),1fr));gap:12px}.pr-weeks .sub-h{margin:0 0 8px}.pr-weeks .bars{gap:4px}.pr-weeks .bar-label{font-size:11px;text-overflow:clip;overflow:visible}.pr-weeks .bar:nth-child(2n) .bar-label{visibility:hidden}.pr-weeks .bar-value{font-size:11px}.pr-gaps{list-style:none;margin:0;padding:0;display:grid;gap:8px}.pr-gaps li{display:flex;flex-direction:column;gap:2px}.pr-left{margin-top:14px}.pr-pre-wrap{display:grid;gap:16px;min-width:0}.pr-pre-cli{display:flex;flex-direction:column;gap:8px;min-width:0}.pr-pre-cli .cmd code{overflow-wrap:anywhere}.pr-auto .send{margin:0}@media(max-width:640px){.pr-me{width:100%}.pr-me .input{width:100%;flex:1}}[data-design=sheet][data-page=prs] .sub-h .muted.small{font:400 14px/1.4 var(--font);color:var(--ink-2)}[data-design=sheet][data-page=prs] .pr-dim{margin-bottom:14px}[data-design=sheet][data-page=prs] .stats{gap:12px;background:none;border:0;overflow:visible}[data-design=sheet][data-page=prs] .stat{display:grid;grid-row:span 3;grid-template-rows:subgrid;row-gap:0;align-content:start;margin:0;padding:0 0 14px;background:var(--surface);border:1.5px solid var(--frame)}[data-design=sheet][data-page=prs] .stat-label{align-items:flex-start;justify-content:space-between;min-height:42px;padding:9px 14px;background:var(--strip);border-bottom:1px solid var(--line-strong);font:700 15px/1.35 var(--font);color:var(--ink)}[data-design=sheet][data-page=prs] .stat-value{margin:0;padding:12px 14px 4px}[data-design=sheet][data-page=prs] .stat-note{padding:0 14px;line-height:1.5}@media(min-width:821px){[data-design=sheet][data-page=prs] .stats:has(>.stat:nth-child(6):last-child){grid-template-columns:repeat(3,minmax(0,1fr))}}[data-design=sheet][data-page=prs] .card{border:1.5px solid var(--frame)}[data-design=sheet][data-page=prs] .card>.table-wrap.card{border:0}[data-design=sheet][data-page=prs] .card-pad>.sub-h:first-child{margin:-18px -18px 14px;padding:9px 18px;min-height:42px;align-items:baseline;background:var(--strip);border-bottom:1px solid var(--line-strong);font-size:16px}[data-design=sheet][data-page=prs] .bar-track{max-width:32px}[data-design=sheet][data-page=prs] .bar-fill.tone-watch{background:var(--sv-amber);border:1px solid var(--ink);border-bottom:0}[data-design=sheet][data-page=prs] .bar-value{font:700 14px/1.2 var(--font);color:var(--ink);font-variant-numeric:tabular-nums}[data-design=sheet][data-page=prs] .bar-label{font:600 14px/1.2 var(--font);color:var(--ink-2)}[data-design=sheet][data-page=prs] .pr-weeks{gap:12px}[data-design=sheet][data-page=prs] .pr-know .columns-lead{grid-template-columns:minmax(0,1fr)}[data-design=sheet][data-page=prs] .pr-know .mono-soft{overflow-wrap:normal;white-space:nowrap;font-size:14px;color:var(--ink);margin-right:8px}[data-design=sheet][data-page=prs] .pr-know .bar-label{white-space:nowrap}[data-design=sheet][data-page=prs] .pr-gaps .muted.small{font-size:14px}[data-design=sheet][data-page=prs] .pr-why{color:var(--ink-2)}.pr-queue .table td{overflow-wrap:normal;word-break:normal}.pr-queue .table td.is-nowrap .btn{white-space:nowrap}.blk-tbl{min-width:0}.blk-tbl+.blk-tbl,.stats+.blk-tbl,.blk-tbl+.stats,.blk-facts+.blk-tbl,.blk-tbl+.blk-facts,.blk-panel+.blk-tbl,.blk-tbl+.blk-panel,.dl-strip+.blk-tbl,.blk-tbl+.blk-grid,.blk-grid+.blk-tbl,.stats+.blk-panel,.blk-panel+.blk-panel,.stats+.blk-grid{margin-top:18px}.blk-tbl-h{display:flex;gap:4px 12px;align-items:baseline;flex-wrap:wrap;padding:10px 14px;background:var(--surface);border:1px solid var(--line);border-bottom:0;border-radius:var(--r-lg) var(--r-lg) 0 0}.blk-tbl-h h3{margin:0;font-size:15.5px;font-weight:700}.blk-tbl-note{font-size:13px;color:var(--ink-2)}.blk-tbl-act{margin-left:auto;display:inline-flex;gap:8px;align-items:center}.blk-tbl .table-wrap{border-top-left-radius:0;border-top-right-radius:0}.blk-tbl>.card:not(.table-wrap){border-top-left-radius:0;border-top-right-radius:0}@media(min-width:641px){.blk-tbl .table :is(th,td)+:is(th,td){border-left:1px solid var(--line)}}.blk-h{display:flex;gap:4px 12px;align-items:baseline;flex-wrap:wrap;margin:26px 0 10px;font-size:16px;font-weight:700}.blk-h:first-child{margin-top:0}.blk-h-note{font-size:13.5px;font-weight:400;color:var(--ink-2)}.blk-panel{display:flex;flex-direction:column;min-width:0;background:var(--surface);border:1px solid var(--line);border-radius:var(--r-lg);overflow:hidden}.blk-panel-h{display:flex;gap:6px 12px;align-items:center;justify-content:space-between;flex-wrap:wrap;min-height:44px;padding:10px 16px;background:var(--surface-2);border-bottom:1px solid var(--line)}.blk-panel-h h3{margin:0;font-size:15.5px;font-weight:700;overflow-wrap:anywhere;min-width:0}.blk-panel-state{font-size:14px;font-weight:600}.blk-panel-b{flex:1;display:flex;flex-direction:column;gap:14px;padding:14px 16px 16px;min-width:0}.blk-panel-b>*{margin:0}.blk-bar{display:flex;gap:8px;align-items:center;flex-wrap:wrap;padding:10px 16px;border-top:1px solid var(--line);background:var(--surface-2)}.blk-panel.blk-good{border-top:4px solid var(--good)}.blk-panel.blk-watch{border-top:4px solid var(--watch)}.blk-panel.blk-bad{border-top:4px solid var(--bad)}.blk-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,320px),1fr));gap:12px;align-items:stretch}.blk-grid>:is(.blk-tbl,.blk-panel){margin-top:0}.blk-facts{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:8px 18px;margin:0;font-size:14px}.blk-fact{display:contents}.blk-fact dt{font-weight:650;color:var(--ink-2)}.blk-fact dd{margin:0;min-width:0;overflow-wrap:anywhere}@media(max-width:520px){.blk-facts{grid-template-columns:minmax(0,1fr);gap:2px}.blk-fact dd{margin-bottom:8px}}.blk-mark{display:inline-flex;align-items:center;gap:7px;font-weight:650;white-space:nowrap}.blk-mark i{width:9px;height:9px;border-radius:50%;flex:none;background:var(--ink-3)}.blk-mark-good i{background:var(--good)}.blk-mark-watch i{background:var(--watch)}.blk-mark-bad i{background:var(--bad)}.blk-mark-accent i{background:var(--accent)}.blk-mark-neutral i{background:none;border:1.5px solid var(--ink-2)}.blk-mark-good{color:var(--good)}.blk-mark-bad{color:var(--bad)}.blk-mark-watch{color:var(--watch)}.blk-mark-neutral{color:var(--ink-2)}.blk-machine .blk-machine-cmd{display:flex;flex-direction:column;gap:10px;min-width:0}.blk-form{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(100%,220px),1fr));gap:12px 16px;align-items:start}.blk-form .field{min-width:0}.blk-form textarea.input{min-height:96px;padding:10px 12px;resize:vertical;font:400 14px/1.5 var(--mono);width:100%}.blk-note{font-size:13.5px;color:var(--ink-2);margin:0;max-width:80ch}.blk-list{margin:0;padding-left:20px;display:grid;gap:4px;font-size:14px}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-tbl-h{min-height:42px;padding:9px 14px;background:var(--strip);border:1.5px solid var(--frame);border-bottom:1px solid var(--line-strong);border-radius:0}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-tbl-h h3{font-size:15.5px;font-weight:700;color:var(--ink)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-tbl-note{font-size:14px;color:var(--ink-2)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-tbl>:is(.table-wrap,.card){border:1.5px solid var(--frame);border-top:0}@media(min-width:641px){[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-tbl .table :is(th,td)+:is(th,td){border-left-color:var(--line)}}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-panel{border:1.5px solid var(--frame);border-radius:0}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-panel.blk-good{border-top:5px solid var(--sv-mint)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-panel.blk-watch{border-top:5px solid var(--sv-amber)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-panel.blk-bad{border-top:5px solid var(--sv-coral)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-panel-h{min-height:42px;padding:9px 14px;background:var(--strip);border-bottom:1px solid var(--line-strong)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-panel-h h3{font-size:15.5px;color:var(--ink)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-panel-state{font-size:15px}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-panel-b{padding:14px;font-size:15px}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-bar{padding:10px 14px;background:var(--surface);border-top:1px solid var(--line-strong)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-facts{font-size:15px;gap:8px 20px}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-fact dt{font-weight:600;color:var(--ink-2)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark{font-size:15px;font-weight:700;color:var(--ink)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark i{width:13px;height:13px;border:0;border-radius:0;background:center / contain no-repeat}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-good i{background-image:var(--mark-good)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-watch i{background-image:var(--mark-watch)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-bad i{background-image:var(--mark-bad)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-good{color:var(--good)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-bad{color:var(--bad)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-watch{color:var(--watch)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-neutral{color:var(--ink-2)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-neutral i{width:10px;height:10px;border:1.5px solid currentColor}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-mark-accent i{width:10px;height:10px;background:var(--sv-blue)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-note{font-size:15px}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-list{font-size:15px}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-form textarea.input{border-radius:0}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-h{padding-bottom:6px;border-bottom:1.5px solid var(--frame);font-size:17px;color:var(--ink)}[data-design=sheet]:is([data-page=prs],[data-page=delivery],[data-page=investment]) .blk-h-note{font-size:15px}