@dailephd/my-frontend-observer 0.8.1

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 (316) hide show
  1. package/CHANGELOG.md +397 -0
  2. package/LICENSE +21 -0
  3. package/README.md +255 -0
  4. package/dist/application/browserCaptureService.d.ts +11 -0
  5. package/dist/application/browserCaptureService.js +12 -0
  6. package/dist/application/browserCaptureService.js.map +1 -0
  7. package/dist/application/comparisonService.d.ts +56 -0
  8. package/dist/application/comparisonService.js +77 -0
  9. package/dist/application/comparisonService.js.map +1 -0
  10. package/dist/application/externalReferencePersistenceService.d.ts +75 -0
  11. package/dist/application/externalReferencePersistenceService.js +182 -0
  12. package/dist/application/externalReferencePersistenceService.js.map +1 -0
  13. package/dist/application/frontendContractEvaluationService.d.ts +49 -0
  14. package/dist/application/frontendContractEvaluationService.js +112 -0
  15. package/dist/application/frontendContractEvaluationService.js.map +1 -0
  16. package/dist/application/frontendContractPersistenceService.d.ts +56 -0
  17. package/dist/application/frontendContractPersistenceService.js +91 -0
  18. package/dist/application/frontendContractPersistenceService.js.map +1 -0
  19. package/dist/application/observationPersistence.d.ts +59 -0
  20. package/dist/application/observationPersistence.js +79 -0
  21. package/dist/application/observationPersistence.js.map +1 -0
  22. package/dist/application/projectCheckService.d.ts +3 -0
  23. package/dist/application/projectCheckService.js +169 -0
  24. package/dist/application/projectCheckService.js.map +1 -0
  25. package/dist/application/projectWorkflowService.d.ts +46 -0
  26. package/dist/application/projectWorkflowService.js +92 -0
  27. package/dist/application/projectWorkflowService.js.map +1 -0
  28. package/dist/application/referenceFidelityEvaluationService.d.ts +28 -0
  29. package/dist/application/referenceFidelityEvaluationService.js +45 -0
  30. package/dist/application/referenceFidelityEvaluationService.js.map +1 -0
  31. package/dist/artifacts/artifactReader.d.ts +19 -0
  32. package/dist/artifacts/artifactReader.js +36 -0
  33. package/dist/artifacts/artifactReader.js.map +1 -0
  34. package/dist/artifacts/artifactWriter.d.ts +25 -0
  35. package/dist/artifacts/artifactWriter.js +68 -0
  36. package/dist/artifacts/artifactWriter.js.map +1 -0
  37. package/dist/artifacts/comparisonArtifactReader.d.ts +18 -0
  38. package/dist/artifacts/comparisonArtifactReader.js +35 -0
  39. package/dist/artifacts/comparisonArtifactReader.js.map +1 -0
  40. package/dist/artifacts/comparisonArtifactWriter.d.ts +41 -0
  41. package/dist/artifacts/comparisonArtifactWriter.js +67 -0
  42. package/dist/artifacts/comparisonArtifactWriter.js.map +1 -0
  43. package/dist/artifacts/externalReferenceArtifactReader.d.ts +18 -0
  44. package/dist/artifacts/externalReferenceArtifactReader.js +35 -0
  45. package/dist/artifacts/externalReferenceArtifactReader.js.map +1 -0
  46. package/dist/artifacts/externalReferenceArtifactWriter.d.ts +44 -0
  47. package/dist/artifacts/externalReferenceArtifactWriter.js +77 -0
  48. package/dist/artifacts/externalReferenceArtifactWriter.js.map +1 -0
  49. package/dist/artifacts/frontendContractArtifactReader.d.ts +24 -0
  50. package/dist/artifacts/frontendContractArtifactReader.js +47 -0
  51. package/dist/artifacts/frontendContractArtifactReader.js.map +1 -0
  52. package/dist/artifacts/frontendContractArtifactWriter.d.ts +34 -0
  53. package/dist/artifacts/frontendContractArtifactWriter.js +70 -0
  54. package/dist/artifacts/frontendContractArtifactWriter.js.map +1 -0
  55. package/dist/artifacts/frontendContractEvaluationArtifactReader.d.ts +17 -0
  56. package/dist/artifacts/frontendContractEvaluationArtifactReader.js +34 -0
  57. package/dist/artifacts/frontendContractEvaluationArtifactReader.js.map +1 -0
  58. package/dist/artifacts/frontendContractEvaluationArtifactWriter.d.ts +32 -0
  59. package/dist/artifacts/frontendContractEvaluationArtifactWriter.js +58 -0
  60. package/dist/artifacts/frontendContractEvaluationArtifactWriter.js.map +1 -0
  61. package/dist/artifacts/types.d.ts +17 -0
  62. package/dist/artifacts/types.js +2 -0
  63. package/dist/artifacts/types.js.map +1 -0
  64. package/dist/browser/chromiumAdapter.d.ts +21 -0
  65. package/dist/browser/chromiumAdapter.js +204 -0
  66. package/dist/browser/chromiumAdapter.js.map +1 -0
  67. package/dist/browser/evidenceCapture.d.ts +62 -0
  68. package/dist/browser/evidenceCapture.js +500 -0
  69. package/dist/browser/evidenceCapture.js.map +1 -0
  70. package/dist/browser/scrollCapture.d.ts +32 -0
  71. package/dist/browser/scrollCapture.js +163 -0
  72. package/dist/browser/scrollCapture.js.map +1 -0
  73. package/dist/browser/types.d.ts +24 -0
  74. package/dist/browser/types.js +2 -0
  75. package/dist/browser/types.js.map +1 -0
  76. package/dist/cli.d.ts +8 -0
  77. package/dist/cli.js +2411 -0
  78. package/dist/cli.js.map +1 -0
  79. package/dist/domain/boundedAgentContext.d.ts +226 -0
  80. package/dist/domain/boundedAgentContext.js +355 -0
  81. package/dist/domain/boundedAgentContext.js.map +1 -0
  82. package/dist/domain/boundedAgentContextCorrelation.d.ts +74 -0
  83. package/dist/domain/boundedAgentContextCorrelation.js +441 -0
  84. package/dist/domain/boundedAgentContextCorrelation.js.map +1 -0
  85. package/dist/domain/boundedAgentContextIdentity.d.ts +26 -0
  86. package/dist/domain/boundedAgentContextIdentity.js +69 -0
  87. package/dist/domain/boundedAgentContextIdentity.js.map +1 -0
  88. package/dist/domain/boundedAgentContextProjection.d.ts +71 -0
  89. package/dist/domain/boundedAgentContextProjection.js +477 -0
  90. package/dist/domain/boundedAgentContextProjection.js.map +1 -0
  91. package/dist/domain/comparison.d.ts +220 -0
  92. package/dist/domain/comparison.js +350 -0
  93. package/dist/domain/comparison.js.map +1 -0
  94. package/dist/domain/comparisonEngine.d.ts +76 -0
  95. package/dist/domain/comparisonEngine.js +734 -0
  96. package/dist/domain/comparisonEngine.js.map +1 -0
  97. package/dist/domain/comparisonIdentity.d.ts +13 -0
  98. package/dist/domain/comparisonIdentity.js +46 -0
  99. package/dist/domain/comparisonIdentity.js.map +1 -0
  100. package/dist/domain/completion.d.ts +30 -0
  101. package/dist/domain/completion.js +22 -0
  102. package/dist/domain/completion.js.map +1 -0
  103. package/dist/domain/diagnostics.d.ts +17 -0
  104. package/dist/domain/diagnostics.js +77 -0
  105. package/dist/domain/diagnostics.js.map +1 -0
  106. package/dist/domain/evidence.d.ts +29 -0
  107. package/dist/domain/evidence.js +59 -0
  108. package/dist/domain/evidence.js.map +1 -0
  109. package/dist/domain/explicitState.d.ts +40 -0
  110. package/dist/domain/explicitState.js +54 -0
  111. package/dist/domain/explicitState.js.map +1 -0
  112. package/dist/domain/externalReference.d.ts +158 -0
  113. package/dist/domain/externalReference.js +167 -0
  114. package/dist/domain/externalReference.js.map +1 -0
  115. package/dist/domain/externalReferenceApplicability.d.ts +43 -0
  116. package/dist/domain/externalReferenceApplicability.js +52 -0
  117. package/dist/domain/externalReferenceApplicability.js.map +1 -0
  118. package/dist/domain/externalReferenceCompatibility.d.ts +40 -0
  119. package/dist/domain/externalReferenceCompatibility.js +48 -0
  120. package/dist/domain/externalReferenceCompatibility.js.map +1 -0
  121. package/dist/domain/externalReferenceFidelity.d.ts +171 -0
  122. package/dist/domain/externalReferenceFidelity.js +419 -0
  123. package/dist/domain/externalReferenceFidelity.js.map +1 -0
  124. package/dist/domain/externalReferenceIdentity.d.ts +38 -0
  125. package/dist/domain/externalReferenceIdentity.js +70 -0
  126. package/dist/domain/externalReferenceIdentity.js.map +1 -0
  127. package/dist/domain/externalReferenceImage.d.ts +35 -0
  128. package/dist/domain/externalReferenceImage.js +160 -0
  129. package/dist/domain/externalReferenceImage.js.map +1 -0
  130. package/dist/domain/externalReferenceRegionRelationships.d.ts +63 -0
  131. package/dist/domain/externalReferenceRegionRelationships.js +98 -0
  132. package/dist/domain/externalReferenceRegionRelationships.js.map +1 -0
  133. package/dist/domain/externalReferenceRegions.d.ts +65 -0
  134. package/dist/domain/externalReferenceRegions.js +105 -0
  135. package/dist/domain/externalReferenceRegions.js.map +1 -0
  136. package/dist/domain/externalReferenceRequirementIdentity.d.ts +12 -0
  137. package/dist/domain/externalReferenceRequirementIdentity.js +35 -0
  138. package/dist/domain/externalReferenceRequirementIdentity.js.map +1 -0
  139. package/dist/domain/externalReferenceRequirements.d.ts +215 -0
  140. package/dist/domain/externalReferenceRequirements.js +401 -0
  141. package/dist/domain/externalReferenceRequirements.js.map +1 -0
  142. package/dist/domain/externalReferenceRuntimeBinding.d.ts +146 -0
  143. package/dist/domain/externalReferenceRuntimeBinding.js +183 -0
  144. package/dist/domain/externalReferenceRuntimeBinding.js.map +1 -0
  145. package/dist/domain/frontendContractEvaluation.d.ts +57 -0
  146. package/dist/domain/frontendContractEvaluation.js +454 -0
  147. package/dist/domain/frontendContractEvaluation.js.map +1 -0
  148. package/dist/domain/frontendContractEvaluationArtifact.d.ts +65 -0
  149. package/dist/domain/frontendContractEvaluationArtifact.js +108 -0
  150. package/dist/domain/frontendContractEvaluationArtifact.js.map +1 -0
  151. package/dist/domain/frontendContractIdentity.d.ts +39 -0
  152. package/dist/domain/frontendContractIdentity.js +70 -0
  153. package/dist/domain/frontendContractIdentity.js.map +1 -0
  154. package/dist/domain/frontendContracts.d.ts +188 -0
  155. package/dist/domain/frontendContracts.js +260 -0
  156. package/dist/domain/frontendContracts.js.map +1 -0
  157. package/dist/domain/identity.d.ts +21 -0
  158. package/dist/domain/identity.js +47 -0
  159. package/dist/domain/identity.js.map +1 -0
  160. package/dist/domain/referenceCorrectionIdentity.d.ts +40 -0
  161. package/dist/domain/referenceCorrectionIdentity.js +77 -0
  162. package/dist/domain/referenceCorrectionIdentity.js.map +1 -0
  163. package/dist/domain/referenceCorrectionWorkflow.d.ts +160 -0
  164. package/dist/domain/referenceCorrectionWorkflow.js +165 -0
  165. package/dist/domain/referenceCorrectionWorkflow.js.map +1 -0
  166. package/dist/domain/referenceFidelityProjection.d.ts +65 -0
  167. package/dist/domain/referenceFidelityProjection.js +135 -0
  168. package/dist/domain/referenceFidelityProjection.js.map +1 -0
  169. package/dist/domain/relationships.d.ts +210 -0
  170. package/dist/domain/relationships.js +352 -0
  171. package/dist/domain/relationships.js.map +1 -0
  172. package/dist/domain/schema.d.ts +269 -0
  173. package/dist/domain/schema.js +442 -0
  174. package/dist/domain/schema.js.map +1 -0
  175. package/dist/domain/scrollEvidence.d.ts +51 -0
  176. package/dist/domain/scrollEvidence.js +134 -0
  177. package/dist/domain/scrollEvidence.js.map +1 -0
  178. package/dist/index.d.ts +114 -0
  179. package/dist/index.js +64 -0
  180. package/dist/index.js.map +1 -0
  181. package/dist/projectWorkflow/aliasCatalog.d.ts +21 -0
  182. package/dist/projectWorkflow/aliasCatalog.js +67 -0
  183. package/dist/projectWorkflow/aliasCatalog.js.map +1 -0
  184. package/dist/projectWorkflow/checkAcceptance.d.ts +25 -0
  185. package/dist/projectWorkflow/checkAcceptance.js +55 -0
  186. package/dist/projectWorkflow/checkAcceptance.js.map +1 -0
  187. package/dist/projectWorkflow/checkResult.d.ts +85 -0
  188. package/dist/projectWorkflow/checkResult.js +101 -0
  189. package/dist/projectWorkflow/checkResult.js.map +1 -0
  190. package/dist/projectWorkflow/projectConfig.d.ts +43 -0
  191. package/dist/projectWorkflow/projectConfig.js +84 -0
  192. package/dist/projectWorkflow/projectConfig.js.map +1 -0
  193. package/dist/projectWorkflow/projectDiscovery.d.ts +9 -0
  194. package/dist/projectWorkflow/projectDiscovery.js +20 -0
  195. package/dist/projectWorkflow/projectDiscovery.js.map +1 -0
  196. package/dist/projectWorkflow/projectPaths.d.ts +8 -0
  197. package/dist/projectWorkflow/projectPaths.js +23 -0
  198. package/dist/projectWorkflow/projectPaths.js.map +1 -0
  199. package/dist/request/paths.d.ts +14 -0
  200. package/dist/request/paths.js +33 -0
  201. package/dist/request/paths.js.map +1 -0
  202. package/dist/request/request.d.ts +111 -0
  203. package/dist/request/request.js +464 -0
  204. package/dist/request/request.js.map +1 -0
  205. package/dist/safety/policy.d.ts +14 -0
  206. package/dist/safety/policy.js +81 -0
  207. package/dist/safety/policy.js.map +1 -0
  208. package/dist/viewer/assets/index-CN_yb9Uf.css +1 -0
  209. package/dist/viewer/assets/index-D98S1_2d.js +9 -0
  210. package/dist/viewer/icons/icon-192.png +0 -0
  211. package/dist/viewer/icons/icon-512.png +0 -0
  212. package/dist/viewer/index.html +15 -0
  213. package/dist/viewer/manifest.webmanifest +1 -0
  214. package/dist/viewer/registerSW.js +1 -0
  215. package/dist/viewer/sw.js +1 -0
  216. package/dist/viewer/workbox-9c191d2f.js +1 -0
  217. package/dist/viewerServer/context.d.ts +48 -0
  218. package/dist/viewerServer/context.js +60 -0
  219. package/dist/viewerServer/context.js.map +1 -0
  220. package/dist/viewerServer/evidence/classify.d.ts +59 -0
  221. package/dist/viewerServer/evidence/classify.js +124 -0
  222. package/dist/viewerServer/evidence/classify.js.map +1 -0
  223. package/dist/viewerServer/evidence/comparisonView.d.ts +28 -0
  224. package/dist/viewerServer/evidence/comparisonView.js +43 -0
  225. package/dist/viewerServer/evidence/comparisonView.js.map +1 -0
  226. package/dist/viewerServer/evidence/contextSourceView.d.ts +25 -0
  227. package/dist/viewerServer/evidence/contextSourceView.js +20 -0
  228. package/dist/viewerServer/evidence/contextSourceView.js.map +1 -0
  229. package/dist/viewerServer/evidence/discovery.d.ts +31 -0
  230. package/dist/viewerServer/evidence/discovery.js +78 -0
  231. package/dist/viewerServer/evidence/discovery.js.map +1 -0
  232. package/dist/viewerServer/evidence/evaluationView.d.ts +32 -0
  233. package/dist/viewerServer/evidence/evaluationView.js +50 -0
  234. package/dist/viewerServer/evidence/evaluationView.js.map +1 -0
  235. package/dist/viewerServer/evidence/handles.d.ts +21 -0
  236. package/dist/viewerServer/evidence/handles.js +43 -0
  237. package/dist/viewerServer/evidence/handles.js.map +1 -0
  238. package/dist/viewerServer/evidence/index.d.ts +41 -0
  239. package/dist/viewerServer/evidence/index.js +82 -0
  240. package/dist/viewerServer/evidence/index.js.map +1 -0
  241. package/dist/viewerServer/evidence/limits.d.ts +27 -0
  242. package/dist/viewerServer/evidence/limits.js +28 -0
  243. package/dist/viewerServer/evidence/limits.js.map +1 -0
  244. package/dist/viewerServer/evidence/linkedEvidence.d.ts +43 -0
  245. package/dist/viewerServer/evidence/linkedEvidence.js +151 -0
  246. package/dist/viewerServer/evidence/linkedEvidence.js.map +1 -0
  247. package/dist/viewerServer/evidence/mediaResolver.d.ts +16 -0
  248. package/dist/viewerServer/evidence/mediaResolver.js +85 -0
  249. package/dist/viewerServer/evidence/mediaResolver.js.map +1 -0
  250. package/dist/viewerServer/evidence/observationView.d.ts +29 -0
  251. package/dist/viewerServer/evidence/observationView.js +46 -0
  252. package/dist/viewerServer/evidence/observationView.js.map +1 -0
  253. package/dist/viewerServer/evidence/pathSafety.d.ts +11 -0
  254. package/dist/viewerServer/evidence/pathSafety.js +31 -0
  255. package/dist/viewerServer/evidence/pathSafety.js.map +1 -0
  256. package/dist/viewerServer/evidence/projection.d.ts +55 -0
  257. package/dist/viewerServer/evidence/projection.js +152 -0
  258. package/dist/viewerServer/evidence/projection.js.map +1 -0
  259. package/dist/viewerServer/evidence/referenceView.d.ts +133 -0
  260. package/dist/viewerServer/evidence/referenceView.js +169 -0
  261. package/dist/viewerServer/evidence/referenceView.js.map +1 -0
  262. package/dist/viewerServer/httpServer.d.ts +27 -0
  263. package/dist/viewerServer/httpServer.js +381 -0
  264. package/dist/viewerServer/httpServer.js.map +1 -0
  265. package/dist/viewerServer/openBrowser.d.ts +7 -0
  266. package/dist/viewerServer/openBrowser.js +32 -0
  267. package/dist/viewerServer/openBrowser.js.map +1 -0
  268. package/dist/viewerServer/port.d.ts +16 -0
  269. package/dist/viewerServer/port.js +19 -0
  270. package/dist/viewerServer/port.js.map +1 -0
  271. package/dist/viewerServer/viewerService.d.ts +62 -0
  272. package/dist/viewerServer/viewerService.js +88 -0
  273. package/dist/viewerServer/viewerService.js.map +1 -0
  274. package/docs/ARCHITECTURE.md +1286 -0
  275. package/docs/CI_CD.md +250 -0
  276. package/docs/COMMANDS.md +972 -0
  277. package/docs/CONTRACTS.md +1856 -0
  278. package/docs/CURRENT_STATE.md +1049 -0
  279. package/docs/DEVELOPMENT.md +202 -0
  280. package/docs/DOCUMENTATION_PRESERVATION_POLICY.md +50 -0
  281. package/docs/PROJECT_DESCRIPTION.md +2221 -0
  282. package/docs/PROJECT_MILESTONES.md +2526 -0
  283. package/docs/PROJECT_OVERVIEW.md +150 -0
  284. package/docs/QUICKSTART.md +83 -0
  285. package/docs/RELEASE.md +27 -0
  286. package/docs/ROADMAP.md +641 -0
  287. package/docs/SECURITY.md +218 -0
  288. package/docs/WORKFLOWS.md +642 -0
  289. package/docs/plans/v0.8-implementation-plan.md +655 -0
  290. package/docs/plans/v0.8.1-cli-usability-patch-plan.md +505 -0
  291. package/docs/reports/v0.7-bounded-fidelity-context-prompt7.md +243 -0
  292. package/docs/reports/v0.7-implementation-completeness-documentation-reconciliation.md +497 -0
  293. package/docs/reports/v0.7-pre-release-readiness.md +337 -0
  294. package/docs/reports/v0.7-reference-binding-prompt5.md +223 -0
  295. package/docs/reports/v0.7-reference-compatibility-prompt4.md +234 -0
  296. package/docs/reports/v0.7-reference-correction-workflow-prompt8.md +222 -0
  297. package/docs/reports/v0.7-reference-fidelity-prompt6.md +216 -0
  298. package/docs/reports/v0.7-reference-foundation-prompt1.md +151 -0
  299. package/docs/reports/v0.7-reference-regions-prompt2.md +195 -0
  300. package/docs/reports/v0.7-reference-requirements-prompt3.md +217 -0
  301. package/docs/reports/v0.7-release-prep.md +423 -0
  302. package/docs/reports/v0.8-binding-fidelity-interaction-batch6.md +279 -0
  303. package/docs/reports/v0.8-bounded-context-correlation-batch7.md +233 -0
  304. package/docs/reports/v0.8-comparison-contract-inspection-batch4.md +279 -0
  305. package/docs/reports/v0.8-evidence-index-readers-batch2.md +247 -0
  306. package/docs/reports/v0.8-implementation-completeness-documentation-reconciliation.md +741 -0
  307. package/docs/reports/v0.8-integrated-viewer-acceptance-batch8.md +128 -0
  308. package/docs/reports/v0.8-observation-svg-inspection-batch3.md +223 -0
  309. package/docs/reports/v0.8-prerelease-readiness-cross-platform-security-code-rot.md +687 -0
  310. package/docs/reports/v0.8-reference-candidate-inspection-batch5.md +232 -0
  311. package/docs/reports/v0.8-viewer-runtime-pwa-batch1.md +278 -0
  312. package/docs/reports/v0.8.1-check-orchestration-prompt2.md +69 -0
  313. package/docs/reports/v0.8.1-implementation-completeness-documentation-reconciliation.md +114 -0
  314. package/docs/reports/v0.8.1-prerelease-readiness-cross-platform-security-code-rot.md +170 -0
  315. package/docs/reports/v0.8.1-project-workflow-foundation-prompt1.md +66 -0
  316. package/package.json +58 -0
@@ -0,0 +1,24 @@
1
+ import type { PersistentBaselineContract, PerChangeContract } from '../domain/frontendContracts.js';
2
+ export type ReadPersistentBaselineContractResult = {
3
+ ok: true;
4
+ contract: PersistentBaselineContract;
5
+ } | {
6
+ ok: false;
7
+ reason: string;
8
+ };
9
+ export type ReadPerChangeContractResult = {
10
+ ok: true;
11
+ contract: PerChangeContract;
12
+ } | {
13
+ ok: false;
14
+ reason: string;
15
+ };
16
+ /**
17
+ * Narrow canonical reader counterpart to `frontendContractArtifactWriter.ts#writePersistentBaselineContract`:
18
+ * reads one `manifest.json`, parses it, and validates it through the same
19
+ * `isValidPersistentBaselineContract` structural gate the writer uses - never
20
+ * a second validator, never a schema upgrade, never a guessed missing field.
21
+ */
22
+ export declare function readPersistentBaselineContract(manifestPath: string): Promise<ReadPersistentBaselineContractResult>;
23
+ /** Narrow canonical reader counterpart to `frontendContractArtifactWriter.ts#writePerChangeContract`. */
24
+ export declare function readPerChangeContract(manifestPath: string): Promise<ReadPerChangeContractResult>;
@@ -0,0 +1,47 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { isValidPersistentBaselineContract, isValidPerChangeContract } from '../domain/frontendContracts.js';
3
+ async function readJson(manifestPath) {
4
+ let raw;
5
+ try {
6
+ raw = await readFile(manifestPath, 'utf8');
7
+ }
8
+ catch (err) {
9
+ const message = err instanceof Error ? err.message : String(err);
10
+ return { ok: false, reason: `failed to read artifact manifest at "${manifestPath}": ${message}` };
11
+ }
12
+ try {
13
+ return { ok: true, value: JSON.parse(raw) };
14
+ }
15
+ catch (err) {
16
+ const message = err instanceof Error ? err.message : String(err);
17
+ return { ok: false, reason: `artifact manifest at "${manifestPath}" is not valid JSON: ${message}` };
18
+ }
19
+ }
20
+ /**
21
+ * Narrow canonical reader counterpart to `frontendContractArtifactWriter.ts#writePersistentBaselineContract`:
22
+ * reads one `manifest.json`, parses it, and validates it through the same
23
+ * `isValidPersistentBaselineContract` structural gate the writer uses - never
24
+ * a second validator, never a schema upgrade, never a guessed missing field.
25
+ */
26
+ export async function readPersistentBaselineContract(manifestPath) {
27
+ const parsed = await readJson(manifestPath);
28
+ if (!parsed.ok)
29
+ return parsed;
30
+ const validation = isValidPersistentBaselineContract(parsed.value);
31
+ if (!validation.valid) {
32
+ return { ok: false, reason: `baseline contract manifest at "${manifestPath}" failed structural validation: ${validation.reason}` };
33
+ }
34
+ return { ok: true, contract: parsed.value };
35
+ }
36
+ /** Narrow canonical reader counterpart to `frontendContractArtifactWriter.ts#writePerChangeContract`. */
37
+ export async function readPerChangeContract(manifestPath) {
38
+ const parsed = await readJson(manifestPath);
39
+ if (!parsed.ok)
40
+ return parsed;
41
+ const validation = isValidPerChangeContract(parsed.value);
42
+ if (!validation.valid) {
43
+ return { ok: false, reason: `per-change contract manifest at "${manifestPath}" failed structural validation: ${validation.reason}` };
44
+ }
45
+ return { ok: true, contract: parsed.value };
46
+ }
47
+ //# sourceMappingURL=frontendContractArtifactReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontendContractArtifactReader.js","sourceRoot":"","sources":["../../src/artifacts/frontendContractArtifactReader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,iCAAiC,EAAE,wBAAwB,EAAE,MAAM,gCAAgC,CAAC;AAK7G,KAAK,UAAU,QAAQ,CAAC,YAAoB;IAC1C,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,wCAAwC,YAAY,MAAM,OAAO,EAAE,EAAE,CAAC;IACpG,CAAC;IACD,IAAI,CAAC;QACH,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,YAAY,wBAAwB,OAAO,EAAE,EAAE,CAAC;IACvG,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,8BAA8B,CAAC,YAAoB;IACvE,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,MAAM,CAAC;IAC9B,MAAM,UAAU,GAAG,iCAAiC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACnE,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kCAAkC,YAAY,mCAAmC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;IACrI,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,KAAmC,EAAE,CAAC;AAC5E,CAAC;AAED,yGAAyG;AACzG,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,YAAoB;IAC9D,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC5C,IAAI,CAAC,MAAM,CAAC,EAAE;QAAE,OAAO,MAAM,CAAC;IAC9B,MAAM,UAAU,GAAG,wBAAwB,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAC1D,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,oCAAoC,YAAY,mCAAmC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;IACvI,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,KAA0B,EAAE,CAAC;AACnE,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { PersistentBaselineContract, PerChangeContract } from '../domain/frontendContracts.js';
2
+ import type { Diagnostic } from '../domain/diagnostics.js';
3
+ export declare const FRONTEND_CONTRACT_MANIFEST_FILENAME = "manifest.json";
4
+ /**
5
+ * Mirrors `PersistedComparisonResult`'s shape/semantics - a frontend contract
6
+ * directory has no screenshot file either, and this writer never touches
7
+ * `artifacts/artifactWriter.ts` or `artifacts/comparisonArtifactWriter.ts`.
8
+ */
9
+ export type PersistedFrontendContractResult = {
10
+ ok: true;
11
+ artifactRoot: string;
12
+ manifestPath: string;
13
+ } | {
14
+ ok: false;
15
+ diagnostics: Diagnostic[];
16
+ };
17
+ export interface WriteFrontendContractArtifactOptions {
18
+ /** Base directory that `outputLocation` is resolved against. Defaults to `process.cwd()`. */
19
+ cwd?: string;
20
+ }
21
+ /**
22
+ * Persists one already-valid `PersistentBaselineContract` as
23
+ * `<outputLocation>/<baselineId>/manifest.json`. Never mutates or removes any
24
+ * other baseline artifact - `supersedesBaselineId` (if present) is written
25
+ * exactly as supplied; this writer never inspects, rewrites, or deletes the
26
+ * baseline it refers to.
27
+ */
28
+ export declare function writePersistentBaselineContract(contract: PersistentBaselineContract, outputLocation: string, options?: WriteFrontendContractArtifactOptions): Promise<PersistedFrontendContractResult>;
29
+ /**
30
+ * Persists one already-valid `PerChangeContract` as
31
+ * `<outputLocation>/<contractId>/manifest.json`, symmetric with baseline
32
+ * persistence above (both share `CONTRACT_ARTIFACT_KIND`/`CONTRACT_SCHEMA_VERSION`).
33
+ */
34
+ export declare function writePerChangeContract(contract: PerChangeContract, outputLocation: string, options?: WriteFrontendContractArtifactOptions): Promise<PersistedFrontendContractResult>;
@@ -0,0 +1,70 @@
1
+ import { mkdir, writeFile, rename, rm, access } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { isValidPersistentBaselineContract, isValidPerChangeContract } from '../domain/frontendContracts.js';
4
+ import { DIAGNOSTIC_SEVERITY } from '../domain/diagnostics.js';
5
+ export const FRONTEND_CONTRACT_MANIFEST_FILENAME = 'manifest.json';
6
+ function writeFailure(message, details) {
7
+ const diagnostic = {
8
+ code: 'artifact-write-failure',
9
+ severity: DIAGNOSTIC_SEVERITY['artifact-write-failure'],
10
+ message,
11
+ ...(details === undefined ? {} : { details }),
12
+ };
13
+ return { ok: false, diagnostics: [diagnostic] };
14
+ }
15
+ async function pathExists(candidate) {
16
+ return access(candidate).then(() => true, () => false);
17
+ }
18
+ /**
19
+ * Shared atomic-write body for both contract classes, following the same
20
+ * discipline as `writeObservationArtifact`/`writeComparisonArtifact`: sibling
21
+ * temporary directory, single `manifest.json`, then one atomic rename. An
22
+ * existing directory at the final identity is a genuine collision (never a
23
+ * destructive overwrite of prior baseline/contract history) and is rejected.
24
+ */
25
+ async function writeContractArtifact(value, id, kindLabel, outputLocation, options) {
26
+ const cwd = options.cwd ?? process.cwd();
27
+ const outputRoot = path.resolve(cwd, outputLocation);
28
+ const finalRoot = path.join(outputRoot, id);
29
+ const tempRoot = path.join(outputRoot, `.tmp-${id}`);
30
+ if (await pathExists(finalRoot)) {
31
+ return writeFailure(`a ${kindLabel} artifact already exists at "${id}"; refusing to overwrite it`, { artifactRoot: finalRoot });
32
+ }
33
+ try {
34
+ await rm(tempRoot, { recursive: true, force: true });
35
+ await mkdir(tempRoot, { recursive: true });
36
+ await writeFile(path.join(tempRoot, FRONTEND_CONTRACT_MANIFEST_FILENAME), JSON.stringify(value, null, 2), 'utf8');
37
+ await rename(tempRoot, finalRoot);
38
+ return { ok: true, artifactRoot: finalRoot, manifestPath: path.join(finalRoot, FRONTEND_CONTRACT_MANIFEST_FILENAME) };
39
+ }
40
+ catch (err) {
41
+ await rm(tempRoot, { recursive: true, force: true }).catch(() => undefined);
42
+ const message = err instanceof Error ? err.message : String(err);
43
+ return writeFailure(`failed to persist ${kindLabel} artifact: ${message}`);
44
+ }
45
+ }
46
+ /**
47
+ * Persists one already-valid `PersistentBaselineContract` as
48
+ * `<outputLocation>/<baselineId>/manifest.json`. Never mutates or removes any
49
+ * other baseline artifact - `supersedesBaselineId` (if present) is written
50
+ * exactly as supplied; this writer never inspects, rewrites, or deletes the
51
+ * baseline it refers to.
52
+ */
53
+ export async function writePersistentBaselineContract(contract, outputLocation, options = {}) {
54
+ const validation = isValidPersistentBaselineContract(contract);
55
+ if (!validation.valid)
56
+ return writeFailure(`refusing to persist an invalid PersistentBaselineContract: ${validation.reason}`);
57
+ return writeContractArtifact(contract, contract.baselineId, 'baseline contract', outputLocation, options);
58
+ }
59
+ /**
60
+ * Persists one already-valid `PerChangeContract` as
61
+ * `<outputLocation>/<contractId>/manifest.json`, symmetric with baseline
62
+ * persistence above (both share `CONTRACT_ARTIFACT_KIND`/`CONTRACT_SCHEMA_VERSION`).
63
+ */
64
+ export async function writePerChangeContract(contract, outputLocation, options = {}) {
65
+ const validation = isValidPerChangeContract(contract);
66
+ if (!validation.valid)
67
+ return writeFailure(`refusing to persist an invalid PerChangeContract: ${validation.reason}`);
68
+ return writeContractArtifact(contract, contract.contractId, 'per-change contract', outputLocation, options);
69
+ }
70
+ //# sourceMappingURL=frontendContractArtifactWriter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontendContractArtifactWriter.js","sourceRoot":"","sources":["../../src/artifacts/frontendContractArtifactWriter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { FrontendContractEvaluationArtifact } from '../domain/frontendContractEvaluationArtifact.js';
2
+ export type ReadFrontendContractEvaluationArtifactResult = {
3
+ ok: true;
4
+ artifact: FrontendContractEvaluationArtifact;
5
+ } | {
6
+ ok: false;
7
+ reason: string;
8
+ };
9
+ /**
10
+ * Narrow canonical reader counterpart to
11
+ * `frontendContractEvaluationArtifactWriter.ts#writeFrontendContractEvaluationArtifact`:
12
+ * reads one `manifest.json`, parses it, and validates it through the same
13
+ * `isValidFrontendContractEvaluationArtifact` structural gate the writer
14
+ * uses. Read-only: never mutates the file, never recomputes or reinterprets
15
+ * the evaluation, never repairs a malformed artifact.
16
+ */
17
+ export declare function readFrontendContractEvaluationArtifact(manifestPath: string): Promise<ReadFrontendContractEvaluationArtifactResult>;
@@ -0,0 +1,34 @@
1
+ import { readFile } from 'node:fs/promises';
2
+ import { isValidFrontendContractEvaluationArtifact } from '../domain/frontendContractEvaluationArtifact.js';
3
+ /**
4
+ * Narrow canonical reader counterpart to
5
+ * `frontendContractEvaluationArtifactWriter.ts#writeFrontendContractEvaluationArtifact`:
6
+ * reads one `manifest.json`, parses it, and validates it through the same
7
+ * `isValidFrontendContractEvaluationArtifact` structural gate the writer
8
+ * uses. Read-only: never mutates the file, never recomputes or reinterprets
9
+ * the evaluation, never repairs a malformed artifact.
10
+ */
11
+ export async function readFrontendContractEvaluationArtifact(manifestPath) {
12
+ let raw;
13
+ try {
14
+ raw = await readFile(manifestPath, 'utf8');
15
+ }
16
+ catch (err) {
17
+ const message = err instanceof Error ? err.message : String(err);
18
+ return { ok: false, reason: `failed to read evaluation artifact manifest at "${manifestPath}": ${message}` };
19
+ }
20
+ let parsed;
21
+ try {
22
+ parsed = JSON.parse(raw);
23
+ }
24
+ catch (err) {
25
+ const message = err instanceof Error ? err.message : String(err);
26
+ return { ok: false, reason: `evaluation artifact manifest at "${manifestPath}" is not valid JSON: ${message}` };
27
+ }
28
+ const validation = isValidFrontendContractEvaluationArtifact(parsed);
29
+ if (!validation.valid) {
30
+ return { ok: false, reason: `evaluation artifact manifest at "${manifestPath}" failed structural validation: ${validation.reason}` };
31
+ }
32
+ return { ok: true, artifact: parsed };
33
+ }
34
+ //# sourceMappingURL=frontendContractEvaluationArtifactReader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontendContractEvaluationArtifactReader.js","sourceRoot":"","sources":["../../src/artifacts/frontendContractEvaluationArtifactReader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C,OAAO,EAAE,yCAAyC,EAAE,MAAM,iDAAiD,CAAC;AAI5G;;;;;;;GAOG;AACH,MAAM,CAAC,KAAK,UAAU,sCAAsC,CAAC,YAAoB;IAC/E,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IAC7C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mDAAmD,YAAY,MAAM,OAAO,EAAE,EAAE,CAAC;IAC/G,CAAC;IAED,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,oCAAoC,YAAY,wBAAwB,OAAO,EAAE,EAAE,CAAC;IAClH,CAAC;IAED,MAAM,UAAU,GAAG,yCAAyC,CAAC,MAAM,CAAC,CAAC;IACrE,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,oCAAoC,YAAY,mCAAmC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;IACvI,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,MAA4C,EAAE,CAAC;AAC9E,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { FrontendContractEvaluationArtifact } from '../domain/frontendContractEvaluationArtifact.js';
2
+ import type { Diagnostic } from '../domain/diagnostics.js';
3
+ export declare const EVALUATION_MANIFEST_FILENAME = "manifest.json";
4
+ export type PersistedFrontendContractEvaluationResult = {
5
+ ok: true;
6
+ artifactRoot: string;
7
+ manifestPath: string;
8
+ } | {
9
+ ok: false;
10
+ diagnostics: Diagnostic[];
11
+ };
12
+ export interface WriteFrontendContractEvaluationArtifactOptions {
13
+ /** Base directory that `outputLocation` is resolved against. Defaults to `process.cwd()`. */
14
+ cwd?: string;
15
+ }
16
+ /**
17
+ * Persists one already-built, already-valid `FrontendContractEvaluationArtifact`
18
+ * as `<outputLocation>/<evaluationId>/manifest.json` only - no screenshot is
19
+ * copied (the artifact's `before`/`after` fields already point back to the
20
+ * source observations). Same atomic-write discipline as
21
+ * `artifactWriter.ts#writeObservationArtifact`/`comparisonArtifactWriter.ts#writeComparisonArtifact`
22
+ * without sharing their implementation: sibling temporary directory, then one
23
+ * atomic rename. `evaluationId` is fresh per execution (see
24
+ * `frontendContractIdentity.ts#buildFrontendContractInstanceIdentity`), so an
25
+ * existing directory at the final path is a genuine collision and is
26
+ * rejected rather than overwritten - a legitimate PASS or FAIL evaluation
27
+ * result is never silently replaced. A `FAIL` verdict is a legitimate,
28
+ * persistable evaluation result, not a write failure; only an unpersistable
29
+ * artifact (invalid shape, or a real filesystem error) is reported as
30
+ * `ok: false`.
31
+ */
32
+ export declare function writeFrontendContractEvaluationArtifact(artifact: FrontendContractEvaluationArtifact, outputLocation: string, options?: WriteFrontendContractEvaluationArtifactOptions): Promise<PersistedFrontendContractEvaluationResult>;
@@ -0,0 +1,58 @@
1
+ import { mkdir, writeFile, rename, rm, access } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { isValidFrontendContractEvaluationArtifact } from '../domain/frontendContractEvaluationArtifact.js';
4
+ import { DIAGNOSTIC_SEVERITY } from '../domain/diagnostics.js';
5
+ export const EVALUATION_MANIFEST_FILENAME = 'manifest.json';
6
+ function writeFailure(message, details) {
7
+ const diagnostic = {
8
+ code: 'artifact-write-failure',
9
+ severity: DIAGNOSTIC_SEVERITY['artifact-write-failure'],
10
+ message,
11
+ ...(details === undefined ? {} : { details }),
12
+ };
13
+ return { ok: false, diagnostics: [diagnostic] };
14
+ }
15
+ async function pathExists(candidate) {
16
+ return access(candidate).then(() => true, () => false);
17
+ }
18
+ /**
19
+ * Persists one already-built, already-valid `FrontendContractEvaluationArtifact`
20
+ * as `<outputLocation>/<evaluationId>/manifest.json` only - no screenshot is
21
+ * copied (the artifact's `before`/`after` fields already point back to the
22
+ * source observations). Same atomic-write discipline as
23
+ * `artifactWriter.ts#writeObservationArtifact`/`comparisonArtifactWriter.ts#writeComparisonArtifact`
24
+ * without sharing their implementation: sibling temporary directory, then one
25
+ * atomic rename. `evaluationId` is fresh per execution (see
26
+ * `frontendContractIdentity.ts#buildFrontendContractInstanceIdentity`), so an
27
+ * existing directory at the final path is a genuine collision and is
28
+ * rejected rather than overwritten - a legitimate PASS or FAIL evaluation
29
+ * result is never silently replaced. A `FAIL` verdict is a legitimate,
30
+ * persistable evaluation result, not a write failure; only an unpersistable
31
+ * artifact (invalid shape, or a real filesystem error) is reported as
32
+ * `ok: false`.
33
+ */
34
+ export async function writeFrontendContractEvaluationArtifact(artifact, outputLocation, options = {}) {
35
+ const validation = isValidFrontendContractEvaluationArtifact(artifact);
36
+ if (!validation.valid)
37
+ return writeFailure(`refusing to persist an invalid FrontendContractEvaluationArtifact: ${validation.reason}`);
38
+ const cwd = options.cwd ?? process.cwd();
39
+ const outputRoot = path.resolve(cwd, outputLocation);
40
+ const finalRoot = path.join(outputRoot, artifact.evaluationId);
41
+ const tempRoot = path.join(outputRoot, `.tmp-${artifact.evaluationId}`);
42
+ if (await pathExists(finalRoot)) {
43
+ return writeFailure(`an evaluation artifact already exists at "${artifact.evaluationId}"; refusing to overwrite it`, { artifactRoot: finalRoot });
44
+ }
45
+ try {
46
+ await rm(tempRoot, { recursive: true, force: true });
47
+ await mkdir(tempRoot, { recursive: true });
48
+ await writeFile(path.join(tempRoot, EVALUATION_MANIFEST_FILENAME), JSON.stringify(artifact, null, 2), 'utf8');
49
+ await rename(tempRoot, finalRoot);
50
+ return { ok: true, artifactRoot: finalRoot, manifestPath: path.join(finalRoot, EVALUATION_MANIFEST_FILENAME) };
51
+ }
52
+ catch (err) {
53
+ await rm(tempRoot, { recursive: true, force: true }).catch(() => undefined);
54
+ const message = err instanceof Error ? err.message : String(err);
55
+ return writeFailure(`failed to persist evaluation artifact: ${message}`);
56
+ }
57
+ }
58
+ //# sourceMappingURL=frontendContractEvaluationArtifactWriter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"frontendContractEvaluationArtifactWriter.js","sourceRoot":"","sources":["../../src/artifacts/frontendContractEvaluationArtifactWriter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { Diagnostic } from '../domain/diagnostics.js';
2
+ /**
3
+ * Observer-owned result of persisting one ObservationArtifact. `artifactRoot`
4
+ * and the file paths are absolute filesystem paths for the *caller's* local
5
+ * use only (e.g. to print or open the result); they are never written back
6
+ * into the persisted manifest itself, which stores only portable relative
7
+ * references.
8
+ */
9
+ export type PersistedObservationResult = {
10
+ ok: true;
11
+ artifactRoot: string;
12
+ manifestPath: string;
13
+ screenshotPath: string;
14
+ } | {
15
+ ok: false;
16
+ diagnostics: Diagnostic[];
17
+ };
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/artifacts/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,21 @@
1
+ import type { NormalizedObservationRequest } from '../request/request.js';
2
+ import type { BrowserCaptureResult } from './types.js';
3
+ export type { BrowserCaptureResult, BrowserProvenance } from './types.js';
4
+ export interface CaptureViewportInternalResult {
5
+ result: BrowserCaptureResult;
6
+ /** True if the launched browser process is still connected after cleanup ran. Always false unless cleanup failed. */
7
+ browserConnected: boolean;
8
+ }
9
+ /**
10
+ * Owns the entire launch -> context -> page -> navigate -> ready -> screenshot
11
+ * -> close lifecycle for one capture. Guarantees `browser.close()` runs on
12
+ * every exit path (success, safety rejection, navigation/readiness failure,
13
+ * or an unexpected internal error), so callers never manage cleanup
14
+ * themselves. Exported (not re-exported from src/index.ts or the application
15
+ * seam) only so integration tests can assert `browserConnected` becomes
16
+ * false after every call - the Browser handle itself never leaves this
17
+ * module.
18
+ */
19
+ export declare function captureViewportInternal(request: NormalizedObservationRequest): Promise<CaptureViewportInternalResult>;
20
+ /** Observer-facing entrypoint: no Playwright object is reachable from its signature or return value. */
21
+ export declare function captureViewport(request: NormalizedObservationRequest): Promise<BrowserCaptureResult>;
@@ -0,0 +1,204 @@
1
+ import { chromium } from 'playwright';
2
+ import { DIAGNOSTIC_SEVERITY } from '../domain/diagnostics.js';
3
+ import { classifyUrl, classifyRedirect, classifySubresource, classifyPopup, classifyDownload } from '../safety/policy.js';
4
+ import { capturePageEvidence, captureTargetEvidence, resolveConfiguredTargets, findResolvedTarget } from './evidenceCapture.js';
5
+ import { captureScrollRuntimeSnapshot, performWindowScrollBy, performTargetScrollBy, waitTwoAnimationFrames } from './scrollCapture.js';
6
+ import { deriveScrollScenarioTransition, deriveScrollOwner } from '../domain/scrollEvidence.js';
7
+ function diagnostic(code, message) {
8
+ return { code, severity: DIAGNOSTIC_SEVERITY[code], message };
9
+ }
10
+ function classifyNavigationError(error, readinessTimeoutMs) {
11
+ const message = error instanceof Error ? error.message : String(error);
12
+ if (/timeout/i.test(message)) {
13
+ return diagnostic('readiness-timeout', `readiness condition not reached within ${readinessTimeoutMs}ms: ${message}`);
14
+ }
15
+ return diagnostic('navigation-failure', `navigation failed: ${message}`);
16
+ }
17
+ /**
18
+ * Owns the entire launch -> context -> page -> navigate -> ready -> screenshot
19
+ * -> close lifecycle for one capture. Guarantees `browser.close()` runs on
20
+ * every exit path (success, safety rejection, navigation/readiness failure,
21
+ * or an unexpected internal error), so callers never manage cleanup
22
+ * themselves. Exported (not re-exported from src/index.ts or the application
23
+ * seam) only so integration tests can assert `browserConnected` becomes
24
+ * false after every call - the Browser handle itself never leaves this
25
+ * module.
26
+ */
27
+ export async function captureViewportInternal(request) {
28
+ const initialDecision = classifyUrl(request.targetUrl);
29
+ if (!initialDecision.allowed) {
30
+ return { result: { ok: false, diagnostics: [initialDecision.diagnostic] }, browserConnected: false };
31
+ }
32
+ let browser;
33
+ let result;
34
+ try {
35
+ browser = await chromium.launch({ headless: true });
36
+ const context = await browser.newContext({
37
+ viewport: { width: request.viewport.width, height: request.viewport.height },
38
+ });
39
+ const page = await context.newPage();
40
+ const diagnostics = [];
41
+ page.on('popup', () => diagnostics.push(classifyPopup()));
42
+ page.on('download', () => diagnostics.push(classifyDownload()));
43
+ let lastAllowedMainFrameUrl = request.targetUrl;
44
+ let rejection;
45
+ await page.route('**/*', async (route) => {
46
+ const req = route.request();
47
+ const url = req.url();
48
+ const isMainFrameNavigation = req.isNavigationRequest() && req.frame() === page.mainFrame();
49
+ if (!isMainFrameNavigation) {
50
+ const decision = classifySubresource(url);
51
+ if (!decision.allowed) {
52
+ rejection = rejection ?? decision.diagnostic;
53
+ await route.abort('blockedbyclient').catch(() => undefined);
54
+ return;
55
+ }
56
+ await route.continue().catch(() => undefined);
57
+ return;
58
+ }
59
+ // Chromium follows navigation redirects internally without re-emitting a
60
+ // routable request per hop, so each main-frame hop is fetched manually
61
+ // (maxRedirects: 0) and inspected here before any further hop is
62
+ // allowed to proceed - this is what lets a prohibited redirect target
63
+ // be blocked before it is ever contacted.
64
+ const decision = url === lastAllowedMainFrameUrl ? { allowed: true } : classifyRedirect(lastAllowedMainFrameUrl, url);
65
+ if (!decision.allowed) {
66
+ rejection = rejection ?? decision.diagnostic;
67
+ await route.fulfill({ status: 204, body: '' }).catch(() => undefined);
68
+ return;
69
+ }
70
+ lastAllowedMainFrameUrl = url;
71
+ let response;
72
+ try {
73
+ response = await route.fetch({ maxRedirects: 0 });
74
+ }
75
+ catch {
76
+ await route.abort('failed').catch(() => undefined);
77
+ return;
78
+ }
79
+ const status = response.status();
80
+ if (status >= 300 && status < 400) {
81
+ const location = response.headers()['location'];
82
+ const resolvedUrl = location ? new URL(location, url).toString() : undefined;
83
+ const redirectDecision = resolvedUrl ? classifyRedirect(lastAllowedMainFrameUrl, resolvedUrl) : { allowed: true };
84
+ if (!redirectDecision.allowed) {
85
+ rejection = rejection ?? redirectDecision.diagnostic;
86
+ await route.fulfill({ status: 204, body: '' }).catch(() => undefined);
87
+ return;
88
+ }
89
+ }
90
+ await route.fulfill({ response }).catch(() => undefined);
91
+ });
92
+ let navigationError;
93
+ try {
94
+ await page.goto(request.targetUrl, {
95
+ waitUntil: request.readiness.condition,
96
+ timeout: request.readiness.timeoutMs,
97
+ });
98
+ }
99
+ catch (err) {
100
+ navigationError = err;
101
+ }
102
+ if (rejection) {
103
+ result = { ok: false, diagnostics: [rejection, ...diagnostics] };
104
+ }
105
+ else if (navigationError) {
106
+ result = { ok: false, diagnostics: [...diagnostics, classifyNavigationError(navigationError, request.readiness.timeoutMs)] };
107
+ }
108
+ else {
109
+ // v0.3 Batch 2/3: for a scenario request, resolve configured targets
110
+ // exactly once (reusing the same canonical resolveConfiguredTargets
111
+ // algorithm captureTargetEvidence uses below), capture the initial
112
+ // runtime snapshot, perform the one immediate scroll action (window or
113
+ // the uniquely-resolved action target - same two-animation-frame
114
+ // stabilization either way), and capture the final runtime snapshot -
115
+ // all before the screenshot and ordinary page/target evidence below,
116
+ // so every one of those downstream captures describes only the final
117
+ // post-action state. No second navigation, page, or observation ever
118
+ // happens.
119
+ let scrollScenarioEvidence;
120
+ if (request.scrollScenario) {
121
+ const action = request.scrollScenario.action;
122
+ const resolvedForScenario = await resolveConfiguredTargets(page, request.targets);
123
+ try {
124
+ const initial = await captureScrollRuntimeSnapshot(page, resolvedForScenario, request.viewport);
125
+ if (action.kind === 'window-scroll-by') {
126
+ await performWindowScrollBy(page, action.deltaX, action.deltaY);
127
+ }
128
+ else {
129
+ const actionTarget = findResolvedTarget(resolvedForScenario, action.target);
130
+ if (actionTarget?.status === 'matched' && actionTarget.handle) {
131
+ await performTargetScrollBy(actionTarget.handle, action.deltaX, action.deltaY);
132
+ }
133
+ // else: the configured action target could not be uniquely
134
+ // resolved at runtime (not-found/ambiguous/unavailable) - no
135
+ // scroll is performed and no movement is fabricated. The
136
+ // existing target-missing/target-ambiguous/target-hidden/
137
+ // browser-evidence-unavailable diagnostic for this same target
138
+ // name still surfaces below from the ordinary
139
+ // captureTargetEvidence pass, so the unresolved action target
140
+ // remains honestly explained rather than silently ignored.
141
+ }
142
+ await waitTwoAnimationFrames(page);
143
+ const final = await captureScrollRuntimeSnapshot(page, resolvedForScenario, request.viewport);
144
+ const transition = deriveScrollScenarioTransition(initial, final);
145
+ const scrollOwner = deriveScrollOwner(transition);
146
+ scrollScenarioEvidence = { initial, final, transition, scrollOwner };
147
+ }
148
+ finally {
149
+ await Promise.all(resolvedForScenario.filter((info) => info.handle).map((info) => info.handle.dispose()));
150
+ }
151
+ }
152
+ // Captured from the same live page, after the same readiness point (and,
153
+ // for a scenario request, after the scroll action above), as required by
154
+ // Batch 3/v0.3 Batch 2: no second browser/page is ever opened.
155
+ const screenshotBuffer = await page.screenshot({ type: 'png' });
156
+ const provenance = { engine: 'chromium', version: browser.version() };
157
+ let pageEvidence;
158
+ try {
159
+ pageEvidence = await capturePageEvidence(page, request.targetUrl, request.viewport);
160
+ }
161
+ catch (err) {
162
+ const message = err instanceof Error ? err.message : String(err);
163
+ diagnostics.push(diagnostic('browser-evidence-unavailable', `page evidence collection failed: ${message}`));
164
+ pageEvidence = {};
165
+ }
166
+ let targetEvidence;
167
+ try {
168
+ const captured = await captureTargetEvidence(page, request.targets);
169
+ targetEvidence = captured.targetEvidence;
170
+ diagnostics.push(...captured.diagnostics);
171
+ }
172
+ catch (err) {
173
+ const message = err instanceof Error ? err.message : String(err);
174
+ diagnostics.push(diagnostic('browser-evidence-unavailable', `target evidence collection failed: ${message}`));
175
+ targetEvidence = {};
176
+ }
177
+ result = {
178
+ ok: true,
179
+ provenance,
180
+ screenshot: new Uint8Array(screenshotBuffer),
181
+ pageEvidence,
182
+ targetEvidence,
183
+ diagnostics,
184
+ ...(scrollScenarioEvidence ? { scrollScenarioEvidence } : {}),
185
+ };
186
+ }
187
+ }
188
+ catch (err) {
189
+ const message = err instanceof Error ? err.message : String(err);
190
+ result = { ok: false, diagnostics: [diagnostic('browser-runtime-failure', `unexpected browser failure: ${message}`)] };
191
+ }
192
+ finally {
193
+ if (browser) {
194
+ await browser.close().catch(() => undefined);
195
+ }
196
+ }
197
+ return { result, browserConnected: browser ? browser.isConnected() : false };
198
+ }
199
+ /** Observer-facing entrypoint: no Playwright object is reachable from its signature or return value. */
200
+ export async function captureViewport(request) {
201
+ const { result } = await captureViewportInternal(request);
202
+ return result;
203
+ }
204
+ //# sourceMappingURL=chromiumAdapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chromiumAdapter.js","sourceRoot":"","sources":["../../src/browser/chromiumAdapter.ts"],"names":[],"mappings":"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"}