@sanity/ailf 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (530) hide show
  1. package/README.md +89 -0
  2. package/bin/ailf.js +64 -0
  3. package/canonical/grader-references/README.md +88 -0
  4. package/canonical/grader-references/groq.yaml +234 -0
  5. package/canonical/grader-references/studio-setup.yaml +275 -0
  6. package/canonical/reference-solutions/.gitkeep +1 -0
  7. package/canonical/reference-solutions/frameworks/nuxt.ts +119 -0
  8. package/canonical/reference-solutions/frameworks/remix.tsx +100 -0
  9. package/canonical/reference-solutions/functions/publish-webhook.ts +60 -0
  10. package/canonical/reference-solutions/groq/advanced-filtering.ts +379 -0
  11. package/canonical/reference-solutions/groq/blog-queries.ts +137 -0
  12. package/canonical/reference-solutions/groq/joins-references.ts +300 -0
  13. package/canonical/reference-solutions/nextjs/app-router-integration.tsx +128 -0
  14. package/canonical/reference-solutions/studio-setup/blog-schema.ts +143 -0
  15. package/canonical/reference-solutions/studio-setup/custom-tool.tsx +78 -0
  16. package/canonical/reference-solutions/visual-editing/live-preview.tsx +137 -0
  17. package/canonical/reference-solutions/visual-editing/presentation-nextjs.tsx +130 -0
  18. package/config/airbyte/ai_literacy_framework.connector.yaml +639 -0
  19. package/config/bigquery/README.md +74 -0
  20. package/config/bigquery/views/area_scores.sql +87 -0
  21. package/config/bigquery/views/reports.sql +49 -0
  22. package/config/features.yaml +116 -0
  23. package/config/models.yaml +115 -0
  24. package/config/prompts.yaml +75 -0
  25. package/config/rubrics.yaml +62 -0
  26. package/config/schedules.yaml +43 -0
  27. package/config/sinks.yaml +54 -0
  28. package/config/sources.yaml +51 -0
  29. package/config/thresholds.yaml +49 -0
  30. package/dist/_vendor/ailf-core/examples/index.d.ts +190 -0
  31. package/dist/_vendor/ailf-core/examples/index.js +285 -0
  32. package/dist/_vendor/ailf-core/index.d.ts +17 -0
  33. package/dist/_vendor/ailf-core/index.js +17 -0
  34. package/dist/_vendor/ailf-core/ports/cache-store.d.ts +72 -0
  35. package/dist/_vendor/ailf-core/ports/cache-store.js +17 -0
  36. package/dist/_vendor/ailf-core/ports/config-source.d.ts +33 -0
  37. package/dist/_vendor/ailf-core/ports/config-source.js +15 -0
  38. package/dist/_vendor/ailf-core/ports/context.d.ts +172 -0
  39. package/dist/_vendor/ailf-core/ports/context.js +14 -0
  40. package/dist/_vendor/ailf-core/ports/doc-fetcher.d.ts +131 -0
  41. package/dist/_vendor/ailf-core/ports/doc-fetcher.js +12 -0
  42. package/dist/_vendor/ailf-core/ports/eval-runner.d.ts +24 -0
  43. package/dist/_vendor/ailf-core/ports/eval-runner.js +8 -0
  44. package/dist/_vendor/ailf-core/ports/index.d.ts +15 -0
  45. package/dist/_vendor/ailf-core/ports/index.js +7 -0
  46. package/dist/_vendor/ailf-core/ports/logger.d.ts +36 -0
  47. package/dist/_vendor/ailf-core/ports/logger.js +11 -0
  48. package/dist/_vendor/ailf-core/ports/pipeline-step.d.ts +46 -0
  49. package/dist/_vendor/ailf-core/ports/pipeline-step.js +8 -0
  50. package/dist/_vendor/ailf-core/ports/task-source.d.ts +159 -0
  51. package/dist/_vendor/ailf-core/ports/task-source.js +72 -0
  52. package/dist/_vendor/ailf-core/schemas/callback-payload.d.ts +24 -0
  53. package/dist/_vendor/ailf-core/schemas/callback-payload.js +29 -0
  54. package/dist/_vendor/ailf-core/schemas/eval-config.d.ts +55 -0
  55. package/dist/_vendor/ailf-core/schemas/eval-config.js +78 -0
  56. package/dist/_vendor/ailf-core/schemas/index.d.ts +16 -0
  57. package/dist/_vendor/ailf-core/schemas/index.js +16 -0
  58. package/dist/_vendor/ailf-core/schemas/pipeline-request.d.ts +125 -0
  59. package/dist/_vendor/ailf-core/schemas/pipeline-request.js +67 -0
  60. package/dist/_vendor/ailf-core/schemas/pipeline.d.ts +531 -0
  61. package/dist/_vendor/ailf-core/schemas/pipeline.js +318 -0
  62. package/dist/_vendor/ailf-core/schemas/schedules.d.ts +68 -0
  63. package/dist/_vendor/ailf-core/schemas/schedules.js +74 -0
  64. package/dist/_vendor/ailf-core/schemas/sinks.d.ts +207 -0
  65. package/dist/_vendor/ailf-core/schemas/sinks.js +108 -0
  66. package/dist/_vendor/ailf-core/services/comparison-formatters.d.ts +18 -0
  67. package/dist/_vendor/ailf-core/services/comparison-formatters.js +189 -0
  68. package/dist/_vendor/ailf-core/services/config-helpers.d.ts +41 -0
  69. package/dist/_vendor/ailf-core/services/config-helpers.js +86 -0
  70. package/dist/_vendor/ailf-core/services/index.d.ts +12 -0
  71. package/dist/_vendor/ailf-core/services/index.js +12 -0
  72. package/dist/_vendor/ailf-core/services/scoring.d.ts +49 -0
  73. package/dist/_vendor/ailf-core/services/scoring.js +222 -0
  74. package/dist/_vendor/ailf-core/types/index.d.ts +1082 -0
  75. package/dist/_vendor/ailf-core/types/index.js +21 -0
  76. package/dist/_vendor/ailf-core/types/scoring-input.d.ts +54 -0
  77. package/dist/_vendor/ailf-core/types/scoring-input.js +9 -0
  78. package/dist/_vendor/ailf-shared/dimension-names.d.ts +21 -0
  79. package/dist/_vendor/ailf-shared/dimension-names.js +27 -0
  80. package/dist/_vendor/ailf-shared/document-ref.d.ts +29 -0
  81. package/dist/_vendor/ailf-shared/document-ref.js +1 -0
  82. package/dist/_vendor/ailf-shared/eval-modes.d.ts +12 -0
  83. package/dist/_vendor/ailf-shared/eval-modes.js +8 -0
  84. package/dist/_vendor/ailf-shared/index.d.ts +16 -0
  85. package/dist/_vendor/ailf-shared/index.js +16 -0
  86. package/dist/_vendor/ailf-shared/noise-threshold.d.ts +9 -0
  87. package/dist/_vendor/ailf-shared/noise-threshold.js +9 -0
  88. package/dist/_vendor/ailf-shared/score-grades.d.ts +17 -0
  89. package/dist/_vendor/ailf-shared/score-grades.js +23 -0
  90. package/dist/adapters/cache/content-lake-cache.d.ts +24 -0
  91. package/dist/adapters/cache/content-lake-cache.js +59 -0
  92. package/dist/adapters/cache/filesystem-cache.d.ts +18 -0
  93. package/dist/adapters/cache/filesystem-cache.js +54 -0
  94. package/dist/adapters/cache/index.d.ts +2 -0
  95. package/dist/adapters/cache/index.js +2 -0
  96. package/dist/adapters/config-sources/cli-config-adapter.d.ts +17 -0
  97. package/dist/adapters/config-sources/cli-config-adapter.js +23 -0
  98. package/dist/adapters/config-sources/file-config-adapter.d.ts +26 -0
  99. package/dist/adapters/config-sources/file-config-adapter.js +96 -0
  100. package/dist/adapters/config-sources/index.d.ts +2 -0
  101. package/dist/adapters/config-sources/index.js +2 -0
  102. package/dist/adapters/doc-fetchers/index.d.ts +1 -0
  103. package/dist/adapters/doc-fetchers/index.js +1 -0
  104. package/dist/adapters/doc-fetchers/sanity-doc-fetcher.d.ts +76 -0
  105. package/dist/adapters/doc-fetchers/sanity-doc-fetcher.js +620 -0
  106. package/dist/adapters/eval-runners/index.d.ts +1 -0
  107. package/dist/adapters/eval-runners/index.js +1 -0
  108. package/dist/adapters/eval-runners/promptfoo-eval-adapter.d.ts +14 -0
  109. package/dist/adapters/eval-runners/promptfoo-eval-adapter.js +63 -0
  110. package/dist/adapters/index.d.ts +12 -0
  111. package/dist/adapters/index.js +12 -0
  112. package/dist/adapters/loggers/console-logger.d.ts +22 -0
  113. package/dist/adapters/loggers/console-logger.js +54 -0
  114. package/dist/adapters/loggers/index.d.ts +9 -0
  115. package/dist/adapters/loggers/index.js +9 -0
  116. package/dist/adapters/loggers/json-logger.d.ts +18 -0
  117. package/dist/adapters/loggers/json-logger.js +33 -0
  118. package/dist/adapters/loggers/quiet-logger.d.ts +16 -0
  119. package/dist/adapters/loggers/quiet-logger.js +30 -0
  120. package/dist/adapters/task-sources/composite-task-source.d.ts +20 -0
  121. package/dist/adapters/task-sources/composite-task-source.js +59 -0
  122. package/dist/adapters/task-sources/content-lake-task-source.d.ts +20 -0
  123. package/dist/adapters/task-sources/content-lake-task-source.js +219 -0
  124. package/dist/adapters/task-sources/index.d.ts +7 -0
  125. package/dist/adapters/task-sources/index.js +7 -0
  126. package/dist/adapters/task-sources/repo-schemas.d.ts +245 -0
  127. package/dist/adapters/task-sources/repo-schemas.js +234 -0
  128. package/dist/adapters/task-sources/repo-task-source.d.ts +22 -0
  129. package/dist/adapters/task-sources/repo-task-source.js +104 -0
  130. package/dist/adapters/task-sources/repo-trigger.d.ts +52 -0
  131. package/dist/adapters/task-sources/repo-trigger.js +153 -0
  132. package/dist/adapters/task-sources/repo-validation.d.ts +49 -0
  133. package/dist/adapters/task-sources/repo-validation.js +164 -0
  134. package/dist/adapters/task-sources/yaml-task-source.d.ts +18 -0
  135. package/dist/adapters/task-sources/yaml-task-source.js +136 -0
  136. package/dist/agent-observer/agentic-provider.d.ts +132 -0
  137. package/dist/agent-observer/agentic-provider.js +983 -0
  138. package/dist/agent-observer/classifier.d.ts +62 -0
  139. package/dist/agent-observer/classifier.js +269 -0
  140. package/dist/agent-observer/index.d.ts +7 -0
  141. package/dist/agent-observer/index.js +4 -0
  142. package/dist/agent-observer/pricing.d.ts +35 -0
  143. package/dist/agent-observer/pricing.js +82 -0
  144. package/dist/agent-observer/provider.d.ts +77 -0
  145. package/dist/agent-observer/provider.js +151 -0
  146. package/dist/agent-observer/proxy.d.ts +91 -0
  147. package/dist/agent-observer/proxy.js +321 -0
  148. package/dist/agent-observer/test-imports.d.ts +7 -0
  149. package/dist/agent-observer/test-imports.js +185 -0
  150. package/dist/agent-observer/types.d.ts +137 -0
  151. package/dist/agent-observer/types.js +16 -0
  152. package/dist/assertions/source-isolation.d.ts +72 -0
  153. package/dist/assertions/source-isolation.js +117 -0
  154. package/dist/cli.d.ts +24 -0
  155. package/dist/cli.js +199 -0
  156. package/dist/commands/agent-report.d.ts +5 -0
  157. package/dist/commands/agent-report.js +69 -0
  158. package/dist/commands/baseline.d.ts +9 -0
  159. package/dist/commands/baseline.js +141 -0
  160. package/dist/commands/cache.d.ts +13 -0
  161. package/dist/commands/cache.js +135 -0
  162. package/dist/commands/calculate-scores.d.ts +8 -0
  163. package/dist/commands/calculate-scores.js +48 -0
  164. package/dist/commands/compare.d.ts +8 -0
  165. package/dist/commands/compare.js +120 -0
  166. package/dist/commands/completion.d.ts +18 -0
  167. package/dist/commands/completion.js +260 -0
  168. package/dist/commands/coverage-audit.d.ts +7 -0
  169. package/dist/commands/coverage-audit.js +40 -0
  170. package/dist/commands/discovery-report.d.ts +10 -0
  171. package/dist/commands/discovery-report.js +44 -0
  172. package/dist/commands/eval.d.ts +9 -0
  173. package/dist/commands/eval.js +35 -0
  174. package/dist/commands/explain-handler.d.ts +34 -0
  175. package/dist/commands/explain-handler.js +719 -0
  176. package/dist/commands/fetch-docs.d.ts +8 -0
  177. package/dist/commands/fetch-docs.js +128 -0
  178. package/dist/commands/generate-configs.d.ts +8 -0
  179. package/dist/commands/generate-configs.js +46 -0
  180. package/dist/commands/grader/index.d.ts +11 -0
  181. package/dist/commands/grader/index.js +118 -0
  182. package/dist/commands/init.d.ts +19 -0
  183. package/dist/commands/init.js +150 -0
  184. package/dist/commands/interactive.d.ts +12 -0
  185. package/dist/commands/interactive.js +238 -0
  186. package/dist/commands/lookup-doc.d.ts +15 -0
  187. package/dist/commands/lookup-doc.js +84 -0
  188. package/dist/commands/measure-retrieval.d.ts +5 -0
  189. package/dist/commands/measure-retrieval.js +65 -0
  190. package/dist/commands/pipeline-action.d.ts +71 -0
  191. package/dist/commands/pipeline-action.js +305 -0
  192. package/dist/commands/pipeline.d.ts +62 -0
  193. package/dist/commands/pipeline.js +53 -0
  194. package/dist/commands/pr-comment.d.ts +8 -0
  195. package/dist/commands/pr-comment.js +47 -0
  196. package/dist/commands/publish.d.ts +26 -0
  197. package/dist/commands/publish.js +253 -0
  198. package/dist/commands/readiness-report.d.ts +10 -0
  199. package/dist/commands/readiness-report.js +104 -0
  200. package/dist/commands/shared/options.d.ts +29 -0
  201. package/dist/commands/shared/options.js +57 -0
  202. package/dist/commands/update-quality-scores.d.ts +5 -0
  203. package/dist/commands/update-quality-scores.js +20 -0
  204. package/dist/commands/validate-tasks.d.ts +16 -0
  205. package/dist/commands/validate-tasks.js +93 -0
  206. package/dist/commands/validate.d.ts +9 -0
  207. package/dist/commands/validate.js +73 -0
  208. package/dist/commands/webhook-server.d.ts +5 -0
  209. package/dist/commands/webhook-server.js +30 -0
  210. package/dist/commands/weekly-digest.d.ts +10 -0
  211. package/dist/commands/weekly-digest.js +104 -0
  212. package/dist/composition-root.d.ts +26 -0
  213. package/dist/composition-root.js +107 -0
  214. package/dist/interpolate.d.ts +26 -0
  215. package/dist/interpolate.js +70 -0
  216. package/dist/job-store.d.ts +104 -0
  217. package/dist/job-store.js +188 -0
  218. package/dist/lib/agent-behavior-report.d.ts +8 -0
  219. package/dist/lib/agent-behavior-report.js +185 -0
  220. package/dist/lib/baseline.d.ts +19 -0
  221. package/dist/lib/baseline.js +153 -0
  222. package/dist/lib/calculate-scores.d.ts +23 -0
  223. package/dist/lib/calculate-scores.js +42 -0
  224. package/dist/lib/compare.d.ts +18 -0
  225. package/dist/lib/compare.js +170 -0
  226. package/dist/lib/coverage-audit.d.ts +4 -0
  227. package/dist/lib/coverage-audit.js +42 -0
  228. package/dist/lib/discovery-report.d.ts +13 -0
  229. package/dist/lib/discovery-report.js +57 -0
  230. package/dist/lib/fetch-docs.d.ts +30 -0
  231. package/dist/lib/fetch-docs.js +171 -0
  232. package/dist/lib/generate-configs.d.ts +25 -0
  233. package/dist/lib/generate-configs.js +42 -0
  234. package/dist/lib/grader-api.d.ts +21 -0
  235. package/dist/lib/grader-api.js +34 -0
  236. package/dist/lib/grader-compare.d.ts +19 -0
  237. package/dist/lib/grader-compare.js +91 -0
  238. package/dist/lib/grader-consistency.d.ts +27 -0
  239. package/dist/lib/grader-consistency.js +79 -0
  240. package/dist/lib/grader-sensitivity.d.ts +19 -0
  241. package/dist/lib/grader-sensitivity.js +75 -0
  242. package/dist/lib/grader-validate.d.ts +19 -0
  243. package/dist/lib/grader-validate.js +78 -0
  244. package/dist/lib/measure-retrieval.d.ts +14 -0
  245. package/dist/lib/measure-retrieval.js +71 -0
  246. package/dist/lib/pr-comment.d.ts +16 -0
  247. package/dist/lib/pr-comment.js +28 -0
  248. package/dist/lib/readiness-report.d.ts +13 -0
  249. package/dist/lib/readiness-report.js +108 -0
  250. package/dist/lib/webhook-server.d.ts +11 -0
  251. package/dist/lib/webhook-server.js +24 -0
  252. package/dist/lib/weekly-digest.d.ts +24 -0
  253. package/dist/lib/weekly-digest.js +148 -0
  254. package/dist/orchestration/build-app-context.d.ts +27 -0
  255. package/dist/orchestration/build-app-context.js +81 -0
  256. package/dist/orchestration/build-step-sequence.d.ts +15 -0
  257. package/dist/orchestration/build-step-sequence.js +84 -0
  258. package/dist/orchestration/config-to-source-overrides.d.ts +9 -0
  259. package/dist/orchestration/config-to-source-overrides.js +28 -0
  260. package/dist/orchestration/env-bridge.d.ts +21 -0
  261. package/dist/orchestration/env-bridge.js +66 -0
  262. package/dist/orchestration/index.d.ts +11 -0
  263. package/dist/orchestration/index.js +11 -0
  264. package/dist/orchestration/pipeline-orchestrator.d.ts +24 -0
  265. package/dist/orchestration/pipeline-orchestrator.js +153 -0
  266. package/dist/orchestration/step-runner.d.ts +20 -0
  267. package/dist/orchestration/step-runner.js +88 -0
  268. package/dist/orchestration/steps/calculate-scores-step.d.ts +13 -0
  269. package/dist/orchestration/steps/calculate-scores-step.js +95 -0
  270. package/dist/orchestration/steps/callback-step.d.ts +24 -0
  271. package/dist/orchestration/steps/callback-step.js +76 -0
  272. package/dist/orchestration/steps/compare-step.d.ts +14 -0
  273. package/dist/orchestration/steps/compare-step.js +92 -0
  274. package/dist/orchestration/steps/discovery-report-step.d.ts +13 -0
  275. package/dist/orchestration/steps/discovery-report-step.js +55 -0
  276. package/dist/orchestration/steps/fetch-docs-shell.d.ts +17 -0
  277. package/dist/orchestration/steps/fetch-docs-shell.js +30 -0
  278. package/dist/orchestration/steps/fetch-docs-step.d.ts +14 -0
  279. package/dist/orchestration/steps/fetch-docs-step.js +135 -0
  280. package/dist/orchestration/steps/gap-analysis-step.d.ts +16 -0
  281. package/dist/orchestration/steps/gap-analysis-step.js +136 -0
  282. package/dist/orchestration/steps/generate-configs-step.d.ts +14 -0
  283. package/dist/orchestration/steps/generate-configs-step.js +85 -0
  284. package/dist/orchestration/steps/grader-consistency-step.d.ts +13 -0
  285. package/dist/orchestration/steps/grader-consistency-step.js +64 -0
  286. package/dist/orchestration/steps/index.d.ts +19 -0
  287. package/dist/orchestration/steps/index.js +19 -0
  288. package/dist/orchestration/steps/mirror-repo-tasks-step.d.ts +21 -0
  289. package/dist/orchestration/steps/mirror-repo-tasks-step.js +94 -0
  290. package/dist/orchestration/steps/publish-report-step.d.ts +26 -0
  291. package/dist/orchestration/steps/publish-report-step.js +216 -0
  292. package/dist/orchestration/steps/readiness-step.d.ts +13 -0
  293. package/dist/orchestration/steps/readiness-step.js +91 -0
  294. package/dist/orchestration/steps/report-step.d.ts +12 -0
  295. package/dist/orchestration/steps/report-step.js +49 -0
  296. package/dist/orchestration/steps/run-eval-step.d.ts +17 -0
  297. package/dist/orchestration/steps/run-eval-step.js +195 -0
  298. package/dist/orchestration/steps/validate-step.d.ts +12 -0
  299. package/dist/orchestration/steps/validate-step.js +41 -0
  300. package/dist/pipeline/agent-behavior-report.d.ts +53 -0
  301. package/dist/pipeline/agent-behavior-report.js +132 -0
  302. package/dist/pipeline/attribution.d.ts +47 -0
  303. package/dist/pipeline/attribution.js +226 -0
  304. package/dist/pipeline/baseline.d.ts +37 -0
  305. package/dist/pipeline/baseline.js +141 -0
  306. package/dist/pipeline/cache.d.ts +101 -0
  307. package/dist/pipeline/cache.js +283 -0
  308. package/dist/pipeline/calculate-scores.d.ts +102 -0
  309. package/dist/pipeline/calculate-scores.js +1128 -0
  310. package/dist/pipeline/callback-delivery.d.ts +50 -0
  311. package/dist/pipeline/callback-delivery.js +89 -0
  312. package/dist/pipeline/checks.d.ts +39 -0
  313. package/dist/pipeline/checks.js +280 -0
  314. package/dist/pipeline/classify-url.d.ts +61 -0
  315. package/dist/pipeline/classify-url.js +93 -0
  316. package/dist/pipeline/compare.d.ts +31 -0
  317. package/dist/pipeline/compare.js +208 -0
  318. package/dist/pipeline/coverage-audit.d.ts +39 -0
  319. package/dist/pipeline/coverage-audit.js +165 -0
  320. package/dist/pipeline/degradations.d.ts +85 -0
  321. package/dist/pipeline/degradations.js +242 -0
  322. package/dist/pipeline/discovery-report.d.ts +55 -0
  323. package/dist/pipeline/discovery-report.js +178 -0
  324. package/dist/pipeline/eval-constants.d.ts +68 -0
  325. package/dist/pipeline/eval-constants.js +111 -0
  326. package/dist/pipeline/eval-fingerprint.d.ts +66 -0
  327. package/dist/pipeline/eval-fingerprint.js +175 -0
  328. package/dist/pipeline/expand-tasks.d.ts +220 -0
  329. package/dist/pipeline/expand-tasks.js +421 -0
  330. package/dist/pipeline/failure-modes.d.ts +46 -0
  331. package/dist/pipeline/failure-modes.js +348 -0
  332. package/dist/pipeline/fetch-url-content.d.ts +44 -0
  333. package/dist/pipeline/fetch-url-content.js +93 -0
  334. package/dist/pipeline/gap-analysis.d.ts +48 -0
  335. package/dist/pipeline/gap-analysis.js +231 -0
  336. package/dist/pipeline/generate-configs.d.ts +72 -0
  337. package/dist/pipeline/generate-configs.js +395 -0
  338. package/dist/pipeline/grader-api.d.ts +49 -0
  339. package/dist/pipeline/grader-api.js +200 -0
  340. package/dist/pipeline/grader-compare-runner.d.ts +44 -0
  341. package/dist/pipeline/grader-compare-runner.js +301 -0
  342. package/dist/pipeline/grader-comparison.d.ts +111 -0
  343. package/dist/pipeline/grader-comparison.js +161 -0
  344. package/dist/pipeline/grader-consistency-runner.d.ts +60 -0
  345. package/dist/pipeline/grader-consistency-runner.js +270 -0
  346. package/dist/pipeline/grader-consistency.d.ts +103 -0
  347. package/dist/pipeline/grader-consistency.js +146 -0
  348. package/dist/pipeline/grader-sensitivity-runner.d.ts +40 -0
  349. package/dist/pipeline/grader-sensitivity-runner.js +282 -0
  350. package/dist/pipeline/grader-sensitivity.d.ts +94 -0
  351. package/dist/pipeline/grader-sensitivity.js +144 -0
  352. package/dist/pipeline/grader-validate-runner.d.ts +38 -0
  353. package/dist/pipeline/grader-validate-runner.js +229 -0
  354. package/dist/pipeline/grader-validation.d.ts +107 -0
  355. package/dist/pipeline/grader-validation.js +169 -0
  356. package/dist/pipeline/map-request-to-config.d.ts +19 -0
  357. package/dist/pipeline/map-request-to-config.js +80 -0
  358. package/dist/pipeline/measure-retrieval.d.ts +59 -0
  359. package/dist/pipeline/measure-retrieval.js +111 -0
  360. package/dist/pipeline/mirror-repo-tasks.d.ts +86 -0
  361. package/dist/pipeline/mirror-repo-tasks.js +350 -0
  362. package/dist/pipeline/plan-format.d.ts +33 -0
  363. package/dist/pipeline/plan-format.js +202 -0
  364. package/dist/pipeline/plan.d.ts +169 -0
  365. package/dist/pipeline/plan.js +708 -0
  366. package/dist/pipeline/pr-comment.d.ts +19 -0
  367. package/dist/pipeline/pr-comment.js +502 -0
  368. package/dist/pipeline/probe.d.ts +52 -0
  369. package/dist/pipeline/probe.js +390 -0
  370. package/dist/pipeline/provenance.d.ts +47 -0
  371. package/dist/pipeline/provenance.js +146 -0
  372. package/dist/pipeline/readiness-report.d.ts +87 -0
  373. package/dist/pipeline/readiness-report.js +205 -0
  374. package/dist/pipeline/release-classification.d.ts +54 -0
  375. package/dist/pipeline/release-classification.js +238 -0
  376. package/dist/pipeline/release-report.d.ts +37 -0
  377. package/dist/pipeline/release-report.js +222 -0
  378. package/dist/pipeline/repo-eval-comment.d.ts +37 -0
  379. package/dist/pipeline/repo-eval-comment.js +165 -0
  380. package/dist/pipeline/repo-threshold-evaluator.d.ts +89 -0
  381. package/dist/pipeline/repo-threshold-evaluator.js +162 -0
  382. package/dist/pipeline/resolve-mappings.d.ts +35 -0
  383. package/dist/pipeline/resolve-mappings.js +72 -0
  384. package/dist/pipeline/retrieval-metrics.d.ts +39 -0
  385. package/dist/pipeline/retrieval-metrics.js +136 -0
  386. package/dist/pipeline/reverse-mapping.d.ts +67 -0
  387. package/dist/pipeline/reverse-mapping.js +88 -0
  388. package/dist/pipeline/schemas.d.ts +9 -0
  389. package/dist/pipeline/schemas.js +9 -0
  390. package/dist/pipeline/steps/calculate-scores-step.d.ts +11 -0
  391. package/dist/pipeline/steps/calculate-scores-step.js +89 -0
  392. package/dist/pipeline/steps/compare-step.d.ts +18 -0
  393. package/dist/pipeline/steps/compare-step.js +90 -0
  394. package/dist/pipeline/steps/eval-step.d.ts +53 -0
  395. package/dist/pipeline/steps/eval-step.js +347 -0
  396. package/dist/pipeline/steps/fetch-docs-step.d.ts +11 -0
  397. package/dist/pipeline/steps/fetch-docs-step.js +84 -0
  398. package/dist/pipeline/steps/generate-configs-step.d.ts +11 -0
  399. package/dist/pipeline/steps/generate-configs-step.js +98 -0
  400. package/dist/pipeline/steps/grader-consistency-step.d.ts +21 -0
  401. package/dist/pipeline/steps/grader-consistency-step.js +74 -0
  402. package/dist/pipeline/steps/publish-report-step.d.ts +57 -0
  403. package/dist/pipeline/steps/publish-report-step.js +243 -0
  404. package/dist/pipeline/steps/report-step.d.ts +13 -0
  405. package/dist/pipeline/steps/report-step.js +56 -0
  406. package/dist/pipeline/steps/update-scores-step.d.ts +11 -0
  407. package/dist/pipeline/steps/update-scores-step.js +42 -0
  408. package/dist/pipeline/targeted-loo.d.ts +88 -0
  409. package/dist/pipeline/targeted-loo.js +203 -0
  410. package/dist/pipeline/thresholds.d.ts +27 -0
  411. package/dist/pipeline/thresholds.js +245 -0
  412. package/dist/pipeline/types.d.ts +10 -0
  413. package/dist/pipeline/types.js +10 -0
  414. package/dist/pipeline/validate.d.ts +67 -0
  415. package/dist/pipeline/validate.js +406 -0
  416. package/dist/pipeline/webhook-server.d.ts +37 -0
  417. package/dist/pipeline/webhook-server.js +133 -0
  418. package/dist/report-store.d.ts +84 -0
  419. package/dist/report-store.js +208 -0
  420. package/dist/sanity/client.d.ts +38 -0
  421. package/dist/sanity/client.js +86 -0
  422. package/dist/sanity/portable-text.d.ts +11 -0
  423. package/dist/sanity/portable-text.js +211 -0
  424. package/dist/sanity/queries.d.ts +133 -0
  425. package/dist/sanity/queries.js +300 -0
  426. package/dist/schedules/digest.d.ts +116 -0
  427. package/dist/schedules/digest.js +156 -0
  428. package/dist/schedules/index.d.ts +12 -0
  429. package/dist/schedules/index.js +10 -0
  430. package/dist/schedules/loader.d.ts +31 -0
  431. package/dist/schedules/loader.js +73 -0
  432. package/dist/schedules/schema.d.ts +9 -0
  433. package/dist/schedules/schema.js +9 -0
  434. package/dist/scripts/agent-behavior-report.d.ts +19 -0
  435. package/dist/scripts/agent-behavior-report.js +315 -0
  436. package/dist/scripts/baseline.d.ts +43 -0
  437. package/dist/scripts/baseline.js +267 -0
  438. package/dist/scripts/calculate-scores.d.ts +166 -0
  439. package/dist/scripts/calculate-scores.js +1296 -0
  440. package/dist/scripts/compare.d.ts +22 -0
  441. package/dist/scripts/compare.js +334 -0
  442. package/dist/scripts/coverage-audit.d.ts +44 -0
  443. package/dist/scripts/coverage-audit.js +209 -0
  444. package/dist/scripts/debug-eval.d.ts +19 -0
  445. package/dist/scripts/debug-eval.js +73 -0
  446. package/dist/scripts/discovery-report.d.ts +58 -0
  447. package/dist/scripts/discovery-report.js +250 -0
  448. package/dist/scripts/fetch-docs.d.ts +35 -0
  449. package/dist/scripts/fetch-docs.js +472 -0
  450. package/dist/scripts/generate-configs.d.ts +66 -0
  451. package/dist/scripts/generate-configs.js +459 -0
  452. package/dist/scripts/grader-api.d.ts +27 -0
  453. package/dist/scripts/grader-api.js +206 -0
  454. package/dist/scripts/grader-compare.d.ts +22 -0
  455. package/dist/scripts/grader-compare.js +368 -0
  456. package/dist/scripts/grader-consistency.d.ts +20 -0
  457. package/dist/scripts/grader-consistency.js +313 -0
  458. package/dist/scripts/grader-sensitivity.d.ts +22 -0
  459. package/dist/scripts/grader-sensitivity.js +354 -0
  460. package/dist/scripts/grader-validate.d.ts +19 -0
  461. package/dist/scripts/grader-validate.js +267 -0
  462. package/dist/scripts/measure-retrieval.d.ts +10 -0
  463. package/dist/scripts/measure-retrieval.js +145 -0
  464. package/dist/scripts/migrate-tasks-to-content-lake.d.ts +24 -0
  465. package/dist/scripts/migrate-tasks-to-content-lake.js +327 -0
  466. package/dist/scripts/pipeline.d.ts +76 -0
  467. package/dist/scripts/pipeline.js +1031 -0
  468. package/dist/scripts/pr-comment.d.ts +10 -0
  469. package/dist/scripts/pr-comment.js +510 -0
  470. package/dist/scripts/readiness-report.d.ts +88 -0
  471. package/dist/scripts/readiness-report.js +342 -0
  472. package/dist/scripts/update-quality-scores.d.ts +15 -0
  473. package/dist/scripts/update-quality-scores.js +184 -0
  474. package/dist/scripts/validate-task-sources.d.ts +21 -0
  475. package/dist/scripts/validate-task-sources.js +210 -0
  476. package/dist/scripts/validate.d.ts +13 -0
  477. package/dist/scripts/validate.js +79 -0
  478. package/dist/scripts/webhook-server.d.ts +26 -0
  479. package/dist/scripts/webhook-server.js +147 -0
  480. package/dist/scripts/weekly-digest.d.ts +24 -0
  481. package/dist/scripts/weekly-digest.js +144 -0
  482. package/dist/sinks/bigquery/index.d.ts +131 -0
  483. package/dist/sinks/bigquery/index.js +222 -0
  484. package/dist/sinks/format-slack.d.ts +64 -0
  485. package/dist/sinks/format-slack.js +306 -0
  486. package/dist/sinks/index.d.ts +23 -0
  487. package/dist/sinks/index.js +18 -0
  488. package/dist/sinks/loader.d.ts +18 -0
  489. package/dist/sinks/loader.js +82 -0
  490. package/dist/sinks/retry.d.ts +24 -0
  491. package/dist/sinks/retry.js +52 -0
  492. package/dist/sinks/schema.d.ts +9 -0
  493. package/dist/sinks/schema.js +9 -0
  494. package/dist/sinks/slack/format.d.ts +65 -0
  495. package/dist/sinks/slack/format.js +327 -0
  496. package/dist/sinks/slack/index.d.ts +27 -0
  497. package/dist/sinks/slack/index.js +78 -0
  498. package/dist/sinks/slack-sink.d.ts +27 -0
  499. package/dist/sinks/slack-sink.js +78 -0
  500. package/dist/sinks/types.d.ts +59 -0
  501. package/dist/sinks/types.js +44 -0
  502. package/dist/sinks/webhook/index.d.ts +19 -0
  503. package/dist/sinks/webhook/index.js +50 -0
  504. package/dist/sinks/webhook-sink.d.ts +19 -0
  505. package/dist/sinks/webhook-sink.js +50 -0
  506. package/dist/sources.d.ts +104 -0
  507. package/dist/sources.js +292 -0
  508. package/dist/webhook/budget.d.ts +42 -0
  509. package/dist/webhook/budget.js +60 -0
  510. package/dist/webhook/debounce.d.ts +67 -0
  511. package/dist/webhook/debounce.js +76 -0
  512. package/dist/webhook/dispatch.d.ts +45 -0
  513. package/dist/webhook/dispatch.js +84 -0
  514. package/dist/webhook/eval-request-handler.d.ts +87 -0
  515. package/dist/webhook/eval-request-handler.js +181 -0
  516. package/dist/webhook/handler.d.ts +88 -0
  517. package/dist/webhook/handler.js +203 -0
  518. package/dist/webhook/index.d.ts +17 -0
  519. package/dist/webhook/index.js +12 -0
  520. package/dist/webhook/types.d.ts +109 -0
  521. package/dist/webhook/types.js +10 -0
  522. package/package.json +72 -0
  523. package/tasks/.expanded.agentic.yaml +51 -0
  524. package/tasks/.expanded.yaml +66 -0
  525. package/tasks/frameworks.yaml +98 -0
  526. package/tasks/functions.yaml +51 -0
  527. package/tasks/groq.yaml +216 -0
  528. package/tasks/nextjs-live.yaml +62 -0
  529. package/tasks/studio-setup.yaml +111 -0
  530. package/tasks/visual-editing.yaml +120 -0
@@ -0,0 +1,50 @@
1
+ /**
2
+ * sinks/webhook/index.ts
3
+ *
4
+ * Generic HTTP webhook sink — POSTs the full report JSON to any endpoint.
5
+ * This is the universal adapter for integrations that don't have a
6
+ * dedicated sink (Airbyte, Zapier, custom services, etc.).
7
+ *
8
+ * @see docs/design-docs/report-store/sink-architecture.md
9
+ */
10
+ export class WebhookSink {
11
+ url;
12
+ headers;
13
+ name;
14
+ constructor(url, headers = {}) {
15
+ this.url = url;
16
+ this.headers = headers;
17
+ try {
18
+ this.name = `webhook:${new URL(url).hostname}`;
19
+ }
20
+ catch {
21
+ this.name = "webhook:invalid-url";
22
+ }
23
+ }
24
+ healthCheck() {
25
+ try {
26
+ new URL(this.url);
27
+ return Promise.resolve({ healthy: true });
28
+ }
29
+ catch {
30
+ return Promise.resolve({
31
+ healthy: false,
32
+ reason: `Invalid URL: ${this.url}`,
33
+ });
34
+ }
35
+ }
36
+ async publish(report) {
37
+ const response = await fetch(this.url, {
38
+ body: JSON.stringify(report),
39
+ headers: { "Content-Type": "application/json", ...this.headers },
40
+ method: "POST",
41
+ });
42
+ if (!response.ok) {
43
+ return {
44
+ error: `HTTP ${response.status}: ${response.statusText}`,
45
+ status: "failed",
46
+ };
47
+ }
48
+ return { detail: `HTTP ${response.status}`, status: "success" };
49
+ }
50
+ }
@@ -0,0 +1,19 @@
1
+ /**
2
+ * sinks/webhook-sink.ts
3
+ *
4
+ * Generic HTTP webhook sink — POSTs the full report JSON to any endpoint.
5
+ * This is the universal adapter for integrations that don't have a
6
+ * dedicated sink (Airbyte, Zapier, custom services, etc.).
7
+ *
8
+ * @see docs/design-docs/report-store/sink-architecture.md
9
+ */
10
+ import type { Report, SinkHealthStatus, SinkResult } from "../pipeline/types.js";
11
+ import type { ReportSink } from "./types.js";
12
+ export declare class WebhookSink implements ReportSink {
13
+ private readonly url;
14
+ private readonly headers;
15
+ readonly name: string;
16
+ constructor(url: string, headers?: Record<string, string>);
17
+ healthCheck(): Promise<SinkHealthStatus>;
18
+ publish(report: Report): Promise<SinkResult>;
19
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * sinks/webhook-sink.ts
3
+ *
4
+ * Generic HTTP webhook sink — POSTs the full report JSON to any endpoint.
5
+ * This is the universal adapter for integrations that don't have a
6
+ * dedicated sink (Airbyte, Zapier, custom services, etc.).
7
+ *
8
+ * @see docs/design-docs/report-store/sink-architecture.md
9
+ */
10
+ export class WebhookSink {
11
+ url;
12
+ headers;
13
+ name;
14
+ constructor(url, headers = {}) {
15
+ this.url = url;
16
+ this.headers = headers;
17
+ try {
18
+ this.name = `webhook:${new URL(url).hostname}`;
19
+ }
20
+ catch {
21
+ this.name = "webhook:invalid-url";
22
+ }
23
+ }
24
+ healthCheck() {
25
+ try {
26
+ new URL(this.url);
27
+ return Promise.resolve({ healthy: true });
28
+ }
29
+ catch {
30
+ return Promise.resolve({
31
+ healthy: false,
32
+ reason: `Invalid URL: ${this.url}`,
33
+ });
34
+ }
35
+ }
36
+ async publish(report) {
37
+ const response = await fetch(this.url, {
38
+ body: JSON.stringify(report),
39
+ headers: { "Content-Type": "application/json", ...this.headers },
40
+ method: "POST",
41
+ });
42
+ if (!response.ok) {
43
+ return {
44
+ error: `HTTP ${response.status}: ${response.statusText}`,
45
+ status: "failed",
46
+ };
47
+ }
48
+ return { detail: `HTTP ${response.status}`, status: "success" };
49
+ }
50
+ }
@@ -0,0 +1,104 @@
1
+ /**
2
+ * Sources.ts
3
+ *
4
+ * Loads and validates documentation source configurations from config/sources.yaml.
5
+ * Each source defines where to find documentation for evaluation — a Sanity
6
+ * dataset, a branch deploy URL, a local dev server, etc.
7
+ *
8
+ * Every source carries all fields needed by both evaluation modes:
9
+ * - Baseline/Observed: uses projectId + dataset (GROQ queries to Sanity CMS)
10
+ * - Agentic: uses baseUrl (agent browses the live site, llms.txt derived automatically)
11
+ *
12
+ * Environment variables in config/sources.yaml are resolved via ${{ VAR | default }}
13
+ * interpolation at load time.
14
+ */
15
+ /**
16
+ * @deprecated Use {@link ResolvedSourceConfig} instead.
17
+ * Kept as a type alias for backward compatibility during the transition.
18
+ */
19
+ export type DocSource = ResolvedSourceConfig;
20
+ /**
21
+ * Fully resolved documentation source configuration.
22
+ *
23
+ * After all CLI flags, environment variables, URL classifications, and
24
+ * config/sources.yaml defaults are merged, the system produces a single
25
+ * ResolvedSourceConfig that drives the entire pipeline.
26
+ *
27
+ * All ${{ }} expressions have been expanded by the time this is constructed.
28
+ */
29
+ export interface ResolvedSourceConfig {
30
+ /** Optional origin allowlist for agentic sandboxing */
31
+ allowedOrigins?: string[];
32
+ /** Base URL for documentation site (agentic mode + URL prefixes in context) */
33
+ baseUrl: string;
34
+ /** Sanity dataset name */
35
+ dataset: string;
36
+ /** Optional list of specific Sanity document IDs to fetch */
37
+ documentIds?: string[];
38
+ /** Custom HTTP headers to send with documentation requests (e.g., auth tokens) */
39
+ headers?: Record<string, string>;
40
+ /** URL to the llms.txt file — always derived as baseUrl + "/llms.txt" */
41
+ llmsTxt: string;
42
+ /** Source name (the key from config/sources.yaml, or "env-override") */
43
+ name: string;
44
+ /** Sanity release perspective ID (optional — for evaluating content releases) */
45
+ perspective?: string;
46
+ /** Hostname extracted from baseUrl — used for search result prioritization */
47
+ priorityDomain: string;
48
+ /** Sanity project ID */
49
+ projectId: string;
50
+ /** Sanity Studio base URL (for URL classification and Studio link generation) */
51
+ studioOrigin: string;
52
+ /** Direct documentation URLs (non-Sanity, from --url/--urls classification) */
53
+ urls: string[];
54
+ }
55
+ /**
56
+ * Check whether a URL is allowed by the given origin patterns.
57
+ *
58
+ * Returns `true` if:
59
+ * - `origins` is empty (no sandboxing configured), or
60
+ * - the URL's hostname matches at least one origin pattern.
61
+ *
62
+ * Returns `false` if the URL is invalid or doesn't match any pattern.
63
+ */
64
+ export declare function isAllowedOrigin(url: string, origins: string[]): boolean;
65
+ /**
66
+ * Overrides for source resolution. When provided, these values take
67
+ * precedence over environment variables. This allows callers with
68
+ * typed config (e.g., orchestration steps) to bypass the env var bridge.
69
+ */
70
+ export interface SourceOverrides {
71
+ allowedOrigins?: string[];
72
+ baseUrl?: string;
73
+ dataset?: string;
74
+ directUrls?: string[];
75
+ documentIds?: string[];
76
+ headers?: Record<string, string>;
77
+ perspective?: string;
78
+ projectId?: string;
79
+ studioOrigin?: string;
80
+ }
81
+ /**
82
+ * Load a documentation source by name.
83
+ *
84
+ * Resolution order:
85
+ * 1. If DOC_BASE_URL env var is set, build an ad-hoc source from env vars
86
+ * 2. If config/sources.yaml exists, load and interpolate the named source
87
+ * 3. Fall back to the built-in default (sanity.io production)
88
+ *
89
+ * @param name - Source name from config/sources.yaml. If omitted, uses DOC_SOURCE
90
+ * env var or the first source defined in config/sources.yaml.
91
+ */
92
+ export declare function loadSource(name?: string, overrides?: SourceOverrides): ResolvedSourceConfig;
93
+ /**
94
+ * Match a hostname against an origin pattern that may contain `*` wildcards.
95
+ *
96
+ * The `*` wildcard matches any substring within a single hostname segment
97
+ * (i.e., it does not cross dots). A bare `*` matches everything.
98
+ *
99
+ * @example
100
+ * matchesOrigin("branch.sanity.build", "*.sanity.build") // true
101
+ * matchesOrigin("sanity.io", "*.sanity.build") // false
102
+ * matchesOrigin("anything.example.com", "*") // true
103
+ */
104
+ export declare function matchesOrigin(hostname: string, pattern: string): boolean;
@@ -0,0 +1,292 @@
1
+ /**
2
+ * Sources.ts
3
+ *
4
+ * Loads and validates documentation source configurations from config/sources.yaml.
5
+ * Each source defines where to find documentation for evaluation — a Sanity
6
+ * dataset, a branch deploy URL, a local dev server, etc.
7
+ *
8
+ * Every source carries all fields needed by both evaluation modes:
9
+ * - Baseline/Observed: uses projectId + dataset (GROQ queries to Sanity CMS)
10
+ * - Agentic: uses baseUrl (agent browses the live site, llms.txt derived automatically)
11
+ *
12
+ * Environment variables in config/sources.yaml are resolved via ${{ VAR | default }}
13
+ * interpolation at load time.
14
+ */
15
+ import { readFileSync } from "fs";
16
+ import { dirname, resolve } from "path";
17
+ import { fileURLToPath } from "url";
18
+ import { load } from "js-yaml";
19
+ import { interpolate } from "./interpolate.js";
20
+ // ---------------------------------------------------------------------------
21
+ // Paths
22
+ // ---------------------------------------------------------------------------
23
+ const __dirname = dirname(fileURLToPath(import.meta.url));
24
+ const SOURCES_PATH = resolve(__dirname, "..", "config", "sources.yaml");
25
+ // ---------------------------------------------------------------------------
26
+ // Default source — used when no config/sources.yaml exists or no --source flag
27
+ // ---------------------------------------------------------------------------
28
+ const DEFAULT_SOURCE = {
29
+ baseUrl: "https://www.sanity.io/docs",
30
+ dataset: "next",
31
+ documentIds: [],
32
+ llmsTxt: "https://www.sanity.io/docs/llms.txt",
33
+ name: "production",
34
+ perspective: undefined,
35
+ priorityDomain: "sanity.io",
36
+ projectId: "3do82whm",
37
+ studioOrigin: "https://admin.sanity.io",
38
+ urls: [],
39
+ };
40
+ // ---------------------------------------------------------------------------
41
+ // Validation
42
+ // ---------------------------------------------------------------------------
43
+ /**
44
+ * Check whether a URL is allowed by the given origin patterns.
45
+ *
46
+ * Returns `true` if:
47
+ * - `origins` is empty (no sandboxing configured), or
48
+ * - the URL's hostname matches at least one origin pattern.
49
+ *
50
+ * Returns `false` if the URL is invalid or doesn't match any pattern.
51
+ */
52
+ export function isAllowedOrigin(url, origins) {
53
+ if (origins.length === 0) {
54
+ return true;
55
+ }
56
+ try {
57
+ const hostname = new URL(url).hostname.replace(/^www\./, "");
58
+ return origins.some((origin) => matchesOrigin(hostname, origin));
59
+ }
60
+ catch {
61
+ return false;
62
+ }
63
+ }
64
+ /**
65
+ * Load a documentation source by name.
66
+ *
67
+ * Resolution order:
68
+ * 1. If DOC_BASE_URL env var is set, build an ad-hoc source from env vars
69
+ * 2. If config/sources.yaml exists, load and interpolate the named source
70
+ * 3. Fall back to the built-in default (sanity.io production)
71
+ *
72
+ * @param name - Source name from config/sources.yaml. If omitted, uses DOC_SOURCE
73
+ * env var or the first source defined in config/sources.yaml.
74
+ */
75
+ export function loadSource(name, overrides) {
76
+ // Priority 1: DOC_BASE_URL env var creates an ad-hoc source
77
+ const envBaseUrl = overrides?.baseUrl ?? process.env.DOC_BASE_URL;
78
+ if (envBaseUrl) {
79
+ const domain = extractHostname(envBaseUrl);
80
+ return {
81
+ allowedOrigins: overrides?.allowedOrigins ?? parseAllowedOriginsEnv(),
82
+ baseUrl: envBaseUrl,
83
+ // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string env var should fall back to default
84
+ dataset: overrides?.dataset ?? (process.env.SANITY_DATASET || "next"),
85
+ documentIds: overrides?.documentIds ?? parseDocumentIdsEnv(),
86
+ headers: overrides?.headers ?? parseHeadersEnv(),
87
+ llmsTxt: envBaseUrl + "/llms.txt",
88
+ name: "env-override",
89
+ // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string env var should fall back to undefined
90
+ perspective: overrides?.perspective ?? (process.env.SANITY_PERSPECTIVE || undefined),
91
+ priorityDomain: domain,
92
+ // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string env var should fall back to default
93
+ projectId: overrides?.projectId ?? (process.env.SANITY_PROJECT_ID || "3do82whm"),
94
+ studioOrigin:
95
+ // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string env var should fall back to default
96
+ overrides?.studioOrigin ??
97
+ (process.env.SANITY_STUDIO_ORIGIN || "https://admin.sanity.io"),
98
+ urls: overrides?.directUrls ?? parseDirectUrlsEnv(),
99
+ };
100
+ }
101
+ // Priority 2: Load from config/sources.yaml
102
+ let rawFile;
103
+ try {
104
+ const content = readFileSync(SOURCES_PATH, "utf-8");
105
+ rawFile = load(content);
106
+ }
107
+ catch {
108
+ // No config/sources.yaml — use built-in default
109
+ console.log(" No config/sources.yaml found, using built-in default (sanity.io production)");
110
+ return DEFAULT_SOURCE;
111
+ }
112
+ if (!rawFile?.sources || Object.keys(rawFile.sources).length === 0) {
113
+ console.log(" config/sources.yaml is empty, using built-in default");
114
+ return DEFAULT_SOURCE;
115
+ }
116
+ // Resolve which source to use
117
+ const sourceName =
118
+ // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty strings should fall through to next candidate
119
+ name || process.env.DOC_SOURCE || Object.keys(rawFile.sources)[0];
120
+ const rawEntry = rawFile.sources[sourceName];
121
+ if (!rawEntry) {
122
+ const available = Object.keys(rawFile.sources).join(", ");
123
+ throw new Error('Source "' +
124
+ sourceName +
125
+ '" not found in config/sources.yaml. Available: ' +
126
+ available);
127
+ }
128
+ // Interpolate ${{ VAR }} expressions
129
+ const resolved = interpolate(rawEntry);
130
+ // Validate after interpolation
131
+ validateSource(sourceName, resolved);
132
+ // Filter empty strings from YAML-interpolated allowedOrigins.
133
+ // An interpolation like ${{ DOC_ALLOWED_ORIGIN | }} resolves to "",
134
+ // Which would produce [""] — matching nothing and silently blocking all origins.
135
+ const filteredOrigins = resolved.allowedOrigins?.filter(Boolean);
136
+ return {
137
+ allowedOrigins: filteredOrigins && filteredOrigins.length > 0
138
+ ? filteredOrigins
139
+ : undefined,
140
+ baseUrl: resolved.baseUrl,
141
+ dataset: resolved.dataset,
142
+ documentIds: overrides?.documentIds ?? parseDocumentIdsEnv() ?? [],
143
+ headers: mergeHeaders(resolved.headers, overrides?.headers ?? parseHeadersEnv()),
144
+ llmsTxt: resolved.baseUrl + "/llms.txt",
145
+ name: sourceName,
146
+ // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string env var should fall back to undefined
147
+ perspective: overrides?.perspective ?? (process.env.SANITY_PERSPECTIVE || undefined),
148
+ priorityDomain: extractHostname(resolved.baseUrl),
149
+ projectId: resolved.projectId,
150
+ // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- empty string env var should fall back to default
151
+ studioOrigin: overrides?.studioOrigin ??
152
+ (process.env.SANITY_STUDIO_ORIGIN || "https://admin.sanity.io"),
153
+ urls: [],
154
+ };
155
+ }
156
+ /**
157
+ * Match a hostname against an origin pattern that may contain `*` wildcards.
158
+ *
159
+ * The `*` wildcard matches any substring within a single hostname segment
160
+ * (i.e., it does not cross dots). A bare `*` matches everything.
161
+ *
162
+ * @example
163
+ * matchesOrigin("branch.sanity.build", "*.sanity.build") // true
164
+ * matchesOrigin("sanity.io", "*.sanity.build") // false
165
+ * matchesOrigin("anything.example.com", "*") // true
166
+ */
167
+ export function matchesOrigin(hostname, pattern) {
168
+ if (pattern === "*") {
169
+ return true;
170
+ }
171
+ // Convert glob pattern to regex: escape dots, replace * with [^.]* (within-segment)
172
+ const regexStr = "^" + pattern.replace(/\./g, "\\.").replace(/\*/g, "[^.]*") + "$";
173
+ return new RegExp(regexStr).test(hostname);
174
+ }
175
+ function extractHostname(url) {
176
+ try {
177
+ return new URL(url).hostname;
178
+ }
179
+ catch {
180
+ return url;
181
+ }
182
+ }
183
+ /**
184
+ * Merge headers from config/sources.yaml with DOC_HEADERS env var.
185
+ * Env var headers take precedence over source-defined headers.
186
+ * Returns undefined if both are empty.
187
+ */
188
+ function mergeHeaders(sourceHeaders, envHeaders) {
189
+ if (!sourceHeaders && !envHeaders) {
190
+ return undefined;
191
+ }
192
+ if (!sourceHeaders) {
193
+ return envHeaders;
194
+ }
195
+ if (!envHeaders) {
196
+ return sourceHeaders;
197
+ }
198
+ return { ...sourceHeaders, ...envHeaders };
199
+ }
200
+ /**
201
+ * Parse allowed origins from environment variables.
202
+ *
203
+ * Reads DOC_ALLOWED_ORIGINS (plural, comma-separated) first, then falls back
204
+ * to DOC_ALLOWED_ORIGIN (singular) for backward compatibility.
205
+ *
206
+ * Returns undefined if neither is set (no sandboxing).
207
+ */
208
+ function parseAllowedOriginsEnv() {
209
+ const plural = process.env.DOC_ALLOWED_ORIGINS;
210
+ if (plural) {
211
+ const origins = plural
212
+ .split(",")
213
+ .map((o) => o.trim())
214
+ .filter(Boolean);
215
+ return origins.length > 0 ? origins : undefined;
216
+ }
217
+ const singular = process.env.DOC_ALLOWED_ORIGIN;
218
+ if (singular) {
219
+ return [singular];
220
+ }
221
+ return undefined;
222
+ }
223
+ // ---------------------------------------------------------------------------
224
+ // Origin matching (exported for use by agentic-provider and assertions)
225
+ // ---------------------------------------------------------------------------
226
+ /**
227
+ * Parse direct documentation URLs from the DOC_DIRECT_URLS environment
228
+ * variable (comma-separated). These are URLs classified as "direct-url"
229
+ * by the URL classifier — they point to documentation pages rather than
230
+ * Sanity CMS resources.
231
+ */
232
+ function parseDirectUrlsEnv() {
233
+ const env = process.env.DOC_DIRECT_URLS;
234
+ if (!env) {
235
+ return [];
236
+ }
237
+ return env
238
+ .split(",")
239
+ .map((u) => u.trim())
240
+ .filter(Boolean);
241
+ }
242
+ /**
243
+ * Parse the SANITY_DOCUMENT_IDS env var (comma-separated UUIDs) into an array.
244
+ * Returns undefined if not set or empty.
245
+ */
246
+ function parseDocumentIdsEnv() {
247
+ const raw = process.env.SANITY_DOCUMENT_IDS;
248
+ if (!raw) {
249
+ return undefined;
250
+ }
251
+ const ids = raw
252
+ .split(",")
253
+ .map((id) => id.trim())
254
+ .filter(Boolean);
255
+ return ids.length > 0 ? ids : undefined;
256
+ }
257
+ /**
258
+ * Parse the DOC_HEADERS env var (JSON string) into a Record.
259
+ * Returns undefined if not set or invalid.
260
+ */
261
+ function parseHeadersEnv() {
262
+ const raw = process.env.DOC_HEADERS;
263
+ if (!raw) {
264
+ return undefined;
265
+ }
266
+ try {
267
+ const parsed = JSON.parse(raw);
268
+ if (typeof parsed === "object" &&
269
+ parsed !== null &&
270
+ !Array.isArray(parsed)) {
271
+ return parsed;
272
+ }
273
+ }
274
+ catch {
275
+ // Invalid JSON — ignore
276
+ }
277
+ return undefined;
278
+ }
279
+ // ---------------------------------------------------------------------------
280
+ // Validation
281
+ // ---------------------------------------------------------------------------
282
+ function validateSource(name, raw) {
283
+ if (!raw.baseUrl) {
284
+ throw new Error('Source "' + name + '" is missing required field "baseUrl".');
285
+ }
286
+ if (!raw.projectId) {
287
+ throw new Error('Source "' + name + '" is missing required field "projectId".');
288
+ }
289
+ if (!raw.dataset) {
290
+ throw new Error('Source "' + name + '" is missing required field "dataset".');
291
+ }
292
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * webhook/budget.ts
3
+ *
4
+ * Daily budget tracking for webhook-triggered evaluations.
5
+ *
6
+ * Evaluations cost $0.50–$5+ per run. Without guardrails, rapid-fire
7
+ * content edits could exhaust the evaluation budget. This module provides
8
+ * a simple in-memory counter that resets daily.
9
+ *
10
+ * For persistent budget tracking across process restarts, store the
11
+ * counter in Sanity or a KV store (future enhancement).
12
+ *
13
+ * @see docs/design-docs/report-store/visibility-workflows.md — Budget caps
14
+ */
15
+ /** Budget tracker state */
16
+ export interface BudgetState {
17
+ /** Number of dispatches today */
18
+ count: number;
19
+ /** ISO date string for the current day (YYYY-MM-DD) */
20
+ date: string;
21
+ /** Maximum dispatches per day */
22
+ limit: number;
23
+ }
24
+ export interface BudgetTracker {
25
+ /** Check if a dispatch is allowed (under budget) */
26
+ canDispatch(): boolean;
27
+ /** Current state */
28
+ currentState(): BudgetState;
29
+ /** Record a dispatch (increments counter) */
30
+ record(): void;
31
+ /** Remaining dispatches today */
32
+ remaining(): number;
33
+ }
34
+ /**
35
+ * Create a daily budget tracker.
36
+ *
37
+ * The counter resets automatically when the date changes (UTC).
38
+ * State is in-memory only — restarting the process resets the counter.
39
+ *
40
+ * @param dailyLimit - Maximum evaluations per day (default: 20)
41
+ */
42
+ export declare function createBudgetTracker(dailyLimit?: number): BudgetTracker;
@@ -0,0 +1,60 @@
1
+ /**
2
+ * webhook/budget.ts
3
+ *
4
+ * Daily budget tracking for webhook-triggered evaluations.
5
+ *
6
+ * Evaluations cost $0.50–$5+ per run. Without guardrails, rapid-fire
7
+ * content edits could exhaust the evaluation budget. This module provides
8
+ * a simple in-memory counter that resets daily.
9
+ *
10
+ * For persistent budget tracking across process restarts, store the
11
+ * counter in Sanity or a KV store (future enhancement).
12
+ *
13
+ * @see docs/design-docs/report-store/visibility-workflows.md — Budget caps
14
+ */
15
+ /**
16
+ * Create a daily budget tracker.
17
+ *
18
+ * The counter resets automatically when the date changes (UTC).
19
+ * State is in-memory only — restarting the process resets the counter.
20
+ *
21
+ * @param dailyLimit - Maximum evaluations per day (default: 20)
22
+ */
23
+ export function createBudgetTracker(dailyLimit = 20) {
24
+ const state = {
25
+ count: 0,
26
+ date: todayUTC(),
27
+ limit: dailyLimit,
28
+ };
29
+ function maybeReset() {
30
+ const today = todayUTC();
31
+ if (state.date !== today) {
32
+ state.count = 0;
33
+ state.date = today;
34
+ }
35
+ }
36
+ return {
37
+ canDispatch() {
38
+ maybeReset();
39
+ return state.count < state.limit;
40
+ },
41
+ currentState() {
42
+ maybeReset();
43
+ return { ...state };
44
+ },
45
+ record() {
46
+ maybeReset();
47
+ state.count++;
48
+ },
49
+ remaining() {
50
+ maybeReset();
51
+ return Math.max(0, state.limit - state.count);
52
+ },
53
+ };
54
+ }
55
+ // ---------------------------------------------------------------------------
56
+ // Helpers
57
+ // ---------------------------------------------------------------------------
58
+ function todayUTC() {
59
+ return new Date().toISOString().slice(0, 10);
60
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * webhook/debounce.ts
3
+ *
4
+ * Time-window debouncing for content change webhooks.
5
+ *
6
+ * When multiple documents are edited in rapid succession (e.g., an editor
7
+ * updating several related articles), we coalesce them into a single
8
+ * evaluation dispatch. This prevents wasting evaluation budget on
9
+ * intermediate states.
10
+ *
11
+ * Strategy: accumulate changed slugs in a time window (default: 5 minutes).
12
+ * When the window expires, dispatch a single evaluation for all accumulated
13
+ * areas. New edits during the window reset the timer ("trailing edge").
14
+ *
15
+ * @see docs/design-docs/report-store/visibility-workflows.md — Debouncing
16
+ */
17
+ /** Callback invoked when the debounce window closes */
18
+ export type DebounceCallback = (slugs: string[]) => Promise<void> | void;
19
+ /**
20
+ * A debouncer that coalesces rapid document changes into batched dispatches.
21
+ *
22
+ * Each call to `push()` adds a slug to the current window and resets the
23
+ * trailing-edge timer. When the timer fires (no new edits for `windowMs`),
24
+ * the callback is invoked with all accumulated slugs.
25
+ *
26
+ * Usage:
27
+ * ```ts
28
+ * const debouncer = createDebouncer(300_000, async (slugs) => {
29
+ * const impact = assessImpact(slugs, reverseMapping)
30
+ * await dispatch(impact)
31
+ * })
32
+ *
33
+ * // Called for each webhook:
34
+ * debouncer.push("groq-introduction")
35
+ * debouncer.push("how-queries-work")
36
+ * // ... 5 minutes of silence ...
37
+ * // → callback fires with ["groq-introduction", "how-queries-work"]
38
+ * ```
39
+ */
40
+ export interface Debouncer {
41
+ /** Cancel the current window without dispatching */
42
+ cancel(): void;
43
+ /** Flush the current window immediately (for shutdown) */
44
+ flush(): Promise<void>;
45
+ /** Number of slugs in the current window */
46
+ pending(): number;
47
+ /** Add a slug to the current debounce window */
48
+ push(slug: string): void;
49
+ /** Current state (for inspection/testing) */
50
+ state(): DebounceState;
51
+ }
52
+ /** State of a debounce window */
53
+ export interface DebounceState {
54
+ /** Accumulated document slugs */
55
+ slugs: Set<string>;
56
+ /** Timer handle for the trailing edge */
57
+ timer: null | ReturnType<typeof setTimeout>;
58
+ /** When the current window opened */
59
+ windowStart: number;
60
+ }
61
+ /**
62
+ * Create a debouncer with a configurable time window.
63
+ *
64
+ * @param windowMs - Debounce window in milliseconds (default: 300_000 = 5 min)
65
+ * @param onFlush - Callback invoked when the window closes
66
+ */
67
+ export declare function createDebouncer(windowMs: number, onFlush: DebounceCallback): Debouncer;