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,189 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import boxen from "boxen";
4
+ import path from "node:path";
5
+ import fs from "node:fs";
6
+ import { buildModel, collectIntegrity, loadHistory, loadProofs } from "../report/format.js";
7
+ import { computeScore, gradeColor } from "../report/score.js";
8
+ import { enumerateFindings } from "../repro/ids.js";
9
+ const BLOCKS = "▁▂▃▄▅▆▇█";
10
+ function sparkline(values) {
11
+ if (values.length === 0)
12
+ return "·";
13
+ if (values.length === 1)
14
+ return chalk.dim(String(values[0]));
15
+ const min = Math.min(...values);
16
+ const max = Math.max(...values);
17
+ const span = max - min || 1;
18
+ const chars = values.map((v) => BLOCKS[Math.min(7, Math.floor(((v - min) / span) * 7.999))]);
19
+ const improving = values[values.length - 1] >= values[0];
20
+ return (improving ? chalk.green : chalk.yellow)(chars.join(""));
21
+ }
22
+ function windowOf(repo, days) {
23
+ const hist = loadHistory(repo);
24
+ if (!days)
25
+ return { scans: hist.scans, verifies: hist.verifies };
26
+ const cut = Date.now() - days * 86_400_000;
27
+ return {
28
+ scans: hist.scans.filter((s) => Date.parse(s.timestamp) >= cut),
29
+ verifies: hist.verifies.filter((v) => Date.parse(v.timestamp) >= cut),
30
+ };
31
+ }
32
+ /**
33
+ * `pitstop digest` — the shareable progress story. Reads the `.pitstop`
34
+ * history and answers "what happened to this repo since <window>?" for humans:
35
+ * score movement, what got fixed, verifies/gates run, cheat attempts caught,
36
+ * flakiest tests, and what's still open.
37
+ */
38
+ export const digest = new Command("digest")
39
+ .description("Progress digest over the .pitstop history: score movement, what got fixed, gate results, " +
40
+ "cheat catches, flaky tests and open findings. --md writes a shareable markdown file.")
41
+ .argument("[repo]", "path to the repo (default: current dir)", ".")
42
+ .option("--days <n>", "only look at the last n days (default: all history)")
43
+ .option("-m, --md [file]", "also write a markdown digest (default PITSTOP_DIGEST.md)")
44
+ .action((repoArg, options) => {
45
+ const repo = path.resolve(repoArg);
46
+ const days = options.days ? Math.max(1, Math.floor(Number(options.days) || 7)) : null;
47
+ const { scans, verifies } = windowOf(repo, days);
48
+ if (scans.length === 0) {
49
+ console.log(chalk.yellow(`no scans ${days ? `in the last ${days} day(s) ` : ""}in ${path.join(repo, ".pitstop")} — run \`pitstop scan\` (or \`pitstop try\`) a few times first.`));
50
+ return;
51
+ }
52
+ const model = buildModel(repo);
53
+ const integ = collectIntegrity(repo);
54
+ const windowInteg = integ
55
+ ? {
56
+ ...integ,
57
+ events: integ.events.filter((e) => !days || Date.parse(e.timestamp) >= Date.now() - days * 86_400_000),
58
+ }
59
+ : undefined;
60
+ const firstScore = computeScore(scans[0]);
61
+ const lastScore = computeScore(scans[scans.length - 1]);
62
+ const scores = scans.map((s) => computeScore(s).score);
63
+ const delta = lastScore.score - firstScore.score;
64
+ const metric = (label, get, worse) => {
65
+ const a = get(scans[0]);
66
+ const b = get(scans[scans.length - 1]);
67
+ if (a == null || b == null)
68
+ return null;
69
+ return { label, a, b, changed: worse(b - a) };
70
+ };
71
+ const metrics = [
72
+ metric("security", (s) => (s.security.status === "ok" ? s.security.issues.length : null), (d) => d > 0),
73
+ metric("circular imports", (s) => (s.dependencyGraph.status === "ok" ? s.dependencyGraph.circular.length : null), (d) => d > 0),
74
+ metric("clones", (s) => (s.duplication.status === "ok" ? s.duplication.cloneCount : null), (d) => d > 0),
75
+ metric("failed tests", (s) => (s.tests.status === "ok" ? s.tests.failed : null), (d) => d > 0),
76
+ metric("coverage %", (s) => (s.tests.status === "ok" ? s.tests.coverage ?? null : null), (d) => d < 0),
77
+ metric("flaky tests", (s) => (s.reliability.status === "ok" ? s.reliability.flakyTests.length : null), (d) => d > 0),
78
+ ].filter((m) => m != null);
79
+ const fixed = [];
80
+ const regressed = [];
81
+ for (const m of metrics) {
82
+ if (m.a === m.b)
83
+ continue;
84
+ const d = m.b - m.a;
85
+ if (m.changed)
86
+ regressed.push(`${m.label} ${m.a} → ${m.b}`);
87
+ else
88
+ fixed.push(`${m.label} ${m.a} → ${m.b}`);
89
+ }
90
+ const flakyTally = new Map();
91
+ for (const s of scans) {
92
+ if (s.reliability.status !== "ok")
93
+ continue;
94
+ for (const f of s.reliability.flakyTests) {
95
+ const hit = flakyTally.get(f.name);
96
+ if (hit)
97
+ hit.count++;
98
+ else
99
+ flakyTally.set(f.name, { name: f.name, count: 1 });
100
+ }
101
+ }
102
+ const flakyTop = [...flakyTally.values()].sort((a, b) => b.count - a.count).slice(0, 3);
103
+ const failedChecks = verifies.filter((v) => (v.exitCode ?? 0) >= 1);
104
+ const catches = (windowInteg?.events ?? []).filter((e) => e.verdict !== "CLEAN").length;
105
+ const latest = scans[scans.length - 1];
106
+ const open = enumerateFindings(latest)
107
+ .sort((a, b) => (a.severity === "critical" || a.severity === "high" ? -1 : 1))
108
+ .slice(0, 3);
109
+ const lines = [];
110
+ lines.push(`${chalk.bold("OpenPitStop Score".padEnd(20))}: ${gradeColorFn(lastScore.grade)(chalk.bold(`${lastScore.score}/100 (${lastScore.grade})`))} ${delta !== 0 ? chalk.dim(`was ${firstScore.score}/100 (${firstScore.grade}) · ${delta > 0 ? chalk.green(`+${delta}`) : chalk.red(delta)}`) : chalk.dim(`unchanged from ${firstScore.score}/100`)}`);
111
+ lines.push(`${chalk.bold("Trend".padEnd(20))}: ${sparkline(scores)}`);
112
+ lines.push("");
113
+ lines.push(chalk.bold("What changed:"));
114
+ if (fixed.length === 0 && regressed.length === 0)
115
+ lines.push(` ${chalk.dim("no measurable change across scans")}`);
116
+ for (const f of fixed)
117
+ lines.push(` ${chalk.green("✓ " + f)}`);
118
+ for (const r of regressed)
119
+ lines.push(` ${chalk.red("✗ " + r)}`);
120
+ lines.push("");
121
+ lines.push(chalk.bold("Gate activity:"));
122
+ lines.push(` ${verifies.length} verify(ies) in window · ${failedChecks.length} failed gate(s) · ${catches} integrity catch(es)${windowInteg?.selfCorrected ? `, ${windowInteg.selfCorrected} self-corrected` : ""}`);
123
+ if (flakyTop.length > 0) {
124
+ lines.push(` flakiest: ${flakyTop.map((f) => `${chalk.yellow(f.name)} (${f.count}×)`).join(", ")}`);
125
+ }
126
+ lines.push("");
127
+ const proofs = loadProofs(repo);
128
+ lines.push(chalk.bold("Permanent proof:"));
129
+ lines.push(proofs.length > 0
130
+ ? ` ${chalk.green(`${proofs.length} committed repro test(s)`)} — every fix proven failing-then-passing`
131
+ : ` ${chalk.yellow("none committed yet")}`);
132
+ lines.push("");
133
+ lines.push(chalk.bold("Still open:"));
134
+ if (open.length === 0)
135
+ lines.push(` ${chalk.green("nothing — latest scan is clean")}`);
136
+ for (const f of open) {
137
+ lines.push(` ${chalk.red(`${f.severity.toUpperCase()} ${f.type}`)}: ${f.description} [${chalk.dim(f.id)}]`);
138
+ }
139
+ lines.push("");
140
+ lines.push(chalk.dim(`${scans.length} scan(s) · ${verifies.length} verify(ies) · oldest ${scans[0].timestamp.slice(0, 19).replace("T", " ")} · newest ${scans[scans.length - 1].timestamp.slice(0, 19).replace("T", " ")}${days ? ` · last ${days} day(s)` : ""}`));
141
+ console.log(boxen(lines.join("\n"), {
142
+ title: ` PITSTOP — Digest `,
143
+ titleAlignment: "center",
144
+ borderStyle: "double",
145
+ padding: 1,
146
+ borderColor: delta < 0 ? "red" : "green",
147
+ }));
148
+ if (options.md) {
149
+ const mdPath = typeof options.md === "string" && options.md.length > 0
150
+ ? path.resolve(options.md)
151
+ : path.join(repo, "PITSTOP_DIGEST.md");
152
+ const md = [
153
+ `# PITSTOP — Digest`,
154
+ ``,
155
+ `_Repo: \`${repo}\` · ${scans.length} scan(s) in ${days ? `the last ${days} day(s)` : "all history"}_ `,
156
+ ``,
157
+ `## OpenPitStop Score: **${lastScore.score}/100 (${lastScore.grade})**${delta !== 0 ? ` (was ${firstScore.score}/100, ${delta > 0 ? "+" : ""}${delta})` : ""}`,
158
+ ``,
159
+ `## What changed`,
160
+ ``,
161
+ ...(fixed.length === 0 && regressed.length === 0 ? ["No measurable change across scans.", ""] : []),
162
+ ...fixed.map((f) => `- ✅ ${f}`),
163
+ ...regressed.map((r) => `- ❌ ${r}`),
164
+ ``,
165
+ `## Gate activity`,
166
+ ``,
167
+ `- ${verifies.length} verify(ies) · ${failedChecks.length} failed gate(s) · ${catches} integrity catch(es)`,
168
+ ...(flakyTop.length > 0 ? [`- Flakiest: ${flakyTop.map((f) => `${f.name} (${f.count}×)`).join(", ")}`] : []),
169
+ ``,
170
+ `## Permanent proof`,
171
+ ``,
172
+ proofs.length > 0
173
+ ? `- ${proofs.length} committed repro test(s) — every fix proven failing-then-passing`
174
+ : `- None committed yet.`,
175
+ ``,
176
+ `## Still open`,
177
+ ``,
178
+ ...(open.length === 0 ? ["- Nothing — latest scan is clean.", ""] : open.map((f) => `- **${f.severity.toUpperCase()} ${f.type}** — ${f.description} (\`${f.id}\`)`)),
179
+ ``,
180
+ ].join("\n");
181
+ fs.writeFileSync(mdPath, md);
182
+ console.log(chalk.dim(`\nMarkdown digest written to ${mdPath}\n`));
183
+ }
184
+ });
185
+ function gradeColorFn(g) {
186
+ const c = gradeColor(g);
187
+ return c === "green" ? chalk.green : c === "yellow" ? chalk.yellow : chalk.red;
188
+ }
189
+ //# sourceMappingURL=digest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"digest.js","sourceRoot":"","sources":["../../src/commands/digest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare const doctor: Command;
@@ -0,0 +1,98 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import boxen from "boxen";
4
+ import path from "node:path";
5
+ import fs from "node:fs";
6
+ import { commandExists, safeExec } from "../analyzers/util.js";
7
+ /**
8
+ * `pitstop doctor` — why is a category "skipped"? One command answers it.
9
+ * Checks the toolchain (node, git, jscpd, gitleaks, semgrep, pa11y/axe) and
10
+ * prints install hints for everything missing.
11
+ */
12
+ function hasCommand(cmd) {
13
+ try {
14
+ return commandExists(cmd);
15
+ }
16
+ catch {
17
+ return false;
18
+ }
19
+ }
20
+ export const doctor = new Command("doctor")
21
+ .description("Check the local toolchain and explain which scan categories can (and cannot) run")
22
+ .argument("[repo]", "path to the repo to diagnose (defaults to cwd)", ".")
23
+ .action((repoArg) => {
24
+ const repo = path.resolve(repoArg);
25
+ const rows = [];
26
+ const major = Number(process.versions.node.split(".")[0]);
27
+ rows.push([
28
+ "Node.js",
29
+ major >= 22,
30
+ `v${process.versions.node}${major >= 22 ? "" : " — OpenPitStop needs v22+ (npm install node@latest)"}`,
31
+ ]);
32
+ const git = hasCommand("git");
33
+ rows.push(["git", git, "the fix loop, integrity gate and verify all diff against git"]);
34
+ let hasHead = false;
35
+ if (git) {
36
+ const inRepo = safeExec("git", ["rev-parse", "--is-inside-work-tree"], repo, 10000);
37
+ hasHead =
38
+ inRepo.code === 0 &&
39
+ safeExec("git", ["rev-parse", "--verify", "HEAD"], repo, 10000).code === 0;
40
+ }
41
+ rows.push([
42
+ "git baseline (HEAD)",
43
+ hasHead,
44
+ hasHead ? "commits present — integrity gate can diff fixes" : "no commits yet — the integrity gate needs a committed baseline",
45
+ ]);
46
+ rows.push(["npm", hasCommand("npm"), "bundled with Node.js"]);
47
+ const jscpd = hasCommand("jscpd");
48
+ rows.push(["jscpd (duplication)", jscpd, jscpd ? "ready" : "npm install -g jscpd — enables the duplication analyzer"]);
49
+ const gitleaks = hasCommand("gitleaks");
50
+ rows.push(["gitleaks (secrets)", gitleaks, gitleaks ? "ready" : "brew install gitleaks / scoop install gitleaks — adds secret scanning"]);
51
+ const semgrep = hasCommand("semgrep");
52
+ rows.push(["semgrep (code scanning)", semgrep, semgrep ? "ready" : "pip install semgrep — adds static code scanning"]);
53
+ const pa11y = hasCommand("pa11y");
54
+ rows.push(["pa11y / axe (accessibility)", pa11y, pa11y ? "ready" : "npm install -g pa11y — enables live-page accessibility checks (falls back to static JSX lint)"]);
55
+ let testFrameworks = "none detected";
56
+ const pkgPath = path.join(repo, "package.json");
57
+ if (fs.existsSync(pkgPath)) {
58
+ try {
59
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf8"));
60
+ const all = { ...(pkg.dependencies ?? {}), ...(pkg.devDependencies ?? {}) };
61
+ const found = ["jest", "vitest", "mocha", "ava"].filter((f) => f in all);
62
+ if (found.length > 0)
63
+ testFrameworks = found.join(", ");
64
+ }
65
+ catch {
66
+ /* ignore */
67
+ }
68
+ }
69
+ rows.push(["test framework", testFrameworks !== "none detected", testFrameworks]);
70
+ const pitstopDir = path.join(repo, ".pitstop");
71
+ rows.push([
72
+ ".pitstop history",
73
+ fs.existsSync(pitstopDir),
74
+ fs.existsSync(pitstopDir) ? "scans recorded" : "no scans yet — run `pitstop scan` to start the history",
75
+ ]);
76
+ const lines = rows.map(([name, ok, note]) => {
77
+ const statusRaw = ok ? "✓ ok" : "✗ missing";
78
+ const status = (ok ? chalk.green : chalk.red)(statusRaw.padEnd(9));
79
+ const label = chalk.bold(name.padEnd(24));
80
+ const hint = ok ? chalk.dim(note) : chalk.yellow(note);
81
+ return ` ${label} ${status} ${hint}`;
82
+ });
83
+ const missing = rows.filter(([, ok]) => !ok);
84
+ const critical = rows.filter(([name, ok]) => !ok && ["Node.js", "git", "npm"].includes(name));
85
+ const verdict = critical.length > 0
86
+ ? chalk.red(`${critical.length} critical missing — install those before relying on OpenPitStop`)
87
+ : missing.length === 0
88
+ ? chalk.green("everything OpenPitStop needs is installed — the full scan should run with no `skipped` categories")
89
+ : chalk.yellow(`${missing.length} optional tool(s) missing — those scan categories will print "skipped" (install hints above)`);
90
+ console.log(boxen([...lines, "", ` ${chalk.bold("Verdict:")} ${verdict}`].join("\n"), {
91
+ title: " PITSTOP — Doctor ",
92
+ titleAlignment: "center",
93
+ borderStyle: "double",
94
+ padding: 1,
95
+ borderColor: critical.length > 0 ? "red" : missing.length > 0 ? "yellow" : "green",
96
+ }));
97
+ });
98
+ //# sourceMappingURL=doctor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"doctor.js","sourceRoot":"","sources":["../../src/commands/doctor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { Command } from "commander";
2
+ export declare const drive: Command;
3
+ export default drive;
@@ -0,0 +1,170 @@
1
+ import { Command } from "commander";
2
+ import chalk from "chalk";
3
+ import boxen from "boxen";
4
+ import path from "node:path";
5
+ import { execa } from "execa";
6
+ import { loadScan, repro } from "../repro/index.js";
7
+ import { resolveFinding } from "../repro/ids.js";
8
+ import { loadPenLatest, resolvePenFinding } from "../pen/store.js";
9
+ import { runVerify } from "./verify.js";
10
+ /**
11
+ * `pitstop drive <finding-id>` — hand a finding to YOUR agent, then verify.
12
+ *
13
+ * OpenPitStop never fixes your code itself (no magic auto-edits on a repo it does
14
+ * not own). Instead: drive builds a precise mission prompt for the agent you
15
+ * already trust (claude/codex/opencode/...), runs it, then runs `pitstop
16
+ * verify` on the result and reports PASS/FAIL honestly.
17
+ *
18
+ * The agent command comes from --agent or PITSTOP_AGENT; `{prompt}` is where
19
+ * the mission text is inserted, e.g.:
20
+ * pitstop drive security-abc123 --agent "claude -p \"{prompt}\""
21
+ */
22
+ function missionPrompt(repo, finding, reproHint, fromPen) {
23
+ return [
24
+ `You are fixing one specific OpenPitStop finding in the repo at ${repo}.`,
25
+ ``,
26
+ `Finding: ${finding.id} (${finding.source}/${finding.type}, severity ${finding.severity})`,
27
+ `Description: ${finding.description}`,
28
+ finding.file ? `Location: ${finding.file}${finding.line ? ":" + finding.line : ""}` : "",
29
+ ``,
30
+ `Work like this, in order, without skipping:`,
31
+ `1. RUN the repro first: \`npx openpitstop repro ${finding.id}\`. It MUST FAIL (the bug is live).`,
32
+ ` If it refuses or passes, STOP and re-read the finding — do not fix blind.`,
33
+ reproHint,
34
+ `2. Make the smallest fix that addresses the root cause. Do not refactor unrelated code.`,
35
+ `3. Re-run the SAME repro: it must now PASS.`,
36
+ fromPen
37
+ ? `4. \`npx openpitstop verify\` is a static gate — for runtime pen findings the repro PASS is the real verdict;`
38
+ : `4. Run \`npx openpitstop verify\` — it must come back clean (no regressions, integrity intact).`,
39
+ `5. If anything regressed, revert the smallest unit and try again.`,
40
+ ``,
41
+ `Finish by reporting: what was wrong, what you changed, and the exact commands you ran.`,
42
+ ].filter(Boolean).join("\n");
43
+ }
44
+ export const drive = new Command("drive")
45
+ .description("Hand a finding to YOUR own agent (claude/codex/opencode/...), then verify the result. " +
46
+ "Mission: repro FAILS first → fix → repro PASSES → `pitstop verify` clean. OpenPitStop never auto-edits your code.")
47
+ .argument("<finding-id>", "finding id from scan-latest.json or pen-latest.json")
48
+ .argument("[repo]", "path to the repo", ".")
49
+ .option("--agent <cmd>", "agent command with {prompt} placeholder (or set PITSTOP_AGENT)")
50
+ .action(async (findingId, repoArg, options) => {
51
+ const repo = path.resolve(repoArg);
52
+ const scan = loadScan(repo);
53
+ const pen = loadPenLatest(repo);
54
+ let finding = null;
55
+ let reproHint = "";
56
+ let fromPen = false;
57
+ const scanHit = scan ? resolveFinding(scan, findingId) : null;
58
+ if (scanHit) {
59
+ finding = {
60
+ id: scanHit.id,
61
+ source: scanHit.source,
62
+ severity: scanHit.severity,
63
+ type: scanHit.type,
64
+ description: scanHit.description,
65
+ file: scanHit.file,
66
+ line: scanHit.line,
67
+ };
68
+ reproHint = `The repro generator exists for ${scanHit.source}/${scanHit.type} — use it as your contract.`;
69
+ }
70
+ else if (pen) {
71
+ const pf = resolvePenFinding(pen, findingId);
72
+ if (pf) {
73
+ fromPen = true;
74
+ finding = {
75
+ id: pf.id,
76
+ source: pf.source,
77
+ severity: pf.severity,
78
+ type: pf.type,
79
+ description: pf.title,
80
+ file: pf.file,
81
+ line: pf.line,
82
+ };
83
+ reproHint = pf.attack
84
+ ? `Replay the attack if needed: ${pf.attack.method} ${pf.attack.path}`
85
+ : `This is a static observation — apply the fix guidance, then re-run \`npx openpitstop pen\` for this finding.`;
86
+ }
87
+ }
88
+ if (!finding) {
89
+ console.log(chalk.yellow(`\nfinding "${findingId}" not found in scan-latest.json or pen-latest.json\n`));
90
+ return;
91
+ }
92
+ const agentCmd = options.agent ?? process.env.PITSTOP_AGENT ?? "";
93
+ if (!agentCmd) {
94
+ console.log(boxen(`pitstop drive ${findingId}\n\n` +
95
+ `${chalk.yellow("no agent command configured")}\n\n` +
96
+ `Pass one with --agent (use {prompt} as the placeholder) or export PITSTOP_AGENT.\n\n` +
97
+ `Examples:\n` +
98
+ ` --agent 'claude -p "{prompt}"'\n` +
99
+ ` --agent 'codex exec -- "{prompt}"'\n` +
100
+ ` --agent 'opencode run "{prompt}"'`, {
101
+ title: " PITSTOP — Drive ",
102
+ titleAlignment: "center",
103
+ borderStyle: "round",
104
+ padding: 1,
105
+ borderColor: "yellow",
106
+ }));
107
+ return;
108
+ }
109
+ const prompt = missionPrompt(repo, finding, reproHint, fromPen);
110
+ const tokens = agentCmd.split(/\s+/).map((t) => (t.includes("{prompt}") ? prompt : t)).filter(Boolean);
111
+ const [cmd, ...args] = tokens;
112
+ const finalArgs = args.map((a) => a.replace("{prompt}", prompt));
113
+ console.log(chalk.cyan(`\nDriving ${findingId} → ${cmd} (agent's own credits; OpenPitStop verifies the result)\n`));
114
+ console.log(chalk.dim(prompt.split("\n").slice(0, 4).join("\n") + "\n"));
115
+ let agentCode = -1;
116
+ try {
117
+ const sub = execa(cmd, finalArgs, {
118
+ cwd: repo,
119
+ stdout: "inherit",
120
+ stderr: "inherit",
121
+ reject: false,
122
+ timeout: 30 * 60 * 1000,
123
+ windowsHide: true,
124
+ });
125
+ agentCode = (await sub).exitCode ?? -1;
126
+ }
127
+ catch (err) {
128
+ console.log(chalk.red(`agent could not be started: ${err.message}`));
129
+ return;
130
+ }
131
+ console.log(chalk.dim(`\nagent exited with code ${agentCode} — verifying the result...\n`));
132
+ if (fromPen) {
133
+ const r = await repro(repo, findingId);
134
+ const pass = r.status === "generated-and-ran" && r.ran?.passed === true;
135
+ const paint = pass ? chalk.green : chalk.red;
136
+ const why = pass
137
+ ? "repro now PASSES — the runtime hypothesis is unproven, the fix holds."
138
+ : r.status === "generated-and-ran"
139
+ ? "repro still FAILS — the bug is live; the agent did not address it."
140
+ : `repro could not run: ${r.reason ?? r.status}`;
141
+ const v = await runVerify(repo);
142
+ console.log(boxen(`${paint(pass ? "VERIFIED — repro now PASSES (bug addressed)" : "NOT VERIFIED — repro still FAILS (bug live)")}\n\n` +
143
+ `${why}\n\n` +
144
+ `test: ${r.file ?? "?"} · ${pass ? "PASS" : "FAIL"}\n` +
145
+ `verify (static gate, context only): score ${v.currentScore.score}/100 (${v.currentScore.grade}) vs baseline ${v.baselineScore.score}/100 (${v.baselineScore.grade}) · delta ${v.scoreDelta >= 0 ? "+" : ""}${v.scoreDelta} · integrity ${v.integrity.verdict}`, {
146
+ title: ` PITSTOP — Drive ${findingId} `,
147
+ titleAlignment: "center",
148
+ borderStyle: "round",
149
+ padding: 1,
150
+ borderColor: pass ? "green" : "red",
151
+ }));
152
+ process.exitCode = pass ? 0 : 1;
153
+ return;
154
+ }
155
+ const v = await runVerify(repo);
156
+ const paint = v.exitCode === 0 ? chalk.green : chalk.red;
157
+ console.log(boxen(`${paint(v.exitCode === 0 ? "VERIFIED — pitstop verify is clean" : `NOT VERIFIED — pitstop verify exited ${v.exitCode}`)}\n\n` +
158
+ `score: ${v.currentScore.score}/100 (${v.currentScore.grade}) vs baseline ${v.baselineScore.score}/100 (${v.baselineScore.grade}) · delta ${v.scoreDelta >= 0 ? "+" : ""}${v.scoreDelta}\n` +
159
+ `integrity: ${v.integrity.verdict} · stale baseline: ${v.stale ? "yes" : "no"}\n` +
160
+ (v.exitCode !== 0 ? `\nnext: \`pitstop verify\` shows the failing categories — drive it again or fix by hand.` : ""), {
161
+ title: ` PITSTOP — Drive ${findingId} `,
162
+ titleAlignment: "center",
163
+ borderStyle: "round",
164
+ padding: 1,
165
+ borderColor: v.exitCode === 0 ? "green" : "red",
166
+ }));
167
+ process.exitCode = v.exitCode === 0 ? 0 : 1;
168
+ });
169
+ export default drive;
170
+ //# sourceMappingURL=drive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"drive.js","sourceRoot":"","sources":["../../src/commands/drive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare const gate: Command;