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,203 @@
1
+ import type { Language } from "./util.js";
2
+ export interface ScanIssue {
3
+ type: string;
4
+ severity: string;
5
+ file?: string;
6
+ line?: number;
7
+ description: string;
8
+ /** Stable, deterministic finding id (used by `pitstop repro`). */
9
+ id?: string;
10
+ }
11
+ export interface DependencyGraphResult {
12
+ status: "ok" | "skipped" | "error";
13
+ note?: string;
14
+ engine?: string;
15
+ files: number;
16
+ circular: string[][];
17
+ mostDependedOn: {
18
+ file: string;
19
+ count: number;
20
+ }[];
21
+ orphans: string[];
22
+ }
23
+ export interface SecurityResult {
24
+ status: "ok" | "skipped" | "error";
25
+ note?: string;
26
+ issues: ScanIssue[];
27
+ }
28
+ export interface DuplicationResult {
29
+ status: "ok" | "skipped" | "error";
30
+ note?: string;
31
+ cloneCount: number;
32
+ clones: {
33
+ files: string[];
34
+ lines: number;
35
+ }[];
36
+ }
37
+ export interface TestsResult {
38
+ status: "ok" | "skipped" | "error";
39
+ note?: string;
40
+ framework?: string;
41
+ total: number;
42
+ passed: number;
43
+ failed: number;
44
+ durationMs: number;
45
+ coverage?: number;
46
+ }
47
+ export interface PerfResult {
48
+ status: "ok" | "skipped" | "error";
49
+ note?: string;
50
+ buildTimeMs?: number;
51
+ bundleSizeBytes?: number;
52
+ /** Captured when the build script fails, to aid diagnosis. */
53
+ stderr?: string;
54
+ /** Stable id for the perf baseline finding (used by `pitstop repro`). */
55
+ id?: string;
56
+ }
57
+ export interface AccessibilityResult {
58
+ status: "ok" | "skipped" | "error";
59
+ note?: string;
60
+ /** Which detector produced the findings. */
61
+ engine?: "pa11y" | "axe" | "static-jsx";
62
+ checked?: {
63
+ type: "html" | "jsx";
64
+ count: number;
65
+ };
66
+ issues: ScanIssue[];
67
+ }
68
+ export interface FlakyTest {
69
+ name: string;
70
+ file?: string;
71
+ /** Outcome per sequential run (length === runs). */
72
+ statuses: ("passed" | "failed")[];
73
+ /** Stable, deterministic finding id. */
74
+ id?: string;
75
+ }
76
+ export interface ReliabilityResult {
77
+ status: "ok" | "skipped" | "error";
78
+ note?: string;
79
+ /** How many sequential suite runs were executed (1 if skipped after timing). */
80
+ runs: number;
81
+ /** Wall-clock total across all runs. */
82
+ durationMs: number;
83
+ /** Duration of the first (timing) run. */
84
+ suiteDurationMs?: number;
85
+ flakyTests: FlakyTest[];
86
+ /** Timer/state race-condition heuristics — never certain, always labeled. */
87
+ raceSmells: ScanIssue[];
88
+ }
89
+ export interface DuplicateFunction {
90
+ /** Function name when identical, else "<unnamed>". */
91
+ name: string;
92
+ files: {
93
+ file: string;
94
+ line: number;
95
+ }[];
96
+ /** Source lines of the body. */
97
+ lines: number;
98
+ /** Dice similarity of normalized token streams, 0..1. */
99
+ similarity: number;
100
+ }
101
+ export interface DevexResult {
102
+ status: "ok" | "skipped" | "error";
103
+ note?: string;
104
+ unusedExports: ScanIssue[];
105
+ duplicateFunctions: DuplicateFunction[];
106
+ }
107
+ export interface ClusterFinding {
108
+ source: "security" | "duplication" | "graph" | "a11y" | "reliability" | "devex" | "ledger";
109
+ severity: string;
110
+ type: string;
111
+ description: string;
112
+ files: string[];
113
+ /** Stable finding id — links a cluster back to scan-latest.json and `pitstop repro`. */
114
+ id?: string;
115
+ }
116
+ /** A money-moving endpoint discovered by the static scan. */
117
+ export interface LedgerEndpoint {
118
+ method: string;
119
+ path: string;
120
+ file?: string;
121
+ line?: number;
122
+ framework?: string;
123
+ /** Keyword that flagged the route (charge/capture/payment/transfer/refund/webhook). */
124
+ matchedKeyword: string;
125
+ /** Payment SDK imports seen in the same file. */
126
+ sdkImports: string[];
127
+ /** Heuristic expectation of the payload shape. */
128
+ expectedPayload: {
129
+ idempotencyKeyHeader?: string;
130
+ amountField?: string;
131
+ currencyField?: string;
132
+ orderIdField?: string;
133
+ };
134
+ /** True when this is a webhook-delivery endpoint (duplicate-webhook scenario). */
135
+ webhook: boolean;
136
+ }
137
+ /** One request/response pair that the mocked gateway actually received. */
138
+ export interface LedgerChargeCall {
139
+ at: string;
140
+ host: string;
141
+ method: string;
142
+ path: string;
143
+ key: string | null;
144
+ orderId: string | null;
145
+ requestId: string;
146
+ requestHeaders: Record<string, string>;
147
+ requestBody: unknown;
148
+ charge: boolean;
149
+ responseStatus: number;
150
+ responseBody: unknown;
151
+ }
152
+ export type LedgerScenario = "duplicate-webhook" | "concurrent-double-submit" | "delayed-retry";
153
+ /** A proven double-charge (one idempotency key saw >1 gateway charge call). */
154
+ export interface LedgerEvidence {
155
+ orderId: string;
156
+ idempotencyKey: string;
157
+ scenario: LedgerScenario;
158
+ endpoint: string;
159
+ endpointFile?: string;
160
+ doubleCharged: boolean;
161
+ chargeCalls: LedgerChargeCall[];
162
+ /** One-line human summary, e.g. "order ord_test_1 charged twice via webhook replay, 340ms apart". */
163
+ summary: string;
164
+ evidenceFile?: string;
165
+ /** Stable finding id (used by `pitstop repro`). */
166
+ id?: string;
167
+ }
168
+ export interface LedgerResult {
169
+ status: "ok" | "skipped" | "aborted" | "error";
170
+ note?: string;
171
+ /** Endpoints discovered statically. */
172
+ endpoints: LedgerEndpoint[];
173
+ /** Proven double-charges observed from the mocked gateway's receipt log. */
174
+ evidence: LedgerEvidence[];
175
+ /** Where the mocked gateway recorded what it received. */
176
+ gatewayLogPath?: string;
177
+ /** Absolute path of the written evidence file (`.pitstop/ledger-evidence-<ts>.json`). */
178
+ evidenceFile?: string;
179
+ }
180
+ export interface Cluster {
181
+ rootCause: ClusterFinding;
182
+ symptoms: ClusterFinding[];
183
+ sharedFiles: string[];
184
+ size: number;
185
+ }
186
+ export interface ScanResult {
187
+ timestamp: string;
188
+ repo: string;
189
+ /** `try` was produced by the quick `pitstop try` pass (tests/perf/reliability intentionally skipped). */
190
+ mode?: "full" | "try";
191
+ language: Language;
192
+ dependencyGraph: DependencyGraphResult;
193
+ security: SecurityResult;
194
+ duplication: DuplicationResult;
195
+ tests: TestsResult;
196
+ perf: PerfResult;
197
+ accessibility: AccessibilityResult;
198
+ reliability: ReliabilityResult;
199
+ devex: DevexResult;
200
+ /** Present only when the scan ran with `--ledger`. */
201
+ ledger?: LedgerResult;
202
+ clusters: Cluster[];
203
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/analyzers/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,35 @@
1
+ export type Language = "js" | "python" | "go" | "rust" | "dart" | "dotnet" | "java" | "unknown";
2
+ /**
3
+ * All external tool invocation goes through execa, which resolves PATH /
4
+ * PATHEXT (`.cmd` / `.exe` shims) correctly on Windows — the raw
5
+ * node:child_process execFile cannot spawn npm-installed `.cmd` shims there.
6
+ * `reject: false` + try/catch makes these wrappers never throw.
7
+ */
8
+ export declare function commandExists(cmd: string): boolean;
9
+ export declare function safeExec(file: string, args: string[], cwd: string, timeoutMs?: number): {
10
+ code: number;
11
+ stdout: string;
12
+ stderr: string;
13
+ };
14
+ /**
15
+ * Async twin of safeExec for analyzers that should run in parallel (security,
16
+ * tests, reliability, perf all spend their time waiting on subprocesses).
17
+ */
18
+ export declare function safeExecAsync(file: string, args: string[], cwd: string, timeoutMs?: number): Promise<{
19
+ code: number;
20
+ stdout: string;
21
+ stderr: string;
22
+ }>;
23
+ /** 1-based line number of a character index in a string. */
24
+ export declare function lineOf(content: string, index: number): number;
25
+ export declare function detectLanguage(repo: string): Language;
26
+ /**
27
+ * Newest file mtime under a repo (skipping generated/ignored dirs), used to
28
+ * detect whether a baseline scan has gone stale relative to the working tree.
29
+ */
30
+ export declare function newestModifiedFile(root: string): {
31
+ file: string;
32
+ mtimeMs: number;
33
+ } | null;
34
+ export declare function walkFiles(root: string, exts: string[]): string[];
35
+ export declare function dirSize(root: string): number;
@@ -0,0 +1,209 @@
1
+ import { execaSync, execa } from "execa";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ /**
5
+ * All external tool invocation goes through execa, which resolves PATH /
6
+ * PATHEXT (`.cmd` / `.exe` shims) correctly on Windows — the raw
7
+ * node:child_process execFile cannot spawn npm-installed `.cmd` shims there.
8
+ * `reject: false` + try/catch makes these wrappers never throw.
9
+ */
10
+ export function commandExists(cmd) {
11
+ try {
12
+ execaSync(process.platform === "win32" ? "where" : "which", [cmd], {
13
+ stdio: "ignore",
14
+ windowsHide: true,
15
+ });
16
+ return true;
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }
22
+ export function safeExec(file, args, cwd, timeoutMs = 120000) {
23
+ const asStr = (v) => (typeof v === "string" ? v : v instanceof Buffer ? v.toString() : "");
24
+ let res;
25
+ try {
26
+ res = execaSync(file, args, {
27
+ cwd,
28
+ encoding: "utf8",
29
+ stdio: ["ignore", "pipe", "pipe"],
30
+ timeout: timeoutMs,
31
+ windowsHide: true,
32
+ maxBuffer: 50 * 1024 * 1024,
33
+ reject: false,
34
+ });
35
+ }
36
+ catch (err) {
37
+ return { code: -1, stdout: "", stderr: err?.message ?? String(err) };
38
+ }
39
+ return {
40
+ code: typeof res.exitCode === "number" ? res.exitCode : res.failed ? 1 : -1,
41
+ stdout: asStr(res.stdout),
42
+ stderr: asStr(res.stderr),
43
+ };
44
+ }
45
+ /**
46
+ * Async twin of safeExec for analyzers that should run in parallel (security,
47
+ * tests, reliability, perf all spend their time waiting on subprocesses).
48
+ */
49
+ export async function safeExecAsync(file, args, cwd, timeoutMs = 120000) {
50
+ const asStr = (v) => (typeof v === "string" ? v : v instanceof Buffer ? v.toString() : "");
51
+ try {
52
+ const res = await execa(file, args, {
53
+ cwd,
54
+ encoding: "utf8",
55
+ stdio: ["ignore", "pipe", "pipe"],
56
+ timeout: timeoutMs,
57
+ windowsHide: true,
58
+ maxBuffer: 50 * 1024 * 1024,
59
+ reject: false,
60
+ });
61
+ return {
62
+ code: typeof res.exitCode === "number" ? res.exitCode : res.failed ? 1 : -1,
63
+ stdout: asStr(res.stdout),
64
+ stderr: asStr(res.stderr),
65
+ };
66
+ }
67
+ catch (err) {
68
+ return { code: -1, stdout: "", stderr: err?.message ?? String(err) };
69
+ }
70
+ }
71
+ /** 1-based line number of a character index in a string. */
72
+ export function lineOf(content, index) {
73
+ let line = 1;
74
+ const end = Math.min(index, content.length);
75
+ for (let i = 0; i < end; i++)
76
+ if (content[i] === "\n")
77
+ line++;
78
+ return line;
79
+ }
80
+ export function detectLanguage(repo) {
81
+ if (fs.existsSync(path.join(repo, "package.json")))
82
+ return "js";
83
+ if (fs.existsSync(path.join(repo, "requirements.txt")) ||
84
+ fs.existsSync(path.join(repo, "pyproject.toml")) ||
85
+ fs.existsSync(path.join(repo, "setup.py")))
86
+ return "python";
87
+ if (fs.existsSync(path.join(repo, "go.mod")))
88
+ return "go";
89
+ if (fs.existsSync(path.join(repo, "Cargo.toml")))
90
+ return "rust";
91
+ if (fs.existsSync(path.join(repo, "pubspec.yaml")) ||
92
+ fs.existsSync(path.join(repo, "pubspec.lock")))
93
+ return "dart";
94
+ if (fs.existsSync(path.join(repo, "pom.xml")) ||
95
+ fs.existsSync(path.join(repo, "build.gradle")) ||
96
+ fs.existsSync(path.join(repo, "build.gradle.kts")))
97
+ return "java";
98
+ // .NET projects are commonly nested in src/ folders, so probe the tree.
99
+ if (walkFiles(repo, [".csproj", ".fsproj", ".vbproj"]).length > 0)
100
+ return "dotnet";
101
+ return "unknown";
102
+ }
103
+ const IGNORE_DIRS = new Set([
104
+ "node_modules",
105
+ "dist",
106
+ "build",
107
+ ".git",
108
+ ".pitstop",
109
+ "coverage",
110
+ ".next",
111
+ ".venv",
112
+ "venv",
113
+ "__pycache__",
114
+ // Fixture / seed directories that are not part of the codebase under analysis.
115
+ "demo-repo",
116
+ "templates",
117
+ ]);
118
+ /**
119
+ * Newest file mtime under a repo (skipping generated/ignored dirs), used to
120
+ * detect whether a baseline scan has gone stale relative to the working tree.
121
+ */
122
+ export function newestModifiedFile(root) {
123
+ let best = null;
124
+ const stack = [root];
125
+ while (stack.length) {
126
+ const dir = stack.pop();
127
+ let entries;
128
+ try {
129
+ entries = fs.readdirSync(dir, { withFileTypes: true });
130
+ }
131
+ catch {
132
+ continue;
133
+ }
134
+ for (const e of entries) {
135
+ if (e.isDirectory()) {
136
+ if (IGNORE_DIRS.has(e.name) || e.name.startsWith("."))
137
+ continue;
138
+ stack.push(path.join(dir, e.name));
139
+ }
140
+ else if (e.isFile()) {
141
+ try {
142
+ const st = fs.statSync(path.join(dir, e.name));
143
+ if (!best || st.mtimeMs > best.mtimeMs) {
144
+ best = { file: path.join(dir, e.name), mtimeMs: st.mtimeMs };
145
+ }
146
+ }
147
+ catch {
148
+ /* ignore */
149
+ }
150
+ }
151
+ }
152
+ }
153
+ return best;
154
+ }
155
+ export function walkFiles(root, exts) {
156
+ const out = [];
157
+ const stack = [root];
158
+ while (stack.length) {
159
+ const dir = stack.pop();
160
+ let entries;
161
+ try {
162
+ entries = fs.readdirSync(dir, { withFileTypes: true });
163
+ }
164
+ catch {
165
+ continue;
166
+ }
167
+ for (const e of entries) {
168
+ if (e.isDirectory()) {
169
+ if (IGNORE_DIRS.has(e.name) || e.name.startsWith("."))
170
+ continue;
171
+ stack.push(path.join(dir, e.name));
172
+ }
173
+ else if (e.isFile()) {
174
+ if (exts.includes(path.extname(e.name)))
175
+ out.push(path.join(dir, e.name));
176
+ }
177
+ }
178
+ }
179
+ return out;
180
+ }
181
+ export function dirSize(root) {
182
+ let total = 0;
183
+ const stack = [root];
184
+ while (stack.length) {
185
+ const dir = stack.pop();
186
+ let entries;
187
+ try {
188
+ entries = fs.readdirSync(dir, { withFileTypes: true });
189
+ }
190
+ catch {
191
+ continue;
192
+ }
193
+ for (const e of entries) {
194
+ const p = path.join(dir, e.name);
195
+ if (e.isDirectory())
196
+ stack.push(p);
197
+ else if (e.isFile()) {
198
+ try {
199
+ total += fs.statSync(p).size;
200
+ }
201
+ catch {
202
+ /* ignore */
203
+ }
204
+ }
205
+ }
206
+ }
207
+ return total;
208
+ }
209
+ //# sourceMappingURL=util.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"util.js","sourceRoot":"","sources":["../../src/analyzers/util.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare const tagA = "audit-a";
2
+ export declare function describeA(): string;
@@ -0,0 +1,5 @@
1
+ export const tagA = "audit-a";
2
+ export function describeA() {
3
+ return "a";
4
+ }
5
+ //# sourceMappingURL=ciCheckA.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ciCheckA.js","sourceRoot":"","sources":["../src/ciCheckA.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,IAAI,GAAG,SAAS,CAAC;AAE9B,MAAM,UAAU,SAAS;IACvB,OAAO,GAAG,CAAC;AACb,CAAC"}
@@ -0,0 +1,2 @@
1
+ export declare const tagB = "audit-b";
2
+ export declare function describeB(): string;
@@ -0,0 +1,6 @@
1
+ import { tagA } from "./ciCheckA.js";
2
+ export const tagB = "audit-b";
3
+ export function describeB() {
4
+ return `b(${tagA})`;
5
+ }
6
+ //# sourceMappingURL=ciCheckB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ciCheckB.js","sourceRoot":"","sources":["../src/ciCheckB.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,MAAM,CAAC,MAAM,IAAI,GAAG,SAAS,CAAC;AAE9B,MAAM,UAAU,SAAS;IACvB,OAAO,KAAK,IAAI,GAAG,CAAC;AACtB,CAAC"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ export {};
package/dist/cli.js ADDED
@@ -0,0 +1,65 @@
1
+ #!/usr/bin/env node
2
+ import { Command } from "commander";
3
+ import fs from "node:fs";
4
+ import { install } from "./commands/install.js";
5
+ import { scan } from "./commands/scan.js";
6
+ import { verify } from "./commands/verify.js";
7
+ import { memory } from "./commands/memory.js";
8
+ import { report } from "./commands/report.js";
9
+ import { demo } from "./commands/demo.js";
10
+ import { ci } from "./commands/ci.js";
11
+ import { reproCmd } from "./commands/repro.js";
12
+ import { integrity } from "./commands/integrity.js";
13
+ import { inspect } from "./commands/inspect.js";
14
+ import { trends } from "./commands/trends.js";
15
+ import { doctor } from "./commands/doctor.js";
16
+ import { prompt } from "./commands/prompt.js";
17
+ import { try_ } from "./commands/try.js";
18
+ import { gate } from "./commands/gate.js";
19
+ import { share } from "./commands/share.js";
20
+ import { digest } from "./commands/digest.js";
21
+ import { honesty } from "./commands/honesty.js";
22
+ import { pen } from "./commands/pen.js";
23
+ import { readyCheckCmd } from "./commands/readyCheck.js";
24
+ import { budgetCmd } from "./commands/budget.js";
25
+ import { watch } from "./commands/watch.js";
26
+ import { drive } from "./commands/drive.js";
27
+ function readVersion() {
28
+ try {
29
+ const pkg = JSON.parse(fs.readFileSync(new URL("../package.json", import.meta.url), "utf8"));
30
+ return pkg.version ?? "0.0.0";
31
+ }
32
+ catch {
33
+ return "0.0.0";
34
+ }
35
+ }
36
+ const program = new Command();
37
+ program
38
+ .name("pitstop")
39
+ .description("OpenPitStop CLI")
40
+ .version(readVersion());
41
+ program.addCommand(install);
42
+ program.addCommand(scan);
43
+ program.addCommand(verify);
44
+ program.addCommand(memory);
45
+ program.addCommand(report);
46
+ program.addCommand(demo);
47
+ program.addCommand(ci);
48
+ program.addCommand(reproCmd);
49
+ program.addCommand(integrity);
50
+ program.addCommand(inspect);
51
+ program.addCommand(trends);
52
+ program.addCommand(doctor);
53
+ program.addCommand(prompt);
54
+ program.addCommand(try_);
55
+ program.addCommand(gate);
56
+ program.addCommand(share);
57
+ program.addCommand(digest);
58
+ program.addCommand(honesty);
59
+ program.addCommand(pen);
60
+ program.addCommand(readyCheckCmd);
61
+ program.addCommand(budgetCmd);
62
+ program.addCommand(watch);
63
+ program.addCommand(drive);
64
+ program.parseAsync(process.argv);
65
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ import { Command } from "commander";
2
+ /**
3
+ * `pitstop budget` — the token-economy ledger.
4
+ *
5
+ * The CLI cannot see a model's token counts (nobody can). What it CAN do is
6
+ * keep an honest wall-clock / compute ledger of everything the autonomous loop
7
+ * ran, and tell you exactly how much of it was waste that ready-check /
8
+ * --reuse / --reliability-runs 1 would have saved.
9
+ */
10
+ interface BudgetEntry {
11
+ scans: {
12
+ count: number;
13
+ reliabilityRuns: number;
14
+ testMs: number;
15
+ buildMs: number;
16
+ last: string;
17
+ };
18
+ verifies: {
19
+ count: number;
20
+ last: string;
21
+ };
22
+ pens: {
23
+ count: number;
24
+ last: string;
25
+ };
26
+ ledgerRuns: number;
27
+ auditCacheHits: number;
28
+ totalComputeSeconds: number;
29
+ loopRuns: number;
30
+ }
31
+ export declare function budget(repo: string): BudgetEntry;
32
+ export declare const budgetCmd: Command;
33
+ export default budgetCmd;