prose-qa 0.1.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 (427) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +570 -0
  3. package/dist/agent/bash.d.ts +52 -0
  4. package/dist/agent/bash.d.ts.map +1 -0
  5. package/dist/agent/bash.js +186 -0
  6. package/dist/agent/bash.js.map +1 -0
  7. package/dist/agent/bash.test.d.ts +2 -0
  8. package/dist/agent/bash.test.d.ts.map +1 -0
  9. package/dist/agent/bash.test.js +70 -0
  10. package/dist/agent/bash.test.js.map +1 -0
  11. package/dist/agent/llm-model.d.ts +5 -0
  12. package/dist/agent/llm-model.d.ts.map +1 -0
  13. package/dist/agent/llm-model.js +29 -0
  14. package/dist/agent/llm-model.js.map +1 -0
  15. package/dist/agent/llm-model.test.d.ts +2 -0
  16. package/dist/agent/llm-model.test.d.ts.map +1 -0
  17. package/dist/agent/llm-model.test.js +28 -0
  18. package/dist/agent/llm-model.test.js.map +1 -0
  19. package/dist/agent/prompt.d.ts +17 -0
  20. package/dist/agent/prompt.d.ts.map +1 -0
  21. package/dist/agent/prompt.js +97 -0
  22. package/dist/agent/prompt.js.map +1 -0
  23. package/dist/agent/prompt.test.d.ts +2 -0
  24. package/dist/agent/prompt.test.d.ts.map +1 -0
  25. package/dist/agent/prompt.test.js +124 -0
  26. package/dist/agent/prompt.test.js.map +1 -0
  27. package/dist/agent/provider-options.d.ts +8 -0
  28. package/dist/agent/provider-options.d.ts.map +1 -0
  29. package/dist/agent/provider-options.js +115 -0
  30. package/dist/agent/provider-options.js.map +1 -0
  31. package/dist/agent/provider-options.test.d.ts +2 -0
  32. package/dist/agent/provider-options.test.d.ts.map +1 -0
  33. package/dist/agent/provider-options.test.js +114 -0
  34. package/dist/agent/provider-options.test.js.map +1 -0
  35. package/dist/agent/runner.d.ts +27 -0
  36. package/dist/agent/runner.d.ts.map +1 -0
  37. package/dist/agent/runner.js +291 -0
  38. package/dist/agent/runner.js.map +1 -0
  39. package/dist/agent/verdict-retry-prompt.d.ts +3 -0
  40. package/dist/agent/verdict-retry-prompt.d.ts.map +1 -0
  41. package/dist/agent/verdict-retry-prompt.js +18 -0
  42. package/dist/agent/verdict-retry-prompt.js.map +1 -0
  43. package/dist/agent/verdict-retry-prompt.test.d.ts +2 -0
  44. package/dist/agent/verdict-retry-prompt.test.d.ts.map +1 -0
  45. package/dist/agent/verdict-retry-prompt.test.js +25 -0
  46. package/dist/agent/verdict-retry-prompt.test.js.map +1 -0
  47. package/dist/agent/verdict.d.ts +31 -0
  48. package/dist/agent/verdict.d.ts.map +1 -0
  49. package/dist/agent/verdict.js +123 -0
  50. package/dist/agent/verdict.js.map +1 -0
  51. package/dist/agent/verdict.test.d.ts +2 -0
  52. package/dist/agent/verdict.test.d.ts.map +1 -0
  53. package/dist/agent/verdict.test.js +156 -0
  54. package/dist/agent/verdict.test.js.map +1 -0
  55. package/dist/analyze/build-context.d.ts +58 -0
  56. package/dist/analyze/build-context.d.ts.map +1 -0
  57. package/dist/analyze/build-context.js +141 -0
  58. package/dist/analyze/build-context.js.map +1 -0
  59. package/dist/analyze/build-context.test.d.ts +2 -0
  60. package/dist/analyze/build-context.test.d.ts.map +1 -0
  61. package/dist/analyze/build-context.test.js +118 -0
  62. package/dist/analyze/build-context.test.js.map +1 -0
  63. package/dist/analyze/compare-runs.d.ts +49 -0
  64. package/dist/analyze/compare-runs.d.ts.map +1 -0
  65. package/dist/analyze/compare-runs.js +214 -0
  66. package/dist/analyze/compare-runs.js.map +1 -0
  67. package/dist/analyze/compare-runs.test.d.ts +2 -0
  68. package/dist/analyze/compare-runs.test.d.ts.map +1 -0
  69. package/dist/analyze/compare-runs.test.js +139 -0
  70. package/dist/analyze/compare-runs.test.js.map +1 -0
  71. package/dist/analyze/diff-hunks.d.ts +16 -0
  72. package/dist/analyze/diff-hunks.d.ts.map +1 -0
  73. package/dist/analyze/diff-hunks.js +287 -0
  74. package/dist/analyze/diff-hunks.js.map +1 -0
  75. package/dist/analyze/diff-hunks.test.d.ts +2 -0
  76. package/dist/analyze/diff-hunks.test.d.ts.map +1 -0
  77. package/dist/analyze/diff-hunks.test.js +54 -0
  78. package/dist/analyze/diff-hunks.test.js.map +1 -0
  79. package/dist/analyze/hunk-editor.d.ts +8 -0
  80. package/dist/analyze/hunk-editor.d.ts.map +1 -0
  81. package/dist/analyze/hunk-editor.js +129 -0
  82. package/dist/analyze/hunk-editor.js.map +1 -0
  83. package/dist/analyze/hunk-editor.test.d.ts +2 -0
  84. package/dist/analyze/hunk-editor.test.d.ts.map +1 -0
  85. package/dist/analyze/hunk-editor.test.js +48 -0
  86. package/dist/analyze/hunk-editor.test.js.map +1 -0
  87. package/dist/analyze/index.d.ts +23 -0
  88. package/dist/analyze/index.d.ts.map +1 -0
  89. package/dist/analyze/index.js +122 -0
  90. package/dist/analyze/index.js.map +1 -0
  91. package/dist/analyze/llm-fix.d.ts +11 -0
  92. package/dist/analyze/llm-fix.d.ts.map +1 -0
  93. package/dist/analyze/llm-fix.js +76 -0
  94. package/dist/analyze/llm-fix.js.map +1 -0
  95. package/dist/analyze/parse-proposal.d.ts +41 -0
  96. package/dist/analyze/parse-proposal.d.ts.map +1 -0
  97. package/dist/analyze/parse-proposal.js +53 -0
  98. package/dist/analyze/parse-proposal.js.map +1 -0
  99. package/dist/analyze/parse-proposal.test.d.ts +2 -0
  100. package/dist/analyze/parse-proposal.test.d.ts.map +1 -0
  101. package/dist/analyze/parse-proposal.test.js +40 -0
  102. package/dist/analyze/parse-proposal.test.js.map +1 -0
  103. package/dist/analyze/repl.d.ts +28 -0
  104. package/dist/analyze/repl.d.ts.map +1 -0
  105. package/dist/analyze/repl.js +284 -0
  106. package/dist/analyze/repl.js.map +1 -0
  107. package/dist/analyze/repl.test.d.ts +2 -0
  108. package/dist/analyze/repl.test.d.ts.map +1 -0
  109. package/dist/analyze/repl.test.js +101 -0
  110. package/dist/analyze/repl.test.js.map +1 -0
  111. package/dist/analyze/suggest.d.ts +5 -0
  112. package/dist/analyze/suggest.d.ts.map +1 -0
  113. package/dist/analyze/suggest.js +75 -0
  114. package/dist/analyze/suggest.js.map +1 -0
  115. package/dist/analyze/suggest.test.d.ts +2 -0
  116. package/dist/analyze/suggest.test.d.ts.map +1 -0
  117. package/dist/analyze/suggest.test.js +53 -0
  118. package/dist/analyze/suggest.test.js.map +1 -0
  119. package/dist/analyze/validate-markdown.d.ts +3 -0
  120. package/dist/analyze/validate-markdown.d.ts.map +1 -0
  121. package/dist/analyze/validate-markdown.js +25 -0
  122. package/dist/analyze/validate-markdown.js.map +1 -0
  123. package/dist/artifacts/policy.d.ts +9 -0
  124. package/dist/artifacts/policy.d.ts.map +1 -0
  125. package/dist/artifacts/policy.js +46 -0
  126. package/dist/artifacts/policy.js.map +1 -0
  127. package/dist/artifacts/policy.test.d.ts +2 -0
  128. package/dist/artifacts/policy.test.d.ts.map +1 -0
  129. package/dist/artifacts/policy.test.js +73 -0
  130. package/dist/artifacts/policy.test.js.map +1 -0
  131. package/dist/auth/resolve.d.ts +22 -0
  132. package/dist/auth/resolve.d.ts.map +1 -0
  133. package/dist/auth/resolve.js +148 -0
  134. package/dist/auth/resolve.js.map +1 -0
  135. package/dist/auth/store.d.ts +23 -0
  136. package/dist/auth/store.d.ts.map +1 -0
  137. package/dist/auth/store.js +103 -0
  138. package/dist/auth/store.js.map +1 -0
  139. package/dist/cache/generate.d.ts +8 -0
  140. package/dist/cache/generate.d.ts.map +1 -0
  141. package/dist/cache/generate.js +61 -0
  142. package/dist/cache/generate.js.map +1 -0
  143. package/dist/cache/hash.d.ts +5 -0
  144. package/dist/cache/hash.d.ts.map +1 -0
  145. package/dist/cache/hash.js +21 -0
  146. package/dist/cache/hash.js.map +1 -0
  147. package/dist/cache/hash.test.d.ts +2 -0
  148. package/dist/cache/hash.test.d.ts.map +1 -0
  149. package/dist/cache/hash.test.js +42 -0
  150. package/dist/cache/hash.test.js.map +1 -0
  151. package/dist/cache/resolve.d.ts +5 -0
  152. package/dist/cache/resolve.d.ts.map +1 -0
  153. package/dist/cache/resolve.js +8 -0
  154. package/dist/cache/resolve.js.map +1 -0
  155. package/dist/cache/store.d.ts +20 -0
  156. package/dist/cache/store.d.ts.map +1 -0
  157. package/dist/cache/store.js +90 -0
  158. package/dist/cache/store.js.map +1 -0
  159. package/dist/cache/store.test.d.ts +2 -0
  160. package/dist/cache/store.test.d.ts.map +1 -0
  161. package/dist/cache/store.test.js +101 -0
  162. package/dist/cache/store.test.js.map +1 -0
  163. package/dist/cli/analyze.d.ts +21 -0
  164. package/dist/cli/analyze.d.ts.map +1 -0
  165. package/dist/cli/analyze.js +148 -0
  166. package/dist/cli/analyze.js.map +1 -0
  167. package/dist/cli/concurrency.d.ts +17 -0
  168. package/dist/cli/concurrency.d.ts.map +1 -0
  169. package/dist/cli/concurrency.js +56 -0
  170. package/dist/cli/concurrency.js.map +1 -0
  171. package/dist/cli/concurrency.test.d.ts +2 -0
  172. package/dist/cli/concurrency.test.d.ts.map +1 -0
  173. package/dist/cli/concurrency.test.js +74 -0
  174. package/dist/cli/concurrency.test.js.map +1 -0
  175. package/dist/cli/config.d.ts +2 -0
  176. package/dist/cli/config.d.ts.map +1 -0
  177. package/dist/cli/config.js +14 -0
  178. package/dist/cli/config.js.map +1 -0
  179. package/dist/cli/help.d.ts +23 -0
  180. package/dist/cli/help.d.ts.map +1 -0
  181. package/dist/cli/help.js +458 -0
  182. package/dist/cli/help.js.map +1 -0
  183. package/dist/cli/help.test.d.ts +2 -0
  184. package/dist/cli/help.test.d.ts.map +1 -0
  185. package/dist/cli/help.test.js +41 -0
  186. package/dist/cli/help.test.js.map +1 -0
  187. package/dist/cli/index.d.ts +3 -0
  188. package/dist/cli/index.d.ts.map +1 -0
  189. package/dist/cli/index.js +300 -0
  190. package/dist/cli/index.js.map +1 -0
  191. package/dist/cli/mcp.d.ts +6 -0
  192. package/dist/cli/mcp.d.ts.map +1 -0
  193. package/dist/cli/mcp.js +17 -0
  194. package/dist/cli/mcp.js.map +1 -0
  195. package/dist/cli/record.d.ts +27 -0
  196. package/dist/cli/record.d.ts.map +1 -0
  197. package/dist/cli/record.js +244 -0
  198. package/dist/cli/record.js.map +1 -0
  199. package/dist/cli/run.d.ts +11 -0
  200. package/dist/cli/run.d.ts.map +1 -0
  201. package/dist/cli/run.js +676 -0
  202. package/dist/cli/run.js.map +1 -0
  203. package/dist/cli/subprocess.d.ts +19 -0
  204. package/dist/cli/subprocess.d.ts.map +1 -0
  205. package/dist/cli/subprocess.js +142 -0
  206. package/dist/cli/subprocess.js.map +1 -0
  207. package/dist/cli/subprocess.test.d.ts +2 -0
  208. package/dist/cli/subprocess.test.d.ts.map +1 -0
  209. package/dist/cli/subprocess.test.js +76 -0
  210. package/dist/cli/subprocess.test.js.map +1 -0
  211. package/dist/cli/tags.d.ts +5 -0
  212. package/dist/cli/tags.d.ts.map +1 -0
  213. package/dist/cli/tags.js +33 -0
  214. package/dist/cli/tags.js.map +1 -0
  215. package/dist/cli/tags.test.d.ts +2 -0
  216. package/dist/cli/tags.test.d.ts.map +1 -0
  217. package/dist/cli/tags.test.js +31 -0
  218. package/dist/cli/tags.test.js.map +1 -0
  219. package/dist/config/env-vars.d.ts +2 -0
  220. package/dist/config/env-vars.d.ts.map +1 -0
  221. package/dist/config/env-vars.js +14 -0
  222. package/dist/config/env-vars.js.map +1 -0
  223. package/dist/config/env.d.ts +2 -0
  224. package/dist/config/env.d.ts.map +1 -0
  225. package/dist/config/env.js +9 -0
  226. package/dist/config/env.js.map +1 -0
  227. package/dist/config/lightpanda.d.ts +6 -0
  228. package/dist/config/lightpanda.d.ts.map +1 -0
  229. package/dist/config/lightpanda.js +38 -0
  230. package/dist/config/lightpanda.js.map +1 -0
  231. package/dist/config/lightpanda.test.d.ts +2 -0
  232. package/dist/config/lightpanda.test.d.ts.map +1 -0
  233. package/dist/config/lightpanda.test.js +46 -0
  234. package/dist/config/lightpanda.test.js.map +1 -0
  235. package/dist/config/load.d.ts +22 -0
  236. package/dist/config/load.d.ts.map +1 -0
  237. package/dist/config/load.js +242 -0
  238. package/dist/config/load.js.map +1 -0
  239. package/dist/config/load.test.d.ts +2 -0
  240. package/dist/config/load.test.d.ts.map +1 -0
  241. package/dist/config/load.test.js +86 -0
  242. package/dist/config/load.test.js.map +1 -0
  243. package/dist/config/set.d.ts +8 -0
  244. package/dist/config/set.d.ts.map +1 -0
  245. package/dist/config/set.js +93 -0
  246. package/dist/config/set.js.map +1 -0
  247. package/dist/config/set.test.d.ts +2 -0
  248. package/dist/config/set.test.d.ts.map +1 -0
  249. package/dist/config/set.test.js +98 -0
  250. package/dist/config/set.test.js.map +1 -0
  251. package/dist/healing/classify.d.ts +15 -0
  252. package/dist/healing/classify.d.ts.map +1 -0
  253. package/dist/healing/classify.js +209 -0
  254. package/dist/healing/classify.js.map +1 -0
  255. package/dist/healing/classify.test.d.ts +2 -0
  256. package/dist/healing/classify.test.d.ts.map +1 -0
  257. package/dist/healing/classify.test.js +167 -0
  258. package/dist/healing/classify.test.js.map +1 -0
  259. package/dist/healing/recovery-prompt.d.ts +3 -0
  260. package/dist/healing/recovery-prompt.d.ts.map +1 -0
  261. package/dist/healing/recovery-prompt.js +22 -0
  262. package/dist/healing/recovery-prompt.js.map +1 -0
  263. package/dist/mcp/inline-scenario.d.ts +13 -0
  264. package/dist/mcp/inline-scenario.d.ts.map +1 -0
  265. package/dist/mcp/inline-scenario.js +23 -0
  266. package/dist/mcp/inline-scenario.js.map +1 -0
  267. package/dist/mcp/server.d.ts +4 -0
  268. package/dist/mcp/server.d.ts.map +1 -0
  269. package/dist/mcp/server.js +186 -0
  270. package/dist/mcp/server.js.map +1 -0
  271. package/dist/mcp/skill.d.ts +5 -0
  272. package/dist/mcp/skill.d.ts.map +1 -0
  273. package/dist/mcp/skill.js +38 -0
  274. package/dist/mcp/skill.js.map +1 -0
  275. package/dist/mcp/skill.test.d.ts +2 -0
  276. package/dist/mcp/skill.test.d.ts.map +1 -0
  277. package/dist/mcp/skill.test.js +18 -0
  278. package/dist/mcp/skill.test.js.map +1 -0
  279. package/dist/paths.d.ts +12 -0
  280. package/dist/paths.d.ts.map +1 -0
  281. package/dist/paths.js +61 -0
  282. package/dist/paths.js.map +1 -0
  283. package/dist/prompt/load.d.ts +4 -0
  284. package/dist/prompt/load.d.ts.map +1 -0
  285. package/dist/prompt/load.js +19 -0
  286. package/dist/prompt/load.js.map +1 -0
  287. package/dist/recorder/bridge-process.d.ts +14 -0
  288. package/dist/recorder/bridge-process.d.ts.map +1 -0
  289. package/dist/recorder/bridge-process.js +133 -0
  290. package/dist/recorder/bridge-process.js.map +1 -0
  291. package/dist/recorder/bridge-process.test.d.ts +2 -0
  292. package/dist/recorder/bridge-process.test.d.ts.map +1 -0
  293. package/dist/recorder/bridge-process.test.js +36 -0
  294. package/dist/recorder/bridge-process.test.js.map +1 -0
  295. package/dist/recorder/bridge-worker.d.ts +2 -0
  296. package/dist/recorder/bridge-worker.d.ts.map +1 -0
  297. package/dist/recorder/bridge-worker.js +76 -0
  298. package/dist/recorder/bridge-worker.js.map +1 -0
  299. package/dist/recorder/bridge.d.ts +12 -0
  300. package/dist/recorder/bridge.d.ts.map +1 -0
  301. package/dist/recorder/bridge.js +61 -0
  302. package/dist/recorder/bridge.js.map +1 -0
  303. package/dist/recorder/bridge.test.d.ts +2 -0
  304. package/dist/recorder/bridge.test.d.ts.map +1 -0
  305. package/dist/recorder/bridge.test.js +21 -0
  306. package/dist/recorder/bridge.test.js.map +1 -0
  307. package/dist/recorder/enrich-event.d.ts +31 -0
  308. package/dist/recorder/enrich-event.d.ts.map +1 -0
  309. package/dist/recorder/enrich-event.js +91 -0
  310. package/dist/recorder/enrich-event.js.map +1 -0
  311. package/dist/recorder/events.d.ts +11 -0
  312. package/dist/recorder/events.d.ts.map +1 -0
  313. package/dist/recorder/events.js +42 -0
  314. package/dist/recorder/events.js.map +1 -0
  315. package/dist/recorder/events.test.d.ts +2 -0
  316. package/dist/recorder/events.test.d.ts.map +1 -0
  317. package/dist/recorder/events.test.js +40 -0
  318. package/dist/recorder/events.test.js.map +1 -0
  319. package/dist/recorder/generate-scenario.d.ts +16 -0
  320. package/dist/recorder/generate-scenario.d.ts.map +1 -0
  321. package/dist/recorder/generate-scenario.js +78 -0
  322. package/dist/recorder/generate-scenario.js.map +1 -0
  323. package/dist/recorder/in-page-helpers.d.ts +6 -0
  324. package/dist/recorder/in-page-helpers.d.ts.map +1 -0
  325. package/dist/recorder/in-page-helpers.js +238 -0
  326. package/dist/recorder/in-page-helpers.js.map +1 -0
  327. package/dist/recorder/in-page-helpers.test.d.ts +2 -0
  328. package/dist/recorder/in-page-helpers.test.d.ts.map +1 -0
  329. package/dist/recorder/in-page-helpers.test.js +186 -0
  330. package/dist/recorder/in-page-helpers.test.js.map +1 -0
  331. package/dist/recorder/page-script.d.ts +7 -0
  332. package/dist/recorder/page-script.d.ts.map +1 -0
  333. package/dist/recorder/page-script.js +132 -0
  334. package/dist/recorder/page-script.js.map +1 -0
  335. package/dist/recorder/redact.d.ts +8 -0
  336. package/dist/recorder/redact.d.ts.map +1 -0
  337. package/dist/recorder/redact.js +26 -0
  338. package/dist/recorder/redact.js.map +1 -0
  339. package/dist/recorder/redact.test.d.ts +2 -0
  340. package/dist/recorder/redact.test.d.ts.map +1 -0
  341. package/dist/recorder/redact.test.js +27 -0
  342. package/dist/recorder/redact.test.js.map +1 -0
  343. package/dist/recorder/session.d.ts +8 -0
  344. package/dist/recorder/session.d.ts.map +1 -0
  345. package/dist/recorder/session.js +28 -0
  346. package/dist/recorder/session.js.map +1 -0
  347. package/dist/recorder/snapshot-match.d.ts +22 -0
  348. package/dist/recorder/snapshot-match.d.ts.map +1 -0
  349. package/dist/recorder/snapshot-match.js +102 -0
  350. package/dist/recorder/snapshot-match.js.map +1 -0
  351. package/dist/recorder/snapshot-match.test.d.ts +2 -0
  352. package/dist/recorder/snapshot-match.test.d.ts.map +1 -0
  353. package/dist/recorder/snapshot-match.test.js +34 -0
  354. package/dist/recorder/snapshot-match.test.js.map +1 -0
  355. package/dist/redact/env-secrets.d.ts +14 -0
  356. package/dist/redact/env-secrets.d.ts.map +1 -0
  357. package/dist/redact/env-secrets.js +86 -0
  358. package/dist/redact/env-secrets.js.map +1 -0
  359. package/dist/redact/env-secrets.test.d.ts +2 -0
  360. package/dist/redact/env-secrets.test.d.ts.map +1 -0
  361. package/dist/redact/env-secrets.test.js +103 -0
  362. package/dist/redact/env-secrets.test.js.map +1 -0
  363. package/dist/reporter/export.d.ts +14 -0
  364. package/dist/reporter/export.d.ts.map +1 -0
  365. package/dist/reporter/export.js +53 -0
  366. package/dist/reporter/export.js.map +1 -0
  367. package/dist/reporter/export.test.d.ts +2 -0
  368. package/dist/reporter/export.test.d.ts.map +1 -0
  369. package/dist/reporter/export.test.js +100 -0
  370. package/dist/reporter/export.test.js.map +1 -0
  371. package/dist/reporter/index.d.ts +11 -0
  372. package/dist/reporter/index.d.ts.map +1 -0
  373. package/dist/reporter/index.js +161 -0
  374. package/dist/reporter/index.js.map +1 -0
  375. package/dist/reporter/index.test.d.ts +2 -0
  376. package/dist/reporter/index.test.d.ts.map +1 -0
  377. package/dist/reporter/index.test.js +61 -0
  378. package/dist/reporter/index.test.js.map +1 -0
  379. package/dist/scenarios/globs.d.ts +15 -0
  380. package/dist/scenarios/globs.d.ts.map +1 -0
  381. package/dist/scenarios/globs.js +48 -0
  382. package/dist/scenarios/globs.js.map +1 -0
  383. package/dist/scenarios/globs.test.d.ts +2 -0
  384. package/dist/scenarios/globs.test.d.ts.map +1 -0
  385. package/dist/scenarios/globs.test.js +53 -0
  386. package/dist/scenarios/globs.test.js.map +1 -0
  387. package/dist/scenarios/parser.d.ts +15 -0
  388. package/dist/scenarios/parser.d.ts.map +1 -0
  389. package/dist/scenarios/parser.js +278 -0
  390. package/dist/scenarios/parser.js.map +1 -0
  391. package/dist/scenarios/parser.test.d.ts +2 -0
  392. package/dist/scenarios/parser.test.d.ts.map +1 -0
  393. package/dist/scenarios/parser.test.js +373 -0
  394. package/dist/scenarios/parser.test.js.map +1 -0
  395. package/dist/skills/loader.d.ts +10 -0
  396. package/dist/skills/loader.d.ts.map +1 -0
  397. package/dist/skills/loader.js +98 -0
  398. package/dist/skills/loader.js.map +1 -0
  399. package/dist/types/config.d.ts +131 -0
  400. package/dist/types/config.d.ts.map +1 -0
  401. package/dist/types/config.js +2 -0
  402. package/dist/types/config.js.map +1 -0
  403. package/dist/types/recorder.d.ts +71 -0
  404. package/dist/types/recorder.d.ts.map +1 -0
  405. package/dist/types/recorder.js +2 -0
  406. package/dist/types/recorder.js.map +1 -0
  407. package/dist/types/scenario.d.ts +41 -0
  408. package/dist/types/scenario.d.ts.map +1 -0
  409. package/dist/types/scenario.js +2 -0
  410. package/dist/types/scenario.js.map +1 -0
  411. package/dist/types/skill.d.ts +20 -0
  412. package/dist/types/skill.d.ts.map +1 -0
  413. package/dist/types/skill.js +13 -0
  414. package/dist/types/skill.js.map +1 -0
  415. package/dist/types/verdict.d.ts +82 -0
  416. package/dist/types/verdict.d.ts.map +1 -0
  417. package/dist/types/verdict.js +13 -0
  418. package/dist/types/verdict.js.map +1 -0
  419. package/package.json +75 -0
  420. package/pqa.config.ts +82 -0
  421. package/prompt/ANALYZE-FLAKY.md +62 -0
  422. package/prompt/ANALYZE.md +110 -0
  423. package/prompt/CACHE-HINTS.md +49 -0
  424. package/prompt/RECORD.md +114 -0
  425. package/prompt/SYSTEM.md +118 -0
  426. package/skills/agent-browser/SKILL.md +2438 -0
  427. package/skills/create-pqa-scenario/SKILL.md +273 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.test.js","sourceRoot":"","sources":["../../src/cache/hash.test.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,oBAAoB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,WAAW,CAAC;AAEzC,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhD,SAAS,YAAY,CAAC,YAA+B,EAAE;IACrD,OAAO;QACL,QAAQ,EAAE,iBAAiB;QAC3B,WAAW,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE;QACtC,MAAM,EAAE,EAAE;QACV,IAAI,EAAE,6BAA6B;QACnC,KAAK,EAAE,kBAAkB;QACzB,IAAI,EAAE,CAAC,2BAA2B,CAAC;QACnC,cAAc,EAAE,CAAC,2BAA2B,CAAC;QAC7C,WAAW,EAAE;YACX,EAAE,GAAG,EAAE,2BAA2B,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,EAAE;SAChF;QACD,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,EAAE,CAAC,yCAAyC,EAAE,GAAG,EAAE;QACjD,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC;QACzB,MAAM,CAAC,GAAG,YAAY,CAAC,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC,CAAC;QACvD,MAAM,CAAC,KAAK,CAAC,mBAAmB,CAAC,CAAC,CAAC,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,2BAA2B,EAAE,GAAG,EAAE;QACnC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,YAAY,CAAC,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC,CAAC;QAC1E,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,GAAG,EAAE;QAC9C,MAAM,MAAM,GAAG,YAAY,EAAE,CAAC;QAC9B,MAAM,KAAK,GAAG,YAAY,CAAC;YACzB,IAAI,EAAE,CAAC,mBAAmB,CAAC;YAC3B,cAAc,EAAE,CAAC,mBAAmB,CAAC;YACrC,WAAW,EAAE;gBACX,EAAE,GAAG,EAAE,mBAAmB,EAAE,IAAI,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,EAAE;aAChE;SACF,CAAC,CAAC;QACH,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAC,MAAM,CAAC,EAAE,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;IAC3E,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { PqaConfig } from "../types/config.js";
2
+ import { resolveCacheConfig } from "../config/load.js";
3
+ export { resolveCacheConfig };
4
+ export declare function isCacheEnabled(config: PqaConfig, noCache?: boolean): boolean;
5
+ //# sourceMappingURL=resolve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../src/cache/resolve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B,wBAAgB,cAAc,CAC5B,MAAM,EAAE,SAAS,EACjB,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAGT"}
@@ -0,0 +1,8 @@
1
+ import { resolveCacheConfig } from "../config/load.js";
2
+ export { resolveCacheConfig };
3
+ export function isCacheEnabled(config, noCache) {
4
+ if (noCache)
5
+ return false;
6
+ return resolveCacheConfig(config).enabled;
7
+ }
8
+ //# sourceMappingURL=resolve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolve.js","sourceRoot":"","sources":["../../src/cache/resolve.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,kBAAkB,EAAE,CAAC;AAE9B,MAAM,UAAU,cAAc,CAC5B,MAAiB,EACjB,OAAiB;IAEjB,IAAI,OAAO;QAAE,OAAO,KAAK,CAAC;IAC1B,OAAO,kBAAkB,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { PqaConfig } from "../types/config.js";
2
+ import type { Scenario } from "../types/scenario.js";
3
+ export interface ScenarioCacheMeta {
4
+ scenarioName: string;
5
+ contentHash: string;
6
+ updatedAt: string;
7
+ version: number;
8
+ passCount: number;
9
+ }
10
+ export declare function safeScenarioDirName(name: string): string;
11
+ export declare function resolveCacheRoot(cwd: string, config: PqaConfig): string;
12
+ export declare function scenarioCacheDir(cwd: string, config: PqaConfig, scenarioName: string): string;
13
+ export declare function invalidateScenarioCache(cwd: string, config: PqaConfig, scenarioName: string): void;
14
+ /** Load hints when content hash matches; otherwise invalidate and return undefined. */
15
+ export declare function loadScenarioCache(cwd: string, config: PqaConfig, scenario: Scenario): string | undefined;
16
+ export declare function writeScenarioCache(cwd: string, config: PqaConfig, scenario: Scenario, hints: string, existingMeta?: ScenarioCacheMeta): void;
17
+ export declare function readScenarioCacheMeta(cwd: string, config: PqaConfig, scenarioName: string): ScenarioCacheMeta | undefined;
18
+ export declare function listCachedScenarios(cwd: string, config: PqaConfig): string[];
19
+ export declare function clearCache(cwd: string, config: PqaConfig, scenarioName?: string): void;
20
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/cache/store.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAIrD,MAAM,WAAW,iBAAiB;IAChC,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,GAAG,MAAM,CAGvE;AAED,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,MAAM,GACnB,MAAM,CAKR;AAoBD,wBAAgB,uBAAuB,CACrC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,MAAM,GACnB,IAAI,CAKN;AAED,uFAAuF;AACvF,wBAAgB,iBAAiB,CAC/B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,QAAQ,GACjB,MAAM,GAAG,SAAS,CAgBpB;AAED,wBAAgB,kBAAkB,CAChC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,SAAS,EACjB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,MAAM,EACb,YAAY,CAAC,EAAE,iBAAiB,GAC/B,IAAI,CAeN;AAED,wBAAgB,qBAAqB,CACnC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,SAAS,EACjB,YAAY,EAAE,MAAM,GACnB,iBAAiB,GAAG,SAAS,CAG/B;AAED,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,SAAS,GAChB,MAAM,EAAE,CAOV;AAED,wBAAgB,UAAU,CACxB,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,SAAS,EACjB,YAAY,CAAC,EAAE,MAAM,GACpB,IAAI,CAUN"}
@@ -0,0 +1,90 @@
1
+ import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync, } from "node:fs";
2
+ import path from "node:path";
3
+ import { hashScenarioContent } from "./hash.js";
4
+ import { resolveCacheConfig } from "./resolve.js";
5
+ export function safeScenarioDirName(name) {
6
+ return name.replace(/[^a-z0-9-]/gi, "-").toLowerCase();
7
+ }
8
+ export function resolveCacheRoot(cwd, config) {
9
+ const { dir } = resolveCacheConfig(config);
10
+ return path.isAbsolute(dir) ? dir : path.resolve(cwd, dir);
11
+ }
12
+ export function scenarioCacheDir(cwd, config, scenarioName) {
13
+ return path.join(resolveCacheRoot(cwd, config), safeScenarioDirName(scenarioName));
14
+ }
15
+ function metaPath(cacheDir) {
16
+ return path.join(cacheDir, "meta.json");
17
+ }
18
+ function hintsPath(cacheDir) {
19
+ return path.join(cacheDir, "hints.md");
20
+ }
21
+ function readMeta(cacheDir) {
22
+ const file = metaPath(cacheDir);
23
+ if (!existsSync(file))
24
+ return undefined;
25
+ try {
26
+ return JSON.parse(readFileSync(file, "utf-8"));
27
+ }
28
+ catch {
29
+ return undefined;
30
+ }
31
+ }
32
+ export function invalidateScenarioCache(cwd, config, scenarioName) {
33
+ const dir = scenarioCacheDir(cwd, config, scenarioName);
34
+ if (existsSync(dir)) {
35
+ rmSync(dir, { recursive: true, force: true });
36
+ }
37
+ }
38
+ /** Load hints when content hash matches; otherwise invalidate and return undefined. */
39
+ export function loadScenarioCache(cwd, config, scenario) {
40
+ const name = scenario.frontmatter.name;
41
+ const dir = scenarioCacheDir(cwd, config, name);
42
+ const expectedHash = hashScenarioContent(scenario);
43
+ const meta = readMeta(dir);
44
+ if (!meta || !existsSync(hintsPath(dir))) {
45
+ return undefined;
46
+ }
47
+ if (meta.contentHash !== expectedHash) {
48
+ invalidateScenarioCache(cwd, config, name);
49
+ return undefined;
50
+ }
51
+ return readFileSync(hintsPath(dir), "utf-8").trim() || undefined;
52
+ }
53
+ export function writeScenarioCache(cwd, config, scenario, hints, existingMeta) {
54
+ const name = scenario.frontmatter.name;
55
+ const dir = scenarioCacheDir(cwd, config, name);
56
+ mkdirSync(dir, { recursive: true });
57
+ const meta = {
58
+ scenarioName: name,
59
+ contentHash: hashScenarioContent(scenario),
60
+ updatedAt: new Date().toISOString(),
61
+ version: 1,
62
+ passCount: (existingMeta?.passCount ?? 0) + 1,
63
+ };
64
+ writeFileSync(hintsPath(dir), `${hints.trim()}\n`, "utf-8");
65
+ writeFileSync(metaPath(dir), `${JSON.stringify(meta, null, 2)}\n`, "utf-8");
66
+ }
67
+ export function readScenarioCacheMeta(cwd, config, scenarioName) {
68
+ const dir = scenarioCacheDir(cwd, config, scenarioName);
69
+ return readMeta(dir);
70
+ }
71
+ export function listCachedScenarios(cwd, config) {
72
+ const root = resolveCacheRoot(cwd, config);
73
+ if (!existsSync(root))
74
+ return [];
75
+ return readdirSync(root, { withFileTypes: true })
76
+ .filter((e) => e.isDirectory())
77
+ .map((e) => e.name)
78
+ .sort();
79
+ }
80
+ export function clearCache(cwd, config, scenarioName) {
81
+ if (scenarioName) {
82
+ invalidateScenarioCache(cwd, config, scenarioName);
83
+ return;
84
+ }
85
+ const root = resolveCacheRoot(cwd, config);
86
+ if (existsSync(root)) {
87
+ rmSync(root, { recursive: true, force: true });
88
+ }
89
+ }
90
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/cache/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=store.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.test.d.ts","sourceRoot":"","sources":["../../src/cache/store.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,101 @@
1
+ import assert from "node:assert/strict";
2
+ import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
3
+ import { tmpdir } from "node:os";
4
+ import path from "node:path";
5
+ import { describe, it } from "node:test";
6
+ import { hashScenarioContent } from "./hash.js";
7
+ import { isCacheEnabled } from "./resolve.js";
8
+ import { clearCache, loadScenarioCache, safeScenarioDirName, writeScenarioCache, } from "./store.js";
9
+ const baseConfig = {
10
+ llm: { provider: "anthropic", model: "claude-sonnet-4-20250514" },
11
+ browser: { headed: false, sessionName: "pqa", defaultTimeout: 25_000, engine: "chrome" },
12
+ skills: { dirs: [], preloads: [] },
13
+ agent: { maxTurns: 100, bashTimeoutMs: 120_000 },
14
+ auth: {},
15
+ cache: { dir: ".pqa/cache", enabled: true },
16
+ };
17
+ function makeScenario(overrides = {}) {
18
+ return {
19
+ filePath: "/tmp/example.md",
20
+ frontmatter: { name: "example-smoke" },
21
+ skills: [],
22
+ goal: "Goal",
23
+ steps: "Steps",
24
+ then: ["then one"],
25
+ rawCheckpoints: ["then one"],
26
+ checkpoints: [{ raw: "then one", kind: "unknown" }],
27
+ ...overrides,
28
+ };
29
+ }
30
+ describe("isCacheEnabled", () => {
31
+ it("returns false when noCache is set", () => {
32
+ assert.equal(isCacheEnabled(baseConfig, true), false);
33
+ });
34
+ it("returns false when cache.enabled is false", () => {
35
+ assert.equal(isCacheEnabled({ ...baseConfig, cache: { enabled: false } }), false);
36
+ });
37
+ });
38
+ describe("scenario cache store", () => {
39
+ it("writes and loads hints when hash matches", () => {
40
+ const cwd = mkdtempSync(path.join(tmpdir(), "pqa-cache-"));
41
+ const scenario = makeScenario();
42
+ writeScenarioCache(cwd, baseConfig, scenario, "## Effective actions\n- click @e1");
43
+ const loaded = loadScenarioCache(cwd, baseConfig, scenario);
44
+ assert.match(loaded ?? "", /Effective actions/);
45
+ rmSync(cwd, { recursive: true, force: true });
46
+ });
47
+ it("invalidates cache when expanded content changes", () => {
48
+ const cwd = mkdtempSync(path.join(tmpdir(), "pqa-cache-"));
49
+ const scenario = makeScenario();
50
+ writeScenarioCache(cwd, baseConfig, scenario, "old hints");
51
+ const dir = path.join(cwd, ".pqa", "cache", safeScenarioDirName("example-smoke"));
52
+ assert.ok(existsSync(dir));
53
+ const changed = makeScenario({ steps: "New steps" });
54
+ const loaded = loadScenarioCache(cwd, baseConfig, changed);
55
+ assert.equal(loaded, undefined);
56
+ assert.equal(existsSync(dir), false);
57
+ rmSync(cwd, { recursive: true, force: true });
58
+ });
59
+ it("clearCache removes one or all entries", () => {
60
+ const cwd = mkdtempSync(path.join(tmpdir(), "pqa-cache-"));
61
+ writeScenarioCache(cwd, baseConfig, makeScenario({ frontmatter: { name: "a" } }), "a");
62
+ writeScenarioCache(cwd, baseConfig, makeScenario({ frontmatter: { name: "b" } }), "b");
63
+ clearCache(cwd, baseConfig, "a");
64
+ assert.equal(loadScenarioCache(cwd, baseConfig, makeScenario({ frontmatter: { name: "a" } })), undefined);
65
+ assert.ok(loadScenarioCache(cwd, baseConfig, makeScenario({ frontmatter: { name: "b" } })));
66
+ clearCache(cwd, baseConfig);
67
+ assert.equal(existsSync(path.join(cwd, ".pqa", "cache")), false);
68
+ rmSync(cwd, { recursive: true, force: true });
69
+ });
70
+ it("ignores stale meta hash on disk without matching scenario", () => {
71
+ const cwd = mkdtempSync(path.join(tmpdir(), "pqa-cache-"));
72
+ const scenario = makeScenario();
73
+ const dir = path.join(cwd, ".pqa", "cache", safeScenarioDirName("example-smoke"));
74
+ mkdirSync(dir, { recursive: true });
75
+ writeFileSync(path.join(dir, "hints.md"), "stale\n");
76
+ writeFileSync(path.join(dir, "meta.json"), `${JSON.stringify({
77
+ scenarioName: "example-smoke",
78
+ contentHash: "deadbeef",
79
+ updatedAt: new Date().toISOString(),
80
+ version: 1,
81
+ passCount: 1,
82
+ })}\n`);
83
+ assert.equal(loadScenarioCache(cwd, baseConfig, scenario), undefined);
84
+ assert.equal(existsSync(dir), false);
85
+ rmSync(cwd, { recursive: true, force: true });
86
+ });
87
+ it("increments passCount on write", () => {
88
+ const cwd = mkdtempSync(path.join(tmpdir(), "pqa-cache-"));
89
+ const scenario = makeScenario();
90
+ writeScenarioCache(cwd, baseConfig, scenario, "v1");
91
+ const dir = path.join(cwd, ".pqa", "cache", safeScenarioDirName("example-smoke"));
92
+ const meta1 = JSON.parse(readFileSync(path.join(dir, "meta.json"), "utf-8"));
93
+ assert.equal(meta1.passCount, 1);
94
+ assert.equal(meta1.contentHash, hashScenarioContent(scenario));
95
+ writeScenarioCache(cwd, baseConfig, scenario, "v2", meta1);
96
+ const meta2 = JSON.parse(readFileSync(path.join(dir, "meta.json"), "utf-8"));
97
+ assert.equal(meta2.passCount, 2);
98
+ rmSync(cwd, { recursive: true, force: true });
99
+ });
100
+ });
101
+ //# sourceMappingURL=store.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.test.js","sourceRoot":"","sources":["../../src/cache/store.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import { type AnalyzeReport } from "../analyze/index.js";
2
+ import type { ScenarioFixProposal } from "../analyze/parse-proposal.js";
3
+ export interface AnalyzeOptions {
4
+ configPath?: string;
5
+ last?: number;
6
+ }
7
+ export interface LlmAnalyzeEntry {
8
+ scenario: string;
9
+ filePath: string;
10
+ proposal: ScenarioFixProposal | null;
11
+ parseError?: string;
12
+ applied?: boolean;
13
+ }
14
+ export interface LlmAnalyzeReport {
15
+ runId: string;
16
+ analyzedAt: string;
17
+ entries: LlmAnalyzeEntry[];
18
+ }
19
+ export declare function executeAnalyze(runIds: string[], options: AnalyzeOptions): Promise<number>;
20
+ export type { AnalyzeReport };
21
+ //# sourceMappingURL=analyze.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze.d.ts","sourceRoot":"","sources":["../../src/cli/analyze.ts"],"names":[],"mappings":"AAIA,OAAO,EAIL,KAAK,aAAa,EACnB,MAAM,qBAAqB,CAAC;AAW7B,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AAOxE,MAAM,WAAW,cAAc;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IACrC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,eAAe,EAAE,CAAC;CAC5B;AAmMD,wBAAsB,cAAc,CAClC,MAAM,EAAE,MAAM,EAAE,EAChB,OAAO,EAAE,cAAc,GACtB,OAAO,CAAC,MAAM,CAAC,CAuBjB;AAED,YAAY,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,148 @@
1
+ import { mkdirSync, writeFileSync } from "node:fs";
2
+ import path from "node:path";
3
+ import chalk from "chalk";
4
+ import ora from "ora";
5
+ import { analyzeRun, loadRunReport, resolveRunDirs, } from "../analyze/index.js";
6
+ import { buildFlakyAnalyzeContext, buildLlmAnalyzeContext, flakyFindingToAnalyzeFinding, } from "../analyze/build-context.js";
7
+ import { compareRuns } from "../analyze/compare-runs.js";
8
+ import { proposeFlakyScenarioFixWithLlm, proposeScenarioFixWithLlm, } from "../analyze/llm-fix.js";
9
+ import { runAnalyzeRepl } from "../analyze/repl.js";
10
+ import { loadConfig, missingLlmApiKey, } from "../config/load.js";
11
+ function analyzeOutputDir(cwd) {
12
+ const ts = new Date().toISOString().replace(/[:.]/g, "-");
13
+ const dir = path.join(cwd, ".pqa", "analyze", ts);
14
+ mkdirSync(dir, { recursive: true });
15
+ return dir;
16
+ }
17
+ async function executeSingleRunAnalyze(runDir, cwd, configPath) {
18
+ const report = analyzeRun(runDir, cwd);
19
+ const runReport = loadRunReport(runDir);
20
+ writeFileSync(path.join(runDir, "analyze.json"), `${JSON.stringify(report, null, 2)}\n`);
21
+ const config = await loadConfig(configPath, cwd);
22
+ if (report.findings.length > 0) {
23
+ const missingKey = missingLlmApiKey(config);
24
+ if (missingKey) {
25
+ throw new Error(missingKey);
26
+ }
27
+ }
28
+ const llmReport = {
29
+ runId: report.runId,
30
+ analyzedAt: new Date().toISOString(),
31
+ entries: [],
32
+ };
33
+ const replEntries = [];
34
+ for (const finding of report.findings) {
35
+ const result = runReport.results.find((r) => r.scenario === finding.scenario);
36
+ if (!result)
37
+ continue;
38
+ const spinner = ora(`LLM analysis: ${finding.scenario}`).start();
39
+ const context = buildLlmAnalyzeContext(finding, result, cwd);
40
+ const llmResult = await proposeScenarioFixWithLlm(config, context, cwd);
41
+ spinner.stop();
42
+ const entry = {
43
+ scenario: finding.scenario,
44
+ filePath: finding.filePath,
45
+ proposal: llmResult.proposal,
46
+ parseError: llmResult.parseError,
47
+ };
48
+ replEntries.push({
49
+ finding,
50
+ proposal: llmResult.proposal,
51
+ parseError: llmResult.parseError,
52
+ });
53
+ llmReport.entries.push(entry);
54
+ }
55
+ writeFileSync(path.join(runDir, "analyze-llm.json"), `${JSON.stringify(llmReport, null, 2)}\n`);
56
+ const replResult = await runAnalyzeRepl({
57
+ heuristicReport: report,
58
+ llmEntries: replEntries,
59
+ cwd,
60
+ });
61
+ for (const entry of llmReport.entries) {
62
+ const target = path.resolve(cwd, entry.filePath);
63
+ entry.applied = replResult.appliedFiles.some((p) => path.resolve(p) === target);
64
+ }
65
+ writeFileSync(path.join(runDir, "analyze-llm.json"), `${JSON.stringify(llmReport, null, 2)}\n`);
66
+ console.log(chalk.dim(`\nReports: ${path.join(runDir, "analyze.json")}, ${path.join(runDir, "analyze-llm.json")}`));
67
+ return 0;
68
+ }
69
+ async function executeMultiRunAnalyze(runDirs, cwd, configPath) {
70
+ const flakyReport = compareRuns(runDirs, cwd);
71
+ const outDir = analyzeOutputDir(cwd);
72
+ writeFileSync(path.join(outDir, "analyze-flaky.json"), `${JSON.stringify(flakyReport, null, 2)}\n`);
73
+ if (flakyReport.findings.length === 0) {
74
+ console.log(chalk.green(`\nNo flaky scenarios across ${flakyReport.runIds.length} run(s).`));
75
+ console.log(chalk.dim(`Report: ${path.join(outDir, "analyze-flaky.json")}`));
76
+ return 0;
77
+ }
78
+ const config = await loadConfig(configPath, cwd);
79
+ const missingKey = missingLlmApiKey(config);
80
+ if (missingKey) {
81
+ throw new Error(missingKey);
82
+ }
83
+ const llmReport = {
84
+ runId: flakyReport.runIds.join(","),
85
+ analyzedAt: new Date().toISOString(),
86
+ entries: [],
87
+ };
88
+ const replEntries = [];
89
+ for (const finding of flakyReport.findings) {
90
+ const spinner = ora(`LLM flaky analysis: ${finding.scenario}`).start();
91
+ const context = buildFlakyAnalyzeContext(finding, runDirs, cwd);
92
+ const llmResult = await proposeFlakyScenarioFixWithLlm(config, context, cwd);
93
+ spinner.stop();
94
+ const analyzeFinding = flakyFindingToAnalyzeFinding(finding);
95
+ const entry = {
96
+ scenario: finding.scenario,
97
+ filePath: finding.filePath,
98
+ proposal: llmResult.proposal,
99
+ parseError: llmResult.parseError,
100
+ };
101
+ replEntries.push({
102
+ finding: analyzeFinding,
103
+ proposal: llmResult.proposal,
104
+ parseError: llmResult.parseError,
105
+ });
106
+ llmReport.entries.push(entry);
107
+ }
108
+ writeFileSync(path.join(outDir, "analyze-llm.json"), `${JSON.stringify(llmReport, null, 2)}\n`);
109
+ const placeholderReport = {
110
+ runId: flakyReport.runIds.join(","),
111
+ analyzedAt: flakyReport.analyzedAt,
112
+ findings: replEntries.map((e) => e.finding),
113
+ };
114
+ const replResult = await runAnalyzeRepl({
115
+ heuristicReport: placeholderReport,
116
+ flakyReport,
117
+ llmEntries: replEntries,
118
+ cwd,
119
+ });
120
+ for (const entry of llmReport.entries) {
121
+ const target = path.resolve(cwd, entry.filePath);
122
+ entry.applied = replResult.appliedFiles.some((p) => path.resolve(p) === target);
123
+ }
124
+ writeFileSync(path.join(outDir, "analyze-llm.json"), `${JSON.stringify(llmReport, null, 2)}\n`);
125
+ console.log(chalk.dim(`\nReports: ${path.join(outDir, "analyze-flaky.json")}, ${path.join(outDir, "analyze-llm.json")}`));
126
+ return 0;
127
+ }
128
+ export async function executeAnalyze(runIds, options) {
129
+ const cwd = process.cwd();
130
+ try {
131
+ if (!process.stdin.isTTY) {
132
+ throw new Error("pqa analyze requires an interactive terminal");
133
+ }
134
+ const runDirs = resolveRunDirs(cwd, runIds, options.last);
135
+ if (runDirs.length === 1) {
136
+ return await executeSingleRunAnalyze(runDirs[0], cwd, options.configPath);
137
+ }
138
+ if (runDirs.length < 2) {
139
+ throw new Error("Multi-run analysis requires at least 2 run sessions");
140
+ }
141
+ return await executeMultiRunAnalyze(runDirs, cwd, options.configPath);
142
+ }
143
+ catch (err) {
144
+ console.error(chalk.red(String(err)));
145
+ return 2;
146
+ }
147
+ }
148
+ //# sourceMappingURL=analyze.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"analyze.js","sourceRoot":"","sources":["../../src/cli/analyze.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { Scenario } from "../types/scenario.js";
2
+ import type { ScenarioResult } from "../types/verdict.js";
3
+ export declare const FAIL_FAST_SKIP_REASON = "Not run (--fail-fast stopped the run)";
4
+ export declare function emptyTranscript(): ScenarioResult["transcript"];
5
+ export declare function createSkippedScenarioResult(scenario: Scenario, reason?: string): ScenarioResult;
6
+ /** Fill holes left when parallel fail-fast stops scheduling new work. */
7
+ export declare function alignScenarioResults(scenarios: Scenario[], results: (ScenarioResult | undefined)[]): ScenarioResult[];
8
+ /**
9
+ * Run `fn` over `items` with at most `limit` in-flight tasks at once.
10
+ * When a task finishes, the next item is started immediately on that slot
11
+ * (worker pool), not in fixed batches of `limit`.
12
+ */
13
+ export declare function mapWithConcurrency<T, R>(items: T[], limit: number, fn: (item: T, index: number) => Promise<R>, options?: {
14
+ failFast?: boolean;
15
+ isFailure?: (result: R) => boolean;
16
+ }): Promise<(R | undefined)[]>;
17
+ //# sourceMappingURL=concurrency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency.d.ts","sourceRoot":"","sources":["../../src/cli/concurrency.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D,eAAO,MAAM,qBAAqB,0CACO,CAAC;AAE1C,wBAAgB,eAAe,IAAI,cAAc,CAAC,YAAY,CAAC,CAE9D;AAED,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,QAAQ,EAClB,MAAM,GAAE,MAA8B,GACrC,cAAc,CAUhB;AAED,yEAAyE;AACzE,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,QAAQ,EAAE,EACrB,OAAO,EAAE,CAAC,cAAc,GAAG,SAAS,CAAC,EAAE,GACtC,cAAc,EAAE,CAQlB;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CAAC,CAAC,EAAE,CAAC,EAC3C,KAAK,EAAE,CAAC,EAAE,EACV,KAAK,EAAE,MAAM,EACb,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,CAAC,CAAC,EAC1C,OAAO,CAAC,EAAE;IACR,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAK,OAAO,CAAC;CACpC,GACA,OAAO,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC,CA0B5B"}
@@ -0,0 +1,56 @@
1
+ export const FAIL_FAST_SKIP_REASON = "Not run (--fail-fast stopped the run)";
2
+ export function emptyTranscript() {
3
+ return { entries: [] };
4
+ }
5
+ export function createSkippedScenarioResult(scenario, reason = FAIL_FAST_SKIP_REASON) {
6
+ return {
7
+ scenario: scenario.frontmatter.name,
8
+ filePath: scenario.filePath,
9
+ status: "skipped",
10
+ durationMs: 0,
11
+ verdict: null,
12
+ transcript: emptyTranscript(),
13
+ error: reason,
14
+ };
15
+ }
16
+ /** Fill holes left when parallel fail-fast stops scheduling new work. */
17
+ export function alignScenarioResults(scenarios, results) {
18
+ return scenarios.map((scenario, index) => {
19
+ const result = results[index];
20
+ if (result !== undefined) {
21
+ return result;
22
+ }
23
+ return createSkippedScenarioResult(scenario);
24
+ });
25
+ }
26
+ /**
27
+ * Run `fn` over `items` with at most `limit` in-flight tasks at once.
28
+ * When a task finishes, the next item is started immediately on that slot
29
+ * (worker pool), not in fixed batches of `limit`.
30
+ */
31
+ export async function mapWithConcurrency(items, limit, fn, options) {
32
+ if (items.length === 0)
33
+ return [];
34
+ const concurrency = Number.isFinite(limit)
35
+ ? Math.min(limit, items.length)
36
+ : items.length;
37
+ const results = new Array(items.length);
38
+ const pendingIndices = Array.from({ length: items.length }, (_, i) => i);
39
+ let stopScheduling = false;
40
+ async function worker() {
41
+ while (true) {
42
+ if (options?.failFast && stopScheduling)
43
+ return;
44
+ const index = pendingIndices.shift();
45
+ if (index === undefined)
46
+ return;
47
+ results[index] = await fn(items[index], index);
48
+ if (options?.failFast && options.isFailure?.(results[index])) {
49
+ stopScheduling = true;
50
+ }
51
+ }
52
+ }
53
+ await Promise.all(Array.from({ length: concurrency }, () => worker()));
54
+ return results;
55
+ }
56
+ //# sourceMappingURL=concurrency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency.js","sourceRoot":"","sources":["../../src/cli/concurrency.ts"],"names":[],"mappings":"AAGA,MAAM,CAAC,MAAM,qBAAqB,GAChC,uCAAuC,CAAC;AAE1C,MAAM,UAAU,eAAe;IAC7B,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,2BAA2B,CACzC,QAAkB,EAClB,SAAiB,qBAAqB;IAEtC,OAAO;QACL,QAAQ,EAAE,QAAQ,CAAC,WAAW,CAAC,IAAI;QACnC,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,MAAM,EAAE,SAAS;QACjB,UAAU,EAAE,CAAC;QACb,OAAO,EAAE,IAAI;QACb,UAAU,EAAE,eAAe,EAAE;QAC7B,KAAK,EAAE,MAAM;KACd,CAAC;AACJ,CAAC;AAED,yEAAyE;AACzE,MAAM,UAAU,oBAAoB,CAClC,SAAqB,EACrB,OAAuC;IAEvC,OAAO,SAAS,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE;QACvC,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC9B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YACzB,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,OAAO,2BAA2B,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,KAAU,EACV,KAAa,EACb,EAA0C,EAC1C,OAGC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAElC,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC;QACxC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC;QAC/B,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC;IACjB,MAAM,OAAO,GAAsB,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3D,MAAM,cAAc,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC;IACzE,IAAI,cAAc,GAAG,KAAK,CAAC;IAE3B,KAAK,UAAU,MAAM;QACnB,OAAO,IAAI,EAAE,CAAC;YACZ,IAAI,OAAO,EAAE,QAAQ,IAAI,cAAc;gBAAE,OAAO;YAChD,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,EAAE,CAAC;YACrC,IAAI,KAAK,KAAK,SAAS;gBAAE,OAAO;YAChC,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,KAAK,CAAC,KAAK,CAAE,EAAE,KAAK,CAAC,CAAC;YAChD,IAAI,OAAO,EAAE,QAAQ,IAAI,OAAO,CAAC,SAAS,EAAE,CAAC,OAAO,CAAC,KAAK,CAAE,CAAC,EAAE,CAAC;gBAC9D,cAAc,GAAG,IAAI,CAAC;YACxB,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CACpD,CAAC;IACF,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=concurrency.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"concurrency.test.d.ts","sourceRoot":"","sources":["../../src/cli/concurrency.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,74 @@
1
+ import assert from "node:assert/strict";
2
+ import { describe, it } from "node:test";
3
+ import { FAIL_FAST_SKIP_REASON, alignScenarioResults, mapWithConcurrency, } from "./concurrency.js";
4
+ function stubScenario(name) {
5
+ return {
6
+ filePath: `scenarios/${name}.md`,
7
+ frontmatter: { name, tags: [], url: "http://localhost" },
8
+ goal: "",
9
+ steps: "",
10
+ then: [],
11
+ rawCheckpoints: [],
12
+ checkpoints: [],
13
+ skills: [],
14
+ };
15
+ }
16
+ describe("mapWithConcurrency slot pool", () => {
17
+ it("starts the next item as soon as a worker slot frees", async () => {
18
+ const delays = [20, 80, 20];
19
+ const started = [];
20
+ await mapWithConcurrency([0, 1, 2], 2, async (item) => {
21
+ started.push(item);
22
+ await new Promise((r) => setTimeout(r, delays[item]));
23
+ return item;
24
+ });
25
+ assert.deepEqual(started.slice(0, 2).sort(), [0, 1]);
26
+ assert.equal(started[2], 2);
27
+ assert.ok(started.indexOf(2) < started.length);
28
+ assert.equal(started.length, 3);
29
+ });
30
+ });
31
+ describe("mapWithConcurrency fail-fast", () => {
32
+ it("leaves undefined slots for work never scheduled", async () => {
33
+ const results = await mapWithConcurrency([0, 1, 2, 3], 1, async (item) => {
34
+ if (item === 0)
35
+ return "fail";
36
+ return "pass";
37
+ }, {
38
+ failFast: true,
39
+ isFailure: (r) => r === "fail",
40
+ });
41
+ assert.equal(results[0], "fail");
42
+ assert.equal(results[1], undefined);
43
+ assert.equal(results[2], undefined);
44
+ assert.equal(results[3], undefined);
45
+ });
46
+ });
47
+ describe("alignScenarioResults", () => {
48
+ it("replaces undefined slots with skipped scenario results", () => {
49
+ const scenarios = [
50
+ stubScenario("alpha"),
51
+ stubScenario("beta"),
52
+ stubScenario("gamma"),
53
+ ];
54
+ const aligned = alignScenarioResults(scenarios, [
55
+ {
56
+ scenario: "alpha",
57
+ filePath: scenarios[0].filePath,
58
+ status: "fail",
59
+ durationMs: 1,
60
+ verdict: null,
61
+ transcript: { entries: [] },
62
+ },
63
+ undefined,
64
+ undefined,
65
+ ]);
66
+ assert.equal(aligned.length, 3);
67
+ assert.equal(aligned[0].status, "fail");
68
+ assert.equal(aligned[1].status, "skipped");
69
+ assert.equal(aligned[2].status, "skipped");
70
+ assert.equal(aligned[1].error, FAIL_FAST_SKIP_REASON);
71
+ assert.equal(aligned[1].scenario, "beta");
72
+ });
73
+ });
74
+ //# sourceMappingURL=concurrency.test.js.map