@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
Binary file
Binary file
@@ -0,0 +1,15 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <meta name="viewport" content="width=device-width, initial-scale=1" />
6
+ <meta name="theme-color" content="#0f172a" />
7
+ <title>my-frontend-observer Viewer</title>
8
+ <link rel="icon" type="image/png" href="/icons/icon-192.png" />
9
+ <script type="module" crossorigin src="/assets/index-D98S1_2d.js"></script>
10
+ <link rel="stylesheet" crossorigin href="/assets/index-CN_yb9Uf.css">
11
+ <link rel="manifest" href="/manifest.webmanifest"><script id="vite-plugin-pwa:register-sw" src="/registerSW.js"></script></head>
12
+ <body>
13
+ <div id="root"></div>
14
+ </body>
15
+ </html>
@@ -0,0 +1 @@
1
+ {"name":"my-frontend-observer Viewer","short_name":"Observer Viewer","description":"Local-first interactive viewer for my-frontend-observer runtime evidence.","start_url":"/","display":"standalone","background_color":"#0f172a","theme_color":"#0f172a","lang":"en","scope":"/","icons":[{"src":"icons/icon-192.png","sizes":"192x192","type":"image/png"},{"src":"icons/icon-512.png","sizes":"512x512","type":"image/png"}]}
@@ -0,0 +1 @@
1
+ if('serviceWorker' in navigator) {window.addEventListener('load', () => {navigator.serviceWorker.register('/sw.js', { scope: '/' })})}
@@ -0,0 +1 @@
1
+ if(!self.define){let e,i={};const n=(n,s)=>(n=new URL(n+".js",s).href,i[n]||new Promise(i=>{if("document"in self){const e=document.createElement("script");e.src=n,e.onload=i,document.head.appendChild(e)}else e=n,importScripts(n),i()}).then(()=>{let e=i[n];if(!e)throw new Error(`Module ${n} didn’t register its module`);return e}));self.define=(s,r)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(i[o])return;let c={};const t=e=>n(e,o),d={module:{uri:o},exports:c,require:t};i[o]=Promise.all(s.map(e=>d[e]||t(e))).then(e=>(r(...e),c))}}define(["./workbox-9c191d2f"],function(e){"use strict";self.skipWaiting(),e.clientsClaim(),e.precacheAndRoute([{url:"registerSW.js",revision:"1872c500de691dce40960bb85481de07"},{url:"manifest.webmanifest",revision:"230563056861fe6705b913b3df23b258"},{url:"index.html",revision:"5cb88d42b2c80bd6eb33a9928a9463d9"},{url:"icons/icon-512.png",revision:"e92e70cceb9b8d7f52ea0cfe9099e7de"},{url:"icons/icon-192.png",revision:"175e5f2a92d509b08ccf2a917bb400f6"},{url:"assets/index-D98S1_2d.js",revision:null},{url:"assets/index-CN_yb9Uf.css",revision:null},{url:"icons/icon-192.png",revision:"175e5f2a92d509b08ccf2a917bb400f6"},{url:"icons/icon-512.png",revision:"e92e70cceb9b8d7f52ea0cfe9099e7de"},{url:"manifest.webmanifest",revision:"230563056861fe6705b913b3df23b258"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("index.html"),{denylist:[/^\/api\//]}))});
@@ -0,0 +1 @@
1
+ define(["exports"],function(t){"use strict";try{self["workbox:core:7.4.0"]&&_()}catch(t){}const e=(t,...e)=>{let s=t;return e.length>0&&(s+=` :: ${JSON.stringify(e)}`),s};class s extends Error{constructor(t,s){super(e(t,s)),this.name=t,this.details=s}}try{self["workbox:routing:7.4.0"]&&_()}catch(t){}const n=t=>t&&"object"==typeof t?t:{handle:t};class i{constructor(t,e,s="GET"){this.handler=n(e),this.match=t,this.method=s}setCatchHandler(t){this.catchHandler=n(t)}}class r extends i{constructor(t,e,s){super(({url:e})=>{const s=t.exec(e.href);if(s&&(e.origin===location.origin||0===s.index))return s.slice(1)},e,s)}}class o{constructor(){this.t=new Map,this.i=new Map}get routes(){return this.t}addFetchListener(){self.addEventListener("fetch",t=>{const{request:e}=t,s=this.handleRequest({request:e,event:t});s&&t.respondWith(s)})}addCacheListener(){self.addEventListener("message",t=>{if(t.data&&"CACHE_URLS"===t.data.type){const{payload:e}=t.data,s=Promise.all(e.urlsToCache.map(e=>{"string"==typeof e&&(e=[e]);const s=new Request(...e);return this.handleRequest({request:s,event:t})}));t.waitUntil(s),t.ports&&t.ports[0]&&s.then(()=>t.ports[0].postMessage(!0))}})}handleRequest({request:t,event:e}){const s=new URL(t.url,location.href);if(!s.protocol.startsWith("http"))return;const n=s.origin===location.origin,{params:i,route:r}=this.findMatchingRoute({event:e,request:t,sameOrigin:n,url:s});let o=r&&r.handler;const c=t.method;if(!o&&this.i.has(c)&&(o=this.i.get(c)),!o)return;let a;try{a=o.handle({url:s,request:t,event:e,params:i})}catch(t){a=Promise.reject(t)}const h=r&&r.catchHandler;return a instanceof Promise&&(this.o||h)&&(a=a.catch(async n=>{if(h)try{return await h.handle({url:s,request:t,event:e,params:i})}catch(t){t instanceof Error&&(n=t)}if(this.o)return this.o.handle({url:s,request:t,event:e});throw n})),a}findMatchingRoute({url:t,sameOrigin:e,request:s,event:n}){const i=this.t.get(s.method)||[];for(const r of i){let i;const o=r.match({url:t,sameOrigin:e,request:s,event:n});if(o)return i=o,(Array.isArray(i)&&0===i.length||o.constructor===Object&&0===Object.keys(o).length||"boolean"==typeof o)&&(i=void 0),{route:r,params:i}}return{}}setDefaultHandler(t,e="GET"){this.i.set(e,n(t))}setCatchHandler(t){this.o=n(t)}registerRoute(t){this.t.has(t.method)||this.t.set(t.method,[]),this.t.get(t.method).push(t)}unregisterRoute(t){if(!this.t.has(t.method))throw new s("unregister-route-but-not-found-with-method",{method:t.method});const e=this.t.get(t.method).indexOf(t);if(!(e>-1))throw new s("unregister-route-route-not-registered");this.t.get(t.method).splice(e,1)}}let c;const a=()=>(c||(c=new o,c.addFetchListener(),c.addCacheListener()),c);function h(t,e,n){let o;if("string"==typeof t){const s=new URL(t,location.href);o=new i(({url:t})=>t.href===s.href,e,n)}else if(t instanceof RegExp)o=new r(t,e,n);else if("function"==typeof t)o=new i(t,e,n);else{if(!(t instanceof i))throw new s("unsupported-route-type",{moduleName:"workbox-routing",funcName:"registerRoute",paramName:"capture"});o=t}return a().registerRoute(o),o}const u={googleAnalytics:"googleAnalytics",precache:"precache-v2",prefix:"workbox",runtime:"runtime",suffix:"undefined"!=typeof registration?registration.scope:""},l=t=>[u.prefix,t,u.suffix].filter(t=>t&&t.length>0).join("-"),f=t=>t||l(u.precache),w=t=>t||l(u.runtime);function d(t,e){const s=e();return t.waitUntil(s),s}try{self["workbox:precaching:7.4.0"]&&_()}catch(t){}function p(t){if(!t)throw new s("add-to-cache-list-unexpected-type",{entry:t});if("string"==typeof t){const e=new URL(t,location.href);return{cacheKey:e.href,url:e.href}}const{revision:e,url:n}=t;if(!n)throw new s("add-to-cache-list-unexpected-type",{entry:t});if(!e){const t=new URL(n,location.href);return{cacheKey:t.href,url:t.href}}const i=new URL(n,location.href),r=new URL(n,location.href);return i.searchParams.set("__WB_REVISION__",e),{cacheKey:i.href,url:r.href}}class y{constructor(){this.updatedURLs=[],this.notUpdatedURLs=[],this.handlerWillStart=async({request:t,state:e})=>{e&&(e.originalRequest=t)},this.cachedResponseWillBeUsed=async({event:t,state:e,cachedResponse:s})=>{if("install"===t.type&&e&&e.originalRequest&&e.originalRequest instanceof Request){const t=e.originalRequest.url;s?this.notUpdatedURLs.push(t):this.updatedURLs.push(t)}return s}}}class g{constructor({precacheController:t}){this.cacheKeyWillBeUsed=async({request:t,params:e})=>{const s=(null==e?void 0:e.cacheKey)||this.h.getCacheKeyForURL(t.url);return s?new Request(s,{headers:t.headers}):t},this.h=t}}let R;async function m(t,e){let n=null;if(t.url){n=new URL(t.url).origin}if(n!==self.location.origin)throw new s("cross-origin-copy-response",{origin:n});const i=t.clone(),r={headers:new Headers(i.headers),status:i.status,statusText:i.statusText},o=function(){if(void 0===R){const t=new Response("");if("body"in t)try{new Response(t.body),R=!0}catch(t){R=!1}R=!1}return R}()?i.body:await i.blob();return new Response(o,r)}function v(t,e){const s=new URL(t);for(const t of e)s.searchParams.delete(t);return s.href}class q{constructor(){this.promise=new Promise((t,e)=>{this.resolve=t,this.reject=e})}}const U=new Set;try{self["workbox:strategies:7.4.0"]&&_()}catch(t){}function L(t){return"string"==typeof t?new Request(t):t}class b{constructor(t,e){this.u={},Object.assign(this,e),this.event=e.event,this.l=t,this.p=new q,this.R=[],this.m=[...t.plugins],this.v=new Map;for(const t of this.m)this.v.set(t,{});this.event.waitUntil(this.p.promise)}async fetch(t){const{event:e}=this;let n=L(t);if("navigate"===n.mode&&e instanceof FetchEvent&&e.preloadResponse){const t=await e.preloadResponse;if(t)return t}const i=this.hasCallback("fetchDidFail")?n.clone():null;try{for(const t of this.iterateCallbacks("requestWillFetch"))n=await t({request:n.clone(),event:e})}catch(t){if(t instanceof Error)throw new s("plugin-error-request-will-fetch",{thrownErrorMessage:t.message})}const r=n.clone();try{let t;t=await fetch(n,"navigate"===n.mode?void 0:this.l.fetchOptions);for(const s of this.iterateCallbacks("fetchDidSucceed"))t=await s({event:e,request:r,response:t});return t}catch(t){throw i&&await this.runCallbacks("fetchDidFail",{error:t,event:e,originalRequest:i.clone(),request:r.clone()}),t}}async fetchAndCachePut(t){const e=await this.fetch(t),s=e.clone();return this.waitUntil(this.cachePut(t,s)),e}async cacheMatch(t){const e=L(t);let s;const{cacheName:n,matchOptions:i}=this.l,r=await this.getCacheKey(e,"read"),o=Object.assign(Object.assign({},i),{cacheName:n});s=await caches.match(r,o);for(const t of this.iterateCallbacks("cachedResponseWillBeUsed"))s=await t({cacheName:n,matchOptions:i,cachedResponse:s,request:r,event:this.event})||void 0;return s}async cachePut(t,e){const n=L(t);var i;await(i=0,new Promise(t=>setTimeout(t,i)));const r=await this.getCacheKey(n,"write");if(!e)throw new s("cache-put-with-no-response",{url:(o=r.url,new URL(String(o),location.href).href.replace(new RegExp(`^${location.origin}`),""))});var o;const c=await this.q(e);if(!c)return!1;const{cacheName:a,matchOptions:h}=this.l,u=await self.caches.open(a),l=this.hasCallback("cacheDidUpdate"),f=l?await async function(t,e,s,n){const i=v(e.url,s);if(e.url===i)return t.match(e,n);const r=Object.assign(Object.assign({},n),{ignoreSearch:!0}),o=await t.keys(e,r);for(const e of o)if(i===v(e.url,s))return t.match(e,n)}(u,r.clone(),["__WB_REVISION__"],h):null;try{await u.put(r,l?c.clone():c)}catch(t){if(t instanceof Error)throw"QuotaExceededError"===t.name&&await async function(){for(const t of U)await t()}(),t}for(const t of this.iterateCallbacks("cacheDidUpdate"))await t({cacheName:a,oldResponse:f,newResponse:c.clone(),request:r,event:this.event});return!0}async getCacheKey(t,e){const s=`${t.url} | ${e}`;if(!this.u[s]){let n=t;for(const t of this.iterateCallbacks("cacheKeyWillBeUsed"))n=L(await t({mode:e,request:n,event:this.event,params:this.params}));this.u[s]=n}return this.u[s]}hasCallback(t){for(const e of this.l.plugins)if(t in e)return!0;return!1}async runCallbacks(t,e){for(const s of this.iterateCallbacks(t))await s(e)}*iterateCallbacks(t){for(const e of this.l.plugins)if("function"==typeof e[t]){const s=this.v.get(e),n=n=>{const i=Object.assign(Object.assign({},n),{state:s});return e[t](i)};yield n}}waitUntil(t){return this.R.push(t),t}async doneWaiting(){for(;this.R.length;){const t=this.R.splice(0),e=(await Promise.allSettled(t)).find(t=>"rejected"===t.status);if(e)throw e.reason}}destroy(){this.p.resolve(null)}async q(t){let e=t,s=!1;for(const t of this.iterateCallbacks("cacheWillUpdate"))if(e=await t({request:this.request,response:e,event:this.event})||void 0,s=!0,!e)break;return s||e&&200!==e.status&&(e=void 0),e}}class C{constructor(t={}){this.cacheName=w(t.cacheName),this.plugins=t.plugins||[],this.fetchOptions=t.fetchOptions,this.matchOptions=t.matchOptions}handle(t){const[e]=this.handleAll(t);return e}handleAll(t){t instanceof FetchEvent&&(t={event:t,request:t.request});const e=t.event,s="string"==typeof t.request?new Request(t.request):t.request,n="params"in t?t.params:void 0,i=new b(this,{event:e,request:s,params:n}),r=this.U(i,s,e);return[r,this.L(r,i,s,e)]}async U(t,e,n){let i;await t.runCallbacks("handlerWillStart",{event:n,request:e});try{if(i=await this._(e,t),!i||"error"===i.type)throw new s("no-response",{url:e.url})}catch(s){if(s instanceof Error)for(const r of t.iterateCallbacks("handlerDidError"))if(i=await r({error:s,event:n,request:e}),i)break;if(!i)throw s}for(const s of t.iterateCallbacks("handlerWillRespond"))i=await s({event:n,request:e,response:i});return i}async L(t,e,s,n){let i,r;try{i=await t}catch(r){}try{await e.runCallbacks("handlerDidRespond",{event:n,request:s,response:i}),await e.doneWaiting()}catch(t){t instanceof Error&&(r=t)}if(await e.runCallbacks("handlerDidComplete",{event:n,request:s,response:i,error:r}),e.destroy(),r)throw r}}class E extends C{constructor(t={}){t.cacheName=f(t.cacheName),super(t),this.C=!1!==t.fallbackToNetwork,this.plugins.push(E.copyRedirectedCacheableResponsesPlugin)}async _(t,e){const s=await e.cacheMatch(t);return s||(e.event&&"install"===e.event.type?await this.O(t,e):await this.N(t,e))}async N(t,e){let n;const i=e.params||{};if(!this.C)throw new s("missing-precache-entry",{cacheName:this.cacheName,url:t.url});{const s=i.integrity,r=t.integrity,o=!r||r===s;n=await e.fetch(new Request(t,{integrity:"no-cors"!==t.mode?r||s:void 0})),s&&o&&"no-cors"!==t.mode&&(this.P(),await e.cachePut(t,n.clone()))}return n}async O(t,e){this.P();const n=await e.fetch(t);if(!await e.cachePut(t,n.clone()))throw new s("bad-precaching-response",{url:t.url,status:n.status});return n}P(){let t=null,e=0;for(const[s,n]of this.plugins.entries())n!==E.copyRedirectedCacheableResponsesPlugin&&(n===E.defaultPrecacheCacheabilityPlugin&&(t=s),n.cacheWillUpdate&&e++);0===e?this.plugins.push(E.defaultPrecacheCacheabilityPlugin):e>1&&null!==t&&this.plugins.splice(t,1)}}E.defaultPrecacheCacheabilityPlugin={cacheWillUpdate:async({response:t})=>!t||t.status>=400?null:t},E.copyRedirectedCacheableResponsesPlugin={cacheWillUpdate:async({response:t})=>t.redirected?await m(t):t};class O{constructor({cacheName:t,plugins:e=[],fallbackToNetwork:s=!0}={}){this.j=new Map,this.k=new Map,this.K=new Map,this.l=new E({cacheName:f(t),plugins:[...e,new g({precacheController:this})],fallbackToNetwork:s}),this.install=this.install.bind(this),this.activate=this.activate.bind(this)}get strategy(){return this.l}precache(t){this.addToCacheList(t),this.T||(self.addEventListener("install",this.install),self.addEventListener("activate",this.activate),this.T=!0)}addToCacheList(t){const e=[];for(const n of t){"string"==typeof n?e.push(n):n&&void 0===n.revision&&e.push(n.url);const{cacheKey:t,url:i}=p(n),r="string"!=typeof n&&n.revision?"reload":"default";if(this.j.has(i)&&this.j.get(i)!==t)throw new s("add-to-cache-list-conflicting-entries",{firstEntry:this.j.get(i),secondEntry:t});if("string"!=typeof n&&n.integrity){if(this.K.has(t)&&this.K.get(t)!==n.integrity)throw new s("add-to-cache-list-conflicting-integrities",{url:i});this.K.set(t,n.integrity)}if(this.j.set(i,t),this.k.set(i,r),e.length>0){const t=`Workbox is precaching URLs without revision info: ${e.join(", ")}\nThis is generally NOT safe. Learn more at https://bit.ly/wb-precache`;console.warn(t)}}}install(t){return d(t,async()=>{const e=new y;this.strategy.plugins.push(e);for(const[e,s]of this.j){const n=this.K.get(s),i=this.k.get(e),r=new Request(e,{integrity:n,cache:i,credentials:"same-origin"});await Promise.all(this.strategy.handleAll({params:{cacheKey:s},request:r,event:t}))}const{updatedURLs:s,notUpdatedURLs:n}=e;return{updatedURLs:s,notUpdatedURLs:n}})}activate(t){return d(t,async()=>{const t=await self.caches.open(this.strategy.cacheName),e=await t.keys(),s=new Set(this.j.values()),n=[];for(const i of e)s.has(i.url)||(await t.delete(i),n.push(i.url));return{deletedURLs:n}})}getURLsToCacheKeys(){return this.j}getCachedURLs(){return[...this.j.keys()]}getCacheKeyForURL(t){const e=new URL(t,location.href);return this.j.get(e.href)}getIntegrityForCacheKey(t){return this.K.get(t)}async matchPrecache(t){const e=t instanceof Request?t.url:t,s=this.getCacheKeyForURL(e);if(s){return(await self.caches.open(this.strategy.cacheName)).match(s)}}createHandlerBoundToURL(t){const e=this.getCacheKeyForURL(t);if(!e)throw new s("non-precached-url",{url:t});return s=>(s.request=new Request(t),s.params=Object.assign({cacheKey:e},s.params),this.strategy.handle(s))}}let x;const N=()=>(x||(x=new O),x);class P extends i{constructor(t,e){super(({request:s})=>{const n=t.getURLsToCacheKeys();for(const i of function*(t,{ignoreURLParametersMatching:e=[/^utm_/,/^fbclid$/],directoryIndex:s="index.html",cleanURLs:n=!0,urlManipulation:i}={}){const r=new URL(t,location.href);r.hash="",yield r.href;const o=function(t,e=[]){for(const s of[...t.searchParams.keys()])e.some(t=>t.test(s))&&t.searchParams.delete(s);return t}(r,e);if(yield o.href,s&&o.pathname.endsWith("/")){const t=new URL(o.href);t.pathname+=s,yield t.href}if(n){const t=new URL(o.href);t.pathname+=".html",yield t.href}if(i){const t=i({url:r});for(const e of t)yield e.href}}(s.url,e)){const e=n.get(i);if(e){return{cacheKey:e,integrity:t.getIntegrityForCacheKey(e)}}}},t.strategy)}}t.NavigationRoute=class extends i{constructor(t,{allowlist:e=[/./],denylist:s=[]}={}){super(t=>this.W(t),t),this.M=e,this.S=s}W({url:t,request:e}){if(e&&"navigate"!==e.mode)return!1;const s=t.pathname+t.search;for(const t of this.S)if(t.test(s))return!1;return!!this.M.some(t=>t.test(s))}},t.cleanupOutdatedCaches=function(){self.addEventListener("activate",t=>{const e=f();t.waitUntil((async(t,e="-precache-")=>{const s=(await self.caches.keys()).filter(s=>s.includes(e)&&s.includes(self.registration.scope)&&s!==t);return await Promise.all(s.map(t=>self.caches.delete(t))),s})(e).then(t=>{}))})},t.clientsClaim=function(){self.addEventListener("activate",()=>self.clients.claim())},t.createHandlerBoundToURL=function(t){return N().createHandlerBoundToURL(t)},t.precacheAndRoute=function(t,e){!function(t){N().precache(t)}(t),function(t){const e=N();h(new P(e,t))}(e)},t.registerRoute=h});
@@ -0,0 +1,48 @@
1
+ import type { BoundedAgentContextArtifact } from '../domain/boundedAgentContext.js';
2
+ /**
3
+ * Reuses the existing Batch 2 bounded manifest-read size limit
4
+ * (`MAX_MANIFEST_CANDIDATE_BYTES`, 2,000,000 bytes) rather than inventing a
5
+ * second bound: a `BoundedAgentContextArtifact` is, by its own frozen
6
+ * contract, already far smaller than that in any realistic case (at most 25
7
+ * targets, 25 correlation records with at most 5 candidates each, 15
8
+ * fidelity mismatches, etc. - see `src/domain/boundedAgentContext.ts`'s own
9
+ * `MAX_*` constants) - the same "generous headroom, never an arbitrarily
10
+ * large read" rationale applies unchanged.
11
+ */
12
+ export declare const MAX_CONTEXT_FILE_BYTES = 2000000;
13
+ /**
14
+ * Session state for the bounded-agent-context the viewer was explicitly
15
+ * started with. `'none'` when no `--context-file` was supplied at all -
16
+ * every Batch 1-6 feature remains fully available in this state, and the
17
+ * viewer never fabricates a context nor infers one from currently-selected
18
+ * evidence. `'unsupported-version'` is a distinct, honest state for a
19
+ * recognized-kind context whose `schemaVersion` is not the currently
20
+ * supported one - never coerced into (or displayed as) the current shape.
21
+ */
22
+ export type ContextSessionState = {
23
+ status: 'none';
24
+ } | {
25
+ status: 'unsupported-version';
26
+ foundSchemaVersion: string;
27
+ } | {
28
+ status: 'valid';
29
+ artifact: BoundedAgentContextArtifact;
30
+ };
31
+ export type ClassifyContextFileResult = {
32
+ ok: true;
33
+ state: ContextSessionState;
34
+ } | {
35
+ ok: false;
36
+ error: string;
37
+ };
38
+ /**
39
+ * Classifies one already-parsed JSON value as an explicit `--context-file`
40
+ * root (task §12: the file *is* one `BoundedAgentContextArtifact` value
41
+ * directly - no wrapper object). Fails closed (a startup error, per task
42
+ * §17) on a non-object root, a wrong `artifactKind`, or a current-schema
43
+ * artifact that is structurally invalid. A recognized kind with a
44
+ * different, non-current `schemaVersion` is reported as the honest
45
+ * `'unsupported-version'` state rather than a failure (task §16) - the
46
+ * caller (`runViewCommand`) still starts the viewer in that case.
47
+ */
48
+ export declare function classifyContextFileContent(parsed: unknown): ClassifyContextFileResult;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * v0.8 Batch 7: the narrowest possible viewer-session context-input
3
+ * boundary. `BoundedAgentContextArtifact` remains programmatic-only in the
4
+ * current product workflow (no filesystem writer/reader contract exists for
5
+ * it as an Observer evidence-root artifact family - see
6
+ * `src/viewerServer/evidence/classify.ts`'s own comment on the "known but
7
+ * unreadered" kind) - this module does not change that. It only inspects
8
+ * and validates an explicit, caller-supplied JSON value (the parsed
9
+ * contents of an operator-supplied `--context-file`) against the existing
10
+ * canonical `isValidBoundedAgentContextArtifact` - never a second validator,
11
+ * never a normalization/rewrite of the supplied value, never a call to
12
+ * `projectBoundedAgentContext` or any correlation-derivation function.
13
+ *
14
+ * Byte-reading and JSON parsing remain owned by `src/cli.ts` (mirroring the
15
+ * existing `loadBindingsFile` boundary exactly); this module receives only
16
+ * the already-parsed JSON value.
17
+ */
18
+ import { BOUNDED_AGENT_CONTEXT_ARTIFACT_KIND, BOUNDED_AGENT_CONTEXT_SCHEMA_VERSION, isValidBoundedAgentContextArtifact } from '../domain/boundedAgentContext.js';
19
+ /**
20
+ * Reuses the existing Batch 2 bounded manifest-read size limit
21
+ * (`MAX_MANIFEST_CANDIDATE_BYTES`, 2,000,000 bytes) rather than inventing a
22
+ * second bound: a `BoundedAgentContextArtifact` is, by its own frozen
23
+ * contract, already far smaller than that in any realistic case (at most 25
24
+ * targets, 25 correlation records with at most 5 candidates each, 15
25
+ * fidelity mismatches, etc. - see `src/domain/boundedAgentContext.ts`'s own
26
+ * `MAX_*` constants) - the same "generous headroom, never an arbitrarily
27
+ * large read" rationale applies unchanged.
28
+ */
29
+ export const MAX_CONTEXT_FILE_BYTES = 2_000_000;
30
+ function isPlainObject(value) {
31
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
32
+ }
33
+ /**
34
+ * Classifies one already-parsed JSON value as an explicit `--context-file`
35
+ * root (task §12: the file *is* one `BoundedAgentContextArtifact` value
36
+ * directly - no wrapper object). Fails closed (a startup error, per task
37
+ * §17) on a non-object root, a wrong `artifactKind`, or a current-schema
38
+ * artifact that is structurally invalid. A recognized kind with a
39
+ * different, non-current `schemaVersion` is reported as the honest
40
+ * `'unsupported-version'` state rather than a failure (task §16) - the
41
+ * caller (`runViewCommand`) still starts the viewer in that case.
42
+ */
43
+ export function classifyContextFileContent(parsed) {
44
+ if (!isPlainObject(parsed)) {
45
+ return { ok: false, error: '--context-file root must be a JSON object representing one BoundedAgentContextArtifact value directly (no wrapper object)' };
46
+ }
47
+ if (parsed.artifactKind !== BOUNDED_AGENT_CONTEXT_ARTIFACT_KIND) {
48
+ return { ok: false, error: `--context-file artifactKind must be "${BOUNDED_AGENT_CONTEXT_ARTIFACT_KIND}"; found ${JSON.stringify(parsed.artifactKind)}` };
49
+ }
50
+ if (parsed.schemaVersion !== BOUNDED_AGENT_CONTEXT_SCHEMA_VERSION) {
51
+ const foundSchemaVersion = typeof parsed.schemaVersion === 'string' ? parsed.schemaVersion : 'unknown';
52
+ return { ok: true, state: { status: 'unsupported-version', foundSchemaVersion } };
53
+ }
54
+ const validation = isValidBoundedAgentContextArtifact(parsed);
55
+ if (!validation.valid) {
56
+ return { ok: false, error: `--context-file is not a structurally valid current (schemaVersion ${BOUNDED_AGENT_CONTEXT_SCHEMA_VERSION}) bounded-agent-context artifact: ${validation.reason}` };
57
+ }
58
+ return { ok: true, state: { status: 'valid', artifact: parsed } };
59
+ }
60
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/viewerServer/context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,mCAAmC,EAAE,oCAAoC,EAAE,kCAAkC,EAAE,MAAM,kCAAkC,CAAC;AAGjK;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,sBAAsB,GAAG,SAAS,CAAC;AAkBhD,SAAS,aAAa,CAAC,KAAc;IACnC,OAAO,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;AAC9E,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,0BAA0B,CAAC,MAAe;IACxD,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,2HAA2H,EAAE,CAAC;IAC3J,CAAC;IACD,IAAI,MAAM,CAAC,YAAY,KAAK,mCAAmC,EAAE,CAAC;QAChE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,wCAAwC,mCAAmC,YAAY,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;IAC5J,CAAC;IACD,IAAI,MAAM,CAAC,aAAa,KAAK,oCAAoC,EAAE,CAAC;QAClE,MAAM,kBAAkB,GAAG,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;QACvG,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,EAAE,CAAC;IACpF,CAAC;IACD,MAAM,UAAU,GAAG,kCAAkC,CAAC,MAAM,CAAC,CAAC;IAC9D,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;QACtB,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,qEAAqE,oCAAoC,qCAAqC,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;IACjM,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAgD,EAAE,EAAE,CAAC;AAC9G,CAAC"}
@@ -0,0 +1,59 @@
1
+ import type { ObservationArtifact } from '../../domain/schema.js';
2
+ import type { ComparisonArtifact } from '../../domain/comparison.js';
3
+ import type { PersistentBaselineContract, PerChangeContract } from '../../domain/frontendContracts.js';
4
+ import type { FrontendContractEvaluationArtifact } from '../../domain/frontendContractEvaluationArtifact.js';
5
+ import type { ExternalReferenceArtifact } from '../../domain/externalReference.js';
6
+ export type ArtifactFamily = 'observation' | 'comparison' | 'baseline-contract' | 'change-contract' | 'contract-evaluation' | 'external-reference-imported' | 'external-reference-approved';
7
+ /**
8
+ * Honest, independent viewer-loading/support state - deliberately distinct
9
+ * from any artifact's own `completion`/evidence-state semantics (see
10
+ * ClassifiedRecord.artifact for the latter, when the kind carries one).
11
+ */
12
+ export type ViewerSupportState = 'supported' | 'unsupported-version' | 'invalid-structure' | 'unrecognized-kind' | 'malformed-json' | 'unreadable';
13
+ type FamilyArtifact = {
14
+ observation: ObservationArtifact;
15
+ comparison: ComparisonArtifact;
16
+ 'baseline-contract': PersistentBaselineContract;
17
+ 'change-contract': PerChangeContract;
18
+ 'contract-evaluation': FrontendContractEvaluationArtifact;
19
+ 'external-reference-imported': ExternalReferenceArtifact;
20
+ 'external-reference-approved': ExternalReferenceArtifact;
21
+ };
22
+ /** Per-family discriminated union (not a generically-indexed field) so switching on `family` correctly narrows `artifact`'s type. */
23
+ type SupportedRecord = {
24
+ [K in ArtifactFamily]: {
25
+ supportState: 'supported';
26
+ family: K;
27
+ artifact: FamilyArtifact[K];
28
+ };
29
+ }[ArtifactFamily];
30
+ export type ClassifiedRecord = SupportedRecord | {
31
+ supportState: 'unsupported-version';
32
+ family: ArtifactFamily;
33
+ foundSchemaVersion: string;
34
+ supportedSchemaVersion: string;
35
+ } | {
36
+ supportState: 'invalid-structure';
37
+ family: ArtifactFamily | undefined;
38
+ reason: string;
39
+ } | {
40
+ supportState: 'unrecognized-kind';
41
+ foundArtifactKind: string | undefined;
42
+ } | {
43
+ supportState: 'malformed-json';
44
+ reason: string;
45
+ } | {
46
+ supportState: 'unreadable';
47
+ reason: string;
48
+ };
49
+ /**
50
+ * Classification is not validation (frozen plan §10): this function reads
51
+ * bounded manifest bytes, parses JSON, and peeks only `artifactKind`/
52
+ * `schemaVersion` to decide *which* existing canonical reader to try - the
53
+ * canonical reader's own structural validator remains the sole authority on
54
+ * whether a candidate is actually a valid instance of that family. This
55
+ * function never accepts a candidate that its dispatched reader rejects, and
56
+ * never invents a result the reader did not itself produce.
57
+ */
58
+ export declare function classifyManifest(manifestPath: string): Promise<ClassifiedRecord>;
59
+ export {};
@@ -0,0 +1,124 @@
1
+ import { readFile, stat } from 'node:fs/promises';
2
+ import { ARTIFACT_KIND, SCHEMA_VERSION } from '../../domain/schema.js';
3
+ import { readObservationArtifact } from '../../artifacts/artifactReader.js';
4
+ import { COMPARISON_ARTIFACT_KIND, COMPARISON_SCHEMA_VERSION } from '../../domain/comparison.js';
5
+ import { readComparisonArtifact } from '../../artifacts/comparisonArtifactReader.js';
6
+ import { CONTRACT_ARTIFACT_KIND, CONTRACT_SCHEMA_VERSION } from '../../domain/frontendContracts.js';
7
+ import { readPersistentBaselineContract, readPerChangeContract } from '../../artifacts/frontendContractArtifactReader.js';
8
+ import { EVALUATION_ARTIFACT_KIND, EVALUATION_SCHEMA_VERSION } from '../../domain/frontendContractEvaluationArtifact.js';
9
+ import { readFrontendContractEvaluationArtifact } from '../../artifacts/frontendContractEvaluationArtifactReader.js';
10
+ import { EXTERNAL_REFERENCE_ARTIFACT_KIND, EXTERNAL_REFERENCE_SCHEMA_VERSION } from '../../domain/externalReference.js';
11
+ import { readExternalReferenceArtifact } from '../../artifacts/externalReferenceArtifactReader.js';
12
+ import { MAX_MANIFEST_CANDIDATE_BYTES } from './limits.js';
13
+ function isPlainObject(value) {
14
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
15
+ }
16
+ /**
17
+ * Classification is not validation (frozen plan §10): this function reads
18
+ * bounded manifest bytes, parses JSON, and peeks only `artifactKind`/
19
+ * `schemaVersion` to decide *which* existing canonical reader to try - the
20
+ * canonical reader's own structural validator remains the sole authority on
21
+ * whether a candidate is actually a valid instance of that family. This
22
+ * function never accepts a candidate that its dispatched reader rejects, and
23
+ * never invents a result the reader did not itself produce.
24
+ */
25
+ export async function classifyManifest(manifestPath) {
26
+ let size;
27
+ try {
28
+ size = (await stat(manifestPath)).size;
29
+ }
30
+ catch (err) {
31
+ const message = err instanceof Error ? err.message : String(err);
32
+ return { supportState: 'unreadable', reason: `could not stat candidate manifest: ${message}` };
33
+ }
34
+ if (size > MAX_MANIFEST_CANDIDATE_BYTES) {
35
+ return { supportState: 'unreadable', reason: `candidate manifest exceeds the bounded size limit (${MAX_MANIFEST_CANDIDATE_BYTES} bytes)` };
36
+ }
37
+ let raw;
38
+ try {
39
+ raw = await readFile(manifestPath, 'utf8');
40
+ }
41
+ catch (err) {
42
+ const message = err instanceof Error ? err.message : String(err);
43
+ return { supportState: 'unreadable', reason: `could not read candidate manifest: ${message}` };
44
+ }
45
+ let parsed;
46
+ try {
47
+ parsed = JSON.parse(raw);
48
+ }
49
+ catch (err) {
50
+ const message = err instanceof Error ? err.message : String(err);
51
+ return { supportState: 'malformed-json', reason: message };
52
+ }
53
+ if (!isPlainObject(parsed)) {
54
+ return { supportState: 'unrecognized-kind', foundArtifactKind: undefined };
55
+ }
56
+ const kind = typeof parsed.artifactKind === 'string' ? parsed.artifactKind : undefined;
57
+ const version = typeof parsed.schemaVersion === 'string' ? parsed.schemaVersion : undefined;
58
+ switch (kind) {
59
+ case ARTIFACT_KIND: {
60
+ if (version !== SCHEMA_VERSION) {
61
+ return { supportState: 'unsupported-version', family: 'observation', foundSchemaVersion: version ?? 'unknown', supportedSchemaVersion: SCHEMA_VERSION };
62
+ }
63
+ const read = await readObservationArtifact(manifestPath);
64
+ if (!read.ok)
65
+ return { supportState: 'invalid-structure', family: 'observation', reason: read.reason };
66
+ return { supportState: 'supported', family: 'observation', artifact: read.artifact };
67
+ }
68
+ case COMPARISON_ARTIFACT_KIND: {
69
+ if (version !== COMPARISON_SCHEMA_VERSION) {
70
+ return { supportState: 'unsupported-version', family: 'comparison', foundSchemaVersion: version ?? 'unknown', supportedSchemaVersion: COMPARISON_SCHEMA_VERSION };
71
+ }
72
+ const read = await readComparisonArtifact(manifestPath);
73
+ if (!read.ok)
74
+ return { supportState: 'invalid-structure', family: 'comparison', reason: read.reason };
75
+ return { supportState: 'supported', family: 'comparison', artifact: read.artifact };
76
+ }
77
+ case CONTRACT_ARTIFACT_KIND: {
78
+ if (version !== CONTRACT_SCHEMA_VERSION) {
79
+ return { supportState: 'unsupported-version', family: 'baseline-contract', foundSchemaVersion: version ?? 'unknown', supportedSchemaVersion: CONTRACT_SCHEMA_VERSION };
80
+ }
81
+ // Two structurally distinct persisted shapes share one artifactKind/schemaVersion (contractClass discriminates) -
82
+ // the canonical validators, not this classifier, decide which one (if either) a candidate actually is.
83
+ const baseline = await readPersistentBaselineContract(manifestPath);
84
+ if (baseline.ok)
85
+ return { supportState: 'supported', family: 'baseline-contract', artifact: baseline.contract };
86
+ const change = await readPerChangeContract(manifestPath);
87
+ if (change.ok)
88
+ return { supportState: 'supported', family: 'change-contract', artifact: change.contract };
89
+ return { supportState: 'invalid-structure', family: undefined, reason: `matches neither baseline nor per-change contract shape (baseline: ${baseline.reason}; change: ${change.reason})` };
90
+ }
91
+ case EVALUATION_ARTIFACT_KIND: {
92
+ if (version !== EVALUATION_SCHEMA_VERSION) {
93
+ return { supportState: 'unsupported-version', family: 'contract-evaluation', foundSchemaVersion: version ?? 'unknown', supportedSchemaVersion: EVALUATION_SCHEMA_VERSION };
94
+ }
95
+ const read = await readFrontendContractEvaluationArtifact(manifestPath);
96
+ if (!read.ok)
97
+ return { supportState: 'invalid-structure', family: 'contract-evaluation', reason: read.reason };
98
+ return { supportState: 'supported', family: 'contract-evaluation', artifact: read.artifact };
99
+ }
100
+ case EXTERNAL_REFERENCE_ARTIFACT_KIND: {
101
+ if (version !== EXTERNAL_REFERENCE_SCHEMA_VERSION) {
102
+ return {
103
+ supportState: 'unsupported-version',
104
+ family: 'external-reference-imported',
105
+ foundSchemaVersion: version ?? 'unknown',
106
+ supportedSchemaVersion: EXTERNAL_REFERENCE_SCHEMA_VERSION,
107
+ };
108
+ }
109
+ const read = await readExternalReferenceArtifact(manifestPath);
110
+ if (!read.ok)
111
+ return { supportState: 'invalid-structure', family: undefined, reason: read.reason };
112
+ const family = read.artifact.lifecycle.state === 'approved' ? 'external-reference-approved' : 'external-reference-imported';
113
+ return { supportState: 'supported', family, artifact: read.artifact };
114
+ }
115
+ default:
116
+ // Includes both a genuinely unknown string and the known-but-unreadered
117
+ // `my-frontend-observer/bounded-agent-context` kind (see frozen plan
118
+ // §8: no disk reader/writer exists for that family - inventing
119
+ // persistence-shaped handling for it here would fabricate support that
120
+ // does not exist).
121
+ return { supportState: 'unrecognized-kind', foundArtifactKind: kind };
122
+ }
123
+ }
124
+ //# sourceMappingURL=classify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"classify.js","sourceRoot":"","sources":["../../../src/viewerServer/evidence/classify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ import type { LinkStatus } from './linkedEvidence.js';
2
+ export type ComparisonViewResult = {
3
+ ok: true;
4
+ before: LinkStatus;
5
+ after: LinkStatus;
6
+ } | {
7
+ ok: false;
8
+ reason: 'unknown-handle';
9
+ } | {
10
+ ok: false;
11
+ reason: 'not-a-comparison';
12
+ } | {
13
+ ok: false;
14
+ reason: 'not-currently-loadable';
15
+ };
16
+ /**
17
+ * Batch 4's one additive server-side computation for comparisons: resolves
18
+ * the persisted `ComparisonArtifact`'s `before`/`after` source-observation
19
+ * references (exact identity only, `linkedEvidence.ts`) against the current
20
+ * evidence root. Never calls `compareObservations` - the persisted
21
+ * `ComparisonArtifact` (differences, relationshipsBefore/After,
22
+ * comparability, etc.) remains authoritative and is fetched unchanged
23
+ * through the existing Batch 2 `GET /api/artifacts/<handle>`; this endpoint
24
+ * only answers "where are its source observations, if anywhere in this
25
+ * root". Same handle-decode -> contained-dir-resolve -> re-classify
26
+ * discipline as `observationView.ts`/`mediaResolver.ts`.
27
+ */
28
+ export declare function getComparisonView(root: string, handle: string): Promise<ComparisonViewResult>;
@@ -0,0 +1,43 @@
1
+ import { join } from 'node:path';
2
+ import { stat } from 'node:fs/promises';
3
+ import { classifyManifest } from './classify.js';
4
+ import { decodeArtifactHandle } from './handles.js';
5
+ import { resolveContainedDir } from './pathSafety.js';
6
+ import { resolveObservationByReference } from './linkedEvidence.js';
7
+ /**
8
+ * Batch 4's one additive server-side computation for comparisons: resolves
9
+ * the persisted `ComparisonArtifact`'s `before`/`after` source-observation
10
+ * references (exact identity only, `linkedEvidence.ts`) against the current
11
+ * evidence root. Never calls `compareObservations` - the persisted
12
+ * `ComparisonArtifact` (differences, relationshipsBefore/After,
13
+ * comparability, etc.) remains authoritative and is fetched unchanged
14
+ * through the existing Batch 2 `GET /api/artifacts/<handle>`; this endpoint
15
+ * only answers "where are its source observations, if anywhere in this
16
+ * root". Same handle-decode -> contained-dir-resolve -> re-classify
17
+ * discipline as `observationView.ts`/`mediaResolver.ts`.
18
+ */
19
+ export async function getComparisonView(root, handle) {
20
+ const decoded = decodeArtifactHandle(handle);
21
+ if (!decoded.ok)
22
+ return { ok: false, reason: 'unknown-handle' };
23
+ const dir = resolveContainedDir(root, decoded.relativeDir);
24
+ if (dir === undefined)
25
+ return { ok: false, reason: 'unknown-handle' };
26
+ try {
27
+ const dirInfo = await stat(dir);
28
+ if (!dirInfo.isDirectory())
29
+ return { ok: false, reason: 'unknown-handle' };
30
+ }
31
+ catch {
32
+ return { ok: false, reason: 'unknown-handle' };
33
+ }
34
+ const classified = await classifyManifest(join(dir, 'manifest.json'));
35
+ if (classified.supportState !== 'supported')
36
+ return { ok: false, reason: 'not-currently-loadable' };
37
+ if (classified.family !== 'comparison')
38
+ return { ok: false, reason: 'not-a-comparison' };
39
+ const { artifact } = classified;
40
+ const [before, after] = await Promise.all([resolveObservationByReference(root, artifact.before), resolveObservationByReference(root, artifact.after)]);
41
+ return { ok: true, before, after };
42
+ }
43
+ //# sourceMappingURL=comparisonView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"comparisonView.js","sourceRoot":"","sources":["../../../src/viewerServer/evidence/comparisonView.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,cAAc,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,EAAE,6BAA6B,EAAE,MAAM,qBAAqB,CAAC;AASpE;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAY,EAAE,MAAc;IAClE,MAAM,OAAO,GAAG,oBAAoB,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,CAAC,OAAO,CAAC,EAAE;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAEhE,MAAM,GAAG,GAAG,mBAAmB,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC3D,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAEtE,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC7E,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,gBAAgB,EAAE,CAAC;IACjD,CAAC;IAED,MAAM,UAAU,GAAG,MAAM,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,eAAe,CAAC,CAAC,CAAC;IACtE,IAAI,UAAU,CAAC,YAAY,KAAK,WAAW;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,wBAAwB,EAAE,CAAC;IACpG,IAAI,UAAU,CAAC,MAAM,KAAK,YAAY;QAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC;IAEzF,MAAM,EAAE,QAAQ,EAAE,GAAG,UAAU,CAAC;IAChC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,6BAA6B,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,CAAC,EAAE,6BAA6B,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAEvJ,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AACrC,CAAC"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * v0.8 Batch 7: resolves a validated `BoundedAgentContextArtifact.sources`
3
+ * block against the current evidence root by exact canonical identity only
4
+ * (never pathname/name/similarity heuristics), reusing `linkedEvidence.ts`'s
5
+ * established resolver pattern (Batch 4/5) - every lookup here is a bounded
6
+ * discovery walk that matches on the exact identity fields the source
7
+ * reference actually carries. Never calls `compareObservations`,
8
+ * `evaluateFrontendContract`, `projectBoundedAgentContext`, or any
9
+ * correlation-derivation function.
10
+ */
11
+ import type { BoundedAgentContextSourceReferences } from '../../domain/boundedAgentContext.js';
12
+ import type { LinkStatus } from './linkedEvidence.js';
13
+ export interface ContextSourceResolution {
14
+ /** One resolution per `sources.observationIds` entry, in the same order. */
15
+ observations: {
16
+ observationId: string;
17
+ link: LinkStatus;
18
+ }[];
19
+ comparison?: LinkStatus;
20
+ baselineContract?: LinkStatus;
21
+ changeContract?: LinkStatus;
22
+ evaluation?: LinkStatus;
23
+ reference?: LinkStatus;
24
+ }
25
+ export declare function resolveContextSources(root: string, sources: BoundedAgentContextSourceReferences): Promise<ContextSourceResolution>;
@@ -0,0 +1,20 @@
1
+ import { resolveObservationById, resolveComparisonByIdentity, resolveBaselineContractById, resolveChangeContractById, resolveEvaluationByIdentity, resolveReferenceByIdentity } from './linkedEvidence.js';
2
+ export async function resolveContextSources(root, sources) {
3
+ const [observationLinks, comparison, baselineContract, changeContract, evaluation, reference] = await Promise.all([
4
+ Promise.all(sources.observationIds.map(async (observationId) => ({ observationId, link: await resolveObservationById(root, observationId) }))),
5
+ sources.comparisonId !== undefined && sources.comparisonRequestId !== undefined ? resolveComparisonByIdentity(root, sources.comparisonId, sources.comparisonRequestId) : Promise.resolve(undefined),
6
+ sources.baselineContractId !== undefined ? resolveBaselineContractById(root, sources.baselineContractId) : Promise.resolve(undefined),
7
+ sources.changeContractId !== undefined ? resolveChangeContractById(root, sources.changeContractId) : Promise.resolve(undefined),
8
+ sources.evaluationId !== undefined && sources.evaluationRequestId !== undefined ? resolveEvaluationByIdentity(root, sources.evaluationId, sources.evaluationRequestId) : Promise.resolve(undefined),
9
+ sources.referenceId !== undefined && sources.referenceRequestId !== undefined ? resolveReferenceByIdentity(root, sources.referenceId, sources.referenceRequestId) : Promise.resolve(undefined),
10
+ ]);
11
+ return {
12
+ observations: observationLinks,
13
+ ...(comparison !== undefined ? { comparison } : {}),
14
+ ...(baselineContract !== undefined ? { baselineContract } : {}),
15
+ ...(changeContract !== undefined ? { changeContract } : {}),
16
+ ...(evaluation !== undefined ? { evaluation } : {}),
17
+ ...(reference !== undefined ? { reference } : {}),
18
+ };
19
+ }
20
+ //# sourceMappingURL=contextSourceView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contextSourceView.js","sourceRoot":"","sources":["../../../src/viewerServer/evidence/contextSourceView.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,sBAAsB,EAAE,2BAA2B,EAAE,2BAA2B,EAAE,yBAAyB,EAAE,2BAA2B,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAY3M,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,IAAY,EAAE,OAA4C;IACpG,MAAM,CAAC,gBAAgB,EAAE,UAAU,EAAE,gBAAgB,EAAE,cAAc,EAAE,UAAU,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAChH,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,CAAC,CAAC,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,sBAAsB,CAAC,IAAI,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC;QAC9I,OAAO,CAAC,YAAY,KAAK,SAAS,IAAI,OAAO,CAAC,mBAAmB,KAAK,SAAS,CAAC,CAAC,CAAC,2BAA2B,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;QACnM,OAAO,CAAC,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,2BAA2B,CAAC,IAAI,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;QACrI,OAAO,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,yBAAyB,CAAC,IAAI,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;QAC/H,OAAO,CAAC,YAAY,KAAK,SAAS,IAAI,OAAO,CAAC,mBAAmB,KAAK,SAAS,CAAC,CAAC,CAAC,2BAA2B,CAAC,IAAI,EAAE,OAAO,CAAC,YAAY,EAAE,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;QACnM,OAAO,CAAC,WAAW,KAAK,SAAS,IAAI,OAAO,CAAC,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,0BAA0B,CAAC,IAAI,EAAE,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;KAC/L,CAAC,CAAC;IAEH,OAAO;QACL,YAAY,EAAE,gBAAgB;QAC9B,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,GAAG,CAAC,gBAAgB,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,gBAAgB,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/D,GAAG,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,GAAG,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,GAAG,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAClD,CAAC;AACJ,CAAC"}
@@ -0,0 +1,31 @@
1
+ export interface DiscoveredManifest {
2
+ /** Absolute path to the candidate `manifest.json` file. */
3
+ absolutePath: string;
4
+ /** Absolute path to its containing directory (the artifact's own root). */
5
+ absoluteDir: string;
6
+ /** Root-relative, forward-slash-normalized directory path - display/handle material only, never trusted for filesystem access without re-resolution+containment-check. */
7
+ relativeDir: string;
8
+ }
9
+ export interface DiscoveryResult {
10
+ manifests: DiscoveredManifest[];
11
+ /** True if MAX_MANIFEST_CANDIDATES, MAX_DIRECTORIES_VISITED, or MAX_DISCOVERY_DEPTH was hit before the walk completed naturally. */
12
+ truncated: boolean;
13
+ }
14
+ /**
15
+ * Bounded, deterministic, symlink-safe walk beneath `root` looking only for
16
+ * files literally named `manifest.json` (the one filename every current
17
+ * persisted artifact family uses - see src/artifacts/*Writer.ts). No other
18
+ * filename is ever opened or classified, so arbitrary files
19
+ * (`package.json`, `.env`, source files, unrelated JSON) can never become
20
+ * evidence merely by existing under the root.
21
+ *
22
+ * Security properties:
23
+ * - directory entries that are symbolic links or reparse points/junctions
24
+ * (`dirent.isSymbolicLink()`) are never followed, so discovery can never
25
+ * leave the resolved root via a symlink;
26
+ * - traversal depth, directories visited, and candidate manifests found are
27
+ * all independently bounded (see limits.ts) - discovery always terminates
28
+ * and never depends on filesystem enumeration order for its *result set*
29
+ * (see the caller-side deterministic sort in index.ts).
30
+ */
31
+ export declare function discoverManifests(root: string): Promise<DiscoveryResult>;
@@ -0,0 +1,78 @@
1
+ import { readdir } from 'node:fs/promises';
2
+ import { join, relative, sep } from 'node:path';
3
+ import { MAX_DIRECTORIES_VISITED, MAX_DISCOVERY_DEPTH, MAX_MANIFEST_CANDIDATES } from './limits.js';
4
+ function toPosixRelative(root, absoluteDir) {
5
+ const rel = relative(root, absoluteDir);
6
+ return rel === '' ? '.' : rel.split(sep).join('/');
7
+ }
8
+ /**
9
+ * Bounded, deterministic, symlink-safe walk beneath `root` looking only for
10
+ * files literally named `manifest.json` (the one filename every current
11
+ * persisted artifact family uses - see src/artifacts/*Writer.ts). No other
12
+ * filename is ever opened or classified, so arbitrary files
13
+ * (`package.json`, `.env`, source files, unrelated JSON) can never become
14
+ * evidence merely by existing under the root.
15
+ *
16
+ * Security properties:
17
+ * - directory entries that are symbolic links or reparse points/junctions
18
+ * (`dirent.isSymbolicLink()`) are never followed, so discovery can never
19
+ * leave the resolved root via a symlink;
20
+ * - traversal depth, directories visited, and candidate manifests found are
21
+ * all independently bounded (see limits.ts) - discovery always terminates
22
+ * and never depends on filesystem enumeration order for its *result set*
23
+ * (see the caller-side deterministic sort in index.ts).
24
+ */
25
+ export async function discoverManifests(root) {
26
+ const manifests = [];
27
+ let directoriesVisited = 0;
28
+ let truncated = false;
29
+ async function walk(dir, depth) {
30
+ if (truncated)
31
+ return;
32
+ if (depth > MAX_DISCOVERY_DEPTH) {
33
+ truncated = true;
34
+ return;
35
+ }
36
+ if (directoriesVisited >= MAX_DIRECTORIES_VISITED) {
37
+ truncated = true;
38
+ return;
39
+ }
40
+ directoriesVisited += 1;
41
+ let entries;
42
+ try {
43
+ entries = await readdir(dir, { withFileTypes: true });
44
+ }
45
+ catch {
46
+ // Unreadable directory (permissions, race with external deletion): skip silently, not a discovery failure.
47
+ return;
48
+ }
49
+ // Deterministic child ordering regardless of filesystem enumeration order.
50
+ entries.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
51
+ for (const entry of entries) {
52
+ if (truncated)
53
+ return;
54
+ if (entry.isSymbolicLink())
55
+ continue; // never follow symlinks/junctions/reparse points, for files or directories
56
+ if (entry.isDirectory()) {
57
+ await walk(join(dir, entry.name), depth + 1);
58
+ continue;
59
+ }
60
+ if (entry.isFile() && entry.name === 'manifest.json') {
61
+ if (manifests.length >= MAX_MANIFEST_CANDIDATES) {
62
+ truncated = true;
63
+ return;
64
+ }
65
+ manifests.push({
66
+ absolutePath: join(dir, entry.name),
67
+ absoluteDir: dir,
68
+ relativeDir: toPosixRelative(root, dir),
69
+ });
70
+ }
71
+ }
72
+ }
73
+ await walk(root, 0);
74
+ // Final deterministic ordering of the result set itself, independent of traversal order.
75
+ manifests.sort((a, b) => (a.relativeDir < b.relativeDir ? -1 : a.relativeDir > b.relativeDir ? 1 : 0));
76
+ return { manifests, truncated };
77
+ }
78
+ //# sourceMappingURL=discovery.js.map