@inflexa-ai/harness 0.45.1 → 0.46.2

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 (790) hide show
  1. package/README.md +6 -3
  2. package/dist/agents/conversation-agent.d.ts +9 -3
  3. package/dist/agents/conversation-agent.js +34 -33
  4. package/dist/agents/report-session-agent.d.ts +15 -15
  5. package/dist/agents/report-session-agent.js +23 -15
  6. package/dist/agents/sandbox/index.d.ts +1 -1
  7. package/dist/agents/sandbox/index.js +1 -1
  8. package/dist/agents/sandbox/shared.d.ts +12 -14
  9. package/dist/agents/sandbox/shared.js +18 -12
  10. package/dist/agents/sandbox/types.d.ts +4 -4
  11. package/dist/agents/sandbox/validate-skills.d.ts +2 -2
  12. package/dist/agents/sandbox/validate-skills.js +3 -1
  13. package/dist/agents/sandbox-catalog.d.ts +2 -2
  14. package/dist/agents/sandbox-catalog.js +3 -3
  15. package/dist/agents/system-prompt.d.ts +2 -2
  16. package/dist/app/chat-turn-workflow.d.ts +114 -0
  17. package/dist/app/chat-turn-workflow.js +306 -0
  18. package/dist/app/chat-turn.d.ts +85 -57
  19. package/dist/app/chat-turn.js +123 -100
  20. package/dist/app/data-profile-orientation.js +10 -8
  21. package/dist/app/data-profile-view.d.ts +4 -4
  22. package/dist/app/data-profile-view.js +9 -8
  23. package/dist/app/in-process-turn.d.ts +42 -0
  24. package/dist/app/in-process-turn.js +139 -0
  25. package/dist/app/message-assembly.d.ts +10 -4
  26. package/dist/app/message-assembly.js +13 -8
  27. package/dist/app/report-session-runtime.d.ts +4 -4
  28. package/dist/app/report-session-runtime.js +36 -21
  29. package/dist/app/spawn-report-session.d.ts +33 -28
  30. package/dist/app/spawn-report-session.js +25 -40
  31. package/dist/app/synthesize-run.d.ts +22 -16
  32. package/dist/app/synthesize-run.js +41 -35
  33. package/dist/app/work.d.ts +96 -0
  34. package/dist/app/work.js +147 -0
  35. package/dist/auth/local-auth-context.d.ts +1 -3
  36. package/dist/auth/local-auth-context.js +1 -3
  37. package/dist/auth/local-run-authorizer.d.ts +1 -1
  38. package/dist/auth/local-run-authorizer.js +5 -3
  39. package/dist/auth/types.d.ts +26 -26
  40. package/dist/billing/cached-resolver.d.ts +4 -4
  41. package/dist/billing/run-charge.d.ts +5 -8
  42. package/dist/billing/run-charge.js +2 -2
  43. package/dist/billing/usage-recorder.d.ts +9 -9
  44. package/dist/citations/aggregate.js +1 -1
  45. package/dist/citations/clients/arxiv.d.ts +2 -2
  46. package/dist/citations/clients/arxiv.js +12 -4
  47. package/dist/citations/clients/common.js +4 -2
  48. package/dist/citations/clients/crossref.d.ts +2 -2
  49. package/dist/citations/clients/crossref.js +37 -37
  50. package/dist/citations/clients/doi-registry.js +15 -16
  51. package/dist/citations/clients/pubmed.d.ts +2 -2
  52. package/dist/citations/clients/pubmed.js +20 -13
  53. package/dist/citations/clients/semantic-scholar.d.ts +2 -2
  54. package/dist/citations/clients/semantic-scholar.js +9 -9
  55. package/dist/citations/compare.js +2 -2
  56. package/dist/citations/match.d.ts +2 -2
  57. package/dist/citations/match.js +12 -7
  58. package/dist/citations/normalize.js +35 -26
  59. package/dist/citations/plan.js +6 -2
  60. package/dist/citations/resolve.d.ts +6 -6
  61. package/dist/citations/resolve.js +34 -25
  62. package/dist/citations/types.d.ts +77 -77
  63. package/dist/config/environment-stores.d.ts +6 -6
  64. package/dist/config/resource-limits.js +1 -3
  65. package/dist/contracts/analogy-report.d.ts +7 -7
  66. package/dist/contracts/analogy-report.js +2 -2
  67. package/dist/contracts/chat-events.d.ts +38 -24
  68. package/dist/contracts/chat-frame.d.ts +15 -5
  69. package/dist/contracts/chat-frame.js +64 -41
  70. package/dist/contracts/chat-parts.d.ts +130 -67
  71. package/dist/contracts/chat-parts.js +1 -0
  72. package/dist/contracts/content-url.js +16 -2
  73. package/dist/contracts/data-profile.d.ts +38 -38
  74. package/dist/contracts/index.d.ts +2 -2
  75. package/dist/contracts/index.js +1 -1
  76. package/dist/contracts/message.d.ts +6 -6
  77. package/dist/contracts/organ-system.d.ts +11 -11
  78. package/dist/contracts/part-registry.d.ts +5 -4
  79. package/dist/contracts/part-registry.js +5 -0
  80. package/dist/contracts/profile-vocabulary.d.ts +11 -10
  81. package/dist/contracts/profile-vocabulary.js +10 -3
  82. package/dist/contracts/report-blocks.d.ts +329 -329
  83. package/dist/contracts/report-reference.d.ts +105 -81
  84. package/dist/contracts/report-reference.js +30 -13
  85. package/dist/contracts/schemas/chat-events.d.ts +30 -16
  86. package/dist/contracts/schemas/chat-events.js +15 -6
  87. package/dist/contracts/schemas/chat-parts.d.ts +175 -102
  88. package/dist/contracts/schemas/chat-parts.js +33 -7
  89. package/dist/contracts/severity.d.ts +1 -1
  90. package/dist/contracts/structure-source.d.ts +3 -3
  91. package/dist/contracts/structure-source.js +6 -2
  92. package/dist/contracts/subagent-activity.d.ts +2 -2
  93. package/dist/contracts/subagent-activity.js +5 -3
  94. package/dist/contracts/usage.d.ts +2 -2
  95. package/dist/data/safety-panel-schema.d.ts +25 -25
  96. package/dist/data/safety-panel-schema.js +13 -4
  97. package/dist/execution/artifact-metadata.d.ts +23 -15
  98. package/dist/execution/artifact-metadata.js +33 -10
  99. package/dist/execution/artifact-record.d.ts +2 -2
  100. package/dist/execution/artifact-registration.d.ts +5 -5
  101. package/dist/execution/artifact-registry.d.ts +8 -8
  102. package/dist/execution/dbos-run-launcher.d.ts +24 -4
  103. package/dist/execution/dbos-run-launcher.js +58 -4
  104. package/dist/execution/dbos-workflow-purger.d.ts +5 -6
  105. package/dist/execution/dbos-workflow-purger.js +8 -7
  106. package/dist/execution/input-signature.d.ts +2 -2
  107. package/dist/execution/post-step-pipeline.d.ts +9 -9
  108. package/dist/execution/post-step-pipeline.js +1 -1
  109. package/dist/execution/post-step.js +2 -2
  110. package/dist/execution/reconcile-manifest.d.ts +4 -4
  111. package/dist/execution/reconcile-manifest.js +3 -2
  112. package/dist/execution/run-authorizer.d.ts +46 -37
  113. package/dist/execution/run-authorizer.js +8 -8
  114. package/dist/execution/run-canceler.d.ts +7 -7
  115. package/dist/execution/run-canceler.js +14 -7
  116. package/dist/execution/run-end-record.d.ts +2 -3
  117. package/dist/execution/run-event-parts.d.ts +0 -8
  118. package/dist/execution/run-event-parts.js +29 -24
  119. package/dist/execution/run-event-stream.d.ts +8 -8
  120. package/dist/execution/run-event-stream.js +3 -4
  121. package/dist/execution/run-launcher.d.ts +4 -4
  122. package/dist/execution/run-synthesis.d.ts +49 -48
  123. package/dist/execution/run-synthesis.js +96 -255
  124. package/dist/execution/staged-input.d.ts +2 -2
  125. package/dist/execution/step-summary.d.ts +6 -6
  126. package/dist/execution/step-summary.js +4 -8
  127. package/dist/execution/topo-sort.js +4 -3
  128. package/dist/execution/workflow-purger.d.ts +2 -2
  129. package/dist/index.d.ts +17 -20
  130. package/dist/index.js +25 -36
  131. package/dist/input-sanitization.js +9 -2
  132. package/dist/input-scan/clustering.d.ts +6 -6
  133. package/dist/input-scan/clustering.js +11 -5
  134. package/dist/input-scan/companions.js +3 -2
  135. package/dist/input-scan/detect-sets.d.ts +2 -2
  136. package/dist/input-scan/detect-sets.js +25 -21
  137. package/dist/input-scan/enrich.d.ts +6 -6
  138. package/dist/input-scan/enrich.js +29 -12
  139. package/dist/input-scan/formats.d.ts +2 -2
  140. package/dist/input-scan/formats.js +8 -2
  141. package/dist/input-scan/markers.d.ts +2 -2
  142. package/dist/input-scan/markers.js +14 -5
  143. package/dist/input-scan/menu.d.ts +10 -10
  144. package/dist/input-scan/menu.js +0 -0
  145. package/dist/input-scan/quarantine.d.ts +2 -2
  146. package/dist/input-scan/quarantine.js +23 -18
  147. package/dist/input-scan/readout-budget.d.ts +2 -2
  148. package/dist/input-scan/readout-budget.js +1 -1
  149. package/dist/input-scan/readout.d.ts +2 -2
  150. package/dist/input-scan/readout.js +47 -34
  151. package/dist/input-scan/scan.d.ts +2 -2
  152. package/dist/input-scan/scan.js +7 -5
  153. package/dist/input-scan/set-types.d.ts +28 -28
  154. package/dist/input-scan/shapes.d.ts +4 -4
  155. package/dist/input-scan/shapes.js +0 -0
  156. package/dist/input-scan/templates.d.ts +10 -10
  157. package/dist/input-scan/templates.js +30 -22
  158. package/dist/input-scan/tokens.d.ts +6 -4
  159. package/dist/input-scan/tokens.js +100 -38
  160. package/dist/input-scan/types.d.ts +22 -22
  161. package/dist/lib/async-utils.d.ts +3 -7
  162. package/dist/lib/async-utils.js +5 -9
  163. package/dist/lib/cache.js +1 -1
  164. package/dist/lib/chrome.d.ts +46 -6
  165. package/dist/lib/console-logger.js +2 -2
  166. package/dist/lib/db-result.d.ts +22 -6
  167. package/dist/lib/db-result.js +9 -13
  168. package/dist/lib/eyes.d.ts +4 -4
  169. package/dist/lib/eyes.js +1 -1
  170. package/dist/lib/fs-helpers.js +18 -6
  171. package/dist/lib/fs-result.d.ts +1 -0
  172. package/dist/lib/fs-result.js +5 -6
  173. package/dist/lib/hooks.d.ts +32 -7
  174. package/dist/lib/hooks.js +22 -3
  175. package/dist/lib/host-concurrency.js +3 -2
  176. package/dist/lib/logger.d.ts +2 -2
  177. package/dist/lib/logger.js +2 -1
  178. package/dist/lib/metrics.d.ts +1 -1
  179. package/dist/lib/null-proto.d.ts +6 -0
  180. package/dist/lib/null-proto.js +17 -0
  181. package/dist/lib/otel-spans.d.ts +1 -1
  182. package/dist/lib/otel-spans.js +9 -5
  183. package/dist/lib/otel.d.ts +4 -2
  184. package/dist/lib/otel.js +10 -2
  185. package/dist/lib/page-capture.d.ts +8 -8
  186. package/dist/lib/page-capture.js +9 -4
  187. package/dist/lib/parse-json.d.ts +5 -0
  188. package/dist/lib/parse-json.js +12 -0
  189. package/dist/lib/present.d.ts +12 -0
  190. package/dist/lib/present.js +39 -0
  191. package/dist/lib/rate-limit.d.ts +4 -4
  192. package/dist/lib/rate-limit.js +12 -13
  193. package/dist/lib/regulatory-corpus/fetch-fda-guidance.d.ts +4 -4
  194. package/dist/lib/regulatory-corpus/fetch-fda-guidance.js +4 -10
  195. package/dist/lib/regulatory-corpus/fetch-ich.d.ts +4 -4
  196. package/dist/lib/regulatory-corpus/fetch-ich.js +18 -14
  197. package/dist/lib/regulatory-corpus/normalize-whitespace.d.ts +6 -0
  198. package/dist/lib/regulatory-corpus/normalize-whitespace.js +41 -0
  199. package/dist/lib/regulatory-corpus.d.ts +10 -10
  200. package/dist/lib/regulatory-corpus.js +3 -1
  201. package/dist/lib/result.d.ts +10 -11
  202. package/dist/lib/result.js +15 -13
  203. package/dist/lib/storage.d.ts +2 -2
  204. package/dist/lib/test/async-iterable.d.ts +9 -0
  205. package/dist/lib/test/async-iterable.js +28 -0
  206. package/dist/lib/test/request-url.d.ts +5 -0
  207. package/dist/lib/test/request-url.js +7 -0
  208. package/dist/lib/test/result-assert.d.ts +12 -0
  209. package/dist/lib/test/result-assert.js +17 -0
  210. package/dist/lib/test/text-shapes.d.ts +24 -0
  211. package/dist/lib/test/text-shapes.js +63 -0
  212. package/dist/lib/text.d.ts +22 -0
  213. package/dist/lib/text.js +68 -0
  214. package/dist/lib/thrown.d.ts +18 -0
  215. package/dist/lib/thrown.js +30 -0
  216. package/dist/lib/unknown-array.d.ts +6 -0
  217. package/dist/lib/unknown-array.js +8 -0
  218. package/dist/lib/unknown-containers.d.ts +14 -0
  219. package/dist/lib/unknown-containers.js +17 -0
  220. package/dist/lib/unknown-text.d.ts +8 -0
  221. package/dist/lib/unknown-text.js +28 -0
  222. package/dist/lib/zod-issue-shape.d.ts +1 -1
  223. package/dist/lib/zod-issue-shape.js +31 -31
  224. package/dist/lib/zod-issues.d.ts +3 -3
  225. package/dist/lib/zod-issues.js +30 -17
  226. package/dist/literature/sources/arxiv.d.ts +6 -6
  227. package/dist/literature/sources/arxiv.js +92 -35
  228. package/dist/literature/sources/http.d.ts +2 -2
  229. package/dist/literature/sources/http.js +16 -15
  230. package/dist/literature/sources/pubmed.d.ts +16 -16
  231. package/dist/literature/sources/pubmed.js +96 -61
  232. package/dist/literature/sources/semantic-scholar.d.ts +8 -8
  233. package/dist/literature/sources/semantic-scholar.js +22 -13
  234. package/dist/loop/accounting.d.ts +63 -0
  235. package/dist/loop/accounting.js +141 -0
  236. package/dist/loop/call-policy.d.ts +73 -0
  237. package/dist/loop/call-policy.js +109 -0
  238. package/dist/loop/chat-stream.d.ts +62 -0
  239. package/dist/loop/chat-stream.js +237 -0
  240. package/dist/loop/compaction.d.ts +9 -9
  241. package/dist/loop/compaction.js +1 -1
  242. package/dist/loop/metrics.d.ts +12 -15
  243. package/dist/loop/metrics.js +14 -26
  244. package/dist/loop/run-loop.d.ts +233 -0
  245. package/dist/loop/run-loop.js +770 -0
  246. package/dist/loop/sub-agent.d.ts +61 -0
  247. package/dist/loop/sub-agent.js +160 -0
  248. package/dist/loop/tool-adapter.d.ts +98 -0
  249. package/dist/loop/tool-adapter.js +364 -0
  250. package/dist/loop/tool-detail.d.ts +1 -1
  251. package/dist/loop/tool-detail.js +6 -5
  252. package/dist/loop/tool-outcome.d.ts +1 -1
  253. package/dist/loop/tool-output.d.ts +4 -4
  254. package/dist/loop/tool-output.js +2 -2
  255. package/dist/loop/turn-credentials.d.ts +39 -0
  256. package/dist/loop/turn-credentials.js +90 -0
  257. package/dist/loop/types.d.ts +29 -38
  258. package/dist/loop/types.js +2 -7
  259. package/dist/memory/ai-sdk-message-storage.d.ts +5 -5
  260. package/dist/memory/ai-sdk-message-storage.js +13 -11
  261. package/dist/memory/card-builders.d.ts +14 -14
  262. package/dist/memory/card-builders.js +19 -15
  263. package/dist/memory/conversation-display-recorder.d.ts +22 -4
  264. package/dist/memory/conversation-display-recorder.js +43 -24
  265. package/dist/memory/conversation-display-replay.js +3 -2
  266. package/dist/memory/conversation-display-storage.d.ts +15 -7
  267. package/dist/memory/conversation-display-storage.js +141 -36
  268. package/dist/memory/conversation-view.d.ts +4 -4
  269. package/dist/memory/conversation-view.js +5 -4
  270. package/dist/memory/count-tokens.js +10 -8
  271. package/dist/memory/derive-thread-title.d.ts +0 -13
  272. package/dist/memory/derive-thread-title.js +2 -1
  273. package/dist/memory/message-backfill.d.ts +12 -5
  274. package/dist/memory/message-backfill.js +5 -3
  275. package/dist/memory/thread-history.d.ts +36 -21
  276. package/dist/memory/thread-history.js +78 -54
  277. package/dist/memory/thread-store.d.ts +26 -17
  278. package/dist/memory/thread-store.js +15 -9
  279. package/dist/memory/tool-call-integrity.d.ts +2 -2
  280. package/dist/memory/tool-call-integrity.js +4 -3
  281. package/dist/memory/working-memory.d.ts +16 -12
  282. package/dist/memory/working-memory.js +72 -61
  283. package/dist/prompts/briefing.d.ts +12 -12
  284. package/dist/prompts/briefing.js +1 -1
  285. package/dist/prompts/synthesis-agent.d.ts +1 -1
  286. package/dist/prompts/synthesis-agent.js +6 -14
  287. package/dist/provenance/collector.d.ts +6 -6
  288. package/dist/provenance/collector.js +15 -8
  289. package/dist/provenance/exec-frame.d.ts +2 -2
  290. package/dist/provenance/exec-frame.js +6 -1
  291. package/dist/provenance/seam.d.ts +1 -4
  292. package/dist/provenance/types.d.ts +6 -6
  293. package/dist/providers/ai-sdk.d.ts +113 -62
  294. package/dist/providers/ai-sdk.js +283 -518
  295. package/dist/providers/embedding.d.ts +2 -2
  296. package/dist/providers/embedding.js +1 -1
  297. package/dist/providers/errors.d.ts +22 -2
  298. package/dist/providers/errors.js +98 -50
  299. package/dist/providers/prompt-cache.d.ts +8 -8
  300. package/dist/providers/prompt-cache.js +13 -11
  301. package/dist/providers/reasoning.d.ts +2 -2
  302. package/dist/providers/reasoning.js +2 -2
  303. package/dist/providers/request-headers.js +12 -3
  304. package/dist/providers/types.d.ts +55 -94
  305. package/dist/reference-data/catalog.d.ts +2 -15
  306. package/dist/reference-data/catalog.js +25 -8
  307. package/dist/reference-data/receipt.d.ts +2 -2
  308. package/dist/report-model/assert-rules.js +1 -1
  309. package/dist/report-model/authoring-grammar.d.ts +211 -233
  310. package/dist/report-model/block-walk.d.ts +10 -10
  311. package/dist/report-model/block-walk.js +2 -0
  312. package/dist/report-model/draft-finish.d.ts +8 -8
  313. package/dist/report-model/draft-finish.js +1 -1
  314. package/dist/report-model/draft-hash.js +8 -7
  315. package/dist/report-model/draft-operations.d.ts +22 -10
  316. package/dist/report-model/draft-operations.js +48 -30
  317. package/dist/report-model/draft-read.d.ts +19 -7
  318. package/dist/report-model/draft-read.js +16 -6
  319. package/dist/report-model/draft.d.ts +844 -2
  320. package/dist/report-model/draft.js +3 -1
  321. package/dist/report-model/fixture-resolver.js +39 -16
  322. package/dist/report-model/pin-snapshot.d.ts +2 -2
  323. package/dist/report-model/pin-snapshot.js +15 -15
  324. package/dist/report-model/production-resolver.d.ts +18 -18
  325. package/dist/report-model/production-resolver.js +50 -42
  326. package/dist/report-model/reference-resolver.d.ts +26 -10
  327. package/dist/report-model/reference-resolver.js +68 -5
  328. package/dist/report-model/reference-stamp.js +30 -38
  329. package/dist/report-model/structural-validation.js +12 -4
  330. package/dist/report-model/validate.d.ts +7 -7
  331. package/dist/report-model/validate.js +6 -6
  332. package/dist/report-render/assets.d.ts +2 -2
  333. package/dist/report-render/assets.js +27 -3
  334. package/dist/report-render/chart-export.d.ts +10 -2
  335. package/dist/report-render/chart-export.js +37 -11
  336. package/dist/report-render/chart-presets.d.ts +8 -8
  337. package/dist/report-render/chart-presets.js +3 -3
  338. package/dist/report-render/chart-renderers.d.ts +23 -16
  339. package/dist/report-render/chart-renderers.js +74 -53
  340. package/dist/report-render/chart-toolbox.d.ts +2 -2
  341. package/dist/report-render/chart-toolbox.js +7 -6
  342. package/dist/report-render/chart.d.ts +15 -16
  343. package/dist/report-render/chart.js +369 -252
  344. package/dist/report-render/design.d.ts +36 -297
  345. package/dist/report-render/design.js +0 -12
  346. package/dist/report-render/figures/common.d.ts +12 -12
  347. package/dist/report-render/figures/common.js +42 -31
  348. package/dist/report-render/figures/dendrogram.d.ts +3 -3
  349. package/dist/report-render/figures/dendrogram.js +10 -10
  350. package/dist/report-render/figures/dense.js +15 -8
  351. package/dist/report-render/figures/dotplot.js +46 -33
  352. package/dist/report-render/figures/embedding.js +52 -43
  353. package/dist/report-render/figures/equal-units.d.ts +10 -10
  354. package/dist/report-render/figures/equal-units.js +27 -27
  355. package/dist/report-render/figures/forest.js +9 -7
  356. package/dist/report-render/figures/gsea.js +21 -11
  357. package/dist/report-render/figures/heatmap.js +13 -9
  358. package/dist/report-render/figures/index.d.ts +10 -10
  359. package/dist/report-render/figures/index.js +4 -2
  360. package/dist/report-render/figures/km.js +10 -9
  361. package/dist/report-render/figures/label-room.d.ts +12 -12
  362. package/dist/report-render/figures/label-room.js +7 -2
  363. package/dist/report-render/figures/locuszoom.d.ts +2 -2
  364. package/dist/report-render/figures/locuszoom.js +59 -31
  365. package/dist/report-render/figures/lollipop.js +3 -2
  366. package/dist/report-render/figures/ma.js +8 -4
  367. package/dist/report-render/figures/manhattan.d.ts +1 -2
  368. package/dist/report-render/figures/manhattan.js +52 -34
  369. package/dist/report-render/figures/oncoprint.js +4 -5
  370. package/dist/report-render/figures/pca.js +25 -11
  371. package/dist/report-render/figures/qq.js +20 -9
  372. package/dist/report-render/figures/roc.js +1 -1
  373. package/dist/report-render/figures/sankey.d.ts +2 -2
  374. package/dist/report-render/figures/sankey.js +11 -10
  375. package/dist/report-render/figures/upset.d.ts +6 -6
  376. package/dist/report-render/figures/upset.js +7 -4
  377. package/dist/report-render/figures/volcano.js +12 -10
  378. package/dist/report-render/hybrid-svg.d.ts +4 -4
  379. package/dist/report-render/hybrid-svg.js +7 -5
  380. package/dist/report-render/number-format.d.ts +4 -4
  381. package/dist/report-render/number-format.js +62 -27
  382. package/dist/report-render/page.js +2 -1
  383. package/dist/report-render/provenance-data.d.ts +2 -2
  384. package/dist/report-render/references.d.ts +4 -4
  385. package/dist/report-render/render.d.ts +2 -2
  386. package/dist/report-render/render.js +10 -11
  387. package/dist/report-render/script-json.js +1 -1
  388. package/dist/report-render/table-data.d.ts +6 -6
  389. package/dist/report-render/test/options.d.ts +49 -0
  390. package/dist/report-render/test/options.js +143 -0
  391. package/dist/report-render/test/page-function.d.ts +19 -0
  392. package/dist/report-render/test/page-function.js +33 -0
  393. package/dist/report-render/types.d.ts +10 -10
  394. package/dist/report-render/value-bridge.d.ts +4 -4
  395. package/dist/report-render/value-bridge.js +27 -14
  396. package/dist/report-render/views/chart-view.d.ts +2 -2
  397. package/dist/report-render/views/chart-view.js +2 -2
  398. package/dist/report-render/views/lineage.d.ts +6 -6
  399. package/dist/report-render/views/lineage.js +2 -0
  400. package/dist/report-render/views/page-view.d.ts +2 -2
  401. package/dist/report-render/views/page-view.js +1 -0
  402. package/dist/report-render/views/prose.js +25 -8
  403. package/dist/report-render/views/references-view.js +12 -1
  404. package/dist/report-render/views/values.js +1 -1
  405. package/dist/runtime/assemble.d.ts +53 -26
  406. package/dist/runtime/assemble.js +103 -56
  407. package/dist/runtime/boot.d.ts +8 -7
  408. package/dist/runtime/boot.js +1 -1
  409. package/dist/runtime/connection-budget.d.ts +6 -6
  410. package/dist/runtime/connection-budget.js +1 -1
  411. package/dist/runtime/dbos.d.ts +29 -19
  412. package/dist/runtime/dbos.js +35 -20
  413. package/dist/runtime/result-serialization.js +18 -5
  414. package/dist/runtime/shutdown.d.ts +2 -2
  415. package/dist/sandbox/client.d.ts +7 -3
  416. package/dist/sandbox/cpu-files.d.ts +2 -2
  417. package/dist/sandbox/cpu-files.js +21 -4
  418. package/dist/sandbox/create-sandbox.d.ts +7 -8
  419. package/dist/sandbox/create-sandbox.js +6 -12
  420. package/dist/sandbox/docker-client.d.ts +48 -3
  421. package/dist/sandbox/docker-client.js +10 -6
  422. package/dist/sandbox/estimate-data-profile-resources.js +2 -7
  423. package/dist/sandbox/exec-outcome.d.ts +2 -2
  424. package/dist/sandbox/exec-outcome.js +1 -1
  425. package/dist/sandbox/exec.d.ts +10 -6
  426. package/dist/sandbox/exec.js +27 -12
  427. package/dist/sandbox/execution-id.js +14 -6
  428. package/dist/sandbox/farm.d.ts +2 -2
  429. package/dist/sandbox/farm.js +22 -27
  430. package/dist/sandbox/identity.d.ts +7 -0
  431. package/dist/sandbox/identity.js +14 -3
  432. package/dist/sandbox/image-packages.js +15 -27
  433. package/dist/sandbox/k8s-client.d.ts +35 -8
  434. package/dist/sandbox/k8s-client.js +6 -5
  435. package/dist/sandbox/labels.js +1 -0
  436. package/dist/sandbox/liveness.js +3 -1
  437. package/dist/sandbox/mount-plan.d.ts +10 -10
  438. package/dist/sandbox/mount-plan.js +13 -14
  439. package/dist/sandbox/notification-sweep.d.ts +4 -4
  440. package/dist/sandbox/notification-sweep.js +4 -7
  441. package/dist/sandbox/package-identity.d.ts +6 -13
  442. package/dist/sandbox/package-identity.js +46 -28
  443. package/dist/sandbox/reaper.d.ts +10 -10
  444. package/dist/sandbox/reaper.js +4 -6
  445. package/dist/sandbox/sandbox-error.d.ts +2 -9
  446. package/dist/sandbox/sandbox-error.js +21 -8
  447. package/dist/sandbox/sandbox-step-translate.d.ts +8 -5
  448. package/dist/sandbox/sandbox-step-translate.js +22 -8
  449. package/dist/sandbox/step-sandbox.d.ts +47 -0
  450. package/dist/sandbox/step-sandbox.js +53 -0
  451. package/dist/sandbox/types.d.ts +18 -19
  452. package/dist/sandbox/types.js +1 -1
  453. package/dist/schemas/artifact-manifest.d.ts +4 -4
  454. package/dist/schemas/data-profile-schemas.d.ts +343 -298
  455. package/dist/schemas/file-metadata.js +2 -4
  456. package/dist/schemas/plan-schemas.d.ts +31 -31
  457. package/dist/schemas/run-synthesis.d.ts +95 -26
  458. package/dist/schemas/run-synthesis.js +3 -1
  459. package/dist/schemas/validate-plan.d.ts +4 -4
  460. package/dist/schemas/validate-plan.js +17 -5
  461. package/dist/schemas/workflow-state.d.ts +19 -19
  462. package/dist/schemas/workflow-state.js +2 -2
  463. package/dist/state/active-turns.d.ts +36 -0
  464. package/dist/state/active-turns.js +67 -0
  465. package/dist/state/analyses-metrics.d.ts +8 -8
  466. package/dist/state/analyses-metrics.js +4 -4
  467. package/dist/state/analyses.d.ts +0 -14
  468. package/dist/state/analyses.js +0 -32
  469. package/dist/state/artifacts.d.ts +32 -19
  470. package/dist/state/artifacts.js +28 -5
  471. package/dist/state/data-profile.d.ts +2 -2
  472. package/dist/state/db.d.ts +12 -2
  473. package/dist/state/db.js +5 -0
  474. package/dist/state/edit-intents.d.ts +4 -0
  475. package/dist/state/edit-intents.js +71 -0
  476. package/dist/state/index.d.ts +4 -4
  477. package/dist/state/index.js +2 -2
  478. package/dist/state/init.d.ts +2 -1
  479. package/dist/state/init.js +5 -2
  480. package/dist/state/migrations/20260927120000_baseline.js +3 -1
  481. package/dist/state/migrations/20261026120000_add_the_edit_intents.d.ts +7 -0
  482. package/dist/state/migrations/20261026120000_add_the_edit_intents.js +21 -0
  483. package/dist/state/migrations/20261027120000_record_the_applied_memory_edits.d.ts +7 -0
  484. package/dist/state/migrations/20261027120000_record_the_applied_memory_edits.js +16 -0
  485. package/dist/state/migrations/20261027120100_store_the_authoring_results.d.ts +8 -0
  486. package/dist/state/migrations/20261027120100_store_the_authoring_results.js +20 -0
  487. package/dist/state/migrations/20261027120200_key_the_groups_of_a_turn.d.ts +7 -0
  488. package/dist/state/migrations/20261027120200_key_the_groups_of_a_turn.js +12 -0
  489. package/dist/state/migrations/20261027120300_mark_the_active_turn_of_a_thread.d.ts +7 -0
  490. package/dist/state/migrations/20261027120300_mark_the_active_turn_of_a_thread.js +11 -0
  491. package/dist/state/migrations/20261028120000_record_the_paused_work.d.ts +7 -0
  492. package/dist/state/migrations/20261028120000_record_the_paused_work.js +25 -0
  493. package/dist/state/migrations/20261028120100_end_the_suspended_runs.d.ts +8 -0
  494. package/dist/state/migrations/20261028120100_end_the_suspended_runs.js +13 -0
  495. package/dist/state/migrations/20261029120000_reference_the_run_mandate.d.ts +7 -0
  496. package/dist/state/migrations/20261029120000_reference_the_run_mandate.js +23 -0
  497. package/dist/state/migrations/20261029120100_record_the_run_session_of_a_pause.d.ts +7 -0
  498. package/dist/state/migrations/20261029120100_record_the_run_session_of_a_pause.js +11 -0
  499. package/dist/state/migrations/index.js +18 -0
  500. package/dist/state/paused-work.d.ts +52 -0
  501. package/dist/state/paused-work.js +105 -0
  502. package/dist/state/plans.d.ts +27 -8
  503. package/dist/state/plans.js +14 -11
  504. package/dist/state/purge-analysis.d.ts +6 -6
  505. package/dist/state/purge-analysis.js +10 -2
  506. package/dist/state/report-session-state.d.ts +43 -18
  507. package/dist/state/report-session-state.js +43 -4
  508. package/dist/state/report-versions.d.ts +16 -11
  509. package/dist/state/report-versions.js +5 -3
  510. package/dist/state/runs.d.ts +30 -19
  511. package/dist/state/runs.js +43 -51
  512. package/dist/state/schema.d.ts +18 -21
  513. package/dist/state/schema.js +4 -5
  514. package/dist/state/snapshot-parse.d.ts +2 -2
  515. package/dist/state/snapshot-parse.js +14 -8
  516. package/dist/state/step-executions.d.ts +20 -8
  517. package/dist/state/step-executions.js +6 -4
  518. package/dist/state/tool-outputs.d.ts +2 -2
  519. package/dist/state/tool-outputs.js +2 -1
  520. package/dist/state/vector-store.d.ts +16 -16
  521. package/dist/state/vector-store.js +11 -7
  522. package/dist/tasks/data-profile-absorb.d.ts +3 -3
  523. package/dist/tasks/data-profile-absorb.js +21 -16
  524. package/dist/tasks/data-profile-activity.d.ts +5 -5
  525. package/dist/tasks/data-profile-activity.js +5 -5
  526. package/dist/tasks/data-profile-index.d.ts +4 -4
  527. package/dist/tasks/data-profile-index.js +32 -17
  528. package/dist/tasks/data-profile-resolve.d.ts +8 -8
  529. package/dist/tasks/data-profile-resolve.js +88 -62
  530. package/dist/tasks/data-profile.d.ts +40 -31
  531. package/dist/tasks/data-profile.js +138 -95
  532. package/dist/tasks/extract-values.d.ts +26 -79
  533. package/dist/tasks/extract-values.js +48 -108
  534. package/dist/tasks/refresh-regulatory-corpus.d.ts +4 -20
  535. package/dist/tasks/refresh-regulatory-corpus.js +12 -8
  536. package/dist/tasks/regulatory-corpus-boot-refresh.d.ts +2 -2
  537. package/dist/tasks/regulatory-corpus-boot-refresh.js +12 -10
  538. package/dist/testing.d.ts +62 -0
  539. package/dist/testing.js +101 -0
  540. package/dist/tools/ad-hoc-router.d.ts +9 -9
  541. package/dist/tools/ad-hoc-router.js +65 -52
  542. package/dist/tools/analysis-invocation.d.ts +7 -0
  543. package/dist/tools/analysis-invocation.js +29 -5
  544. package/dist/tools/approval/contract.d.ts +8 -52
  545. package/dist/tools/approval/contract.js +7 -36
  546. package/dist/tools/approval/gateway.d.ts +27 -28
  547. package/dist/tools/approval/gateway.js +33 -130
  548. package/dist/tools/approval/queries.d.ts +6 -11
  549. package/dist/tools/approval/queries.js +43 -29
  550. package/dist/tools/approval/uuidv7.js +2 -2
  551. package/dist/tools/bio/chembl.d.ts +3 -3
  552. package/dist/tools/bio/chembl.js +10 -0
  553. package/dist/tools/bio/comptox.d.ts +25 -8
  554. package/dist/tools/bio/comptox.js +4 -2
  555. package/dist/tools/bio/drug-gene-interactions.d.ts +27 -17
  556. package/dist/tools/bio/drug-gene-interactions.js +11 -8
  557. package/dist/tools/bio/gene-disease-evidence.d.ts +61 -15
  558. package/dist/tools/bio/gene-disease-evidence.js +10 -6
  559. package/dist/tools/bio/gene-preclinical-profile.d.ts +11 -11
  560. package/dist/tools/bio/keys.d.ts +2 -2
  561. package/dist/tools/bio/keys.js +3 -3
  562. package/dist/tools/bio/lookup-annotation.d.ts +5 -5
  563. package/dist/tools/bio/lookup-annotation.js +3 -0
  564. package/dist/tools/bio/opentargets.d.ts +1 -1
  565. package/dist/tools/bio/opentargets.js +6 -0
  566. package/dist/tools/bio/pubchem.d.ts +2 -2
  567. package/dist/tools/bio/pubchem.js +6 -0
  568. package/dist/tools/bio/pubmed.d.ts +26 -16
  569. package/dist/tools/bio/pubmed.js +9 -3
  570. package/dist/tools/bio/search-clinical-trials.d.ts +4 -4
  571. package/dist/tools/bio/search-clinical-trials.js +5 -1
  572. package/dist/tools/bio/search-faers.d.ts +2 -2
  573. package/dist/tools/bio/search-faers.js +1 -1
  574. package/dist/tools/bio/search-gene.d.ts +2 -2
  575. package/dist/tools/bio/search-gene.js +1 -0
  576. package/dist/tools/bio/search-geo-datasets.d.ts +4 -4
  577. package/dist/tools/bio/search-geo-datasets.js +5 -5
  578. package/dist/tools/bio/search-interactions.d.ts +1 -1
  579. package/dist/tools/bio/search-patents.d.ts +28 -22
  580. package/dist/tools/bio/search-patents.js +20 -17
  581. package/dist/tools/bio/search-protein.d.ts +2 -2
  582. package/dist/tools/bio/search-protein.js +1 -1
  583. package/dist/tools/bio/search-regulatory-approvals.d.ts +64 -18
  584. package/dist/tools/bio/search-regulatory-approvals.js +21 -16
  585. package/dist/tools/bio/target-safety.d.ts +8 -8
  586. package/dist/tools/bio/target-safety.js +11 -6
  587. package/dist/tools/capability-data.d.ts +9 -5
  588. package/dist/tools/capability-data.js +2 -1
  589. package/dist/tools/define-tool.d.ts +55 -46
  590. package/dist/tools/define-tool.js +39 -27
  591. package/dist/tools/display/normalize-echart-spec.d.ts +2 -2
  592. package/dist/tools/display/normalize-echart-spec.js +51 -27
  593. package/dist/tools/display/show-user.d.ts +2 -2
  594. package/dist/tools/display/show-user.js +1 -1
  595. package/dist/tools/execute-analysis.d.ts +19 -10
  596. package/dist/tools/execute-analysis.js +83 -62
  597. package/dist/tools/knowledge/check.d.ts +166 -44
  598. package/dist/tools/knowledge/check.js +5 -3
  599. package/dist/tools/knowledge/client.d.ts +31 -62
  600. package/dist/tools/knowledge/client.js +44 -27
  601. package/dist/tools/knowledge/environment.d.ts +6 -6
  602. package/dist/tools/knowledge/environment.js +18 -7
  603. package/dist/tools/knowledge/index.d.ts +2 -2
  604. package/dist/tools/knowledge/index.js +9 -9
  605. package/dist/tools/knowledge/local-slots.d.ts +4 -4
  606. package/dist/tools/knowledge/local-slots.js +11 -4
  607. package/dist/tools/knowledge/pin.d.ts +2 -2
  608. package/dist/tools/knowledge/recommend.d.ts +20 -45
  609. package/dist/tools/knowledge/recommend.js +27 -19
  610. package/dist/tools/knowledge/situation.d.ts +40 -40
  611. package/dist/tools/knowledge/situation.js +2 -9
  612. package/dist/tools/knowledge/skeleton.d.ts +4 -4
  613. package/dist/tools/knowledge/skeleton.js +10 -11
  614. package/dist/tools/knowledge/template.d.ts +20 -18
  615. package/dist/tools/knowledge/template.js +38 -32
  616. package/dist/tools/lib/alphafold-client.js +2 -1
  617. package/dist/tools/lib/amass-client.d.ts +28 -28
  618. package/dist/tools/lib/amass-client.js +20 -10
  619. package/dist/tools/lib/api-utils.d.ts +13 -3
  620. package/dist/tools/lib/api-utils.js +17 -3
  621. package/dist/tools/lib/bgee-client.d.ts +6 -6
  622. package/dist/tools/lib/bgee-client.js +16 -10
  623. package/dist/tools/lib/cbioportal-client.d.ts +4 -4
  624. package/dist/tools/lib/cbioportal-client.js +9 -8
  625. package/dist/tools/lib/chembl-client.d.ts +14 -14
  626. package/dist/tools/lib/chembl-client.js +11 -4
  627. package/dist/tools/lib/clinical-benchmarks-client.d.ts +4 -4
  628. package/dist/tools/lib/clinical-benchmarks-client.js +4 -7
  629. package/dist/tools/lib/clinical-trials-client.d.ts +18 -18
  630. package/dist/tools/lib/clinical-trials-client.js +10 -10
  631. package/dist/tools/lib/clinvar-client.d.ts +2 -2
  632. package/dist/tools/lib/clinvar-client.js +6 -6
  633. package/dist/tools/lib/ctx-ops.d.ts +23 -23
  634. package/dist/tools/lib/ctx-ops.js +13 -10
  635. package/dist/tools/lib/dgidb-client.d.ts +6 -6
  636. package/dist/tools/lib/dgidb-client.js +10 -12
  637. package/dist/tools/lib/disgenet-client.d.ts +4 -4
  638. package/dist/tools/lib/ema-client.d.ts +2 -2
  639. package/dist/tools/lib/ensembl-client.d.ts +4 -4
  640. package/dist/tools/lib/ensembl-client.js +5 -4
  641. package/dist/tools/lib/gwas-catalog-client.d.ts +4 -4
  642. package/dist/tools/lib/gwas-catalog-client.js +17 -17
  643. package/dist/tools/lib/html-text.d.ts +6 -0
  644. package/dist/tools/lib/html-text.js +9 -0
  645. package/dist/tools/lib/identifier-resolver.d.ts +4 -4
  646. package/dist/tools/lib/identifier-resolver.js +7 -3
  647. package/dist/tools/lib/impc-client.d.ts +8 -8
  648. package/dist/tools/lib/impc-client.js +46 -35
  649. package/dist/tools/lib/iuphar-client.d.ts +2 -2
  650. package/dist/tools/lib/iuphar-client.js +7 -16
  651. package/dist/tools/lib/monarch-client.d.ts +4 -4
  652. package/dist/tools/lib/openfda-client.d.ts +22 -22
  653. package/dist/tools/lib/openfda-client.js +23 -22
  654. package/dist/tools/lib/opentargets-client.d.ts +12 -12
  655. package/dist/tools/lib/pathway-client.d.ts +4 -4
  656. package/dist/tools/lib/pathway-client.js +15 -19
  657. package/dist/tools/lib/pharmgkb-client.d.ts +2 -2
  658. package/dist/tools/lib/pharmgkb-client.js +1 -1
  659. package/dist/tools/lib/protein-family-modality.d.ts +2 -2
  660. package/dist/tools/lib/protein-family-modality.js +0 -2
  661. package/dist/tools/lib/protein-family-normalize.js +7 -0
  662. package/dist/tools/lib/pubchem-client.d.ts +2 -2
  663. package/dist/tools/lib/pubchem-client.js +1 -0
  664. package/dist/tools/lib/pubchem-ops.d.ts +4 -4
  665. package/dist/tools/lib/pubchem-ops.js +8 -0
  666. package/dist/tools/lib/pubmed-client.d.ts +9 -9
  667. package/dist/tools/lib/pubmed-client.js +1 -1
  668. package/dist/tools/lib/string-client.d.ts +6 -6
  669. package/dist/tools/lib/uniprot-client.d.ts +8 -8
  670. package/dist/tools/lib/uniprot-client.js +5 -1
  671. package/dist/tools/memory/update-working-memory.d.ts +16 -13
  672. package/dist/tools/memory/update-working-memory.js +21 -3
  673. package/dist/tools/read-tool-output.js +8 -2
  674. package/dist/tools/registry.d.ts +2 -2
  675. package/dist/tools/report-authoring/authoring-tools.d.ts +54 -23
  676. package/dist/tools/report-authoring/authoring-tools.js +128 -62
  677. package/dist/tools/report-session/derive-table.d.ts +19 -59
  678. package/dist/tools/report-session/derive-table.js +120 -122
  679. package/dist/tools/report-session/examine-page.d.ts +6 -6
  680. package/dist/tools/report-session/examine-page.js +14 -12
  681. package/dist/tools/report-session/list-artifacts.d.ts +6 -6
  682. package/dist/tools/report-session/list-artifacts.js +5 -5
  683. package/dist/tools/report-session/page-faults.d.ts +6 -6
  684. package/dist/tools/report-session/page-faults.js +3 -1
  685. package/dist/tools/report-session/preview-report.d.ts +4 -3
  686. package/dist/tools/report-session/preview-report.js +26 -7
  687. package/dist/tools/report-session/record-version.d.ts +9 -4
  688. package/dist/tools/report-session/record-version.js +16 -9
  689. package/dist/tools/report-session/session-page-publisher.d.ts +6 -6
  690. package/dist/tools/research/generate-analogy-report.d.ts +14 -7
  691. package/dist/tools/research/generate-analogy-report.js +80 -76
  692. package/dist/tools/research/generate-plan.d.ts +16 -16
  693. package/dist/tools/research/generate-plan.js +410 -374
  694. package/dist/tools/research/guarded-address.js +3 -2
  695. package/dist/tools/research/inspect-data-profile.d.ts +27 -20
  696. package/dist/tools/research/inspect-data-profile.js +26 -25
  697. package/dist/tools/research/inspect-run.d.ts +54 -27
  698. package/dist/tools/research/inspect-run.js +50 -40
  699. package/dist/tools/research/literature-reviewer.d.ts +8 -7
  700. package/dist/tools/research/literature-reviewer.js +29 -28
  701. package/dist/tools/research/search-arxiv.d.ts +1 -1
  702. package/dist/tools/research/search-arxiv.js +1 -1
  703. package/dist/tools/research/search-github-repos.d.ts +10 -7
  704. package/dist/tools/research/search-github-repos.js +25 -22
  705. package/dist/tools/research/search-semantic-scholar.js +1 -1
  706. package/dist/tools/research/searxng-engine.d.ts +2 -2
  707. package/dist/tools/research/searxng-engine.js +6 -4
  708. package/dist/tools/research/web-fetch.d.ts +24 -21
  709. package/dist/tools/research/web-fetch.js +65 -74
  710. package/dist/tools/research/web-search.d.ts +26 -17
  711. package/dist/tools/research/web-search.js +26 -21
  712. package/dist/tools/sandbox/link-packages.d.ts +11 -7
  713. package/dist/tools/sandbox/link-packages.js +11 -8
  714. package/dist/tools/sandbox/list-available-packages.d.ts +17 -8
  715. package/dist/tools/sandbox/list-available-packages.js +31 -25
  716. package/dist/tools/sandbox/list-available-refs.d.ts +17 -14
  717. package/dist/tools/sandbox/list-available-refs.js +61 -36
  718. package/dist/tools/sandbox/report-blocker.d.ts +30 -37
  719. package/dist/tools/sandbox/report-blocker.js +23 -73
  720. package/dist/tools/sandbox/skills.d.ts +16 -12
  721. package/dist/tools/sandbox/skills.js +16 -12
  722. package/dist/tools/sandbox/submit-file-metadata.d.ts +12 -9
  723. package/dist/tools/sandbox/submit-file-metadata.js +18 -21
  724. package/dist/tools/start-report-session.d.ts +13 -5
  725. package/dist/tools/start-report-session.js +35 -8
  726. package/dist/tools/terminal-text.d.ts +5 -2
  727. package/dist/tools/terminal-text.js +35 -3
  728. package/dist/tools/workspace/decision-record.d.ts +4 -4
  729. package/dist/tools/workspace/decision-record.js +23 -13
  730. package/dist/tools/workspace/edit-file.d.ts +59 -20
  731. package/dist/tools/workspace/edit-file.js +81 -16
  732. package/dist/tools/workspace/execute-command.d.ts +15 -13
  733. package/dist/tools/workspace/execute-command.js +11 -9
  734. package/dist/tools/workspace/file-stat.d.ts +6 -3
  735. package/dist/tools/workspace/grep.d.ts +10 -7
  736. package/dist/tools/workspace/grep.js +9 -3
  737. package/dist/tools/workspace/list-files.d.ts +6 -3
  738. package/dist/tools/workspace/mutator.d.ts +28 -15
  739. package/dist/tools/workspace/mutator.js +107 -53
  740. package/dist/tools/workspace/read-file.d.ts +8 -5
  741. package/dist/tools/workspace/result-bounds.d.ts +5 -5
  742. package/dist/tools/workspace/result-bounds.js +4 -2
  743. package/dist/tools/workspace/run-exec.d.ts +2 -2
  744. package/dist/tools/workspace/run-exec.js +3 -3
  745. package/dist/tools/workspace/scan-inputs.d.ts +8 -5
  746. package/dist/tools/workspace/scan-inputs.js +17 -5
  747. package/dist/tools/workspace/show-file.d.ts +1 -1
  748. package/dist/tools/workspace/show-file.js +2 -1
  749. package/dist/tools/workspace/show-plan.d.ts +8 -5
  750. package/dist/tools/workspace/show-plan.js +9 -8
  751. package/dist/tools/workspace/workspace-search.d.ts +41 -13
  752. package/dist/tools/workspace/workspace-search.js +27 -14
  753. package/dist/tools/workspace/write-file.d.ts +9 -7
  754. package/dist/workflows/execute-analysis-scheduler.d.ts +9 -9
  755. package/dist/workflows/execute-analysis-scheduler.js +6 -3
  756. package/dist/workflows/execute-analysis.d.ts +46 -62
  757. package/dist/workflows/execute-analysis.js +137 -219
  758. package/dist/workflows/pause.d.ts +71 -0
  759. package/dist/workflows/pause.js +173 -0
  760. package/dist/workflows/sandbox-step.d.ts +38 -61
  761. package/dist/workflows/sandbox-step.js +99 -106
  762. package/dist/workflows/test/sql-writes.d.ts +21 -0
  763. package/dist/workflows/test/sql-writes.js +36 -0
  764. package/dist/workspace/filesystem.d.ts +6 -6
  765. package/dist/workspace/filesystem.js +10 -8
  766. package/dist/workspace/paths.d.ts +1 -1
  767. package/dist/workspace/paths.js +15 -4
  768. package/dist/workspace/search-config.d.ts +2 -2
  769. package/dist/workspace/search-config.js +1 -1
  770. package/package.json +21 -22
  771. package/dist/loop/call-guard.d.ts +0 -50
  772. package/dist/loop/call-guard.js +0 -90
  773. package/dist/loop/continue-agent.d.ts +0 -40
  774. package/dist/loop/continue-agent.js +0 -38
  775. package/dist/loop/genai-spans.d.ts +0 -47
  776. package/dist/loop/genai-spans.js +0 -134
  777. package/dist/loop/run-agent.d.ts +0 -245
  778. package/dist/loop/run-agent.js +0 -1124
  779. package/dist/loop/run-step.d.ts +0 -29
  780. package/dist/loop/run-step.js +0 -34
  781. package/dist/loop/run-to-terminal.d.ts +0 -66
  782. package/dist/loop/run-to-terminal.js +0 -93
  783. package/dist/loop/tool-mask.d.ts +0 -23
  784. package/dist/loop/tool-mask.js +0 -46
  785. package/dist/providers/streaming-chat.d.ts +0 -32
  786. package/dist/providers/streaming-chat.js +0 -91
  787. package/dist/tasks/derive-table-exec.d.ts +0 -54
  788. package/dist/tasks/derive-table-exec.js +0 -86
  789. package/dist/workflows/suspension.d.ts +0 -32
  790. package/dist/workflows/suspension.js +0 -38
@@ -25,9 +25,12 @@
25
25
  * other value axis keeps the tick values that ECharts computes. A custom series names its renderer as a
26
26
  * string, and each consumer of the option binds the name (`chart-renderers.ts`).
27
27
  */
28
+ import { textOf } from "../lib/unknown-text.js";
28
29
  import { err, ok } from "neverthrow";
29
30
  import { channelColumn, channelOrder, channelTransform, } from "../contracts/report-blocks.js";
30
31
  import { declaredForColumn } from "../contracts/report-reference.js";
32
+ import { isUnknownArray } from "../lib/unknown-array.js";
33
+ import { parseUnknownRecord } from "../lib/unknown-containers.js";
31
34
  import { normalizeEchartSpec } from "../tools/display/normalize-echart-spec.js";
32
35
  import { categoryInterval, INTERVAL_RENDERER, LABEL_LINE_SHARE, OUTLINE_RENDERER, VIOLIN_GRID_POINTS } from "./chart-renderers.js";
33
36
  import { BAR_VALUE_LABEL_LIMIT, CHART_BODY_PX, CHART_FONT_STACK, CHART_INK, CHART_INLINE_OPTION_BOUND, CHART_PAGE_TEXT_PX, CHART_PAGE_WIDTH_PX, CHART_SLOT_LIMIT, COLOR_SCALE_BAND_PCT, FACET_COLUMNS, FACET_PANEL_LIMIT, FACET_ROW_PX, FOCUS_CHART_COLOR, MUTED_CHART_COLOR, SCATTER_CROWD_OPACITY, SCATTER_CROWD_ROWS, SCATTER_CROWD_SYMBOL_SIZE, SCATTER_HOVER_ROWS, SCATTER_HOVER_SYMBOL_SIZE, SIZE_CHANNEL_RANGE_PX, } from "./design.js";
@@ -35,7 +38,7 @@ import { applyFigureRules, axisNameFields, categoryAxisTitle, categoryName, char
35
38
  import { FIGURE_MEMBER_READERS, FIGURE_MODULES, isModuleOnlyType, } from "./figures/index.js";
36
39
  import { SHAPED_SCATTER_FIGURE } from "./figures/pca.js";
37
40
  import { formatNumberCell, selectNumberKind } from "./number-format.js";
38
- export { transformColumn };
41
+ export { transformColumn } from "./figures/common.js";
39
42
  /**
40
43
  * The category values that carry no finding.
41
44
  *
@@ -174,7 +177,7 @@ function bodyPxOf(raw, option) {
174
177
  const grids = option.grid;
175
178
  if (!Array.isArray(grids))
176
179
  return CHART_BODY_PX;
177
- const panels = grids.filter((grid) => typeof grid === "object" && grid !== null && grid.outerBoundsMode === FACET_BOUNDS_MODE).length;
180
+ const panels = grids.filter((grid) => parseUnknownRecord(grid)?.outerBoundsMode === FACET_BOUNDS_MODE).length;
178
181
  const rows = panels <= 2 ? 1 : Math.ceil(panels / FACET_COLUMNS);
179
182
  return CHART_BODY_PX + (rows - 1) * FACET_ROW_PX;
180
183
  }
@@ -193,7 +196,7 @@ function blockWidthOf(option, bodyPx) {
193
196
  return undefined;
194
197
  let width;
195
198
  for (const rule of media) {
196
- const query = typeof rule === "object" && rule !== null ? rule.query : undefined;
199
+ const query = parseUnknownRecord(parseUnknownRecord(rule)?.query);
197
200
  if (query === undefined || query.maxWidth !== undefined || typeof query.minWidth !== "number" || typeof query.minHeight !== "number")
198
201
  continue;
199
202
  if (query.minHeight <= bodyPx)
@@ -247,7 +250,7 @@ function chartRender(pass) {
247
250
  readsPayload: pass.readsPayload,
248
251
  inline: pass.inline,
249
252
  bodyPx: pass.bodyPx,
250
- ...(widthPx !== undefined ? { widthPx } : {}),
253
+ widthPx,
251
254
  };
252
255
  }
253
256
  /**
@@ -288,7 +291,7 @@ function describesLead(series, collector) {
288
291
  return (composed !== undefined &&
289
292
  composed.length === described &&
290
293
  described < series.length &&
291
- composed.every((name, index) => series[index].name === name));
294
+ composed.every((name, index) => parseUnknownRecord(series[index])?.name === name));
292
295
  }
293
296
  /**
294
297
  * The quick path of one block that draws one point for one row, or `undefined` for every other block.
@@ -319,12 +322,12 @@ function perRowQuickPath(block, opts) {
319
322
  function sourcedOption(option, series, collector, key) {
320
323
  const source = {
321
324
  payload: key,
322
- ...(collector.rule !== undefined ? { rule: collector.rule } : {}),
325
+ rule: collector.rule,
323
326
  series: collector.series,
324
327
  };
325
328
  return {
326
329
  ...option,
327
- series: series.map((entry, index) => (index < collector.series.length ? { ...entry, data: [] } : entry)),
330
+ series: series.map((entry, index) => (index < collector.series.length ? { ...parseUnknownRecord(entry), data: [] } : entry)),
328
331
  [CHART_SOURCE_MEMBER]: source,
329
332
  };
330
333
  }
@@ -409,8 +412,8 @@ function deriveRaw(block, rows, columns, collector, inputs, opts) {
409
412
  return deriveBase({
410
413
  ...quick.value.block,
411
414
  meanings,
412
- ...(block.focus !== undefined ? { focus: block.focus } : {}),
413
- ...(stackedFacet !== undefined ? { facet: channelColumn(stackedFacet) } : {}),
415
+ focus: block.focus,
416
+ facet: stackedFacet === undefined ? undefined : channelColumn(stackedFacet),
414
417
  }, quick.value.rows, columns);
415
418
  }
416
419
  /** The members that the canonical figures add. A chart type with no figure module reads none of them. */
@@ -435,10 +438,32 @@ function declaresMember(block, member) {
435
438
  }
436
439
  }
437
440
  /** Each member that one block declares, in the order of the grammar. */
441
+ const ENCODING_KEYS = [
442
+ "x",
443
+ "y",
444
+ "group",
445
+ "value",
446
+ "label",
447
+ "color",
448
+ "size",
449
+ "low",
450
+ "high",
451
+ "facet",
452
+ "shape",
453
+ "p",
454
+ "censor",
455
+ "risk",
456
+ "hit",
457
+ "metric",
458
+ "tracks",
459
+ ];
460
+ function isEncodingKey(key) {
461
+ return ENCODING_KEYS.some((member) => member === key);
462
+ }
438
463
  function declaredMembers(block) {
439
464
  const members = [];
440
465
  for (const key of Object.keys(block.encoding ?? {})) {
441
- if (block.encoding?.[key] !== undefined)
466
+ if (isEncodingKey(key) && block.encoding?.[key] !== undefined)
442
467
  members.push(key);
443
468
  }
444
469
  for (const member of ["statistics", "track", "trees", "focus"]) {
@@ -450,7 +475,7 @@ function declaredMembers(block) {
450
475
  /** The sentence that names the chart types that read one member that the canonical figures add. */
451
476
  function readersSentence(member) {
452
477
  const readers = FIGURE_MEMBER_READERS[member];
453
- const list = readers.length <= 2 ? readers.join(" and ") : `${readers.slice(0, -1).join(", ")}, and ${readers[readers.length - 1]}`;
478
+ const list = readers.length <= 2 ? readers.join(" and ") : `${readers.slice(0, -1).join(", ")}, and ${String(readers[readers.length - 1])}`;
454
479
  switch (member) {
455
480
  case "statistics":
456
481
  return `The statistics are legal on the ${list} charts.`;
@@ -516,10 +541,10 @@ function deriveFigure(block, chartType, figure, rows, columns, collector, inputs
516
541
  blockId: block.id,
517
542
  labels,
518
543
  meanings,
519
- ...(columns !== undefined ? { columns } : {}),
544
+ columns,
520
545
  statistics: statistics.value,
521
- ...(track.value !== undefined ? { track: track.value } : {}),
522
- ...(trees.value !== undefined ? { trees: trees.value } : {}),
546
+ track: track.value,
547
+ trees: trees.value,
523
548
  textPx: CHART_PAGE_TEXT_PX,
524
549
  compose: (composition, { keepsRowsInline, ...extras } = {}) => {
525
550
  // A composition with no collector describes no page build, thus the chart keeps its rows inline.
@@ -528,7 +553,7 @@ function deriveFigure(block, chartType, figure, rows, columns, collector, inputs
528
553
  if (described !== undefined && option.isOk()) {
529
554
  // The names of the composition output let the pass tell it apart from a series that the
530
555
  // figure adds after it.
531
- described.composed = Array.isArray(option.value.series) ? option.value.series.map((entry) => String(entry.name)) : [];
556
+ described.composed = Array.isArray(option.value.series) ? option.value.series.map((entry) => textOf(parseUnknownRecord(entry)?.name)) : [];
532
557
  }
533
558
  return option;
534
559
  },
@@ -552,10 +577,18 @@ function figureStatistics(block, values) {
552
577
  if (values === undefined || values.length !== declared.length) {
553
578
  return err(missingPart(block.id, `The chart declares ${declared.length} statistics, and its value entry carries ${values?.length ?? 0}.`));
554
579
  }
555
- return ok(declared.map((statistic, index) => ({
580
+ const pairs = [];
581
+ for (const [index, statistic] of declared.entries()) {
582
+ const resolved = values[index];
583
+ if (resolved === undefined) {
584
+ return err(missingPart(block.id, `The chart declares ${declared.length} statistics, and its value entry carries ${values.length}.`));
585
+ }
586
+ pairs.push([statistic, resolved]);
587
+ }
588
+ return ok(pairs.map(([statistic, resolved]) => ({
556
589
  label: statistic.label,
557
- value: values[index].value,
558
- text: statisticText(values[index].value, statistic.value.locator.column, statistic.value.unit),
590
+ value: resolved.value,
591
+ text: statisticText(resolved.value, statistic.value.locator.column, statistic.value.unit),
559
592
  })));
560
593
  }
561
594
  /** The resolved track of one block, or `undefined` for a block that declares none. An entry with no track refuses. */
@@ -568,11 +601,11 @@ function figureTrack(block, value) {
568
601
  }
569
602
  return ok({
570
603
  rows: value.rows,
571
- ...(value.columns !== undefined ? { columns: value.columns } : {}),
604
+ columns: value.columns,
572
605
  start: declared.start,
573
606
  end: declared.end,
574
607
  label: declared.label,
575
- ...(declared.length !== undefined ? { length: declared.length } : {}),
608
+ length: declared.length,
576
609
  labels: declared.binding.columnLabels,
577
610
  meanings: declared.binding.columnMeanings,
578
611
  });
@@ -596,7 +629,7 @@ function figureTrees(block, values) {
596
629
  }
597
630
  trees[axis] = {
598
631
  rows: value.rows,
599
- ...(value.columns !== undefined ? { columns: value.columns } : {}),
632
+ columns: value.columns,
600
633
  parent: tree.parent,
601
634
  child: tree.child,
602
635
  height: tree.height,
@@ -741,19 +774,19 @@ function deriveAsComposition(blockId, chartType, encoding, rows, columns, labels
741
774
  encoding: {
742
775
  x: x.value,
743
776
  y: y.value,
744
- ...(encoding.group !== undefined ? { group: encoding.group } : {}),
745
- ...(encoding.label !== undefined ? { label: encoding.label } : {}),
746
- ...(encoding.color !== undefined ? { color: encoding.color } : {}),
747
- ...(encoding.size !== undefined ? { size: encoding.size } : {}),
748
- ...(encoding.low !== undefined ? { low: encoding.low } : {}),
749
- ...(encoding.high !== undefined ? { high: encoding.high } : {}),
777
+ group: encoding.group,
778
+ label: encoding.label,
779
+ color: encoding.color,
780
+ size: encoding.size,
781
+ low: encoding.low,
782
+ high: encoding.high,
750
783
  },
751
784
  // The caller refused an orientation on every type but the bar, thus the form here is a bar
752
785
  // wherever one arrives. The arrangement crosses onto the series, and no name channel loses it.
753
- ...(orientation !== undefined ? { orientation } : {}),
786
+ orientation,
754
787
  },
755
788
  ],
756
- ...(encoding.facet !== undefined ? { facet: encoding.facet } : {}),
789
+ facet: encoding.facet,
757
790
  };
758
791
  return deriveComposition(blockId, composition, rows, columns, labels, extras);
759
792
  }
@@ -820,18 +853,18 @@ const CHANNELS = ["x", "y", "group", "value"];
820
853
  * without a value drops, thus no substitute value ever appears.
821
854
  */
822
855
  function deriveTransformedRows(rows, derived) {
823
- const values = derived.map((entry) => transformColumn(rows, entry.column, entry.transform));
856
+ const columns = derived.map((entry) => ({ name: entry.name, values: transformColumn(rows, entry.column, entry.transform) }));
824
857
  const out = [];
825
- for (let index = 0; index < rows.length; index += 1) {
826
- const next = { ...rows[index] };
858
+ for (const [index, row] of rows.entries()) {
859
+ const next = { ...row };
827
860
  let complete = true;
828
- for (let slot = 0; slot < derived.length; slot += 1) {
829
- const value = values[slot][index];
861
+ for (const column of columns) {
862
+ const value = column.values[index] ?? null;
830
863
  if (value === null) {
831
864
  complete = false;
832
865
  break;
833
866
  }
834
- next[derived[slot].name] = value;
867
+ next[column.name] = value;
835
868
  }
836
869
  if (complete)
837
870
  out.push(next);
@@ -875,19 +908,23 @@ function deriveBar(block, rows, columns, mode) {
875
908
  if (focused.isErr())
876
909
  return err(focused.error);
877
910
  const focus = focused.value;
878
- const bars = groupedSeries(rows, group, (groupRows, name) => ({
879
- type: "bar",
880
- ...(name !== undefined ? { name: categoryName(name) } : {}),
881
- ...categoryStyle(name, focus),
882
- barGap: 0,
883
- barCategoryGap: BAR_CATEGORY_GAP,
884
- data: groupRows.map((row) => {
885
- const pair = horizontal ? [row[y], categoryCell(row[x])] : [categoryCell(row[x]), row[y]];
886
- // A bar with no group reads the focus over its own categories, thus each item carries its color.
887
- const color = group === undefined ? focusColor(focus, row[x]) : undefined;
888
- return color === undefined ? pair : { value: pair, itemStyle: { color } };
889
- }),
890
- }));
911
+ const bars = groupedSeries(rows, group, (groupRows, name) => {
912
+ const bar = {
913
+ type: "bar",
914
+ ...categoryStyle(name, focus),
915
+ barGap: 0,
916
+ barCategoryGap: BAR_CATEGORY_GAP,
917
+ data: groupRows.map((row) => {
918
+ const pair = horizontal ? [row[y], categoryCell(row[x])] : [categoryCell(row[x]), row[y]];
919
+ // A bar with no group reads the focus over its own categories, thus each item carries its color.
920
+ const color = group === undefined ? focusColor(focus, row[x]) : undefined;
921
+ return color === undefined ? pair : { value: pair, itemStyle: { color } };
922
+ }),
923
+ };
924
+ if (name !== undefined)
925
+ bar.name = categoryName(name);
926
+ return bar;
927
+ });
891
928
  series = withValueLabels(bars, horizontal, (cell) => valueLabelText(y, cell, block.meanings));
892
929
  }
893
930
  else {
@@ -899,7 +936,12 @@ function deriveBar(block, rows, columns, mode) {
899
936
  return err(stacked.error);
900
937
  series = stacked.value;
901
938
  }
902
- const valueAxis = { type: "value", ...(mode === "normalized" ? { min: 0, max: 1 } : {}), ...labelRoom(series, horizontal) };
939
+ const valueAxis = { type: "value" };
940
+ if (mode === "normalized") {
941
+ valueAxis.min = 0;
942
+ valueAxis.max = 1;
943
+ }
944
+ Object.assign(valueAxis, labelRoom(series, horizontal));
903
945
  if (horizontal) {
904
946
  return ok({
905
947
  xAxis: { ...valueAxis, ...xAxisName(axisTitle(block.labels, y)) },
@@ -1009,7 +1051,7 @@ function deriveStackedFacets(block, rows, columns, x, y, categories, normalized,
1009
1051
  let negative = 0;
1010
1052
  for (const entry of panel.value) {
1011
1053
  // `stackedSeries` gives each series one part or null for each category, in category order.
1012
- const part = toNumber(entry.data[index]);
1054
+ const part = toNumber(isUnknownArray(entry.data) ? entry.data[index] : undefined);
1013
1055
  if (part === null)
1014
1056
  continue;
1015
1057
  if (part > 0)
@@ -1076,13 +1118,23 @@ function derivePointForm(block, rows, columns, form) {
1076
1118
  const xText = xAxis.value.type === "category";
1077
1119
  const yText = yAxis.value.type === "category";
1078
1120
  const pairOf = (row) => [xText ? categoryCell(row[x]) : row[x], yText ? categoryCell(row[y]) : row[y]];
1079
- const series = groupedSeries(rows, group, (groupRows, name) => ({
1080
- type: form,
1081
- ...(name !== undefined ? { name: categoryName(name) } : {}),
1082
- ...categoryStyle(name, focused.value),
1083
- ...(form === "line" ? { showSymbol: false } : { large: true, largeThreshold: 2000 }),
1084
- data: form === "line" ? sortByX(groupRows.map(pairOf), places) : groupRows.map(pairOf),
1085
- }));
1121
+ const series = groupedSeries(rows, group, (groupRows, name) => {
1122
+ const entry = {
1123
+ type: form,
1124
+ ...categoryStyle(name, focused.value),
1125
+ data: form === "line" ? sortByX(groupRows.map(pairOf), places) : groupRows.map(pairOf),
1126
+ };
1127
+ if (name !== undefined)
1128
+ entry.name = categoryName(name);
1129
+ if (form === "line") {
1130
+ entry.showSymbol = false;
1131
+ }
1132
+ else {
1133
+ entry.large = true;
1134
+ entry.largeThreshold = 2000;
1135
+ }
1136
+ return entry;
1137
+ });
1086
1138
  return ok({ xAxis: xAxis.value, yAxis: yAxis.value, series });
1087
1139
  }
1088
1140
  /**
@@ -1158,22 +1210,21 @@ function deriveBox(block, rows, columns) {
1158
1210
  return err(focused.error);
1159
1211
  const series = [];
1160
1212
  const buckets = slotBuckets(rows, x, y, groupColumn);
1161
- const valuesOf = groups.map((group) => categories.map((category) => buckets.get(slotKey(group.name, category)) ?? []));
1162
- const pointed = drawsDistributionPoints(valuesOf.flat());
1213
+ const lanes = groups.map((group) => ({ name: group.name, values: categories.map((category) => buckets.get(slotKey(group.name, category)) ?? []) }));
1214
+ const pointed = drawsDistributionPoints(lanes.flatMap((lane) => lane.values));
1163
1215
  // The axis jitter centers each point on its category and not on its slot, thus a grouped box places its
1164
1216
  // points on the slot axis.
1165
1217
  const grouped = groups.length > 1;
1166
1218
  const points = [];
1167
1219
  const slotted = [];
1168
- for (const [place, group] of groups.entries()) {
1169
- const color = focusColor(focused.value, group.name);
1220
+ for (const [place, lane] of lanes.entries()) {
1221
+ const color = focusColor(focused.value, lane.name);
1170
1222
  const slot = boxSlot(place, groups.length);
1171
1223
  const boxData = [];
1172
1224
  const outliers = [];
1173
1225
  const slotPointList = [];
1174
1226
  const medians = [];
1175
- for (let index = 0; index < categories.length; index++) {
1176
- const values = valuesOf[place][index];
1227
+ for (const [index, values] of lane.values.entries()) {
1177
1228
  if (pointed && grouped)
1178
1229
  slotPointList.push(...slotPoints(values, index, slot));
1179
1230
  else if (pointed) {
@@ -1195,30 +1246,34 @@ function deriveBox(block, rows, columns) {
1195
1246
  outliers.push([index, outlier]);
1196
1247
  }
1197
1248
  }
1198
- series.push({
1249
+ const box = {
1199
1250
  type: "boxplot",
1200
- ...(group.name !== undefined ? { name: categoryName(group.name) } : {}),
1201
1251
  // A box draws its median in the border color, thus a focus colors the border and never the fill.
1202
- ...(color !== undefined ? { itemStyle: { borderColor: color } } : {}),
1252
+ itemStyle: { borderColor: color },
1203
1253
  data: boxData,
1204
- });
1254
+ };
1255
+ if (lane.name !== undefined)
1256
+ box.name = categoryName(lane.name);
1257
+ series.push(box);
1205
1258
  // The outlier scatter pairs with its box series, thus it only appears when an outlier exists. A box with
1206
1259
  // no group takes no palette slot by name, thus its outliers take the ink of the points.
1207
1260
  if (outliers.length > 0) {
1208
- const outlierColor = color ?? (group.name === undefined ? CHART_INK : undefined);
1209
- series.push({
1261
+ const outlierColor = color ?? (lane.name === undefined ? CHART_INK : undefined);
1262
+ const outlierMarks = {
1210
1263
  type: "scatter",
1211
- ...(group.name !== undefined ? { name: categoryName(group.name) } : {}),
1212
- ...(outlierColor !== undefined ? { itemStyle: { color: outlierColor } } : {}),
1264
+ itemStyle: { color: outlierColor },
1213
1265
  symbolSize: 4,
1214
1266
  data: outliers,
1215
- });
1267
+ };
1268
+ if (lane.name !== undefined)
1269
+ outlierMarks.name = categoryName(lane.name);
1270
+ series.push(outlierMarks);
1216
1271
  }
1217
- const onSlots = slotSeries(group.name === undefined ? undefined : categoryName(group.name), slotPointList, medians, grouped ? color : CHART_INK);
1272
+ const onSlots = slotSeries(lane.name === undefined ? undefined : categoryName(lane.name), slotPointList, medians, grouped ? color : CHART_INK);
1218
1273
  if (onSlots !== undefined)
1219
1274
  slotted.push(onSlots);
1220
1275
  }
1221
- const pointName = groups[0]?.name;
1276
+ const pointName = lanes[0]?.name;
1222
1277
  if (points.length > 0)
1223
1278
  series.push(pointSeries(points, pointName === undefined ? undefined : categoryName(pointName)));
1224
1279
  series.push(...slotted);
@@ -1226,8 +1281,9 @@ function deriveBox(block, rows, columns) {
1226
1281
  type: "category",
1227
1282
  data: categories,
1228
1283
  ...axisNameFields("x", categoryAxisTitle(block.labels, x)),
1229
- ...(points.length > 0 ? JITTERED_AXIS : {}),
1230
1284
  };
1285
+ if (points.length > 0)
1286
+ Object.assign(categoryAxis, JITTERED_AXIS);
1231
1287
  return ok({
1232
1288
  xAxis: slotted.length > 0 ? [categoryAxis, slotAxis(categories.length)] : categoryAxis,
1233
1289
  yAxis: { type: "value", ...yAxisName(axisTitle(block.labels, y)) },
@@ -1297,19 +1353,17 @@ function slotSeries(name, points, medians, color) {
1297
1353
  return undefined;
1298
1354
  return {
1299
1355
  ...pointSeries(points, name),
1300
- itemStyle: { ...(color !== undefined ? { color } : {}), opacity: DISTRIBUTION_POINT_OPACITY },
1356
+ itemStyle: { color, opacity: DISTRIBUTION_POINT_OPACITY },
1301
1357
  xAxisIndex: 1,
1302
- ...(medians.length > 0
1358
+ markLine: medians.length > 0
1303
1359
  ? {
1304
- markLine: {
1305
- silent: true,
1306
- symbol: "none",
1307
- label: { show: false },
1308
- lineStyle: { width: MEDIAN_LINE_WIDTH_PX, type: "solid", opacity: 1 },
1309
- data: medians.map((line) => [...line]),
1310
- },
1360
+ silent: true,
1361
+ symbol: "none",
1362
+ label: { show: false },
1363
+ lineStyle: { width: MEDIAN_LINE_WIDTH_PX, type: "solid", opacity: 1 },
1364
+ data: medians.map((line) => [...line]),
1311
1365
  }
1312
- : {}),
1366
+ : undefined,
1313
1367
  };
1314
1368
  }
1315
1369
  /**
@@ -1338,7 +1392,7 @@ const JITTERED_AXIS = { jitter: 24, jitterOverlap: false, jitterMargin: 0 };
1338
1392
  function pointSeries(points, name) {
1339
1393
  return {
1340
1394
  type: "scatter",
1341
- ...(name !== undefined ? { name } : {}),
1395
+ name,
1342
1396
  silent: true,
1343
1397
  symbolSize: DISTRIBUTION_POINT_SIZE,
1344
1398
  itemStyle: { color: CHART_INK, opacity: DISTRIBUTION_POINT_OPACITY },
@@ -1414,31 +1468,34 @@ function deriveViolin(block, rows, columns) {
1414
1468
  if (focused.isErr())
1415
1469
  return err(focused.error);
1416
1470
  const buckets = slotBuckets(rows, x, y, groupColumn);
1417
- const shapes = groups.map((group) => categories.flatMap((category, index) => {
1418
- const shape = violinShape(buckets.get(slotKey(group.name, category)) ?? []);
1419
- return shape === undefined ? [] : [{ ...shape, category: index }];
1471
+ const lanes = groups.map((group) => ({
1472
+ name: group.name,
1473
+ shapes: categories.flatMap((category, index) => {
1474
+ const shape = violinShape(buckets.get(slotKey(group.name, category)) ?? []);
1475
+ return shape === undefined ? [] : [{ ...shape, category: index }];
1476
+ }),
1477
+ values: categories.map((category) => buckets.get(slotKey(group.name, category)) ?? []),
1420
1478
  }));
1421
1479
  let largest = 0;
1422
- for (const shape of shapes.flat()) {
1480
+ for (const shape of lanes.flatMap((lane) => lane.shapes)) {
1423
1481
  for (const density of shape.densities)
1424
1482
  largest = Math.max(largest, density);
1425
1483
  }
1426
- const valuesOf = groups.map((group) => categories.map((category) => buckets.get(slotKey(group.name, category)) ?? []));
1427
- const pointed = drawsDistributionPoints(valuesOf.flat());
1484
+ const pointed = drawsDistributionPoints(lanes.flatMap((lane) => lane.values));
1428
1485
  // The axis jitter centers each point on its category and not on its slot, thus a grouped violin places its
1429
1486
  // points on the slot axis.
1430
1487
  const grouped = groups.length > 1;
1431
1488
  const slotted = [];
1432
1489
  const series = [];
1433
1490
  const legend = [];
1434
- for (const [place, group] of groups.entries()) {
1435
- const name = group.name !== undefined ? categoryName(group.name) : axisTitle(block.labels, y);
1491
+ for (const [place, lane] of lanes.entries()) {
1492
+ const name = lane.name !== undefined ? categoryName(lane.name) : axisTitle(block.labels, y);
1436
1493
  const offset = slotOffset(place, groups.length);
1437
1494
  const slot = violinSlot(place, groups.length);
1438
- const shaped = new Set(shapes[place].map((shape) => shape.category));
1439
- const medians = valuesOf[place].flatMap((values, index) => (shaped.has(index) || values.length === 0 ? [] : [medianLine(values, index, slot)]));
1440
- const slotPointList = pointed && grouped ? valuesOf[place].flatMap((values, index) => slotPoints(values, index, slot)) : [];
1441
- const color = focusColor(focused.value, group.name);
1495
+ const shaped = new Set(lane.shapes.map((shape) => shape.category));
1496
+ const medians = lane.values.flatMap((values, index) => (shaped.has(index) || values.length === 0 ? [] : [medianLine(values, index, slot)]));
1497
+ const slotPointList = pointed && grouped ? lane.values.flatMap((values, index) => slotPoints(values, index, slot)) : [];
1498
+ const color = focusColor(focused.value, lane.name);
1442
1499
  const onSlots = slotSeries(name, slotPointList, medians, grouped ? color : CHART_INK);
1443
1500
  if (onSlots !== undefined)
1444
1501
  slotted.push(onSlots);
@@ -1449,13 +1506,13 @@ function deriveViolin(block, rows, columns) {
1449
1506
  renderItem: OUTLINE_RENDERER,
1450
1507
  silent: true,
1451
1508
  encode: { x: 0, y: [1, 2] },
1452
- ...(color !== undefined ? { itemStyle: { color } } : nullCategoryStyle(group.name)),
1453
- data: shapes[place].map((shape) => [
1509
+ itemStyle: color !== undefined ? { color } : nullCategoryStyle(lane.name).itemStyle,
1510
+ data: lane.shapes.map((shape) => [
1454
1511
  shape.category,
1455
1512
  shape.grid[0],
1456
1513
  shape.grid[shape.grid.length - 1],
1457
1514
  offset,
1458
- ...shape.grid.flatMap((value, point) => [roundWidth(largest > 0 ? (shape.densities[point] / largest) * halfWidth : 0), value]),
1515
+ ...shape.grid.flatMap((value, point) => [roundWidth(largest > 0 ? ((shape.densities[point] ?? 0) / largest) * halfWidth : 0), value]),
1459
1516
  ]),
1460
1517
  });
1461
1518
  series.push({
@@ -1464,13 +1521,13 @@ function deriveViolin(block, rows, columns) {
1464
1521
  renderItem: INTERVAL_RENDERER,
1465
1522
  silent: true,
1466
1523
  encode: { x: 0, y: [1, 2, 3] },
1467
- data: shapes[place].map((shape) => [shape.category, shape.median, shape.q1, shape.q3, 1, offset, 1]),
1524
+ data: lane.shapes.map((shape) => [shape.category, shape.median, shape.q1, shape.q3, 1, offset, 1]),
1468
1525
  });
1469
1526
  legend.push(name);
1470
1527
  }
1471
1528
  const points = [];
1472
1529
  if (pointed && !grouped) {
1473
- for (const [index, values] of (valuesOf[0] ?? []).entries()) {
1530
+ for (const [index, values] of (lanes[0]?.values ?? []).entries()) {
1474
1531
  for (const value of values)
1475
1532
  points.push([index, value]);
1476
1533
  }
@@ -1482,8 +1539,9 @@ function deriveViolin(block, rows, columns) {
1482
1539
  type: "category",
1483
1540
  data: categories,
1484
1541
  ...axisNameFields("x", categoryAxisTitle(block.labels, x)),
1485
- ...(points.length > 0 ? JITTERED_AXIS : {}),
1486
1542
  };
1543
+ if (points.length > 0)
1544
+ Object.assign(categoryAxis, JITTERED_AXIS);
1487
1545
  return ok({
1488
1546
  xAxis: slotted.length > 0 ? [categoryAxis, slotAxis(categories.length)] : categoryAxis,
1489
1547
  yAxis: { type: "value", scale: true, ...yAxisName(axisTitle(block.labels, y)) },
@@ -1650,7 +1708,8 @@ function deriveComposition(blockId, composition, rows, columns, labels, extras =
1650
1708
  return err(series.error);
1651
1709
  resolved.push(series.value);
1652
1710
  }
1653
- if (resolved.length === 0) {
1711
+ const first = resolved[0];
1712
+ if (first === undefined) {
1654
1713
  // The schema holds a composition to one series at least. The guard states the same rule for a
1655
1714
  // value that reaches the renderer without a parse, because the axes come from the first series.
1656
1715
  return err(problem(blockId, "The composition carries no series."));
@@ -1659,7 +1718,7 @@ function deriveComposition(blockId, composition, rows, columns, labels, extras =
1659
1718
  const labeled = pointLabelRows(blockId, annotations, rows, columns, plottedRows(resolved, rows.length));
1660
1719
  if (labeled.isErr())
1661
1720
  return err(labeled.error);
1662
- const focused = focusSet(blockId, extras.focus, rows.length, compositionCategories(resolved, rows.length));
1721
+ const focused = focusSet(blockId, extras.focus, rows.length, compositionCategories(resolved));
1663
1722
  if (focused.isErr())
1664
1723
  return err(focused.error);
1665
1724
  if (collector !== undefined && classification !== undefined) {
@@ -1686,10 +1745,9 @@ function deriveComposition(blockId, composition, rows, columns, labels, extras =
1686
1745
  density: scatterDensity(rows.length),
1687
1746
  annotations,
1688
1747
  // The axes come from the first series, thus its order sorts the shared x axis of every series.
1689
- orderedX: resolved[0].x.order !== undefined,
1748
+ orderedX: first.x.order !== undefined,
1690
1749
  colorOnTop: extras.colorOnTop === true,
1691
1750
  };
1692
- const first = resolved[0];
1693
1751
  const axes = compositionAxes(context, first, composition.axes);
1694
1752
  if (axes.isErr())
1695
1753
  return err(axes.error);
@@ -1706,21 +1764,26 @@ function deriveComposition(blockId, composition, rows, columns, labels, extras =
1706
1764
  const series = labeledSeries(context, emitted.value, horizontal);
1707
1765
  const room = first.declared.form === "bar" ? labelRoom(series, horizontal) : {};
1708
1766
  const colored = emitted.value.some((entry) => entry.entry?.color !== undefined);
1709
- const grid = {
1710
- // A horizontal bar draws its category names as y labels, thus the grid must hold them.
1711
- ...(isHorizontalBar(first.declared) ? LABEL_CONTAINING_GRID : {}),
1712
- // A continuous color draws its scale at the right edge, thus the grid leaves that band free.
1713
- ...(colored ? { right: COLOR_SCALE_GRID_RIGHT } : {}),
1714
- };
1715
- return ok({
1767
+ const grid = {};
1768
+ // A continuous color draws its scale at the right edge, thus the grid leaves that band free.
1769
+ if (colored)
1770
+ grid.right = COLOR_SCALE_GRID_RIGHT;
1771
+ // A horizontal bar draws its category names as y labels, thus the grid must hold them.
1772
+ if (isHorizontalBar(first.declared))
1773
+ Object.assign(grid, LABEL_CONTAINING_GRID);
1774
+ const panel = {
1716
1775
  tooltip: named ? { ...NAMED_TOOLTIP } : { ...PLAIN_TOOLTIP },
1717
1776
  xAxis: horizontal ? { ...axes.value.xAxis, ...room } : axes.value.xAxis,
1718
1777
  yAxis: horizontal ? axes.value.yAxis : { ...axes.value.yAxis, ...room },
1719
1778
  series,
1720
- ...(maps.length > 0 ? { visualMap: maps } : {}),
1721
- ...(emitted.value.some((entry) => entry.auxiliary) ? { legend: legendOf(drawnNames(emitted.value)) } : {}),
1722
- ...(Object.keys(grid).length > 0 ? { grid } : {}),
1723
- });
1779
+ };
1780
+ if (maps.length > 0)
1781
+ panel.visualMap = maps;
1782
+ if (emitted.value.some((entry) => entry.auxiliary))
1783
+ panel.legend = legendOf(drawnNames(emitted.value));
1784
+ if (Object.keys(grid).length > 0)
1785
+ panel.grid = grid;
1786
+ return ok(panel);
1724
1787
  }
1725
1788
  /** The stack prefix of a band. A facet panel adds its own place, thus two panels never stack each other. */
1726
1789
  const BAND_STACK_PREFIX = "band-";
@@ -1804,14 +1867,13 @@ function compositionFault(composition, focus) {
1804
1867
  * The categories that a focus of one composition can name: the values of each group channel, and the `x`
1805
1868
  * values of each bar series that splits by no group.
1806
1869
  */
1807
- function compositionCategories(resolved, rowCount) {
1870
+ function compositionCategories(resolved) {
1808
1871
  const categories = [];
1809
1872
  for (const entry of resolved) {
1810
1873
  const channel = entry.group ?? (entry.declared.form === "bar" ? entry.x : undefined);
1811
1874
  if (channel === undefined)
1812
1875
  continue;
1813
- for (let index = 0; index < rowCount; index += 1) {
1814
- const value = channel.values[index];
1876
+ for (const value of channel.values) {
1815
1877
  if (value !== null)
1816
1878
  categories.push(value);
1817
1879
  }
@@ -1845,22 +1907,23 @@ function composePanel(context, resolved, members, axes, stackPrefix) {
1845
1907
  emitted.push(...built.value);
1846
1908
  }
1847
1909
  const marks = markMembers(context.annotations);
1848
- const target = markCarrier(emitted);
1849
- if (Object.keys(marks).length > 0 && target >= 0) {
1850
- emitted[target] = { ...emitted[target], option: { ...emitted[target].option, ...marks } };
1910
+ const carrier = markCarrier(emitted);
1911
+ if (Object.keys(marks).length > 0 && carrier !== undefined) {
1912
+ const target = emitted.indexOf(carrier);
1913
+ emitted[target] = { ...carrier, option: { ...carrier.option, ...marks } };
1851
1914
  }
1852
1915
  return ok(emitted);
1853
1916
  }
1854
1917
  /** The option of each emitted series, with the value label of each bar of a small bar chart. */
1855
1918
  function labeledSeries(context, emitted, horizontal) {
1856
1919
  return withValueLabels(emitted.map((entry) => entry.option), horizontal, (cell, index) => {
1857
- const value = emitted[index].entry?.y;
1920
+ const value = emitted[index]?.entry?.y;
1858
1921
  return value === undefined ? String(cell) : valueLabelText(value.transformed ? value.name : value.column, cell, context.meanings);
1859
- }, (index) => emitted[index].entry?.low === undefined);
1922
+ }, (index) => emitted[index]?.entry?.low === undefined);
1860
1923
  }
1861
1924
  /** The names of the drawn series, in series order. An auxiliary series names no entry of its own. */
1862
1925
  function drawnNames(emitted) {
1863
- return emitted.filter((entry) => !entry.auxiliary).map((entry) => String(entry.option.name));
1926
+ return emitted.filter((entry) => !entry.auxiliary).map((entry) => textOf(entry.option.name));
1864
1927
  }
1865
1928
  /**
1866
1929
  * The visual maps of one composition: one map over the continuous color, and one map over the symbol size
@@ -1912,8 +1975,8 @@ function visualMaps(context, resolved, emitted) {
1912
1975
  show: false,
1913
1976
  seriesIndex,
1914
1977
  dimension,
1915
- min: sizes.length > 0 ? lowest(sizes) : 0,
1916
- max: sizes.length > 0 ? highest(sizes) : 1,
1978
+ min: lowest(sizes) ?? 0,
1979
+ max: highest(sizes) ?? 1,
1917
1980
  inRange: { symbolSize: [...SIZE_CHANNEL_RANGE_PX] },
1918
1981
  });
1919
1982
  }
@@ -1926,11 +1989,12 @@ function visualMaps(context, resolved, emitted) {
1926
1989
  function drawnMembers(emitted, seriesIndex, dimension) {
1927
1990
  const members = [];
1928
1991
  for (const index of seriesIndex) {
1929
- const data = emitted[index].option.data;
1992
+ const data = emitted[index]?.option.data;
1930
1993
  if (!Array.isArray(data))
1931
1994
  continue;
1932
1995
  for (const item of data) {
1933
- const value = Array.isArray(item) ? item : typeof item === "object" && item !== null ? item.value : undefined;
1996
+ const fields = parseUnknownRecord(item);
1997
+ const value = Array.isArray(item) ? item : fields?.value;
1934
1998
  const member = Array.isArray(value) ? toNumber(value[dimension]) : null;
1935
1999
  if (member !== null)
1936
2000
  members.push(member);
@@ -1938,20 +2002,22 @@ function drawnMembers(emitted, seriesIndex, dimension) {
1938
2002
  }
1939
2003
  return members;
1940
2004
  }
1941
- /** The smallest of some values, read in one pass. */
2005
+ /** The smallest of some values, or `undefined` for no value. */
1942
2006
  function lowest(values) {
1943
- let min = values[0];
1944
- for (const value of values)
1945
- if (value < min)
2007
+ let min;
2008
+ for (const value of values) {
2009
+ if (min === undefined || value < min)
1946
2010
  min = value;
2011
+ }
1947
2012
  return min;
1948
2013
  }
1949
- /** The largest of some values, read in one pass. */
2014
+ /** The largest of some values, or `undefined` for no value. */
1950
2015
  function highest(values) {
1951
- let max = values[0];
1952
- for (const value of values)
1953
- if (value > max)
2016
+ let max;
2017
+ for (const value of values) {
2018
+ if (max === undefined || value > max)
1954
2019
  max = value;
2020
+ }
1955
2021
  return max;
1956
2022
  }
1957
2023
  /**
@@ -1968,9 +2034,9 @@ function intervalAlongX(entry, axes) {
1968
2034
  }
1969
2035
  /** The place of each category of one axis, keyed by the text of the category, or `undefined` for a value axis. */
1970
2036
  function categoryPlaces(axis) {
1971
- if (axis.type !== "category" || !Array.isArray(axis.data))
2037
+ if (axis.type !== "category" || !isUnknownArray(axis.data))
1972
2038
  return undefined;
1973
- return new Map(axis.data.map((category, place) => [String(category), place]));
2039
+ return new Map(axis.data.map((category, place) => [textOf(category), place]));
1974
2040
  }
1975
2041
  /**
1976
2042
  * The interval series of one runtime series: one custom series with the `interval` renderer, after the series
@@ -2039,6 +2105,10 @@ function deriveFacets(context, facet, columns, resolved, axes) {
2039
2105
  if (context.collector !== undefined) {
2040
2106
  context.collector.failed = true;
2041
2107
  }
2108
+ const first = resolved[0];
2109
+ if (first === undefined) {
2110
+ return err(problem(context.blockId, "The composition carries no series."));
2111
+ }
2042
2112
  const split = splitByChannel(context.rows, channel.value);
2043
2113
  if (split.length > FACET_PANEL_LIMIT) {
2044
2114
  return err(problem(context.blockId, `The facet splits the table into ${split.length} panels. A facet holds ${FACET_PANEL_LIMIT} panels at most, thus a table of fewer groups serves the reader.`));
@@ -2055,24 +2125,26 @@ function deriveFacets(context, facet, columns, resolved, axes) {
2055
2125
  emitted.push({ ...entry, option: { ...entry.option, xAxisIndex: place, yAxisIndex: place } });
2056
2126
  }
2057
2127
  }
2058
- const labeledPanels = labeledSeries(context, emitted, isHorizontalBar(resolved[0].declared));
2059
- const labeled = resolved[0].declared.form === "bar" && Object.keys(labelRoom(labeledPanels, isHorizontalBar(resolved[0].declared))).length > 0;
2060
- const shared = sharedAxes(context, resolved, axes, labeled);
2128
+ const labeledPanels = labeledSeries(context, emitted, isHorizontalBar(first.declared));
2129
+ const labeled = first.declared.form === "bar" && Object.keys(labelRoom(labeledPanels, isHorizontalBar(first.declared))).length > 0;
2130
+ const shared = sharedAxes(context, resolved, axes, labeled, isHorizontalBar(first.declared));
2061
2131
  // A continuous color draws its scale at the right edge, thus the panels leave that band free.
2062
2132
  const scaleBand = emitted.some((entry) => entry.entry?.color !== undefined) ? COLOR_SCALE_BAND_PCT : 0;
2063
2133
  const layout = facetLayout(panels.map((panel) => panel.name), shared, legendOf(drawnNames(emitted)), scaleBand);
2064
2134
  const named = resolved.some((entry) => entry.label !== undefined) || context.labeled.size > 0;
2065
2135
  const maps = visualMaps(context, resolved, emitted);
2066
- return ok({
2136
+ const panel = {
2067
2137
  tooltip: named ? { ...NAMED_TOOLTIP } : { ...PLAIN_TOOLTIP },
2068
2138
  grid: layout.grid,
2069
2139
  xAxis: layout.xAxis,
2070
2140
  yAxis: layout.yAxis,
2071
2141
  series: labeledPanels,
2072
2142
  graphic: layout.graphic,
2073
- ...(maps.length > 0 ? { visualMap: maps } : {}),
2074
2143
  legend: layout.legend,
2075
- });
2144
+ };
2145
+ if (maps.length > 0)
2146
+ panel.visualMap = maps;
2147
+ return ok(panel);
2076
2148
  }
2077
2149
  /**
2078
2150
  * The layout of the panels of a facet, one panel for each name in order.
@@ -2140,12 +2212,12 @@ function facetLayout(names, shared, legend, scaleBand) {
2140
2212
  * turned label still covers its neighbor. `widthPx` is the panel width on the page, and an x axis alone states it.
2141
2213
  */
2142
2214
  function panelAxis(axis, widthPx) {
2143
- const label = typeof axis.axisLabel === "object" && axis.axisLabel !== null ? axis.axisLabel : {};
2215
+ const label = parseUnknownRecord(axis.axisLabel) ?? {};
2144
2216
  const base = { ...withoutName(axis), splitNumber: FACET_SPLIT_NUMBER };
2145
- if (axis.type !== "category" || !Array.isArray(axis.data))
2217
+ if (axis.type !== "category" || !isUnknownArray(axis.data))
2146
2218
  return { ...base, axisLabel: { ...label, hideOverlap: true } };
2147
2219
  const turn = widthPx === undefined || label.rotate !== undefined ? undefined : categoryTurn(axis.data, widthPx);
2148
- return { ...base, axisLabel: { ...label, interval: 0, ...(turn !== undefined ? { rotate: turn } : {}) } };
2220
+ return { ...base, axisLabel: { ...label, interval: 0, rotate: turn } };
2149
2221
  }
2150
2222
  /** The width of one character of the chart text, as a share of the text size. */
2151
2223
  const LABEL_CHARACTER_SHARE = 0.6;
@@ -2178,30 +2250,36 @@ function categoryTurn(categories, widthPx) {
2178
2250
  function thinnedLabels(option) {
2179
2251
  if (option.xAxis === undefined)
2180
2252
  return option;
2181
- let thinned = false;
2182
2253
  const thin = (axis) => {
2183
- if (typeof axis !== "object" || axis === null || Array.isArray(axis))
2254
+ const fields = parseUnknownRecord(axis);
2255
+ if (fields === undefined)
2184
2256
  return axis;
2185
- const fields = axis;
2186
- const label = typeof fields.axisLabel === "object" && fields.axisLabel !== null ? fields.axisLabel : {};
2187
- if (fields.type !== "category" || !Array.isArray(fields.data) || label.rotate !== 90 || label.show === false)
2257
+ const label = parseUnknownRecord(fields.axisLabel) ?? {};
2258
+ if (fields.type !== "category" || !isUnknownArray(fields.data) || label.rotate !== 90 || label.show === false)
2188
2259
  return axis;
2189
2260
  const interval = categoryInterval(fields.data.length, CHART_PAGE_TEXT_PX, pagePlotWidth(option.grid, fields));
2190
2261
  if (interval === 0)
2191
2262
  return axis;
2192
- thinned = true;
2193
2263
  return { ...fields, axisLabel: { ...label, interval } };
2194
2264
  };
2195
- const xAxis = Array.isArray(option.xAxis) ? option.xAxis.map(thin) : thin(option.xAxis);
2196
- return { ...option, xAxis, ...(thinned && option.tooltip === undefined ? { tooltip: { trigger: "axis" } } : {}) };
2265
+ const declared = option.xAxis;
2266
+ const axes = Array.isArray(declared) ? declared : [declared];
2267
+ const thinnedAxes = axes.map(thin);
2268
+ const thinned = thinnedAxes.some((axis, index) => axis !== axes[index]);
2269
+ const [singleAxis] = thinnedAxes;
2270
+ const xAxis = Array.isArray(declared) ? thinnedAxes : singleAxis;
2271
+ const result = { ...option, xAxis };
2272
+ if (thinned && option.tooltip === undefined)
2273
+ result.tooltip = { trigger: "axis" };
2274
+ return result;
2197
2275
  }
2198
2276
  /**
2199
2277
  * The plot width of the grid of one axis on the page, in pixels. A grid that states its width gives that width,
2200
2278
  * as a facet panel does. Every other grid spans the page chart body less its two side margins.
2201
2279
  */
2202
2280
  function pagePlotWidth(grid, axis) {
2203
- const entry = Array.isArray(grid) ? grid[typeof axis.gridIndex === "number" ? axis.gridIndex : 0] : grid;
2204
- const fields = typeof entry === "object" && entry !== null ? entry : {};
2281
+ const entry = isUnknownArray(grid) ? grid[typeof axis.gridIndex === "number" ? axis.gridIndex : 0] : grid;
2282
+ const fields = parseUnknownRecord(entry) ?? {};
2205
2283
  const stated = pagePx(fields.width);
2206
2284
  return stated > 0 ? stated : CHART_PAGE_WIDTH_PX - pagePx(fields.left) - pagePx(fields.right);
2207
2285
  }
@@ -2242,7 +2320,7 @@ function withoutName(axis) {
2242
2320
  * values. A category axis already lists the categories of every row, and a log axis keeps the range of the
2243
2321
  * chart runtime.
2244
2322
  */
2245
- function sharedAxes(context, resolved, axes, labeled) {
2323
+ function sharedAxes(context, resolved, axes, labeled, horizontal) {
2246
2324
  const xs = [];
2247
2325
  const ys = [];
2248
2326
  for (const entry of resolved) {
@@ -2268,7 +2346,6 @@ function sharedAxes(context, resolved, axes, labeled) {
2268
2346
  (horizontal ? xs : ys).push(0);
2269
2347
  }
2270
2348
  // The value labels of a bar sit past the bar ends, thus the value axis of the bar takes the label room.
2271
- const horizontal = isHorizontalBar(resolved[0].declared);
2272
2349
  return { xAxis: sharedRange(axes.xAxis, xs, labeled && horizontal), yAxis: sharedRange(axes.yAxis, ys, labeled && !horizontal) };
2273
2350
  }
2274
2351
  /**
@@ -2278,11 +2355,11 @@ function sharedAxes(context, resolved, axes, labeled) {
2278
2355
  * of a bar chart with labels does on one panel. The zero of a bar stays the end of its side.
2279
2356
  */
2280
2357
  function sharedRange(axis, values, room) {
2281
- if (axis.type !== "value" || values.length === 0) {
2282
- return axis;
2283
- }
2284
2358
  let low = lowest(values);
2285
2359
  let high = highest(values);
2360
+ if (axis.type !== "value" || low === undefined || high === undefined) {
2361
+ return axis;
2362
+ }
2286
2363
  if (room) {
2287
2364
  const span = high - low;
2288
2365
  if (high > 0)
@@ -2363,12 +2440,12 @@ function plottedSeries(entry, axes, meanings) {
2363
2440
  const horizontal = isHorizontalBar(entry.declared);
2364
2441
  const xAxis = horizontal ? axes.yAxis : axes.xAxis;
2365
2442
  const yAxis = horizontal ? axes.xAxis : axes.yAxis;
2366
- return {
2367
- ...entry,
2368
- x: plottedChannel(entry.x, xAxis, meanings),
2369
- y: plottedChannel(entry.y, yAxis, meanings),
2370
- ...(entry.y0 !== undefined ? { y0: plottedChannel(entry.y0, yAxis, meanings) } : {}),
2371
- };
2443
+ const plotted = { ...entry };
2444
+ plotted.x = plottedChannel(entry.x, xAxis, meanings);
2445
+ plotted.y = plottedChannel(entry.y, yAxis, meanings);
2446
+ if (entry.y0 !== undefined)
2447
+ plotted.y0 = plottedChannel(entry.y0, yAxis, meanings);
2448
+ return plotted;
2372
2449
  }
2373
2450
  /**
2374
2451
  * One plotted channel in the form that its axis reads.
@@ -2385,7 +2462,11 @@ function plottedSeries(entry, axes, meanings) {
2385
2462
  function plottedChannel(channel, axis, meanings) {
2386
2463
  if (axis.type === "category") {
2387
2464
  const retyped = channel.values.some((cell) => typeof cell === "number");
2388
- return { ...channel, values: channel.values.map((cell) => (cell === null ? null : categoryCell(cell))), ...(retyped ? { retyped: true } : {}) };
2465
+ return {
2466
+ ...channel,
2467
+ values: channel.values.map((cell) => (cell === null ? null : (categoryCell(cell) ?? null))),
2468
+ retyped: retyped ? true : undefined,
2469
+ };
2389
2470
  }
2390
2471
  if (channel.transformed || channel.values.some((cell) => cell !== null && isNonNumericString(cell)))
2391
2472
  return channel;
@@ -2474,8 +2555,7 @@ function splitByChannel(rows, group) {
2474
2555
  }
2475
2556
  const buckets = [];
2476
2557
  const byKey = new Map();
2477
- for (let index = 0; index < rows.length; index += 1) {
2478
- const value = group.values[index];
2558
+ for (const [index, value] of group.values.entries()) {
2479
2559
  if (value === null)
2480
2560
  continue;
2481
2561
  // The key carries the type of the cell, thus the number `1` and the string `"1"` are two groups.
@@ -2588,20 +2668,28 @@ function collectSource(collector, entry, split, labeled, form, rises) {
2588
2668
  return;
2589
2669
  }
2590
2670
  const flags = split.indices.filter((index) => labeled.has(index));
2591
- collector.series.push({
2592
- x,
2593
- y,
2594
- ...(color !== undefined ? { color } : {}),
2595
- ...(size !== undefined ? { size } : {}),
2596
- ...(group !== undefined ? { group } : {}),
2597
- ...(split.category === undefined && split.name !== undefined ? { value: split.name } : {}),
2598
- ...(split.category !== undefined ? { category: split.category } : {}),
2599
- ...(label !== undefined ? { label } : {}),
2600
- ...(flags.length > 0 ? { flags } : {}),
2601
- ...(SORTED_FORMS.has(form) ? { sort: true } : {}),
2602
- ...(rises ? { rise: true } : {}),
2603
- ...(isHorizontalBar(entry.declared) ? { swap: true } : {}),
2604
- });
2671
+ const described = { x, y };
2672
+ if (color !== undefined)
2673
+ described.color = color;
2674
+ if (size !== undefined)
2675
+ described.size = size;
2676
+ if (group !== undefined)
2677
+ described.group = group;
2678
+ if (split.category === undefined && split.name !== undefined)
2679
+ described.value = split.name;
2680
+ if (split.category !== undefined)
2681
+ described.category = split.category;
2682
+ if (label !== undefined)
2683
+ described.label = label;
2684
+ if (flags.length > 0)
2685
+ described.flags = flags;
2686
+ if (SORTED_FORMS.has(form))
2687
+ described.sort = true;
2688
+ if (rises)
2689
+ described.rise = true;
2690
+ if (isHorizontalBar(entry.declared))
2691
+ described.swap = true;
2692
+ collector.series.push(described);
2605
2693
  }
2606
2694
  /**
2607
2695
  * The payload column of one resolved channel, or `undefined` when the payload holds no such column or when the
@@ -2623,10 +2711,11 @@ function columnSource(collector, channel) {
2623
2711
  * no item style, and the theme answers for it.
2624
2712
  */
2625
2713
  function seriesItemStyle(color, form, density) {
2626
- const fields = {
2627
- ...(color !== undefined ? { color } : {}),
2628
- ...(form === "scatter" && density === "crowd" ? { opacity: SCATTER_CROWD_OPACITY } : {}),
2629
- };
2714
+ const fields = {};
2715
+ if (color !== undefined)
2716
+ fields.color = color;
2717
+ if (form === "scatter" && density === "crowd")
2718
+ fields.opacity = SCATTER_CROWD_OPACITY;
2630
2719
  return Object.keys(fields).length > 0 ? { itemStyle: fields } : {};
2631
2720
  }
2632
2721
  /**
@@ -2640,11 +2729,9 @@ function seriesItemStyle(color, form, density) {
2640
2729
  * then any carrier at all. Each guide reaches the page under every one of the three.
2641
2730
  */
2642
2731
  function markCarrier(emitted) {
2643
- const drawn = emitted.findIndex((entry) => entry.carriesMarks && !entry.muted && !entry.empty);
2644
- if (drawn >= 0)
2645
- return drawn;
2646
- const colored = emitted.findIndex((entry) => entry.carriesMarks && !entry.muted);
2647
- return colored >= 0 ? colored : emitted.findIndex((entry) => entry.carriesMarks);
2732
+ return (emitted.find((entry) => entry.carriesMarks && !entry.muted && !entry.empty) ??
2733
+ emitted.find((entry) => entry.carriesMarks && !entry.muted) ??
2734
+ emitted.find((entry) => entry.carriesMarks));
2648
2735
  }
2649
2736
  /**
2650
2737
  * The points of one group. A row whose channel gives no value drops, and no substitute value appears. A wide
@@ -2655,7 +2742,7 @@ function collectPoints(entry, indices) {
2655
2742
  for (const index of indices) {
2656
2743
  const x = entry.x.values[index];
2657
2744
  const y = entry.y.values[index];
2658
- if (x === null || y === null)
2745
+ if (x === null || x === undefined || y === null || y === undefined)
2659
2746
  continue;
2660
2747
  const point = { index, x, y };
2661
2748
  if (entry.y0 !== undefined) {
@@ -2733,14 +2820,21 @@ function seriesData(entry, points, labeled, horizontal, itemColor) {
2733
2820
  continue;
2734
2821
  }
2735
2822
  itemObjects = true;
2736
- data.push({
2823
+ const item = {
2737
2824
  value: pair,
2738
- // A marked point of a series with no label channel takes the x cell as its name. Thus the
2739
- // `{b}` of the label template and of the tooltip names a cell of the row, and never nothing.
2740
- ...(named || marked ? { name: named ? String(label) : String(point.x) } : {}),
2741
- ...(color !== undefined ? { itemStyle: { color } } : {}),
2742
- ...(marked ? { label: { ...POINT_LABEL } } : {}),
2743
- });
2825
+ };
2826
+ // A marked point of a series with no label channel takes the x cell as its name. Thus the
2827
+ // `{b}` of the label template and of the tooltip names a cell of the row, and never nothing.
2828
+ if (named || marked) {
2829
+ item.name = named ? String(label) : String(point.x);
2830
+ }
2831
+ if (color !== undefined) {
2832
+ item.itemStyle = { color };
2833
+ }
2834
+ if (marked) {
2835
+ item.label = { ...POINT_LABEL };
2836
+ }
2837
+ data.push(item);
2744
2838
  }
2745
2839
  return { data, itemObjects };
2746
2840
  }
@@ -2806,13 +2900,19 @@ function formOptions(form, density, perPoint) {
2806
2900
  return { step: "end", showSymbol: false };
2807
2901
  case "area":
2808
2902
  return { showSymbol: false, areaStyle: {} };
2809
- case "scatter":
2810
- return {
2811
- ...(density === "normal" ? {} : { symbolSize: density === "crowd" ? SCATTER_CROWD_SYMBOL_SIZE : SCATTER_HOVER_SYMBOL_SIZE }),
2812
- // The large path draws a simplified point in one fill, and it drops a per-item style. Thus a
2813
- // series whose items carry a name, a label, a color, or a size keeps the normal path.
2814
- ...(perPoint ? {} : { large: true, largeThreshold: LARGE_SCATTER_THRESHOLD }),
2815
- };
2903
+ case "scatter": {
2904
+ const scatter = {};
2905
+ if (density !== "normal") {
2906
+ scatter.symbolSize = density === "crowd" ? SCATTER_CROWD_SYMBOL_SIZE : SCATTER_HOVER_SYMBOL_SIZE;
2907
+ }
2908
+ // The large path draws a simplified point in one fill, and it drops a per-item style. Thus a
2909
+ // series whose items carry a name, a label, a color, or a size keeps the normal path.
2910
+ if (!perPoint) {
2911
+ scatter.large = true;
2912
+ scatter.largeThreshold = LARGE_SCATTER_THRESHOLD;
2913
+ }
2914
+ return scatter;
2915
+ }
2816
2916
  }
2817
2917
  }
2818
2918
  /**
@@ -2869,15 +2969,16 @@ function pointLabelRows(blockId, annotations, rows, columns, plotted) {
2869
2969
  */
2870
2970
  function topRows(rows, column, order, n, plotted) {
2871
2971
  const ranked = [];
2872
- for (let index = 0; index < rows.length; index += 1) {
2873
- if (plotted.has(index) && rows[index][column] !== undefined)
2874
- ranked.push(index);
2972
+ for (const [index, row] of rows.entries()) {
2973
+ const cell = row[column];
2974
+ if (plotted.has(index) && cell !== undefined)
2975
+ ranked.push({ index, cell });
2875
2976
  }
2876
2977
  ranked.sort((a, b) => {
2877
- const compared = compareCell(rows[a][column], rows[b][column]);
2978
+ const compared = compareCell(a.cell, b.cell);
2878
2979
  return order === "asc" ? compared : -compared;
2879
2980
  });
2880
- return ranked.slice(0, n);
2981
+ return ranked.slice(0, n).map((entry) => entry.index);
2881
2982
  }
2882
2983
  /**
2883
2984
  * The mark members of the annotations.
@@ -2902,10 +3003,12 @@ function markMembers(annotations) {
2902
3003
  ]);
2903
3004
  }
2904
3005
  }
2905
- return {
2906
- ...(lines.length > 0 ? { markLine: guideMarkLine(lines) } : {}),
2907
- ...(areas.length > 0 ? { markArea: { silent: true, data: areas } } : {}),
2908
- };
3006
+ const marks = {};
3007
+ if (lines.length > 0)
3008
+ marks.markLine = guideMarkLine(lines);
3009
+ if (areas.length > 0)
3010
+ marks.markArea = { silent: true, data: areas };
3011
+ return marks;
2909
3012
  }
2910
3013
  /**
2911
3014
  * The label of one mark member. The text is a constant of the annotation, and never a template.
@@ -2914,10 +3017,11 @@ function markMembers(annotations) {
2914
3017
  * its own default, and a member of either kind that states nothing gives the same bytes as before.
2915
3018
  */
2916
3019
  function markLabel(label, position) {
2917
- const fields = {
2918
- ...(label !== undefined ? { formatter: label } : {}),
2919
- ...(position !== undefined ? { position } : {}),
2920
- };
3020
+ const fields = {};
3021
+ if (label !== undefined)
3022
+ fields.formatter = label;
3023
+ if (position !== undefined)
3024
+ fields.position = position;
2921
3025
  return Object.keys(fields).length > 0 ? { label: fields } : {};
2922
3026
  }
2923
3027
  /** The mark key of one axis. A mark member names `xAxis` or `yAxis`, and the constant that sits on it. */
@@ -3014,13 +3118,13 @@ function compositionAxis(context, channel, axis, declared, preset) {
3014
3118
  if (base.type !== "category") {
3015
3119
  return err(problem(context.blockId, valueAxisOrderFault(channel.column)));
3016
3120
  }
3017
- const ordered = orderChannel(context, channel, base.data);
3121
+ const ordered = orderChannel(context, channel, isUnknownArray(base.data) ? base.data : []);
3018
3122
  return ordered.map((data) => ({ ...base, data }));
3019
3123
  }
3020
3124
  /** Sort the categories of one composition channel by its order, or keep them where it declares none. */
3021
3125
  function orderChannel(context, channel, categories) {
3022
3126
  const order = channel.order;
3023
- return orderCategories(context.blockId, context.rows.length, (index) => channel.values[index], categories, order, (index) => (order === undefined ? undefined : context.rows[index][order.by]));
3127
+ return orderCategories(context.blockId, context.rows.length, (index) => channel.values[index], categories, order, (index) => (order === undefined ? undefined : context.rows[index]?.[order.by]));
3024
3128
  }
3025
3129
  // ── The shared building blocks ──────────────────────────────────────────────
3026
3130
  /**
@@ -3096,7 +3200,7 @@ function orderedAxis(blockId, rows, column, axis, titles, order, categorical) {
3096
3200
  if (inferred.type !== "category") {
3097
3201
  return err(problem(blockId, valueAxisOrderFault(column)));
3098
3202
  }
3099
- const sorted = orderCategories(blockId, rows.length, (index) => String(rows[index][column]), inferred.data, order, (index) => rows[index][order.by]);
3203
+ const sorted = orderCategories(blockId, rows.length, (index) => String(rows[index]?.[column]), isUnknownArray(inferred.data) ? inferred.data : [], order, (index) => rows[index]?.[order.by]);
3100
3204
  return sorted.map((data) => ({ ...inferred, data }));
3101
3205
  }
3102
3206
  /** The refusal of an order on a channel whose axis draws values. */
@@ -3134,24 +3238,26 @@ function focusSet(blockId, focus, rowCount, categories) {
3134
3238
  * no function and the plotted value stays the cell.
3135
3239
  */
3136
3240
  function withValueLabels(series, horizontal, textOf, labelable = () => true) {
3137
- const labeled = (entry) => entry.type === "bar" && entry.stack === undefined && Array.isArray(entry.data);
3241
+ const labeled = (entry) => entry.type === "bar" && entry.stack === undefined && isUnknownArray(entry.data);
3138
3242
  let count = 0;
3139
3243
  for (const entry of series) {
3140
- if (labeled(entry))
3244
+ if (labeled(entry) && isUnknownArray(entry.data))
3141
3245
  count += entry.data.length;
3142
3246
  }
3143
3247
  if (count === 0 || count > BAR_VALUE_LABEL_LIMIT) {
3144
3248
  return [...series];
3145
3249
  }
3146
3250
  return series.map((entry, index) => {
3147
- if (!labeled(entry) || !labelable(index))
3251
+ if (!labeled(entry) || !labelable(index) || !isUnknownArray(entry.data))
3148
3252
  return entry;
3149
3253
  const data = entry.data.map((item) => {
3150
3254
  // A bar item is a pair or an object whose value is the pair, thus the two forms read one field.
3151
- const fields = typeof item === "object" && item !== null && !Array.isArray(item) ? item : { value: item };
3152
- if (fields.label !== undefined || !Array.isArray(fields.value))
3255
+ const fields = parseUnknownRecord(item) ?? { value: item };
3256
+ const itemValue = fields.value;
3257
+ if (fields.label !== undefined || !isUnknownArray(itemValue))
3153
3258
  return item;
3154
- const cell = fields.value[horizontal ? 0 : 1];
3259
+ const read = itemValue[horizontal ? 0 : 1];
3260
+ const cell = typeof read === "number" || typeof read === "string" ? read : undefined;
3155
3261
  return { ...fields, label: { show: true, position: labelPosition(cell, horizontal), formatter: textOf(cell, index) } };
3156
3262
  });
3157
3263
  return { ...entry, data };
@@ -3173,12 +3279,13 @@ function labelRoom(series, horizontal) {
3173
3279
  let negative = false;
3174
3280
  let positive = false;
3175
3281
  for (const entry of series) {
3176
- if (entry.type !== "bar" || !Array.isArray(entry.data))
3282
+ if (entry.type !== "bar" || !isUnknownArray(entry.data))
3177
3283
  continue;
3178
3284
  for (const item of entry.data) {
3179
- if (typeof item !== "object" || item === null || Array.isArray(item) || item.label === undefined)
3285
+ const fields = parseUnknownRecord(item);
3286
+ if (fields?.label === undefined)
3180
3287
  continue;
3181
- const value = item.value;
3288
+ const value = fields.value;
3182
3289
  // The sign rule of `labelPosition`: a bar under zero puts its label at its lower end.
3183
3290
  if ((toNumber(Array.isArray(value) ? value[horizontal ? 0 : 1] : null) ?? 0) < 0)
3184
3291
  negative = true;
@@ -3303,6 +3410,9 @@ function histogramEdges(values) {
3303
3410
  const sorted = [...values].sort((a, b) => a - b);
3304
3411
  const min = sorted[0];
3305
3412
  const max = sorted[sorted.length - 1];
3413
+ if (min === undefined || max === undefined) {
3414
+ return [];
3415
+ }
3306
3416
  if (max === min) {
3307
3417
  return [min, max];
3308
3418
  }
@@ -3335,16 +3445,20 @@ function autoBinCount(sorted, min, max) {
3335
3445
  /** The bin counts for the values against the edges. The max value falls in the last bin. */
3336
3446
  function binCounts(values, edges) {
3337
3447
  const bins = edges.length - 1;
3338
- const counts = new Array(bins).fill(0);
3339
3448
  const min = edges[0];
3340
- const width = (edges[bins] - min) / bins;
3449
+ const max = edges[bins];
3450
+ if (bins < 1 || min === undefined || max === undefined) {
3451
+ return [];
3452
+ }
3453
+ const width = (max - min) / bins;
3454
+ const counts = new Array(bins).fill(0);
3341
3455
  for (const value of values) {
3342
3456
  let index = width === 0 ? 0 : Math.floor((value - min) / width);
3343
3457
  if (index < 0)
3344
3458
  index = 0;
3345
3459
  if (index >= bins)
3346
3460
  index = bins - 1;
3347
- counts[index] += 1;
3461
+ counts[index] = (counts[index] ?? 0) + 1;
3348
3462
  }
3349
3463
  return counts;
3350
3464
  }
@@ -3352,8 +3466,12 @@ function binCounts(values, edges) {
3352
3466
  function histogramSeries(values, edges, name) {
3353
3467
  const counts = binCounts(values, edges);
3354
3468
  const data = [];
3355
- for (let i = 0; i < counts.length; i++) {
3356
- data.push([(edges[i] + edges[i + 1]) / 2, counts[i]]);
3469
+ for (const [index, count] of counts.entries()) {
3470
+ const low = edges[index];
3471
+ const high = edges[index + 1];
3472
+ if (low === undefined || high === undefined)
3473
+ continue;
3474
+ data.push([(low + high) / 2, count]);
3357
3475
  }
3358
3476
  if (name === undefined) {
3359
3477
  return { type: "bar", barWidth: "99%", data };
@@ -3439,6 +3557,8 @@ function violinShape(values) {
3439
3557
  return undefined;
3440
3558
  const min = sorted[0];
3441
3559
  const max = sorted[n - 1];
3560
+ if (min === undefined || max === undefined)
3561
+ return undefined;
3442
3562
  const grid = [];
3443
3563
  for (let point = 0; point < VIOLIN_GRID_POINTS; point += 1) {
3444
3564
  grid.push(min + (point * (max - min)) / (VIOLIN_GRID_POINTS - 1));
@@ -3469,13 +3589,10 @@ function roundWidth(width) {
3469
3589
  * linearly between the `floor` and the `ceil` of that index.
3470
3590
  */
3471
3591
  function quantileType7(sorted, p) {
3472
- const n = sorted.length;
3473
- if (n === 1)
3474
- return sorted[0];
3475
- const index = p * (n - 1);
3476
- const low = Math.floor(index);
3477
- const high = Math.ceil(index);
3478
- if (low === high)
3479
- return sorted[low];
3480
- return sorted[low] + (index - low) * (sorted[high] - sorted[low]);
3592
+ const index = p * (sorted.length - 1);
3593
+ const low = sorted[Math.floor(index)];
3594
+ const high = sorted[Math.ceil(index)];
3595
+ if (low === undefined || high === undefined)
3596
+ return Number.NaN;
3597
+ return low + (index - Math.floor(index)) * (high - low);
3481
3598
  }