swipium 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 (387) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +295 -0
  3. package/dist/appMap/automationLink.js +74 -0
  4. package/dist/appMap/automationLink.js.map +1 -0
  5. package/dist/appMap/build.js +193 -0
  6. package/dist/appMap/build.js.map +1 -0
  7. package/dist/appMap/codeIndex.js +73 -0
  8. package/dist/appMap/codeIndex.js.map +1 -0
  9. package/dist/appMap/featureModel.js +83 -0
  10. package/dist/appMap/featureModel.js.map +1 -0
  11. package/dist/appMap/firstRunApply.js +131 -0
  12. package/dist/appMap/firstRunApply.js.map +1 -0
  13. package/dist/appMap/fsWalk.js +75 -0
  14. package/dist/appMap/fsWalk.js.map +1 -0
  15. package/dist/appMap/issues.js +227 -0
  16. package/dist/appMap/issues.js.map +1 -0
  17. package/dist/appMap/migrations.js +87 -0
  18. package/dist/appMap/migrations.js.map +1 -0
  19. package/dist/appMap/prelaunch.js +66 -0
  20. package/dist/appMap/prelaunch.js.map +1 -0
  21. package/dist/appMap/projectRegistry.js +70 -0
  22. package/dist/appMap/projectRegistry.js.map +1 -0
  23. package/dist/appMap/provenance.js +52 -0
  24. package/dist/appMap/provenance.js.map +1 -0
  25. package/dist/appMap/query.js +118 -0
  26. package/dist/appMap/query.js.map +1 -0
  27. package/dist/appMap/runtimeMerge.js +207 -0
  28. package/dist/appMap/runtimeMerge.js.map +1 -0
  29. package/dist/appMap/schema.js +65 -0
  30. package/dist/appMap/schema.js.map +1 -0
  31. package/dist/appMap/screenMatch.js +75 -0
  32. package/dist/appMap/screenMatch.js.map +1 -0
  33. package/dist/appMap/staticScan.js +614 -0
  34. package/dist/appMap/staticScan.js.map +1 -0
  35. package/dist/appMap/store.js +173 -0
  36. package/dist/appMap/store.js.map +1 -0
  37. package/dist/appMap/tsAstScan.js +184 -0
  38. package/dist/appMap/tsAstScan.js.map +1 -0
  39. package/dist/artifacts/bundletool.js +199 -0
  40. package/dist/artifacts/bundletool.js.map +1 -0
  41. package/dist/artifacts/resolve.js +388 -0
  42. package/dist/artifacts/resolve.js.map +1 -0
  43. package/dist/automationGen/appiumModel.js +129 -0
  44. package/dist/automationGen/appiumModel.js.map +1 -0
  45. package/dist/automationGen/ciEmitter.js +80 -0
  46. package/dist/automationGen/ciEmitter.js.map +1 -0
  47. package/dist/automationGen/jsEmitter.js +440 -0
  48. package/dist/automationGen/jsEmitter.js.map +1 -0
  49. package/dist/automationGen/packagePatch.js +56 -0
  50. package/dist/automationGen/packagePatch.js.map +1 -0
  51. package/dist/automationGen/projectProfile.js +317 -0
  52. package/dist/automationGen/projectProfile.js.map +1 -0
  53. package/dist/automationGen/pythonEmitter.js +386 -0
  54. package/dist/automationGen/pythonEmitter.js.map +1 -0
  55. package/dist/automationGen/readmeEmitter.js +66 -0
  56. package/dist/automationGen/readmeEmitter.js.map +1 -0
  57. package/dist/automationGen/suitePlan.js +94 -0
  58. package/dist/automationGen/suitePlan.js.map +1 -0
  59. package/dist/automationGen/validation.js +150 -0
  60. package/dist/automationGen/validation.js.map +1 -0
  61. package/dist/build/parseBuildLog.js +119 -0
  62. package/dist/build/parseBuildLog.js.map +1 -0
  63. package/dist/build/plan.js +150 -0
  64. package/dist/build/plan.js.map +1 -0
  65. package/dist/ci/preflight.js +85 -0
  66. package/dist/ci/preflight.js.map +1 -0
  67. package/dist/cli/init.js +105 -0
  68. package/dist/cli/init.js.map +1 -0
  69. package/dist/cli/scan.js +85 -0
  70. package/dist/cli/scan.js.map +1 -0
  71. package/dist/cli/suite.js +85 -0
  72. package/dist/cli/suite.js.map +1 -0
  73. package/dist/cli/verify.js +62 -0
  74. package/dist/cli/verify.js.map +1 -0
  75. package/dist/consent/consent.js +43 -0
  76. package/dist/consent/consent.js.map +1 -0
  77. package/dist/context/detect.js +156 -0
  78. package/dist/context/detect.js.map +1 -0
  79. package/dist/context/findApps.js +198 -0
  80. package/dist/context/findApps.js.map +1 -0
  81. package/dist/context/projectRoot.js +41 -0
  82. package/dist/context/projectRoot.js.map +1 -0
  83. package/dist/context/scan.js +167 -0
  84. package/dist/context/scan.js.map +1 -0
  85. package/dist/core/target.js +115 -0
  86. package/dist/core/target.js.map +1 -0
  87. package/dist/core/targetPlan.js +140 -0
  88. package/dist/core/targetPlan.js.map +1 -0
  89. package/dist/drivers/DirectDriver.js +228 -0
  90. package/dist/drivers/DirectDriver.js.map +1 -0
  91. package/dist/drivers/Driver.js +4 -0
  92. package/dist/drivers/Driver.js.map +1 -0
  93. package/dist/drivers/SimctlDriver.js +127 -0
  94. package/dist/drivers/SimctlDriver.js.map +1 -0
  95. package/dist/drivers/WdaDriver.js +250 -0
  96. package/dist/drivers/WdaDriver.js.map +1 -0
  97. package/dist/explore/candidates.js +93 -0
  98. package/dist/explore/candidates.js.map +1 -0
  99. package/dist/explore/graph.js +116 -0
  100. package/dist/explore/graph.js.map +1 -0
  101. package/dist/explore/memory.js +35 -0
  102. package/dist/explore/memory.js.map +1 -0
  103. package/dist/explore/planner.js +105 -0
  104. package/dist/explore/planner.js.map +1 -0
  105. package/dist/explore/policy.js +85 -0
  106. package/dist/explore/policy.js.map +1 -0
  107. package/dist/explore/runner.js +475 -0
  108. package/dist/explore/runner.js.map +1 -0
  109. package/dist/explore/signatures.js +35 -0
  110. package/dist/explore/signatures.js.map +1 -0
  111. package/dist/explore/suite.js +55 -0
  112. package/dist/explore/suite.js.map +1 -0
  113. package/dist/featureTesting/executionBootstrap.js +140 -0
  114. package/dist/featureTesting/executionBootstrap.js.map +1 -0
  115. package/dist/firstRun/authStateMachine.js +83 -0
  116. package/dist/firstRun/authStateMachine.js.map +1 -0
  117. package/dist/firstRun/classifyScreen.js +201 -0
  118. package/dist/firstRun/classifyScreen.js.map +1 -0
  119. package/dist/firstRun/firstRunPlanner.js +207 -0
  120. package/dist/firstRun/firstRunPlanner.js.map +1 -0
  121. package/dist/firstRun/firstRunRunner.js +331 -0
  122. package/dist/firstRun/firstRunRunner.js.map +1 -0
  123. package/dist/firstRun/generatedDataPolicy.js +215 -0
  124. package/dist/firstRun/generatedDataPolicy.js.map +1 -0
  125. package/dist/firstRun/inputPlanner.js +67 -0
  126. package/dist/firstRun/inputPlanner.js.map +1 -0
  127. package/dist/firstRun/onboardingStateMachine.js +46 -0
  128. package/dist/firstRun/onboardingStateMachine.js.map +1 -0
  129. package/dist/firstRun/paywallPolicy.js +54 -0
  130. package/dist/firstRun/paywallPolicy.js.map +1 -0
  131. package/dist/firstRun/types.js +7 -0
  132. package/dist/firstRun/types.js.map +1 -0
  133. package/dist/fixtures/catalog.js +131 -0
  134. package/dist/fixtures/catalog.js.map +1 -0
  135. package/dist/flows/discover.js +18 -0
  136. package/dist/flows/discover.js.map +1 -0
  137. package/dist/flows/generate.js +211 -0
  138. package/dist/flows/generate.js.map +1 -0
  139. package/dist/flows/lint.js +97 -0
  140. package/dist/flows/lint.js.map +1 -0
  141. package/dist/flows/pack.js +68 -0
  142. package/dist/flows/pack.js.map +1 -0
  143. package/dist/flows/run.js +738 -0
  144. package/dist/flows/run.js.map +1 -0
  145. package/dist/flows/schema.js +240 -0
  146. package/dist/flows/schema.js.map +1 -0
  147. package/dist/flows/seedExec.js +108 -0
  148. package/dist/flows/seedExec.js.map +1 -0
  149. package/dist/flows/templates.js +155 -0
  150. package/dist/flows/templates.js.map +1 -0
  151. package/dist/flows/waitGuards.js +12 -0
  152. package/dist/flows/waitGuards.js.map +1 -0
  153. package/dist/index.js +33 -0
  154. package/dist/index.js.map +1 -0
  155. package/dist/ios/signing.js +182 -0
  156. package/dist/ios/signing.js.map +1 -0
  157. package/dist/issues/classify.js +186 -0
  158. package/dist/issues/classify.js.map +1 -0
  159. package/dist/issues/fingerprint.js +130 -0
  160. package/dist/issues/fingerprint.js.map +1 -0
  161. package/dist/issues/index.js +240 -0
  162. package/dist/issues/index.js.map +1 -0
  163. package/dist/issues/metrics.js +155 -0
  164. package/dist/issues/metrics.js.map +1 -0
  165. package/dist/issues/recurrence.js +193 -0
  166. package/dist/issues/recurrence.js.map +1 -0
  167. package/dist/issues/report.js +110 -0
  168. package/dist/issues/report.js.map +1 -0
  169. package/dist/issues/reportBridge.js +119 -0
  170. package/dist/issues/reportBridge.js.map +1 -0
  171. package/dist/issues/schema.js +90 -0
  172. package/dist/issues/schema.js.map +1 -0
  173. package/dist/issues/sourceRevision.js +108 -0
  174. package/dist/issues/sourceRevision.js.map +1 -0
  175. package/dist/issues/store.js +155 -0
  176. package/dist/issues/store.js.map +1 -0
  177. package/dist/lib/android.js +278 -0
  178. package/dist/lib/android.js.map +1 -0
  179. package/dist/lib/commandTemplate.js +55 -0
  180. package/dist/lib/commandTemplate.js.map +1 -0
  181. package/dist/lib/coordSpace.js +23 -0
  182. package/dist/lib/coordSpace.js.map +1 -0
  183. package/dist/lib/device.js +87 -0
  184. package/dist/lib/device.js.map +1 -0
  185. package/dist/lib/gitignore.js +22 -0
  186. package/dist/lib/gitignore.js.map +1 -0
  187. package/dist/lib/image.js +97 -0
  188. package/dist/lib/image.js.map +1 -0
  189. package/dist/lib/logger.js +8 -0
  190. package/dist/lib/logger.js.map +1 -0
  191. package/dist/lib/metroState.js +45 -0
  192. package/dist/lib/metroState.js.map +1 -0
  193. package/dist/lib/needsInput.js +201 -0
  194. package/dist/lib/needsInput.js.map +1 -0
  195. package/dist/lib/png.js +103 -0
  196. package/dist/lib/png.js.map +1 -0
  197. package/dist/lib/redact.js +21 -0
  198. package/dist/lib/redact.js.map +1 -0
  199. package/dist/lib/result.js +87 -0
  200. package/dist/lib/result.js.map +1 -0
  201. package/dist/lib/schemaHash.js +65 -0
  202. package/dist/lib/schemaHash.js.map +1 -0
  203. package/dist/lib/sensitive.js +13 -0
  204. package/dist/lib/sensitive.js.map +1 -0
  205. package/dist/lib/simctl.js +149 -0
  206. package/dist/lib/simctl.js.map +1 -0
  207. package/dist/lib/spawn.js +144 -0
  208. package/dist/lib/spawn.js.map +1 -0
  209. package/dist/lib/wda.js +347 -0
  210. package/dist/lib/wda.js.map +1 -0
  211. package/dist/lib/wdaConfig.js +69 -0
  212. package/dist/lib/wdaConfig.js.map +1 -0
  213. package/dist/lib/wdaTune.js +58 -0
  214. package/dist/lib/wdaTune.js.map +1 -0
  215. package/dist/oracle/auth.js +22 -0
  216. package/dist/oracle/auth.js.map +1 -0
  217. package/dist/oracle/failures.js +193 -0
  218. package/dist/oracle/failures.js.map +1 -0
  219. package/dist/oracle/health.js +123 -0
  220. package/dist/oracle/health.js.map +1 -0
  221. package/dist/oracle/record.js +36 -0
  222. package/dist/oracle/record.js.map +1 -0
  223. package/dist/orchestration/envelope.js +52 -0
  224. package/dist/orchestration/envelope.js.map +1 -0
  225. package/dist/orchestration/goal.js +98 -0
  226. package/dist/orchestration/goal.js.map +1 -0
  227. package/dist/plan/plan.js +124 -0
  228. package/dist/plan/plan.js.map +1 -0
  229. package/dist/prompts/index.js +63 -0
  230. package/dist/prompts/index.js.map +1 -0
  231. package/dist/report/artifactManifest.js +44 -0
  232. package/dist/report/artifactManifest.js.map +1 -0
  233. package/dist/report/coverage.js +60 -0
  234. package/dist/report/coverage.js.map +1 -0
  235. package/dist/report/evidence.js +84 -0
  236. package/dist/report/evidence.js.map +1 -0
  237. package/dist/report/export.js +447 -0
  238. package/dist/report/export.js.map +1 -0
  239. package/dist/report/flake.js +61 -0
  240. package/dist/report/flake.js.map +1 -0
  241. package/dist/report/history.js +564 -0
  242. package/dist/report/history.js.map +1 -0
  243. package/dist/report/policy.js +98 -0
  244. package/dist/report/policy.js.map +1 -0
  245. package/dist/report/qaLevel.js +96 -0
  246. package/dist/report/qaLevel.js.map +1 -0
  247. package/dist/report/readiness.js +213 -0
  248. package/dist/report/readiness.js.map +1 -0
  249. package/dist/report/summary.js +42 -0
  250. package/dist/report/summary.js.map +1 -0
  251. package/dist/report/testCatalog.js +93 -0
  252. package/dist/report/testCatalog.js.map +1 -0
  253. package/dist/report/timing.js +37 -0
  254. package/dist/report/timing.js.map +1 -0
  255. package/dist/server.js +180 -0
  256. package/dist/server.js.map +1 -0
  257. package/dist/services/automationGenerate.js +60 -0
  258. package/dist/services/automationGenerate.js.map +1 -0
  259. package/dist/services/build.js +66 -0
  260. package/dist/services/build.js.map +1 -0
  261. package/dist/services/preflight.js +51 -0
  262. package/dist/services/preflight.js.map +1 -0
  263. package/dist/services/prepareAndroid.js +183 -0
  264. package/dist/services/prepareAndroid.js.map +1 -0
  265. package/dist/services/prepareIos.js +162 -0
  266. package/dist/services/prepareIos.js.map +1 -0
  267. package/dist/services/report.js +537 -0
  268. package/dist/services/report.js.map +1 -0
  269. package/dist/services/smoke.js +120 -0
  270. package/dist/services/smoke.js.map +1 -0
  271. package/dist/services/suiteGenerate.js +123 -0
  272. package/dist/services/suiteGenerate.js.map +1 -0
  273. package/dist/services/testSuiteKnowledge.js +150 -0
  274. package/dist/services/testSuiteKnowledge.js.map +1 -0
  275. package/dist/session/attach.js +47 -0
  276. package/dist/session/attach.js.map +1 -0
  277. package/dist/session/progress.js +56 -0
  278. package/dist/session/progress.js.map +1 -0
  279. package/dist/session/store.js +329 -0
  280. package/dist/session/store.js.map +1 -0
  281. package/dist/snapshot/overlays.js +132 -0
  282. package/dist/snapshot/overlays.js.map +1 -0
  283. package/dist/snapshot/parse.js +204 -0
  284. package/dist/snapshot/parse.js.map +1 -0
  285. package/dist/snapshot/present.js +12 -0
  286. package/dist/snapshot/present.js.map +1 -0
  287. package/dist/snapshot/settle.js +36 -0
  288. package/dist/snapshot/settle.js.map +1 -0
  289. package/dist/state/profile.js +318 -0
  290. package/dist/state/profile.js.map +1 -0
  291. package/dist/suite/compile.js +176 -0
  292. package/dist/suite/compile.js.map +1 -0
  293. package/dist/suite/lint.js +45 -0
  294. package/dist/suite/lint.js.map +1 -0
  295. package/dist/suite/pom.js +285 -0
  296. package/dist/suite/pom.js.map +1 -0
  297. package/dist/suite/testcase.js +87 -0
  298. package/dist/suite/testcase.js.map +1 -0
  299. package/dist/testSuite/generator.js +222 -0
  300. package/dist/testSuite/generator.js.map +1 -0
  301. package/dist/testSuite/history.js +44 -0
  302. package/dist/testSuite/history.js.map +1 -0
  303. package/dist/testSuite/issueLinks.js +96 -0
  304. package/dist/testSuite/issueLinks.js.map +1 -0
  305. package/dist/testSuite/merge.js +190 -0
  306. package/dist/testSuite/merge.js.map +1 -0
  307. package/dist/testSuite/schema.js +86 -0
  308. package/dist/testSuite/schema.js.map +1 -0
  309. package/dist/testSuite/store.js +116 -0
  310. package/dist/testSuite/store.js.map +1 -0
  311. package/dist/testSuite/traceability.js +55 -0
  312. package/dist/testSuite/traceability.js.map +1 -0
  313. package/dist/tools/act.js +457 -0
  314. package/dist/tools/act.js.map +1 -0
  315. package/dist/tools/agent.js +225 -0
  316. package/dist/tools/agent.js.map +1 -0
  317. package/dist/tools/appMap.js +317 -0
  318. package/dist/tools/appMap.js.map +1 -0
  319. package/dist/tools/assertVisual.js +74 -0
  320. package/dist/tools/assertVisual.js.map +1 -0
  321. package/dist/tools/automationGenerate.js +394 -0
  322. package/dist/tools/automationGenerate.js.map +1 -0
  323. package/dist/tools/capabilities.js +114 -0
  324. package/dist/tools/capabilities.js.map +1 -0
  325. package/dist/tools/clearOverlay.js +150 -0
  326. package/dist/tools/clearOverlay.js.map +1 -0
  327. package/dist/tools/detectContext.js +41 -0
  328. package/dist/tools/detectContext.js.map +1 -0
  329. package/dist/tools/doctor.js +116 -0
  330. package/dist/tools/doctor.js.map +1 -0
  331. package/dist/tools/explore.js +289 -0
  332. package/dist/tools/explore.js.map +1 -0
  333. package/dist/tools/firstRun.js +136 -0
  334. package/dist/tools/firstRun.js.map +1 -0
  335. package/dist/tools/flow.js +331 -0
  336. package/dist/tools/flow.js.map +1 -0
  337. package/dist/tools/flowGenerate.js +55 -0
  338. package/dist/tools/flowGenerate.js.map +1 -0
  339. package/dist/tools/getArtifact.js +39 -0
  340. package/dist/tools/getArtifact.js.map +1 -0
  341. package/dist/tools/health.js +41 -0
  342. package/dist/tools/health.js.map +1 -0
  343. package/dist/tools/ios.js +492 -0
  344. package/dist/tools/ios.js.map +1 -0
  345. package/dist/tools/jobs.js +20 -0
  346. package/dist/tools/jobs.js.map +1 -0
  347. package/dist/tools/network.js +50 -0
  348. package/dist/tools/network.js.map +1 -0
  349. package/dist/tools/note.js +69 -0
  350. package/dist/tools/note.js.map +1 -0
  351. package/dist/tools/plan.js +49 -0
  352. package/dist/tools/plan.js.map +1 -0
  353. package/dist/tools/prepareIosTarget.js +99 -0
  354. package/dist/tools/prepareIosTarget.js.map +1 -0
  355. package/dist/tools/prepareTarget.js +257 -0
  356. package/dist/tools/prepareTarget.js.map +1 -0
  357. package/dist/tools/report.js +42 -0
  358. package/dist/tools/report.js.map +1 -0
  359. package/dist/tools/screenRecord.js +24 -0
  360. package/dist/tools/screenRecord.js.map +1 -0
  361. package/dist/tools/screenshot.js +63 -0
  362. package/dist/tools/screenshot.js.map +1 -0
  363. package/dist/tools/smoke.js +39 -0
  364. package/dist/tools/smoke.js.map +1 -0
  365. package/dist/tools/snapshot.js +129 -0
  366. package/dist/tools/snapshot.js.map +1 -0
  367. package/dist/tools/startSession.js +169 -0
  368. package/dist/tools/startSession.js.map +1 -0
  369. package/dist/tools/state.js +87 -0
  370. package/dist/tools/state.js.map +1 -0
  371. package/dist/tools/suite.js +412 -0
  372. package/dist/tools/suite.js.map +1 -0
  373. package/dist/tools/testThis.js +774 -0
  374. package/dist/tools/testThis.js.map +1 -0
  375. package/dist/tools/wda.js +477 -0
  376. package/dist/tools/wda.js.map +1 -0
  377. package/dist/version.js +62 -0
  378. package/dist/version.js.map +1 -0
  379. package/dist/visual/ocr.js +72 -0
  380. package/dist/visual/ocr.js.map +1 -0
  381. package/dist/visual/provider.js +75 -0
  382. package/dist/visual/provider.js.map +1 -0
  383. package/docs/README.md +19 -0
  384. package/docs/assets/swipium-lockup-ink-on-light.png +0 -0
  385. package/docs/mcp-server.md +135 -0
  386. package/docs/tools.md +130 -0
  387. package/package.json +70 -0
@@ -0,0 +1,110 @@
1
+ // SWIPIUM Issue Log — fold issue memory into reports (SWIPIUM-REQ-07 "Report Changes").
2
+ //
3
+ // Builds the `issues` section of a QA report from the derived index, and renders the Markdown
4
+ // "Issue Memory" block. PURE — takes records + now, returns data/strings.
5
+ import { APP_BUG_CATEGORIES, combineReleaseImpact, defaultReleaseImpact, } from './schema.js';
6
+ /**
7
+ * Build the report issues section.
8
+ * @param records all index records for the app/project
9
+ * @param runIssueIds ids touched in THIS run (so "new/recurring" reflect this run, not all history)
10
+ * @param verifiedFixedIssueIds ids whose fix was VERIFIED this run by passing evidence (REQ-08). Only
11
+ * these are reported as "fixed issues verified this run". When omitted AND no runIssueIds is given
12
+ * (whole-history view, e.g. qa_issue_log) all fixed issues are listed historically.
13
+ */
14
+ export function buildReportIssuesSection(records, runIssueIds, verifiedFixedIssueIds) {
15
+ const inRun = (r) => !runIssueIds || runIssueIds.has(r.issueId);
16
+ const newIssues = records.filter((r) => inRun(r) && (r.state === 'open' || r.state === 'observed_again') && r.observationCount <= 1 && !r.lastRecurrenceMessage);
17
+ const openIssues = records.filter((r) => inRun(r) && (r.state === 'open' || r.state === 'observed_again'));
18
+ const recurringIssues = records.filter((r) => inRun(r) && (r.state === 'reopened' || Boolean(r.lastRecurrenceMessage)));
19
+ // "Verified this run" requires CURRENT-RUN pass evidence (a verified_fixed linked_run). REQ-08:
20
+ // honest fix verification. When a verification set is supplied, only those fixed issues count; when
21
+ // a run scope is supplied but no verification set, nothing is claimed verified; with neither (a
22
+ // whole-history view) all fixed issues are listed.
23
+ const fixedIssuesVerified = records.filter((r) => r.state === 'fixed' &&
24
+ (verifiedFixedIssueIds ? verifiedFixedIssueIds.has(r.issueId) : runIssueIds ? false : true));
25
+ const knownNoise = records.filter((r) => r.state === 'expected_environment_noise' || r.state === 'suppressed' || r.category === 'environment_noise');
26
+ const hardGates = records.filter((r) => inRun(r) && r.category === 'hard_gate');
27
+ const improvements = records.filter((r) => inRun(r) && (r.category === 'improvement' || r.category === 'accessibility_readiness'));
28
+ // Release impact: real, non-suppressed app defects + store/security issues drive the gate.
29
+ const impacts = [];
30
+ for (const r of records) {
31
+ if (!inRun(r))
32
+ continue;
33
+ if (r.state === 'suppressed' || r.state === 'expected_environment_noise' || r.state === 'fixed')
34
+ continue;
35
+ if (APP_BUG_CATEGORIES.includes(r.category) || r.category === 'security_privacy' || r.category === 'store_compliance' || r.category === 'improvement' || r.category === 'accessibility_readiness' || r.category === 'hard_gate') {
36
+ impacts.push(defaultReleaseImpact(r.category, r.severity));
37
+ }
38
+ }
39
+ const releaseImpact = combineReleaseImpact(impacts);
40
+ return {
41
+ summary: {
42
+ newOpen: openIssues.length,
43
+ recurring: recurringIssues.length,
44
+ fixedStillPassing: fixedIssuesVerified.length,
45
+ suppressed: records.filter((r) => r.state === 'suppressed').length,
46
+ environmentNoise: records.filter((r) => r.state === 'expected_environment_noise' || r.category === 'environment_noise').length,
47
+ hardGates: hardGates.length,
48
+ },
49
+ releaseImpact,
50
+ newIssues,
51
+ recurringIssues,
52
+ fixedIssuesVerified,
53
+ knownNoise,
54
+ hardGates,
55
+ improvements,
56
+ };
57
+ }
58
+ /** Render the Markdown "Issue Memory" block (spec §Report Changes example). */
59
+ export function issuesSectionToMarkdown(section) {
60
+ const s = section.summary;
61
+ const lines = [];
62
+ lines.push('## Issue Memory');
63
+ lines.push('');
64
+ lines.push('| Status | Count |');
65
+ lines.push('| --- | ---: |');
66
+ lines.push(`| New / open issues | ${s.newOpen} |`);
67
+ lines.push(`| Recurring (regressed) issues | ${s.recurring} |`);
68
+ lines.push(`| Known environment noise | ${s.environmentNoise} |`);
69
+ lines.push(`| Suppressed | ${s.suppressed} |`);
70
+ lines.push(`| Hard gates | ${s.hardGates} |`);
71
+ lines.push(`| Fixed issues still passing | ${s.fixedStillPassing} |`);
72
+ lines.push('');
73
+ lines.push(`Release impact: **${section.releaseImpact.toUpperCase()}**`);
74
+ const blockingBugs = section.newIssues.filter((r) => r.category === 'blocker_app_bug' || (r.category === 'app_bug' && (r.severity === 'blocker' || r.severity === 'high')));
75
+ if (blockingBugs.length) {
76
+ lines.push('', '### Blocking App Bugs');
77
+ for (const r of blockingBugs)
78
+ lines.push(`- \`${r.issueId}\` (${r.severity}): ${r.summary}`);
79
+ }
80
+ if (section.recurringIssues.length) {
81
+ lines.push('', '### Recurring Issues');
82
+ for (const r of section.recurringIssues) {
83
+ lines.push(`- \`${r.issueId}\`: ${r.summary}.`);
84
+ if (r.lastRecurrenceMessage)
85
+ lines.push(` ${r.lastRecurrenceMessage}`);
86
+ }
87
+ }
88
+ if (section.hardGates.length) {
89
+ lines.push('', '### Hard Gates');
90
+ for (const r of section.hardGates)
91
+ lines.push(`- \`${r.issueId}\`: ${r.summary} (workflow gated, not an app bug).`);
92
+ }
93
+ if (section.knownNoise.length) {
94
+ lines.push('', '### Environment Noise');
95
+ for (const r of section.knownNoise)
96
+ lines.push(`- \`${r.issueId}\`: ${r.summary}${r.suppressionReason ? ` (suppressed: ${r.suppressionReason})` : ''}.`);
97
+ }
98
+ if (section.improvements.length) {
99
+ lines.push('', '### Improvements & Precautions');
100
+ for (const r of section.improvements)
101
+ lines.push(`- \`${r.issueId}\`: ${r.summary}.`);
102
+ }
103
+ if (section.fixedIssuesVerified.length) {
104
+ lines.push('', '### Fixed Issues Verified This Run');
105
+ for (const r of section.fixedIssuesVerified)
106
+ lines.push(`- \`${r.issueId}\`: ${r.summary}${r.fixedInCommit ? ` (fixed in \`${r.fixedInCommit}\`)` : ''}.`);
107
+ }
108
+ return lines.join('\n');
109
+ }
110
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/issues/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,119 @@
1
+ // SWIPIUM Issue Log — report integration bridge (SWIPIUM-REQ-07 "Integration Points → Reports").
2
+ //
3
+ // Converts a finished run's health findings + structured test outcomes into normalized issue
4
+ // observations, records them in the durable ledger (so recurrence works across runs), and returns
5
+ // the report `issues` section + recurrence messages. The health oracle stays observation-only; this
6
+ // bridge + src/issues/classify.ts own category/severity/state.
7
+ //
8
+ // Best-effort: the caller wraps this in try/catch so report generation never fails because of the
9
+ // ledger. Inputs are plain shapes (not Session) so this stays unit-testable.
10
+ import { recordObservation } from './index.js';
11
+ import { getIndex } from './store.js';
12
+ import { buildReportIssuesSection } from './report.js';
13
+ import { isIssueCategory } from './schema.js';
14
+ const BILLING_HINTS = [
15
+ ['revenuecat', /revenuecat/i],
16
+ ['storekit', /storekit/i],
17
+ ['google_play_billing', /billing_unavailable|google play billing|play billing/i],
18
+ ];
19
+ function detectSubsystem(text) {
20
+ for (const [name, re] of BILLING_HINTS)
21
+ if (re.test(text))
22
+ return name;
23
+ return undefined;
24
+ }
25
+ function findingToObservation(f) {
26
+ const subsystem = detectSubsystem(`${f.detail} ${f.evidence ?? ''}`);
27
+ return {
28
+ title: `${f.kind}${f.screen ? ` on ${f.screen}` : ''}`,
29
+ summary: f.detail.slice(0, 200),
30
+ failureCode: f.failureCode,
31
+ screenPurpose: f.screen,
32
+ visibleText: f.evidence,
33
+ subsystem,
34
+ };
35
+ }
36
+ /** Infer a screen purpose from a workflow/reason so the classifier can resolve gate-style notes. */
37
+ function inferScreenPurpose(n) {
38
+ const hay = `${n.workflow} ${n.reason ?? ''}`.toLowerCase();
39
+ if (/paywall|subscribe|purchase|trial/.test(hay))
40
+ return 'paywall';
41
+ if (/login|sign\s?in/.test(hay))
42
+ return 'login';
43
+ if (/forgot.?password/.test(hay))
44
+ return 'login';
45
+ return undefined;
46
+ }
47
+ function noteToObservation(n) {
48
+ const subsystem = detectSubsystem(`${n.workflow} ${n.reason ?? ''}`);
49
+ return {
50
+ title: `${n.workflow} → ${n.outcome}`,
51
+ summary: n.reason ? n.reason.slice(0, 200) : `${n.workflow} ${n.outcome}`,
52
+ failureCode: n.failureCode,
53
+ workflow: n.workflow,
54
+ screenPurpose: inferScreenPurpose(n),
55
+ visibleText: n.reason,
56
+ subsystem,
57
+ };
58
+ }
59
+ // A blocked/failed note in any of these categories is a real REQ-07 issue-ledger entry (not just
60
+ // app bugs): hard gates, store-compliance/privacy gaps, readiness improvements, missing data, etc.
61
+ // Intentional skips and not-applicable / passing outcomes are NOT recorded.
62
+ const RECORDED_NOTE_CATEGORIES = new Set([
63
+ 'app_bug',
64
+ 'blocker_app_bug',
65
+ 'hard_gate',
66
+ 'expected_gate',
67
+ 'store_compliance',
68
+ 'security_privacy',
69
+ 'accessibility_readiness',
70
+ 'improvement',
71
+ 'missing_test_data',
72
+ 'mcp_limitation',
73
+ ]);
74
+ function shouldRecordNote(n) {
75
+ if (n.outcome !== 'fail' && n.outcome !== 'blocked')
76
+ return false;
77
+ if (n.category === 'intentionally_skipped')
78
+ return false;
79
+ // Record when it carries a recognized category, a failure code, or is an uncategorized failure
80
+ // (an uncategorized fail/blocked is still worth remembering — the classifier triages it).
81
+ return !n.category || RECORDED_NOTE_CATEGORIES.has(n.category) || Boolean(n.failureCode);
82
+ }
83
+ /**
84
+ * Fold a run's findings + notes into the issue ledger and build the report section.
85
+ * Only non-info findings and failing/blocked app-bug notes become observations.
86
+ */
87
+ export function foldRunIntoLedger(root, findings, notes, now, meta = {},
88
+ /** Issue ids whose fix was VERIFIED this run by passing evidence (from test-suite/audit links). */
89
+ verifiedFixedIssueIds) {
90
+ const recordedIssueIds = [];
91
+ const recurrences = [];
92
+ const recorded = [];
93
+ const run = { sessionId: meta.sessionId, reportPath: meta.reportPath, reportUri: meta.reportUri };
94
+ for (const f of findings) {
95
+ if (f.severity === 'info')
96
+ continue; // info findings are not issues
97
+ const res = recordObservation(root, findingToObservation(f), now, { environment: meta.environment }, { appId: meta.appId, appName: meta.appName, platform: meta.platform, environment: meta.environment, sourceRevision: meta.sourceRevision, run });
98
+ recordedIssueIds.push(res.issueId);
99
+ recorded.push({ issueId: res.issueId, fingerprint: res.fingerprint, source: 'finding', category: res.record.category, severity: res.record.severity, state: res.record.state, reopened: res.reopened });
100
+ if (res.recurrenceMessage)
101
+ recurrences.push(res.recurrenceMessage);
102
+ }
103
+ for (const n of notes) {
104
+ if (!shouldRecordNote(n))
105
+ continue;
106
+ // Trust an explicit, valid issue-category note as a classifier fallback (the text rules still
107
+ // win when they detect a stronger signal, e.g. an actual RedBox mentioned in the reason).
108
+ const categoryHint = n.category && isIssueCategory(n.category) ? n.category : undefined;
109
+ const res = recordObservation(root, noteToObservation(n), now, { environment: meta.environment, categoryHint }, { appId: meta.appId, appName: meta.appName, platform: meta.platform, environment: meta.environment, sourceRevision: meta.sourceRevision, run: { ...run, testCaseId: n.workflow } });
110
+ recordedIssueIds.push(res.issueId);
111
+ recorded.push({ issueId: res.issueId, fingerprint: res.fingerprint, source: 'note', workflow: n.workflow, category: res.record.category, severity: res.record.severity, state: res.record.state, reopened: res.reopened });
112
+ if (res.recurrenceMessage)
113
+ recurrences.push(res.recurrenceMessage);
114
+ }
115
+ const index = getIndex(root, now, meta.appId);
116
+ const section = buildReportIssuesSection(index.records, new Set(recordedIssueIds), verifiedFixedIssueIds);
117
+ return { section, recordedIssueIds, recurrences, recorded };
118
+ }
119
+ //# sourceMappingURL=reportBridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reportBridge.js","sourceRoot":"","sources":["../../src/issues/reportBridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,90 @@
1
+ // SWIPIUM Issue Log / Error Tracking (SWIPIUM-REQ-07). Type definitions, enums, and validation
2
+ // helpers for the durable, project-level issue ledger.
3
+ //
4
+ // The ledger is Swipium's mobile-QA memory: an append-only event log (`.swipium/issues-log.jsonl`)
5
+ // plus a derived index (`.swipium/issues/index.json`). Events are compact and never hold full
6
+ // screenshots / logs / stack traces / report JSON — only references to artifacts (Developer Notes).
7
+ // Every lifecycle mutation is append-only so a developer can audit WHY an issue is currently
8
+ // considered fixed / reopened / suppressed.
9
+ //
10
+ // PURE: nothing here touches the clock or the filesystem. Callers pass `now` (an ISO string) in.
11
+ export const ISSUE_SCHEMA_VERSION = 1;
12
+ export function emptyIndex(now, appId) {
13
+ return { schemaVersion: ISSUE_SCHEMA_VERSION, updatedAt: now, appId, records: [] };
14
+ }
15
+ /** A user-visible issue is one a release reviewer should still see (not silently hidden). */
16
+ export const NOISE_STATES = ['expected_environment_noise', 'suppressed'];
17
+ export const OPEN_STATES = ['open', 'observed_again', 'reopened', 'needs_triage'];
18
+ export const ALL_ISSUE_STATES = [
19
+ 'open',
20
+ 'observed_again',
21
+ 'fixed',
22
+ 'reopened',
23
+ 'suppressed',
24
+ 'expected_environment_noise',
25
+ 'needs_triage',
26
+ ];
27
+ export const ALL_ISSUE_CATEGORIES = [
28
+ 'app_bug',
29
+ 'blocker_app_bug',
30
+ 'environment_noise',
31
+ 'expected_gate',
32
+ 'hard_gate',
33
+ 'improvement',
34
+ 'missing_test_data',
35
+ 'mcp_limitation',
36
+ 'security_privacy',
37
+ 'store_compliance',
38
+ 'accessibility_readiness',
39
+ ];
40
+ export const ALL_ISSUE_SEVERITIES = ['blocker', 'high', 'medium', 'low', 'info'];
41
+ /** Categories that count as "real app defects" rather than noise / gates / readiness. */
42
+ export const APP_BUG_CATEGORIES = ['app_bug', 'blocker_app_bug'];
43
+ /** Map a category to its default release impact when a policy rule doesn't override it. */
44
+ export function defaultReleaseImpact(category, severity) {
45
+ if (category === 'blocker_app_bug' || severity === 'blocker')
46
+ return 'block';
47
+ if (category === 'app_bug')
48
+ return severity === 'high' ? 'block' : 'warn';
49
+ if (category === 'security_privacy' || category === 'store_compliance')
50
+ return severity === 'high' ? 'block' : 'warn';
51
+ if (category === 'hard_gate')
52
+ return 'warn';
53
+ if (category === 'environment_noise')
54
+ return 'pass';
55
+ if (category === 'improvement' || category === 'accessibility_readiness')
56
+ return 'warn';
57
+ return 'warn';
58
+ }
59
+ /** Roll up many per-issue impacts into a single release decision (block > warn > pass). */
60
+ export function combineReleaseImpact(impacts) {
61
+ if (impacts.includes('block'))
62
+ return 'block';
63
+ if (impacts.includes('warn'))
64
+ return 'warn';
65
+ return 'pass';
66
+ }
67
+ /** Lightweight structural validation for an event (best-effort; never throws). */
68
+ export function validateEvent(e) {
69
+ const out = [];
70
+ if (typeof e !== 'object' || e === null)
71
+ return [{ path: '', message: 'event is not an object' }];
72
+ const ev = e;
73
+ if (ev.schemaVersion !== ISSUE_SCHEMA_VERSION)
74
+ out.push({ path: 'schemaVersion', message: 'unexpected schema version' });
75
+ for (const k of ['eventId', 'issueId', 'fingerprint', 'eventType', 'createdAt']) {
76
+ if (typeof ev[k] !== 'string' || !ev[k])
77
+ out.push({ path: k, message: `missing/invalid ${k}` });
78
+ }
79
+ return out;
80
+ }
81
+ export function isIssueState(v) {
82
+ return typeof v === 'string' && ALL_ISSUE_STATES.includes(v);
83
+ }
84
+ export function isIssueCategory(v) {
85
+ return typeof v === 'string' && ALL_ISSUE_CATEGORIES.includes(v);
86
+ }
87
+ export function isIssueSeverity(v) {
88
+ return typeof v === 'string' && ALL_ISSUE_SEVERITIES.includes(v);
89
+ }
90
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/issues/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,108 @@
1
+ // SWIPIUM Issue Log — source revision resolution (SWIPIUM-REQ-07 "Source revision").
2
+ //
3
+ // Fix attribution is strongest when issues link to a commit/release. But Swipium intentionally does
4
+ // NOT execute Git in spawned providers. So we resolve a SourceRevision in priority order WITHOUT
5
+ // running Git: explicit input → CI environment variables → app build metadata → optional read-only
6
+ // `.git/HEAD` (only when policy sets allowGitMetadataRead). `unknown` is always an acceptable result.
7
+ //
8
+ // PURE w.r.t. process state except the optional read-only git read, which only touches `.git/HEAD`
9
+ // and a ref file (never executes a binary). The env map is injected so this stays unit-testable.
10
+ import { existsSync, readFileSync } from 'node:fs';
11
+ import { join } from 'node:path';
12
+ /** Resolve from CI environment variables (GitHub Actions / GitLab / Bitbucket). */
13
+ export function fromCiEnv(env) {
14
+ if (env.GITHUB_SHA) {
15
+ return {
16
+ provider: 'github_actions',
17
+ commit: env.GITHUB_SHA,
18
+ branch: env.GITHUB_REF_NAME,
19
+ runUrl: env.GITHUB_SERVER_URL && env.GITHUB_REPOSITORY && env.GITHUB_RUN_ID
20
+ ? `${env.GITHUB_SERVER_URL}/${env.GITHUB_REPOSITORY}/actions/runs/${env.GITHUB_RUN_ID}`
21
+ : undefined,
22
+ };
23
+ }
24
+ if (env.CI_COMMIT_SHA) {
25
+ return {
26
+ provider: 'gitlab_ci',
27
+ commit: env.CI_COMMIT_SHA,
28
+ branch: env.CI_COMMIT_REF_NAME,
29
+ runUrl: env.CI_PIPELINE_URL,
30
+ };
31
+ }
32
+ if (env.BITBUCKET_COMMIT) {
33
+ return {
34
+ provider: 'bitbucket_ci',
35
+ commit: env.BITBUCKET_COMMIT,
36
+ branch: env.BITBUCKET_BRANCH,
37
+ };
38
+ }
39
+ return null;
40
+ }
41
+ /** Read-only `.git/HEAD` resolution. NEVER executes git; only reads ref files. */
42
+ export function fromGitReadonly(root) {
43
+ try {
44
+ const headPath = join(root, '.git', 'HEAD');
45
+ if (!existsSync(headPath))
46
+ return null;
47
+ const head = readFileSync(headPath, 'utf8').trim();
48
+ const refMatch = head.match(/^ref:\s*(.+)$/);
49
+ if (refMatch) {
50
+ const ref = refMatch[1].trim();
51
+ const branch = ref.replace(/^refs\/heads\//, '');
52
+ const refPath = join(root, '.git', ref);
53
+ let commit;
54
+ if (existsSync(refPath)) {
55
+ commit = readFileSync(refPath, 'utf8').trim();
56
+ }
57
+ else {
58
+ // packed-refs fallback
59
+ const packed = join(root, '.git', 'packed-refs');
60
+ if (existsSync(packed)) {
61
+ const line = readFileSync(packed, 'utf8')
62
+ .split('\n')
63
+ .find((l) => l.endsWith(` ${ref}`));
64
+ if (line)
65
+ commit = line.split(' ')[0];
66
+ }
67
+ }
68
+ return { provider: 'git_readonly', commit, branch };
69
+ }
70
+ // detached HEAD: the file is the commit sha itself
71
+ if (/^[0-9a-f]{7,40}$/i.test(head))
72
+ return { provider: 'git_readonly', commit: head };
73
+ return null;
74
+ }
75
+ catch {
76
+ return null;
77
+ }
78
+ }
79
+ export function fromAppBuild(meta) {
80
+ if (!meta.buildVersion && !meta.buildNumber && !meta.artifactHash)
81
+ return null;
82
+ return { provider: 'app_build', buildVersion: meta.buildVersion, buildNumber: meta.buildNumber, artifactHash: meta.artifactHash };
83
+ }
84
+ /** Resolve a SourceRevision in the documented priority order. Always returns a value. */
85
+ export function resolveSourceRevision(opts = {}) {
86
+ // 1. explicit input wins (mark provider explicit unless the caller already set one).
87
+ if (opts.explicit && (opts.explicit.commit || opts.explicit.buildVersion || opts.explicit.tag)) {
88
+ return { ...opts.explicit, provider: opts.explicit.provider ?? 'explicit' };
89
+ }
90
+ // 2. CI environment.
91
+ const ci = fromCiEnv(opts.env ?? {});
92
+ if (ci)
93
+ return ci;
94
+ // 3. app build metadata.
95
+ if (opts.appBuild) {
96
+ const ab = fromAppBuild(opts.appBuild);
97
+ if (ab)
98
+ return ab;
99
+ }
100
+ // 4. optional read-only git, only behind policy.
101
+ if (opts.allowGitMetadataRead && opts.root) {
102
+ const git = fromGitReadonly(opts.root);
103
+ if (git)
104
+ return git;
105
+ }
106
+ return { provider: 'unknown' };
107
+ }
108
+ //# sourceMappingURL=sourceRevision.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sourceRevision.js","sourceRoot":"","sources":["../../src/issues/sourceRevision.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,155 @@
1
+ // SWIPIUM Issue Log — persistence (SWIPIUM-REQ-07 "New storage").
2
+ //
3
+ // `.swipium/issues-log.jsonl` — canonical, append-only event ledger. NEVER pruned by default.
4
+ // `.swipium/issues/index.json` — derived cache, rebuildable from the log if deleted/corrupt.
5
+ // `.swipium/issues/policy.json` — classifier + retention + source-revision policy.
6
+ // `.swipium/issues/artifacts/` — large evidence files (may follow normal retention).
7
+ //
8
+ // The log is the source of truth: the index is always recomputable via rebuildRecords(). Writes are
9
+ // append-only for events and atomic (temp + rename) for the index. Best-effort I/O — corrupt files
10
+ // degrade to a rebuild, never throw on read.
11
+ import { createHash } from 'node:crypto';
12
+ import { appendFileSync, existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
13
+ import { join } from 'node:path';
14
+ import { ensureGitignored } from '../lib/gitignore.js';
15
+ import { rebuildRecords } from './recurrence.js';
16
+ import { ISSUE_SCHEMA_VERSION, emptyIndex, validateEvent } from './schema.js';
17
+ const SWIPIUM = '.swipium';
18
+ export function issuesLogPath(root) {
19
+ return join(root, SWIPIUM, 'issues-log.jsonl');
20
+ }
21
+ export function issuesDir(root) {
22
+ return join(root, SWIPIUM, 'issues');
23
+ }
24
+ export function issuesIndexPath(root) {
25
+ return join(issuesDir(root), 'index.json');
26
+ }
27
+ export function issuesPolicyPath(root) {
28
+ return join(issuesDir(root), 'policy.json');
29
+ }
30
+ export function issuesArtifactsDir(root) {
31
+ return join(issuesDir(root), 'artifacts');
32
+ }
33
+ export function issuesProjectId(root) {
34
+ return createHash('sha256').update(root).digest('hex').slice(0, 16);
35
+ }
36
+ export function issuesResourceUri(root) {
37
+ return `swipium://project/${issuesProjectId(root)}/issues`;
38
+ }
39
+ export const DEFAULT_POLICY = {
40
+ schemaVersion: 1,
41
+ allowGitMetadataRead: false,
42
+ retention: { keepIssueEvents: 'forever', pruneEvidenceAfterDays: 90 },
43
+ };
44
+ /** Load the policy file, merged over defaults. Best-effort — corrupt file → defaults. */
45
+ export function loadPolicy(root) {
46
+ try {
47
+ const path = issuesPolicyPath(root);
48
+ if (!existsSync(path))
49
+ return { ...DEFAULT_POLICY };
50
+ const raw = JSON.parse(readFileSync(path, 'utf8'));
51
+ return { ...DEFAULT_POLICY, ...raw, retention: { ...DEFAULT_POLICY.retention, ...raw.retention } };
52
+ }
53
+ catch {
54
+ return { ...DEFAULT_POLICY };
55
+ }
56
+ }
57
+ /** Read all events from the append-only log, skipping unparsable/invalid lines. */
58
+ export function readEvents(root) {
59
+ const path = issuesLogPath(root);
60
+ if (!existsSync(path))
61
+ return [];
62
+ const out = [];
63
+ let text;
64
+ try {
65
+ text = readFileSync(path, 'utf8');
66
+ }
67
+ catch {
68
+ return [];
69
+ }
70
+ for (const line of text.split('\n')) {
71
+ const trimmed = line.trim();
72
+ if (!trimmed)
73
+ continue;
74
+ try {
75
+ const ev = JSON.parse(trimmed);
76
+ if (validateEvent(ev).length === 0)
77
+ out.push(ev);
78
+ }
79
+ catch {
80
+ /* skip a corrupt line — the log stays usable */
81
+ }
82
+ }
83
+ return out;
84
+ }
85
+ /** Append one or more events to the canonical log (creating dirs + gitignore on first write). */
86
+ export function appendEvents(root, events) {
87
+ if (events.length === 0)
88
+ return { path: issuesLogPath(root), count: 0 };
89
+ mkdirSync(join(root, SWIPIUM), { recursive: true });
90
+ ensureGitignored(root);
91
+ const path = issuesLogPath(root);
92
+ const payload = events.map((e) => JSON.stringify(e)).join('\n') + '\n';
93
+ appendFileSync(path, payload);
94
+ return { path, count: events.length };
95
+ }
96
+ /** Atomically write the derived index (temp + rename). */
97
+ export function saveIndex(root, index) {
98
+ mkdirSync(issuesDir(root), { recursive: true });
99
+ ensureGitignored(root);
100
+ const path = issuesIndexPath(root);
101
+ const tmp = `${path}.tmp`;
102
+ writeFileSync(tmp, JSON.stringify(index, null, 2));
103
+ renameSync(tmp, path);
104
+ return { path, resourceUri: issuesResourceUri(root) };
105
+ }
106
+ /** Load the index from disk; null when absent/corrupt (caller should rebuild). */
107
+ export function loadIndex(root) {
108
+ try {
109
+ const path = issuesIndexPath(root);
110
+ if (!existsSync(path))
111
+ return null;
112
+ const raw = JSON.parse(readFileSync(path, 'utf8'));
113
+ if (raw.schemaVersion !== ISSUE_SCHEMA_VERSION || !Array.isArray(raw.records))
114
+ return null;
115
+ return raw;
116
+ }
117
+ catch {
118
+ return null;
119
+ }
120
+ }
121
+ /** Rebuild the index from the canonical log and persist it. The log is always authoritative. */
122
+ export function rebuildIndex(root, now, appId) {
123
+ const events = readEvents(root);
124
+ const records = rebuildRecords(events);
125
+ const index = { schemaVersion: ISSUE_SCHEMA_VERSION, updatedAt: now, appId, records };
126
+ if (events.length > 0)
127
+ saveIndex(root, index);
128
+ return index;
129
+ }
130
+ /** Get the current index, rebuilding from the log when the cache is missing/stale/corrupt. */
131
+ export function getIndex(root, now, appId) {
132
+ const cached = loadIndex(root);
133
+ if (cached)
134
+ return cached;
135
+ const events = readEvents(root);
136
+ if (events.length === 0)
137
+ return emptyIndex(now, appId);
138
+ return rebuildIndex(root, now, appId);
139
+ }
140
+ /**
141
+ * Count events already in the log for an issue. Used to allocate a monotonic per-issue sequence so
142
+ * event ids stay unique even when several observations share the same timestamp.
143
+ */
144
+ export function eventCountForIssue(root, issueId) {
145
+ let n = 0;
146
+ for (const e of readEvents(root))
147
+ if (e.issueId === issueId)
148
+ n += 1;
149
+ return n;
150
+ }
151
+ /** Find an index record by issue id or fingerprint. */
152
+ export function findRecord(index, key) {
153
+ return index.records.find((r) => (key.issueId && r.issueId === key.issueId) || (key.fingerprint && r.fingerprint === key.fingerprint));
154
+ }
155
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/issues/store.ts"],"names":[],"mappings":"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"}