@pikku/core 0.12.72 → 0.12.77

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 (848) hide show
  1. package/CHANGELOG.md +1171 -0
  2. package/dist/column-form.d.ts +32 -0
  3. package/dist/column-form.js +42 -0
  4. package/dist/crypto-utils.d.ts +43 -7
  5. package/dist/crypto-utils.js +163 -42
  6. package/dist/data-classification.d.ts +44 -0
  7. package/dist/dev/hot-reload.js +11 -30
  8. package/dist/dev/module-runner.d.ts +3 -7
  9. package/dist/dev/module-runner.js +4 -10
  10. package/dist/dev/reload-meta.d.ts +8 -20
  11. package/dist/dev/reload-meta.js +9 -29
  12. package/dist/errors/error-handler.d.ts +5 -30
  13. package/dist/errors/error-handler.js +16 -32
  14. package/dist/errors/errors.d.ts +32 -151
  15. package/dist/errors/errors.js +55 -157
  16. package/dist/function/abort-scope.d.ts +47 -0
  17. package/dist/function/abort-scope.js +63 -0
  18. package/dist/function/function-runner.js +37 -32
  19. package/dist/function/functions.types.d.ts +57 -136
  20. package/dist/function/functions.types.js +0 -58
  21. package/dist/function/index.d.ts +1 -1
  22. package/dist/function/list.types.d.ts +12 -62
  23. package/dist/function/list.types.js +4 -25
  24. package/dist/handle-error.d.ts +0 -13
  25. package/dist/handle-error.js +0 -18
  26. package/dist/index.d.ts +11 -5
  27. package/dist/index.js +7 -2
  28. package/dist/middleware/auth-apikey.d.ts +3 -18
  29. package/dist/middleware/auth-apikey.js +0 -17
  30. package/dist/middleware/auth-bearer.d.ts +6 -41
  31. package/dist/middleware/auth-bearer.js +5 -41
  32. package/dist/middleware/auth-cookie.d.ts +5 -27
  33. package/dist/middleware/auth-cookie.js +2 -26
  34. package/dist/middleware/cors.d.ts +7 -34
  35. package/dist/middleware/cors.js +7 -34
  36. package/dist/middleware/remote-auth.d.ts +3 -1
  37. package/dist/middleware/remote-auth.js +4 -3
  38. package/dist/middleware/telemetry.d.ts +8 -33
  39. package/dist/middleware/telemetry.js +2 -31
  40. package/dist/middleware-runner.d.ts +4 -55
  41. package/dist/middleware-runner.js +5 -74
  42. package/dist/permissions.d.ts +3 -44
  43. package/dist/permissions.js +19 -71
  44. package/dist/pikku-request.d.ts +0 -6
  45. package/dist/pikku-request.js +0 -6
  46. package/dist/pikku-state.d.ts +0 -26
  47. package/dist/pikku-state.js +2 -30
  48. package/dist/remote.d.ts +3 -5
  49. package/dist/remote.js +9 -8
  50. package/dist/schema.d.ts +5 -39
  51. package/dist/schema.js +5 -39
  52. package/dist/scopes.d.ts +4 -23
  53. package/dist/scopes.js +7 -48
  54. package/dist/secret-value.d.ts +56 -0
  55. package/dist/secret-value.js +46 -0
  56. package/dist/services/ai-agent-runner-service.d.ts +20 -0
  57. package/dist/services/ai-embedding-service.d.ts +2 -25
  58. package/dist/services/audit-service.d.ts +74 -4
  59. package/dist/services/audit-service.js +8 -7
  60. package/dist/services/content-service.d.ts +1 -46
  61. package/dist/services/credential-service.d.ts +3 -40
  62. package/dist/services/credential-wire-service.d.ts +5 -0
  63. package/dist/services/credential-wire-service.js +9 -1
  64. package/dist/services/deployment-service.d.ts +3 -9
  65. package/dist/services/email-service.d.ts +2 -1
  66. package/dist/services/gateway-service.d.ts +0 -15
  67. package/dist/services/http-personas.d.ts +80 -0
  68. package/dist/services/http-personas.js +233 -0
  69. package/dist/services/in-memory-queue-service.d.ts +0 -14
  70. package/dist/services/in-memory-queue-service.js +1 -15
  71. package/dist/services/in-memory-trigger-service.d.ts +0 -18
  72. package/dist/services/in-memory-trigger-service.js +1 -18
  73. package/dist/services/in-memory-workflow-service.d.ts +0 -16
  74. package/dist/services/in-memory-workflow-service.js +4 -33
  75. package/dist/services/index.d.ts +8 -9
  76. package/dist/services/index.js +3 -6
  77. package/dist/services/istanbul-coverage-service.d.ts +1 -5
  78. package/dist/services/istanbul-coverage-service.js +2 -8
  79. package/dist/services/jwt-service.d.ts +1 -16
  80. package/dist/services/local-content-request-handler.d.ts +29 -0
  81. package/dist/services/local-content-request-handler.js +176 -0
  82. package/dist/services/local-content.d.ts +13 -2
  83. package/dist/services/local-content.js +40 -13
  84. package/dist/services/local-gateway-service.d.ts +0 -16
  85. package/dist/services/local-gateway-service.js +2 -17
  86. package/dist/services/local-secrets.d.ts +4 -7
  87. package/dist/services/local-secrets.js +7 -7
  88. package/dist/services/logger-console.d.ts +3 -7
  89. package/dist/services/logger-console.js +3 -7
  90. package/dist/services/logger.d.ts +22 -40
  91. package/dist/services/meta-service.d.ts +23 -26
  92. package/dist/services/meta-service.js +22 -36
  93. package/dist/services/personas-service.d.ts +134 -0
  94. package/dist/services/personas-service.js +40 -0
  95. package/dist/services/pikku-user-id.js +0 -4
  96. package/dist/services/queue-webhook-service.d.ts +2 -36
  97. package/dist/services/queue-webhook-service.js +10 -42
  98. package/dist/services/scheduler-service.d.ts +1 -50
  99. package/dist/services/scheduler-service.js +0 -10
  100. package/dist/services/schema-service.d.ts +1 -24
  101. package/dist/services/scope-service.d.ts +49 -34
  102. package/dist/services/scoped-secret-service.d.ts +4 -7
  103. package/dist/services/scoped-secret-service.js +0 -4
  104. package/dist/services/secret-host-binding.d.ts +8 -0
  105. package/dist/services/secret-host-binding.js +36 -0
  106. package/dist/services/secret-service.d.ts +12 -35
  107. package/dist/services/secretless.d.ts +6 -0
  108. package/dist/services/secretless.js +21 -0
  109. package/dist/services/stub-tracker.d.ts +7 -18
  110. package/dist/services/stub-tracker.js +8 -18
  111. package/dist/services/system-role-guard.d.ts +33 -0
  112. package/dist/services/system-role-guard.js +38 -0
  113. package/dist/services/trigger-service.d.ts +0 -12
  114. package/dist/services/typed-secret-service.d.ts +5 -11
  115. package/dist/services/typed-secret-service.js +1 -7
  116. package/dist/services/v8-coverage-service.d.ts +2 -3
  117. package/dist/services/v8-coverage-service.js +1 -2
  118. package/dist/services/variables-service.d.ts +1 -8
  119. package/dist/services/webhook-service.d.ts +21 -64
  120. package/dist/services/webhook-service.js +6 -20
  121. package/dist/services/workflow-service.d.ts +3 -15
  122. package/dist/testing/service-tests.js +6 -23
  123. package/dist/time-utils.d.ts +0 -16
  124. package/dist/time-utils.js +1 -19
  125. package/dist/types/core.types.d.ts +120 -219
  126. package/dist/types/core.types.js +0 -42
  127. package/dist/types/state.types.d.ts +4 -9
  128. package/dist/utils/hmac.d.ts +4 -10
  129. package/dist/utils/hmac.js +4 -10
  130. package/dist/utils/safe-fetch.d.ts +7 -35
  131. package/dist/utils/safe-fetch.js +13 -53
  132. package/dist/utils.d.ts +1 -6
  133. package/dist/utils.js +6 -15
  134. package/dist/wirings/actor-flow/actor-flow.types.d.ts +1 -34
  135. package/dist/wirings/actor-flow/index.d.ts +0 -9
  136. package/dist/wirings/actor-flow/run-conversation.d.ts +5 -5
  137. package/dist/wirings/actor-flow/run-conversation.js +14 -7
  138. package/dist/wirings/ai-agent/ai-agent-agui.d.ts +0 -5
  139. package/dist/wirings/ai-agent/ai-agent-agui.js +46 -12
  140. package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +7 -0
  141. package/dist/wirings/ai-agent/ai-agent-helpers.js +7 -0
  142. package/dist/wirings/ai-agent/ai-agent-interrupt.d.ts +153 -0
  143. package/dist/wirings/ai-agent/ai-agent-interrupt.js +256 -0
  144. package/dist/wirings/ai-agent/ai-agent-memory.js +0 -2
  145. package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +0 -9
  146. package/dist/wirings/ai-agent/ai-agent-model-config.js +1 -9
  147. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +10 -99
  148. package/dist/wirings/ai-agent/ai-agent-prepare.js +65 -132
  149. package/dist/wirings/ai-agent/ai-agent-registry.d.ts +2 -1
  150. package/dist/wirings/ai-agent/ai-agent-registry.js +5 -1
  151. package/dist/wirings/ai-agent/ai-agent-runner.js +63 -22
  152. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +25 -2
  153. package/dist/wirings/ai-agent/ai-agent-stream.js +180 -64
  154. package/dist/wirings/ai-agent/ai-agent.types.d.ts +124 -4
  155. package/dist/wirings/ai-agent/index.d.ts +6 -4
  156. package/dist/wirings/ai-agent/index.js +5 -4
  157. package/dist/wirings/ai-agent/voice-input.d.ts +59 -1
  158. package/dist/wirings/ai-agent/voice-input.js +90 -12
  159. package/dist/wirings/ai-agent/voice-output.d.ts +69 -1
  160. package/dist/wirings/ai-agent/voice-output.js +162 -50
  161. package/dist/wirings/channel/channel-common.d.ts +7 -20
  162. package/dist/wirings/channel/channel-common.js +7 -21
  163. package/dist/wirings/channel/channel-handler.js +25 -6
  164. package/dist/wirings/channel/channel-host-rpc.d.ts +25 -0
  165. package/dist/wirings/channel/channel-host-rpc.js +38 -0
  166. package/dist/wirings/channel/channel-middleware-runner.d.ts +0 -12
  167. package/dist/wirings/channel/channel-middleware-runner.js +0 -12
  168. package/dist/wirings/channel/channel-rpc-registry.d.ts +31 -0
  169. package/dist/wirings/channel/channel-rpc-registry.js +89 -0
  170. package/dist/wirings/channel/channel-rpc-responder.d.ts +15 -0
  171. package/dist/wirings/channel/channel-rpc-responder.js +71 -0
  172. package/dist/wirings/channel/channel-rpc-service.d.ts +40 -0
  173. package/dist/wirings/channel/channel-rpc-service.js +106 -0
  174. package/dist/wirings/channel/channel-rpc-validators.d.ts +14 -0
  175. package/dist/wirings/channel/channel-rpc-validators.js +30 -0
  176. package/dist/wirings/channel/channel-rpc.d.ts +5 -0
  177. package/dist/wirings/channel/channel-rpc.js +5 -0
  178. package/dist/wirings/channel/channel-rpc.types.d.ts +90 -0
  179. package/dist/wirings/channel/channel-rpc.types.js +50 -0
  180. package/dist/wirings/channel/channel-runner.d.ts +0 -4
  181. package/dist/wirings/channel/channel-runner.js +0 -14
  182. package/dist/wirings/channel/channel-store.d.ts +0 -10
  183. package/dist/wirings/channel/channel.types.d.ts +12 -1
  184. package/dist/wirings/channel/define-channel-routes.d.ts +0 -20
  185. package/dist/wirings/channel/define-channel-routes.js +0 -20
  186. package/dist/wirings/channel/eventhub-service.d.ts +0 -18
  187. package/dist/wirings/channel/index.d.ts +4 -1
  188. package/dist/wirings/channel/index.js +2 -0
  189. package/dist/wirings/channel/local/local-channel-runner.js +3 -1
  190. package/dist/wirings/channel/local/local-eventhub-service.d.ts +0 -33
  191. package/dist/wirings/channel/local/local-eventhub-service.js +2 -36
  192. package/dist/wirings/channel/log-channels.d.ts +0 -4
  193. package/dist/wirings/channel/log-channels.js +0 -4
  194. package/dist/wirings/channel/pikku-abstract-channel-handler.js +6 -0
  195. package/dist/wirings/channel/serverless/serverless-channel-runner.js +2 -5
  196. package/dist/wirings/cli/channel/cli-approval.d.ts +41 -0
  197. package/dist/wirings/cli/channel/cli-approval.js +81 -0
  198. package/dist/wirings/cli/channel/cli-channel-runner.d.ts +0 -4
  199. package/dist/wirings/cli/channel/cli-channel-runner.js +3 -25
  200. package/dist/wirings/cli/channel/cli-raw-channel-runner.d.ts +47 -9
  201. package/dist/wirings/cli/channel/cli-raw-channel-runner.js +24 -16
  202. package/dist/wirings/cli/channel/cli-raw-client-runner.d.ts +38 -0
  203. package/dist/wirings/cli/channel/cli-raw-client-runner.js +129 -0
  204. package/dist/wirings/cli/channel/index.d.ts +5 -0
  205. package/dist/wirings/cli/channel/index.js +2 -0
  206. package/dist/wirings/cli/cli-runner.d.ts +20 -20
  207. package/dist/wirings/cli/cli-runner.js +28 -89
  208. package/dist/wirings/cli/cli.types.d.ts +14 -3
  209. package/dist/wirings/cli/command-parser.d.ts +1 -10
  210. package/dist/wirings/cli/command-parser.js +10 -87
  211. package/dist/wirings/cli/define-cli-commands.d.ts +1 -17
  212. package/dist/wirings/cli/define-cli-commands.js +1 -17
  213. package/dist/wirings/credential/credential.types.d.ts +0 -12
  214. package/dist/wirings/credential/define-credential.d.ts +48 -0
  215. package/dist/wirings/credential/define-credential.js +47 -0
  216. package/dist/wirings/credential/index.d.ts +1 -1
  217. package/dist/wirings/credential/index.js +1 -1
  218. package/dist/wirings/credential/validate-credential-definitions.d.ts +2 -4
  219. package/dist/wirings/gateway/gateway-runner.d.ts +1 -20
  220. package/dist/wirings/gateway/gateway-runner.js +8 -105
  221. package/dist/wirings/gateway/gateway.types.d.ts +7 -80
  222. package/dist/wirings/http/http-routes.d.ts +0 -63
  223. package/dist/wirings/http/http-routes.js +0 -63
  224. package/dist/wirings/http/http-runner.d.ts +0 -99
  225. package/dist/wirings/http/http-runner.js +9 -165
  226. package/dist/wirings/http/http.types.d.ts +14 -55
  227. package/dist/wirings/http/log-http-routes.d.ts +0 -4
  228. package/dist/wirings/http/log-http-routes.js +0 -4
  229. package/dist/wirings/http/pikku-fetch-http-request.d.ts +0 -40
  230. package/dist/wirings/http/pikku-fetch-http-request.js +0 -58
  231. package/dist/wirings/http/pikku-fetch-http-response.js +0 -3
  232. package/dist/wirings/http/routers/path-to-regex.js +2 -13
  233. package/dist/wirings/http/web-request.d.ts +0 -8
  234. package/dist/wirings/http/web-request.js +25 -17
  235. package/dist/wirings/mcp/mcp-runner.d.ts +1 -4
  236. package/dist/wirings/mcp/mcp-runner.js +1 -14
  237. package/dist/wirings/mcp/mcp.types.d.ts +2 -35
  238. package/dist/wirings/oauth2/oauth2.types.d.ts +0 -28
  239. package/dist/wirings/oauth2/oauth2.types.js +0 -3
  240. package/dist/wirings/persona/define-personas.d.ts +32 -0
  241. package/dist/wirings/persona/define-personas.js +31 -0
  242. package/dist/wirings/persona/index.d.ts +21 -0
  243. package/dist/wirings/persona/index.js +17 -0
  244. package/dist/wirings/persona/persona-email.d.ts +37 -0
  245. package/dist/wirings/persona/persona-email.js +69 -0
  246. package/dist/wirings/persona/persona-environments.d.ts +45 -0
  247. package/dist/wirings/persona/persona-environments.js +81 -0
  248. package/dist/wirings/persona/persona-mailbox.d.ts +101 -0
  249. package/dist/wirings/persona/persona-mailbox.js +53 -0
  250. package/dist/wirings/persona/persona.types.d.ts +136 -0
  251. package/dist/wirings/persona/persona.types.js +1 -0
  252. package/dist/wirings/persona/validate-personas.d.ts +53 -0
  253. package/dist/wirings/persona/validate-personas.js +94 -0
  254. package/dist/wirings/queue/index.d.ts +3 -0
  255. package/dist/wirings/queue/index.js +2 -3
  256. package/dist/wirings/queue/queue-identity.d.ts +28 -0
  257. package/dist/wirings/queue/queue-identity.js +103 -0
  258. package/dist/wirings/queue/queue-runner.d.ts +0 -19
  259. package/dist/wirings/queue/queue-runner.js +9 -30
  260. package/dist/wirings/queue/queue.types.d.ts +20 -90
  261. package/dist/wirings/queue/register-queue-helper.d.ts +0 -12
  262. package/dist/wirings/queue/register-queue-helper.js +0 -11
  263. package/dist/wirings/queue/signed-queue-service.d.ts +17 -0
  264. package/dist/wirings/queue/signed-queue-service.js +42 -0
  265. package/dist/wirings/queue/validate-worker-config.d.ts +2 -23
  266. package/dist/wirings/queue/validate-worker-config.js +0 -14
  267. package/dist/wirings/role/define-system-role.d.ts +32 -0
  268. package/dist/wirings/role/define-system-role.js +31 -0
  269. package/dist/wirings/role/index.d.ts +3 -0
  270. package/dist/wirings/role/index.js +2 -0
  271. package/dist/wirings/role/role.types.d.ts +43 -0
  272. package/dist/wirings/role/role.types.js +1 -0
  273. package/dist/wirings/role/validate-role-definitions.d.ts +21 -0
  274. package/dist/wirings/role/validate-role-definitions.js +71 -0
  275. package/dist/wirings/rpc/addon-runner.d.ts +0 -19
  276. package/dist/wirings/rpc/addon-runner.js +0 -51
  277. package/dist/wirings/rpc/remote-addon-auth.d.ts +3 -13
  278. package/dist/wirings/rpc/remote-addon-auth.js +7 -11
  279. package/dist/wirings/rpc/rpc-runner.d.ts +11 -18
  280. package/dist/wirings/rpc/rpc-runner.js +88 -105
  281. package/dist/wirings/rpc/rpc-types.d.ts +7 -6
  282. package/dist/wirings/rpc/wire-addon.d.ts +25 -0
  283. package/dist/wirings/rpc/wire-addon.js +62 -0
  284. package/dist/wirings/rpc/wire-remote-addon.d.ts +3 -28
  285. package/dist/wirings/rpc/wire-remote-addon.js +0 -8
  286. package/dist/wirings/scheduler/log-schedulers.d.ts +0 -4
  287. package/dist/wirings/scheduler/log-schedulers.js +0 -4
  288. package/dist/wirings/scheduler/scheduler-runner.d.ts +0 -1
  289. package/dist/wirings/scheduler/scheduler-runner.js +0 -1
  290. package/dist/wirings/scheduler/scheduler.types.d.ts +1 -14
  291. package/dist/wirings/scope/define-scope.d.ts +32 -0
  292. package/dist/wirings/scope/define-scope.js +31 -0
  293. package/dist/wirings/scope/index.d.ts +1 -1
  294. package/dist/wirings/scope/index.js +1 -1
  295. package/dist/wirings/scope/scope.types.d.ts +7 -9
  296. package/dist/wirings/scope/validate-scope-definitions.d.ts +2 -21
  297. package/dist/wirings/scope/validate-scope-definitions.js +3 -21
  298. package/dist/wirings/secret/index.d.ts +1 -1
  299. package/dist/wirings/secret/index.js +1 -1
  300. package/dist/wirings/secret/secret.types.d.ts +19 -15
  301. package/dist/wirings/secret/secret.types.js +1 -1
  302. package/dist/wirings/secret/validate-secret-definitions.d.ts +2 -4
  303. package/dist/wirings/trigger/trigger-runner.d.ts +0 -27
  304. package/dist/wirings/trigger/trigger-runner.js +1 -24
  305. package/dist/wirings/trigger/trigger.types.d.ts +1 -82
  306. package/dist/wirings/trigger/trigger.types.js +0 -34
  307. package/dist/wirings/variable/index.d.ts +1 -1
  308. package/dist/wirings/variable/index.js +1 -1
  309. package/dist/wirings/variable/validate-variable-definitions.d.ts +2 -4
  310. package/dist/wirings/variable/variable.types.d.ts +1 -13
  311. package/dist/wirings/variable/variable.types.js +1 -1
  312. package/dist/wirings/virtual-user/index.d.ts +30 -0
  313. package/dist/wirings/virtual-user/index.js +10 -0
  314. package/dist/wirings/virtual-user/prepare-virtual-user-run.d.ts +54 -0
  315. package/dist/wirings/virtual-user/prepare-virtual-user-run.js +49 -0
  316. package/dist/wirings/virtual-user/run-virtual-user.d.ts +92 -0
  317. package/dist/wirings/virtual-user/run-virtual-user.js +478 -0
  318. package/dist/wirings/virtual-user/virtual-user-agents.d.ts +38 -0
  319. package/dist/wirings/virtual-user/virtual-user-agents.js +24 -0
  320. package/dist/wirings/virtual-user/virtual-user-catalogue.d.ts +92 -0
  321. package/dist/wirings/virtual-user/virtual-user-catalogue.js +134 -0
  322. package/dist/wirings/virtual-user/virtual-user-derive.d.ts +26 -0
  323. package/dist/wirings/virtual-user/virtual-user-derive.js +137 -0
  324. package/dist/wirings/virtual-user/virtual-user-dispositions.d.ts +79 -0
  325. package/dist/wirings/virtual-user/virtual-user-dispositions.js +128 -0
  326. package/dist/wirings/virtual-user/virtual-user-intents.d.ts +78 -0
  327. package/dist/wirings/virtual-user/virtual-user-intents.js +142 -0
  328. package/dist/wirings/virtual-user/virtual-user-rng.d.ts +24 -0
  329. package/dist/wirings/virtual-user/virtual-user-rng.js +44 -0
  330. package/dist/wirings/virtual-user/virtual-user-run-store.d.ts +90 -0
  331. package/dist/wirings/virtual-user/virtual-user-run-store.js +1 -0
  332. package/dist/wirings/virtual-user/virtual-user-target.d.ts +21 -0
  333. package/dist/wirings/virtual-user/virtual-user-target.js +34 -0
  334. package/dist/wirings/virtual-user/virtual-user.types.d.ts +199 -0
  335. package/dist/wirings/virtual-user/virtual-user.types.js +8 -0
  336. package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +19 -15
  337. package/dist/wirings/workflow/dsl/workflow-runner.d.ts +0 -4
  338. package/dist/wirings/workflow/dsl/workflow-runner.js +0 -4
  339. package/dist/wirings/workflow/feature.d.ts +0 -19
  340. package/dist/wirings/workflow/feature.js +0 -19
  341. package/dist/wirings/workflow/graph/graph-node.d.ts +0 -98
  342. package/dist/wirings/workflow/graph/graph-node.js +0 -34
  343. package/dist/wirings/workflow/graph/graph-runner.js +6 -41
  344. package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +0 -4
  345. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -58
  346. package/dist/wirings/workflow/graph/workflow-graph.types.js +0 -6
  347. package/dist/wirings/workflow/index.d.ts +5 -7
  348. package/dist/wirings/workflow/index.js +3 -17
  349. package/dist/wirings/workflow/pikku-scenario-service.d.ts +87 -5
  350. package/dist/wirings/workflow/pikku-scenario-service.js +204 -43
  351. package/dist/wirings/workflow/pikku-workflow-service.d.ts +7 -459
  352. package/dist/wirings/workflow/pikku-workflow-service.js +58 -551
  353. package/dist/wirings/workflow/run-timeline.d.ts +0 -47
  354. package/dist/wirings/workflow/run-timeline.js +0 -22
  355. package/dist/wirings/workflow/scenario-cookie-jar.d.ts +0 -23
  356. package/dist/wirings/workflow/scenario-cookie-jar.js +0 -16
  357. package/dist/wirings/workflow/scenario-poll.d.ts +0 -15
  358. package/dist/wirings/workflow/scenario-poll.js +0 -12
  359. package/dist/wirings/workflow/scenario-prose.d.ts +0 -28
  360. package/dist/wirings/workflow/scenario-prose.js +1 -19
  361. package/dist/wirings/workflow/scenario-step-guards.d.ts +0 -13
  362. package/dist/wirings/workflow/scenario-step-guards.js +1 -14
  363. package/dist/wirings/workflow/scenario-step.types.d.ts +84 -12
  364. package/dist/wirings/workflow/scenario-step.types.js +5 -1
  365. package/dist/wirings/workflow/scenario-surface.d.ts +16 -0
  366. package/dist/wirings/workflow/scenario-surface.js +56 -0
  367. package/dist/wirings/workflow/workflow-invocation-id.d.ts +0 -18
  368. package/dist/wirings/workflow/workflow-invocation-id.js +2 -22
  369. package/dist/wirings/workflow/workflow-queue-workers.d.ts +0 -20
  370. package/dist/wirings/workflow/workflow-queue-workers.js +0 -19
  371. package/dist/wirings/workflow/workflow.types.d.ts +5 -195
  372. package/knowledge/decisions/index.md +19 -0
  373. package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +49 -0
  374. package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-and-not-a-queued-job.md +48 -0
  375. package/knowledge/decisions/internals/actor-flow-conversations-seed-a-hidden-kickoff-message.md +23 -0
  376. package/knowledge/decisions/internals/actor-flow-drives-the-target-through-a-transport-seam.md +24 -0
  377. package/knowledge/decisions/internals/actor-flow-verdicts-are-llm-self-evaluations.md +25 -0
  378. package/knowledge/decisions/internals/addon-package-roots-resolve-by-walking-node-module-search-paths.md +26 -0
  379. package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +33 -0
  380. package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +28 -0
  381. package/knowledge/decisions/internals/ai-agent-agui-bridge-obeys-the-client-ordering-contract.md +29 -0
  382. package/knowledge/decisions/internals/ai-agent-audio-chunks-carry-the-format-the-provider-returned.md +20 -0
  383. package/knowledge/decisions/internals/ai-agent-credential-suspensions-hide-the-tool-result.md +26 -0
  384. package/knowledge/decisions/internals/ai-agent-delegate-and-supervise-hide-different-text.md +26 -0
  385. package/knowledge/decisions/internals/ai-agent-llm-tool-arguments-have-nulls-stripped.md +23 -0
  386. package/knowledge/decisions/internals/ai-agent-model-config-stays-a-single-resolution-seam.md +25 -0
  387. package/knowledge/decisions/internals/ai-agent-onerror-hooks-cannot-change-the-failure.md +22 -0
  388. package/knowledge/decisions/internals/ai-agent-runner-methods-must-keep-their-receiver.md +22 -0
  389. package/knowledge/decisions/internals/ai-agent-stream-persistence-is-best-effort.md +27 -0
  390. package/knowledge/decisions/internals/ai-agent-sub-agents-inherit-the-parent-context-block.md +26 -0
  391. package/knowledge/decisions/internals/ai-agent-tool-execute-failures-are-logged-unconditionally.md +25 -0
  392. package/knowledge/decisions/internals/ai-agent-voice-input-transcribes-audio-parts-in-place.md +22 -0
  393. package/knowledge/decisions/internals/ai-agent-working-memory-is-persisted-only-when-valid.md +25 -0
  394. package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +30 -0
  395. package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +31 -0
  396. package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md +29 -0
  397. package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +28 -0
  398. package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +27 -0
  399. package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +28 -0
  400. package/knowledge/decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md +34 -0
  401. package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +29 -0
  402. package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +84 -0
  403. package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +41 -0
  404. package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +44 -0
  405. package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +39 -0
  406. package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +42 -0
  407. package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +39 -0
  408. package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +43 -0
  409. package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +38 -0
  410. package/knowledge/decisions/internals/core-state-is-a-global-map-written-only-at-registration-time.md +44 -0
  411. package/knowledge/decisions/internals/email-meta-is-read-uncached-because-codegen-rewrites-it-mid-session.md +27 -0
  412. package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +32 -0
  413. package/knowledge/decisions/internals/gateway-webhook-challenges-echo-bytes-not-json.md +28 -0
  414. package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +31 -0
  415. package/knowledge/decisions/internals/generated-src-paths-in-pikku-meta-are-absolute.md +26 -0
  416. package/knowledge/decisions/internals/http-request-bodies-are-read-once-and-shared.md +32 -0
  417. package/knowledge/decisions/internals/http-route-groups-cascade-config-in-a-fixed-order.md +28 -0
  418. package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +30 -0
  419. package/knowledge/decisions/internals/http-runner-logs-through-a-trace-scoped-logger-functions-do-not.md +26 -0
  420. package/knowledge/decisions/internals/http-set-cookie-headers-are-appended-never-joined.md +28 -0
  421. package/knowledge/decisions/internals/http-sse-streams-flush-headers-only-after-middleware.md +32 -0
  422. package/knowledge/decisions/internals/http-wiring-without-metadata-is-skipped-not-fatal.md +26 -0
  423. package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +25 -0
  424. package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +26 -0
  425. package/knowledge/decisions/internals/index.md +117 -0
  426. package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +25 -0
  427. package/knowledge/decisions/internals/local-trigger-and-gateway-services-assume-a-single-process.md +26 -0
  428. package/knowledge/decisions/internals/node-only-builtins-are-imported-dynamically.md +24 -0
  429. package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +53 -0
  430. package/knowledge/decisions/internals/queue-group-concurrency-keeps-one-shared-queue-fair.md +28 -0
  431. package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +27 -0
  432. package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +31 -0
  433. package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +32 -0
  434. package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +27 -0
  435. package/knowledge/decisions/internals/scenario-meta-lives-apart-from-app-meta-but-merges-when-read-off-disk.md +26 -0
  436. package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +27 -0
  437. package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +48 -0
  438. package/knowledge/decisions/internals/scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md +30 -0
  439. package/knowledge/decisions/internals/serverless-channel-disconnect-must-tolerate-a-missing-channel.md +28 -0
  440. package/knowledge/decisions/internals/the-dev-queue-copies-prod-timing-and-serialization-semantics.md +30 -0
  441. package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +29 -0
  442. package/knowledge/decisions/internals/the-in-memory-workflow-service-is-inline-only-and-single-process.md +27 -0
  443. package/knowledge/decisions/internals/the-kek-salt-is-scoped-to-the-key-version.md +40 -0
  444. package/knowledge/decisions/internals/the-schema-service-is-never-stubbed.md +26 -0
  445. package/knowledge/decisions/internals/trigger-declaration-is-split-from-trigger-source.md +33 -0
  446. package/knowledge/decisions/internals/typed-secret-service-caches-for-the-process-lifetime.md +26 -0
  447. package/knowledge/decisions/internals/validate-checks-personas-through-a-shared-module.md +43 -0
  448. package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +26 -0
  449. package/knowledge/decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md +25 -0
  450. package/knowledge/decisions/internals/whether-a-run-is-inline-is-read-from-the-run-record.md +58 -0
  451. package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +34 -0
  452. package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +42 -0
  453. package/knowledge/decisions/internals/workflow-dsl-meta-separates-runtime-expressions-from-literals.md +38 -0
  454. package/knowledge/decisions/internals/workflow-features-resolve-scenarios-by-object-identity.md +29 -0
  455. package/knowledge/decisions/internals/workflow-graph-inline-and-queued-runs-share-one-planner.md +42 -0
  456. package/knowledge/decisions/internals/workflow-graph-node-notes-are-excluded-from-the-graph-hash.md +25 -0
  457. package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +29 -0
  458. package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +43 -0
  459. package/knowledge/decisions/internals/workflow-queued-step-dispatch-requires-an-explicit-opt-in.md +29 -0
  460. package/knowledge/decisions/internals/workflow-queues-are-per-workflow-by-default.md +42 -0
  461. package/knowledge/decisions/internals/workflow-repeated-step-names-get-an-ordinal-suffix.md +33 -0
  462. package/knowledge/decisions/internals/workflow-replay-reads-its-steps-once-and-caches-only-the-immutable-half.md +32 -0
  463. package/knowledge/decisions/internals/workflow-retries-are-owned-by-the-workflow-not-the-queue.md +31 -0
  464. package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +39 -0
  465. package/knowledge/decisions/internals/workflow-run-mirror-is-never-a-source-of-truth.md +29 -0
  466. package/knowledge/decisions/internals/workflow-run-polling-backs-off-to-the-callers-ceiling.md +33 -0
  467. package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +37 -0
  468. package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +50 -0
  469. package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +43 -0
  470. package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +32 -0
  471. package/knowledge/decisions/internals/workflow-scenario-quarantine-reason-lives-in-code.md +18 -0
  472. package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +34 -0
  473. package/knowledge/decisions/internals/workflow-step-compensation-runs-as-its-own-durable-step.md +26 -0
  474. package/knowledge/decisions/internals/workflow-step-dispatch-failure-is-transient-not-a-run-failure.md +33 -0
  475. package/knowledge/decisions/internals/workflow-step-lock-is-held-only-to-claim-the-step.md +27 -0
  476. package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +34 -0
  477. package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +38 -0
  478. package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +30 -0
  479. package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +26 -0
  480. package/knowledge/decisions/security/actor-flow-missing-approval-decisions-default-to-denied.md +22 -0
  481. package/knowledge/decisions/security/actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +27 -0
  482. package/knowledge/decisions/security/actor-sign-in-only-works-for-actor-flagged-users.md +27 -0
  483. package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +43 -0
  484. package/knowledge/decisions/security/addon-config-gates-apply-only-at-the-namespaced-rpc-boundary.md +52 -0
  485. package/knowledge/decisions/security/addon-scopes-are-resolved-where-the-function-runs.md +46 -0
  486. package/knowledge/decisions/security/ai-agent-approval-forwarding-requires-a-symbol-brand.md +27 -0
  487. package/knowledge/decisions/security/ai-agent-credential-requests-are-symbol-branded.md +37 -0
  488. package/knowledge/decisions/security/ai-agent-gate-requires-a-session-only-when-auth-is-true.md +31 -0
  489. package/knowledge/decisions/security/ai-agent-ownership-failures-never-echo-the-resource.md +23 -0
  490. package/knowledge/decisions/security/ai-agent-resume-re-runs-the-authorization-gate.md +22 -0
  491. package/knowledge/decisions/security/ai-agent-sessionless-deployments-have-no-thread-ownership.md +39 -0
  492. package/knowledge/decisions/security/ai-agent-thread-ownership-composes-the-session-principal.md +30 -0
  493. package/knowledge/decisions/security/ai-agent-tool-filtering-reads-the-live-function-config.md +24 -0
  494. package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +30 -0
  495. package/knowledge/decisions/security/an-exposed-ungated-function-is-a-codegen-warning.md +49 -0
  496. package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +76 -0
  497. package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +39 -0
  498. package/knowledge/decisions/security/core-secrets-use-a-per-secret-dek-wrapped-by-a-kek.md +37 -0
  499. package/knowledge/decisions/security/gateway-handlers-run-through-the-function-runner-gate.md +31 -0
  500. package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +30 -0
  501. package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +40 -0
  502. package/knowledge/decisions/security/http-error-detail-is-withheld-from-clients-in-production.md +33 -0
  503. package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +46 -0
  504. package/knowledge/decisions/security/index.md +55 -0
  505. package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +27 -0
  506. package/knowledge/decisions/security/passphrases-are-stretched-key-material-is-expanded.md +40 -0
  507. package/knowledge/decisions/security/permission-auth-filtering-requires-live-permission-functions.md +31 -0
  508. package/knowledge/decisions/security/pikku-carries-actor-scopes-as-data-and-the-app-grants-them.md +26 -0
  509. package/knowledge/decisions/security/queue-job-identities-are-signed-at-enqueue.md +69 -0
  510. package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +39 -0
  511. package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +34 -0
  512. package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +49 -0
  513. package/knowledge/decisions/security/scenario-step-functions-are-never-externally-invocable.md +30 -0
  514. package/knowledge/decisions/security/scope-resolution-happens-at-the-session-boundary-and-sync-never-deletes.md +28 -0
  515. package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +34 -0
  516. package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +37 -0
  517. package/knowledge/decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md +25 -0
  518. package/knowledge/decisions/security/workflow-actor-steps-always-use-the-real-transport.md +34 -0
  519. package/knowledge/decisions/security/workflow-approval-payloads-are-validated-on-replay-inside-the-workflow.md +40 -0
  520. package/knowledge/decisions/security/workflow-queued-steps-rehydrate-their-session-from-the-run-wire.md +32 -0
  521. package/knowledge/decisions/security/workflow-scenario-sessions-are-isolated-per-actor-and-per-scenario.md +32 -0
  522. package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +31 -0
  523. package/knowledge/index.md +24 -0
  524. package/knowledge/questions/index.md +15 -0
  525. package/package.json +6 -2
  526. package/run-tests.sh +0 -0
  527. package/src/column-form.test.ts +97 -0
  528. package/src/column-form.ts +58 -0
  529. package/src/crypto-utils.test.ts +460 -19
  530. package/src/crypto-utils.ts +306 -59
  531. package/src/data-classification.ts +45 -7
  532. package/src/dev/hot-reload.test.ts +0 -4
  533. package/src/dev/hot-reload.ts +11 -30
  534. package/src/dev/module-runner.ts +7 -32
  535. package/src/dev/reload-meta.ts +9 -29
  536. package/src/errors/error-handler.ts +20 -35
  537. package/src/errors/error.test.ts +30 -1
  538. package/src/errors/errors.ts +73 -157
  539. package/src/function/abort-scope.test.ts +97 -0
  540. package/src/function/abort-scope.ts +80 -0
  541. package/src/function/function-runner.test.ts +0 -7
  542. package/src/function/function-runner.ts +62 -32
  543. package/src/function/functions.types.ts +95 -138
  544. package/src/function/index.ts +1 -0
  545. package/src/function/list.types.test.ts +3 -25
  546. package/src/function/list.types.ts +12 -62
  547. package/src/handle-error.ts +0 -18
  548. package/src/index.ts +84 -3
  549. package/src/middleware/auth-apikey.test.ts +0 -1
  550. package/src/middleware/auth-apikey.ts +0 -17
  551. package/src/middleware/auth-bearer.test.ts +3 -5
  552. package/src/middleware/auth-bearer.ts +5 -41
  553. package/src/middleware/auth-cookie.test.ts +0 -6
  554. package/src/middleware/auth-cookie.ts +2 -26
  555. package/src/middleware/cors.test.ts +34 -0
  556. package/src/middleware/cors.ts +12 -33
  557. package/src/middleware/remote-auth.test.ts +26 -10
  558. package/src/middleware/remote-auth.ts +11 -3
  559. package/src/middleware/telemetry.ts +2 -31
  560. package/src/middleware-runner.test.ts +0 -2
  561. package/src/middleware-runner.ts +5 -74
  562. package/src/permissions.test.ts +30 -0
  563. package/src/permissions.ts +24 -74
  564. package/src/pikku-request.ts +0 -6
  565. package/src/pikku-state.ts +2 -30
  566. package/src/production-barrels-stay-lean.test.ts +110 -0
  567. package/src/remote.test.ts +173 -0
  568. package/src/remote.ts +18 -8
  569. package/src/schema.ts +5 -39
  570. package/src/scopes.ts +7 -48
  571. package/src/secret-value.test.ts +204 -0
  572. package/src/secret-value.ts +111 -0
  573. package/src/services/ai-agent-runner-service.ts +20 -0
  574. package/src/services/ai-embedding-service.ts +3 -25
  575. package/src/services/audit-service.ts +88 -11
  576. package/src/services/content-service.ts +1 -46
  577. package/src/services/credential-service.ts +3 -40
  578. package/src/services/credential-wire-service.test.ts +0 -2
  579. package/src/services/credential-wire-service.ts +9 -1
  580. package/src/services/deployment-service.ts +3 -9
  581. package/src/services/email-service.ts +3 -1
  582. package/src/services/gateway-service.ts +0 -15
  583. package/src/services/{http-scenario-actors-converse.test.ts → http-personas-converse.test.ts} +38 -9
  584. package/src/services/{http-scenario-actors.test.ts → http-personas.test.ts} +39 -22
  585. package/src/services/{http-scenario-actors.ts → http-personas.ts} +85 -45
  586. package/src/services/in-memory-queue-service.ts +1 -15
  587. package/src/services/in-memory-trigger-service.ts +1 -18
  588. package/src/services/in-memory-workflow-service.test.ts +0 -13
  589. package/src/services/in-memory-workflow-service.ts +4 -38
  590. package/src/services/index.ts +23 -18
  591. package/src/services/istanbul-coverage-service.ts +2 -8
  592. package/src/services/jwt-service.ts +1 -16
  593. package/src/services/local-content-request-handler.test.ts +202 -0
  594. package/src/services/local-content-request-handler.ts +267 -0
  595. package/src/services/local-content.test.ts +159 -27
  596. package/src/services/local-content.ts +55 -23
  597. package/src/services/local-gateway-service.ts +2 -17
  598. package/src/services/local-secrets.test.ts +20 -5
  599. package/src/services/local-secrets.ts +15 -11
  600. package/src/services/logger-console.test.ts +0 -1
  601. package/src/services/logger-console.ts +3 -7
  602. package/src/services/logger.ts +31 -46
  603. package/src/services/meta-service.test.ts +1 -5
  604. package/src/services/meta-service.ts +41 -61
  605. package/src/services/{scenario-actors-service.ts → personas-service.ts} +48 -43
  606. package/src/services/pikku-user-id.ts +0 -4
  607. package/src/services/queue-webhook-service.test.ts +2 -1
  608. package/src/services/queue-webhook-service.ts +10 -42
  609. package/src/services/scheduler-service.ts +1 -50
  610. package/src/services/schema-service.ts +1 -24
  611. package/src/services/scope-service.ts +50 -34
  612. package/src/services/scoped-secret-service.ts +4 -7
  613. package/src/services/secret-host-binding.test.ts +138 -0
  614. package/src/services/secret-host-binding.ts +51 -0
  615. package/src/services/secret-service.ts +12 -35
  616. package/src/services/secretless.test.ts +54 -0
  617. package/src/services/secretless.ts +29 -0
  618. package/src/services/stub-tracker.ts +8 -18
  619. package/src/services/system-role-guard.test.ts +93 -0
  620. package/src/services/system-role-guard.ts +71 -0
  621. package/src/services/trigger-service.ts +0 -12
  622. package/src/services/typed-secret-service.ts +12 -14
  623. package/src/services/v8-coverage-service.ts +3 -6
  624. package/src/services/variables-service.ts +1 -8
  625. package/src/services/webhook-service.ts +23 -64
  626. package/src/services/workflow-service.ts +3 -20
  627. package/src/testing/service-tests.ts +6 -32
  628. package/src/time-utils.ts +1 -19
  629. package/src/types/core.types.ts +137 -229
  630. package/src/types/state.types.ts +7 -9
  631. package/src/utils/hmac.ts +4 -10
  632. package/src/utils/safe-fetch.ts +13 -54
  633. package/src/utils.test.ts +11 -2
  634. package/src/utils.ts +6 -15
  635. package/src/wirings/actor-flow/actor-flow.types.ts +1 -34
  636. package/src/wirings/actor-flow/index.ts +0 -9
  637. package/src/wirings/actor-flow/run-conversation.test.ts +11 -6
  638. package/src/wirings/actor-flow/run-conversation.ts +19 -12
  639. package/src/wirings/ai-agent/ai-agent-agui.test.ts +91 -10
  640. package/src/wirings/ai-agent/ai-agent-agui.ts +49 -17
  641. package/src/wirings/ai-agent/ai-agent-helpers.ts +20 -0
  642. package/src/wirings/ai-agent/ai-agent-interrupt.test.ts +842 -0
  643. package/src/wirings/ai-agent/ai-agent-interrupt.ts +399 -0
  644. package/src/wirings/ai-agent/ai-agent-memory.ts +0 -2
  645. package/src/wirings/ai-agent/ai-agent-model-config.ts +1 -9
  646. package/src/wirings/ai-agent/ai-agent-prepare.test.ts +202 -31
  647. package/src/wirings/ai-agent/ai-agent-prepare.ts +89 -139
  648. package/src/wirings/ai-agent/ai-agent-registry.test.ts +191 -6
  649. package/src/wirings/ai-agent/ai-agent-registry.ts +18 -1
  650. package/src/wirings/ai-agent/ai-agent-resume-authorization.test.ts +0 -2
  651. package/src/wirings/ai-agent/ai-agent-runner.test.ts +11 -9
  652. package/src/wirings/ai-agent/ai-agent-runner.ts +85 -35
  653. package/src/wirings/ai-agent/ai-agent-stream.test.ts +205 -103
  654. package/src/wirings/ai-agent/ai-agent-stream.ts +224 -76
  655. package/src/wirings/ai-agent/ai-agent-thread-ownership.test.ts +301 -0
  656. package/src/wirings/ai-agent/ai-agent.types.ts +130 -5
  657. package/src/wirings/ai-agent/index.ts +37 -3
  658. package/src/wirings/ai-agent/voice-input.test.ts +137 -7
  659. package/src/wirings/ai-agent/voice-input.ts +96 -12
  660. package/src/wirings/ai-agent/voice-output.test.ts +512 -0
  661. package/src/wirings/ai-agent/voice-output.ts +243 -56
  662. package/src/wirings/channel/channel-common.ts +15 -20
  663. package/src/wirings/channel/channel-handler.test.ts +50 -0
  664. package/src/wirings/channel/channel-handler.ts +32 -11
  665. package/src/wirings/channel/channel-host-rpc.test.ts +150 -0
  666. package/src/wirings/channel/channel-host-rpc.ts +69 -0
  667. package/src/wirings/channel/channel-middleware-runner.test.ts +0 -1
  668. package/src/wirings/channel/channel-middleware-runner.ts +0 -12
  669. package/src/wirings/channel/channel-rpc-registry.ts +116 -0
  670. package/src/wirings/channel/channel-rpc-responder.ts +117 -0
  671. package/src/wirings/channel/channel-rpc-service.ts +146 -0
  672. package/src/wirings/channel/channel-rpc-validators.ts +65 -0
  673. package/src/wirings/channel/channel-rpc.test.ts +820 -0
  674. package/src/wirings/channel/channel-rpc.ts +5 -0
  675. package/src/wirings/channel/channel-rpc.types.ts +150 -0
  676. package/src/wirings/channel/channel-runner.ts +0 -14
  677. package/src/wirings/channel/channel-store.ts +0 -10
  678. package/src/wirings/channel/channel.types.ts +19 -8
  679. package/src/wirings/channel/define-channel-routes.ts +0 -20
  680. package/src/wirings/channel/eventhub-service.ts +0 -18
  681. package/src/wirings/channel/index.ts +35 -0
  682. package/src/wirings/channel/local/local-channel-handler.ts +3 -1
  683. package/src/wirings/channel/local/local-channel-runner.test.ts +0 -10
  684. package/src/wirings/channel/local/local-channel-runner.ts +3 -1
  685. package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -13
  686. package/src/wirings/channel/local/local-eventhub-service.ts +2 -37
  687. package/src/wirings/channel/log-channels.ts +0 -4
  688. package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +83 -2
  689. package/src/wirings/channel/pikku-abstract-channel-handler.ts +7 -0
  690. package/src/wirings/channel/serverless/serverless-channel-runner.ts +2 -5
  691. package/src/wirings/cli/channel/cli-approval.test.ts +177 -0
  692. package/src/wirings/cli/channel/cli-approval.ts +135 -0
  693. package/src/wirings/cli/channel/cli-channel-runner.ts +4 -26
  694. package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +169 -0
  695. package/src/wirings/cli/channel/cli-raw-channel-runner.ts +59 -16
  696. package/src/wirings/cli/channel/cli-raw-client-runner.test.ts +480 -0
  697. package/src/wirings/cli/channel/cli-raw-client-runner.ts +185 -0
  698. package/src/wirings/cli/channel/index.ts +13 -0
  699. package/src/wirings/cli/cli-runner.test.ts +0 -1
  700. package/src/wirings/cli/cli-runner.ts +46 -88
  701. package/src/wirings/cli/cli.types.ts +14 -3
  702. package/src/wirings/cli/command-parser.test.ts +0 -4
  703. package/src/wirings/cli/command-parser.ts +11 -91
  704. package/src/wirings/cli/define-cli-commands.ts +1 -17
  705. package/src/wirings/credential/credential.types.ts +0 -12
  706. package/src/wirings/credential/{wire-credential.ts → define-credential.ts} +7 -7
  707. package/src/wirings/credential/index.ts +1 -1
  708. package/src/wirings/credential/validate-credential-definitions.ts +2 -4
  709. package/src/wirings/gateway/gateway-runner.test.ts +1 -21
  710. package/src/wirings/gateway/gateway-runner.ts +8 -110
  711. package/src/wirings/gateway/gateway.types.ts +7 -80
  712. package/src/wirings/http/http-routes.test.ts +0 -3
  713. package/src/wirings/http/http-routes.ts +0 -86
  714. package/src/wirings/http/http-runner.test.ts +0 -1
  715. package/src/wirings/http/http-runner.ts +8 -167
  716. package/src/wirings/http/http.types.ts +15 -62
  717. package/src/wirings/http/log-http-routes.ts +0 -4
  718. package/src/wirings/http/pikku-fetch-http-request.test.ts +2 -10
  719. package/src/wirings/http/pikku-fetch-http-request.ts +0 -58
  720. package/src/wirings/http/pikku-fetch-http-response.test.ts +1 -1
  721. package/src/wirings/http/pikku-fetch-http-response.ts +0 -3
  722. package/src/wirings/http/routers/path-to-regex.test.ts +4 -17
  723. package/src/wirings/http/routers/path-to-regex.ts +2 -13
  724. package/src/wirings/http/web-request.test.ts +33 -2
  725. package/src/wirings/http/web-request.ts +30 -17
  726. package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -1
  727. package/src/wirings/mcp/mcp-runner.ts +2 -17
  728. package/src/wirings/mcp/mcp.types.ts +7 -42
  729. package/src/wirings/oauth2/oauth2.types.ts +0 -30
  730. package/src/wirings/persona/define-personas.ts +33 -0
  731. package/src/wirings/persona/index.ts +62 -0
  732. package/src/wirings/persona/persona-email.ts +87 -0
  733. package/src/wirings/persona/persona-environments.test.ts +183 -0
  734. package/src/wirings/persona/persona-environments.ts +138 -0
  735. package/src/wirings/persona/persona-mailbox.ts +156 -0
  736. package/src/wirings/persona/persona.test.ts +220 -0
  737. package/src/wirings/persona/persona.types.ts +142 -0
  738. package/src/wirings/persona/validate-personas.ts +133 -0
  739. package/src/wirings/queue/index.ts +13 -3
  740. package/src/wirings/queue/queue-identity.test.ts +454 -0
  741. package/src/wirings/queue/queue-identity.ts +176 -0
  742. package/src/wirings/queue/queue-runner.ts +12 -31
  743. package/src/wirings/queue/queue.types.ts +25 -90
  744. package/src/wirings/queue/register-queue-helper.ts +0 -14
  745. package/src/wirings/queue/signed-queue-service.ts +60 -0
  746. package/src/wirings/queue/validate-worker-config.ts +2 -28
  747. package/src/wirings/role/define-system-role.ts +33 -0
  748. package/src/wirings/role/index.ts +13 -0
  749. package/src/wirings/role/role.test.ts +104 -0
  750. package/src/wirings/role/role.types.ts +47 -0
  751. package/src/wirings/role/validate-role-definitions.ts +93 -0
  752. package/src/wirings/rpc/addon-auth-tags.test.ts +223 -0
  753. package/src/wirings/rpc/addon-runner.ts +0 -56
  754. package/src/wirings/rpc/addon-scopes.test.ts +225 -0
  755. package/src/wirings/rpc/remote-addon-auth.ts +9 -16
  756. package/src/wirings/rpc/rpc-runner.test.ts +192 -6
  757. package/src/wirings/rpc/rpc-runner.ts +145 -127
  758. package/src/wirings/rpc/rpc-types.ts +11 -6
  759. package/src/wirings/rpc/wire-addon.test.ts +43 -1
  760. package/src/wirings/rpc/wire-addon.ts +99 -0
  761. package/src/wirings/rpc/wire-remote-addon.ts +9 -29
  762. package/src/wirings/scheduler/log-schedulers.ts +0 -4
  763. package/src/wirings/scheduler/scheduler-runner.test.ts +1 -8
  764. package/src/wirings/scheduler/scheduler-runner.ts +0 -2
  765. package/src/wirings/scheduler/scheduler.types.ts +1 -14
  766. package/src/wirings/scope/{wire-scope.ts → define-scope.ts} +5 -6
  767. package/src/wirings/scope/index.ts +1 -1
  768. package/src/wirings/scope/scope.test.ts +1 -2
  769. package/src/wirings/scope/scope.types.ts +7 -9
  770. package/src/wirings/scope/validate-scope-definitions.ts +3 -21
  771. package/src/wirings/secret/index.ts +1 -1
  772. package/src/wirings/secret/secret.types.ts +19 -15
  773. package/src/wirings/secret/validate-secret-definitions.ts +2 -4
  774. package/src/wirings/trigger/trigger-runner.ts +1 -27
  775. package/src/wirings/trigger/trigger.types.ts +1 -82
  776. package/src/wirings/variable/index.ts +1 -1
  777. package/src/wirings/variable/validate-variable-definitions.ts +2 -4
  778. package/src/wirings/variable/variable.types.ts +1 -13
  779. package/src/wirings/virtual-user/index.ts +88 -0
  780. package/src/wirings/virtual-user/prepare-virtual-user-run.test.ts +115 -0
  781. package/src/wirings/virtual-user/prepare-virtual-user-run.ts +95 -0
  782. package/src/wirings/virtual-user/run-virtual-user.test.ts +765 -0
  783. package/src/wirings/virtual-user/run-virtual-user.ts +671 -0
  784. package/src/wirings/virtual-user/virtual-user-agents.test.ts +65 -0
  785. package/src/wirings/virtual-user/virtual-user-agents.ts +57 -0
  786. package/src/wirings/virtual-user/virtual-user-catalogue.test.ts +215 -0
  787. package/src/wirings/virtual-user/virtual-user-catalogue.ts +184 -0
  788. package/src/wirings/virtual-user/virtual-user-derive.test.ts +398 -0
  789. package/src/wirings/virtual-user/virtual-user-derive.ts +173 -0
  790. package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +63 -0
  791. package/src/wirings/virtual-user/virtual-user-dispositions.ts +213 -0
  792. package/src/wirings/virtual-user/virtual-user-intents.test.ts +208 -0
  793. package/src/wirings/virtual-user/virtual-user-intents.ts +185 -0
  794. package/src/wirings/virtual-user/virtual-user-rng.test.ts +72 -0
  795. package/src/wirings/virtual-user/virtual-user-rng.ts +50 -0
  796. package/src/wirings/virtual-user/virtual-user-run-store.ts +98 -0
  797. package/src/wirings/virtual-user/virtual-user-target.ts +47 -0
  798. package/src/wirings/virtual-user/virtual-user.types.ts +219 -0
  799. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +19 -20
  800. package/src/wirings/workflow/dsl/workflow-runner.ts +0 -4
  801. package/src/wirings/workflow/feature.ts +0 -19
  802. package/src/wirings/workflow/graph/graph-node.ts +0 -136
  803. package/src/wirings/workflow/graph/graph-runner.test.ts +20 -19
  804. package/src/wirings/workflow/graph/graph-runner.ts +6 -41
  805. package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -4
  806. package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -58
  807. package/src/wirings/workflow/index.ts +10 -44
  808. package/src/wirings/workflow/pikku-scenario-service.ts +235 -61
  809. package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -39
  810. package/src/wirings/workflow/pikku-workflow-service.ts +77 -674
  811. package/src/wirings/workflow/run-timeline.test.ts +7 -19
  812. package/src/wirings/workflow/run-timeline.ts +0 -56
  813. package/src/wirings/workflow/scenario-cookie-jar.test.ts +0 -1
  814. package/src/wirings/workflow/scenario-cookie-jar.ts +0 -25
  815. package/src/wirings/workflow/scenario-expectations.test.ts +2 -7
  816. package/src/wirings/workflow/scenario-hooks.test.ts +2 -7
  817. package/src/wirings/workflow/scenario-poll.test.ts +0 -2
  818. package/src/wirings/workflow/scenario-poll.ts +0 -15
  819. package/src/wirings/workflow/scenario-prose.test.ts +5 -7
  820. package/src/wirings/workflow/scenario-prose.ts +1 -29
  821. package/src/wirings/workflow/scenario-service.test.ts +2 -10
  822. package/src/wirings/workflow/scenario-step-guards.ts +1 -14
  823. package/src/wirings/workflow/scenario-step.test.ts +163 -19
  824. package/src/wirings/workflow/scenario-step.types.ts +94 -12
  825. package/src/wirings/workflow/scenario-surface.test.ts +146 -0
  826. package/src/wirings/workflow/scenario-surface.ts +71 -0
  827. package/src/wirings/workflow/workflow-dispatch-durability.test.ts +14 -15
  828. package/src/wirings/workflow/workflow-dispatch-payload.test.ts +0 -4
  829. package/src/wirings/workflow/workflow-inline-authority.test.ts +169 -0
  830. package/src/wirings/workflow/workflow-invocation-id.test.ts +0 -2
  831. package/src/wirings/workflow/workflow-invocation-id.ts +2 -22
  832. package/src/wirings/workflow/workflow-mirror.test.ts +0 -7
  833. package/src/wirings/workflow/workflow-on-error.test.ts +0 -9
  834. package/src/wirings/workflow/workflow-queue-workers.ts +0 -21
  835. package/src/wirings/workflow/workflow-replay-snapshot.test.ts +8 -7
  836. package/src/wirings/workflow/workflow-retry-policy.test.ts +0 -5
  837. package/src/wirings/workflow/workflow-run-context.test.ts +5 -10
  838. package/src/wirings/workflow/workflow-run-polling.test.ts +0 -5
  839. package/src/wirings/workflow/workflow-step-ordinal.test.ts +19 -4
  840. package/src/wirings/workflow/workflow-step-session.test.ts +0 -7
  841. package/src/wirings/workflow/workflow.types.ts +5 -201
  842. package/tsconfig.tsbuildinfo +1 -1
  843. package/tsconfig.type-tests.json +12 -0
  844. package/src/middleware/timeout.ts +0 -22
  845. package/src/pikku-response.ts +0 -5
  846. package/src/wirings/mcp/mcp-endpoint-registry.test.d.ts +0 -1
  847. package/src/wirings/workflow/dsl/index.ts +0 -36
  848. package/src/wirings/workflow/graph/index.ts +0 -15
@@ -5,8 +5,9 @@ import { createScenarioRunner } from './pikku-scenario-service.js'
5
5
  import type { InMemoryWorkflowService } from '../../services/in-memory-workflow-service.js'
6
6
  import { pikkuState, resetPikkuState } from '../../pikku-state.js'
7
7
  import { addFunction } from '../../function/function-runner.js'
8
- import type { ScenarioActor } from '../../services/scenario-actors-service.js'
8
+ import type { ScenarioPersona } from '../../services/personas-service.js'
9
9
  import type { PikkuWire } from '../../types/core.types.js'
10
+ import type { ScenarioSurface } from './scenario-step.types.js'
10
11
  import { requireActor, requireScenarioEnv } from './scenario-step-guards.js'
11
12
 
12
13
  const noopLogger = { error() {}, info() {}, warn() {}, debug() {} }
@@ -14,7 +15,7 @@ const noopLogger = { error() {}, info() {}, warn() {}, debug() {} }
14
15
  const fakeActor = (
15
16
  name: string,
16
17
  handler: (rpcName: string, data: unknown) => Promise<unknown>
17
- ): ScenarioActor & { calls: Array<{ rpcName: string; data: unknown }> } => {
18
+ ): ScenarioPersona & { calls: Array<{ rpcName: string; data: unknown }> } => {
18
19
  const calls: Array<{ rpcName: string; data: unknown }> = []
19
20
  return {
20
21
  name,
@@ -87,8 +88,6 @@ describe('scenario actor steps (workflow.do with `actor`)', () => {
87
88
  const first = await wire.do('step', 'someRpc', {}, { actor: yasser })
88
89
  assert.deepEqual(first, { n: 1 })
89
90
 
90
- // Simulate replay: reset per-run ordinals so the same logical step name
91
- // resolves to the same durable step key.
92
91
  await (ws as any).beginReplay(runId)
93
92
  const replayWire = ws.createWorkflowWire('scenarioTest', runId, {})
94
93
  const replayed = await replayWire.do(
@@ -113,7 +112,6 @@ describe('scenario actor steps (workflow.do with `actor`)', () => {
113
112
  },
114
113
  },
115
114
  })
116
- // Function meta says this RPC would normally dispatch via the queue.
117
115
  pikkuState(null, 'function', 'meta').queuedRpc = {
118
116
  pikkuFuncId: 'queuedRpc',
119
117
  workflowQueued: true,
@@ -146,20 +144,18 @@ const registerStep = (
146
144
  name: string,
147
145
  config: {
148
146
  description?: string
149
- browser?: boolean
147
+ surfaces?: ScenarioSurface[]
150
148
  func: (services: any, data: any, wire: PikkuWire) => Promise<unknown>
151
149
  }
152
150
  ) => {
153
151
  addFunction(name, config as any)
154
- // `pikkuScenarioStep` maps to PikkuFunctionSessionless, which is what the
155
- // inspector records — a step is driven by an actor, not by a wire session.
156
152
  pikkuState(null, 'function', 'meta')[name] = {
157
153
  pikkuFuncId: name,
158
154
  sessionless: true,
159
155
  } as any
160
156
  }
161
157
 
162
- describe('pikkuScenarioStep (scenario.step/given/when/then)', () => {
158
+ describe('pikkuScenarioStep (scenario.given/when/then)', () => {
163
159
  beforeEach(() => resetPikkuState())
164
160
 
165
161
  test('the step func is called with the phase, step identity and data on the wire', async () => {
@@ -206,12 +202,11 @@ describe('pikkuScenarioStep (scenario.step/given/when/then)', () => {
206
202
 
207
203
  const runId = await setup(ws)
208
204
  const wire = ws.createWorkflowWire('scenarioTest', runId, {})
209
- await wire.step('a', 'noop')
210
205
  await wire.given('b', 'noop')
211
206
  await wire.when('c', 'noop')
212
207
  await wire.then('d', 'noop')
213
208
 
214
- assert.deepEqual(phases, ['step', 'given', 'when', 'then'])
209
+ assert.deepEqual(phases, ['given', 'when', 'then'])
215
210
  })
216
211
 
217
212
  test('the actor is handed to the step rather than used to dispatch it', async () => {
@@ -295,7 +290,7 @@ describe('pikkuScenarioStep (scenario.step/given/when/then)', () => {
295
290
 
296
291
  const runId = await setup(ws)
297
292
  const wire = ws.createWorkflowWire('scenarioTest', runId, {})
298
- const result = await wire.step('waits for the page', 'flaky', undefined, {
293
+ const result = await wire.when('waits for the page', 'flaky', undefined, {
299
294
  retries: 3,
300
295
  retryDelay: 1,
301
296
  })
@@ -306,9 +301,10 @@ describe('pikkuScenarioStep (scenario.step/given/when/then)', () => {
306
301
 
307
302
  test('a browser step fails loudly when no provider is registered', async () => {
308
303
  const { workflowService: ws, scenarioService } = createScenarioRunner()
304
+ scenarioService.setRunSurface('browser')
309
305
  const shopper = fakeActor('shopper', async () => ({}))
310
306
  registerStep('visitsCheckout', {
311
- browser: true,
307
+ surfaces: ['browser'],
312
308
  func: async () => null,
313
309
  })
314
310
 
@@ -325,6 +321,7 @@ describe('pikkuScenarioStep (scenario.step/given/when/then)', () => {
325
321
 
326
322
  test('a registered provider hands the step a session keyed by the actor', async () => {
327
323
  const { workflowService: ws, scenarioService } = createScenarioRunner()
324
+ scenarioService.setRunSurface('browser')
328
325
  const shopper = fakeActor('shopper', async () => ({}))
329
326
  const requested: string[] = []
330
327
  const session = { actor: 'shopper' } as any
@@ -337,7 +334,7 @@ describe('pikkuScenarioStep (scenario.step/given/when/then)', () => {
337
334
 
338
335
  let handed: unknown
339
336
  registerStep('visitsCheckout', {
340
- browser: true,
337
+ surfaces: ['browser'],
341
338
  func: async (_services, _data, wire) => {
342
339
  handed = wire.browser
343
340
  return null
@@ -354,13 +351,164 @@ describe('pikkuScenarioStep (scenario.step/given/when/then)', () => {
354
351
  assert.equal(handed, session)
355
352
  })
356
353
 
354
+ test('an action step falls back to its default binding rather than failing', async () => {
355
+ const { workflowService: ws, scenarioService } = createScenarioRunner()
356
+ scenarioService.setRunSurface('browser')
357
+ const ran: ScenarioSurface[] = []
358
+ registerStep('seedsAnAccount', {
359
+ surfaces: ['default'],
360
+ func: async (_services, _data, wire) => {
361
+ ran.push(wire.scenarioStep!.surface)
362
+ return null
363
+ },
364
+ })
365
+
366
+ const runId = await setup(ws)
367
+ const wire = ws.createWorkflowWire('scenarioTest', runId, {})
368
+ await wire.given('an account exists', 'seedsAnAccount')
369
+
370
+ assert.deepEqual(ran, ['default'], 'setup does not need a UI to be honest')
371
+ })
372
+
373
+ test('an action step with no runnable binding fails rather than silently skipping', async () => {
374
+ const { workflowService: ws, scenarioService } = createScenarioRunner()
375
+ scenarioService.setRunSurface('cli')
376
+ registerStep('clicksBuy', {
377
+ surfaces: ['browser'],
378
+ func: async () => null,
379
+ })
380
+
381
+ const runId = await setup(ws)
382
+ const wire = ws.createWorkflowWire('scenarioTest', runId, {})
383
+
384
+ await assert.rejects(
385
+ wire.when('shopper buys it', 'clicksBuy'),
386
+ /declares no binding for 'cli'/
387
+ )
388
+ })
389
+
390
+ test('a then step runs every witness, surface first', async () => {
391
+ const { workflowService: ws, scenarioService } = createScenarioRunner()
392
+ scenarioService.setRunSurface('browser')
393
+ scenarioService.setScenarioBrowserProvider({
394
+ sessionFor: async () => ({ actor: 'shopper' }) as any,
395
+ } as any)
396
+ const shopper = fakeActor('shopper', async () => ({}))
397
+ const ran: ScenarioSurface[] = []
398
+ registerStep('seesTheOrderConfirmed', {
399
+ surfaces: ['browser', 'default'],
400
+ func: async (_services, _data, wire) => {
401
+ ran.push(wire.scenarioStep!.surface)
402
+ return { status: 'paid' }
403
+ },
404
+ })
405
+
406
+ const runId = await setup(ws)
407
+ const wire = ws.createWorkflowWire('scenarioTest', runId, {})
408
+ await wire.then(
409
+ 'shopper sees the order confirmed',
410
+ 'seesTheOrderConfirmed',
411
+ undefined,
412
+ { actor: shopper }
413
+ )
414
+
415
+ assert.deepEqual(ran, ['browser', 'default'])
416
+ })
417
+
418
+ test('the page saying something else than the database is a failure', async () => {
419
+ const { workflowService: ws, scenarioService } = createScenarioRunner()
420
+ scenarioService.setRunSurface('browser')
421
+ scenarioService.setScenarioBrowserProvider({
422
+ sessionFor: async () => ({ actor: 'shopper' }) as any,
423
+ } as any)
424
+ const shopper = fakeActor('shopper', async () => ({}))
425
+ registerStep('seesTheOrderConfirmed', {
426
+ surfaces: ['browser', 'default'],
427
+ func: async (_services, _data, wire) =>
428
+ wire.scenarioStep!.surface === 'browser'
429
+ ? { status: 'pending' }
430
+ : { status: 'paid' },
431
+ })
432
+
433
+ const runId = await setup(ws)
434
+ const wire = ws.createWorkflowWire('scenarioTest', runId, {})
435
+
436
+ await assert.rejects(
437
+ wire.then(
438
+ 'shopper sees the order confirmed',
439
+ 'seesTheOrderConfirmed',
440
+ undefined,
441
+ { actor: shopper }
442
+ ),
443
+ /observed different things on different surfaces/
444
+ )
445
+ })
446
+
447
+ test('a default run pays for only one witness', async () => {
448
+ const { workflowService: ws, scenarioService } = createScenarioRunner()
449
+ const ran: ScenarioSurface[] = []
450
+ registerStep('seesTheOrderConfirmed', {
451
+ surfaces: ['browser', 'default'],
452
+ func: async (_services, _data, wire) => {
453
+ ran.push(wire.scenarioStep!.surface)
454
+ return { status: 'paid' }
455
+ },
456
+ })
457
+
458
+ const runId = await setup(ws)
459
+ const wire = ws.createWorkflowWire('scenarioTest', runId, {})
460
+ await wire.then('shopper sees the order confirmed', 'seesTheOrderConfirmed')
461
+
462
+ assert.deepEqual(ran, ['default'])
463
+ })
464
+
465
+ test('an assertion with no witness for the run fails instead of passing having checked nothing', async () => {
466
+ const { workflowService: ws, scenarioService } = createScenarioRunner()
467
+ scenarioService.setRunSurface('cli')
468
+ let ran = 0
469
+ registerStep('seesTheBanner', {
470
+ surfaces: ['browser'],
471
+ func: async () => {
472
+ ran++
473
+ return { visible: true }
474
+ },
475
+ })
476
+
477
+ const runId = await setup(ws)
478
+ const wire = ws.createWorkflowWire('scenarioTest', runId, {})
479
+
480
+ await assert.rejects(
481
+ wire.then('shopper sees the banner', 'seesTheBanner'),
482
+ /has no witness to run on 'cli'/
483
+ )
484
+ assert.equal(ran, 0, 'nothing ran — which is exactly why it must not pass')
485
+ })
486
+
487
+ test('a browser-only assertion is not silently skipped by the fast suite', async () => {
488
+ // The fast path is where this is most dangerous: `--run default` prints no
489
+ // coverage line, so a skipped assertion would leave no trace at all.
490
+ const { workflowService: ws, scenarioService } = createScenarioRunner()
491
+ registerStep('seesTheBanner', {
492
+ surfaces: ['browser'],
493
+ func: async () => ({ visible: true }),
494
+ })
495
+
496
+ const runId = await setup(ws)
497
+ const wire = ws.createWorkflowWire('scenarioTest', runId, {})
498
+
499
+ await assert.rejects(
500
+ wire.then('shopper sees the banner', 'seesTheBanner'),
501
+ /has no witness to run on 'default'/
502
+ )
503
+ })
504
+
357
505
  test('a non-string step target is rejected instead of silently dispatching', async () => {
358
506
  const { workflowService: ws, scenarioService } = createScenarioRunner()
359
507
  const runId = await setup(ws)
360
508
  const wire = ws.createWorkflowWire('scenarioTest', runId, {})
361
509
 
362
510
  await assert.rejects(
363
- (wire.step as any)('a name', async () => 'inline'),
511
+ (wire.when as any)('a name', async () => 'inline'),
364
512
  /string/i
365
513
  )
366
514
  })
@@ -446,8 +594,6 @@ describe('scenario step input is recorded on the run', () => {
446
594
  packageName: '@pikku/addon-todos',
447
595
  })
448
596
 
449
- // A reporter renders each step's prose from this, so two calls to one step
450
- // must be distinguishable by what they were asked to check.
451
597
  const steps = await ws.getRunSteps(runId)
452
598
  assert.deepEqual(
453
599
  steps.map((step) => step.data),
@@ -496,8 +642,6 @@ describe('scenario step names its function on the run', () => {
496
642
 
497
643
  const runId = await setup(ws)
498
644
  const wire = ws.createWorkflowWire('scenarioTest', runId, {})
499
- // What a loop produces: the durable name is the interpolated one, so it
500
- // matches no statically recorded step name.
501
645
  for (const packageName of ['console', 'todos']) {
502
646
  await wire.then(`sees ${packageName}`, 'seesAddon', { packageName })
503
647
  }
@@ -1,28 +1,105 @@
1
- import type { ScenarioActor } from '../../services/scenario-actors-service.js'
1
+ import type { ScenarioPersona } from '../../services/personas-service.js'
2
2
 
3
3
  /**
4
4
  * Scenario steps: named, typed units of scenario behaviour.
5
5
  *
6
6
  * A step's body is an ordinary pikku function, so it may drive a browser, call
7
- * an RPC as its actor, or run a workflow. `given`/`when`/`then` are sugar over
8
- * `step` they only change the prose the reporter renders.
7
+ * an RPC as its actor, or run a workflow. `given` and `when` differ only in the
8
+ * prose the reporter renders; `then` also changes what runs, because its
9
+ * bindings are witnesses — every declared surface is observed and the
10
+ * observations must agree. See {@link ScenarioSurfaceResolution}.
9
11
  */
10
12
 
11
13
  /**
12
- * Which Gherkin-style keyword the reporter prefixes this step with. `step`
13
- * renders no prefix at all.
14
+ * Which Gherkin-style keyword the reporter prefixes this step with.
15
+ *
16
+ * Every step takes one. A scenario is read by people deciding whether it
17
+ * describes the behaviour they wanted, and a step that says only what it does
18
+ * without saying whether it is setup, action or claim is the one nobody can
19
+ * check — which is also why PKU680 can tell a scenario that never asserts.
20
+ */
21
+ export type ScenarioStepPhase = 'given' | 'when' | 'then'
22
+
23
+ /**
24
+ * Who acts in a step.
25
+ *
26
+ * `persona` is a person driving the system through one of its surfaces — the
27
+ * ordinary `pikkuScenarioStep`. `platform` is the app acting on itself ("the
28
+ * platform has expired the trial"), and `addon` is a third-party system acting
29
+ * on it ("Stripe's webhook arrives"), contributed by the addon that wraps that
30
+ * service.
31
+ *
32
+ * The three are separate declarations rather than a field on one, so the
33
+ * inspector verifies a step's kind by which function was called rather than by
34
+ * trusting a string literal — and so an addon package exports only addon steps,
35
+ * which is checkable.
14
36
  */
15
- export type ScenarioStepPhase = 'step' | 'given' | 'when' | 'then'
37
+ export type ScenarioStepKind = 'persona' | 'platform' | 'addon'
16
38
 
17
39
  /**
18
- * Options accepted by `scenario.step/given/when/then`.
40
+ * How an actor drives the system for one step.
41
+ *
42
+ * A step declares one implementation per surface it supports, and the runner
43
+ * picks between them — so the same ladder can run through a real browser, over
44
+ * the websocket, or entirely server-side.
45
+ *
46
+ * `default` is the floor: it is what every other surface falls back to, so it
47
+ * can never itself fall back.
48
+ */
49
+ export type ScenarioSurface = 'browser' | 'cli' | 'default'
50
+
51
+ export const SCENARIO_SURFACES: readonly ScenarioSurface[] = [
52
+ 'browser',
53
+ 'cli',
54
+ 'default',
55
+ ]
56
+
57
+ /**
58
+ * How a step's declared surfaces resolve for one run.
59
+ *
60
+ * `given`/`when` bindings are **alternatives** — clicking Buy and calling
61
+ * `createOrder` are two ways to cause one effect, so exactly one runs.
62
+ *
63
+ * `then` bindings are **witnesses** — "the order row says paid" and "the
64
+ * confirmation panel says paid" are different claims that share a name, and the
65
+ * gap between them is the bug nobody catches. So every declared witness runs and
66
+ * they must agree.
67
+ */
68
+ export type ScenarioSurfaceResolution =
69
+ | {
70
+ kind: 'action'
71
+ surface: ScenarioSurface
72
+ /** The run asked for a surface this step does not implement. */
73
+ fellBack: boolean
74
+ }
75
+ | {
76
+ kind: 'witness'
77
+ /**
78
+ * Every witness to run, surface first. Empty means the assertion has no
79
+ * binding this run can execute at all — nothing would check anything, so
80
+ * the step fails rather than reporting a pass it never earned.
81
+ */
82
+ surfaces: ScenarioSurface[]
83
+ /**
84
+ * Something checked the assertion, but not on the surface its prose
85
+ * claims — so nobody looked at the UI. Reported as its own state and
86
+ * counted against coverage: not being in the UI *is* the finding.
87
+ *
88
+ * Disjoint from an empty `surfaces`; an assertion that ran nowhere is a
89
+ * failure, not a coverage statistic.
90
+ */
91
+ unwitnessed: boolean
92
+ }
93
+
94
+ /**
95
+ * Options accepted by `scenario.given/when/then`.
19
96
  *
20
97
  * Note the retry default differs from an ordinary workflow step: retrying a
21
98
  * failed assertion is the wrong behaviour for a test primitive, so steps
22
99
  * default to no retries.
23
100
  */
24
101
  export interface ScenarioStepOptions {
25
- /** The actor this step runs as. Required for steps declaring `browser: true`. */
102
+ /** The actor this step runs as. Required for steps declaring a `browser` binding. */
26
103
  actor?: unknown
27
104
  /** Overrides the step's own `description` for this call site only. */
28
105
  description?: string
@@ -33,7 +110,7 @@ export interface ScenarioStepOptions {
33
110
 
34
111
  /**
35
112
  * The environment a scenario run targets, as declared in pikku.config.json
36
- * under `scenarios.environments`.
113
+ * under `environments`.
37
114
  */
38
115
  export interface ScenarioEnvironment {
39
116
  /** Base API URL of the target app, INCLUDING the HTTP prefix. */
@@ -46,16 +123,21 @@ export interface ScenarioEnvironment {
46
123
  * The `scenarioStep` wire, present on every scenario step invocation.
47
124
  *
48
125
  * `TActor` is the project's own actor type, so a step reaches only the RPCs its
49
- * actors can actually call. It defaults to the open `ScenarioActor` for a
126
+ * actors can actually call. It defaults to the open `ScenarioPersona` for a
50
127
  * project that declares no registry.
51
128
  */
52
- export interface PikkuScenarioStepWire<TActor = ScenarioActor> {
129
+ export interface PikkuScenarioStepWire<TActor = ScenarioPersona> {
53
130
  /** Registered step name (also its pikkuFuncId) */
54
131
  name: string
55
132
  /** Durable key within the run; may carry an `#ordinal` suffix when repeated */
56
133
  stepName: string
57
134
  runId: string
58
135
  phase: ScenarioStepPhase
136
+ /**
137
+ * Which of the step's bindings is currently executing. A `then` step runs once
138
+ * per witness, so its body sees this change between invocations.
139
+ */
140
+ surface: ScenarioSurface
59
141
  /**
60
142
  * The actor this step runs as, when one was given. Call RPCs through it
61
143
  * (`actor.invoke(...)`) so they run against the target environment as that
@@ -96,7 +178,7 @@ export interface TestIdSelector {
96
178
 
97
179
  /**
98
180
  * Structural browser handle, present only when the runner provisioned a
99
- * browser for this step (`browser: true` on the step config).
181
+ * browser for this step (a `browser` binding on the step config).
100
182
  *
101
183
  * `@pikku/core` deliberately never imports playwright — it must stay
102
184
  * dependency-free for edge runtimes. `@pikku/playwright` augments this
@@ -0,0 +1,146 @@
1
+ import { describe, test } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+ import { resolveScenarioSurfaces, witnessesAgree } from './scenario-surface.js'
4
+ import type { ScenarioSurface } from './scenario-step.types.js'
5
+
6
+ const ALL: ScenarioSurface[] = ['browser', 'cli', 'default']
7
+
8
+ describe('action steps pick exactly one binding', () => {
9
+ test('runs the binding the run asked for', () => {
10
+ assert.deepEqual(resolveScenarioSurfaces('when', ALL, 'browser'), {
11
+ kind: 'action',
12
+ surface: 'browser',
13
+ fellBack: false,
14
+ })
15
+ })
16
+
17
+ test('falls back to default and says so when the surface is not implemented', () => {
18
+ assert.deepEqual(resolveScenarioSurfaces('when', ['default'], 'browser'), {
19
+ kind: 'action',
20
+ surface: 'default',
21
+ fellBack: true,
22
+ })
23
+ })
24
+
25
+ test('given resolves like when, not like then', () => {
26
+ assert.deepEqual(resolveScenarioSurfaces('given', ALL, 'cli'), {
27
+ kind: 'action',
28
+ surface: 'cli',
29
+ fellBack: false,
30
+ })
31
+ })
32
+
33
+ test('a default run never counts as a fallback', () => {
34
+ assert.deepEqual(resolveScenarioSurfaces('when', ['default'], 'default'), {
35
+ kind: 'action',
36
+ surface: 'default',
37
+ fellBack: false,
38
+ })
39
+ })
40
+ })
41
+
42
+ describe('then steps run every witness', () => {
43
+ test('a browser run checks the page AND the system of record', () => {
44
+ assert.deepEqual(
45
+ resolveScenarioSurfaces('then', ['browser', 'default'], 'browser'),
46
+ { kind: 'witness', surfaces: ['browser', 'default'], unwitnessed: false }
47
+ )
48
+ })
49
+
50
+ test('the surface witness comes first, so its failure is the one reported', () => {
51
+ const resolution = resolveScenarioSurfaces(
52
+ 'then',
53
+ ['default', 'browser'],
54
+ 'browser'
55
+ )
56
+ assert.equal(resolution.kind, 'witness')
57
+ assert.deepEqual(
58
+ resolution.kind === 'witness' ? resolution.surfaces[0] : null,
59
+ 'browser'
60
+ )
61
+ })
62
+
63
+ test('a default run is unchanged — one witness, no extra cost', () => {
64
+ assert.deepEqual(
65
+ resolveScenarioSurfaces('then', ['browser', 'default'], 'default'),
66
+ { kind: 'witness', surfaces: ['default'], unwitnessed: false }
67
+ )
68
+ })
69
+
70
+ test('no witness for the run surface is flagged rather than excused', () => {
71
+ assert.deepEqual(resolveScenarioSurfaces('then', ['default'], 'browser'), {
72
+ kind: 'witness',
73
+ surfaces: ['default'],
74
+ unwitnessed: true,
75
+ })
76
+ })
77
+
78
+ test('a browser-only assertion has nothing to run on a default run', () => {
79
+ // No witness at all is not a coverage statistic — nothing checked anything,
80
+ // so `unwitnessed` stays false and the caller is expected to fail the step.
81
+ assert.deepEqual(resolveScenarioSurfaces('then', ['browser'], 'default'), {
82
+ kind: 'witness',
83
+ surfaces: [],
84
+ unwitnessed: false,
85
+ })
86
+ })
87
+
88
+ test('an assertion that runs nowhere is not counted as merely unwitnessed', () => {
89
+ assert.deepEqual(resolveScenarioSurfaces('then', ['browser'], 'cli'), {
90
+ kind: 'witness',
91
+ surfaces: [],
92
+ unwitnessed: false,
93
+ })
94
+ })
95
+
96
+ test('unwitnessed means checked somewhere else, never checked nowhere', () => {
97
+ const ranElsewhere = resolveScenarioSurfaces('then', ['default'], 'cli')
98
+ assert.equal(ranElsewhere.kind, 'witness')
99
+ assert.ok(
100
+ ranElsewhere.kind === 'witness' && ranElsewhere.surfaces.length > 0,
101
+ 'the two states are disjoint: unwitnessed always has something that ran'
102
+ )
103
+ assert.equal(
104
+ ranElsewhere.kind === 'witness' && ranElsewhere.unwitnessed,
105
+ true
106
+ )
107
+ })
108
+ })
109
+
110
+ describe('witness agreement', () => {
111
+ test('key order does not make two observations disagree', () => {
112
+ assert.equal(
113
+ witnessesAgree(
114
+ { status: 'paid', total: 500 },
115
+ { total: 500, status: 'paid' }
116
+ ),
117
+ true
118
+ )
119
+ })
120
+
121
+ test('a page showing something else is a disagreement', () => {
122
+ assert.equal(
123
+ witnessesAgree({ status: 'paid' }, { status: 'pending' }),
124
+ false
125
+ )
126
+ })
127
+
128
+ test('a witness that asserted by throwing is not compared', () => {
129
+ assert.equal(witnessesAgree(undefined, { status: 'paid' }), true)
130
+ assert.equal(witnessesAgree({ status: 'paid' }, undefined), true)
131
+ })
132
+
133
+ test('nested observations compare structurally', () => {
134
+ assert.equal(
135
+ witnessesAgree(
136
+ { order: { items: [{ sku: 'a' }, { sku: 'b' }] } },
137
+ { order: { items: [{ sku: 'a' }, { sku: 'b' }] } }
138
+ ),
139
+ true
140
+ )
141
+ assert.equal(
142
+ witnessesAgree({ items: ['a', 'b'] }, { items: ['b', 'a'] }),
143
+ false
144
+ )
145
+ })
146
+ })
@@ -0,0 +1,71 @@
1
+ import type {
2
+ ScenarioStepPhase,
3
+ ScenarioSurface,
4
+ ScenarioSurfaceResolution,
5
+ } from './scenario-step.types.js'
6
+
7
+ /**
8
+ * Resolve which of a step's declared bindings run, for one step, in one run.
9
+ *
10
+ * The asymmetry between phases is the whole point — see
11
+ * {@link ScenarioSurfaceResolution}.
12
+ */
13
+ export const resolveScenarioSurfaces = (
14
+ phase: ScenarioStepPhase,
15
+ declared: readonly ScenarioSurface[],
16
+ runSurface: ScenarioSurface
17
+ ): ScenarioSurfaceResolution => {
18
+ const has = (surface: ScenarioSurface) => declared.includes(surface)
19
+
20
+ if (phase !== 'then') {
21
+ if (has(runSurface)) {
22
+ return { kind: 'action', surface: runSurface, fellBack: false }
23
+ }
24
+ return { kind: 'action', surface: 'default', fellBack: true }
25
+ }
26
+
27
+ const surfaces: ScenarioSurface[] = []
28
+ if (runSurface !== 'default' && has(runSurface)) {
29
+ surfaces.push(runSurface)
30
+ }
31
+ if (has('default')) {
32
+ surfaces.push('default')
33
+ }
34
+ return {
35
+ kind: 'witness',
36
+ surfaces,
37
+ // Only meaningful once something ran: an assertion checked server-side
38
+ // under `--run browser` is a coverage gap, but one checked nowhere at all
39
+ // is a step that did not happen, which the caller fails rather than counts.
40
+ unwitnessed:
41
+ surfaces.length > 0 && runSurface !== 'default' && !has(runSurface),
42
+ }
43
+ }
44
+
45
+ /**
46
+ * Structural comparison of two witnesses' observations.
47
+ *
48
+ * A witness that returns `undefined` asserted by throwing rather than by
49
+ * reporting what it saw, so it is not compared — that keeps assertion-style
50
+ * steps working without forcing every one of them to return a value.
51
+ */
52
+ export const witnessesAgree = (a: unknown, b: unknown): boolean => {
53
+ if (a === undefined || b === undefined) {
54
+ return true
55
+ }
56
+ return stableStringify(a) === stableStringify(b)
57
+ }
58
+
59
+ const stableStringify = (value: unknown): string => {
60
+ if (value === null || typeof value !== 'object') {
61
+ return JSON.stringify(value) ?? 'undefined'
62
+ }
63
+ if (Array.isArray(value)) {
64
+ return `[${value.map(stableStringify).join(',')}]`
65
+ }
66
+ const entries = Object.entries(value as Record<string, unknown>)
67
+ .filter(([, v]) => v !== undefined)
68
+ .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
69
+ .map(([k, v]) => `${JSON.stringify(k)}:${stableStringify(v)}`)
70
+ return `{${entries.join(',')}}`
71
+ }