@pikku/core 0.12.142 → 0.12.144

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 (703) hide show
  1. package/dist/analytics/analytics.d.ts +14 -0
  2. package/dist/analytics/analytics.js +14 -0
  3. package/dist/analytics/analytics.types.d.ts +1 -0
  4. package/dist/analytics/anonymous-analytics-identity.d.ts +1 -0
  5. package/dist/analytics/cookie-analytics-identity.d.ts +1 -0
  6. package/dist/analytics/mint-cookie.d.ts +1 -0
  7. package/dist/{wirings/channel/channel-middleware-runner.d.ts → channel-middleware-runner.d.ts} +17 -3
  8. package/dist/{wirings/channel/channel-middleware-runner.js → channel-middleware-runner.js} +24 -8
  9. package/dist/classification/data-classification.d.ts +13 -0
  10. package/dist/classification/secret-value.d.ts +7 -0
  11. package/dist/classification/secret-value.js +7 -0
  12. package/dist/crypto-utils.d.ts +93 -0
  13. package/dist/crypto-utils.js +92 -0
  14. package/dist/dev/hot-reload.d.ts +16 -0
  15. package/dist/dev/hot-reload.js +16 -1
  16. package/dist/dev/module-runner.js +7 -3
  17. package/dist/dev/reload-meta.js +1 -1
  18. package/dist/errors/error-handler.d.ts +9 -0
  19. package/dist/errors/error-handler.js +8 -0
  20. package/dist/errors/errors.d.ts +219 -0
  21. package/dist/errors/errors.js +227 -0
  22. package/dist/errors/serialized-error.d.ts +4 -0
  23. package/dist/function/abort-scope.d.ts +5 -0
  24. package/dist/function/function-meta.types.d.ts +20 -0
  25. package/dist/function/function-runner.d.ts +41 -0
  26. package/dist/function/function-runner.js +57 -11
  27. package/dist/function/functions.types.d.ts +59 -0
  28. package/dist/function/functions.types.js +23 -0
  29. package/dist/function/list.types.d.ts +4 -0
  30. package/dist/lifecycle.d.ts +12 -1
  31. package/dist/lifecycle.js +12 -1
  32. package/dist/middleware/addon-scope-cap.d.ts +4 -0
  33. package/dist/middleware/addon-scope-cap.js +7 -3
  34. package/dist/middleware/auth-apikey.js +3 -3
  35. package/dist/middleware/auth-bearer.js +5 -13
  36. package/dist/middleware/auth-cookie.js +3 -3
  37. package/dist/middleware/middleware-factories.d.ts +17 -0
  38. package/dist/middleware/middleware-factories.js +17 -0
  39. package/dist/middleware/middleware.types.d.ts +23 -0
  40. package/dist/middleware/remote-auth.d.ts +15 -0
  41. package/dist/middleware/remote-auth.js +18 -3
  42. package/dist/middleware/remote-jobs-secret.js +2 -10
  43. package/dist/middleware-runner.d.ts +7 -0
  44. package/dist/middleware-runner.js +23 -7
  45. package/dist/permissions.d.ts +13 -0
  46. package/dist/permissions.js +13 -0
  47. package/dist/pikku-state.d.ts +49 -0
  48. package/dist/pikku-state.js +49 -0
  49. package/dist/remote.js +20 -5
  50. package/dist/schema.d.ts +36 -0
  51. package/dist/schema.js +36 -0
  52. package/dist/services/agent-run-state-service.d.ts +8 -0
  53. package/dist/services/agent-runner-service.d.ts +24 -0
  54. package/dist/services/agent-storage-service.d.ts +8 -0
  55. package/dist/services/ai-embedding-service.d.ts +4 -0
  56. package/dist/services/audit-service.d.ts +48 -0
  57. package/dist/services/audit-service.js +22 -0
  58. package/dist/services/content-service.d.ts +34 -0
  59. package/dist/services/credential-wire-service.d.ts +9 -0
  60. package/dist/services/credential-wire-service.js +9 -0
  61. package/dist/services/deployment-service.d.ts +14 -0
  62. package/dist/services/email-service.d.ts +20 -0
  63. package/dist/services/email-template.d.ts +24 -0
  64. package/dist/services/email-template.js +12 -0
  65. package/dist/services/file-scenario-run-store.d.ts +5 -0
  66. package/dist/services/file-scenario-run-store.js +4 -0
  67. package/dist/services/gateway-service.d.ts +5 -0
  68. package/dist/services/in-memory-agent-run-state-service.d.ts +5 -0
  69. package/dist/services/in-memory-agent-run-state-service.js +5 -0
  70. package/dist/services/in-memory-lease-service.d.ts +5 -0
  71. package/dist/services/in-memory-lease-service.js +5 -0
  72. package/dist/services/in-memory-session-store.d.ts +4 -0
  73. package/dist/services/in-memory-session-store.js +4 -0
  74. package/dist/services/incoming-webhook-queue.d.ts +2 -0
  75. package/dist/services/incoming-webhook-queue.js +2 -0
  76. package/dist/services/incoming-webhook-service.d.ts +11 -1
  77. package/dist/services/incoming-webhook-service.js +5 -1
  78. package/dist/services/index.d.ts +1 -5
  79. package/dist/services/index.js +1 -5
  80. package/dist/services/jwt-service.d.ts +8 -0
  81. package/dist/services/lease-service.d.ts +5 -0
  82. package/dist/services/lease-service.js +1 -0
  83. package/dist/services/local-content-request-handler.d.ts +20 -0
  84. package/dist/services/local-content-request-handler.js +11 -0
  85. package/dist/services/local-content.d.ts +45 -0
  86. package/dist/services/local-content.js +35 -0
  87. package/dist/services/local-credential-service.d.ts +5 -0
  88. package/dist/services/local-credential-service.js +5 -0
  89. package/dist/services/local-email-service.d.ts +7 -0
  90. package/dist/services/local-email-service.js +7 -0
  91. package/dist/services/local-secrets.d.ts +8 -0
  92. package/dist/services/local-secrets.js +8 -0
  93. package/dist/services/local-variables.d.ts +6 -0
  94. package/dist/services/local-variables.js +6 -0
  95. package/dist/services/logger.d.ts +4 -0
  96. package/dist/services/logger.js +4 -0
  97. package/dist/services/meta-service.d.ts +38 -0
  98. package/dist/services/meta-service.js +6 -0
  99. package/dist/services/queue-webhook-service.d.ts +19 -0
  100. package/dist/services/queue-webhook-service.js +19 -0
  101. package/dist/services/remote-jobs.d.ts +8 -13
  102. package/dist/services/remote-jobs.js +3 -54
  103. package/dist/services/scenario-cookie-jar.d.ts +4 -0
  104. package/dist/services/scheduler-service.d.ts +16 -0
  105. package/dist/services/scheduler-service.js +12 -0
  106. package/dist/services/schema-service.d.ts +9 -0
  107. package/dist/services/scope-service.d.ts +10 -0
  108. package/dist/services/scoped-secret-service.d.ts +5 -0
  109. package/dist/services/scoped-secret-service.js +5 -0
  110. package/dist/services/secret-host-binding.d.ts +5 -0
  111. package/dist/services/secret-host-binding.js +5 -0
  112. package/dist/services/secret-service.d.ts +19 -1
  113. package/dist/services/secretless.d.ts +6 -0
  114. package/dist/services/secretless.js +6 -0
  115. package/dist/services/session-store.d.ts +5 -0
  116. package/dist/services/stub-tracker.d.ts +1 -0
  117. package/dist/services/temporary-file-service.d.ts +9 -0
  118. package/dist/services/temporary-file-service.js +9 -0
  119. package/dist/services/trigger-service.d.ts +4 -0
  120. package/dist/services/trigger-source-store.d.ts +13 -0
  121. package/dist/services/trigger-source-store.js +7 -0
  122. package/dist/services/typed-credential-service.d.ts +6 -0
  123. package/dist/services/typed-credential-service.js +5 -0
  124. package/dist/services/typed-secret-service.d.ts +12 -0
  125. package/dist/services/typed-secret-service.js +11 -0
  126. package/dist/services/typed-variables-service.d.ts +1 -0
  127. package/dist/services/user-session-service.d.ts +31 -1
  128. package/dist/services/user-session-service.js +29 -3
  129. package/dist/services/v8-coverage-service.d.ts +27 -0
  130. package/dist/services/v8-coverage-service.js +5 -0
  131. package/dist/services/variables-service.d.ts +8 -0
  132. package/dist/services/virtual-user-sign-in.d.ts +1 -0
  133. package/dist/services/virtual-user-statement.d.ts +8 -0
  134. package/dist/services/virtual-user-statement.js +4 -0
  135. package/dist/services/webhook-service.d.ts +25 -0
  136. package/dist/services/webhook-service.js +15 -0
  137. package/dist/services/workflow-service.d.ts +6 -0
  138. package/dist/test-utils.js +1 -1
  139. package/dist/testing/service-tests.d.ts +4 -0
  140. package/dist/time-utils.d.ts +15 -0
  141. package/dist/time-utils.js +14 -0
  142. package/dist/types/core.types.d.ts +80 -0
  143. package/dist/types/state.types.d.ts +4 -0
  144. package/dist/utils/hmac.d.ts +3 -0
  145. package/dist/utils/safe-fetch.d.ts +14 -0
  146. package/dist/utils/safe-fetch.js +13 -0
  147. package/dist/utils/stable-stringify.d.ts +11 -0
  148. package/dist/utils/stable-stringify.js +33 -0
  149. package/dist/utils.d.ts +28 -0
  150. package/dist/utils.js +22 -0
  151. package/dist/version.d.ts +7 -0
  152. package/dist/version.js +7 -0
  153. package/dist/wirings/addon/define-screens.d.ts +2 -0
  154. package/dist/wirings/addon/remote-addon-auth.d.ts +9 -0
  155. package/dist/wirings/addon/remote-addon-auth.js +5 -0
  156. package/dist/wirings/addon/wire-addon.d.ts +4 -0
  157. package/dist/wirings/addon/wire-remote-addon.d.ts +1 -0
  158. package/dist/wirings/agent/agent-agui.d.ts +14 -5
  159. package/dist/wirings/agent/agent-agui.js +17 -6
  160. package/dist/wirings/agent/agent-helpers.d.ts +61 -1
  161. package/dist/wirings/agent/agent-helpers.js +62 -2
  162. package/dist/wirings/agent/agent-interrupt.d.ts +5 -0
  163. package/dist/wirings/agent/agent-output.d.ts +20 -0
  164. package/dist/wirings/agent/agent-output.js +69 -0
  165. package/dist/wirings/agent/agent-prepare.d.ts +41 -0
  166. package/dist/wirings/agent/agent-prepare.js +38 -2
  167. package/dist/wirings/agent/agent-registry.d.ts +8 -0
  168. package/dist/wirings/agent/agent-registry.js +10 -4
  169. package/dist/wirings/agent/agent-runner.d.ts +33 -0
  170. package/dist/wirings/agent/agent-runner.js +40 -7
  171. package/dist/wirings/agent/agent-stream.d.ts +30 -0
  172. package/dist/wirings/agent/agent-stream.js +33 -11
  173. package/dist/wirings/agent/agent.types.d.ts +43 -0
  174. package/dist/wirings/agent/voice-input.d.ts +12 -0
  175. package/dist/wirings/agent/voice-input.js +12 -0
  176. package/dist/wirings/agent/voice-output.d.ts +14 -0
  177. package/dist/wirings/agent/voice-output.js +10 -0
  178. package/dist/wirings/agent-scorer/agent-scorer-judge.js +1 -2
  179. package/dist/wirings/agent-scorer/agent-scorer-registry.d.ts +10 -0
  180. package/dist/wirings/agent-scorer/agent-scorer-registry.js +10 -0
  181. package/dist/wirings/agent-scorer/agent-scorer-snapshots.d.ts +1 -0
  182. package/dist/wirings/agent-scorer/agent-scorer-snapshots.js +1 -0
  183. package/dist/wirings/agent-scorer/agent-scorer.types.d.ts +7 -0
  184. package/dist/wirings/channel/channel-common.js +1 -1
  185. package/dist/wirings/channel/channel-rpc.types.d.ts +5 -0
  186. package/dist/wirings/channel/channel-runner.d.ts +22 -0
  187. package/dist/wirings/channel/channel-runner.js +22 -0
  188. package/dist/wirings/channel/channel-store.d.ts +8 -0
  189. package/dist/wirings/channel/channel-store.js +7 -0
  190. package/dist/wirings/channel/channel.types.d.ts +18 -0
  191. package/dist/wirings/channel/define-channel-routes.d.ts +5 -0
  192. package/dist/wirings/channel/define-channel-routes.js +5 -0
  193. package/dist/wirings/channel/eventhub-service.d.ts +9 -0
  194. package/dist/wirings/channel/eventhub-store.d.ts +1 -0
  195. package/dist/wirings/channel/eventhub-store.js +1 -0
  196. package/dist/wirings/channel/index.d.ts +1 -1
  197. package/dist/wirings/channel/index.js +1 -1
  198. package/dist/wirings/channel/local/local-channel-handler.d.ts +1 -0
  199. package/dist/wirings/channel/local/local-channel-handler.js +1 -0
  200. package/dist/wirings/channel/local/local-channel-runner.d.ts +13 -0
  201. package/dist/wirings/channel/local/local-channel-runner.js +13 -0
  202. package/dist/wirings/channel/local/local-eventhub-service.d.ts +1 -0
  203. package/dist/wirings/channel/local/local-eventhub-service.js +1 -0
  204. package/dist/wirings/channel/log-channels.d.ts +1 -0
  205. package/dist/wirings/channel/log-channels.js +1 -0
  206. package/dist/wirings/channel/pikku-abstract-channel-handler.d.ts +5 -0
  207. package/dist/wirings/channel/pikku-abstract-channel-handler.js +5 -0
  208. package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +32 -0
  209. package/dist/wirings/channel/serverless/serverless-channel-runner.js +31 -0
  210. package/dist/wirings/cli/channel/cli-channel-runner.d.ts +8 -0
  211. package/dist/wirings/cli/channel/cli-channel-runner.js +8 -0
  212. package/dist/wirings/cli/channel/cli-raw-channel-runner.d.ts +1 -0
  213. package/dist/wirings/cli/cli-runner.d.ts +43 -0
  214. package/dist/wirings/cli/cli-runner.js +43 -0
  215. package/dist/wirings/cli/command-parser.d.ts +13 -0
  216. package/dist/wirings/cli/command-parser.js +12 -0
  217. package/dist/wirings/credential/credential-overrides.d.ts +1 -0
  218. package/dist/wirings/credential/credential.types.d.ts +7 -0
  219. package/dist/wirings/credential/validate-credential-definitions.d.ts +7 -0
  220. package/dist/wirings/credential/validate-credential-definitions.js +7 -0
  221. package/dist/wirings/flag/cached-flag-source.d.ts +1 -0
  222. package/dist/wirings/flag/flag.types.d.ts +3 -0
  223. package/dist/wirings/gateway/gateway-runner.d.ts +23 -0
  224. package/dist/wirings/gateway/gateway-runner.js +23 -0
  225. package/dist/wirings/gateway/gateway.types.d.ts +3 -0
  226. package/dist/wirings/gateway/local-gateway-service.d.ts +10 -0
  227. package/dist/{services → wirings/gateway}/local-gateway-service.js +6 -2
  228. package/dist/wirings/http/http-routes.d.ts +21 -0
  229. package/dist/wirings/http/http-routes.js +11 -0
  230. package/dist/wirings/http/http-runner.d.ts +71 -0
  231. package/dist/wirings/http/http-runner.js +73 -5
  232. package/dist/wirings/http/http.types.d.ts +27 -0
  233. package/dist/wirings/http/index.d.ts +1 -0
  234. package/dist/wirings/http/index.js +1 -0
  235. package/dist/wirings/http/log-http-routes.d.ts +1 -0
  236. package/dist/wirings/http/log-http-routes.js +1 -0
  237. package/dist/wirings/http/merge-request-data.d.ts +12 -0
  238. package/dist/wirings/http/merge-request-data.js +42 -0
  239. package/dist/wirings/http/pikku-fetch-http-request.d.ts +1 -0
  240. package/dist/wirings/http/pikku-fetch-http-request.js +3 -32
  241. package/dist/wirings/http/pikku-fetch-http-response.d.ts +1 -0
  242. package/dist/wirings/http/pikku-fetch-http-response.js +1 -0
  243. package/dist/wirings/http/routers/http-router.d.ts +6 -0
  244. package/dist/wirings/http/routers/http-router.js +6 -0
  245. package/dist/wirings/http/web-request.d.ts +17 -0
  246. package/dist/wirings/http/web-request.js +17 -0
  247. package/dist/wirings/mcp/mcp-endpoint-registry.d.ts +7 -0
  248. package/dist/wirings/mcp/mcp-endpoint-registry.js +7 -0
  249. package/dist/wirings/mcp/mcp-runner.d.ts +63 -0
  250. package/dist/wirings/mcp/mcp-runner.js +62 -0
  251. package/dist/wirings/mcp/mcp.types.d.ts +12 -0
  252. package/dist/wirings/node/node.types.d.ts +4 -0
  253. package/dist/wirings/oauth2/oauth2.types.d.ts +2 -0
  254. package/dist/wirings/queue/in-memory-queue-service.d.ts +23 -0
  255. package/dist/wirings/queue/in-memory-queue-service.js +129 -0
  256. package/dist/wirings/queue/index.d.ts +2 -1
  257. package/dist/wirings/queue/index.js +1 -0
  258. package/dist/wirings/queue/queue-identity.js +2 -14
  259. package/dist/wirings/queue/queue-runner.d.ts +37 -0
  260. package/dist/wirings/queue/queue-runner.js +37 -0
  261. package/dist/wirings/queue/queue.types.d.ts +56 -0
  262. package/dist/wirings/queue/register-queue-helper.d.ts +12 -0
  263. package/dist/wirings/queue/register-queue-helper.js +11 -0
  264. package/dist/wirings/queue/remote-queue-job.d.ts +11 -0
  265. package/dist/wirings/queue/remote-queue-job.js +41 -0
  266. package/dist/wirings/queue/signed-queue-service.d.ts +4 -1
  267. package/dist/wirings/queue/signed-queue-service.js +3 -0
  268. package/dist/wirings/queue/validate-worker-config.d.ts +1 -0
  269. package/dist/wirings/role/role.types.d.ts +3 -0
  270. package/dist/wirings/rpc/rpc-runner.d.ts +24 -0
  271. package/dist/wirings/rpc/rpc-runner.js +37 -2
  272. package/dist/wirings/rpc/rpc-types.d.ts +2 -0
  273. package/dist/wirings/scheduler/index.d.ts +2 -1
  274. package/dist/wirings/scheduler/index.js +1 -0
  275. package/dist/wirings/scheduler/log-schedulers.d.ts +1 -0
  276. package/dist/wirings/scheduler/log-schedulers.js +1 -0
  277. package/dist/wirings/scheduler/remote-scheduled-job.d.ts +11 -0
  278. package/dist/wirings/scheduler/remote-scheduled-job.js +20 -0
  279. package/dist/wirings/scheduler/scheduler-runner.d.ts +29 -0
  280. package/dist/wirings/scheduler/scheduler-runner.js +28 -0
  281. package/dist/wirings/scheduler/scheduler.types.d.ts +15 -0
  282. package/dist/wirings/scope/scope.types.d.ts +5 -0
  283. package/dist/wirings/secret/index.d.ts +2 -2
  284. package/dist/wirings/secret/index.js +1 -1
  285. package/dist/wirings/secret/secret.types.d.ts +26 -1
  286. package/dist/wirings/secret/secret.types.js +1 -0
  287. package/dist/wirings/secret/validate-secret-definitions.d.ts +8 -0
  288. package/dist/wirings/secret/validate-secret-definitions.js +15 -0
  289. package/dist/wirings/trigger/in-memory-trigger-service.d.ts +11 -0
  290. package/dist/{services → wirings/trigger}/in-memory-trigger-service.js +10 -3
  291. package/dist/wirings/trigger/index.d.ts +1 -1
  292. package/dist/wirings/trigger/pikku-trigger-service.d.ts +8 -3
  293. package/dist/wirings/trigger/pikku-trigger-service.js +14 -3
  294. package/dist/wirings/trigger/trigger-runner.d.ts +27 -2
  295. package/dist/wirings/trigger/trigger-runner.js +35 -2
  296. package/dist/wirings/trigger/trigger.types.d.ts +26 -4
  297. package/dist/wirings/trigger/webhook-source-runner.d.ts +24 -0
  298. package/dist/wirings/trigger/webhook-source-runner.js +19 -0
  299. package/dist/wirings/trigger/webhook-source.types.d.ts +12 -2
  300. package/dist/wirings/trigger/webhook-source.types.js +1 -1
  301. package/dist/wirings/variable/validate-variable-definitions.d.ts +7 -0
  302. package/dist/wirings/variable/validate-variable-definitions.js +7 -0
  303. package/dist/wirings/variable/variable.types.d.ts +7 -0
  304. package/dist/wirings/virtual-user/conversation/conversation.types.d.ts +5 -0
  305. package/dist/wirings/virtual-user/conversation/run-conversation.d.ts +6 -0
  306. package/dist/wirings/virtual-user/conversation/run-conversation.js +1 -1
  307. package/dist/{services → wirings/virtual-user}/http-virtual-users.d.ts +4 -3
  308. package/dist/{services → wirings/virtual-user}/http-virtual-users.js +6 -6
  309. package/dist/wirings/virtual-user/index.d.ts +1 -1
  310. package/dist/wirings/virtual-user/index.js +1 -1
  311. package/dist/wirings/virtual-user/run-virtual-user.d.ts +2 -1
  312. package/dist/wirings/virtual-user/run-virtual-user.js +1 -14
  313. package/dist/wirings/virtual-user/virtual-user-declaration.types.d.ts +4 -0
  314. package/dist/wirings/virtual-user/virtual-user-scaffold.d.ts +10 -1
  315. package/dist/wirings/virtual-user/virtual-user-scaffold.js +5 -0
  316. package/dist/wirings/virtual-user/virtual-user-schedule.d.ts +5 -0
  317. package/dist/wirings/virtual-user/virtual-user-schedule.js +1 -0
  318. package/dist/wirings/virtual-user/virtual-user-target.d.ts +1 -0
  319. package/dist/wirings/webhook/define-outgoing-webhook.d.ts +20 -0
  320. package/dist/wirings/webhook/define-outgoing-webhook.js +9 -0
  321. package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +8 -4
  322. package/dist/wirings/workflow/dsl/workflow-runner.d.ts +7 -0
  323. package/dist/wirings/workflow/dsl/workflow-runner.js +7 -0
  324. package/dist/wirings/workflow/feature.d.ts +12 -0
  325. package/dist/wirings/workflow/feature.js +12 -0
  326. package/dist/wirings/workflow/graph/graph-node.d.ts +5 -0
  327. package/dist/wirings/workflow/graph/graph-node.js +5 -0
  328. package/dist/wirings/workflow/graph/template.d.ts +6 -0
  329. package/dist/wirings/workflow/graph/template.js +5 -0
  330. package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +12 -0
  331. package/dist/wirings/workflow/graph/wire-workflow-graph.js +10 -0
  332. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +11 -0
  333. package/dist/wirings/workflow/graph/workflow-graph.types.js +1 -0
  334. package/dist/{services → wirings/workflow}/in-memory-workflow-service.d.ts +8 -3
  335. package/dist/{services → wirings/workflow}/in-memory-workflow-service.js +9 -4
  336. package/dist/wirings/workflow/pikku-scenario-service.d.ts +1 -1
  337. package/dist/wirings/workflow/pikku-scenario-service.js +2 -2
  338. package/dist/wirings/workflow/pikku-workflow-service.d.ts +1 -0
  339. package/dist/wirings/workflow/pikku-workflow-service.js +1 -0
  340. package/dist/wirings/workflow/run-timeline.d.ts +21 -0
  341. package/dist/wirings/workflow/run-timeline.js +15 -7
  342. package/dist/wirings/workflow/scenario-coverage.d.ts +1 -0
  343. package/dist/wirings/workflow/scenario-poll.d.ts +1 -0
  344. package/dist/wirings/workflow/scenario-prose.d.ts +6 -0
  345. package/dist/wirings/workflow/scenario-prose.js +6 -0
  346. package/dist/wirings/workflow/scenario-run.types.d.ts +3 -0
  347. package/dist/wirings/workflow/scenario-step.types.d.ts +1 -0
  348. package/dist/wirings/workflow/scenario-step.types.js +1 -0
  349. package/dist/wirings/workflow/scenario-surface.js +1 -13
  350. package/dist/wirings/workflow/scenario.types.d.ts +6 -0
  351. package/dist/wirings/workflow/workflow-approval-policy.d.ts +6 -0
  352. package/dist/wirings/workflow/workflow-approval-policy.js +6 -0
  353. package/dist/wirings/workflow/workflow-constants.d.ts +7 -1
  354. package/dist/wirings/workflow/workflow-constants.js +10 -1
  355. package/dist/wirings/workflow/workflow-errors.d.ts +13 -0
  356. package/dist/wirings/workflow/workflow-errors.js +13 -0
  357. package/dist/wirings/workflow/workflow-invocation-id.d.ts +4 -0
  358. package/dist/wirings/workflow/workflow-invocation-id.js +4 -0
  359. package/dist/wirings/workflow/workflow-queue-workers.d.ts +3 -0
  360. package/dist/wirings/workflow/workflow-run-ownership.d.ts +1 -0
  361. package/dist/wirings/workflow/workflow-run-ownership.js +1 -0
  362. package/dist/wirings/workflow/workflow-status-stream.d.ts +1 -0
  363. package/dist/wirings/workflow/workflow-unwind-plan.js +2 -7
  364. package/dist/wirings/workflow/workflow.types.d.ts +40 -0
  365. package/package.json +26 -9
  366. package/CHANGELOG.md +0 -6961
  367. package/dist/services/in-memory-queue-service.d.ts +0 -8
  368. package/dist/services/in-memory-queue-service.js +0 -54
  369. package/dist/services/in-memory-trigger-service.d.ts +0 -4
  370. package/dist/services/local-gateway-service.d.ts +0 -6
  371. package/dist/utils/hash.d.ts +0 -2
  372. package/dist/utils/hash.js +0 -23
  373. package/knowledge/decisions/index.md +0 -19
  374. package/knowledge/decisions/internals/a-credential-name-declared-twice-must-agree-on-schema-and-type.md +0 -29
  375. package/knowledge/decisions/internals/a-grant-can-name-a-scope-declared-without-its-addon.md +0 -29
  376. package/knowledge/decisions/internals/a-held-run-is-woken-later-not-retried.md +0 -28
  377. package/knowledge/decisions/internals/a-non-streaming-agent-run-registers-with-agentrunstate-too.md +0 -22
  378. package/knowledge/decisions/internals/a-reset-suite-makes-the-dev-seed-the-fixture.md +0 -50
  379. package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +0 -20
  380. package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +0 -21
  381. package/knowledge/decisions/internals/a-scheduled-task-writes-its-caller-session-before-it-runs.md +0 -22
  382. package/knowledge/decisions/internals/a-secret-set-in-memory-shadows-the-variable-of-the-same-name.md +0 -28
  383. package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +0 -49
  384. package/knowledge/decisions/internals/a-virtual-user-acts-through-invokeraw-so-a-refusal-is-data.md +0 -32
  385. package/knowledge/decisions/internals/a-virtual-user-cadence-is-a-row-not-a-timer.md +0 -66
  386. package/knowledge/decisions/internals/a-virtual-user-converse-signs-in-before-its-first-turn.md +0 -24
  387. package/knowledge/decisions/internals/a-virtual-user-decides-whether-to-trust-memory-once-per-turn.md +0 -21
  388. package/knowledge/decisions/internals/a-virtual-user-email-is-computed-with-the-run-id-as-a-sub-address.md +0 -34
  389. package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-but-it-needs-a-trigger.md +0 -65
  390. package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +0 -46
  391. package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +0 -45
  392. package/knowledge/decisions/internals/addon-package-roots-resolve-by-walking-node-module-search-paths.md +0 -26
  393. package/knowledge/decisions/internals/addon-pikku-meta-ships-at-the-package-root-or-under-dist.md +0 -32
  394. package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +0 -33
  395. package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +0 -28
  396. package/knowledge/decisions/internals/agent-agui-bridge-obeys-the-client-ordering-contract.md +0 -29
  397. package/knowledge/decisions/internals/agent-audio-chunks-carry-the-format-the-provider-returned.md +0 -20
  398. package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +0 -21
  399. package/knowledge/decisions/internals/agent-credential-suspensions-hide-the-tool-result.md +0 -26
  400. package/knowledge/decisions/internals/agent-delegate-and-supervise-hide-different-text.md +0 -26
  401. package/knowledge/decisions/internals/agent-llm-tool-arguments-have-nulls-stripped.md +0 -23
  402. package/knowledge/decisions/internals/agent-model-config-stays-a-single-resolution-seam.md +0 -25
  403. package/knowledge/decisions/internals/agent-onerror-hooks-cannot-change-the-failure.md +0 -22
  404. package/knowledge/decisions/internals/agent-runner-methods-must-keep-their-receiver.md +0 -22
  405. package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +0 -22
  406. package/knowledge/decisions/internals/agent-stream-persistence-is-best-effort.md +0 -27
  407. package/knowledge/decisions/internals/agent-sub-agents-inherit-the-parent-context-block.md +0 -26
  408. package/knowledge/decisions/internals/agent-tool-execute-failures-are-logged-unconditionally.md +0 -25
  409. package/knowledge/decisions/internals/agent-voice-input-transcribes-audio-parts-in-place.md +0 -22
  410. package/knowledge/decisions/internals/agent-working-memory-is-persisted-only-when-valid.md +0 -25
  411. package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +0 -39
  412. package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +0 -23
  413. package/knowledge/decisions/internals/an-agent-is-offered-under-its-registry-key-and-only-within-the-virtual-users-scopes.md +0 -27
  414. package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +0 -25
  415. package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +0 -22
  416. package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +0 -20
  417. package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.md +0 -22
  418. package/knowledge/decisions/internals/an-oauth2-credential-implies-an-optional-app-secret.md +0 -26
  419. package/knowledge/decisions/internals/an-unref-d-timer-cannot-be-awaited-under-node-test.md +0 -66
  420. package/knowledge/decisions/internals/analytics-identity-resolvers-run-in-declared-order.md +0 -22
  421. package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +0 -30
  422. package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +0 -31
  423. package/knowledge/decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md +0 -33
  424. package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md +0 -29
  425. package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +0 -28
  426. package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +0 -27
  427. package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +0 -28
  428. package/knowledge/decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md +0 -34
  429. package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +0 -29
  430. package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +0 -84
  431. package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +0 -41
  432. package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +0 -44
  433. package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +0 -39
  434. package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +0 -42
  435. package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +0 -39
  436. package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +0 -43
  437. package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +0 -38
  438. package/knowledge/decisions/internals/core-state-is-a-global-map-written-only-at-registration-time.md +0 -44
  439. package/knowledge/decisions/internals/email-meta-is-read-uncached-because-codegen-rewrites-it-mid-session.md +0 -27
  440. package/knowledge/decisions/internals/feature-flag-declarations-refuse-an-empty-anyof-and-conflicting-scopes.md +0 -22
  441. package/knowledge/decisions/internals/feature-flags-fail-open-and-never-enforce-access.md +0 -28
  442. package/knowledge/decisions/internals/flag-sync-rewrites-only-the-declared-text.md +0 -24
  443. package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +0 -32
  444. package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +0 -43
  445. package/knowledge/decisions/internals/gateway-webhook-challenges-echo-bytes-not-json.md +0 -28
  446. package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +0 -31
  447. package/knowledge/decisions/internals/generated-src-paths-in-pikku-meta-are-absolute.md +0 -26
  448. package/knowledge/decisions/internals/global-middleware-resolves-from-the-root-namespace-too.md +0 -32
  449. package/knowledge/decisions/internals/hot-reload-reads-the-changed-source-never-a-compiled-copy.md +0 -38
  450. package/knowledge/decisions/internals/hot-reload-writes-into-the-function-map-captured-at-startup.md +0 -26
  451. package/knowledge/decisions/internals/http-request-bodies-are-read-once-and-shared.md +0 -32
  452. package/knowledge/decisions/internals/http-route-groups-cascade-config-in-a-fixed-order.md +0 -28
  453. package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +0 -30
  454. package/knowledge/decisions/internals/http-runner-logs-through-a-trace-scoped-logger-functions-do-not.md +0 -26
  455. package/knowledge/decisions/internals/http-set-cookie-headers-are-appended-never-joined.md +0 -28
  456. package/knowledge/decisions/internals/http-sse-streams-flush-headers-only-after-middleware.md +0 -32
  457. package/knowledge/decisions/internals/http-wiring-without-metadata-is-skipped-not-fatal.md +0 -26
  458. package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +0 -25
  459. package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +0 -26
  460. package/knowledge/decisions/internals/index.md +0 -181
  461. package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +0 -25
  462. package/knowledge/decisions/internals/local-trigger-and-gateway-services-assume-a-single-process.md +0 -26
  463. package/knowledge/decisions/internals/mcp-wire-names-are-assigned-over-the-whole-registry.md +0 -39
  464. package/knowledge/decisions/internals/node-only-builtins-are-imported-dynamically.md +0 -24
  465. package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +0 -53
  466. package/knowledge/decisions/internals/only-exposed-functions-enter-a-virtual-user-catalogue.md +0 -21
  467. package/knowledge/decisions/internals/queue-group-concurrency-keeps-one-shared-queue-fair.md +0 -28
  468. package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +0 -27
  469. package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +0 -31
  470. package/knowledge/decisions/internals/role-names-cannot-contain-the-scope-separator.md +0 -30
  471. package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +0 -32
  472. package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +0 -31
  473. package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +0 -24
  474. package/knowledge/decisions/internals/scenario-meta-lives-apart-from-app-meta-but-merges-when-read-off-disk.md +0 -26
  475. package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +0 -27
  476. package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +0 -48
  477. package/knowledge/decisions/internals/scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md +0 -30
  478. package/knowledge/decisions/internals/serverless-channel-disconnect-must-tolerate-a-missing-channel.md +0 -28
  479. package/knowledge/decisions/internals/side-effects-are-an-allowlist-not-a-boolean.md +0 -34
  480. package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +0 -24
  481. package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.md +0 -26
  482. package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +0 -43
  483. package/knowledge/decisions/internals/the-core-scope-validator-refuses-separator-wildcard-and-empty-segments.md +0 -22
  484. package/knowledge/decisions/internals/the-dev-queue-copies-prod-timing-and-serialization-semantics.md +0 -30
  485. package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +0 -83
  486. package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +0 -29
  487. package/knowledge/decisions/internals/the-in-memory-workflow-service-is-inline-only-and-single-process.md +0 -27
  488. package/knowledge/decisions/internals/the-kek-salt-is-scoped-to-the-key-version.md +0 -40
  489. package/knowledge/decisions/internals/the-mcp-handshake-is-challenged-only-when-every-target-is-gated.md +0 -29
  490. package/knowledge/decisions/internals/the-middleware-resolution-cache-is-deliberately-unbounded.md +0 -40
  491. package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +0 -40
  492. package/knowledge/decisions/internals/the-pikku-user-id-resolves-in-a-fixed-order.md +0 -24
  493. package/knowledge/decisions/internals/the-runner-resolves-wire-services-itself.md +0 -31
  494. package/knowledge/decisions/internals/the-schema-service-is-never-stubbed.md +0 -26
  495. package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +0 -25
  496. package/knowledge/decisions/internals/the-virtual-user-catalogue-is-the-only-gate-on-what-may-be-called.md +0 -21
  497. package/knowledge/decisions/internals/the-virtual-user-prompt-says-json-because-of-json-object-mode.md +0 -22
  498. package/knowledge/decisions/internals/the-virtual-user-runtime-is-exported-from-the-virtual-user-entry-point.md +0 -28
  499. package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +0 -22
  500. package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +0 -25
  501. package/knowledge/decisions/internals/trigger-declaration-is-split-from-trigger-source.md +0 -33
  502. package/knowledge/decisions/internals/typed-secret-service-caches-for-the-process-lifetime.md +0 -26
  503. package/knowledge/decisions/internals/validate-checks-virtual-users-through-a-shared-module.md +0 -43
  504. package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +0 -115
  505. package/knowledge/decisions/internals/virtual-user-conversation-drives-the-target-through-a-transport-seam.md +0 -24
  506. package/knowledge/decisions/internals/virtual-user-conversation-verdicts-are-llm-self-evaluations.md +0 -25
  507. package/knowledge/decisions/internals/virtual-user-conversations-seed-a-hidden-kickoff-message.md +0 -23
  508. package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +0 -21
  509. package/knowledge/decisions/internals/virtual-users-are-declared-in-one-definevirtualusers-call-per-codebase.md +0 -30
  510. package/knowledge/decisions/internals/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.md +0 -24
  511. package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +0 -26
  512. package/knowledge/decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md +0 -25
  513. package/knowledge/decisions/internals/whether-a-run-is-inline-is-read-from-the-run-record.md +0 -58
  514. package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +0 -35
  515. package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +0 -34
  516. package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +0 -42
  517. package/knowledge/decisions/internals/workflow-dsl-meta-separates-runtime-expressions-from-literals.md +0 -38
  518. package/knowledge/decisions/internals/workflow-features-resolve-scenarios-by-object-identity.md +0 -29
  519. package/knowledge/decisions/internals/workflow-graph-inline-and-queued-runs-share-one-planner.md +0 -42
  520. package/knowledge/decisions/internals/workflow-graph-node-notes-are-excluded-from-the-graph-hash.md +0 -25
  521. package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +0 -29
  522. package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +0 -43
  523. package/knowledge/decisions/internals/workflow-queued-step-dispatch-requires-an-explicit-opt-in.md +0 -29
  524. package/knowledge/decisions/internals/workflow-queues-are-per-workflow-by-default.md +0 -42
  525. package/knowledge/decisions/internals/workflow-repeated-step-names-get-an-ordinal-suffix.md +0 -33
  526. package/knowledge/decisions/internals/workflow-replay-reads-its-steps-once-and-caches-only-the-immutable-half.md +0 -32
  527. package/knowledge/decisions/internals/workflow-retries-are-owned-by-the-workflow-not-the-queue.md +0 -31
  528. package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +0 -39
  529. package/knowledge/decisions/internals/workflow-run-mirror-is-never-a-source-of-truth.md +0 -29
  530. package/knowledge/decisions/internals/workflow-run-polling-backs-off-to-the-callers-ceiling.md +0 -33
  531. package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +0 -37
  532. package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +0 -54
  533. package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +0 -43
  534. package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +0 -32
  535. package/knowledge/decisions/internals/workflow-scenario-quarantine-reason-lives-in-code.md +0 -18
  536. package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +0 -34
  537. package/knowledge/decisions/internals/workflow-step-compensation-runs-as-its-own-durable-step.md +0 -29
  538. package/knowledge/decisions/internals/workflow-step-dispatch-failure-is-transient-not-a-run-failure.md +0 -33
  539. package/knowledge/decisions/internals/workflow-step-lock-is-held-only-to-claim-the-step.md +0 -34
  540. package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +0 -34
  541. package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +0 -38
  542. package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +0 -30
  543. package/knowledge/decisions/security/a-bearer-token-checked-against-a-secret-reads-it-per-request.md +0 -26
  544. package/knowledge/decisions/security/a-call-without-a-session-raises-missing-session-not-forbidden.md +0 -20
  545. package/knowledge/decisions/security/a-caller-cookie-wins-over-the-jar-for-the-same-name.md +0 -23
  546. package/knowledge/decisions/security/a-channel-lifecycle-acts-as-the-socket-upgrade-session.md +0 -16
  547. package/knowledge/decisions/security/a-channel-requires-a-session-unless-it-says-auth-false.md +0 -26
  548. package/knowledge/decisions/security/a-credential-read-path-follows-its-declared-type-not-absence.md +0 -32
  549. package/knowledge/decisions/security/a-credential-type-is-a-literal-the-inspector-checks-at-declaration.md +0 -27
  550. package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +0 -28
  551. package/knowledge/decisions/security/a-first-party-cookie-is-written-only-after-its-purposes-consent.md +0 -33
  552. package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +0 -37
  553. package/knowledge/decisions/security/a-graph-run-starts-at-an-entry-node-the-graph-declared.md +0 -33
  554. package/knowledge/decisions/security/a-permission-gets-a-wire-it-cannot-reply-on.md +0 -33
  555. package/knowledge/decisions/security/a-public-function-says-so-with-auth-false.md +0 -34
  556. package/knowledge/decisions/security/a-readonly-session-reaches-only-readonly-functions.md +0 -25
  557. package/knowledge/decisions/security/a-scaffold-flag-says-a-surface-exists-not-who-may-call-it.md +0 -52
  558. package/knowledge/decisions/security/a-scheduled-virtual-user-run-needs-no-admin-at-run-time.md +0 -27
  559. package/knowledge/decisions/security/a-scoped-credential-view-is-limited-to-declared-names.md +0 -26
  560. package/knowledge/decisions/security/a-scoped-secret-view-reads-only-declared-keys-and-never-writes.md +0 -25
  561. package/knowledge/decisions/security/a-secret-is-sent-only-to-the-hosts-it-declares.md +0 -29
  562. package/knowledge/decisions/security/a-step-can-name-an-identity-no-virtual-user-holds-through-per-call-headers.md +0 -25
  563. package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +0 -37
  564. package/knowledge/decisions/security/a-stopped-run-by-id-skips-the-ownership-check.md +0 -24
  565. package/knowledge/decisions/security/a-vault-secret-redacts-on-serialization-and-throws-on-coercion.md +0 -29
  566. package/knowledge/decisions/security/a-virtual-user-catalogue-entry-is-filtered-by-scope-and-approval-is-denied-by-default.md +0 -30
  567. package/knowledge/decisions/security/a-virtual-user-environment-fails-closed.md +0 -38
  568. package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +0 -27
  569. package/knowledge/decisions/security/a-virtual-user-never-runs-against-production.md +0 -23
  570. package/knowledge/decisions/security/a-virtual-user-reads-its-roles-from-the-apps-own-rpc-before-better-auth.md +0 -27
  571. package/knowledge/decisions/security/a-virtual-user-run-treats-an-unresolved-environment-as-production.md +0 -41
  572. package/knowledge/decisions/security/a-virtual-user-scopes-are-expanded-from-its-roles-once-at-run-preparation.md +0 -25
  573. package/knowledge/decisions/security/a-virtual-user-whose-roles-drift-from-the-declaration-refuses-to-run.md +0 -32
  574. package/knowledge/decisions/security/a-workflow-run-is-read-and-approved-by-its-owner.md +0 -50
  575. package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +0 -43
  576. package/knowledge/decisions/security/addon-config-gates-apply-only-at-the-namespaced-rpc-boundary.md +0 -52
  577. package/knowledge/decisions/security/addon-scopes-are-resolved-where-the-function-runs.md +0 -46
  578. package/knowledge/decisions/security/addon-screen-scopes-hide-and-do-not-enforce.md +0 -20
  579. package/knowledge/decisions/security/agent-approval-forwarding-requires-a-symbol-brand.md +0 -27
  580. package/knowledge/decisions/security/agent-credential-requests-are-symbol-branded.md +0 -37
  581. package/knowledge/decisions/security/agent-gate-requires-a-session-only-when-auth-is-true.md +0 -31
  582. package/knowledge/decisions/security/agent-ownership-failures-never-echo-the-resource.md +0 -23
  583. package/knowledge/decisions/security/agent-resume-re-runs-the-authorization-gate.md +0 -22
  584. package/knowledge/decisions/security/agent-sessionless-deployments-have-no-thread-ownership.md +0 -39
  585. package/knowledge/decisions/security/agent-thread-ownership-composes-the-session-principal.md +0 -30
  586. package/knowledge/decisions/security/agent-tool-filtering-reads-the-live-function-config.md +0 -24
  587. package/knowledge/decisions/security/an-addon-header-can-only-narrow-the-session.md +0 -26
  588. package/knowledge/decisions/security/an-addon-instance-reads-only-the-secrets-and-credentials-it-is-named.md +0 -33
  589. package/knowledge/decisions/security/an-addon-may-reach-only-itself-and-the-addons-it-uses.md +0 -16
  590. package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +0 -33
  591. package/knowledge/decisions/security/an-api-key-is-jwt-decoded-into-the-session.md +0 -26
  592. package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +0 -59
  593. package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +0 -30
  594. package/knowledge/decisions/security/an-exposed-ungated-function-is-a-codegen-warning.md +0 -52
  595. package/knowledge/decisions/security/an-external-virtual-user-caller-presents-one-signed-statement.md +0 -38
  596. package/knowledge/decisions/security/an-inbound-webhook-source-dispatches-only-verified-requests.md +0 -31
  597. package/knowledge/decisions/security/an-mcp-call-with-no-http-request-stays-anonymous.md +0 -18
  598. package/knowledge/decisions/security/an-mcp-refusal-is-decided-before-dispatch.md +0 -48
  599. package/knowledge/decisions/security/an-oauth2-credential-is-read-by-its-account-row.md +0 -40
  600. package/knowledge/decisions/security/an-omitted-user-id-addresses-the-platform-credential.md +0 -32
  601. package/knowledge/decisions/security/an-upload-is-counted-as-it-arrives-not-buffered-then-measured.md +0 -24
  602. package/knowledge/decisions/security/analytics-identity-is-stamped-from-the-session-not-the-event.md +0 -24
  603. package/knowledge/decisions/security/app-access-is-a-scope-tree-synthesised-from-virtual-users.md +0 -26
  604. package/knowledge/decisions/security/approval-policy-decides-who-answers-a-tool-call.md +0 -27
  605. package/knowledge/decisions/security/auth-false-on-a-session-function-warns-and-still-requires-one.md +0 -25
  606. package/knowledge/decisions/security/bearer-token-hashes-are-unpeppered-sha256.md +0 -18
  607. package/knowledge/decisions/security/consent-is-read-from-a-cookie-and-a-recognised-denial-counts-as-refusal.md +0 -29
  608. package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +0 -84
  609. package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +0 -39
  610. package/knowledge/decisions/security/core-secrets-use-a-per-secret-dek-wrapped-by-a-kek.md +0 -37
  611. package/knowledge/decisions/security/cors-defaults-to-any-origin-and-refuses-the-wildcard-with-credentials.md +0 -22
  612. package/knowledge/decisions/security/credential-backends-share-one-conformance-suite-for-per-user-isolation.md +0 -29
  613. package/knowledge/decisions/security/each-stage-has-one-virtual-user-key-pair.md +0 -27
  614. package/knowledge/decisions/security/gateway-handlers-run-through-the-function-runner-gate.md +0 -41
  615. package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +0 -30
  616. package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +0 -40
  617. package/knowledge/decisions/security/hmac-verification-fails-closed-on-empty-inputs.md +0 -25
  618. package/knowledge/decisions/security/http-error-detail-is-withheld-from-clients-in-production.md +0 -33
  619. package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +0 -46
  620. package/knowledge/decisions/security/index.md +0 -135
  621. package/knowledge/decisions/security/local-content-refuses-private-buckets-under-the-public-segment.md +0 -21
  622. package/knowledge/decisions/security/mail-is-allowlisted-before-a-virtual-user-run-sees-it.md +0 -38
  623. package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +0 -27
  624. package/knowledge/decisions/security/mcp-resources-tools-and-prompts-take-sessionless-functions.md +0 -18
  625. package/knowledge/decisions/security/origin-locked-routes-match-the-origin-exactly.md +0 -22
  626. package/knowledge/decisions/security/oss-auth-works-without-pikku-studio-cloud.md +0 -26
  627. package/knowledge/decisions/security/outbound-webhooks-use-an-allowlist-when-configured.md +0 -24
  628. package/knowledge/decisions/security/passphrases-are-stretched-key-material-is-expanded.md +0 -40
  629. package/knowledge/decisions/security/permission-auth-filtering-requires-live-permission-functions.md +0 -31
  630. package/knowledge/decisions/security/pikku-carries-virtual-user-scopes-as-data-and-the-app-grants-them.md +0 -35
  631. package/knowledge/decisions/security/queue-job-identities-are-signed-at-enqueue.md +0 -69
  632. package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +0 -39
  633. package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +0 -34
  634. package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +0 -55
  635. package/knowledge/decisions/security/scenario-step-functions-are-never-externally-invocable.md +0 -30
  636. package/knowledge/decisions/security/scope-resolution-happens-at-the-session-boundary-and-sync-never-deletes.md +0 -28
  637. package/knowledge/decisions/security/scoped-content-access-is-a-root-folder-with-longest-prefix-grants.md +0 -31
  638. package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +0 -34
  639. package/knowledge/decisions/security/services-without-secrets-get-a-throwing-secrets-accessor.md +0 -22
  640. package/knowledge/decisions/security/shared-guards-refuse-to-mutate-or-shadow-a-system-role.md +0 -34
  641. package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +0 -37
  642. package/knowledge/decisions/security/signed-uploads-are-verified-by-the-same-check-as-signed-reads.md +0 -26
  643. package/knowledge/decisions/security/system-role-scopes-must-be-declared-with-define-scope.md +0 -24
  644. package/knowledge/decisions/security/system-roles-are-additive-and-immutable.md +0 -16
  645. package/knowledge/decisions/security/the-channel-rpc-does-not-send-the-callers-session.md +0 -21
  646. package/knowledge/decisions/security/the-remote-jobs-inbox-fails-closed-without-a-secret.md +0 -24
  647. package/knowledge/decisions/security/the-remote-rpc-gate-fails-closed-and-binds-the-token-to-its-function.md +0 -34
  648. package/knowledge/decisions/security/the-workflow-status-stream-rechecks-ownership-on-every-poll.md +0 -16
  649. package/knowledge/decisions/security/two-credentials-on-one-key-must-share-a-read-mode.md +0 -29
  650. package/knowledge/decisions/security/verified-bearer-claims-are-pass-through-data-that-core-never-fills.md +0 -23
  651. package/knowledge/decisions/security/virtual-user-catalogue-excludes-the-machinery-that-runs-virtual-users.md +0 -25
  652. package/knowledge/decisions/security/virtual-user-conversation-missing-approval-decisions-default-to-denied.md +0 -22
  653. package/knowledge/decisions/security/virtual-user-run-records-are-gated-behind-a-read-scope.md +0 -18
  654. package/knowledge/decisions/security/virtual-user-sign-in-does-not-exist-in-production.md +0 -25
  655. package/knowledge/decisions/security/virtual-user-sign-in-has-one-door.md +0 -42
  656. package/knowledge/decisions/security/virtual-user-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +0 -29
  657. package/knowledge/decisions/security/virtual-user-sign-in-only-works-for-virtual-user-flagged-users.md +0 -29
  658. package/knowledge/decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md +0 -25
  659. package/knowledge/decisions/security/wire-addon-expose-selects-the-rpc-surface.md +0 -51
  660. package/knowledge/decisions/security/workflow-approval-payloads-are-validated-on-replay-inside-the-workflow.md +0 -40
  661. package/knowledge/decisions/security/workflow-helper-functions-are-sessionless-by-declaration.md +0 -18
  662. package/knowledge/decisions/security/workflow-queued-steps-rehydrate-their-session-from-the-run-wire.md +0 -32
  663. package/knowledge/decisions/security/workflow-scenario-sessions-are-isolated-per-virtual-user-and-per-scenario.md +0 -32
  664. package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +0 -31
  665. package/knowledge/decisions/security/workflow-virtual-user-steps-always-use-the-real-transport.md +0 -34
  666. package/knowledge/decisions/security/writing-a-virtual-user-schedule-is-gated-by-its-own-scope.md +0 -18
  667. package/knowledge/index.md +0 -24
  668. package/knowledge/questions/a-bearer-jwt-with-no-identity-becomes-a-session.md +0 -24
  669. package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +0 -35
  670. package/knowledge/questions/dev-quick-login-as-impersonation.md +0 -25
  671. package/knowledge/questions/does-a-delayed-rpc-run-as-the-session-it-was-scheduled-with.md +0 -26
  672. package/knowledge/questions/does-a-user-id-with-a-colon-read-another-users-credentials.md +0 -27
  673. package/knowledge/questions/does-a-wirecli-command-need-a-session-by-default.md +0 -26
  674. package/knowledge/questions/does-an-adversarial-in-scope-success-count-as-a-finding.md +0 -26
  675. package/knowledge/questions/does-approve-step-need-the-run-owners-session-or-the-gates-approvers.md +0 -34
  676. package/knowledge/questions/does-cors-origin-true-reflect-any-origin-with-credentials.md +0 -20
  677. package/knowledge/questions/does-skip-user-session-do-anything-on-a-channel.md +0 -24
  678. package/knowledge/questions/does-the-store-session-match-the-other-two.md +0 -19
  679. package/knowledge/questions/index.md +0 -41
  680. package/knowledge/questions/is-the-agent-score-worker-reachable-without-a-session.md +0 -21
  681. package/knowledge/questions/live-scheduled-tests-may-write.md +0 -19
  682. package/knowledge/questions/provision-virtual-users-has-no-caller-in-this-repo.md +0 -23
  683. package/knowledge/questions/remote-secret-refuses-requests-without-a-remote-token-on-every-path.md +0 -32
  684. package/knowledge/questions/should-a-middleware-set-session-persist-to-the-store.md +0 -25
  685. package/knowledge/questions/should-a-scoped-secret-view-throw-from-has-secret-for-a-disallowed-key.md +0 -23
  686. package/knowledge/questions/should-a-wrong-bearer-token-be-anonymous-or-refused.md +0 -35
  687. package/knowledge/questions/should-an-empty-webhook-signing-secret-send-unsigned.md +0 -23
  688. package/knowledge/questions/should-http-virtual-user-sessions-reset-between-scenarios-in-one-run.md +0 -27
  689. package/knowledge/questions/should-the-cookie-jar-scope-cookies-to-the-api-origin.md +0 -26
  690. package/knowledge/questions/should-voice-input-fetch-audio-urls-without-a-host-allowlist.md +0 -20
  691. package/knowledge/questions/staging-impersonation-rules.md +0 -27
  692. package/knowledge/questions/unauthorized-channel-replies-escape-the-declared-out-type.md +0 -44
  693. package/knowledge/questions/virtual-user-keys-on-cloud-stages-are-pikku-studios-to-build.md +0 -34
  694. package/knowledge/questions/virtual-user-statement-replay-is-per-process.md +0 -20
  695. package/knowledge/questions/what-an-impersonated-session-carries.md +0 -22
  696. package/run-tests.sh +0 -68
  697. package/scripts/generate-api-report.d.mts +0 -1
  698. package/scripts/generate-api-report.mjs +0 -96
  699. package/scripts/generate-api-report.mts +0 -333
  700. package/src/public-surface.json +0 -637
  701. package/src/public-surface.json.README +0 -43
  702. /package/dist/{function/compensation-name.d.ts → compensation-name.d.ts} +0 -0
  703. /package/dist/{function/compensation-name.js → compensation-name.js} +0 -0
@@ -1,13 +1,13 @@
1
1
  import { beginChanges } from './abort-scope.js';
2
- import { forwardStepName, isCompensationStepName } from './compensation-name.js';
2
+ import { forwardStepName, isCompensationStepName, } from '../compensation-name.js';
3
3
  import { runMiddleware, combineMiddleware } from '../middleware-runner.js';
4
- import { combineChannelMiddleware, wrapChannelWithMiddleware, } from '../wirings/channel/channel-middleware-runner.js';
4
+ import { combineChannelMiddleware, wrapChannelWithMiddleware, } from '../channel-middleware-runner.js';
5
5
  import { runPermissions } from '../permissions.js';
6
6
  import { withoutSecrets } from '../services/secretless.js';
7
7
  import { getCreateWireServices, pikkuState } from '../pikku-state.js';
8
8
  import { applyDefaultsFromSchema, coerceTopLevelDataFromSchema, validateSchema, } from '../schema.js';
9
9
  import { parseVersionedId } from '../version.js';
10
- import { PikkuSessionService } from '../services/user-session-service.js';
10
+ import { PikkuSessionService, createFunctionSessionWireProps, } from '../services/user-session-service.js';
11
11
  import { MissingSessionError, ReadonlySessionError } from '../errors/errors.js';
12
12
  import { verifyScopes } from '../scopes.js';
13
13
  import { assertFeatureAvailable } from '../wirings/flag/assert-feature-available.js';
@@ -22,6 +22,13 @@ import { getOrCreatePackageSingletonServices } from '../wirings/addon/addon-runn
22
22
  import { resolveAddonAuth, resolveAddonFunctionTarget, resolveAddonScopes, resolveAddonTagMiddleware, } from '../wirings/addon/wire-addon.js';
23
23
  import { closeWireServices } from '../utils.js';
24
24
  async function resolveSession(wire, singletonServices, sessionService) {
25
+ // A session middleware established lives on the session service, not on the
26
+ // transport's snapshot of the wire. Read it from there, so it is what the
27
+ // function sees and what its user id is resolved from.
28
+ // knowledge: decisions/security/set-session-persists-and-set-initial-session-does-not.md
29
+ if (!wire.session && sessionService?.get()) {
30
+ wire.session = sessionService.get();
31
+ }
25
32
  const pikkuUserId = defaultPikkuUserIdResolver(wire);
26
33
  if (pikkuUserId) {
27
34
  wire.pikkuUserId = pikkuUserId;
@@ -45,6 +52,15 @@ async function resolveSession(wire, singletonServices, sessionService) {
45
52
  sessionService?.setInitial(wire.session);
46
53
  }
47
54
  }
55
+ /**
56
+ * Registers a function's config under its id so wirings can run it by name.
57
+ * Generated code calls this for every function codegen found; an app rarely
58
+ * needs to. Registering the same id again replaces the earlier config.
59
+ *
60
+ * @param funcName - The function id, as it appears in the generated metadata.
61
+ * @param funcConfig - The object a `pikkuFunc` / `pikkuSessionlessFunc` returned.
62
+ * @param packageName - The addon package it belongs to; `null` for the app.
63
+ */
48
64
  export const addFunction = (funcName, funcConfig, packageName = null) => {
49
65
  pikkuState(packageName, 'function', 'functions').set(funcName, funcConfig);
50
66
  };
@@ -52,6 +68,10 @@ export const getFunctionNames = (packageName = null) => {
52
68
  const functionsMeta = pikkuState(packageName, 'function', 'meta');
53
69
  return Object.keys(functionsMeta);
54
70
  };
71
+ /**
72
+ * Every function id with generated metadata: the app's own, then each addon's
73
+ * prefixed with the namespace it was wired under (`ns:name`).
74
+ */
55
75
  export const getAllFunctionNames = () => {
56
76
  const functions = [];
57
77
  const mainFunctionsMeta = pikkuState(null, 'function', 'meta');
@@ -65,6 +85,34 @@ export const getAllFunctionNames = () => {
65
85
  }
66
86
  return functions;
67
87
  };
88
+ /**
89
+ * Runs one registered function the way every wiring does. Each transport's
90
+ * runner (HTTP, channel, queue, scheduler, RPC, MCP, CLI, workflow, agent)
91
+ * ends up here; an app calls it directly only when it is building its own
92
+ * transport.
93
+ *
94
+ * In order, it: resolves the function (falling back from `name@vN` to the
95
+ * unversioned name, and into an addon for `ns:name`), runs the combined
96
+ * middleware, resolves the session, enforces auth, `readonly`, scopes and the
97
+ * feature flag, reads `data()`, applies schema defaults and validation, runs
98
+ * global and function permissions, builds and finally closes the wire
99
+ * services, and calls the function. The function and its permissions receive
100
+ * services whose `secrets` throws on access — they read secrets through the
101
+ * declared typed wrappers instead.
102
+ *
103
+ * @param wireType - The transport, recorded on `wire.wireType` if unset.
104
+ * @param wireId - The wiring's id (route, queue name, …), recorded on
105
+ * `wire.wireId` if unset. Middleware registered against it is applied.
106
+ * @param funcName - The registered function id.
107
+ * @returns Whatever the function returns.
108
+ * @throws {MissingSessionError} A session is required and none resolved.
109
+ * @throws {ReadonlySessionError} A readonly session called a mutating function.
110
+ * @throws {MissingScopeError} The session lacks a required scope.
111
+ * @throws {FeatureUnavailableError} The function's feature flag is off.
112
+ * @throws {ForbiddenError} A permission refused the call.
113
+ * @throws {Error} The function or its metadata is not registered. Errors thrown
114
+ * by validation, middleware and the function itself propagate unchanged.
115
+ */
68
116
  export const runPikkuFunc = async (wireType, wireId, funcName, { singletonServices, createWireServices, wireServices: providedWireServices, data, auth: wiringAuth, inheritedMiddleware, wireMiddleware, inheritedChannelMiddleware, wireChannelMiddleware, coerceDataFromSchema, wire, sessionService, credentialWireService, packageName = null, addonInstance, }) => {
69
117
  wire.wireType ??= wireType;
70
118
  wire.wireId ??= wireId;
@@ -204,17 +252,13 @@ export const runPikkuFunc = async (wireType, wireId, funcName, { singletonServic
204
252
  const executeFunction = async () => {
205
253
  await resolveSession(invocationWire, resolvedSingletonServices, sessionService);
206
254
  if (sessionService) {
207
- invocationWire.session = sessionService.freezeInitial();
208
- invocationWire.setSession = (s) => sessionService.set(s);
209
- invocationWire.clearSession = () => sessionService.clear();
210
- invocationWire.getSession = () => sessionService.get();
211
- invocationWire.hasSessionChanged = () => sessionService.sessionChanged;
255
+ Object.assign(invocationWire, createFunctionSessionWireProps(sessionService));
212
256
  }
213
257
  const session = invocationWire.session;
214
258
  if (funcMeta.sessionless) {
215
259
  if (wiringAuth === true ||
216
260
  funcConfig.auth === true ||
217
- resolveAddonAuth(packageName, addonInstance?.namespace)) {
261
+ resolveAddonAuth(funcPackageName, addonInstance?.namespace)) {
218
262
  if (!session) {
219
263
  throw new MissingSessionError('Authentication required');
220
264
  }
@@ -239,7 +283,9 @@ export const runPikkuFunc = async (wireType, wireId, funcName, { singletonServic
239
283
  invocationWire.beginChanges = () => beginChanges(abortScope);
240
284
  }
241
285
  // knowledge: decisions/security/addon-scopes-are-resolved-where-the-function-runs.md
242
- const addonScopes = resolveAddonScopes(packageName, addonInstance?.namespace);
286
+ // The function's package, not the wire's: a `ref('ns:fn')` route stays the
287
+ // app's, and reading the wire's left it outside the addon's floor.
288
+ const addonScopes = resolveAddonScopes(funcPackageName, addonInstance?.namespace);
243
289
  const functionScopes = funcConfig.scopes ?? funcMeta.scopes;
244
290
  verifyScopes(addonScopes.length > 0
245
291
  ? [...addonScopes, ...(functionScopes ?? [])]
@@ -330,7 +376,7 @@ export const runPikkuFunc = async (wireType, wireId, funcName, { singletonServic
330
376
  }
331
377
  }
332
378
  };
333
- const addonTagMiddleware = resolveAddonTagMiddleware(packageName, addonInstance?.namespace);
379
+ const addonTagMiddleware = resolveAddonTagMiddleware(funcPackageName, addonInstance?.namespace);
334
380
  const allMiddleware = combineMiddleware(wireType, wireId, {
335
381
  wireInheritedMiddleware: inheritedMiddleware,
336
382
  wireMiddleware: addonTagMiddleware.length > 0
@@ -7,15 +7,50 @@ import type { PikkuError } from '../errors/error-handler.js';
7
7
  import type { CoreNodeConfig } from '../wirings/node/node.types.js';
8
8
  import type { ScenarioSurface } from '../wirings/workflow/scenario-step.types.js';
9
9
  import type { Safe } from '../classification/secret-value.js';
10
+ /**
11
+ * The body of a function that requires a session: `(services, data, wire)`,
12
+ * with `wire.session` typed as present. `pikkuFunc` takes one of these; the
13
+ * runner refuses the call with `MissingSessionError` before the body runs when
14
+ * there is no session.
15
+ */
10
16
  export type CorePikkuFunction<In, Out, Services extends CoreSecretlessSingletonServices = SecretlessServices<CoreServices>, Session extends CoreUserSession = CoreUserSession, Wire extends PikkuWire<In, Out, true, Session, PikkuRPC, null, string> = PikkuWire<In, Out, true, Session>> = (services: Services, data: In, wire: Wire) => Wire['channel'] extends null ? Promise<Safe<Out>> : Promise<Safe<Out>> | Promise<void>;
17
+ /**
18
+ * The body of a function that may run without a session, so `wire.session` is
19
+ * optional. `pikkuSessionlessFunc` takes one of these.
20
+ */
11
21
  export type CorePikkuFunctionSessionless<In, Out, Services extends CoreSecretlessSingletonServices = SecretlessServices<CoreServices>, Session extends CoreUserSession = CoreUserSession, Wire extends PikkuWire<In, Out, false, Session, PikkuRPC, null, string> = PikkuWire<In, Out, false, Session>> = (services: Services, data: In, wire: Wire) => Wire['channel'] extends null ? Promise<Safe<Out>> : Promise<Safe<Out>> | Promise<void>;
22
+ /**
23
+ * A permission check: resolves `true` to allow the call. Runs after input
24
+ * validation, so `data` is the validated input. Its services have no
25
+ * `secrets`.
26
+ */
12
27
  export type CorePikkuPermission<In = any, Services extends CoreSecretlessSingletonServices = SecretlessServices<CoreServices>, Wire extends PikkuWire<In, never, false, any, PikkuRPC, never, never> = PikkuWire<In, never, false, any, PikkuRPC, never, never>> = (services: Services, data: In, wire: Wire) => Promise<boolean>;
28
+ /**
29
+ * The object form of {@link pikkuPermission}, for a check that carries a name
30
+ * or description.
31
+ */
13
32
  export type CorePikkuPermissionConfig<In = any, Services extends CoreSecretlessSingletonServices = SecretlessServices<CoreServices>, Wire extends PikkuWire<In, never, false, any, PikkuRPC, never, never> = PikkuWire<In, never, false, any, PikkuRPC, never, never>> = {
14
33
  func: CorePikkuPermission<In, Services, Wire>;
15
34
  name?: string;
16
35
  description?: string;
17
36
  };
37
+ /**
38
+ * Declares a permission: an async check that resolves `true` to allow a call
39
+ * and `false` to refuse it with `ForbiddenError` (403). It receives the
40
+ * services (without `secrets`), the validated input and the wire.
41
+ *
42
+ * Attach it through a function's or wiring's `permissions`: within one group
43
+ * the keys are alternatives, so the call passes when any key passes, and an
44
+ * array under a key must pass in full. Global permissions from
45
+ * `addGlobalPermission` must all pass as well.
46
+ *
47
+ * @example snippet: permissionFunction
48
+ */
18
49
  export declare const pikkuPermission: <In = any, Services extends CoreSecretlessSingletonServices = SecretlessServices<CoreServices>, Wire extends PickRequired<PikkuWire<In, never, false, any, PikkuRPC, never, never>, 'session'> = PickRequired<PikkuWire<In, never, false, any, PikkuRPC, never, never>, 'session'>>(permission: CorePikkuPermission<In, Services, Wire> | CorePikkuPermissionConfig<In, Services, Wire>) => CorePikkuPermission<In, Services, Wire>;
50
+ /**
51
+ * A function that takes options and returns a permission, as declared with
52
+ * {@link pikkuPermissionFactory}.
53
+ */
19
54
  export type CorePikkuPermissionFactory<In = any, Services extends CoreSecretlessSingletonServices = SecretlessServices<CoreServices>, Wire extends PikkuWire<In, never, false, any, PikkuRPC, never, never> = PikkuWire<In, never, false, any, PikkuRPC, never, never>> = (input: In) => CorePikkuPermission<any, Services, Wire>;
20
55
  /**
21
56
  * Declares a permission that takes configuration, so one check serves many
@@ -35,7 +70,12 @@ export type CorePikkuApprovalDescription<In = any, Services extends CoreSecretle
35
70
  * @example snippet: approvalDescription
36
71
  */
37
72
  export declare const pikkuApprovalDescription: <In = any, Services extends CoreSecretlessSingletonServices = CoreSecretlessSingletonServices>(fn: CorePikkuApprovalDescription<In, Services>) => CorePikkuApprovalDescription<In, Services>;
73
+ /** A session check: receives the services and the session, never the input. */
38
74
  export type CorePikkuAuth<Services extends CoreSecretlessSingletonServices = SecretlessServices<CoreServices>, Session extends CoreUserSession = CoreUserSession> = (services: Services, session: Session) => Promise<boolean> | boolean;
75
+ /**
76
+ * The object form of {@link pikkuAuth}, for a check that carries a name or
77
+ * description.
78
+ */
39
79
  export type CorePikkuAuthConfig<Services extends CoreSecretlessSingletonServices = SecretlessServices<CoreServices>, Session extends CoreUserSession = CoreUserSession> = {
40
80
  func: CorePikkuAuth<Services, Session>;
41
81
  name?: string;
@@ -50,7 +90,22 @@ export type CorePikkuAuthConfig<Services extends CoreSecretlessSingletonServices
50
90
  export type AuthBranded = {
51
91
  __pikkuAuth?: true;
52
92
  };
93
+ /**
94
+ * Declares a permission that depends only on the session, not the input. The
95
+ * resulting permission refuses outright when there is no session, so the
96
+ * check itself always sees one.
97
+ *
98
+ * Because it does not read the input, an agent can evaluate it ahead of time
99
+ * to decide which tools a session may be offered (see `checkAuthPermissions`);
100
+ * ordinary permissions are only checked when a tool is actually called.
101
+ *
102
+ * @example snippet: shopIsAuthenticated
103
+ */
53
104
  export declare const pikkuAuth: <Services extends CoreSecretlessSingletonServices = SecretlessServices<CoreServices>, Session extends CoreUserSession = CoreUserSession>(auth: CorePikkuAuth<Services, Session> | CorePikkuAuthConfig<Services, Session>) => CorePikkuPermission<any, Services, any>;
105
+ /**
106
+ * Permissions keyed by name. The call passes when any key passes (OR); an array
107
+ * under one key must pass in full (AND).
108
+ */
54
109
  export type CorePermissionGroup<PikkuPermission = CorePikkuPermission<any>> = Record<string, PikkuPermission | PikkuPermission[]> | undefined;
55
110
  /**
56
111
  * A lifecycle hook: same call signature as the function it hangs off, return
@@ -58,6 +113,10 @@ export type CorePermissionGroup<PikkuPermission = CorePikkuPermission<any>> = Re
58
113
  * it is never recorded and never replayed.
59
114
  */
60
115
  export type CorePikkuFunctionHook<Services = any, Data = any, Wire = any> = (services: Services, data: Data, wire: Wire) => Promise<void> | void;
116
+ /**
117
+ * Everything a function is declared with: its body and the options
118
+ * `pikkuFunc` / `pikkuSessionlessFunc` accept.
119
+ */
61
120
  export type CorePikkuFunctionConfig<PikkuFunction extends CorePikkuFunction<any, any, any, any, any> | CorePikkuFunctionSessionless<any, any, any, any, any>, PikkuPermission extends CorePikkuPermission<any, any, any> = CorePikkuPermission<any>, PikkuMiddleware extends CorePikkuMiddleware<any, any> = CorePikkuMiddleware<any, any>, InputSchema extends StandardSchemaV1 | undefined = undefined, OutputSchema extends StandardSchemaV1 | undefined = undefined, Scope extends string = string, FeatureFlagName extends string = string> = {
62
121
  /** A human name for this function, shown wherever it is listed rather than called. */
63
122
  title?: string;
@@ -1,3 +1,15 @@
1
+ /**
2
+ * Declares a permission: an async check that resolves `true` to allow a call
3
+ * and `false` to refuse it with `ForbiddenError` (403). It receives the
4
+ * services (without `secrets`), the validated input and the wire.
5
+ *
6
+ * Attach it through a function's or wiring's `permissions`: within one group
7
+ * the keys are alternatives, so the call passes when any key passes, and an
8
+ * array under a key must pass in full. Global permissions from
9
+ * `addGlobalPermission` must all pass as well.
10
+ *
11
+ * @example snippet: permissionFunction
12
+ */
1
13
  export const pikkuPermission = (permission) => {
2
14
  return typeof permission === 'function' ? permission : permission.func;
3
15
  };
@@ -18,6 +30,17 @@ export const pikkuPermissionFactory = (factory) => {
18
30
  export const pikkuApprovalDescription = (fn) => {
19
31
  return fn;
20
32
  };
33
+ /**
34
+ * Declares a permission that depends only on the session, not the input. The
35
+ * resulting permission refuses outright when there is no session, so the
36
+ * check itself always sees one.
37
+ *
38
+ * Because it does not read the input, an agent can evaluate it ahead of time
39
+ * to decide which tools a session may be offered (see `checkAuthPermissions`);
40
+ * ordinary permissions are only checked when a tool is actually called.
41
+ *
42
+ * @example snippet: shopIsAuthenticated
43
+ */
21
44
  export const pikkuAuth = (auth) => {
22
45
  const fn = typeof auth === 'function' ? auth : auth.func;
23
46
  const wrapper = async (services, _data, wire) => {
@@ -18,6 +18,10 @@ export interface ListInput<F extends Record<string, unknown> = Record<string, ne
18
18
  /** Unstructured text search across server-configured fields. */
19
19
  search?: string;
20
20
  }
21
+ /**
22
+ * The output a list function returns: one page of rows and the cursor for the
23
+ * next.
24
+ */
21
25
  export interface ListOutput<Row> {
22
26
  rows: Row[];
23
27
  /** Null when no more pages. */
@@ -1,6 +1,17 @@
1
1
  import type { CoreSingletonServices, ServerLifecycle } from './types/core.types.js';
2
2
  /** Stops addon package services first, then the parent singleton services. */
3
3
  export declare const stopSingletonServices: () => Promise<void>;
4
- /** Wrap server lifecycle hooks so the inspector can discover them. */
4
+ /**
5
+ * Wrap server lifecycle hooks so the inspector can discover them.
6
+ *
7
+ * @example snippet: serverLifecycle
8
+ */
5
9
  export declare const pikkuServerLifecycle: <SS extends CoreSingletonServices = CoreSingletonServices>(lifecycle: ServerLifecycle<SS>) => ServerLifecycle<SS>;
10
+ /**
11
+ * Calls `run` once when the process receives one of `signals` (default
12
+ * `SIGINT` and `SIGTERM`); later signals are ignored while it runs. Does
13
+ * nothing outside Node-like runtimes. It does not exit the process.
14
+ *
15
+ * @returns A function that removes the handlers.
16
+ */
6
17
  export declare const onShutdownSignals: (run: (signal: NodeJS.Signals) => void | Promise<void>, signals?: NodeJS.Signals[]) => (() => void);
package/dist/lifecycle.js CHANGED
@@ -34,8 +34,19 @@ export const stopSingletonServices = async () => {
34
34
  await stopService(logger, name, service);
35
35
  }
36
36
  };
37
- /** Wrap server lifecycle hooks so the inspector can discover them. */
37
+ /**
38
+ * Wrap server lifecycle hooks so the inspector can discover them.
39
+ *
40
+ * @example snippet: serverLifecycle
41
+ */
38
42
  export const pikkuServerLifecycle = (lifecycle) => lifecycle;
43
+ /**
44
+ * Calls `run` once when the process receives one of `signals` (default
45
+ * `SIGINT` and `SIGTERM`); later signals are ignored while it runs. Does
46
+ * nothing outside Node-like runtimes. It does not exit the process.
47
+ *
48
+ * @returns A function that removes the handlers.
49
+ */
39
50
  export const onShutdownSignals = (run, signals = ['SIGINT', 'SIGTERM']) => {
40
51
  const proc = typeof process !== 'undefined' ? process : undefined;
41
52
  if (!proc?.on)
@@ -1,3 +1,7 @@
1
+ /**
2
+ * The request header naming the addon a call is made on behalf of, read by
3
+ * {@link addonScopeCap}.
4
+ */
1
5
  export declare const ADDON_HEADER = "x-pikku-addon";
2
6
  /**
3
7
  * Narrows the session to what an addon is allowed to do. A call that names an
@@ -1,6 +1,10 @@
1
1
  import { ForbiddenError } from '../errors/errors.js';
2
2
  import { intersectScopes } from '../scopes.js';
3
3
  import { pikkuMiddleware, pikkuMiddlewareFactory, } from './middleware-factories.js';
4
+ /**
5
+ * The request header naming the addon a call is made on behalf of, read by
6
+ * {@link addonScopeCap}.
7
+ */
4
8
  export const ADDON_HEADER = 'x-pikku-addon';
5
9
  /**
6
10
  * Narrows the session to what an addon is allowed to do. A call that names an
@@ -16,17 +20,17 @@ export const ADDON_HEADER = 'x-pikku-addon';
16
20
  * Register it after the session middleware: it narrows a session that is
17
21
  * already resolved, and a call with no session has nothing to narrow.
18
22
  */
19
- export const addonScopeCap = pikkuMiddlewareFactory(({ resolve }) => pikkuMiddleware(async (_services, { http, setSession, getSession }, next) => {
23
+ export const addonScopeCap = pikkuMiddlewareFactory(({ resolve }) => pikkuMiddleware(async (_services, { http, setInitialSession, getSession }, next) => {
20
24
  const name = http?.request?.header(ADDON_HEADER);
21
25
  const session = await getSession?.();
22
- if (!name || !setSession || !session) {
26
+ if (!name || !setInitialSession || !session) {
23
27
  return next();
24
28
  }
25
29
  const role = await resolve(name);
26
30
  if (!role) {
27
31
  throw new ForbiddenError(`Unknown addon '${name}'`);
28
32
  }
29
- await setSession({
33
+ setInitialSession({
30
34
  ...session,
31
35
  scopes: intersectScopes(session.scopes, role),
32
36
  });
@@ -5,8 +5,8 @@ import { pikkuMiddleware, pikkuMiddlewareFactory, } from './middleware-factories
5
5
  *
6
6
  * @example snippet: machineAuth
7
7
  */
8
- export const authAPIKey = pikkuMiddlewareFactory(({ source }) => pikkuMiddleware(async ({ jwt: jwtService }, { http, setSession, session }, next) => {
9
- if (!http?.request || !setSession || session) {
8
+ export const authAPIKey = pikkuMiddlewareFactory(({ source }) => pikkuMiddleware(async ({ jwt: jwtService }, { http, setInitialSession, session }, next) => {
9
+ if (!http?.request || !setInitialSession || session) {
10
10
  return next();
11
11
  }
12
12
  let apiKey = null;
@@ -19,7 +19,7 @@ export const authAPIKey = pikkuMiddlewareFactory(({ source }) => pikkuMiddleware
19
19
  if (apiKey && jwtService) {
20
20
  const userSession = await jwtService.decode(apiKey);
21
21
  if (userSession) {
22
- await setSession?.(userSession);
22
+ setInitialSession?.(userSession);
23
23
  }
24
24
  }
25
25
  return next();
@@ -1,14 +1,6 @@
1
1
  import { InvalidSessionError } from '../errors/errors.js';
2
2
  import { pikkuMiddleware, pikkuMiddlewareFactory, } from './middleware-factories.js';
3
- const constantTimeEqual = (a, b) => {
4
- if (a.length !== b.length)
5
- return false;
6
- let result = 0;
7
- for (let i = 0; i < a.length; i++) {
8
- result |= a.charCodeAt(i) ^ b.charCodeAt(i);
9
- }
10
- return result === 0;
11
- };
3
+ import { timingSafeStringEqual } from '../utils/hmac.js';
12
4
  /**
13
5
  * Validates a bearer token: JWT-decoded by default, or compared in constant
14
6
  * time against a static `value` or a `secretId` resolved through the secrets
@@ -16,8 +8,8 @@ const constantTimeEqual = (a, b) => {
16
8
  *
17
9
  * @example snippet: machineAuth
18
10
  */
19
- export const authBearer = pikkuMiddlewareFactory(({ token } = {}) => pikkuMiddleware(async ({ jwt: jwtService, secrets }, { http, setSession, session }, next) => {
20
- if (!http?.request || !setSession || session) {
11
+ export const authBearer = pikkuMiddlewareFactory(({ token } = {}) => pikkuMiddleware(async ({ jwt: jwtService, secrets }, { http, setInitialSession, session }, next) => {
12
+ if (!http?.request || !setInitialSession || session) {
21
13
  return next();
22
14
  }
23
15
  const authHeader = http.request.header('authorization') ||
@@ -40,7 +32,7 @@ export const authBearer = pikkuMiddlewareFactory(({ token } = {}) => pikkuMiddle
40
32
  .catch(() => undefined);
41
33
  expected = stored?.reveal();
42
34
  }
43
- if (expected && constantTimeEqual(bearerToken, expected)) {
35
+ if (expected && timingSafeStringEqual(bearerToken, expected)) {
44
36
  userSession = token.userSession;
45
37
  }
46
38
  }
@@ -48,7 +40,7 @@ export const authBearer = pikkuMiddlewareFactory(({ token } = {}) => pikkuMiddle
48
40
  userSession = await jwtService.decode(bearerToken);
49
41
  }
50
42
  if (userSession) {
51
- await setSession?.(userSession);
43
+ setInitialSession?.(userSession);
52
44
  }
53
45
  }
54
46
  return next();
@@ -34,8 +34,8 @@ export const authCookie = pikkuMiddlewareFactory(({ name, options, expiresIn })
34
34
  path: '/',
35
35
  ...options,
36
36
  };
37
- return pikkuMiddleware(async ({ jwt: jwtService, logger }, { http, setSession, getSession, session, hasSessionChanged }, next) => {
38
- if (!http?.request || !setSession || session) {
37
+ return pikkuMiddleware(async ({ jwt: jwtService, logger }, { http, setInitialSession, getSession, session, hasSessionChanged }, next) => {
38
+ if (!http?.request || !setInitialSession || session) {
39
39
  return next();
40
40
  }
41
41
  const cookieValue = http.request.cookie(name);
@@ -47,7 +47,7 @@ export const authCookie = pikkuMiddlewareFactory(({ name, options, expiresIn })
47
47
  // standard JWT timestamp, so an identity-less token is treated as no
48
48
  // session rather than as an authenticated one.
49
49
  if (userSession && hasSessionIdentity(userSession)) {
50
- await setSession?.(userSession);
50
+ setInitialSession?.(userSession);
51
51
  }
52
52
  }
53
53
  await next();
@@ -2,7 +2,24 @@ import type { CoreSingletonServices, CoreUserSession } from '../types/core.types
2
2
  import type { CorePikkuChannelMiddleware, CorePikkuChannelMiddlewareFactory } from '../wirings/channel/channel.types.js';
3
3
  import type { PikkuAgentMiddlewareHooks } from '../wirings/agent/agent.types.js';
4
4
  import type { CorePikkuMiddleware, CorePikkuMiddlewareConfig, CorePikkuMiddlewareFactory } from './middleware.types.js';
5
+ /**
6
+ * Declares middleware that runs around a function: authentication, logging,
7
+ * headers, rate limits. Takes the middleware itself, or `{ func, name,
8
+ * description, priority }`; `priority` (default `medium`) orders it among the
9
+ * other middleware on the same invocation, `highest` outermost.
10
+ *
11
+ * The inspector reads the destructured services and wire parameters to know
12
+ * what the middleware uses, so destructure them rather than taking them whole.
13
+ *
14
+ * @example snippet: corsMiddleware
15
+ */
5
16
  export declare const pikkuMiddleware: <SingletonServices extends CoreSingletonServices = CoreSingletonServices, UserSession extends CoreUserSession = CoreUserSession>(middleware: CorePikkuMiddleware<SingletonServices, UserSession> | CorePikkuMiddlewareConfig<SingletonServices, UserSession>) => CorePikkuMiddleware<SingletonServices, UserSession>;
17
+ /**
18
+ * Declares middleware that takes options, so one definition can be wired
19
+ * several times with different configuration.
20
+ *
21
+ * @example snippet: middlewareFactory
22
+ */
6
23
  export declare const pikkuMiddlewareFactory: <In = any>(factory: CorePikkuMiddlewareFactory<In>) => CorePikkuMiddlewareFactory<In>;
7
24
  /**
8
25
  * Declares middleware for a channel — it runs around the connection and its
@@ -1,3 +1,14 @@
1
+ /**
2
+ * Declares middleware that runs around a function: authentication, logging,
3
+ * headers, rate limits. Takes the middleware itself, or `{ func, name,
4
+ * description, priority }`; `priority` (default `medium`) orders it among the
5
+ * other middleware on the same invocation, `highest` outermost.
6
+ *
7
+ * The inspector reads the destructured services and wire parameters to know
8
+ * what the middleware uses, so destructure them rather than taking them whole.
9
+ *
10
+ * @example snippet: corsMiddleware
11
+ */
1
12
  export const pikkuMiddleware = (middleware) => {
2
13
  if (typeof middleware === 'function')
3
14
  return middleware;
@@ -7,6 +18,12 @@ export const pikkuMiddleware = (middleware) => {
7
18
  }
8
19
  return func;
9
20
  };
21
+ /**
22
+ * Declares middleware that takes options, so one definition can be wired
23
+ * several times with different configuration.
24
+ *
25
+ * @example snippet: middlewareFactory
26
+ */
10
27
  export const pikkuMiddlewareFactory = (factory) => {
11
28
  return factory;
12
29
  };
@@ -1,10 +1,20 @@
1
1
  import type { CoreSingletonServices, CoreUserSession, PikkuWire } from '../types/core.types.js';
2
+ /**
3
+ * Middleware around a function invocation: it receives the services and the
4
+ * wire, and runs the rest of the chain by awaiting `next()`. Not calling `next`
5
+ * stops the chain, so the function never runs; throwing answers with that
6
+ * error.
7
+ */
2
8
  export type CorePikkuMiddleware<SingletonServices extends CoreSingletonServices = CoreSingletonServices, UserSession extends CoreUserSession = CoreUserSession> = (services: SingletonServices, wires: PikkuWire, next: () => Promise<void>) => Promise<void>;
3
9
  /**
4
10
  * Execution order: `highest` runs first (outermost in the onion), `lowest`
5
11
  * runs last, closest to the function.
6
12
  */
7
13
  export type MiddlewarePriority = 'highest' | 'high' | 'medium' | 'low' | 'lowest';
14
+ /**
15
+ * The object form of {@link pikkuMiddleware}, for middleware that carries a
16
+ * name, description or priority.
17
+ */
8
18
  export type CorePikkuMiddlewareConfig<SingletonServices extends CoreSingletonServices = CoreSingletonServices, UserSession extends CoreUserSession = CoreUserSession> = {
9
19
  func: CorePikkuMiddleware<SingletonServices, UserSession>;
10
20
  name?: string;
@@ -12,8 +22,21 @@ export type CorePikkuMiddlewareConfig<SingletonServices extends CoreSingletonSer
12
22
  /** Execution priority. Lower runs first (outermost). Defaults to 'medium'. */
13
23
  priority?: MiddlewarePriority;
14
24
  };
25
+ /**
26
+ * A function that takes options and returns middleware, as declared with
27
+ * {@link pikkuMiddlewareFactory}.
28
+ */
15
29
  export type CorePikkuMiddlewareFactory<In = any, SingletonServices extends CoreSingletonServices = CoreSingletonServices, UserSession extends CoreUserSession = CoreUserSession> = (input: In) => CorePikkuMiddleware<SingletonServices, UserSession>;
30
+ /**
31
+ * A list of middleware, or middleware factories, registered together against
32
+ * a tag or route.
33
+ */
16
34
  export type CorePikkuMiddlewareGroup<SingletonServices extends CoreSingletonServices = CoreSingletonServices, UserSession extends CoreUserSession = CoreUserSession> = Array<CorePikkuMiddleware<SingletonServices, UserSession> | CorePikkuMiddlewareFactory<any, SingletonServices, UserSession>>;
35
+ /**
36
+ * How codegen records where a piece of inherited middleware comes from: an
37
+ * HTTP route pattern, a tag, or a named wire-level middleware.
38
+ * @internal
39
+ */
17
40
  export type MiddlewareMetadata = {
18
41
  type: 'http';
19
42
  route: string;
@@ -1,3 +1,18 @@
1
+ /**
2
+ * Authenticates calls between deployments of the same app, on the generated
3
+ * remote-RPC route. Once `PIKKU_REMOTE_SECRET` is set it requires a
4
+ * `Bearer` JWT with audience `pikku-remote`; a token bound to a function (`fn`)
5
+ * is only accepted on that function's `/remote/rpc/<fn>` path, and any session
6
+ * it carries is decrypted with the secret and set on the wire.
7
+ *
8
+ * Without the secret it lets non-remote paths through and refuses
9
+ * `/remote/rpc/*`, so the remote surface fails closed.
10
+ *
11
+ * @throws {UnauthorizedError} On a missing, malformed, mis-addressed or
12
+ * undecryptable token.
13
+ * @throws {WeakKeyMaterialError} When the secret is too short to use.
14
+ * @throws {Error} When the secret is set but no JWT service is configured.
15
+ */
1
16
  export declare const pikkuRemoteAuthMiddleware: import("./middleware.types.js").CorePikkuMiddleware<import("../types/core.types.js").CoreSingletonServices<{
2
17
  logLevel?: import("../services/logger.js").LogLevel;
3
18
  secrets?: {
@@ -10,7 +10,22 @@ const REMOTE_RPC_PREFIX = '/remote/rpc/';
10
10
  * past the trust gate and the token's `fn` binding while still being dispatched.
11
11
  */
12
12
  const isRemoteRpcPath = (path) => path.toLowerCase().startsWith(REMOTE_RPC_PREFIX);
13
- export const pikkuRemoteAuthMiddleware = pikkuMiddleware(async ({ secrets, jwt }, { http, setSession }, next) => {
13
+ /**
14
+ * Authenticates calls between deployments of the same app, on the generated
15
+ * remote-RPC route. Once `PIKKU_REMOTE_SECRET` is set it requires a
16
+ * `Bearer` JWT with audience `pikku-remote`; a token bound to a function (`fn`)
17
+ * is only accepted on that function's `/remote/rpc/<fn>` path, and any session
18
+ * it carries is decrypted with the secret and set on the wire.
19
+ *
20
+ * Without the secret it lets non-remote paths through and refuses
21
+ * `/remote/rpc/*`, so the remote surface fails closed.
22
+ *
23
+ * @throws {UnauthorizedError} On a missing, malformed, mis-addressed or
24
+ * undecryptable token.
25
+ * @throws {WeakKeyMaterialError} When the secret is too short to use.
26
+ * @throws {Error} When the secret is set but no JWT service is configured.
27
+ */
28
+ export const pikkuRemoteAuthMiddleware = pikkuMiddleware(async ({ secrets, jwt }, { http, setInitialSession }, next) => {
14
29
  if (!http?.request || !secrets) {
15
30
  return next();
16
31
  }
@@ -58,8 +73,8 @@ export const pikkuRemoteAuthMiddleware = pikkuMiddleware(async ({ secrets, jwt }
58
73
  if (payload?.session) {
59
74
  try {
60
75
  const decrypted = await decryptWithKeyMaterial('PIKKU_REMOTE_SECRET', secret, REMOTE_SESSION_INFO, payload.session);
61
- if (decrypted?.session && setSession) {
62
- await setSession(decrypted.session);
76
+ if (decrypted?.session && setInitialSession) {
77
+ setInitialSession(decrypted.session);
63
78
  }
64
79
  }
65
80
  catch {
@@ -1,15 +1,7 @@
1
1
  import { UnauthorizedError } from '../errors/errors.js';
2
2
  import { REMOTE_JOBS_SECRET_HEADER, REMOTE_JOBS_SECRET_VARIABLE, } from '../services/remote-jobs.js';
3
3
  import { pikkuMiddleware } from './middleware-factories.js';
4
- const constantTimeEqual = (a, b) => {
5
- if (a.length !== b.length)
6
- return false;
7
- let result = 0;
8
- for (let i = 0; i < a.length; i++) {
9
- result |= a.charCodeAt(i) ^ b.charCodeAt(i);
10
- }
11
- return result === 0;
12
- };
4
+ import { timingSafeStringEqual } from '../utils/hmac.js';
13
5
  /**
14
6
  * Guards the remote job inbox. Fails closed: an unset secret rejects every
15
7
  * caller, so the routes are never open just because the deployment forgot to
@@ -20,7 +12,7 @@ export const remoteJobsSecret = pikkuMiddleware(async ({ variables }, { http },
20
12
  const provided = http?.request?.header(REMOTE_JOBS_SECRET_HEADER);
21
13
  if (!expected ||
22
14
  typeof provided !== 'string' ||
23
- !constantTimeEqual(provided, expected)) {
15
+ !timingSafeStringEqual(provided, expected)) {
24
16
  throw new UnauthorizedError('invalid dispatch secret');
25
17
  }
26
18
  return next();
@@ -1,5 +1,12 @@
1
1
  import type { PikkuWiringTypes } from './types/core.types.js';
2
2
  import type { CorePikkuMiddleware, CorePikkuMiddlewareGroup, MiddlewareMetadata } from './middleware/middleware.types.js';
3
+ /**
4
+ * Runs `middlewares` as an onion around `main`, ordered by priority (stable
5
+ * within a priority), and returns `main`'s result. A middleware that does not
6
+ * call `next` stops the chain: `main` is never run and the result is
7
+ * `undefined`.
8
+ * @internal
9
+ */
3
10
  export declare const runMiddleware: <Middleware extends CorePikkuMiddleware<any, any>>(services: Parameters<Middleware>[0], wire: Parameters<Middleware>[1], middlewares: readonly Middleware[], main?: () => Promise<unknown>) => Promise<unknown>;
4
11
  /**
5
12
  * Registers tag-scoped middleware for any wiring carrying the tag. Wrap in a