@pikku/core 0.12.83 → 0.12.86

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 (661) hide show
  1. package/CHANGELOG.md +492 -0
  2. package/README.md +1 -1
  3. package/dist/bootstrap-compat/root.d.ts +20 -0
  4. package/dist/classification/column-form.d.ts +32 -0
  5. package/dist/classification/column-form.js +42 -0
  6. package/dist/classification/data-classification.d.ts +64 -0
  7. package/dist/classification/index.d.ts +13 -0
  8. package/dist/classification/index.js +2 -0
  9. package/dist/classification/secret-value.d.ts +56 -0
  10. package/dist/classification/secret-value.js +46 -0
  11. package/dist/crypto-utils.d.ts +1 -1
  12. package/dist/ecosystem/agent-scorer.d.ts +12 -0
  13. package/dist/ecosystem/agent-scorer.js +5 -0
  14. package/dist/ecosystem/agent.d.ts +21 -0
  15. package/dist/ecosystem/agent.js +6 -0
  16. package/dist/ecosystem/channel/local.d.ts +3 -0
  17. package/dist/ecosystem/channel/local.js +3 -0
  18. package/dist/ecosystem/channel/serverless.d.ts +9 -0
  19. package/dist/ecosystem/channel/serverless.js +1 -0
  20. package/dist/ecosystem/channel.d.ts +15 -0
  21. package/dist/ecosystem/channel.js +5 -0
  22. package/dist/ecosystem/cli/channel.d.ts +16 -0
  23. package/dist/ecosystem/cli/channel.js +2 -0
  24. package/dist/ecosystem/cli.d.ts +9 -0
  25. package/dist/ecosystem/cli.js +2 -0
  26. package/dist/ecosystem/credential.d.ts +10 -0
  27. package/dist/ecosystem/credential.js +1 -0
  28. package/dist/ecosystem/crypto-utils.d.ts +8 -0
  29. package/dist/ecosystem/crypto-utils.js +1 -0
  30. package/dist/ecosystem/dev.d.ts +9 -0
  31. package/dist/ecosystem/dev.js +2 -0
  32. package/dist/ecosystem/errors.d.ts +8 -0
  33. package/dist/ecosystem/errors.js +2 -0
  34. package/dist/ecosystem/function.d.ts +13 -0
  35. package/dist/ecosystem/function.js +2 -0
  36. package/dist/ecosystem/gateway.d.ts +1 -0
  37. package/dist/ecosystem/hmac.d.ts +1 -0
  38. package/dist/ecosystem/hmac.js +1 -0
  39. package/dist/ecosystem/http.d.ts +13 -0
  40. package/dist/ecosystem/http.js +5 -0
  41. package/dist/ecosystem/mcp.d.ts +3 -0
  42. package/dist/ecosystem/mcp.js +2 -0
  43. package/dist/ecosystem/middleware.d.ts +18 -0
  44. package/dist/ecosystem/middleware.js +7 -0
  45. package/dist/ecosystem/node-host-resolver.d.ts +1 -0
  46. package/dist/ecosystem/node-host-resolver.js +1 -0
  47. package/dist/ecosystem/node.d.ts +1 -0
  48. package/dist/ecosystem/oauth2.d.ts +1 -0
  49. package/dist/ecosystem/oauth2.js +1 -0
  50. package/dist/ecosystem/persona.d.ts +17 -0
  51. package/dist/ecosystem/persona.js +5 -0
  52. package/dist/ecosystem/queue.d.ts +13 -0
  53. package/dist/ecosystem/queue.js +4 -0
  54. package/dist/ecosystem/remote.d.ts +8 -0
  55. package/dist/ecosystem/remote.js +1 -0
  56. package/dist/ecosystem/role.d.ts +4 -0
  57. package/dist/ecosystem/role.js +2 -0
  58. package/dist/ecosystem/rpc.d.ts +6 -0
  59. package/dist/ecosystem/rpc.js +3 -0
  60. package/dist/ecosystem/safe-fetch.d.ts +7 -0
  61. package/dist/ecosystem/safe-fetch.js +1 -0
  62. package/dist/ecosystem/scenario.d.ts +21 -0
  63. package/dist/ecosystem/scenario.js +8 -0
  64. package/dist/ecosystem/scheduler.d.ts +3 -0
  65. package/dist/ecosystem/scheduler.js +2 -0
  66. package/dist/ecosystem/schema.d.ts +2 -0
  67. package/dist/ecosystem/schema.js +1 -0
  68. package/dist/ecosystem/scope.d.ts +5 -0
  69. package/dist/ecosystem/scope.js +3 -0
  70. package/dist/ecosystem/secret.d.ts +11 -0
  71. package/dist/ecosystem/secret.js +2 -0
  72. package/dist/ecosystem/services/istanbul-coverage.d.ts +1 -0
  73. package/dist/ecosystem/services/istanbul-coverage.js +1 -0
  74. package/dist/ecosystem/services/local-content-request-handler.d.ts +9 -0
  75. package/dist/ecosystem/services/local-content-request-handler.js +1 -0
  76. package/dist/ecosystem/services/local-content.d.ts +2 -0
  77. package/dist/ecosystem/services/local-content.js +1 -0
  78. package/dist/ecosystem/services/local-meta.d.ts +1 -0
  79. package/dist/ecosystem/services/local-meta.js +1 -0
  80. package/dist/ecosystem/services/v8-coverage.d.ts +1 -0
  81. package/dist/ecosystem/services/v8-coverage.js +1 -0
  82. package/dist/ecosystem/services.d.ts +36 -0
  83. package/dist/ecosystem/services.js +12 -0
  84. package/dist/ecosystem/testing.d.ts +7 -0
  85. package/dist/ecosystem/testing.js +1 -0
  86. package/dist/ecosystem/trigger.d.ts +2 -0
  87. package/dist/ecosystem/trigger.js +1 -0
  88. package/dist/ecosystem/types.d.ts +12 -0
  89. package/dist/ecosystem/types.js +6 -0
  90. package/dist/ecosystem/variable.d.ts +9 -0
  91. package/dist/ecosystem/variable.js +1 -0
  92. package/dist/ecosystem/virtual-user.d.ts +24 -0
  93. package/dist/ecosystem/virtual-user.js +8 -0
  94. package/dist/ecosystem/workflow.d.ts +20 -0
  95. package/dist/ecosystem/workflow.js +6 -0
  96. package/dist/errors/index.d.ts +8 -0
  97. package/dist/errors/index.js +1 -0
  98. package/dist/errors/serialized-error.d.ts +7 -0
  99. package/dist/errors/serialized-error.js +1 -0
  100. package/dist/function/function-meta.types.d.ts +139 -0
  101. package/dist/function/function-meta.types.js +1 -0
  102. package/dist/function/function-runner.d.ts +3 -2
  103. package/dist/function/function-runner.js +31 -11
  104. package/dist/function/functions.types.d.ts +10 -2
  105. package/dist/function/index.d.ts +8 -2
  106. package/dist/function/index.js +4 -1
  107. package/dist/function/pikku-request.d.ts +8 -0
  108. package/dist/function/pikku-request.js +15 -0
  109. package/dist/index.d.ts +8 -8
  110. package/dist/index.js +3 -3
  111. package/dist/middleware/auth-apikey.d.ts +2 -10
  112. package/dist/middleware/auth-apikey.js +1 -1
  113. package/dist/middleware/auth-bearer.d.ts +2 -10
  114. package/dist/middleware/auth-bearer.js +1 -1
  115. package/dist/middleware/auth-cookie.d.ts +2 -10
  116. package/dist/middleware/auth-cookie.js +1 -1
  117. package/dist/middleware/cors.d.ts +5 -11
  118. package/dist/middleware/cors.js +13 -6
  119. package/dist/middleware/index.d.ts +3 -0
  120. package/dist/middleware/index.js +1 -0
  121. package/dist/middleware/middleware-factories.d.ts +9 -0
  122. package/dist/middleware/middleware-factories.js +19 -0
  123. package/dist/middleware/middleware.types.d.ts +27 -0
  124. package/dist/middleware/middleware.types.js +1 -0
  125. package/dist/middleware/remote-auth.d.ts +1 -1
  126. package/dist/middleware/remote-auth.js +1 -1
  127. package/dist/middleware/telemetry.d.ts +4 -20
  128. package/dist/middleware/telemetry.js +1 -1
  129. package/dist/middleware-runner.d.ts +2 -1
  130. package/dist/pikku-state.d.ts +2 -1
  131. package/dist/services/{ai-run-state-service.d.ts → agent-run-state-service.d.ts} +5 -5
  132. package/dist/services/agent-run-state-service.js +1 -0
  133. package/dist/services/{ai-agent-runner-service.d.ts → agent-runner-service.d.ts} +12 -12
  134. package/dist/services/agent-runner-service.js +1 -0
  135. package/dist/services/{ai-storage-service.d.ts → agent-storage-service.d.ts} +7 -7
  136. package/dist/services/agent-storage-service.js +1 -0
  137. package/dist/services/audit-service.d.ts +1 -1
  138. package/dist/services/credential-wire-service.js +1 -1
  139. package/dist/services/email-service.d.ts +1 -1
  140. package/dist/services/file-scenario-run-store.d.ts +58 -0
  141. package/dist/services/file-scenario-run-store.js +214 -0
  142. package/dist/services/http-personas.d.ts +1 -1
  143. package/dist/services/http-personas.js +3 -3
  144. package/dist/services/{in-memory-ai-run-state-service.d.ts → in-memory-agent-run-state-service.d.ts} +5 -5
  145. package/dist/services/{in-memory-ai-run-state-service.js → in-memory-agent-run-state-service.js} +1 -1
  146. package/dist/services/in-memory-workflow-service.d.ts +1 -1
  147. package/dist/services/index.d.ts +9 -5
  148. package/dist/services/index.js +4 -1
  149. package/dist/services/local-secrets.d.ts +1 -1
  150. package/dist/services/local-secrets.js +1 -1
  151. package/dist/services/logger.d.ts +7 -7
  152. package/dist/services/meta-service.d.ts +5 -4
  153. package/dist/services/scoped-secret-service.d.ts +1 -1
  154. package/dist/services/secret-service.d.ts +1 -1
  155. package/dist/services/typed-secret-service.d.ts +16 -2
  156. package/dist/services/typed-secret-service.js +5 -0
  157. package/dist/services/webhook-service.d.ts +1 -1
  158. package/dist/services/workflow-service.d.ts +2 -1
  159. package/dist/testing/index.d.ts +1 -0
  160. package/dist/testing/index.js +1 -0
  161. package/dist/testing/service-tests/agent-run-service-tests.d.ts +1 -1
  162. package/dist/testing/service-tests/agent-run-service-tests.js +3 -3
  163. package/dist/testing/service-tests/agent-storage-service-tests.d.ts +3 -0
  164. package/dist/testing/service-tests/{ai-storage-service-tests.js → agent-storage-service-tests.js} +4 -4
  165. package/dist/testing/service-tests.d.ts +4 -4
  166. package/dist/testing/service-tests.js +4 -4
  167. package/dist/types/core.types.d.ts +37 -187
  168. package/dist/types/core.types.js +1 -19
  169. package/dist/types/index.d.ts +2 -0
  170. package/dist/types/index.js +1 -0
  171. package/dist/types/state.types.d.ts +8 -6
  172. package/dist/utils.d.ts +13 -0
  173. package/dist/utils.js +2 -0
  174. package/dist/wirings/actor-flow/run-conversation.d.ts +2 -2
  175. package/dist/wirings/addon/addon-runner.d.ts +17 -0
  176. package/dist/wirings/addon/addon-runner.js +150 -0
  177. package/dist/wirings/addon/index.d.ts +6 -0
  178. package/dist/wirings/addon/index.js +3 -0
  179. package/dist/wirings/addon/remote-addon-auth.d.ts +16 -0
  180. package/dist/wirings/addon/remote-addon-auth.js +39 -0
  181. package/dist/wirings/addon/wire-addon.d.ts +80 -0
  182. package/dist/wirings/addon/wire-addon.js +120 -0
  183. package/dist/wirings/addon/wire-remote-addon.d.ts +22 -0
  184. package/dist/wirings/addon/wire-remote-addon.js +11 -0
  185. package/dist/wirings/{ai-agent/ai-agent-agui.d.ts → agent/agent-agui.d.ts} +2 -2
  186. package/dist/wirings/{ai-agent/ai-agent-agui.js → agent/agent-agui.js} +1 -1
  187. package/dist/wirings/{ai-agent/ai-agent-finalize.d.ts → agent/agent-finalize.d.ts} +10 -10
  188. package/dist/wirings/{ai-agent/ai-agent-finalize.js → agent/agent-finalize.js} +7 -7
  189. package/dist/wirings/{ai-agent/ai-agent-helpers.d.ts → agent/agent-helpers.d.ts} +1 -1
  190. package/dist/wirings/{ai-agent/ai-agent-interrupt.d.ts → agent/agent-interrupt.d.ts} +4 -4
  191. package/dist/wirings/{ai-agent/ai-agent-interrupt.js → agent/agent-interrupt.js} +2 -2
  192. package/dist/wirings/{ai-agent/ai-agent-memory.d.ts → agent/agent-memory.d.ts} +14 -14
  193. package/dist/wirings/{ai-agent/ai-agent-memory.js → agent/agent-memory.js} +1 -1
  194. package/dist/wirings/{ai-agent/ai-agent-model-config.js → agent/agent-model-config.js} +1 -1
  195. package/dist/wirings/{ai-agent/ai-agent-prepare.d.ts → agent/agent-prepare.d.ts} +24 -24
  196. package/dist/wirings/{ai-agent/ai-agent-prepare.js → agent/agent-prepare.js} +17 -17
  197. package/dist/wirings/agent/agent-registry.d.ts +16 -0
  198. package/dist/wirings/{ai-agent/ai-agent-registry.js → agent/agent-registry.js} +9 -9
  199. package/dist/wirings/{ai-agent → agent}/agent-rpc.js +8 -8
  200. package/dist/wirings/agent/agent-runner.d.ts +7 -0
  201. package/dist/wirings/{ai-agent/ai-agent-runner.js → agent/agent-runner.js} +49 -50
  202. package/dist/wirings/{ai-agent/ai-agent-stream.d.ts → agent/agent-stream.d.ts} +15 -15
  203. package/dist/wirings/{ai-agent/ai-agent-stream.js → agent/agent-stream.js} +78 -78
  204. package/dist/wirings/{ai-agent/ai-agent-turn.d.ts → agent/agent-turn.d.ts} +5 -5
  205. package/dist/wirings/{ai-agent/ai-agent-turn.js → agent/agent-turn.js} +4 -4
  206. package/dist/wirings/agent/agent-utils.d.ts +14 -0
  207. package/dist/wirings/agent/agent-utils.js +17 -0
  208. package/dist/wirings/{ai-agent/ai-agent.types.d.ts → agent/agent.types.d.ts} +47 -46
  209. package/dist/wirings/agent/agent.types.js +1 -0
  210. package/dist/wirings/agent/index.d.ts +12 -0
  211. package/dist/wirings/agent/index.js +10 -0
  212. package/dist/wirings/{ai-agent → agent}/voice-input.d.ts +1 -1
  213. package/dist/wirings/{ai-agent → agent}/voice-input.js +5 -5
  214. package/dist/wirings/{ai-agent → agent}/voice-output.d.ts +2 -3
  215. package/dist/wirings/{ai-agent → agent}/voice-output.js +8 -8
  216. package/dist/wirings/{ai-scorer/ai-scorer-grade.d.ts → agent-scorer/agent-scorer-grade.d.ts} +3 -3
  217. package/dist/wirings/{ai-scorer/ai-scorer-grade.js → agent-scorer/agent-scorer-grade.js} +6 -6
  218. package/dist/wirings/agent-scorer/agent-scorer-judge.d.ts +30 -0
  219. package/dist/wirings/{ai-scorer/ai-scorer-judge.js → agent-scorer/agent-scorer-judge.js} +57 -5
  220. package/dist/wirings/{ai-scorer/ai-scorer-live.d.ts → agent-scorer/agent-scorer-live.d.ts} +1 -1
  221. package/dist/wirings/{ai-scorer/ai-scorer-live.js → agent-scorer/agent-scorer-live.js} +3 -3
  222. package/dist/wirings/{ai-scorer/ai-scorer-registry.d.ts → agent-scorer/agent-scorer-registry.d.ts} +6 -6
  223. package/dist/wirings/{ai-scorer/ai-scorer-registry.js → agent-scorer/agent-scorer-registry.js} +4 -4
  224. package/dist/wirings/{ai-scorer/ai-scorer-snapshots.d.ts → agent-scorer/agent-scorer-snapshots.d.ts} +1 -1
  225. package/dist/wirings/{ai-scorer/ai-scorer-worker.d.ts → agent-scorer/agent-scorer-worker.d.ts} +3 -3
  226. package/dist/wirings/{ai-scorer/ai-scorer-worker.js → agent-scorer/agent-scorer-worker.js} +9 -7
  227. package/dist/wirings/{ai-scorer/ai-scorer.d.ts → agent-scorer/agent-scorer.d.ts} +12 -6
  228. package/dist/wirings/{ai-scorer/ai-scorer.js → agent-scorer/agent-scorer.js} +4 -3
  229. package/dist/wirings/{ai-scorer/ai-scorer.types.d.ts → agent-scorer/agent-scorer.types.d.ts} +24 -4
  230. package/dist/wirings/agent-scorer/agent-scorer.types.js +4 -0
  231. package/dist/wirings/agent-scorer/index.d.ts +6 -0
  232. package/dist/wirings/agent-scorer/index.js +5 -0
  233. package/dist/wirings/channel/channel-common.d.ts +2 -1
  234. package/dist/wirings/channel/channel-middleware-runner.d.ts +2 -1
  235. package/dist/wirings/channel/channel-rpc.types.d.ts +2 -2
  236. package/dist/wirings/channel/channel.types.d.ts +1 -1
  237. package/dist/wirings/channel/serverless/index.d.ts +1 -0
  238. package/dist/wirings/cli/channel/index.d.ts +1 -1
  239. package/dist/wirings/cli/cli-runner.d.ts +2 -1
  240. package/dist/wirings/cli/cli-runner.js +4 -1
  241. package/dist/wirings/cli/cli.types.d.ts +21 -2
  242. package/dist/wirings/cli/command-parser.js +157 -23
  243. package/dist/wirings/gateway/gateway.types.d.ts +2 -1
  244. package/dist/wirings/http/http-runner.d.ts +1 -1
  245. package/dist/wirings/http/http-runner.js +1 -1
  246. package/dist/wirings/http/http.types.d.ts +2 -2
  247. package/dist/wirings/http/index.d.ts +1 -0
  248. package/dist/wirings/http/index.js +1 -0
  249. package/dist/wirings/http/pikku-fetch-http-request.js +1 -1
  250. package/dist/wirings/http/pikku-fetch-http-response.js +2 -2
  251. package/dist/wirings/mcp/mcp.types.d.ts +1 -1
  252. package/dist/wirings/persona/index.d.ts +1 -1
  253. package/dist/wirings/persona/index.js +1 -1
  254. package/dist/wirings/persona/persona.types.d.ts +14 -0
  255. package/dist/wirings/queue/queue.types.d.ts +1 -1
  256. package/dist/wirings/queue/signed-queue-service.d.ts +1 -1
  257. package/dist/wirings/rpc/index.d.ts +0 -6
  258. package/dist/wirings/rpc/index.js +0 -3
  259. package/dist/wirings/rpc/remote-addon-auth.d.ts +1 -1
  260. package/dist/wirings/rpc/remote-addon-auth.js +1 -1
  261. package/dist/wirings/rpc/rpc-runner.d.ts +1 -1
  262. package/dist/wirings/rpc/rpc-runner.js +4 -4
  263. package/dist/wirings/rpc/rpc-types.d.ts +1 -1
  264. package/dist/wirings/rpc/wire-addon.d.ts +1 -1
  265. package/dist/wirings/scheduler/scheduler.types.d.ts +2 -1
  266. package/dist/wirings/scope/index.d.ts +1 -0
  267. package/dist/wirings/scope/index.js +1 -0
  268. package/dist/wirings/secret/secret.types.d.ts +10 -0
  269. package/dist/wirings/secret/validate-secret-definitions.js +2 -0
  270. package/dist/wirings/variable/validate-variable-definitions.js +2 -0
  271. package/dist/wirings/variable/variable.types.d.ts +9 -0
  272. package/dist/wirings/virtual-user/index.d.ts +1 -1
  273. package/dist/wirings/virtual-user/index.js +1 -1
  274. package/dist/wirings/virtual-user/prepare-virtual-user-run.d.ts +1 -1
  275. package/dist/wirings/virtual-user/prepare-virtual-user-run.js +1 -1
  276. package/dist/wirings/virtual-user/virtual-user-agents.d.ts +1 -1
  277. package/dist/wirings/virtual-user/virtual-user-derive.d.ts +1 -1
  278. package/dist/wirings/workflow/graph/graph-node.d.ts +9 -2
  279. package/dist/wirings/workflow/graph/graph-node.js +2 -0
  280. package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -0
  281. package/dist/wirings/workflow/graph/graph-runner.js +283 -31
  282. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +16 -1
  283. package/dist/wirings/workflow/index.d.ts +2 -0
  284. package/dist/wirings/workflow/index.js +1 -0
  285. package/dist/wirings/workflow/pikku-scenario-service.d.ts +14 -4
  286. package/dist/wirings/workflow/pikku-scenario-service.js +44 -16
  287. package/dist/wirings/workflow/pikku-workflow-service.d.ts +2 -1
  288. package/dist/wirings/workflow/pikku-workflow-service.js +3 -4
  289. package/dist/wirings/workflow/run-timeline.d.ts +2 -3
  290. package/dist/wirings/workflow/scenario-run.types.d.ts +171 -0
  291. package/dist/wirings/workflow/scenario-run.types.js +1 -0
  292. package/dist/wirings/workflow/scenario-step-guards.d.ts +1 -2
  293. package/dist/wirings/workflow/scenario-step-guards.js +0 -8
  294. package/dist/wirings/workflow/scenario-step.types.d.ts +27 -12
  295. package/dist/wirings/workflow/workflow-approval.js +2 -1
  296. package/dist/wirings/workflow/workflow-run-engine.types.d.ts +2 -1
  297. package/dist/wirings/workflow/workflow.types.d.ts +2 -1
  298. package/knowledge/decisions/index.md +2 -0
  299. package/knowledge/decisions/internals/{a-non-streaming-agent-run-registers-with-airunstate-too.md → a-non-streaming-agent-run-registers-with-agentrunstate-too.md} +6 -6
  300. package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +1 -1
  301. package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +1 -1
  302. package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +1 -1
  303. package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-and-not-a-queued-job.md +2 -2
  304. package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +6 -6
  305. package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +1 -1
  306. package/knowledge/decisions/internals/actor-flow-drives-the-target-through-a-transport-seam.md +1 -1
  307. package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +1 -1
  308. package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +1 -1
  309. package/knowledge/decisions/internals/{ai-agent-agui-bridge-obeys-the-client-ordering-contract.md → agent-agui-bridge-obeys-the-client-ordering-contract.md} +5 -5
  310. package/knowledge/decisions/internals/{ai-agent-audio-chunks-carry-the-format-the-provider-returned.md → agent-audio-chunks-carry-the-format-the-provider-returned.md} +2 -2
  311. package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +1 -1
  312. package/knowledge/decisions/internals/{ai-agent-credential-suspensions-hide-the-tool-result.md → agent-credential-suspensions-hide-the-tool-result.md} +2 -2
  313. package/knowledge/decisions/internals/{ai-agent-delegate-and-supervise-hide-different-text.md → agent-delegate-and-supervise-hide-different-text.md} +4 -4
  314. package/knowledge/decisions/internals/{ai-agent-llm-tool-arguments-have-nulls-stripped.md → agent-llm-tool-arguments-have-nulls-stripped.md} +3 -3
  315. package/knowledge/decisions/internals/{ai-agent-model-config-stays-a-single-resolution-seam.md → agent-model-config-stays-a-single-resolution-seam.md} +3 -3
  316. package/knowledge/decisions/internals/{ai-agent-onerror-hooks-cannot-change-the-failure.md → agent-onerror-hooks-cannot-change-the-failure.md} +6 -6
  317. package/knowledge/decisions/internals/{ai-agent-runner-methods-must-keep-their-receiver.md → agent-runner-methods-must-keep-their-receiver.md} +4 -4
  318. package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +1 -1
  319. package/knowledge/decisions/internals/{ai-agent-stream-persistence-is-best-effort.md → agent-stream-persistence-is-best-effort.md} +4 -4
  320. package/knowledge/decisions/internals/{ai-agent-sub-agents-inherit-the-parent-context-block.md → agent-sub-agents-inherit-the-parent-context-block.md} +3 -3
  321. package/knowledge/decisions/internals/{ai-agent-tool-execute-failures-are-logged-unconditionally.md → agent-tool-execute-failures-are-logged-unconditionally.md} +3 -3
  322. package/knowledge/decisions/internals/{ai-agent-voice-input-transcribes-audio-parts-in-place.md → agent-voice-input-transcribes-audio-parts-in-place.md} +2 -2
  323. package/knowledge/decisions/internals/{ai-agent-working-memory-is-persisted-only-when-valid.md → agent-working-memory-is-persisted-only-when-valid.md} +2 -2
  324. package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +1 -1
  325. package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +2 -2
  326. package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +3 -3
  327. package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +2 -2
  328. package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +1 -1
  329. package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.md +1 -1
  330. package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +1 -1
  331. package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +1 -1
  332. package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +1 -1
  333. package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +1 -1
  334. package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +1 -1
  335. package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +1 -1
  336. package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +4 -4
  337. package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +1 -1
  338. package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +3 -3
  339. package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +2 -2
  340. package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +2 -2
  341. package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +1 -1
  342. package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +1 -1
  343. package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +3 -3
  344. package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +1 -1
  345. package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +4 -4
  346. package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +1 -1
  347. package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +1 -1
  348. package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +1 -1
  349. package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +1 -1
  350. package/knowledge/decisions/internals/index.md +4 -2
  351. package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +1 -1
  352. package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +1 -1
  353. package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +1 -1
  354. package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +1 -1
  355. package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +1 -1
  356. package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +2 -2
  357. package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +5 -5
  358. package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +1 -1
  359. package/knowledge/decisions/internals/the-actor-prompt-says-json-because-of-json-object-mode.md +1 -1
  360. package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.md +1 -1
  361. package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +1 -1
  362. package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +43 -19
  363. package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +1 -1
  364. package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +5 -5
  365. package/knowledge/decisions/internals/the-persona-runtime-is-exported-from-the-persona-entry-point.md +1 -1
  366. package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +2 -2
  367. package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +1 -1
  368. package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +2 -2
  369. package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +3 -3
  370. package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +1 -1
  371. package/knowledge/decisions/internals/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.md +1 -1
  372. package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +1 -1
  373. package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +1 -1
  374. package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +1 -1
  375. package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +1 -1
  376. package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +1 -1
  377. package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +1 -1
  378. package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +1 -1
  379. package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +1 -1
  380. package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +9 -5
  381. package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +1 -1
  382. package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +2 -2
  383. package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +1 -1
  384. package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +1 -1
  385. package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +1 -1
  386. package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +2 -3
  387. package/knowledge/decisions/security/actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +1 -1
  388. package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +1 -1
  389. package/knowledge/decisions/security/{ai-agent-approval-forwarding-requires-a-symbol-brand.md → agent-approval-forwarding-requires-a-symbol-brand.md} +3 -3
  390. package/knowledge/decisions/security/{ai-agent-credential-requests-are-symbol-branded.md → agent-credential-requests-are-symbol-branded.md} +4 -4
  391. package/knowledge/decisions/security/{ai-agent-gate-requires-a-session-only-when-auth-is-true.md → agent-gate-requires-a-session-only-when-auth-is-true.md} +4 -4
  392. package/knowledge/decisions/security/{ai-agent-ownership-failures-never-echo-the-resource.md → agent-ownership-failures-never-echo-the-resource.md} +2 -2
  393. package/knowledge/decisions/security/{ai-agent-resume-re-runs-the-authorization-gate.md → agent-resume-re-runs-the-authorization-gate.md} +4 -4
  394. package/knowledge/decisions/security/{ai-agent-sessionless-deployments-have-no-thread-ownership.md → agent-sessionless-deployments-have-no-thread-ownership.md} +5 -5
  395. package/knowledge/decisions/security/{ai-agent-thread-ownership-composes-the-session-principal.md → agent-thread-ownership-composes-the-session-principal.md} +2 -2
  396. package/knowledge/decisions/security/{ai-agent-tool-filtering-reads-the-live-function-config.md → agent-tool-filtering-reads-the-live-function-config.md} +2 -2
  397. package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +3 -3
  398. package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +3 -3
  399. package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +3 -3
  400. package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +21 -13
  401. package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +1 -1
  402. package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +2 -2
  403. package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +1 -1
  404. package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +2 -2
  405. package/knowledge/decisions/security/index.md +3 -2
  406. package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +1 -1
  407. package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +3 -3
  408. package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +1 -1
  409. package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +2 -2
  410. package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +1 -1
  411. package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +2 -2
  412. package/knowledge/index.md +3 -1
  413. package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +1 -1
  414. package/knowledge/questions/index.md +2 -0
  415. package/package.json +16 -14
  416. package/run-tests.sh +0 -0
  417. package/scripts/generate-api-report.d.mts +1 -1
  418. package/scripts/generate-api-report.mjs +67 -60
  419. package/scripts/generate-api-report.mts +37 -47
  420. package/src/agent-naming.test.ts +68 -0
  421. package/src/api-report.test.ts +70 -1
  422. package/src/app-alias-surface.test.ts +179 -0
  423. package/src/app-leaf-surface.test.ts +217 -0
  424. package/src/bootstrap-compat/root.ts +20 -0
  425. package/src/{column-form.test.ts → classification/column-form.test.ts} +2 -2
  426. package/src/{data-classification.ts → classification/data-classification.ts} +1 -5
  427. package/src/classification/index.ts +38 -0
  428. package/src/{secret-value.test.ts → classification/secret-value.test.ts} +2 -2
  429. package/src/{secret-value.ts → classification/secret-value.ts} +1 -6
  430. package/src/crypto-utils.ts +1 -1
  431. package/src/dev/reload-meta.test.ts +1 -1
  432. package/src/errors/index.ts +9 -0
  433. package/src/errors/serialized-error.ts +9 -0
  434. package/src/factory-functions.test.ts +4 -2
  435. package/src/function/function-meta.types.ts +151 -0
  436. package/src/function/function-runner.test.ts +4 -2
  437. package/src/function/function-runner.ts +47 -14
  438. package/src/function/functions.types.ts +11 -7
  439. package/src/function/index.ts +24 -5
  440. package/src/function/list.types.ts +1 -3
  441. package/src/middleware/auth-apikey.ts +4 -2
  442. package/src/middleware/auth-bearer.test.ts +1 -1
  443. package/src/middleware/auth-bearer.ts +4 -2
  444. package/src/middleware/auth-cookie.ts +4 -1
  445. package/src/middleware/cors.test.ts +126 -5
  446. package/src/middleware/cors.ts +19 -8
  447. package/src/middleware/index.ts +16 -0
  448. package/src/middleware/middleware-factories.ts +62 -0
  449. package/src/middleware/middleware.types.ts +61 -0
  450. package/src/middleware/remote-auth.test.ts +1 -1
  451. package/src/middleware/remote-auth.ts +1 -1
  452. package/src/middleware/telemetry.ts +4 -2
  453. package/src/middleware-runner.test.ts +2 -3
  454. package/src/middleware-runner.ts +2 -2
  455. package/src/no-root-barrel.test.ts +114 -0
  456. package/src/permissions.ts +2 -4
  457. package/src/pikku-state.ts +6 -4
  458. package/src/public-surface.json +90 -170
  459. package/src/public-surface.json.README +20 -2
  460. package/src/public-surface.test.ts +31 -3
  461. package/src/remote.test.ts +1 -1
  462. package/src/removed-legacy-exports.test.ts +5 -1
  463. package/src/services/{ai-run-state-service.ts → agent-run-state-service.ts} +5 -5
  464. package/src/services/{ai-agent-runner-service.ts → agent-runner-service.ts} +18 -18
  465. package/src/services/{ai-storage-service.ts → agent-storage-service.ts} +7 -7
  466. package/src/services/audit-service.ts +1 -1
  467. package/src/services/credential-wire-service.ts +1 -1
  468. package/src/services/email-service.ts +2 -4
  469. package/src/services/file-scenario-run-store.test.ts +349 -0
  470. package/src/services/file-scenario-run-store.ts +282 -0
  471. package/src/services/http-personas-converse.test.ts +3 -3
  472. package/src/services/http-personas.ts +4 -4
  473. package/src/services/{in-memory-ai-run-state-service.ts → in-memory-agent-run-state-service.ts} +7 -7
  474. package/src/services/in-memory-workflow-service.ts +1 -1
  475. package/src/services/index.ts +22 -10
  476. package/src/services/local-content-request-handler.ts +1 -2
  477. package/src/services/local-secrets.ts +1 -1
  478. package/src/services/logger.ts +7 -7
  479. package/src/services/meta-service.ts +5 -5
  480. package/src/services/queue-webhook-service.test.ts +1 -1
  481. package/src/services/scoped-secret-service.ts +1 -1
  482. package/src/services/secret-service.ts +1 -1
  483. package/src/services/typed-secret-service.test.ts +52 -0
  484. package/src/services/typed-secret-service.ts +26 -2
  485. package/src/services/webhook-service.ts +1 -1
  486. package/src/services/workflow-service.ts +2 -1
  487. package/src/template-alias-surface.test.ts +240 -0
  488. package/src/testing/index.ts +1 -0
  489. package/src/testing/service-tests/agent-run-service-tests.ts +4 -4
  490. package/src/testing/service-tests/{ai-storage-service-tests.ts → agent-storage-service-tests.ts} +8 -8
  491. package/src/testing/service-tests.ts +10 -8
  492. package/src/types/core.types.ts +40 -292
  493. package/src/types/index.ts +2 -0
  494. package/src/types/state.types.ts +12 -14
  495. package/src/types/typed-credentials.test.ts +72 -0
  496. package/src/utils.ts +34 -0
  497. package/src/wirings/actor-flow/run-conversation.test.ts +2 -2
  498. package/src/wirings/actor-flow/run-conversation.ts +7 -9
  499. package/src/wirings/{rpc → addon}/addon-scopes.test.ts +1 -1
  500. package/src/wirings/addon/index.ts +12 -0
  501. package/src/wirings/{rpc → addon}/remote-addon-auth.ts +4 -1
  502. package/src/wirings/{rpc → addon}/wire-addon.ts +37 -2
  503. package/src/wirings/{ai-agent/ai-agent-agui.test.ts → agent/agent-agui.test.ts} +126 -105
  504. package/src/wirings/{ai-agent/ai-agent-agui.ts → agent/agent-agui.ts} +7 -7
  505. package/src/wirings/{ai-agent/ai-agent-authorization.test.ts → agent/agent-authorization.test.ts} +6 -6
  506. package/src/wirings/{ai-agent/ai-agent-finalize.test.ts → agent/agent-finalize.test.ts} +17 -16
  507. package/src/wirings/{ai-agent/ai-agent-finalize.ts → agent/agent-finalize.ts} +22 -22
  508. package/src/wirings/{ai-agent/ai-agent-helpers.test.ts → agent/agent-helpers.test.ts} +1 -1
  509. package/src/wirings/{ai-agent/ai-agent-helpers.ts → agent/agent-helpers.ts} +1 -1
  510. package/src/wirings/{ai-agent/ai-agent-interrupt.test.ts → agent/agent-interrupt.test.ts} +67 -77
  511. package/src/wirings/{ai-agent/ai-agent-interrupt.ts → agent/agent-interrupt.ts} +5 -5
  512. package/src/wirings/{ai-agent/ai-agent-memory.test.ts → agent/agent-memory.test.ts} +12 -12
  513. package/src/wirings/{ai-agent/ai-agent-memory.ts → agent/agent-memory.ts} +36 -36
  514. package/src/wirings/{ai-agent/ai-agent-model-config.test.ts → agent/agent-model-config.test.ts} +2 -5
  515. package/src/wirings/{ai-agent/ai-agent-model-config.ts → agent/agent-model-config.ts} +1 -1
  516. package/src/wirings/{ai-agent/ai-agent-prepare.test.ts → agent/agent-prepare.test.ts} +18 -18
  517. package/src/wirings/{ai-agent/ai-agent-prepare.ts → agent/agent-prepare.ts} +60 -56
  518. package/src/wirings/{ai-agent/ai-agent-registry.test.ts → agent/agent-registry.test.ts} +49 -43
  519. package/src/wirings/{ai-agent/ai-agent-registry.ts → agent/agent-registry.ts} +14 -14
  520. package/src/wirings/{ai-agent/ai-agent-resume-authorization.test.ts → agent/agent-resume-authorization.test.ts} +18 -18
  521. package/src/wirings/{ai-agent → agent}/agent-rpc.ts +16 -20
  522. package/src/wirings/{ai-agent/ai-agent-runner.test.ts → agent/agent-runner.test.ts} +105 -106
  523. package/src/wirings/{ai-agent/ai-agent-runner.ts → agent/agent-runner.ts} +91 -82
  524. package/src/wirings/{ai-agent/ai-agent-stream-output-hooks.test.ts → agent/agent-stream-output-hooks.test.ts} +25 -25
  525. package/src/wirings/{ai-agent/ai-agent-stream.test.ts → agent/agent-stream.test.ts} +147 -143
  526. package/src/wirings/{ai-agent/ai-agent-stream.ts → agent/agent-stream.ts} +148 -148
  527. package/src/wirings/{ai-agent/ai-agent-thread-ownership.test.ts → agent/agent-thread-ownership.test.ts} +24 -28
  528. package/src/wirings/{ai-agent/ai-agent-turn.test.ts → agent/agent-turn.test.ts} +3 -5
  529. package/src/wirings/{ai-agent/ai-agent-turn.ts → agent/agent-turn.ts} +7 -7
  530. package/src/wirings/agent/agent-utils.ts +20 -0
  531. package/src/wirings/{ai-agent/ai-agent.types.ts → agent/agent.types.ts} +54 -51
  532. package/src/wirings/agent/index.ts +57 -0
  533. package/src/wirings/{ai-agent → agent}/voice-input.test.ts +15 -15
  534. package/src/wirings/{ai-agent → agent}/voice-input.ts +11 -11
  535. package/src/wirings/{ai-agent → agent}/voice-output.test.ts +25 -27
  536. package/src/wirings/{ai-agent → agent}/voice-output.ts +11 -11
  537. package/src/wirings/{ai-scorer/ai-scorer-grade.test.ts → agent-scorer/agent-scorer-grade.test.ts} +8 -8
  538. package/src/wirings/{ai-scorer/ai-scorer-grade.ts → agent-scorer/agent-scorer-grade.ts} +9 -9
  539. package/src/wirings/agent-scorer/agent-scorer-judge.test.ts +285 -0
  540. package/src/wirings/agent-scorer/agent-scorer-judge.ts +180 -0
  541. package/src/wirings/{ai-scorer/ai-scorer-live.test.ts → agent-scorer/agent-scorer-live.test.ts} +11 -11
  542. package/src/wirings/{ai-scorer/ai-scorer-live.ts → agent-scorer/agent-scorer-live.ts} +3 -3
  543. package/src/wirings/{ai-scorer/ai-scorer-registry.ts → agent-scorer/agent-scorer-registry.ts} +11 -8
  544. package/src/wirings/{ai-scorer/ai-scorer-sampling.test.ts → agent-scorer/agent-scorer-sampling.test.ts} +1 -1
  545. package/src/wirings/{ai-scorer/ai-scorer-snapshots.test.ts → agent-scorer/agent-scorer-snapshots.test.ts} +2 -2
  546. package/src/wirings/{ai-scorer/ai-scorer-snapshots.ts → agent-scorer/agent-scorer-snapshots.ts} +1 -1
  547. package/src/wirings/{ai-scorer/ai-scorer-worker.test.ts → agent-scorer/agent-scorer-worker.test.ts} +15 -15
  548. package/src/wirings/{ai-scorer/ai-scorer-worker.ts → agent-scorer/agent-scorer-worker.ts} +9 -7
  549. package/src/wirings/{ai-scorer/ai-scorer.ts → agent-scorer/agent-scorer.ts} +15 -7
  550. package/src/wirings/{ai-scorer/ai-scorer.types.ts → agent-scorer/agent-scorer.types.ts} +27 -6
  551. package/src/wirings/agent-scorer/index.ts +23 -0
  552. package/src/wirings/channel/channel-common.ts +4 -2
  553. package/src/wirings/channel/channel-handler.ts +2 -5
  554. package/src/wirings/channel/channel-middleware-runner.ts +1 -1
  555. package/src/wirings/channel/channel-rpc.types.ts +3 -7
  556. package/src/wirings/channel/channel.types.ts +1 -2
  557. package/src/wirings/channel/local/local-channel-runner.test.ts +1 -2
  558. package/src/wirings/channel/serverless/index.ts +1 -0
  559. package/src/wirings/cli/channel/cli-raw-channel-runner.ts +2 -2
  560. package/src/wirings/cli/channel/index.ts +1 -3
  561. package/src/wirings/cli/cli-runner.test.ts +1 -1
  562. package/src/wirings/cli/cli-runner.ts +11 -7
  563. package/src/wirings/cli/cli.types.ts +24 -3
  564. package/src/wirings/cli/command-parser.test.ts +388 -1
  565. package/src/wirings/cli/command-parser.ts +189 -29
  566. package/src/wirings/gateway/gateway-runner.test.ts +1 -2
  567. package/src/wirings/gateway/gateway-runner.ts +3 -6
  568. package/src/wirings/gateway/gateway.types.ts +5 -4
  569. package/src/wirings/http/http-routes.test.ts +1 -2
  570. package/src/wirings/http/http-runner-addon-ref.test.ts +238 -0
  571. package/src/wirings/http/http-runner.test.ts +3 -8
  572. package/src/wirings/http/http-runner.ts +9 -3
  573. package/src/wirings/http/http.types.ts +3 -12
  574. package/src/wirings/http/index.ts +1 -0
  575. package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
  576. package/src/wirings/http/pikku-fetch-http-response.ts +3 -2
  577. package/src/wirings/mcp/mcp-runner.test.ts +1 -1
  578. package/src/wirings/mcp/mcp.types.ts +1 -2
  579. package/src/wirings/persona/index.ts +1 -4
  580. package/src/wirings/persona/persona.types.ts +14 -0
  581. package/src/wirings/queue/queue-identity.test.ts +1 -1
  582. package/src/wirings/queue/queue.types.ts +2 -6
  583. package/src/wirings/queue/signed-queue-service.ts +1 -1
  584. package/src/wirings/rpc/index.ts +0 -12
  585. package/src/wirings/rpc/rpc-runner.test.ts +4 -4
  586. package/src/wirings/rpc/rpc-runner.ts +5 -5
  587. package/src/wirings/rpc/rpc-types.ts +1 -1
  588. package/src/wirings/scheduler/scheduler.types.ts +2 -5
  589. package/src/wirings/scope/index.ts +1 -0
  590. package/src/wirings/secret/secret.types.ts +10 -0
  591. package/src/wirings/secret/validate-secret-definitions.test.ts +23 -0
  592. package/src/wirings/secret/validate-secret-definitions.ts +2 -0
  593. package/src/wirings/variable/validate-variable-definitions.test.ts +23 -0
  594. package/src/wirings/variable/validate-variable-definitions.ts +2 -0
  595. package/src/wirings/variable/variable.types.ts +9 -0
  596. package/src/wirings/virtual-user/index.ts +1 -4
  597. package/src/wirings/virtual-user/prepare-virtual-user-run.ts +2 -2
  598. package/src/wirings/virtual-user/run-virtual-user.test.ts +2 -2
  599. package/src/wirings/virtual-user/run-virtual-user.ts +3 -3
  600. package/src/wirings/virtual-user/virtual-user-agents.ts +1 -1
  601. package/src/wirings/virtual-user/virtual-user-derive.test.ts +1 -1
  602. package/src/wirings/virtual-user/virtual-user-derive.ts +1 -1
  603. package/src/wirings/virtual-user/virtual-user.types.ts +1 -5
  604. package/src/wirings/workflow/graph/graph-foreach-queued.test.ts +569 -0
  605. package/src/wirings/workflow/graph/graph-foreach.test.ts +626 -0
  606. package/src/wirings/workflow/graph/graph-node.ts +16 -1
  607. package/src/wirings/workflow/graph/graph-runner.ts +387 -61
  608. package/src/wirings/workflow/graph/workflow-graph.types.ts +28 -3
  609. package/src/wirings/workflow/index.ts +8 -0
  610. package/src/wirings/workflow/pikku-scenario-service.ts +59 -19
  611. package/src/wirings/workflow/pikku-workflow-service.ts +6 -8
  612. package/src/wirings/workflow/run-timeline.ts +2 -2
  613. package/src/wirings/workflow/scenario-expectations.test.ts +28 -13
  614. package/src/wirings/workflow/scenario-run.types.ts +186 -0
  615. package/src/wirings/workflow/scenario-step-guards.ts +1 -14
  616. package/src/wirings/workflow/scenario-step.test.ts +32 -7
  617. package/src/wirings/workflow/scenario-step.types.ts +27 -12
  618. package/src/wirings/workflow/workflow-approval-policy.test.ts +117 -47
  619. package/src/wirings/workflow/workflow-approval.ts +2 -1
  620. package/src/wirings/workflow/workflow-run-engine.types.ts +2 -1
  621. package/src/wirings/workflow/workflow.types.ts +4 -12
  622. package/src/wirings-stay-decoupled.test.ts +7 -4
  623. package/tsconfig.tsbuildinfo +1 -1
  624. package/tsconfig.type-tests.json +3 -2
  625. package/dist/testing/service-tests/ai-storage-service-tests.d.ts +0 -3
  626. package/dist/wirings/ai-agent/ai-agent-registry.d.ts +0 -16
  627. package/dist/wirings/ai-agent/ai-agent-runner.d.ts +0 -7
  628. package/dist/wirings/ai-agent/ai-agent-utils.d.ts +0 -1
  629. package/dist/wirings/ai-agent/ai-agent-utils.js +0 -1
  630. package/dist/wirings/ai-agent/index.d.ts +0 -12
  631. package/dist/wirings/ai-agent/index.js +0 -10
  632. package/dist/wirings/ai-scorer/ai-scorer-judge.d.ts +0 -17
  633. package/dist/wirings/ai-scorer/ai-scorer.types.js +0 -4
  634. package/dist/wirings/ai-scorer/index.d.ts +0 -6
  635. package/dist/wirings/ai-scorer/index.js +0 -5
  636. package/src/ecosystem.ts +0 -40
  637. package/src/index.ts +0 -255
  638. package/src/wirings/ai-agent/ai-agent-utils.ts +0 -1
  639. package/src/wirings/ai-agent/index.ts +0 -65
  640. package/src/wirings/ai-scorer/ai-scorer-judge.test.ts +0 -143
  641. package/src/wirings/ai-scorer/ai-scorer-judge.ts +0 -120
  642. package/src/wirings/ai-scorer/index.ts +0 -24
  643. /package/dist/{services/ai-agent-runner-service.js → bootstrap-compat/root.js} +0 -0
  644. /package/dist/{services/ai-run-state-service.js → classification/data-classification.js} +0 -0
  645. /package/dist/{services/ai-storage-service.js → ecosystem/gateway.js} +0 -0
  646. /package/dist/{wirings/ai-agent/ai-agent.types.js → ecosystem/node.js} +0 -0
  647. /package/dist/wirings/{ai-agent/ai-agent-helpers.js → agent/agent-helpers.js} +0 -0
  648. /package/dist/wirings/{ai-agent/ai-agent-model-config.d.ts → agent/agent-model-config.d.ts} +0 -0
  649. /package/dist/wirings/{ai-agent → agent}/agent-rpc.d.ts +0 -0
  650. /package/dist/wirings/{ai-scorer/ai-scorer-sampling.d.ts → agent-scorer/agent-scorer-sampling.d.ts} +0 -0
  651. /package/dist/wirings/{ai-scorer/ai-scorer-sampling.js → agent-scorer/agent-scorer-sampling.js} +0 -0
  652. /package/dist/wirings/{ai-scorer/ai-scorer-snapshots.js → agent-scorer/agent-scorer-snapshots.js} +0 -0
  653. /package/src/{column-form.ts → classification/column-form.ts} +0 -0
  654. /package/src/{pikku-request.test.ts → function/pikku-request.test.ts} +0 -0
  655. /package/src/{pikku-request.ts → function/pikku-request.ts} +0 -0
  656. /package/src/wirings/{rpc → addon}/addon-auth-tags.test.ts +0 -0
  657. /package/src/wirings/{rpc → addon}/addon-runner.ts +0 -0
  658. /package/src/wirings/{rpc → addon}/addon-secrets.test.ts +0 -0
  659. /package/src/wirings/{rpc → addon}/wire-addon.test.ts +0 -0
  660. /package/src/wirings/{rpc → addon}/wire-remote-addon.ts +0 -0
  661. /package/src/wirings/{ai-scorer/ai-scorer-sampling.ts → agent-scorer/agent-scorer-sampling.ts} +0 -0
@@ -36,10 +36,31 @@ import type {
36
36
  WorkflowExpectErrorOptions,
37
37
  WorkflowExpectScoreOptions,
38
38
  WorkflowExpectServiceOptions,
39
+ WorkflowStepOptions,
39
40
  } from './dsl/workflow-dsl.types.js'
40
41
 
42
+ /**
43
+ * The retry default for the `expect*` family: none, the same as `given`,
44
+ * `when` and `then` take, and for the same reason — a failed assertion is a
45
+ * result, not a transient fault.
46
+ *
47
+ * Left to the workflow-wide `DEFAULT_STEP_RETRIES` they get six attempts each,
48
+ * which re-runs the RPC behind a failing `expectError`, restarts a whole
49
+ * `expectEventually` poll after it has already spent its own deadline, and
50
+ * lets a live judge re-roll a grade until one lands inside the band. The last
51
+ * of those is how it was found: a judge scored a deliberately useless answer
52
+ * 1, and the scenario went green anyway on the next attempt.
53
+ *
54
+ * A caller that genuinely wants attempts still asks for them.
55
+ */
56
+ const assertionStep = <T extends WorkflowStepOptions>(
57
+ options?: T
58
+ ): T & { retries: number } =>
59
+ ({ ...options, retries: options?.retries ?? 0 }) as T & { retries: number }
60
+
41
61
  export { addFeature, resolveFeatureScenarios } from './feature.js'
42
62
  export type * from './scenario.types.js'
63
+ export type * from './scenario-run.types.js'
43
64
  export { SCENARIO_SURFACES } from './scenario-step.types.js'
44
65
 
45
66
  // Which of a step's bindings run: one for an action, every witness for a `then`
@@ -50,7 +71,7 @@ export { createCookieJar } from './scenario-cookie-jar.js'
50
71
  export type { ScenarioCookieJar } from './scenario-cookie-jar.js'
51
72
  export { composeStepProse, renderStepTemplate } from './scenario-prose.js'
52
73
 
53
- export { requireActor, requireScenarioEnv } from './scenario-step-guards.js'
74
+ export { requireScenarioEnv } from './scenario-step-guards.js'
54
75
 
55
76
  export type {
56
77
  ScenarioHttpResponse,
@@ -171,20 +192,24 @@ addError(ScenarioBrowserUnavailable, {
171
192
  })
172
193
 
173
194
  /**
174
- * A browser binding was reached without an actor, so there is no persona whose
175
- * window it would run in.
195
+ * A step that is driven by a persona was dispatched without one.
196
+ *
197
+ * Raised before the body runs rather than partway through it: the step declared
198
+ * that it needs an actor — by having a `browser` binding, which cannot be
199
+ * provisioned without a window to open, or by `actor: true` — so a call site
200
+ * that omits one is a mistake at the call site.
176
201
  */
177
- export class ScenarioBrowserActorRequired extends PikkuError {
202
+ export class ScenarioActorRequired extends PikkuError {
178
203
  constructor(public readonly stepFunc: string) {
179
204
  super(
180
- `[scenario] step '${stepFunc}' resolved to its browser binding but was called without an actor. ` +
181
- `Pass { actor: actors.<name> } so the browser signs in as that persona.`
205
+ `[scenario] step '${stepFunc}' is driven by a persona but was called without an actor. ` +
206
+ `Pass { actor: actors.<name> } so it runs as that persona.`
182
207
  )
183
208
  }
184
209
  }
185
- addError(ScenarioBrowserActorRequired, {
210
+ addError(ScenarioActorRequired, {
186
211
  status: 500,
187
- message: 'A browser binding needs an actor.',
212
+ message: 'This step needs an actor.',
188
213
  })
189
214
 
190
215
  /**
@@ -480,8 +505,7 @@ export class PikkuScenarioService implements WorkflowRunExtension {
480
505
  let wireServices: Record<string, unknown> | undefined
481
506
  try {
482
507
  wireServices = (await createWireServices?.(singletonServices, wire)) as
483
- | Record<string, unknown>
484
- | undefined
508
+ Record<string, unknown> | undefined
485
509
  const services =
486
510
  wireServices && Object.keys(wireServices).length > 0
487
511
  ? { ...singletonServices, ...wireServices }
@@ -602,7 +626,7 @@ export class PikkuScenarioService implements WorkflowRunExtension {
602
626
  await new Promise((resolve) => setTimeout(resolve, interval))
603
627
  }
604
628
  },
605
- options
629
+ assertionStep(options)
606
630
  )
607
631
  },
608
632
 
@@ -645,7 +669,7 @@ export class PikkuScenarioService implements WorkflowRunExtension {
645
669
  `[workflow] expectError '${stepName}' ('${resolvedRpcName}') expected an error but the call succeeded: ${JSON.stringify(result)?.slice(0, 300)}`
646
670
  )
647
671
  },
648
- options
672
+ assertionStep(options)
649
673
  )
650
674
  },
651
675
 
@@ -700,7 +724,7 @@ export class PikkuScenarioService implements WorkflowRunExtension {
700
724
  )
701
725
  }
702
726
  },
703
- options
727
+ assertionStep(options)
704
728
  )
705
729
  },
706
730
 
@@ -745,7 +769,7 @@ export class PikkuScenarioService implements WorkflowRunExtension {
745
769
  }
746
770
  return grade
747
771
  },
748
- options
772
+ assertionStep(options)
749
773
  )
750
774
  },
751
775
 
@@ -814,6 +838,10 @@ export class PikkuScenarioService implements WorkflowRunExtension {
814
838
  this.scenarioStepDescription(packageName, resolvedStepFunc) ??
815
839
  stepName
816
840
 
841
+ if (!actor && this.requiresActor(packageName, resolvedStepFunc)) {
842
+ throw new ScenarioActorRequired(resolvedStepFunc)
843
+ }
844
+
817
845
  const declared = this.declaredSurfaces(packageName, resolvedStepFunc)
818
846
  const resolution = resolveScenarioSurfaces(phase, declared, this.runSurface)
819
847
 
@@ -828,13 +856,13 @@ export class PikkuScenarioService implements WorkflowRunExtension {
828
856
  scenario: workflowWire,
829
857
  pikkuUserId: workflowWire.pikkuUserId,
830
858
  actors: this.runActors.get(runId),
859
+ ...(actor ? { actor } : {}),
831
860
  scenarioStep: {
832
861
  name: resolvedStepFunc,
833
862
  stepName,
834
863
  runId,
835
864
  phase,
836
865
  surface,
837
- actor,
838
866
  env: this.scenarioEnvironment,
839
867
  },
840
868
  }
@@ -842,11 +870,10 @@ export class PikkuScenarioService implements WorkflowRunExtension {
842
870
  if (!this.scenarioBrowserProvider) {
843
871
  throw new ScenarioBrowserUnavailable(resolvedStepFunc)
844
872
  }
845
- if (!actor) {
846
- throw new ScenarioBrowserActorRequired(resolvedStepFunc)
847
- }
873
+ // The dispatch guard above already refused an actor-less call, and a
874
+ // browser binding always requires one.
848
875
  wire.browser = await this.scenarioBrowserProvider.sessionFor(
849
- actor.name
876
+ actor!.name
850
877
  )
851
878
  }
852
879
  return await runPikkuFunc(
@@ -947,4 +974,17 @@ export class PikkuScenarioService implements WorkflowRunExtension {
947
974
  const surfaces = this.scenarioStepConfig(packageName, stepFunc)?.surfaces
948
975
  return surfaces?.length ? surfaces : ['default']
949
976
  }
977
+
978
+ /**
979
+ * Whether a step is driven by a persona, and so must be given one. Stamped by
980
+ * the definer from a `browser` binding or an explicit `actor: true`.
981
+ */
982
+ private requiresActor(
983
+ packageName: string | null,
984
+ stepFunc: string
985
+ ): boolean {
986
+ return (
987
+ this.scenarioStepConfig(packageName, stepFunc)?.requiresActor === true
988
+ )
989
+ }
950
990
  }
@@ -5,11 +5,8 @@ import {
5
5
  pikkuState,
6
6
  } from '../../pikku-state.js'
7
7
  import { getDurationInMilliseconds } from '../../time-utils.js'
8
- import type {
9
- CoreUserSession,
10
- PikkuRawWire,
11
- SerializedError,
12
- } from '../../types/core.types.js'
8
+ import type { CoreUserSession, PikkuRawWire } from '../../types/core.types.js'
9
+ import type { SerializedError } from '../../errors/serialized-error.js'
13
10
  import type {
14
11
  GroupConcurrencyConfig,
15
12
  JobGroup,
@@ -39,6 +36,7 @@ import {
39
36
  executeGraphStep,
40
37
  runWorkflowGraph,
41
38
  runFromMeta,
39
+ stripInstanceOrdinal,
42
40
  } from './graph/graph-runner.js'
43
41
  import type { WorkflowService } from '../../services/workflow-service.js'
44
42
  import type { ScenarioPersonas } from '../../services/personas-service.js'
@@ -1352,9 +1350,9 @@ export abstract class PikkuWorkflowService implements WorkflowService {
1352
1350
  if (stepName in workflowMeta.nodes) {
1353
1351
  graphNodeId = stepName
1354
1352
  } else {
1355
- const hash = stepName.lastIndexOf('#')
1356
- const base = hash > 0 ? stepName.slice(0, hash) : undefined
1357
- if (base && base in workflowMeta.nodes) graphNodeId = base
1353
+ const base = stripInstanceOrdinal(stepName)
1354
+ if (base !== stepName && base in workflowMeta.nodes)
1355
+ graphNodeId = base
1358
1356
  }
1359
1357
  }
1360
1358
  if (graphNodeId) {
@@ -1,4 +1,4 @@
1
- import type { SerializedError } from '../../types/core.types.js'
1
+ import type { SerializedError } from '../../errors/serialized-error.js'
2
2
  import type { StepState, StepStatus } from './workflow.types.js'
3
3
 
4
4
  export interface RunTimelineEvent {
@@ -17,7 +17,7 @@ export interface RunTimelineEvent {
17
17
 
18
18
  export type RunTimeline = RunTimelineEvent[]
19
19
 
20
- type HistoryEntry = StepState & { stepName: string }
20
+ export type HistoryEntry = StepState & { stepName: string }
21
21
 
22
22
  const LIFECYCLE_ORDER: Record<RunTimelineEvent['type'], number> = {
23
23
  pending: 0,
@@ -65,7 +65,7 @@ describe('workflow.expectError', () => {
65
65
  })
66
66
 
67
67
  await assert.rejects(
68
- wire.expectError('should have failed', 'deleteTodo', {}, { retries: 0 }),
68
+ wire.expectError('should have failed', 'deleteTodo', {}),
69
69
  /expected an error but the call succeeded/
70
70
  )
71
71
  })
@@ -82,7 +82,7 @@ describe('workflow.expectError', () => {
82
82
  'wrong reason',
83
83
  'deleteTodo',
84
84
  {},
85
- { matches: /Forbidden/, retries: 0 }
85
+ { matches: /Forbidden/ }
86
86
  ),
87
87
  /did not match .*database offline/
88
88
  )
@@ -114,10 +114,7 @@ describe('workflow.expectService', () => {
114
114
  const { wire } = await scenarioWire(oneEmail())
115
115
 
116
116
  await assert.rejects(
117
- wire.expectService('two emails', 'email.send', {
118
- times: 2,
119
- retries: 0,
120
- }),
117
+ wire.expectService('two emails', 'email.send', { times: 2 }),
121
118
  /expected 2 call\(s\).*found 1.*email\.send/s
122
119
  )
123
120
  })
@@ -131,7 +128,6 @@ describe('workflow.expectService', () => {
131
128
  await assert.rejects(
132
129
  wire.expectService('emailed someone else', 'email.send', {
133
130
  calledWith: { to: 'x@y.z' },
134
- retries: 0,
135
131
  }),
136
132
  /found 0/
137
133
  )
@@ -172,7 +168,7 @@ describe('workflow.expectScore', () => {
172
168
  const { wire } = await scenarioWire(grades({ score: 0 }))
173
169
 
174
170
  await assert.rejects(
175
- wire.expectScore('was brief', 'run-1', 'brevity', { retries: 0 }),
171
+ wire.expectScore('was brief', 'run-1', 'brevity'),
176
172
  /expected 'brevity' to grade run run-1 at least 0\.5, got 0/
177
173
  )
178
174
  })
@@ -183,10 +179,7 @@ describe('workflow.expectScore', () => {
183
179
  )
184
180
 
185
181
  await assert.rejects(
186
- wire.expectScore('was brief', 'run-1', 'brevity', {
187
- atLeast: 0.8,
188
- retries: 0,
189
- }),
182
+ wire.expectScore('was brief', 'run-1', 'brevity', { atLeast: 0.8 }),
190
183
  /It rambled for four paragraphs/
191
184
  )
192
185
  })
@@ -198,12 +191,34 @@ describe('workflow.expectScore', () => {
198
191
  wire.expectScore('was not sycophantic', 'run-1', 'sycophancy', {
199
192
  atLeast: 0,
200
193
  atMost: 0.3,
201
- retries: 0,
202
194
  }),
203
195
  /between 0 and 0\.3, got 0\.95/
204
196
  )
205
197
  })
206
198
 
199
+ test('a grade that misses the bound is not re-rolled until it lands', async () => {
200
+ let graded = 0
201
+ const { wire } = await scenarioWire({
202
+ rpcWithWire: async () => {
203
+ graded += 1
204
+ return { score: 1 }
205
+ },
206
+ })
207
+
208
+ await assert.rejects(
209
+ wire.expectScore('was not sycophantic', 'run-1', 'sycophancy', {
210
+ atLeast: 0,
211
+ atMost: 0.3,
212
+ }),
213
+ /got 1/
214
+ )
215
+
216
+ // The whole point of a judge is that it is not deterministic. Six attempts
217
+ // at it is six chances for one to land inside the band, which grades the
218
+ // sampling rather than the run.
219
+ assert.equal(graded, 1)
220
+ })
221
+
207
222
  test('a reference answer reaches the grader', async () => {
208
223
  let seen: any
209
224
  const { wire } = await scenarioWire({
@@ -0,0 +1,186 @@
1
+ /**
2
+ * What one `pikku scenario run` leaves behind.
3
+ *
4
+ * A run is history: the scenarios it selected, the sentences they were made of,
5
+ * and the images and footage they produced. The sentences are snapshotted into
6
+ * the record rather than looked up later, because a scenario is code and the
7
+ * code moves — a run from last week describes a suite that no longer exists,
8
+ * and re-deriving its ladder from today's source would quietly rewrite it.
9
+ *
10
+ * Everything here is plain serialisable data. That is what lets one record be
11
+ * a JSON file on disk in OSS and a row in Postgres on a hosted project, read
12
+ * back by the same console screen either way.
13
+ */
14
+ import type { ScenarioBrowserFailure } from './scenario-step.types.js'
15
+
16
+ /** What a run filed, in the order it filed it. */
17
+ export type ScenarioArtifactKind = 'screenshot' | 'failure' | 'video'
18
+
19
+ /**
20
+ * One image or recording a scenario produced.
21
+ *
22
+ * `path` is relative to the run's artifact root and always uses forward
23
+ * slashes: it is a content key, not a filesystem path. Locally it resolves
24
+ * under the run's directory; on a hosted project it is the object key in a
25
+ * bucket, and the same record works unchanged.
26
+ */
27
+ export interface ScenarioArtifact {
28
+ /** The scenario label this belongs to, as the report names it. */
29
+ scenario: string
30
+ kind: ScenarioArtifactKind
31
+ path: string
32
+ /** Whose window it was — a two-actor scenario produces two of everything. */
33
+ actor?: string
34
+ /** The caption the scenario author took a screenshot under. */
35
+ name?: string
36
+ }
37
+
38
+ /** One step of a run, already joined to the prose that declared it. */
39
+ export interface ScenarioStepRow {
40
+ sentence: string
41
+ status: string
42
+ durationMs?: number
43
+ error?: string
44
+ }
45
+
46
+ /** Everything known about why one scenario failed. */
47
+ export interface ScenarioFailureDetail {
48
+ /** The rendered sentence of the failing step; absent if no step failed. */
49
+ sentence?: string
50
+ message: string
51
+ stack?: string
52
+ /**
53
+ * True when the failure was a deliberate one (a PikkuError). Its message is
54
+ * the whole story, so the stack is noise.
55
+ */
56
+ expected?: boolean
57
+ browser?: ScenarioBrowserFailure[]
58
+ }
59
+
60
+ export interface ScenarioResult {
61
+ name: string
62
+ status: 'passed' | 'failed'
63
+ durationMs: number
64
+ output?: unknown
65
+ error?: string
66
+ steps?: ScenarioStepRow[]
67
+ failure?: ScenarioFailureDetail
68
+ /** The scenario registration this ran, which the label alone does not give. */
69
+ scenarioName?: string
70
+ /** The feature that grouped it, when one did. */
71
+ feature?: string
72
+ tags?: string[]
73
+ /** Images and footage this scenario produced, filed under the run. */
74
+ artifacts?: ScenarioArtifact[]
75
+ }
76
+
77
+ /** One scenario that was not run, and why. */
78
+ export interface ScenarioSkip {
79
+ name: string
80
+ reason: string
81
+ }
82
+
83
+ export interface ScenarioRunReport {
84
+ environment: string
85
+ results: ScenarioResult[]
86
+ /**
87
+ * Scenarios not run at all, each carrying why. A skip is only useful if the
88
+ * reader can tell a browser scenario held back by `--no-browser` from one the
89
+ * project itself quarantined, so the reason travels with the name rather than
90
+ * being assumed by the formatter.
91
+ */
92
+ skipped: ScenarioSkip[]
93
+ /** Feature-level hook failures, which belong to no single scenario. */
94
+ hookFailures: string[]
95
+ }
96
+
97
+ export type ScenarioRunStatus = 'running' | 'passed' | 'failed'
98
+
99
+ /**
100
+ * A whole run, as it is stored and read back.
101
+ *
102
+ * `status` is `running` from the moment the run is created until it finishes,
103
+ * so a console watching a run in progress can tell "still going" from "nothing
104
+ * came back" — and a run killed halfway stays `running` forever, which is the
105
+ * honest record of what happened to it.
106
+ */
107
+ export interface ScenarioRunRecord extends ScenarioRunReport {
108
+ runId: string
109
+ status: ScenarioRunStatus
110
+ /** The surface the run targeted: `default`, `browser`, … */
111
+ surface: string
112
+ startedAt: string
113
+ finishedAt?: string
114
+ }
115
+
116
+ /** Enough of a run to list it without loading its steps and stacks. */
117
+ export interface ScenarioRunSummary {
118
+ runId: string
119
+ environment: string
120
+ surface: string
121
+ status: ScenarioRunStatus
122
+ startedAt: string
123
+ finishedAt?: string
124
+ durationMs?: number
125
+ passed: number
126
+ failed: number
127
+ skipped: number
128
+ /** Whether anything is there to watch, so a list can say so without a second read. */
129
+ artifacts: number
130
+ }
131
+
132
+ /**
133
+ * Where runs are kept.
134
+ *
135
+ * Deliberately not the workflow service: a scenario run is a workflow run under
136
+ * the hood, but its history has a different lifetime, a different audience, and
137
+ * a different home — a JSON file beside the project locally, a project-scoped
138
+ * table and an object store when hosted.
139
+ *
140
+ * Written progressively rather than at the end, so a suite that dies on its
141
+ * fortieth scenario still leaves the thirty-nine behind.
142
+ */
143
+ export interface ScenarioRunStore {
144
+ /** Open a run. Called before the first scenario, with `status: 'running'`. */
145
+ start(record: ScenarioRunRecord): Promise<void>
146
+ /** Append one finished scenario to an open run. */
147
+ recordScenario(runId: string, result: ScenarioResult): Promise<void>
148
+ /**
149
+ * File the run's artifacts against the scenarios that produced them.
150
+ *
151
+ * Separate from `recordScenario` because a scenario's video does not exist
152
+ * when the scenario ends — it is finalised by the next scenario's reset, and
153
+ * renamed again when the run closes. Artifacts are matched to a result by the
154
+ * label the report knows it under.
155
+ */
156
+ attachArtifacts(runId: string, artifacts: ScenarioArtifact[]): Promise<void>
157
+ /** Close a run, settling everything only known once every scenario has run. */
158
+ finish(
159
+ runId: string,
160
+ outcome: Pick<
161
+ ScenarioRunRecord,
162
+ 'status' | 'finishedAt' | 'skipped' | 'hookFailures'
163
+ >
164
+ ): Promise<void>
165
+ /**
166
+ * The bytes of one artifact, by the `path` its record carries.
167
+ *
168
+ * Reading goes through the store because only the store knows where a run's
169
+ * files actually are — a directory beside the project, or an object store
170
+ * behind a bucket. Absent when the run or the path is unknown, which is also
171
+ * the answer for a path that tries to leave the run.
172
+ *
173
+ * The bytes are backed by their own `ArrayBuffer` so they can be handed
174
+ * straight to a `Response` — a view onto a pooled or shared buffer is not a
175
+ * valid body.
176
+ */
177
+ readArtifact(
178
+ runId: string,
179
+ path: string
180
+ ): Promise<{ body: Uint8Array<ArrayBuffer>; contentType: string } | undefined>
181
+ /** Most recent first. */
182
+ list(options?: { limit?: number }): Promise<ScenarioRunSummary[]>
183
+ get(runId: string): Promise<ScenarioRunRecord | undefined>
184
+ /** Forget a run and everything it filed. */
185
+ remove(runId: string): Promise<void>
186
+ }
@@ -3,21 +3,8 @@ import type {
3
3
  ScenarioEnvironment,
4
4
  } from './scenario-step.types.js'
5
5
 
6
- export const requireActor = <TActor>(
7
- scenarioStep: PikkuScenarioStepWire<TActor> | undefined
8
- ): TActor => {
9
- const actor = scenarioStep?.actor
10
- if (!actor) {
11
- throw new Error(
12
- `[scenario] step '${scenarioStep?.name ?? 'unknown'}' was called without an actor. ` +
13
- `Pass { actor: actors.<name> } so it runs as that persona.`
14
- )
15
- }
16
- return actor
17
- }
18
-
19
6
  export const requireScenarioEnv = (
20
- scenarioStep: PikkuScenarioStepWire<unknown> | undefined
7
+ scenarioStep: PikkuScenarioStepWire | undefined
21
8
  ): ScenarioEnvironment => {
22
9
  const env = scenarioStep?.env
23
10
  if (!env) {
@@ -8,7 +8,7 @@ import { addFunction } from '../../function/function-runner.js'
8
8
  import type { ScenarioPersona } from '../../services/personas-service.js'
9
9
  import type { PikkuWire } from '../../types/core.types.js'
10
10
  import type { ScenarioSurface } from './scenario-step.types.js'
11
- import { requireActor, requireScenarioEnv } from './scenario-step-guards.js'
11
+ import { requireScenarioEnv } from './scenario-step-guards.js'
12
12
 
13
13
  const noopLogger = { error() {}, info() {}, warn() {}, debug() {} }
14
14
 
@@ -145,6 +145,7 @@ const registerStep = (
145
145
  config: {
146
146
  description?: string
147
147
  surfaces?: ScenarioSurface[]
148
+ requiresActor?: boolean
148
149
  func: (services: any, data: any, wire: PikkuWire) => Promise<unknown>
149
150
  }
150
151
  ) => {
@@ -215,7 +216,7 @@ describe('pikkuScenarioStep (scenario.given/when/then)', () => {
215
216
  let received: unknown
216
217
  registerStep('checksOut', {
217
218
  func: async (_services, _data, wire) => {
218
- received = wire.scenarioStep!.actor
219
+ received = wire.actor
219
220
  return null
220
221
  },
221
222
  })
@@ -712,16 +713,17 @@ describe('the scenario environment reaches the step wire', () => {
712
713
  })
713
714
  })
714
715
 
715
- describe('requireActor / requireScenarioEnv', () => {
716
+ describe('a step driven by a persona is given its actor', () => {
716
717
  beforeEach(() => resetPikkuState())
717
718
 
718
- test('requireActor returns the actor a step was called with', async () => {
719
+ test('the actor is on the wire, not something the body unwraps', async () => {
719
720
  const { workflowService: ws, scenarioService } = createScenarioRunner()
720
721
  const shopper = fakeActor('shopper', async () => null)
721
722
  let resolved: unknown
722
723
  registerStep('needsAnActor', {
724
+ requiresActor: true,
723
725
  func: async (_services, _data, wire) => {
724
- resolved = requireActor(wire.scenarioStep)
726
+ resolved = wire.actor
725
727
  return null
726
728
  },
727
729
  })
@@ -735,10 +737,15 @@ describe('requireActor / requireScenarioEnv', () => {
735
737
  assert.equal(resolved, shopper)
736
738
  })
737
739
 
738
- test('requireActor names the step when it was called without one', async () => {
740
+ test('one dispatched without an actor is refused before its body runs', async () => {
739
741
  const { workflowService: ws, scenarioService } = createScenarioRunner()
742
+ let bodyRan = false
740
743
  registerStep('needsAnActor', {
741
- func: async (_services, _data, wire) => requireActor(wire.scenarioStep),
744
+ requiresActor: true,
745
+ func: async () => {
746
+ bodyRan = true
747
+ return null
748
+ },
742
749
  })
743
750
 
744
751
  const runId = await setup(ws)
@@ -747,6 +754,24 @@ describe('requireActor / requireScenarioEnv', () => {
747
754
  wire.when('nobody acts', 'needsAnActor'),
748
755
  /needsAnActor.*actor/s
749
756
  )
757
+ assert.equal(bodyRan, false)
758
+ })
759
+
760
+ test('a step that declares no persona runs without one', async () => {
761
+ const { workflowService: ws, scenarioService } = createScenarioRunner()
762
+ let seen: unknown = 'unset'
763
+ registerStep('assertsSomething', {
764
+ func: async (_services, _data, wire) => {
765
+ seen = wire.actor
766
+ return null
767
+ },
768
+ })
769
+
770
+ const runId = await setup(ws)
771
+ const wire = ws.createWorkflowWire('scenarioTest', runId, {})
772
+ await wire.then('it holds', 'assertsSomething')
773
+
774
+ assert.equal(seen, undefined)
750
775
  })
751
776
 
752
777
  test('requireScenarioEnv returns the environment, or says how to declare one', async () => {