@pikku/core 0.12.84 → 0.12.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (564) hide show
  1. package/CHANGELOG.md +424 -0
  2. package/dist/bootstrap-compat/root.d.ts +20 -0
  3. package/dist/classification/column-form.d.ts +32 -0
  4. package/dist/classification/column-form.js +42 -0
  5. package/dist/classification/data-classification.d.ts +64 -0
  6. package/dist/classification/index.d.ts +13 -0
  7. package/dist/classification/index.js +2 -0
  8. package/dist/classification/secret-value.d.ts +56 -0
  9. package/dist/classification/secret-value.js +46 -0
  10. package/dist/crypto-utils.d.ts +1 -1
  11. package/dist/ecosystem/agent-scorer.d.ts +1 -1
  12. package/dist/ecosystem/agent.d.ts +4 -1
  13. package/dist/ecosystem/channel/local.d.ts +2 -0
  14. package/dist/ecosystem/channel/local.js +2 -0
  15. package/dist/ecosystem/channel/serverless.d.ts +9 -0
  16. package/dist/ecosystem/channel/serverless.js +1 -0
  17. package/dist/ecosystem/channel.d.ts +3 -0
  18. package/dist/ecosystem/channel.js +1 -0
  19. package/dist/ecosystem/cli.d.ts +1 -1
  20. package/dist/ecosystem/cli.js +1 -1
  21. package/dist/ecosystem/credential.d.ts +1 -0
  22. package/dist/ecosystem/crypto-utils.d.ts +8 -0
  23. package/dist/ecosystem/crypto-utils.js +1 -0
  24. package/dist/ecosystem/dev.d.ts +1 -0
  25. package/dist/ecosystem/dev.js +1 -0
  26. package/{src/ecosystem/testing.ts → dist/ecosystem/errors.d.ts} +3 -3
  27. package/dist/ecosystem/errors.js +2 -0
  28. package/dist/ecosystem/function.d.ts +1 -1
  29. package/dist/ecosystem/function.js +1 -1
  30. package/dist/ecosystem/http.d.ts +3 -1
  31. package/dist/ecosystem/http.js +3 -1
  32. package/dist/ecosystem/mcp.d.ts +1 -1
  33. package/dist/ecosystem/mcp.js +1 -1
  34. package/dist/ecosystem/middleware.d.ts +2 -1
  35. package/dist/ecosystem/middleware.js +2 -1
  36. package/dist/ecosystem/persona.d.ts +4 -2
  37. package/dist/ecosystem/persona.js +2 -1
  38. package/dist/ecosystem/queue.d.ts +4 -2
  39. package/dist/ecosystem/queue.js +3 -1
  40. package/dist/ecosystem/role.d.ts +1 -0
  41. package/dist/ecosystem/rpc.d.ts +2 -0
  42. package/dist/ecosystem/rpc.js +1 -0
  43. package/dist/ecosystem/scenario.d.ts +8 -2
  44. package/dist/ecosystem/scenario.js +5 -1
  45. package/dist/ecosystem/scheduler.d.ts +2 -1
  46. package/dist/ecosystem/scheduler.js +2 -1
  47. package/dist/ecosystem/schema.d.ts +2 -1
  48. package/dist/ecosystem/schema.js +1 -1
  49. package/dist/ecosystem/scope.d.ts +2 -0
  50. package/dist/ecosystem/scope.js +1 -0
  51. package/dist/ecosystem/secret.d.ts +2 -0
  52. package/dist/ecosystem/secret.js +1 -0
  53. package/dist/ecosystem/services/local-content.d.ts +2 -1
  54. package/dist/ecosystem/services/local-content.js +1 -1
  55. package/dist/ecosystem/services/local-meta.d.ts +1 -0
  56. package/dist/ecosystem/services/local-meta.js +1 -0
  57. package/dist/ecosystem/services.d.ts +11 -3
  58. package/dist/ecosystem/services.js +7 -1
  59. package/dist/ecosystem/trigger.d.ts +1 -0
  60. package/dist/ecosystem/trigger.js +1 -1
  61. package/dist/ecosystem/types.d.ts +6 -3
  62. package/dist/ecosystem/types.js +3 -2
  63. package/dist/ecosystem/variable.d.ts +1 -0
  64. package/dist/ecosystem/virtual-user.d.ts +3 -0
  65. package/dist/ecosystem/virtual-user.js +3 -0
  66. package/dist/ecosystem/workflow.d.ts +2 -0
  67. package/dist/ecosystem/workflow.js +2 -0
  68. package/dist/errors/index.d.ts +8 -0
  69. package/dist/errors/index.js +1 -0
  70. package/dist/errors/serialized-error.d.ts +7 -0
  71. package/dist/function/function-meta.types.d.ts +139 -0
  72. package/dist/function/function-runner.d.ts +3 -2
  73. package/dist/function/function-runner.js +31 -11
  74. package/dist/function/functions.types.d.ts +10 -2
  75. package/dist/function/index.d.ts +8 -2
  76. package/dist/function/index.js +4 -1
  77. package/dist/function/pikku-request.d.ts +8 -0
  78. package/dist/function/pikku-request.js +15 -0
  79. package/dist/middleware/auth-apikey.d.ts +2 -10
  80. package/dist/middleware/auth-apikey.js +1 -1
  81. package/dist/middleware/auth-bearer.d.ts +2 -10
  82. package/dist/middleware/auth-bearer.js +1 -1
  83. package/dist/middleware/auth-cookie.d.ts +2 -10
  84. package/dist/middleware/auth-cookie.js +1 -1
  85. package/dist/middleware/cors.d.ts +5 -11
  86. package/dist/middleware/cors.js +13 -6
  87. package/dist/middleware/index.d.ts +3 -0
  88. package/dist/middleware/index.js +1 -0
  89. package/dist/middleware/middleware-factories.d.ts +9 -0
  90. package/dist/middleware/middleware-factories.js +19 -0
  91. package/dist/middleware/middleware.types.d.ts +27 -0
  92. package/dist/middleware/middleware.types.js +1 -0
  93. package/dist/middleware/remote-auth.d.ts +2 -2
  94. package/dist/middleware/remote-auth.js +1 -1
  95. package/dist/middleware/telemetry.d.ts +4 -20
  96. package/dist/middleware/telemetry.js +1 -1
  97. package/dist/middleware-runner.d.ts +2 -1
  98. package/dist/pikku-state.d.ts +2 -1
  99. package/dist/services/audit-service.d.ts +1 -1
  100. package/dist/services/credential-wire-service.js +1 -1
  101. package/dist/services/email-service.d.ts +1 -1
  102. package/dist/services/file-scenario-run-store.d.ts +58 -0
  103. package/dist/services/file-scenario-run-store.js +214 -0
  104. package/dist/services/in-memory-workflow-service.d.ts +1 -1
  105. package/dist/services/index.d.ts +5 -1
  106. package/dist/services/index.js +3 -0
  107. package/dist/services/local-secrets.d.ts +1 -1
  108. package/dist/services/local-secrets.js +1 -1
  109. package/dist/services/logger.d.ts +7 -7
  110. package/dist/services/meta-service.d.ts +2 -1
  111. package/dist/services/scoped-secret-service.d.ts +1 -1
  112. package/dist/services/secret-service.d.ts +1 -1
  113. package/dist/services/typed-secret-service.d.ts +16 -2
  114. package/dist/services/typed-secret-service.js +5 -0
  115. package/dist/services/webhook-service.d.ts +1 -1
  116. package/dist/services/workflow-service.d.ts +2 -1
  117. package/dist/testing/index.d.ts +1 -0
  118. package/dist/testing/index.js +1 -0
  119. package/dist/types/core.types.d.ts +30 -180
  120. package/dist/types/core.types.js +1 -19
  121. package/dist/types/index.d.ts +2 -0
  122. package/dist/types/index.js +1 -0
  123. package/dist/types/state.types.d.ts +3 -1
  124. package/dist/utils.d.ts +13 -0
  125. package/dist/utils.js +2 -0
  126. package/dist/wirings/addon/addon-runner.d.ts +17 -0
  127. package/dist/wirings/addon/addon-runner.js +150 -0
  128. package/dist/wirings/addon/index.d.ts +6 -0
  129. package/dist/wirings/addon/index.js +3 -0
  130. package/dist/wirings/addon/remote-addon-auth.d.ts +16 -0
  131. package/dist/wirings/addon/remote-addon-auth.js +39 -0
  132. package/dist/wirings/addon/wire-addon.d.ts +80 -0
  133. package/dist/wirings/addon/wire-addon.js +120 -0
  134. package/dist/wirings/addon/wire-remote-addon.d.ts +22 -0
  135. package/dist/wirings/addon/wire-remote-addon.js +11 -0
  136. package/dist/wirings/agent/agent-prepare.d.ts +3 -3
  137. package/dist/wirings/agent/agent-prepare.js +1 -1
  138. package/dist/wirings/agent/agent-runner.js +2 -3
  139. package/dist/wirings/agent/agent-stream.js +2 -2
  140. package/dist/wirings/agent/agent-utils.d.ts +13 -0
  141. package/dist/wirings/agent/agent-utils.js +16 -0
  142. package/dist/wirings/agent/agent.types.d.ts +3 -2
  143. package/dist/wirings/agent/index.d.ts +1 -1
  144. package/dist/wirings/agent/voice-input.js +1 -1
  145. package/dist/wirings/agent/voice-output.js +1 -1
  146. package/dist/wirings/agent-scorer/agent-scorer-judge.d.ts +13 -0
  147. package/dist/wirings/agent-scorer/agent-scorer-judge.js +52 -0
  148. package/dist/wirings/agent-scorer/agent-scorer.d.ts +7 -1
  149. package/dist/wirings/agent-scorer/agent-scorer.js +1 -0
  150. package/dist/wirings/agent-scorer/agent-scorer.types.d.ts +20 -0
  151. package/dist/wirings/agent-scorer/index.d.ts +1 -1
  152. package/dist/wirings/channel/channel-common.d.ts +2 -1
  153. package/dist/wirings/channel/channel-middleware-runner.d.ts +2 -1
  154. package/dist/wirings/channel/channel.types.d.ts +1 -1
  155. package/dist/wirings/channel/serverless/index.d.ts +1 -0
  156. package/dist/wirings/cli/channel/index.d.ts +1 -1
  157. package/dist/wirings/cli/cli-runner.d.ts +2 -1
  158. package/dist/wirings/cli/cli-runner.js +4 -1
  159. package/dist/wirings/cli/cli.types.d.ts +21 -2
  160. package/dist/wirings/cli/command-parser.js +157 -23
  161. package/dist/wirings/gateway/gateway.types.d.ts +2 -1
  162. package/dist/wirings/http/http-runner.d.ts +1 -1
  163. package/dist/wirings/http/http-runner.js +1 -1
  164. package/dist/wirings/http/http.types.d.ts +2 -2
  165. package/dist/wirings/http/index.d.ts +1 -0
  166. package/dist/wirings/http/index.js +1 -0
  167. package/dist/wirings/http/pikku-fetch-http-request.js +1 -1
  168. package/dist/wirings/http/pikku-fetch-http-response.js +2 -2
  169. package/dist/wirings/mcp/mcp.types.d.ts +1 -1
  170. package/dist/wirings/persona/index.d.ts +1 -1
  171. package/dist/wirings/persona/index.js +1 -1
  172. package/dist/wirings/persona/persona.types.d.ts +14 -0
  173. package/dist/wirings/queue/queue.types.d.ts +1 -1
  174. package/dist/wirings/queue/signed-queue-service.d.ts +1 -1
  175. package/dist/wirings/rpc/index.d.ts +0 -6
  176. package/dist/wirings/rpc/index.js +0 -3
  177. package/dist/wirings/rpc/remote-addon-auth.d.ts +1 -1
  178. package/dist/wirings/rpc/remote-addon-auth.js +1 -1
  179. package/dist/wirings/rpc/rpc-runner.js +2 -2
  180. package/dist/wirings/rpc/wire-addon.d.ts +1 -1
  181. package/dist/wirings/scheduler/scheduler.types.d.ts +2 -1
  182. package/dist/wirings/scope/index.d.ts +1 -0
  183. package/dist/wirings/scope/index.js +1 -0
  184. package/dist/wirings/secret/secret.types.d.ts +10 -0
  185. package/dist/wirings/secret/validate-secret-definitions.js +2 -0
  186. package/dist/wirings/variable/validate-variable-definitions.js +2 -0
  187. package/dist/wirings/variable/variable.types.d.ts +9 -0
  188. package/dist/wirings/virtual-user/index.d.ts +1 -1
  189. package/dist/wirings/virtual-user/index.js +1 -1
  190. package/dist/wirings/virtual-user/prepare-virtual-user-run.d.ts +1 -1
  191. package/dist/wirings/virtual-user/virtual-user-derive.d.ts +1 -1
  192. package/dist/wirings/workflow/graph/graph-node.d.ts +9 -2
  193. package/dist/wirings/workflow/graph/graph-node.js +2 -0
  194. package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -0
  195. package/dist/wirings/workflow/graph/graph-runner.js +283 -31
  196. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +16 -1
  197. package/dist/wirings/workflow/index.d.ts +2 -0
  198. package/dist/wirings/workflow/index.js +1 -0
  199. package/dist/wirings/workflow/pikku-scenario-service.d.ts +14 -4
  200. package/dist/wirings/workflow/pikku-scenario-service.js +44 -16
  201. package/dist/wirings/workflow/pikku-workflow-service.d.ts +2 -1
  202. package/dist/wirings/workflow/pikku-workflow-service.js +3 -4
  203. package/dist/wirings/workflow/run-timeline.d.ts +1 -1
  204. package/dist/wirings/workflow/scenario-run.types.d.ts +171 -0
  205. package/dist/wirings/workflow/scenario-run.types.js +1 -0
  206. package/dist/wirings/workflow/scenario-step-guards.d.ts +1 -2
  207. package/dist/wirings/workflow/scenario-step-guards.js +0 -8
  208. package/dist/wirings/workflow/scenario-step.types.d.ts +27 -12
  209. package/dist/wirings/workflow/workflow-approval.js +2 -1
  210. package/dist/wirings/workflow/workflow-run-engine.types.d.ts +2 -1
  211. package/dist/wirings/workflow/workflow.types.d.ts +2 -1
  212. package/knowledge/decisions/index.md +2 -0
  213. package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +1 -1
  214. package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +1 -1
  215. package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-and-not-a-queued-job.md +2 -2
  216. package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +6 -6
  217. package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +1 -1
  218. package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +1 -1
  219. package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +1 -1
  220. package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +1 -1
  221. package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +1 -1
  222. package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +1 -1
  223. package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +1 -1
  224. package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +1 -1
  225. package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +1 -1
  226. package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +1 -1
  227. package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +4 -4
  228. package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +1 -1
  229. package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +3 -3
  230. package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +2 -2
  231. package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +2 -2
  232. package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +1 -1
  233. package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +1 -1
  234. package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +3 -3
  235. package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +1 -1
  236. package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +4 -4
  237. package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +1 -1
  238. package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +1 -1
  239. package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +1 -1
  240. package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +1 -1
  241. package/knowledge/decisions/internals/index.md +4 -2
  242. package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +1 -1
  243. package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +1 -1
  244. package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +1 -1
  245. package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +1 -1
  246. package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +1 -1
  247. package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +2 -2
  248. package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +5 -5
  249. package/knowledge/decisions/internals/the-actor-prompt-says-json-because-of-json-object-mode.md +1 -1
  250. package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +1 -1
  251. package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +43 -19
  252. package/knowledge/decisions/internals/the-persona-runtime-is-exported-from-the-persona-entry-point.md +1 -1
  253. package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +1 -1
  254. package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +3 -3
  255. package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +1 -1
  256. package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +1 -1
  257. package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +1 -1
  258. package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +1 -1
  259. package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +1 -1
  260. package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +1 -1
  261. package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +1 -1
  262. package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +1 -1
  263. package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +1 -1
  264. package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +9 -5
  265. package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +1 -1
  266. package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +2 -2
  267. package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +1 -1
  268. package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +1 -1
  269. package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +1 -1
  270. package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +2 -3
  271. package/knowledge/decisions/security/actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +1 -1
  272. package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +1 -1
  273. package/knowledge/decisions/security/agent-gate-requires-a-session-only-when-auth-is-true.md +1 -1
  274. package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +3 -3
  275. package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +4 -3
  276. package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +1 -1
  277. package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +2 -2
  278. package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +1 -1
  279. package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +2 -2
  280. package/knowledge/decisions/security/index.md +2 -0
  281. package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +1 -1
  282. package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +3 -3
  283. package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +1 -1
  284. package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +2 -2
  285. package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +1 -1
  286. package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +2 -2
  287. package/knowledge/index.md +3 -1
  288. package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +1 -1
  289. package/knowledge/questions/index.md +2 -0
  290. package/package.json +14 -13
  291. package/run-tests.sh +0 -0
  292. package/scripts/generate-api-report.d.mts +1 -1
  293. package/scripts/generate-api-report.mjs +67 -60
  294. package/scripts/generate-api-report.mts +11 -45
  295. package/src/api-report.test.ts +70 -1
  296. package/src/app-alias-surface.test.ts +179 -0
  297. package/src/app-leaf-surface.test.ts +217 -0
  298. package/src/bootstrap-compat/root.ts +20 -0
  299. package/src/{column-form.test.ts → classification/column-form.test.ts} +2 -2
  300. package/src/{data-classification.ts → classification/data-classification.ts} +1 -5
  301. package/src/classification/index.ts +38 -0
  302. package/src/{secret-value.test.ts → classification/secret-value.test.ts} +2 -2
  303. package/src/{secret-value.ts → classification/secret-value.ts} +1 -6
  304. package/src/crypto-utils.ts +1 -1
  305. package/src/dev/reload-meta.test.ts +1 -1
  306. package/src/errors/index.ts +9 -0
  307. package/src/errors/serialized-error.ts +9 -0
  308. package/src/factory-functions.test.ts +4 -2
  309. package/src/function/function-meta.types.ts +151 -0
  310. package/src/function/function-runner.test.ts +4 -2
  311. package/src/function/function-runner.ts +47 -14
  312. package/src/function/functions.types.ts +11 -7
  313. package/src/function/index.ts +24 -5
  314. package/src/function/list.types.ts +1 -3
  315. package/src/middleware/auth-apikey.ts +4 -2
  316. package/src/middleware/auth-bearer.test.ts +1 -1
  317. package/src/middleware/auth-bearer.ts +4 -2
  318. package/src/middleware/auth-cookie.ts +4 -1
  319. package/src/middleware/cors.test.ts +126 -5
  320. package/src/middleware/cors.ts +19 -8
  321. package/src/middleware/index.ts +16 -0
  322. package/src/middleware/middleware-factories.ts +62 -0
  323. package/src/middleware/middleware.types.ts +61 -0
  324. package/src/middleware/remote-auth.test.ts +1 -1
  325. package/src/middleware/remote-auth.ts +1 -1
  326. package/src/middleware/telemetry.ts +4 -2
  327. package/src/middleware-runner.test.ts +2 -3
  328. package/src/middleware-runner.ts +2 -2
  329. package/src/no-root-barrel.test.ts +114 -0
  330. package/src/permissions.ts +2 -4
  331. package/src/pikku-state.ts +3 -1
  332. package/src/public-surface.json +56 -241
  333. package/src/public-surface.json.README +3 -3
  334. package/src/public-surface.test.ts +5 -5
  335. package/src/remote.test.ts +1 -1
  336. package/src/removed-legacy-exports.test.ts +5 -1
  337. package/src/services/audit-service.ts +1 -1
  338. package/src/services/credential-wire-service.ts +1 -1
  339. package/src/services/email-service.ts +2 -4
  340. package/src/services/file-scenario-run-store.test.ts +349 -0
  341. package/src/services/file-scenario-run-store.ts +282 -0
  342. package/src/services/in-memory-workflow-service.ts +1 -1
  343. package/src/services/index.ts +13 -1
  344. package/src/services/local-content-request-handler.ts +1 -2
  345. package/src/services/local-secrets.ts +1 -1
  346. package/src/services/logger.ts +7 -7
  347. package/src/services/meta-service.ts +2 -2
  348. package/src/services/queue-webhook-service.test.ts +1 -1
  349. package/src/services/scoped-secret-service.ts +1 -1
  350. package/src/services/secret-service.ts +1 -1
  351. package/src/services/typed-secret-service.test.ts +52 -0
  352. package/src/services/typed-secret-service.ts +26 -2
  353. package/src/services/webhook-service.ts +1 -1
  354. package/src/services/workflow-service.ts +2 -1
  355. package/src/template-alias-surface.test.ts +240 -0
  356. package/src/testing/index.ts +1 -0
  357. package/src/types/core.types.ts +33 -285
  358. package/src/types/index.ts +2 -0
  359. package/src/types/state.types.ts +6 -5
  360. package/src/types/typed-credentials.test.ts +72 -0
  361. package/src/utils.ts +34 -0
  362. package/src/wirings/{rpc → addon}/addon-scopes.test.ts +1 -1
  363. package/src/wirings/addon/index.ts +12 -0
  364. package/src/wirings/{rpc → addon}/remote-addon-auth.ts +4 -1
  365. package/src/wirings/{rpc → addon}/wire-addon.ts +37 -2
  366. package/src/wirings/agent/agent-prepare.ts +8 -5
  367. package/src/wirings/agent/agent-runner.ts +2 -3
  368. package/src/wirings/agent/agent-stream.ts +2 -3
  369. package/src/wirings/agent/agent-utils.ts +19 -0
  370. package/src/wirings/agent/agent.types.ts +3 -3
  371. package/src/wirings/agent/index.ts +1 -0
  372. package/src/wirings/agent/voice-input.ts +1 -1
  373. package/src/wirings/agent/voice-output.test.ts +2 -4
  374. package/src/wirings/agent/voice-output.ts +1 -1
  375. package/src/wirings/agent-scorer/agent-scorer-judge.test.ts +145 -0
  376. package/src/wirings/agent-scorer/agent-scorer-judge.ts +60 -0
  377. package/src/wirings/agent-scorer/agent-scorer.ts +8 -0
  378. package/src/wirings/agent-scorer/agent-scorer.types.ts +21 -0
  379. package/src/wirings/agent-scorer/index.ts +1 -0
  380. package/src/wirings/channel/channel-common.ts +4 -2
  381. package/src/wirings/channel/channel-handler.ts +2 -5
  382. package/src/wirings/channel/channel-middleware-runner.ts +1 -1
  383. package/src/wirings/channel/channel-rpc.types.ts +1 -5
  384. package/src/wirings/channel/channel.types.ts +1 -2
  385. package/src/wirings/channel/local/local-channel-runner.test.ts +1 -2
  386. package/src/wirings/channel/serverless/index.ts +1 -0
  387. package/src/wirings/cli/channel/cli-raw-channel-runner.ts +2 -2
  388. package/src/wirings/cli/channel/index.ts +1 -3
  389. package/src/wirings/cli/cli-runner.test.ts +1 -1
  390. package/src/wirings/cli/cli-runner.ts +11 -7
  391. package/src/wirings/cli/cli.types.ts +24 -3
  392. package/src/wirings/cli/command-parser.test.ts +388 -1
  393. package/src/wirings/cli/command-parser.ts +189 -29
  394. package/src/wirings/gateway/gateway-runner.test.ts +1 -2
  395. package/src/wirings/gateway/gateway-runner.ts +3 -6
  396. package/src/wirings/gateway/gateway.types.ts +5 -4
  397. package/src/wirings/http/http-routes.test.ts +1 -2
  398. package/src/wirings/http/http-runner-addon-ref.test.ts +238 -0
  399. package/src/wirings/http/http-runner.test.ts +3 -8
  400. package/src/wirings/http/http-runner.ts +9 -3
  401. package/src/wirings/http/http.types.ts +3 -12
  402. package/src/wirings/http/index.ts +1 -0
  403. package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
  404. package/src/wirings/http/pikku-fetch-http-response.ts +3 -2
  405. package/src/wirings/mcp/mcp-runner.test.ts +1 -1
  406. package/src/wirings/mcp/mcp.types.ts +1 -2
  407. package/src/wirings/persona/index.ts +1 -4
  408. package/src/wirings/persona/persona.types.ts +14 -0
  409. package/src/wirings/queue/queue-identity.test.ts +1 -1
  410. package/src/wirings/queue/queue.types.ts +2 -6
  411. package/src/wirings/queue/signed-queue-service.ts +1 -1
  412. package/src/wirings/rpc/index.ts +0 -12
  413. package/src/wirings/rpc/rpc-runner.test.ts +4 -4
  414. package/src/wirings/rpc/rpc-runner.ts +3 -3
  415. package/src/wirings/scheduler/scheduler.types.ts +2 -5
  416. package/src/wirings/scope/index.ts +1 -0
  417. package/src/wirings/secret/secret.types.ts +10 -0
  418. package/src/wirings/secret/validate-secret-definitions.test.ts +23 -0
  419. package/src/wirings/secret/validate-secret-definitions.ts +2 -0
  420. package/src/wirings/variable/validate-variable-definitions.test.ts +23 -0
  421. package/src/wirings/variable/validate-variable-definitions.ts +2 -0
  422. package/src/wirings/variable/variable.types.ts +9 -0
  423. package/src/wirings/virtual-user/index.ts +1 -4
  424. package/src/wirings/virtual-user/prepare-virtual-user-run.ts +1 -1
  425. package/src/wirings/virtual-user/virtual-user-derive.test.ts +1 -1
  426. package/src/wirings/virtual-user/virtual-user-derive.ts +1 -1
  427. package/src/wirings/virtual-user/virtual-user.types.ts +1 -5
  428. package/src/wirings/workflow/graph/graph-foreach-queued.test.ts +569 -0
  429. package/src/wirings/workflow/graph/graph-foreach.test.ts +626 -0
  430. package/src/wirings/workflow/graph/graph-node.ts +16 -1
  431. package/src/wirings/workflow/graph/graph-runner.ts +387 -61
  432. package/src/wirings/workflow/graph/workflow-graph.types.ts +28 -3
  433. package/src/wirings/workflow/index.ts +8 -0
  434. package/src/wirings/workflow/pikku-scenario-service.ts +59 -19
  435. package/src/wirings/workflow/pikku-workflow-service.ts +6 -8
  436. package/src/wirings/workflow/run-timeline.ts +1 -1
  437. package/src/wirings/workflow/scenario-expectations.test.ts +28 -13
  438. package/src/wirings/workflow/scenario-run.types.ts +186 -0
  439. package/src/wirings/workflow/scenario-step-guards.ts +1 -14
  440. package/src/wirings/workflow/scenario-step.test.ts +32 -7
  441. package/src/wirings/workflow/scenario-step.types.ts +27 -12
  442. package/src/wirings/workflow/workflow-approval-policy.test.ts +117 -47
  443. package/src/wirings/workflow/workflow-approval.ts +2 -1
  444. package/src/wirings/workflow/workflow-run-engine.types.ts +2 -1
  445. package/src/wirings/workflow/workflow.types.ts +4 -12
  446. package/src/wirings-stay-decoupled.test.ts +6 -3
  447. package/tsconfig.tsbuildinfo +1 -1
  448. package/tsconfig.type-tests.json +3 -2
  449. package/dist/ecosystem/ai-agent.d.ts +0 -18
  450. package/dist/ecosystem/ai-agent.js +0 -6
  451. package/dist/ecosystem/ai-scorer.d.ts +0 -12
  452. package/dist/ecosystem/ai-scorer.js +0 -5
  453. package/dist/services/ai-agent-runner-service.d.ts +0 -220
  454. package/dist/services/ai-run-state-service.d.ts +0 -29
  455. package/dist/services/ai-storage-service.d.ts +0 -18
  456. package/dist/services/in-memory-ai-run-state-service.d.ts +0 -19
  457. package/dist/services/in-memory-ai-run-state-service.js +0 -54
  458. package/dist/testing/service-tests/ai-storage-service-tests.d.ts +0 -3
  459. package/dist/testing/service-tests/ai-storage-service-tests.js +0 -302
  460. package/dist/wirings/ai-agent/agent-rpc.d.ts +0 -15
  461. package/dist/wirings/ai-agent/agent-rpc.js +0 -53
  462. package/dist/wirings/ai-agent/ai-agent-agui.d.ts +0 -79
  463. package/dist/wirings/ai-agent/ai-agent-agui.js +0 -327
  464. package/dist/wirings/ai-agent/ai-agent-finalize.d.ts +0 -58
  465. package/dist/wirings/ai-agent/ai-agent-finalize.js +0 -138
  466. package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +0 -35
  467. package/dist/wirings/ai-agent/ai-agent-helpers.js +0 -47
  468. package/dist/wirings/ai-agent/ai-agent-interrupt.d.ts +0 -153
  469. package/dist/wirings/ai-agent/ai-agent-interrupt.js +0 -257
  470. package/dist/wirings/ai-agent/ai-agent-memory.d.ts +0 -42
  471. package/dist/wirings/ai-agent/ai-agent-memory.js +0 -333
  472. package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +0 -16
  473. package/dist/wirings/ai-agent/ai-agent-model-config.js +0 -51
  474. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +0 -117
  475. package/dist/wirings/ai-agent/ai-agent-prepare.js +0 -728
  476. package/dist/wirings/ai-agent/ai-agent-registry.d.ts +0 -16
  477. package/dist/wirings/ai-agent/ai-agent-registry.js +0 -51
  478. package/dist/wirings/ai-agent/ai-agent-runner.d.ts +0 -7
  479. package/dist/wirings/ai-agent/ai-agent-runner.js +0 -580
  480. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +0 -41
  481. package/dist/wirings/ai-agent/ai-agent-stream.js +0 -1029
  482. package/dist/wirings/ai-agent/ai-agent-turn.d.ts +0 -57
  483. package/dist/wirings/ai-agent/ai-agent-turn.js +0 -82
  484. package/dist/wirings/ai-agent/ai-agent-utils.d.ts +0 -1
  485. package/dist/wirings/ai-agent/ai-agent-utils.js +0 -1
  486. package/dist/wirings/ai-agent/ai-agent.types.d.ts +0 -625
  487. package/dist/wirings/ai-agent/index.d.ts +0 -12
  488. package/dist/wirings/ai-agent/index.js +0 -10
  489. package/dist/wirings/ai-agent/voice-input.d.ts +0 -69
  490. package/dist/wirings/ai-agent/voice-input.js +0 -150
  491. package/dist/wirings/ai-agent/voice-output.d.ts +0 -85
  492. package/dist/wirings/ai-agent/voice-output.js +0 -196
  493. package/dist/wirings/ai-scorer/ai-scorer-grade.d.ts +0 -26
  494. package/dist/wirings/ai-scorer/ai-scorer-grade.js +0 -33
  495. package/dist/wirings/ai-scorer/ai-scorer-judge.d.ts +0 -17
  496. package/dist/wirings/ai-scorer/ai-scorer-judge.js +0 -92
  497. package/dist/wirings/ai-scorer/ai-scorer-live.d.ts +0 -15
  498. package/dist/wirings/ai-scorer/ai-scorer-live.js +0 -38
  499. package/dist/wirings/ai-scorer/ai-scorer-registry.d.ts +0 -18
  500. package/dist/wirings/ai-scorer/ai-scorer-registry.js +0 -46
  501. package/dist/wirings/ai-scorer/ai-scorer-sampling.d.ts +0 -8
  502. package/dist/wirings/ai-scorer/ai-scorer-sampling.js +0 -31
  503. package/dist/wirings/ai-scorer/ai-scorer-snapshots.d.ts +0 -10
  504. package/dist/wirings/ai-scorer/ai-scorer-snapshots.js +0 -40
  505. package/dist/wirings/ai-scorer/ai-scorer-worker.d.ts +0 -15
  506. package/dist/wirings/ai-scorer/ai-scorer-worker.js +0 -58
  507. package/dist/wirings/ai-scorer/ai-scorer.d.ts +0 -39
  508. package/dist/wirings/ai-scorer/ai-scorer.js +0 -40
  509. package/dist/wirings/ai-scorer/ai-scorer.types.d.ts +0 -90
  510. package/dist/wirings/ai-scorer/ai-scorer.types.js +0 -4
  511. package/dist/wirings/ai-scorer/index.d.ts +0 -6
  512. package/dist/wirings/ai-scorer/index.js +0 -5
  513. package/src/ecosystem/agent-scorer.ts +0 -24
  514. package/src/ecosystem/agent.ts +0 -42
  515. package/src/ecosystem/channel/local.ts +0 -1
  516. package/src/ecosystem/channel.ts +0 -22
  517. package/src/ecosystem/cli/channel.ts +0 -25
  518. package/src/ecosystem/cli.ts +0 -21
  519. package/src/ecosystem/credential.ts +0 -10
  520. package/src/ecosystem/dev.ts +0 -12
  521. package/src/ecosystem/function.ts +0 -28
  522. package/src/ecosystem/gateway.ts +0 -4
  523. package/src/ecosystem/hmac.ts +0 -1
  524. package/src/ecosystem/http.ts +0 -22
  525. package/src/ecosystem/mcp.ts +0 -17
  526. package/src/ecosystem/middleware.ts +0 -27
  527. package/src/ecosystem/node-host-resolver.ts +0 -1
  528. package/src/ecosystem/node.ts +0 -5
  529. package/src/ecosystem/oauth2.ts +0 -4
  530. package/src/ecosystem/persona.ts +0 -30
  531. package/src/ecosystem/queue.ts +0 -23
  532. package/src/ecosystem/remote.ts +0 -9
  533. package/src/ecosystem/role.ts +0 -13
  534. package/src/ecosystem/rpc.ts +0 -7
  535. package/src/ecosystem/safe-fetch.ts +0 -8
  536. package/src/ecosystem/scenario.ts +0 -32
  537. package/src/ecosystem/scheduler.ts +0 -5
  538. package/src/ecosystem/schema.ts +0 -1
  539. package/src/ecosystem/scope.ts +0 -14
  540. package/src/ecosystem/secret.ts +0 -15
  541. package/src/ecosystem/services/istanbul-coverage.ts +0 -1
  542. package/src/ecosystem/services/local-content-request-handler.ts +0 -16
  543. package/src/ecosystem/services/local-content.ts +0 -1
  544. package/src/ecosystem/services/v8-coverage.ts +0 -1
  545. package/src/ecosystem/services.ts +0 -82
  546. package/src/ecosystem/trigger.ts +0 -7
  547. package/src/ecosystem/types.ts +0 -34
  548. package/src/ecosystem/variable.ts +0 -14
  549. package/src/ecosystem/virtual-user.ts +0 -48
  550. package/src/ecosystem/workflow.ts +0 -68
  551. package/src/ecosystem.ts +0 -40
  552. package/src/index.ts +0 -244
  553. /package/dist/{services/ai-agent-runner-service.js → bootstrap-compat/root.js} +0 -0
  554. /package/dist/{services/ai-run-state-service.js → classification/data-classification.js} +0 -0
  555. /package/dist/{services/ai-storage-service.js → errors/serialized-error.js} +0 -0
  556. /package/dist/{wirings/ai-agent/ai-agent.types.js → function/function-meta.types.js} +0 -0
  557. /package/src/{column-form.ts → classification/column-form.ts} +0 -0
  558. /package/src/{pikku-request.test.ts → function/pikku-request.test.ts} +0 -0
  559. /package/src/{pikku-request.ts → function/pikku-request.ts} +0 -0
  560. /package/src/wirings/{rpc → addon}/addon-auth-tags.test.ts +0 -0
  561. /package/src/wirings/{rpc → addon}/addon-runner.ts +0 -0
  562. /package/src/wirings/{rpc → addon}/addon-secrets.test.ts +0 -0
  563. /package/src/wirings/{rpc → addon}/wire-addon.test.ts +0 -0
  564. /package/src/wirings/{rpc → addon}/wire-remote-addon.ts +0 -0
@@ -0,0 +1,151 @@
1
+ import type { MiddlewareMetadata } from '../middleware/middleware.types.js'
2
+ import type { AuditDurability } from '../services/audit-service.js'
3
+ import type {
4
+ ScenarioStepKind,
5
+ ScenarioSurface,
6
+ } from '../wirings/workflow/scenario-step.types.js'
7
+ import type { CommonWireMeta } from '../types/core.types.js'
8
+
9
+ export interface FunctionServicesMeta {
10
+ optimized: boolean
11
+ services: string[]
12
+ }
13
+
14
+ export interface FunctionWiresMeta {
15
+ optimized: boolean
16
+ wires: string[]
17
+ }
18
+
19
+ /**
20
+ * A reference to a permission function, resolved by name. Function-scoped
21
+ * only: there are no wire- or tag-level permission references.
22
+ */
23
+ export type PermissionMetadata = {
24
+ type: 'wire'
25
+ name: string
26
+ inline?: boolean
27
+ }
28
+
29
+ export type FunctionRuntimeMeta = {
30
+ pikkuFuncId: string
31
+ inputSchemaName: string | null
32
+ outputSchemaName: string | null
33
+ /** Scopes the session must hold to run this function. All are required (AND). */
34
+ scopes?: string[]
35
+ expose?: boolean
36
+ /**
37
+ * A sessionless function's own `auth: true`. `sessionless` carries the
38
+ * baseline — a `pikkuFunc` always requires a session — and this carries the
39
+ * tightening a `pikkuSessionlessFunc` applies to itself. Both are needed to
40
+ * know whether a function is gated without running it.
41
+ */
42
+ auth?: boolean
43
+ /**
44
+ * The author's declaration that this function's permission check lives in its
45
+ * own body. Carries no runtime effect — it records a gate codegen cannot see,
46
+ * so an audit is not left to guess whether a sessionless function is open.
47
+ * Refused unless `allow.permissionsInBody` is set in `pikku.config.json`.
48
+ */
49
+ permissionsInBody?: boolean
50
+ remote?: boolean
51
+ /**
52
+ * A step RPC: invoked by name only from a scenario run and refused
53
+ * everywhere else, so it is never network-callable.
54
+ */
55
+ scenarioStep?: boolean
56
+ /**
57
+ * The body of a `pikkuScenario(...)`. Only ever run by `pikku scenario run`,
58
+ * so it is held back from the app bootstrap and from every deployed unit.
59
+ */
60
+ scenario?: boolean
61
+ mcp?: boolean
62
+ readonly?: boolean
63
+ deploy?: 'serverless' | 'server' | 'auto'
64
+ sessionless?: boolean
65
+ /** When true, workflow steps calling this function are dispatched via the queue. No queue service configured is a hard error. */
66
+ workflowQueued?: boolean
67
+ /** Retry count when this function is used as a workflow step. */
68
+ workflowRetries?: number
69
+ /** Timeout when this function is used as a workflow step (e.g. '30s', '5m'). */
70
+ workflowTimeout?: string
71
+ /**
72
+ * Scenario steps only: which surfaces this step declares a binding for.
73
+ *
74
+ * The reporter derives coverage from this — a `then` with no binding for the
75
+ * surface the run targeted was never actually witnessed there, which is a gap
76
+ * worth counting rather than excusing.
77
+ */
78
+ scenarioStepSurfaces?: ScenarioSurface[]
79
+ /**
80
+ * Scenario steps only: this step runs as a persona, so every call site must
81
+ * pass one and the runner injects it as `wire.actor`.
82
+ *
83
+ * Declared by `actor: true`, or implied by a `browser` binding — a window is
84
+ * opened as somebody. Absent on a step with nobody to be: an assertion over
85
+ * what an earlier step returned, or one posting credentials precisely because
86
+ * it must not reuse an actor's session.
87
+ */
88
+ scenarioStepRequiresActor?: boolean
89
+ /**
90
+ * Scenario steps only: who acts. Absent means `persona` — the ordinary step,
91
+ * and the only kind that existed before the other two.
92
+ *
93
+ * A `platform` or `addon` step is the app or a third-party system acting, and
94
+ * it must never reach a virtual user's catalogue. That is not tidiness: a
95
+ * virtual user that can invoke "Stripe's webhook arrives" can forge its own
96
+ * payment success, and every finding downstream of that is worthless.
97
+ */
98
+ scenarioStepKind?: ScenarioStepKind
99
+ /** Addon steps only: the addon whose system acts — `wireAddon`'s `name`. */
100
+ scenarioStepAddon?: string
101
+ /** Scenario steps only: the prose a reporter renders, with `{placeholders}` filled from the step's recorded input. */
102
+ scenarioStepTemplate?: string
103
+ /**
104
+ * The function's `audit` config, resolved — `audit: true` reads as
105
+ * `{ durability: 'best-effort' }`. Absent means the function records nothing:
106
+ * `auditLog.write()` from an unmarked function is dropped with a warning, so
107
+ * this is the only place a reader can see which functions have a trail at all
108
+ * without running them.
109
+ *
110
+ * Informational. The runner resolves audit from the live function config, not
111
+ * from here, so meta and runtime cannot disagree about whether audit is on.
112
+ */
113
+ audit?: {
114
+ durability: AuditDurability
115
+ }
116
+ version?: number
117
+ approvalRequired?: boolean
118
+ approvalDescription?: string
119
+ implementationHash?: string
120
+ contractHash?: string
121
+ inputHash?: string
122
+ outputHash?: string
123
+ }
124
+
125
+ export type FunctionMeta = FunctionRuntimeMeta &
126
+ Partial<
127
+ {
128
+ name: string
129
+ /** `remote`: a contract with no local body, answered by a connected client. */
130
+ functionType: 'user' | 'inline' | 'helper' | 'remote'
131
+ funcWrapper: string
132
+ services: FunctionServicesMeta
133
+ wires: FunctionWiresMeta
134
+ inputs: string[] | null
135
+ outputs: string[] | null
136
+ middleware: MiddlewareMetadata[]
137
+ permissions: PermissionMetadata[]
138
+ isDirectFunction: boolean
139
+ sourceFile: string
140
+ exportedName: string
141
+ /** File containing the handler body when it differs from sourceFile (imported handlers) */
142
+ bodySourceFile?: string
143
+ /** 1-indexed first line of the handler body (verbose meta; coverage mapping) */
144
+ bodyStart: number
145
+ /** 1-indexed last line of the handler body (verbose meta; coverage mapping) */
146
+ bodyEnd: number
147
+ } & CommonWireMeta
148
+ >
149
+
150
+ export type FunctionsRuntimeMeta = Record<string, FunctionRuntimeMeta>
151
+ export type FunctionsMeta = Record<string, FunctionMeta>
@@ -6,10 +6,12 @@ import {
6
6
  getFunctionNames,
7
7
  runPikkuFunc,
8
8
  } from './function-runner.js'
9
- import { addGlobalPermission, addTagMiddleware } from '../index.js'
9
+ import { addGlobalPermission } from '../permissions.js'
10
+ import { addTagMiddleware } from '../middleware-runner.js'
10
11
  import { addSchema } from '../schema.js'
11
12
  import { resetPikkuState, pikkuState } from '../pikku-state.js'
12
- import type { CoreServices, CorePikkuMiddleware } from '../types/core.types.js'
13
+ import type { CoreServices } from '../types/core.types.js'
14
+ import type { CorePikkuMiddleware } from '../middleware/middleware.types.js'
13
15
  import type { CorePermissionGroup } from './functions.types.js'
14
16
  import { PikkuSessionService } from '../services/user-session-service.js'
15
17
  import { MissingScopeError, ReadonlySessionError } from '../errors/errors.js'
@@ -14,14 +14,16 @@ import {
14
14
  } from '../schema.js'
15
15
  import type {
16
16
  CoreUserSession,
17
- CorePikkuMiddleware,
18
17
  PikkuWiringTypes,
19
18
  PikkuWire,
20
19
  PikkuRawWire,
21
- MiddlewareMetadata,
22
20
  CoreSingletonServices,
23
21
  CreateWireServices,
24
22
  } from '../types/core.types.js'
23
+ import type {
24
+ CorePikkuMiddleware,
25
+ MiddlewareMetadata,
26
+ } from '../middleware/middleware.types.js'
25
27
  import type { CorePikkuChannelMiddleware } from '../wirings/channel/channel.types.js'
26
28
  import type { CorePikkuFunctionConfig } from './functions.types.js'
27
29
  import { parseVersionedId } from '../version.js'
@@ -40,13 +42,14 @@ import {
40
42
  type AuditLog,
41
43
  } from '../services/audit-service.js'
42
44
  import { rpcService } from '../wirings/rpc/rpc-runner.js'
43
- import { getOrCreatePackageSingletonServices } from '../wirings/rpc/addon-runner.js'
45
+ import { getOrCreatePackageSingletonServices } from '../wirings/addon/addon-runner.js'
44
46
  import {
45
47
  resolveAddonAuth,
48
+ resolveAddonFunctionTarget,
46
49
  resolveAddonScopes,
47
50
  resolveAddonTagMiddleware,
48
- } from '../wirings/rpc/wire-addon.js'
49
- import type { AddonInstance } from '../wirings/rpc/addon-runner.js'
51
+ } from '../wirings/addon/wire-addon.js'
52
+ import type { AddonInstance } from '../wirings/addon/addon-runner.js'
50
53
  import { closeWireServices } from '../utils.js'
51
54
 
52
55
  async function resolveSession(
@@ -168,6 +171,32 @@ export const runPikkuFunc = async <In = any, Out = any>(
168
171
  }
169
172
  }
170
173
 
174
+ /**
175
+ * The package the *function* belongs to, which is the wire's own until a
176
+ * `ref()` resolves the target into an addon. The wiring stays the consuming
177
+ * app's — that is what keeps the app's middleware running rather than the
178
+ * addon's — but everything the function is declared with lives in the addon's
179
+ * package state, so its schemas, services and permissions are read from here.
180
+ */
181
+ let funcPackageName = packageName
182
+
183
+ if (!funcMeta) {
184
+ const addonTarget = resolveAddonFunctionTarget(funcName, packageName)
185
+ if (addonTarget) {
186
+ funcConfig =
187
+ funcConfig ||
188
+ pikkuState(addonTarget.packageName, 'function', 'functions').get(
189
+ addonTarget.localName
190
+ )
191
+ funcMeta = pikkuState(addonTarget.packageName, 'function', 'meta')[
192
+ addonTarget.localName
193
+ ]
194
+ if (funcMeta) {
195
+ funcPackageName = addonTarget.packageName
196
+ }
197
+ }
198
+ }
199
+
171
200
  if (!funcConfig) {
172
201
  throw new Error(`Function not found: ${funcName}`)
173
202
  }
@@ -177,17 +206,17 @@ export const runPikkuFunc = async <In = any, Out = any>(
177
206
 
178
207
  const resolvedFunctionId = funcMeta.pikkuFuncId ?? funcName
179
208
 
180
- const resolvedSingletonServices = packageName
209
+ const resolvedSingletonServices = funcPackageName
181
210
  ? await getOrCreatePackageSingletonServices(
182
- packageName,
211
+ funcPackageName,
183
212
  singletonServices,
184
213
  addonInstance
185
214
  )
186
215
  : singletonServices
187
216
 
188
217
  let resolvedCreateWireServices = createWireServices
189
- if (packageName) {
190
- const factories = pikkuState(packageName, 'package', 'factories')
218
+ if (funcPackageName) {
219
+ const factories = pikkuState(funcPackageName, 'package', 'factories')
191
220
  if (factories?.createWireServices) {
192
221
  resolvedCreateWireServices = factories.createWireServices
193
222
  }
@@ -345,17 +374,21 @@ export const runPikkuFunc = async <In = any, Out = any>(
345
374
  actualData = applyDefaultsFromSchema(
346
375
  inputSchemaName,
347
376
  actualData,
348
- packageName
377
+ funcPackageName
349
378
  )
350
379
  if (coerceDataFromSchema) {
351
- coerceTopLevelDataFromSchema(inputSchemaName, actualData, packageName)
380
+ coerceTopLevelDataFromSchema(
381
+ inputSchemaName,
382
+ actualData,
383
+ funcPackageName
384
+ )
352
385
  }
353
386
  await validateSchema(
354
387
  resolvedSingletonServices.logger,
355
388
  resolvedSingletonServices.schema,
356
389
  inputSchemaName,
357
390
  actualData,
358
- packageName
391
+ funcPackageName
359
392
  )
360
393
  }
361
394
 
@@ -368,7 +401,7 @@ export const runPikkuFunc = async <In = any, Out = any>(
368
401
  // knowledge: decisions/security/a-permission-gets-a-wire-it-cannot-reply-on.md
369
402
  wire: invocationWire as PermissionWire,
370
403
  data: actualData,
371
- packageName,
404
+ packageName: funcPackageName,
372
405
  })
373
406
 
374
407
  let wireServices: Record<string, unknown> | undefined
@@ -395,7 +428,7 @@ export const runPikkuFunc = async <In = any, Out = any>(
395
428
  )
396
429
  services = { ...services, auditLog: invocationAuditLog }
397
430
  }
398
- const callerPackageName = packageName
431
+ const callerPackageName = funcPackageName
399
432
  Object.defineProperty(invocationWire, 'rpc', {
400
433
  get() {
401
434
  const rpc = rpcService.getContextRPCService(
@@ -2,17 +2,17 @@ import type {
2
2
  CoreServices,
3
3
  CoreSecretlessSingletonServices,
4
4
  CoreUserSession,
5
- CorePikkuMiddleware,
6
5
  PikkuWire,
7
- PickRequired,
8
6
  SecretlessServices,
9
7
  } from '../types/core.types.js'
8
+ import type { CorePikkuMiddleware } from '../middleware/middleware.types.js'
9
+ import type { PickRequired } from '../utils.js'
10
10
  import type { PikkuRPC } from '../wirings/rpc/rpc-types.js'
11
11
  import type { StandardSchemaV1 } from '@standard-schema/spec'
12
12
  import type { PikkuError } from '../errors/error-handler.js'
13
13
  import type { CoreNodeConfig } from '../wirings/node/node.types.js'
14
14
  import type { ScenarioSurface } from '../wirings/workflow/scenario-step.types.js'
15
- import type { Safe } from '../secret-value.js'
15
+ import type { Safe } from '../classification/secret-value.js'
16
16
 
17
17
  export type CorePikkuFunction<
18
18
  In,
@@ -149,8 +149,7 @@ export const pikkuAuth = <
149
149
  Session extends CoreUserSession = CoreUserSession,
150
150
  >(
151
151
  auth:
152
- | CorePikkuAuth<Services, Session>
153
- | CorePikkuAuthConfig<Services, Session>
152
+ CorePikkuAuth<Services, Session> | CorePikkuAuthConfig<Services, Session>
154
153
  ): CorePikkuPermission<any, Services, any> => {
155
154
  const fn = typeof auth === 'function' ? auth : auth.func
156
155
  const wrapper: CorePikkuPermission<any, Services, any> & AuthBranded = async (
@@ -167,8 +166,7 @@ export const pikkuAuth = <
167
166
  }
168
167
 
169
168
  export type CorePermissionGroup<PikkuPermission = CorePikkuPermission<any>> =
170
- | Record<string, PikkuPermission | PikkuPermission[]>
171
- | undefined
169
+ Record<string, PikkuPermission | PikkuPermission[]> | undefined
172
170
 
173
171
  /**
174
172
  * A lifecycle hook: same call signature as the function it hangs off, return
@@ -232,6 +230,12 @@ export type CorePikkuFunctionConfig<
232
230
  * and report how much of the flow each surface actually covers.
233
231
  */
234
232
  surfaces?: ScenarioSurface[]
233
+ /**
234
+ * Scenario steps only: this step is driven by a persona, so the runner injects
235
+ * `wire.actor` and refuses to dispatch it without one. Set by the definer from
236
+ * a `browser` binding or an explicit `actor: true`, never written by hand.
237
+ */
238
+ requiresActor?: boolean
235
239
  audit?:
236
240
  | boolean
237
241
  | {
@@ -1,4 +1,8 @@
1
- export { addFunction, getAllFunctionNames } from './function-runner.js'
1
+ export {
2
+ addFunction,
3
+ getAllFunctionNames,
4
+ runPikkuFunc,
5
+ } from './function-runner.js'
2
6
  export {
3
7
  pikkuAuth,
4
8
  pikkuPermission,
@@ -14,8 +18,23 @@ export type {
14
18
  CorePikkuAuthConfig,
15
19
  CorePikkuPermission,
16
20
  } from './functions.types.js'
21
+ export type { ListInput, ListOutput, Filter } from './list.types.js'
22
+ export { AbandonedError } from './abort-scope.js'
23
+ export type { AbortScope } from './abort-scope.js'
24
+ export { checkAuthPermissions } from '../permissions.js'
25
+ export type {
26
+ CorePermissionGroup,
27
+ CorePikkuApprovalDescription,
28
+ CorePikkuPermissionConfig,
29
+ CorePikkuPermissionFactory,
30
+ } from './functions.types.js'
17
31
  export type {
18
- ListInput,
19
- ListOutput,
20
- Filter,
21
- } from './list.types.js'
32
+ FunctionMeta,
33
+ FunctionRuntimeMeta,
34
+ FunctionServicesMeta,
35
+ FunctionWiresMeta,
36
+ FunctionsMeta,
37
+ FunctionsRuntimeMeta,
38
+ PermissionMetadata,
39
+ } from './function-meta.types.js'
40
+ export { PikkuRequest } from './pikku-request.js'
@@ -66,6 +66,4 @@ export type LeafFilter<F extends Record<string, unknown>> = {
66
66
  * evaluation time; a single-key object is a leaf predicate.
67
67
  */
68
68
  export type Filter<F extends Record<string, unknown>> =
69
- | LeafFilter<F>
70
- | Filter<F>[]
71
- | { [label: string]: Filter<F> }
69
+ LeafFilter<F> | Filter<F>[] | { [label: string]: Filter<F> }
@@ -1,5 +1,7 @@
1
- import { pikkuMiddleware, pikkuMiddlewareFactory } from '../types/core.types.js'
2
-
1
+ import {
2
+ pikkuMiddleware,
3
+ pikkuMiddlewareFactory,
4
+ } from './middleware-factories.js'
3
5
  export const authAPIKey = pikkuMiddlewareFactory<{
4
6
  source: 'header' | 'query' | 'all'
5
7
  }>(({ source }) =>
@@ -8,7 +8,7 @@ import {
8
8
  createMiddlewareSessionWireProps,
9
9
  } from '../services/user-session-service.js'
10
10
  import { InvalidSessionError } from '../errors/errors.js'
11
- import { createSecretValue } from '../secret-value.js'
11
+ import { createSecretValue } from '../classification/secret-value.js'
12
12
 
13
13
  beforeEach(() => {
14
14
  resetPikkuState()
@@ -1,7 +1,9 @@
1
1
  import { InvalidSessionError } from '../errors/errors.js'
2
2
  import type { CoreUserSession } from '../types/core.types.js'
3
- import { pikkuMiddleware, pikkuMiddlewareFactory } from '../types/core.types.js'
4
-
3
+ import {
4
+ pikkuMiddleware,
5
+ pikkuMiddlewareFactory,
6
+ } from './middleware-factories.js'
5
7
  const constantTimeEqual = (a: string, b: string): boolean => {
6
8
  if (a.length !== b.length) return false
7
9
  let result = 0
@@ -1,5 +1,8 @@
1
1
  import type { SerializeOptions } from 'cookie'
2
- import { pikkuMiddleware, pikkuMiddlewareFactory } from '../types/core.types.js'
2
+ import {
3
+ pikkuMiddleware,
4
+ pikkuMiddlewareFactory,
5
+ } from './middleware-factories.js'
3
6
  import type { RelativeTimeInput } from '../time-utils.js'
4
7
  import { getRelativeTimeOffsetFromNow } from '../time-utils.js'
5
8
 
@@ -15,6 +15,21 @@ const createMockRequest = (method = 'get', origin?: string) => ({
15
15
  },
16
16
  })
17
17
 
18
+ const createMockServices = () => {
19
+ const debugMessages: string[] = []
20
+ return {
21
+ logger: {
22
+ debug: (message: string) => {
23
+ debugMessages.push(message)
24
+ },
25
+ info: () => {},
26
+ warn: () => {},
27
+ error: () => {},
28
+ },
29
+ _debugMessages: debugMessages,
30
+ }
31
+ }
32
+
18
33
  const createMockResponse = () => {
19
34
  const headers: Record<string, string> = {}
20
35
  let statusCode: number | undefined
@@ -125,30 +140,113 @@ describe('cors', () => {
125
140
  )
126
141
  })
127
142
 
128
- test('should use first origin when request origin not in array', async () => {
143
+ test('should omit Access-Control-Allow-Origin when request origin not in array', async () => {
129
144
  const middleware = cors({ origin: ['https://a.com', 'https://b.com'] })
130
145
  const request = createMockRequest('get', 'https://unknown.com')
131
146
  const response = createMockResponse()
147
+ const services = createMockServices()
132
148
 
133
149
  await middleware(
134
- {} as any,
150
+ services as any,
135
151
  { http: { request, response } } as any,
136
152
  async () => {}
137
153
  )
138
154
 
139
155
  assert.strictEqual(
140
156
  response._headers['Access-Control-Allow-Origin'],
141
- 'https://a.com'
157
+ undefined
142
158
  )
143
159
  })
144
160
 
145
- test('should use first origin when no request origin header', async () => {
161
+ test('should log the rejected origin at debug level', async () => {
162
+ const middleware = cors({ origin: ['https://a.com', 'https://b.com'] })
163
+ const request = createMockRequest('get', 'https://unknown.com')
164
+ const response = createMockResponse()
165
+ const services = createMockServices()
166
+
167
+ await middleware(
168
+ services as any,
169
+ { http: { request, response } } as any,
170
+ async () => {}
171
+ )
172
+
173
+ assert.strictEqual(services._debugMessages.length, 1)
174
+ assert.match(services._debugMessages[0]!, /https:\/\/unknown\.com/)
175
+ })
176
+
177
+ test('should omit Access-Control-Allow-Origin when no request origin header', async () => {
146
178
  const middleware = cors({ origin: ['https://a.com', 'https://b.com'] })
147
179
  const request = createMockRequest('get')
148
180
  const response = createMockResponse()
181
+ const services = createMockServices()
149
182
 
150
183
  await middleware(
151
- {} as any,
184
+ services as any,
185
+ { http: { request, response } } as any,
186
+ async () => {}
187
+ )
188
+
189
+ assert.strictEqual(
190
+ response._headers['Access-Control-Allow-Origin'],
191
+ undefined
192
+ )
193
+ assert.strictEqual(services._debugMessages.length, 0)
194
+ })
195
+
196
+ test('should still call next for a disallowed origin', async () => {
197
+ const middleware = cors({ origin: ['https://a.com'] })
198
+ const request = createMockRequest('get', 'https://unknown.com')
199
+ const response = createMockResponse()
200
+ const services = createMockServices()
201
+ let nextCalled = false
202
+
203
+ await middleware(
204
+ services as any,
205
+ { http: { request, response } } as any,
206
+ async () => {
207
+ nextCalled = true
208
+ }
209
+ )
210
+
211
+ assert.strictEqual(nextCalled, true)
212
+ })
213
+
214
+ test('should omit Access-Control-Allow-Credentials for a disallowed origin', async () => {
215
+ const middleware = cors({
216
+ origin: ['https://a.com'],
217
+ credentials: true,
218
+ })
219
+ const request = createMockRequest('get', 'https://unknown.com')
220
+ const response = createMockResponse()
221
+ const services = createMockServices()
222
+
223
+ await middleware(
224
+ services as any,
225
+ { http: { request, response } } as any,
226
+ async () => {}
227
+ )
228
+
229
+ assert.strictEqual(
230
+ response._headers['Access-Control-Allow-Origin'],
231
+ undefined
232
+ )
233
+ assert.strictEqual(
234
+ response._headers['Access-Control-Allow-Credentials'],
235
+ undefined
236
+ )
237
+ })
238
+
239
+ test('should set credentials header for an allowed array origin', async () => {
240
+ const middleware = cors({
241
+ origin: ['https://a.com'],
242
+ credentials: true,
243
+ })
244
+ const request = createMockRequest('get', 'https://a.com')
245
+ const response = createMockResponse()
246
+ const services = createMockServices()
247
+
248
+ await middleware(
249
+ services as any,
152
250
  { http: { request, response } } as any,
153
251
  async () => {}
154
252
  )
@@ -157,6 +255,29 @@ describe('cors', () => {
157
255
  response._headers['Access-Control-Allow-Origin'],
158
256
  'https://a.com'
159
257
  )
258
+ assert.strictEqual(
259
+ response._headers['Access-Control-Allow-Credentials'],
260
+ 'true'
261
+ )
262
+ })
263
+
264
+ test('should omit Access-Control-Allow-Origin on a disallowed preflight but still return 204', async () => {
265
+ const middleware = cors({ origin: ['https://a.com'] })
266
+ const request = createMockRequest('options', 'https://unknown.com')
267
+ const response = createMockResponse()
268
+ const services = createMockServices()
269
+
270
+ await middleware(
271
+ services as any,
272
+ { http: { request, response } } as any,
273
+ async () => {}
274
+ )
275
+
276
+ assert.strictEqual(
277
+ response._headers['Access-Control-Allow-Origin'],
278
+ undefined
279
+ )
280
+ assert.strictEqual(response._getStatus(), 204)
160
281
  })
161
282
 
162
283
  test('should set Vary: Origin header when origin is array', async () => {
@@ -1,9 +1,13 @@
1
- import { pikkuMiddleware, pikkuMiddlewareFactory } from '../types/core.types.js'
2
-
1
+ import {
2
+ pikkuMiddleware,
3
+ pikkuMiddlewareFactory,
4
+ } from './middleware-factories.js'
3
5
  /**
4
6
  * Sets CORS headers on every response and short-circuits OPTIONS preflight
5
7
  * with a 204. `origin: true` reflects the request origin; an array reflects a
6
- * matching origin and otherwise falls back to its first entry.
8
+ * matching origin and otherwise sends no `Access-Control-Allow-Origin` at all,
9
+ * so the browser reports "origin not allowed" rather than an origin mismatch
10
+ * against whichever entry happened to be first.
7
11
  */
8
12
  export const cors = pikkuMiddlewareFactory<{
9
13
  origin?: string | string[] | true
@@ -29,7 +33,7 @@ export const cors = pikkuMiddlewareFactory<{
29
33
  return pikkuMiddleware({
30
34
  name: 'CORS',
31
35
  description: 'Handles cross-origin requests including OPTIONS preflight',
32
- func: async (_services, wires, next) => {
36
+ func: async (services, wires, next) => {
33
37
  const request = wires.http?.request
34
38
  const response = wires.http?.response
35
39
 
@@ -39,19 +43,26 @@ export const cors = pikkuMiddlewareFactory<{
39
43
 
40
44
  const requestOrigin = request.header('origin')
41
45
 
42
- let allowedOrigin: string
46
+ let allowedOrigin: string | undefined
43
47
  if (origin === true) {
44
48
  allowedOrigin = requestOrigin || '*'
45
49
  } else if (Array.isArray(origin)) {
46
50
  allowedOrigin =
47
51
  requestOrigin && origin.includes(requestOrigin)
48
52
  ? requestOrigin
49
- : origin[0]
53
+ : undefined
54
+ if (requestOrigin && !allowedOrigin) {
55
+ services.logger.debug(
56
+ `CORS: origin '${requestOrigin}' is not in the allowed list, omitting Access-Control-Allow-Origin`
57
+ )
58
+ }
50
59
  } else {
51
60
  allowedOrigin = origin
52
61
  }
53
62
 
54
- response.header('Access-Control-Allow-Origin', allowedOrigin)
63
+ if (allowedOrigin) {
64
+ response.header('Access-Control-Allow-Origin', allowedOrigin)
65
+ }
55
66
  response.header('Access-Control-Allow-Methods', methods.join(', '))
56
67
  response.header('Access-Control-Allow-Headers', headers.join(', '))
57
68
 
@@ -62,7 +73,7 @@ export const cors = pikkuMiddlewareFactory<{
62
73
  )
63
74
  }
64
75
 
65
- if (credentials) {
76
+ if (credentials && allowedOrigin) {
66
77
  response.header('Access-Control-Allow-Credentials', 'true')
67
78
  }
68
79