openpitstop 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (274) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +512 -0
  3. package/demo-repo/README.md +24 -0
  4. package/demo-repo/package-lock.json +4483 -0
  5. package/demo-repo/package.json +17 -0
  6. package/demo-repo/src/config.js +5 -0
  7. package/demo-repo/src/db.js +31 -0
  8. package/demo-repo/src/server.js +13 -0
  9. package/demo-repo/src/userController.js +22 -0
  10. package/demo-repo/src/userRepo.js +18 -0
  11. package/demo-repo/src/userService.js +59 -0
  12. package/demo-repo/test/user.test.js +12 -0
  13. package/demo-repo-fintech/README.md +27 -0
  14. package/demo-repo-fintech/package-lock.json +1023 -0
  15. package/demo-repo-fintech/package.json +14 -0
  16. package/demo-repo-fintech/pitstop-repro-ledger-order-ord-conc-1-charged-2.test.mjs +175 -0
  17. package/demo-repo-fintech/pitstop-repro-ledger-order-ord-retry-2-charged-2.test.mjs +175 -0
  18. package/demo-repo-fintech/pitstop-repro-ledger-order-ord-webhook-3-charged-2.test.mjs +175 -0
  19. package/demo-repo-fintech/src/gateway.js +26 -0
  20. package/demo-repo-fintech/src/server.js +61 -0
  21. package/demo-repo-generators/package-lock.json +1508 -0
  22. package/demo-repo-generators/package.json +17 -0
  23. package/demo-repo-generators/public/index.html +10 -0
  24. package/demo-repo-generators/scripts/build.js +17 -0
  25. package/demo-repo-generators/src/counter.js +16 -0
  26. package/demo-repo-integrity/README.md +49 -0
  27. package/demo-repo-integrity/package.json +12 -0
  28. package/demo-repo-integrity/src/money.js +19 -0
  29. package/demo-repo-integrity/test/money.test.js +17 -0
  30. package/dist/analyzers/accessibility.d.ts +18 -0
  31. package/dist/analyzers/accessibility.js +248 -0
  32. package/dist/analyzers/accessibility.js.map +1 -0
  33. package/dist/analyzers/dependencyGraph.d.ts +14 -0
  34. package/dist/analyzers/dependencyGraph.js +206 -0
  35. package/dist/analyzers/dependencyGraph.js.map +1 -0
  36. package/dist/analyzers/devex.d.ts +19 -0
  37. package/dist/analyzers/devex.js +301 -0
  38. package/dist/analyzers/devex.js.map +1 -0
  39. package/dist/analyzers/duplication.d.ts +2 -0
  40. package/dist/analyzers/duplication.js +47 -0
  41. package/dist/analyzers/duplication.js.map +1 -0
  42. package/dist/analyzers/index.d.ts +12 -0
  43. package/dist/analyzers/index.js +38 -0
  44. package/dist/analyzers/index.js.map +1 -0
  45. package/dist/analyzers/integrity/assertionLiteralTamper.d.ts +2 -0
  46. package/dist/analyzers/integrity/assertionLiteralTamper.js +164 -0
  47. package/dist/analyzers/integrity/assertionLiteralTamper.js.map +1 -0
  48. package/dist/analyzers/integrity/exceptionSwallow.d.ts +2 -0
  49. package/dist/analyzers/integrity/exceptionSwallow.js +198 -0
  50. package/dist/analyzers/integrity/exceptionSwallow.js.map +1 -0
  51. package/dist/analyzers/integrity/exitCheat.d.ts +2 -0
  52. package/dist/analyzers/integrity/exitCheat.js +31 -0
  53. package/dist/analyzers/integrity/exitCheat.js.map +1 -0
  54. package/dist/analyzers/integrity/git.d.ts +10 -0
  55. package/dist/analyzers/integrity/git.js +181 -0
  56. package/dist/analyzers/integrity/git.js.map +1 -0
  57. package/dist/analyzers/integrity/hardcodedMatch.d.ts +2 -0
  58. package/dist/analyzers/integrity/hardcodedMatch.js +93 -0
  59. package/dist/analyzers/integrity/hardcodedMatch.js.map +1 -0
  60. package/dist/analyzers/integrity/helpers.d.ts +21 -0
  61. package/dist/analyzers/integrity/helpers.js +66 -0
  62. package/dist/analyzers/integrity/helpers.js.map +1 -0
  63. package/dist/analyzers/integrity/index.d.ts +10 -0
  64. package/dist/analyzers/integrity/index.js +27 -0
  65. package/dist/analyzers/integrity/index.js.map +1 -0
  66. package/dist/analyzers/integrity/mockOverreach.d.ts +2 -0
  67. package/dist/analyzers/integrity/mockOverreach.js +72 -0
  68. package/dist/analyzers/integrity/mockOverreach.js.map +1 -0
  69. package/dist/analyzers/integrity/suppressionCreep.d.ts +2 -0
  70. package/dist/analyzers/integrity/suppressionCreep.js +27 -0
  71. package/dist/analyzers/integrity/suppressionCreep.js.map +1 -0
  72. package/dist/analyzers/integrity/testTamper.d.ts +2 -0
  73. package/dist/analyzers/integrity/testTamper.js +153 -0
  74. package/dist/analyzers/integrity/testTamper.js.map +1 -0
  75. package/dist/analyzers/integrity/types.d.ts +63 -0
  76. package/dist/analyzers/integrity/types.js +13 -0
  77. package/dist/analyzers/integrity/types.js.map +1 -0
  78. package/dist/analyzers/ledger/attacks.d.ts +17 -0
  79. package/dist/analyzers/ledger/attacks.js +135 -0
  80. package/dist/analyzers/ledger/attacks.js.map +1 -0
  81. package/dist/analyzers/ledger/discover.d.ts +15 -0
  82. package/dist/analyzers/ledger/discover.js +122 -0
  83. package/dist/analyzers/ledger/discover.js.map +1 -0
  84. package/dist/analyzers/ledger/evidence.d.ts +22 -0
  85. package/dist/analyzers/ledger/evidence.js +127 -0
  86. package/dist/analyzers/ledger/evidence.js.map +1 -0
  87. package/dist/analyzers/ledger/harness.d.ts +4 -0
  88. package/dist/analyzers/ledger/harness.js +270 -0
  89. package/dist/analyzers/ledger/harness.js.map +1 -0
  90. package/dist/analyzers/ledger/index.d.ts +14 -0
  91. package/dist/analyzers/ledger/index.js +116 -0
  92. package/dist/analyzers/ledger/index.js.map +1 -0
  93. package/dist/analyzers/ledger/types.d.ts +31 -0
  94. package/dist/analyzers/ledger/types.js +2 -0
  95. package/dist/analyzers/ledger/types.js.map +1 -0
  96. package/dist/analyzers/perf.d.ts +2 -0
  97. package/dist/analyzers/perf.js +106 -0
  98. package/dist/analyzers/perf.js.map +1 -0
  99. package/dist/analyzers/reliability.d.ts +22 -0
  100. package/dist/analyzers/reliability.js +339 -0
  101. package/dist/analyzers/reliability.js.map +1 -0
  102. package/dist/analyzers/routes.d.ts +17 -0
  103. package/dist/analyzers/routes.js +115 -0
  104. package/dist/analyzers/routes.js.map +1 -0
  105. package/dist/analyzers/security.d.ts +2 -0
  106. package/dist/analyzers/security.js +302 -0
  107. package/dist/analyzers/security.js.map +1 -0
  108. package/dist/analyzers/suiteRunner.d.ts +64 -0
  109. package/dist/analyzers/suiteRunner.js +381 -0
  110. package/dist/analyzers/suiteRunner.js.map +1 -0
  111. package/dist/analyzers/tests.d.ts +2 -0
  112. package/dist/analyzers/tests.js +215 -0
  113. package/dist/analyzers/tests.js.map +1 -0
  114. package/dist/analyzers/types.d.ts +203 -0
  115. package/dist/analyzers/types.js +2 -0
  116. package/dist/analyzers/types.js.map +1 -0
  117. package/dist/analyzers/util.d.ts +35 -0
  118. package/dist/analyzers/util.js +209 -0
  119. package/dist/analyzers/util.js.map +1 -0
  120. package/dist/ciCheckA.d.ts +2 -0
  121. package/dist/ciCheckA.js +5 -0
  122. package/dist/ciCheckA.js.map +1 -0
  123. package/dist/ciCheckB.d.ts +2 -0
  124. package/dist/ciCheckB.js +6 -0
  125. package/dist/ciCheckB.js.map +1 -0
  126. package/dist/cli.d.ts +2 -0
  127. package/dist/cli.js +65 -0
  128. package/dist/cli.js.map +1 -0
  129. package/dist/commands/budget.d.ts +33 -0
  130. package/dist/commands/budget.js +108 -0
  131. package/dist/commands/budget.js.map +1 -0
  132. package/dist/commands/ci.d.ts +14 -0
  133. package/dist/commands/ci.js +157 -0
  134. package/dist/commands/ci.js.map +1 -0
  135. package/dist/commands/demo.d.ts +2 -0
  136. package/dist/commands/demo.js +163 -0
  137. package/dist/commands/demo.js.map +1 -0
  138. package/dist/commands/digest.d.ts +8 -0
  139. package/dist/commands/digest.js +189 -0
  140. package/dist/commands/digest.js.map +1 -0
  141. package/dist/commands/doctor.d.ts +2 -0
  142. package/dist/commands/doctor.js +98 -0
  143. package/dist/commands/doctor.js.map +1 -0
  144. package/dist/commands/drive.d.ts +3 -0
  145. package/dist/commands/drive.js +170 -0
  146. package/dist/commands/drive.js.map +1 -0
  147. package/dist/commands/gate.d.ts +2 -0
  148. package/dist/commands/gate.js +136 -0
  149. package/dist/commands/gate.js.map +1 -0
  150. package/dist/commands/honesty.d.ts +2 -0
  151. package/dist/commands/honesty.js +182 -0
  152. package/dist/commands/honesty.js.map +1 -0
  153. package/dist/commands/inspect.d.ts +2 -0
  154. package/dist/commands/inspect.js +244 -0
  155. package/dist/commands/inspect.js.map +1 -0
  156. package/dist/commands/install.d.ts +2 -0
  157. package/dist/commands/install.js +81 -0
  158. package/dist/commands/install.js.map +1 -0
  159. package/dist/commands/integrity.d.ts +2 -0
  160. package/dist/commands/integrity.js +74 -0
  161. package/dist/commands/integrity.js.map +1 -0
  162. package/dist/commands/memory.d.ts +6 -0
  163. package/dist/commands/memory.js +90 -0
  164. package/dist/commands/memory.js.map +1 -0
  165. package/dist/commands/pen.d.ts +17 -0
  166. package/dist/commands/pen.js +158 -0
  167. package/dist/commands/pen.js.map +1 -0
  168. package/dist/commands/prompt.d.ts +2 -0
  169. package/dist/commands/prompt.js +37 -0
  170. package/dist/commands/prompt.js.map +1 -0
  171. package/dist/commands/readyCheck.d.ts +21 -0
  172. package/dist/commands/readyCheck.js +68 -0
  173. package/dist/commands/readyCheck.js.map +1 -0
  174. package/dist/commands/report.d.ts +2 -0
  175. package/dist/commands/report.js +48 -0
  176. package/dist/commands/report.js.map +1 -0
  177. package/dist/commands/repro.d.ts +3 -0
  178. package/dist/commands/repro.js +61 -0
  179. package/dist/commands/repro.js.map +1 -0
  180. package/dist/commands/scan.d.ts +27 -0
  181. package/dist/commands/scan.js +348 -0
  182. package/dist/commands/scan.js.map +1 -0
  183. package/dist/commands/share.d.ts +2 -0
  184. package/dist/commands/share.js +163 -0
  185. package/dist/commands/share.js.map +1 -0
  186. package/dist/commands/trends.d.ts +2 -0
  187. package/dist/commands/trends.js +103 -0
  188. package/dist/commands/trends.js.map +1 -0
  189. package/dist/commands/try.d.ts +12 -0
  190. package/dist/commands/try.js +208 -0
  191. package/dist/commands/try.js.map +1 -0
  192. package/dist/commands/verify.d.ts +44 -0
  193. package/dist/commands/verify.js +381 -0
  194. package/dist/commands/verify.js.map +1 -0
  195. package/dist/commands/watch.d.ts +10 -0
  196. package/dist/commands/watch.js +70 -0
  197. package/dist/commands/watch.js.map +1 -0
  198. package/dist/evidence.d.ts +37 -0
  199. package/dist/evidence.js +61 -0
  200. package/dist/evidence.js.map +1 -0
  201. package/dist/graph/correlate.d.ts +7 -0
  202. package/dist/graph/correlate.js +246 -0
  203. package/dist/graph/correlate.js.map +1 -0
  204. package/dist/graph/integrity.d.ts +22 -0
  205. package/dist/graph/integrity.js +39 -0
  206. package/dist/graph/integrity.js.map +1 -0
  207. package/dist/installer/targets.d.ts +23 -0
  208. package/dist/installer/targets.js +162 -0
  209. package/dist/installer/targets.js.map +1 -0
  210. package/dist/memory/store.d.ts +33 -0
  211. package/dist/memory/store.js +131 -0
  212. package/dist/memory/store.js.map +1 -0
  213. package/dist/pen/dynamic.d.ts +36 -0
  214. package/dist/pen/dynamic.js +622 -0
  215. package/dist/pen/dynamic.js.map +1 -0
  216. package/dist/pen/fix.d.ts +35 -0
  217. package/dist/pen/fix.js +239 -0
  218. package/dist/pen/fix.js.map +1 -0
  219. package/dist/pen/proof.d.ts +46 -0
  220. package/dist/pen/proof.js +112 -0
  221. package/dist/pen/proof.js.map +1 -0
  222. package/dist/pen/report.d.ts +11 -0
  223. package/dist/pen/report.js +258 -0
  224. package/dist/pen/report.js.map +1 -0
  225. package/dist/pen/static.d.ts +17 -0
  226. package/dist/pen/static.js +565 -0
  227. package/dist/pen/static.js.map +1 -0
  228. package/dist/pen/store.d.ts +11 -0
  229. package/dist/pen/store.js +36 -0
  230. package/dist/pen/store.js.map +1 -0
  231. package/dist/pen/types.d.ts +112 -0
  232. package/dist/pen/types.js +53 -0
  233. package/dist/pen/types.js.map +1 -0
  234. package/dist/report/format.d.ts +126 -0
  235. package/dist/report/format.js +706 -0
  236. package/dist/report/format.js.map +1 -0
  237. package/dist/report/score.d.ts +47 -0
  238. package/dist/report/score.js +164 -0
  239. package/dist/report/score.js.map +1 -0
  240. package/dist/repro/framework.d.ts +26 -0
  241. package/dist/repro/framework.js +224 -0
  242. package/dist/repro/framework.js.map +1 -0
  243. package/dist/repro/generate.d.ts +14 -0
  244. package/dist/repro/generate.js +669 -0
  245. package/dist/repro/generate.js.map +1 -0
  246. package/dist/repro/ids.d.ts +32 -0
  247. package/dist/repro/ids.js +175 -0
  248. package/dist/repro/ids.js.map +1 -0
  249. package/dist/repro/index.d.ts +24 -0
  250. package/dist/repro/index.js +69 -0
  251. package/dist/repro/index.js.map +1 -0
  252. package/dist/repro/pen.d.ts +26 -0
  253. package/dist/repro/pen.js +321 -0
  254. package/dist/repro/pen.js.map +1 -0
  255. package/dist/repro/run.d.ts +18 -0
  256. package/dist/repro/run.js +36 -0
  257. package/dist/repro/run.js.map +1 -0
  258. package/dist/sandbox/proxy.d.ts +41 -0
  259. package/dist/sandbox/proxy.js +231 -0
  260. package/dist/sandbox/proxy.js.map +1 -0
  261. package/dist/sandbox/startCmd.d.ts +24 -0
  262. package/dist/sandbox/startCmd.js +71 -0
  263. package/dist/sandbox/startCmd.js.map +1 -0
  264. package/dist/ui/spinner.d.ts +18 -0
  265. package/dist/ui/spinner.js +26 -0
  266. package/dist/ui/spinner.js.map +1 -0
  267. package/dist/verify/metrics.d.ts +13 -0
  268. package/dist/verify/metrics.js +72 -0
  269. package/dist/verify/metrics.js.map +1 -0
  270. package/package.json +68 -0
  271. package/scripts/cheat-demo.cjs +102 -0
  272. package/templates/ledger/preload.cjs +331 -0
  273. package/templates/pen/preload.cjs +196 -0
  274. package/templates/pitstop.prompt.md +371 -0
@@ -0,0 +1,163 @@
1
+ import { Command } from "commander";
2
+ import path from "node:path";
3
+ import fs from "node:fs";
4
+ import { exec } from "node:child_process";
5
+ import chalk from "chalk";
6
+ import { buildModel, escapeHtml, loadHistory, svgTrend } from "../report/format.js";
7
+ import { computeScore, gradeHex, renderBadgeSvg } from "../report/score.js";
8
+ import { checkEvidence } from "../evidence.js";
9
+ import { enumerateFindings } from "../repro/ids.js";
10
+ const SEV_ORDER = { critical: 0, high: 1, medium: 2, low: 3, warning: 4 };
11
+ /**
12
+ * `pitstop share` — the viral artifact: a 1200×630 self-contained HTML card
13
+ * (inline CSS + inline SVG, zero external assets) built to be screenshotted and
14
+ * posted on X/LinkedIn. Opens in the browser with `--open`.
15
+ */
16
+ function topFindings(latest) {
17
+ if (!latest)
18
+ return [];
19
+ return enumerateFindings(latest)
20
+ .sort((a, b) => (SEV_ORDER[a.severity] ?? 9) - (SEV_ORDER[b.severity] ?? 9) ||
21
+ a.type.localeCompare(b.type))
22
+ .slice(0, 4);
23
+ }
24
+ function chip(hex, text) {
25
+ return `<span style="display:inline-block;background:${hex}1f;color:${hex};border:1px solid ${hex}66;border-radius:999px;padding:3px 12px;font-size:13px;font-weight:600;margin:3px 6px 0 0">${escapeHtml(text)}</span>`;
26
+ }
27
+ function renderShareHtml(args) {
28
+ const sc = args.score;
29
+ const accent = sc ? gradeHex(sc.grade) : "#58a6ff";
30
+ const findingsRows = args.findings.length === 0
31
+ ? `<div class="muted" style="font-size:15px">No findings in the latest scan — clean repo.</div>`
32
+ : args.findings
33
+ .map((f) => {
34
+ const dot = f.severity === "critical" || f.severity === "high"
35
+ ? "#f85149"
36
+ : f.severity === "medium"
37
+ ? "#d29922"
38
+ : "#58a6ff";
39
+ return `<div class="finding"><span class="dot" style="background:${dot}"></span><span class="fsrc">${escapeHtml(f.source)}</span><span class="fdesc">${escapeHtml(f.description)}</span></div>`;
40
+ })
41
+ .join("\n");
42
+ return `<!DOCTYPE html>
43
+ <html lang="en">
44
+ <head>
45
+ <meta charset="utf-8"/>
46
+ <meta name="viewport" content="width=device-width, initial-scale=1"/>
47
+ <title>PITSTOP — ${escapeHtml(args.repo)}</title>
48
+ <meta name="twitter:card" content="summary_large_image"/>
49
+ <meta name="og:title" content="OpenPitStop scored ${escapeHtml(args.repo)} — ${sc ? sc.score + "/100 (" + sc.grade + ")" : "no scan yet"}"/>
50
+ <meta name="og:description" content="OpenPitStop scans repos, gates AI agents, and seals every report with a tamper-evident signature. npx openpitstop try"/>
51
+ <style>
52
+ :root{color-scheme:dark}
53
+ *{box-sizing:border-box;margin:0;padding:0}
54
+ html,body{width:1200px;height:630px;overflow:hidden}
55
+ body{background:#0d1117;color:#e6edf3;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif}
56
+ .wrap{width:1200px;height:630px;display:flex;flex-direction:column;padding:44px 52px 34px;position:relative;background:radial-gradient(1200px 420px at 88% -8%, ${accent}1c, transparent 60%)}
57
+ header{display:flex;align-items:center;gap:20px}
58
+ .mark{font-size:27px;font-weight:800;letter-spacing:0.5px;flex:0 0 auto}
59
+ .mark b{color:${accent}}
60
+ .repo{color:#8b949e;font-size:16px;flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
61
+ .when{color:#8b949e;font-size:13px;flex:0 0 auto}
62
+ main{flex:1;display:flex;gap:64px;align-items:center;margin-top:22px}
63
+ .left{flex:0 0 300px}
64
+ .score{font-size:150px;font-weight:800;line-height:1;color:${accent};font-variant-numeric:tabular-nums}
65
+ .score small{font-size:34px;font-weight:600;color:#8b949e}
66
+ .grd{font-size:40px;font-weight:800;color:${accent};margin-top:8px}
67
+ .sub{color:#8b949e;font-size:15px;margin-top:10px}
68
+ .right{flex:1;min-width:0}
69
+ .chips{display:flex;flex-wrap:wrap}
70
+ .trend{margin-top:16px;background:#161b22;border:1px solid #30363d;border-radius:12px;padding:14px 16px}
71
+ .trend h4{color:#8b949e;font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:0.5px;margin-bottom:6px}
72
+ .findings{background:#161b22;border:1px solid #30363d;border-radius:12px;padding:16px 18px;margin-top:14px}
73
+ .findings h4{color:#8b949e;font-size:12px;font-weight:600;text-transform:uppercase;letter-spacing:0.5px;margin-bottom:8px}
74
+ .finding{display:flex;align-items:center;gap:10px;padding:8px 0;font-size:15px}
75
+ .finding + .finding{border-top:1px solid #21262d}
76
+ .dot{width:9px;height:9px;border-radius:50%;flex:0 0 auto}
77
+ .fsrc{color:#8b949e;font-size:12px;text-transform:uppercase;letter-spacing:0.4px;flex:0 0 72px}
78
+ .fdesc{color:#e6edf3;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
79
+ footer{margin-top:22px;padding-top:16px;border-top:1px solid #30363d;display:flex;justify-content:space-between;align-items:center;color:#8b949e;font-size:13px}
80
+ footer b{color:${accent}}
81
+ .muted{color:#8b949e}
82
+ </style>
83
+ </head>
84
+ <body><div class="wrap">
85
+ <header>
86
+ <div class="mark">PITSTOP</div>
87
+ <div class="repo" title="${escapeHtml(args.repo)}">${escapeHtml(args.repo)}</div>
88
+ <div class="when">${escapeHtml(args.generatedAt.slice(0, 19).replace("T", " "))}</div>
89
+ </header>
90
+ <main>
91
+ <div class="left">
92
+ ${sc ? `<div class="score">${sc.score}<small>/100</small></div><div class="grd">${escapeHtml(sc.grade)}</div>` : `<div class="score" style="font-size:52px">no scan</div><div class="grd">—</div>`}
93
+ <div class="sub">OpenPitStop Score · health of the repo</div>
94
+ </div>
95
+ <div class="right">
96
+ <div class="chips">${args.chips}</div>
97
+ <div class="trend"><h4>Score across ${args.scansCount} scan(s)</h4>${args.sparkline}</div>
98
+ <div class="findings"><h4>Top findings</h4>${findingsRows}</div>
99
+ </div>
100
+ </main>
101
+ <footer>
102
+ <span>npx openpitstop try · scan / verify / gate / digest</span>
103
+ <span>permanent proof: <b>${args.proofCount}</b> committed repro test(s)</span>
104
+ </footer>
105
+ </div></body></html>`;
106
+ }
107
+ export const share = new Command("share")
108
+ .description("Generate a 1200×630 self-contained share card (PITSTOP_CARD.html) with the OpenPitStop Score, " +
109
+ "integrity/evidence status and top findings — built to be screenshotted and posted.")
110
+ .argument("[repo]", "path to the repo (default: current dir)", ".")
111
+ .option("-o, --open", "open the card in the default browser", false)
112
+ .action((repoArg, options) => {
113
+ const repo = path.resolve(repoArg);
114
+ const model = buildModel(repo);
115
+ const hist = loadHistory(repo);
116
+ if (hist.scans.length === 0) {
117
+ console.log(chalk.yellow(`no scan history in ${path.join(repo, ".pitstop")} — run \`pitstop try\` or \`pitstop scan\` first.`));
118
+ return;
119
+ }
120
+ const sc = model.latestScan ? computeScore(model.latestScan) : null;
121
+ const accent = sc ? gradeHex(sc.grade) : "#58a6ff";
122
+ const scores = hist.scans.map((s) => computeScore(s).score);
123
+ const spark = svgTrend(scores, "#58a6ff");
124
+ const latestEv = model.latestScan ? checkEvidence(model.latestScan) : null;
125
+ const evStatus = latestEv?.status === "verified"
126
+ ? `signed ${latestEv.digest.slice(0, 8)}…`
127
+ : latestEv?.status === "tampered"
128
+ ? "evidence TAMPERED"
129
+ : "evidence untracked";
130
+ const chips = [];
131
+ chips.push(`${sc?.score ?? 0}/100 ${sc?.grade ?? "?"}`);
132
+ chips.push(model.integrity
133
+ ? `integrity ${model.integrity.catches} catch · ${model.integrity.selfCorrected} self-corrected`
134
+ : "integrity not checked");
135
+ chips.push(evStatus);
136
+ const findings = topFindings(model.latestScan);
137
+ const badgeSvg = sc ? renderBadgeSvg(sc) : "";
138
+ const html = renderShareHtml({
139
+ repo,
140
+ generatedAt: model.generatedAt,
141
+ score: sc ? { score: sc.score, grade: sc.grade } : null,
142
+ scansCount: hist.scans.length,
143
+ sparkline: spark,
144
+ chips: chips.map((c) => chip(accent, c)).join(""),
145
+ findings,
146
+ proofCount: model.proofs.length,
147
+ });
148
+ const out = path.join(repo, "PITSTOP_CARD.html");
149
+ fs.writeFileSync(out, html);
150
+ console.log(chalk.cyan(`\nShare card written to ${out}`));
151
+ console.log(chalk.dim(` open it, screenshot at 1200×630, post it. Fully self-contained.\n`) +
152
+ (badgeSvg ? chalk.dim(` README badge also renders: ${chalk.cyan("[OpenPitStop score](PITSTOP_BADGE.svg)")}\n`) : ""));
153
+ if (options.open) {
154
+ const cmd = process.platform === "win32"
155
+ ? `start "" "${out}"`
156
+ : process.platform === "darwin"
157
+ ? `open "${out}"`
158
+ : `xdg-open "${out}"`;
159
+ exec(cmd);
160
+ console.log(chalk.dim(" opened in your default browser."));
161
+ }
162
+ });
163
+ //# sourceMappingURL=share.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"share.js","sourceRoot":"","sources":["../../src/commands/share.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare const trends: Command;
@@ -0,0 +1,103 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import boxen from "boxen";
4
+ import path from "node:path";
5
+ import { loadHistory } from "../report/format.js";
6
+ import { computeScore, gradeColor } from "../report/score.js";
7
+ /**
8
+ * `pitstop trends` — turn the .pitstop/scan-*.json history into sparklines.
9
+ * Every scan is persisted, so this shows the loop actually improving things.
10
+ */
11
+ const BLOCKS = "▁▂▃▄▅▆▇█";
12
+ function sparkline(values) {
13
+ const pts = values.filter((v) => v != null);
14
+ if (pts.length === 0)
15
+ return chalk.dim("no data");
16
+ if (pts.length === 1)
17
+ return chalk.dim(String(pts[0]));
18
+ const min = Math.min(...pts);
19
+ const max = Math.max(...pts);
20
+ const span = max - min || 1;
21
+ const chars = values.map((v) => {
22
+ if (v == null)
23
+ return " ";
24
+ const idx = Math.min(7, Math.floor(((v - min) / span) * 7.999));
25
+ return BLOCKS[idx];
26
+ });
27
+ const improving = pts[pts.length - 1] < pts[0];
28
+ const paint = pts.length < 2 ? chalk.dim : improving ? chalk.green : chalk.yellow;
29
+ return paint(chars.join(""));
30
+ }
31
+ function num(v) {
32
+ return v == null ? null : v;
33
+ }
34
+ /** Show the last N values only — keeps the box readable on long histories. */
35
+ const WINDOW = 10;
36
+ function windowed(vals) {
37
+ if (vals.length <= WINDOW)
38
+ return { window: vals, truncated: false };
39
+ return { window: vals.slice(-WINDOW), truncated: true };
40
+ }
41
+ export const trends = new Command("trends")
42
+ .description("Show how key metrics moved across every recorded scan, as sparklines")
43
+ .argument("[repo]", "path to the repo to trend (defaults to cwd)", ".")
44
+ .action((repoArg) => {
45
+ const repo = path.resolve(repoArg);
46
+ const hist = loadHistory(repo);
47
+ const scans = hist.scans;
48
+ if (scans.length === 0) {
49
+ console.log(chalk.yellow(`no scan history found in ${path.join(repo, ".pitstop")} — run \`pitstop scan\` a few times first.`));
50
+ return;
51
+ }
52
+ const rows = [];
53
+ const sec = scans.map((s) => (s.security.status === "ok" ? num(s.security.issues.length) : null));
54
+ rows.push({ label: "Security issues", values: sec, fmt: (v) => (v > 0 ? chalk.red(String(v)) : chalk.green(String(v))) });
55
+ const circ = scans.map((s) => (s.dependencyGraph.status === "ok" ? num(s.dependencyGraph.circular.length) : null));
56
+ rows.push({ label: "Circular imports", values: circ, fmt: (v) => (v > 0 ? chalk.yellow(String(v)) : chalk.green(String(v))) });
57
+ const clones = scans.map((s) => (s.duplication.status === "ok" ? num(s.duplication.cloneCount) : null));
58
+ rows.push({ label: "Duplication clones", values: clones, fmt: (v) => (v > 0 ? chalk.yellow(String(v)) : chalk.green(String(v))) });
59
+ const failed = scans.map((s) => (s.tests.status === "ok" ? num(s.tests.failed) : null));
60
+ rows.push({ label: "Failed tests", values: failed, fmt: (v) => (v > 0 ? chalk.red(String(v)) : chalk.green(String(v))) });
61
+ const cov = scans.map((s) => (s.tests.status === "ok" ? num(s.tests.coverage) : null));
62
+ rows.push({ label: "Coverage %", values: cov, fmt: (v) => (v >= 80 ? chalk.green(String(v)) : chalk.yellow(String(v))) });
63
+ const flaky = scans.map((s) => (s.reliability.status === "ok" ? num(s.reliability.flakyTests.length) : null));
64
+ rows.push({ label: "Flaky tests", values: flaky, fmt: (v) => (v > 0 ? chalk.yellow(String(v)) : chalk.green(String(v))) });
65
+ const unused = scans.map((s) => (s.devex.status === "ok" ? num(s.devex.unusedExports.length) : null));
66
+ rows.push({ label: "Unused exports", values: unused, fmt: (v) => (v > 0 ? chalk.yellow(String(v)) : chalk.green(String(v))) });
67
+ const scores = scans.map((s) => computeScore(s));
68
+ const last = scores[scores.length - 1];
69
+ const first = scores[0];
70
+ const gradeColorFn = (g) => gradeColor(g) === "green" ? chalk.green : gradeColor(g) === "yellow" ? chalk.yellow : chalk.red;
71
+ const lines = [];
72
+ lines.push(`${chalk.bold("OpenPitStop Score".padEnd(24))}: ${gradeColorFn(last.grade)(chalk.bold(`${last.score}/100 (${last.grade})`))} ${first.score !== last.score ? chalk.dim(`(was ${first.score}/100 ${first.grade})`) : ""}${scores.length > 1 ? " " + sparkline(scores.map((s) => s.score)) : ""}`);
73
+ lines.push("");
74
+ for (const row of rows) {
75
+ const { window, truncated } = windowed(row.values);
76
+ const vals = window.map((v) => (v == null ? "·" : row.fmt(v))).join(" ");
77
+ const prefix = truncated ? chalk.dim("… ") : "";
78
+ lines.push(`${chalk.bold(row.label.padEnd(24))}: ${sparkline(window)} ${prefix}${chalk.dim(vals)}`);
79
+ }
80
+ lines.push("", chalk.dim(`scan history: ${scans.length} scan(s) · oldest ${scans[0].timestamp.slice(0, 19).replace("T", " ")} · newest ${scans[scans.length - 1].timestamp.slice(0, 19).replace("T", " ")}`));
81
+ if (hist.verifies.length > 0) {
82
+ lines.push("", chalk.bold("Verify history:"));
83
+ for (const v of hist.verifies) {
84
+ const risk = v.risk === "High" ? chalk.red(v.risk) : v.risk === "Medium" ? chalk.yellow(v.risk) : chalk.green(v.risk);
85
+ const s = v.score;
86
+ const sc = s
87
+ ? ` · ${gradeColorFn(s.grade)(`${s.current}/100 ${s.grade}${s.delta !== 0 ? `, ${s.delta > 0 ? "+" : ""}${s.delta}` : ""}`)}`
88
+ : "";
89
+ const integ = v.integrity
90
+ ? ` · integrity ${v.integrity.verdict === "CLEAN" ? chalk.green("CLEAN") : v.integrity.verdict === "SUSPICIOUS" ? chalk.yellow("SUSPICIOUS") : chalk.red("CONFIRMED_CHEAT")}`
91
+ : "";
92
+ lines.push(` ${chalk.dim(v.timestamp.slice(0, 19).replace("T", " "))} ${risk}${sc}${integ}`);
93
+ }
94
+ }
95
+ console.log(boxen(lines.join("\n"), {
96
+ title: " PITSTOP — Trends ",
97
+ titleAlignment: "center",
98
+ borderStyle: "double",
99
+ padding: 1,
100
+ borderColor: "cyan",
101
+ }));
102
+ });
103
+ //# sourceMappingURL=trends.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trends.js","sourceRoot":"","sources":["../../src/commands/trends.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAG9D;;;GAGG;AAEH,MAAM,MAAM,GAAG,UAAU,CAAC;AAE1B,SAAS,SAAS,CAAC,MAAyB;IAC1C,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC;IACzD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;IAClD,IAAI,GAAG,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACvD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;IAC7B,MAAM,IAAI,GAAG,GAAG,GAAG,GAAG,IAAI,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE;QAC7B,IAAI,CAAC,IAAI,IAAI;YAAE,OAAO,GAAG,CAAC;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;QAChE,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC,CAAC,CAAC;IACH,MAAM,SAAS,GAAI,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAY,GAAI,GAAG,CAAC,CAAC,CAAY,CAAC;IACvE,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;IAClF,OAAO,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,GAAG,CAAC,CAA4B;IACvC,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAC9B,CAAC;AAED,8EAA8E;AAC9E,MAAM,MAAM,GAAG,EAAE,CAAC;AAClB,SAAS,QAAQ,CAAC,IAAuB;IACvC,IAAI,IAAI,CAAC,MAAM,IAAI,MAAM;QAAE,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACrE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;AAC1D,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG,IAAI,OAAO,CAAC,QAAQ,CAAC;KACxC,WAAW,CAAC,sEAAsE,CAAC;KACnF,QAAQ,CAAC,QAAQ,EAAE,6CAA6C,EAAE,GAAG,CAAC;KACtE,MAAM,CAAC,CAAC,OAAe,EAAE,EAAE;IAC1B,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IACnC,MAAM,IAAI,GAAG,WAAW,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;IAEzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,MAAM,CAAC,4BAA4B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,4CAA4C,CAAC,CAClH,CAAC;QACF,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAA+E,EAAE,CAAC;IAC5F,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAClG,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1H,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,eAAe,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACnH,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC/H,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACxG,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IACnI,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACxF,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1H,MAAM,GAAG,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACvF,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1H,MAAM,KAAK,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAC9G,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC3H,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IACtG,IAAI,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,gBAAgB,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAE/H,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,YAAY,GAAG,CAAC,CAAS,EAAyB,EAAE,CACxD,UAAU,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC;IAElG,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CACR,GAAG,KAAK,CAAC,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CACxE,KAAK,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,SAAS,IAAI,CAAC,KAAK,GAAG,CAAC,CAChD,IAAI,KAAK,CAAC,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,KAAK,CAAC,KAAK,QAAQ,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,SAAS,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CACrK,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnD,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACzE,MAAM,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAChD,KAAK,CAAC,IAAI,CACR,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,MAAM,CAAC,KAAK,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CACzF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,KAAK,CAAC,MAAM,qBAAqB,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,aAAa,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAE9M,IAAI,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC7B,KAAK,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC;QAC9C,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACtH,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC;YAClB,MAAM,EAAE,GAAG,CAAC;gBACV,CAAC,CAAC,MAAM,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,OAAO,QAAQ,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE;gBAC7H,CAAC,CAAC,EAAE,CAAC;YACP,MAAM,KAAK,GAAG,CAAC,CAAC,SAAS;gBACvB,CAAC,CAAC,gBAAgB,CAAC,CAAC,SAAS,CAAC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,KAAK,YAAY,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,EAAE;gBAC7K,CAAC,CAAC,EAAE,CAAC;YACP,KAAK,CAAC,IAAI,CACR,KAAK,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,IAAI,IAAI,GAAG,EAAE,GAAG,KAAK,EAAE,CAClF,CAAC;QACJ,CAAC;IACH,CAAC;IAED,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;QACtB,KAAK,EAAE,oBAAoB;QAC3B,cAAc,EAAE,QAAQ;QACxB,WAAW,EAAE,QAAQ;QACrB,OAAO,EAAE,CAAC;QACV,WAAW,EAAE,MAAM;KACpB,CAAC,CACH,CAAC;AACJ,CAAC,CAAC,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { Command } from "commander";
2
+ import type { ScanResult } from "../analyzers/types.js";
3
+ /**
4
+ * `pitstop try` — the instant wow. It runs only the cheap analyzers against
5
+ * ANY existing repo (tests/build/flaky detection are intentionally skipped,
6
+ * honest in the note text) so a OpenPitStop Score lands in a couple of seconds
7
+ * with zero setup: no install, no tool config, no curated fixture. The result
8
+ * is persisted as a sealed baseline so `pitstop scan`/`verify`/`gate` pick up
9
+ * where it left off.
10
+ */
11
+ export declare function tryScan(repo: string): Promise<ScanResult>;
12
+ export declare const try_: Command;
@@ -0,0 +1,208 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import boxen from "boxen";
4
+ import { performance } from "node:perf_hooks";
5
+ import path from "node:path";
6
+ import { analyzeDependencyGraph } from "../analyzers/dependencyGraph.js";
7
+ import { analyzeSecurity } from "../analyzers/security.js";
8
+ import { analyzeDuplication } from "../analyzers/duplication.js";
9
+ import { analyzeAccessibility } from "../analyzers/accessibility.js";
10
+ import { analyzeDevex } from "../analyzers/devex.js";
11
+ import { detectLanguage } from "../analyzers/util.js";
12
+ import { stampFindings } from "../repro/ids.js";
13
+ import { correlate } from "../graph/correlate.js";
14
+ import { computeScore } from "../report/score.js";
15
+ import { createSpinner } from "../ui/spinner.js";
16
+ import { persistScan } from "./scan.js";
17
+ function rel(repo, p) {
18
+ return p ? path.relative(repo, p) : "";
19
+ }
20
+ function label(text) {
21
+ return chalk.bold(text.padEnd(17));
22
+ }
23
+ function gradePaint(g) {
24
+ switch (g[0]) {
25
+ case "A": return chalk.greenBright;
26
+ case "B":
27
+ case "C": return chalk.yellow;
28
+ default: return chalk.red;
29
+ }
30
+ }
31
+ /**
32
+ * `pitstop try` — the instant wow. It runs only the cheap analyzers against
33
+ * ANY existing repo (tests/build/flaky detection are intentionally skipped,
34
+ * honest in the note text) so a OpenPitStop Score lands in a couple of seconds
35
+ * with zero setup: no install, no tool config, no curated fixture. The result
36
+ * is persisted as a sealed baseline so `pitstop scan`/`verify`/`gate` pick up
37
+ * where it left off.
38
+ */
39
+ export async function tryScan(repo) {
40
+ const language = detectLanguage(repo);
41
+ const notesFor = {
42
+ tests: "try is the 2-second pass — `pitstop scan` runs the suite, coverage and build",
43
+ perf: "try is the 2-second pass — `pitstop scan` measures build/bundle timing",
44
+ reliability: "try is the 2-second pass — `pitstop scan` runs flaky-test detection",
45
+ };
46
+ // npm audit via analyzeSecurity is the only subprocess; it is cache-backed so
47
+ // repeated `try` runs on the same lockfile are instant.
48
+ const security = await analyzeSecurity(repo);
49
+ return {
50
+ timestamp: new Date().toISOString(),
51
+ repo,
52
+ mode: "try",
53
+ language,
54
+ dependencyGraph: analyzeDependencyGraph(repo),
55
+ security,
56
+ duplication: analyzeDuplication(repo),
57
+ tests: {
58
+ status: "skipped",
59
+ note: notesFor.tests,
60
+ total: 0,
61
+ passed: 0,
62
+ failed: 0,
63
+ durationMs: 0,
64
+ },
65
+ perf: { status: "skipped", note: notesFor.perf },
66
+ accessibility: analyzeAccessibility(repo),
67
+ reliability: {
68
+ status: "skipped",
69
+ note: notesFor.reliability,
70
+ runs: 0,
71
+ durationMs: 0,
72
+ flakyTests: [],
73
+ raceSmells: [],
74
+ },
75
+ devex: analyzeDevex(repo),
76
+ clusters: [],
77
+ };
78
+ }
79
+ function categoryLines(r) {
80
+ const lines = [];
81
+ const dg = r.dependencyGraph;
82
+ if (dg.status === "ok") {
83
+ if (dg.circular.length > 0) {
84
+ const cyc = dg.circular[0].map((f) => rel(r.repo, f)).join(" → ");
85
+ lines.push(`${label("Dependency Graph")}: ${chalk.red(`${dg.circular.length} circular`)} — ${cyc}`);
86
+ }
87
+ else {
88
+ lines.push(`${label("Dependency Graph")}: ${chalk.green("0 circular")} — clean`);
89
+ }
90
+ }
91
+ else {
92
+ lines.push(`${label("Dependency Graph")}: ${chalk.yellow(`skipped — ${dg.note ?? "unavailable"}`)}`);
93
+ }
94
+ const sec = r.security;
95
+ if (sec.status === "ok") {
96
+ if (sec.issues.length > 0) {
97
+ const i = sec.issues[0];
98
+ lines.push(`${label("Security")}: ${chalk.red(`${sec.issues.length} issue(s)`)} — ${i.type}: ${i.description}`);
99
+ }
100
+ else {
101
+ lines.push(`${label("Security")}: ${chalk.green("clean")} — ${sec.issues.length} issues`);
102
+ }
103
+ }
104
+ else {
105
+ lines.push(`${label("Security")}: ${chalk.yellow(`skipped — ${sec.note ?? "unavailable"}`)}`);
106
+ }
107
+ const dup = r.duplication;
108
+ if (dup.status === "ok") {
109
+ lines.push(dup.cloneCount > 0
110
+ ? `${label("Duplication")}: ${chalk.yellow(`${dup.cloneCount} clone(s)`)}`
111
+ : `${label("Duplication")}: ${chalk.green("clean")}`);
112
+ }
113
+ else {
114
+ lines.push(`${label("Duplication")}: ${chalk.yellow(`skipped — ${dup.note ?? "unavailable"}`)}`);
115
+ }
116
+ const a = r.accessibility;
117
+ if (a.status === "ok") {
118
+ lines.push(a.issues.length > 0
119
+ ? `${label("Accessibility")}: ${chalk.yellow(`${a.issues.length} issue(s)`)}`
120
+ : `${label("Accessibility")}: ${chalk.green("clean")}`);
121
+ }
122
+ else {
123
+ lines.push(`${label("Accessibility")}: ${chalk.yellow(`skipped — ${a.note ?? "unavailable"}`)}`);
124
+ }
125
+ const dx = r.devex;
126
+ if (dx.status === "ok") {
127
+ const parts = [
128
+ dx.unusedExports.length > 0 ? chalk.yellow(`${dx.unusedExports.length} unused export(s)`) : chalk.green("0 unused"),
129
+ dx.duplicateFunctions.length > 0 ? chalk.yellow(`${dx.duplicateFunctions.length} dup fn(s)`) : chalk.green("0 dup fn"),
130
+ ];
131
+ lines.push(`${label("DevEx")}: ${parts.join(" · ")}`);
132
+ }
133
+ else {
134
+ lines.push(`${label("DevEx")}: ${chalk.yellow(`skipped — ${dx.note ?? "unavailable"}`)}`);
135
+ }
136
+ return lines;
137
+ }
138
+ function renderTryBox(r, elapsedMs) {
139
+ const sc = computeScore(r);
140
+ const paint = gradePaint(sc.grade);
141
+ const skipped = sc.total - sc.analyzed;
142
+ const skippedStr = skipped > 0 ? chalk.dim(` · ${skipped} skipped (tests/perf are a scan-detail)`) : "";
143
+ const lines = [];
144
+ lines.push(`${label("OpenPitStop Score")}: ${paint.bold(`${sc.score}/100 (${sc.grade})`)}${skippedStr}`);
145
+ lines.push("");
146
+ lines.push(...categoryLines(r));
147
+ lines.push("");
148
+ lines.push(chalk.dim(`scanned in ${elapsedMs}ms · ${chalk.bold("static pass")} only — `) +
149
+ chalk.dim("no tests/build/flaky yet"));
150
+ lines.push("");
151
+ lines.push(chalk.cyan("next:"));
152
+ lines.push(` pitstop scan full audit (tests, perf, flaky, ledger) — cached 24h audit`);
153
+ lines.push(` pitstop verify gate every future fix against this baseline`);
154
+ lines.push(` pitstop demo the guided fix-loop tour`);
155
+ return boxen(lines.join("\n"), {
156
+ title: " PITSTOP — Try ",
157
+ titleAlignment: "center",
158
+ borderStyle: "single",
159
+ padding: 1,
160
+ borderColor: paint === chalk.greenBright ? "green" : paint === chalk.yellow ? "yellow" : "red",
161
+ });
162
+ }
163
+ export const try_ = new Command("try")
164
+ .description("Zero-setup 2-second check: static-analyze ANY existing repo (no install, no tool config) " +
165
+ "and print its OpenPitStop Score. Persists a real baseline for scan/verify/gate to build on.")
166
+ .argument("[repo]", "path to the repo to try (default: current dir)", ".")
167
+ .option("--json", "print the raw quick-scan result as JSON")
168
+ .action(async (repoArg, options) => {
169
+ const repo = path.resolve(repoArg);
170
+ if (!options.json) {
171
+ console.log(chalk.cyan(`\nTrying ${repo} ...\n`));
172
+ }
173
+ const language = detectLanguage(repo);
174
+ if (language === "unknown") {
175
+ const msg = `couldn't find a supported project in ${repo} — looking for package.json, ` +
176
+ `requirements.txt, pyproject.toml or setup.py`;
177
+ if (options.json) {
178
+ console.log(JSON.stringify({ ok: false, repo, reason: msg }));
179
+ }
180
+ else {
181
+ console.log(chalk.red(msg));
182
+ }
183
+ process.exitCode = 1;
184
+ return;
185
+ }
186
+ const t0 = performance.now();
187
+ const spin = createSpinner("Running static analyzers");
188
+ let result;
189
+ try {
190
+ result = await tryScan(repo);
191
+ spin.succeed("Probe complete");
192
+ }
193
+ catch (err) {
194
+ spin.fail("Probe failed");
195
+ throw err;
196
+ }
197
+ const elapsedMs = Math.max(1, Math.round(performance.now() - t0));
198
+ stampFindings(result);
199
+ result.clusters = correlate(repo, result).clusters;
200
+ persistScan(repo, result);
201
+ if (options.json) {
202
+ console.log(JSON.stringify(result, null, 2));
203
+ return;
204
+ }
205
+ console.log(renderTryBox(result, elapsedMs));
206
+ console.log(chalk.dim(`\nBaseline saved to ${path.join(repo, ".pitstop", "scan-latest.json")}\n`));
207
+ });
208
+ //# sourceMappingURL=try.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"try.js","sourceRoot":"","sources":["../../src/commands/try.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,44 @@
1
+ import { Command } from "commander";
2
+ import type { VerifyMetrics } from "../report/format.js";
3
+ import { deltasOf } from "../verify/metrics.js";
4
+ import { type ScoreResult } from "../report/score.js";
5
+ import type { IntegrityFinding, Verdict } from "../analyzers/integrity/types.js";
6
+ import { type EvidenceCheck } from "../evidence.js";
7
+ interface IntegrityGate {
8
+ verdict: Verdict;
9
+ findings: IntegrityFinding[];
10
+ summary: {
11
+ confirmed: number;
12
+ suspicious: number;
13
+ total: number;
14
+ };
15
+ }
16
+ type Risk = "Low" | "Medium" | "High";
17
+ export interface VerifyOutcome {
18
+ repo: string;
19
+ missingBaseline: boolean;
20
+ baselineTimestamp?: string;
21
+ evidence?: EvidenceCheck;
22
+ stale: boolean;
23
+ staleNote?: string;
24
+ risk: Risk;
25
+ integrity: IntegrityGate;
26
+ blocked: boolean;
27
+ current: VerifyMetrics;
28
+ baseline: VerifyMetrics;
29
+ deltas: ReturnType<typeof deltasOf>;
30
+ baselineScore: ScoreResult;
31
+ currentScore: ScoreResult;
32
+ scoreDelta: number;
33
+ exitCode: number;
34
+ file?: string;
35
+ }
36
+ /**
37
+ * The shared verify pipeline (also used by `pitstop gate`): re-measure the
38
+ * fast metrics, diff against the scan baseline, run the integrity gate, check
39
+ * the baseline's evidence signature, and write a sealed verify report. Returns
40
+ * everything a renderer needs plus the exit code to propagate.
41
+ */
42
+ export declare function runVerify(repo: string): Promise<VerifyOutcome>;
43
+ export declare const verify: Command;
44
+ export {};