@pikku/core 0.12.79 → 0.12.82

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 (479) hide show
  1. package/CHANGELOG.md +473 -0
  2. package/dist/dev/hot-reload.js +1 -6
  3. package/dist/ecosystem.d.ts +27 -0
  4. package/dist/ecosystem.js +26 -0
  5. package/dist/errors/error-handler.js +4 -2
  6. package/dist/errors/index.d.ts +1 -1
  7. package/dist/errors/index.js +1 -1
  8. package/dist/function/function-runner.js +22 -47
  9. package/dist/function/functions.types.d.ts +9 -5
  10. package/dist/function/index.d.ts +1 -1
  11. package/dist/index.d.ts +14 -19
  12. package/dist/index.js +6 -11
  13. package/dist/middleware/auth-cookie.d.ts +0 -4
  14. package/dist/middleware/auth-cookie.js +38 -2
  15. package/dist/middleware/cors.js +1 -0
  16. package/dist/middleware/index.d.ts +1 -1
  17. package/dist/middleware/index.js +1 -1
  18. package/dist/middleware/remote-auth.js +14 -3
  19. package/dist/permissions.d.ts +8 -10
  20. package/dist/permissions.js +0 -11
  21. package/dist/pikku-state.js +16 -5
  22. package/dist/schema.js +35 -1
  23. package/dist/services/ai-agent-runner-service.d.ts +7 -0
  24. package/dist/services/ai-run-state-service.d.ts +17 -1
  25. package/dist/services/in-memory-ai-run-state-service.d.ts +6 -2
  26. package/dist/services/in-memory-ai-run-state-service.js +11 -1
  27. package/dist/services/in-memory-workflow-service.js +2 -0
  28. package/dist/services/index.d.ts +15 -15
  29. package/dist/services/index.js +5 -5
  30. package/dist/services/local-content-request-handler.d.ts +21 -0
  31. package/dist/services/local-content-request-handler.js +72 -53
  32. package/dist/services/local-content.d.ts +6 -0
  33. package/dist/services/local-content.js +14 -1
  34. package/dist/services/scoped-credential-service.d.ts +21 -0
  35. package/dist/services/scoped-credential-service.js +53 -0
  36. package/dist/services/workflow-service.d.ts +4 -2
  37. package/dist/testing/service-tests/agent-run-service-tests.d.ts +10 -0
  38. package/dist/testing/service-tests/agent-run-service-tests.js +72 -0
  39. package/dist/testing/service-tests/ai-storage-service-tests.d.ts +3 -0
  40. package/dist/testing/service-tests/ai-storage-service-tests.js +302 -0
  41. package/dist/testing/service-tests/channel-store-tests.d.ts +3 -0
  42. package/dist/testing/service-tests/channel-store-tests.js +72 -0
  43. package/dist/testing/service-tests/credential-service-tests.d.ts +3 -0
  44. package/dist/testing/service-tests/credential-service-tests.js +109 -0
  45. package/dist/testing/service-tests/deployment-service-tests.d.ts +3 -0
  46. package/dist/testing/service-tests/deployment-service-tests.js +21 -0
  47. package/dist/testing/service-tests/event-hub-store-tests.d.ts +3 -0
  48. package/dist/testing/service-tests/event-hub-store-tests.js +34 -0
  49. package/dist/testing/service-tests/secret-service-tests.d.ts +3 -0
  50. package/dist/testing/service-tests/secret-service-tests.js +80 -0
  51. package/dist/testing/service-tests/session-store-tests.d.ts +3 -0
  52. package/dist/testing/service-tests/session-store-tests.js +43 -0
  53. package/dist/testing/service-tests/workflow-run-service-tests.d.ts +3 -0
  54. package/dist/testing/service-tests/workflow-run-service-tests.js +42 -0
  55. package/dist/testing/service-tests/workflow-service-tests.d.ts +3 -0
  56. package/dist/testing/service-tests/workflow-service-tests.js +150 -0
  57. package/dist/testing/service-tests.d.ts +6 -0
  58. package/dist/testing/service-tests.js +26 -791
  59. package/dist/types/core.types.d.ts +11 -3
  60. package/dist/types/state.types.d.ts +14 -1
  61. package/dist/wirings/actor-flow/index.d.ts +1 -1
  62. package/dist/wirings/actor-flow/run-conversation.js +1 -6
  63. package/dist/wirings/ai-agent/agent-rpc.d.ts +15 -0
  64. package/dist/wirings/ai-agent/agent-rpc.js +53 -0
  65. package/dist/wirings/ai-agent/ai-agent-agui.js +1 -5
  66. package/dist/wirings/ai-agent/ai-agent-finalize.d.ts +58 -0
  67. package/dist/wirings/ai-agent/ai-agent-finalize.js +138 -0
  68. package/dist/wirings/ai-agent/ai-agent-interrupt.js +1 -0
  69. package/dist/wirings/ai-agent/ai-agent-memory.d.ts +2 -8
  70. package/dist/wirings/ai-agent/ai-agent-memory.js +37 -18
  71. package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +7 -0
  72. package/dist/wirings/ai-agent/ai-agent-model-config.js +44 -1
  73. package/dist/wirings/ai-agent/ai-agent-prepare.js +5 -9
  74. package/dist/wirings/ai-agent/ai-agent-runner.js +89 -147
  75. package/dist/wirings/ai-agent/ai-agent-stream.js +109 -97
  76. package/dist/wirings/ai-agent/ai-agent-turn.d.ts +57 -0
  77. package/dist/wirings/ai-agent/ai-agent-turn.js +82 -0
  78. package/dist/wirings/ai-agent/ai-agent.types.d.ts +47 -2
  79. package/dist/wirings/ai-agent/index.d.ts +8 -7
  80. package/dist/wirings/ai-agent/index.js +5 -4
  81. package/dist/wirings/ai-agent/voice-input.js +1 -6
  82. package/dist/wirings/ai-agent/voice-output.js +2 -12
  83. package/dist/wirings/ai-scorer/ai-scorer-grade.d.ts +26 -0
  84. package/dist/wirings/ai-scorer/ai-scorer-grade.js +33 -0
  85. package/dist/wirings/ai-scorer/ai-scorer-judge.d.ts +17 -0
  86. package/dist/wirings/ai-scorer/ai-scorer-judge.js +92 -0
  87. package/dist/wirings/ai-scorer/ai-scorer-live.d.ts +15 -0
  88. package/dist/wirings/ai-scorer/ai-scorer-live.js +38 -0
  89. package/dist/wirings/ai-scorer/ai-scorer-registry.d.ts +18 -0
  90. package/dist/wirings/ai-scorer/ai-scorer-registry.js +46 -0
  91. package/dist/wirings/ai-scorer/ai-scorer-sampling.d.ts +8 -0
  92. package/dist/wirings/ai-scorer/ai-scorer-sampling.js +31 -0
  93. package/dist/wirings/ai-scorer/ai-scorer-snapshots.d.ts +10 -0
  94. package/dist/wirings/ai-scorer/ai-scorer-snapshots.js +40 -0
  95. package/dist/wirings/ai-scorer/ai-scorer-worker.d.ts +15 -0
  96. package/dist/wirings/ai-scorer/ai-scorer-worker.js +58 -0
  97. package/dist/wirings/ai-scorer/ai-scorer.d.ts +39 -0
  98. package/dist/wirings/ai-scorer/ai-scorer.js +40 -0
  99. package/dist/wirings/ai-scorer/ai-scorer.types.d.ts +90 -0
  100. package/dist/wirings/ai-scorer/ai-scorer.types.js +4 -0
  101. package/dist/wirings/ai-scorer/index.d.ts +6 -0
  102. package/dist/wirings/ai-scorer/index.js +5 -0
  103. package/dist/wirings/channel/channel-common.js +1 -0
  104. package/dist/wirings/channel/channel-handler.js +3 -5
  105. package/dist/wirings/channel/channel-rpc-service.d.ts +0 -6
  106. package/dist/wirings/channel/channel-rpc-service.js +0 -8
  107. package/dist/wirings/channel/channel-rpc.types.d.ts +6 -0
  108. package/dist/wirings/channel/channel-rpc.types.js +8 -0
  109. package/dist/wirings/channel/channel-runner.d.ts +1 -3
  110. package/dist/wirings/channel/channel-runner.js +16 -8
  111. package/dist/wirings/channel/channel.types.d.ts +2 -0
  112. package/dist/wirings/channel/index.d.ts +5 -6
  113. package/dist/wirings/channel/index.js +3 -4
  114. package/dist/wirings/channel/local/local-channel-runner.js +8 -1
  115. package/dist/wirings/channel/pikku-abstract-channel-handler.js +1 -0
  116. package/dist/wirings/channel/serverless/serverless-channel-runner.js +3 -0
  117. package/dist/wirings/cli/channel/cli-channel-runner.js +2 -0
  118. package/dist/wirings/cli/channel/cli-raw-channel-runner.js +9 -1
  119. package/dist/wirings/cli/channel/index.d.ts +1 -2
  120. package/dist/wirings/cli/channel/index.js +0 -1
  121. package/dist/wirings/cli/cli-runner.js +17 -3
  122. package/dist/wirings/cli/cli.types.d.ts +0 -8
  123. package/dist/wirings/cli/command-parser.js +13 -0
  124. package/dist/wirings/credential/index.d.ts +1 -1
  125. package/dist/wirings/gateway/gateway-runner.js +9 -2
  126. package/dist/wirings/gateway/index.d.ts +1 -1
  127. package/dist/wirings/http/http-routes.js +2 -0
  128. package/dist/wirings/http/http-runner.d.ts +0 -10
  129. package/dist/wirings/http/http-runner.js +14 -15
  130. package/dist/wirings/http/http.types.d.ts +0 -10
  131. package/dist/wirings/http/index.d.ts +2 -3
  132. package/dist/wirings/http/index.js +1 -1
  133. package/dist/wirings/mcp/index.d.ts +1 -1
  134. package/dist/wirings/mcp/mcp-runner.d.ts +15 -7
  135. package/dist/wirings/mcp/mcp-runner.js +18 -11
  136. package/dist/wirings/persona/index.d.ts +3 -4
  137. package/dist/wirings/persona/index.js +2 -3
  138. package/dist/wirings/queue/index.d.ts +1 -3
  139. package/dist/wirings/queue/index.js +1 -3
  140. package/dist/wirings/rpc/addon-runner.d.ts +4 -0
  141. package/dist/wirings/rpc/addon-runner.js +19 -3
  142. package/dist/wirings/rpc/rpc-runner.d.ts +8 -51
  143. package/dist/wirings/rpc/rpc-runner.js +55 -86
  144. package/dist/wirings/rpc/rpc-types.d.ts +7 -0
  145. package/dist/wirings/rpc/wire-addon.d.ts +13 -0
  146. package/dist/wirings/rpc/wire-addon.js +4 -0
  147. package/dist/wirings/scheduler/index.d.ts +1 -1
  148. package/dist/wirings/secret/validate-secret-definitions.js +2 -2
  149. package/dist/wirings/trigger/index.d.ts +1 -1
  150. package/dist/wirings/trigger/pikku-trigger-service.d.ts +0 -4
  151. package/dist/wirings/trigger/trigger-runner.js +1 -0
  152. package/dist/wirings/virtual-user/index.d.ts +5 -6
  153. package/dist/wirings/virtual-user/index.js +2 -4
  154. package/dist/wirings/virtual-user/run-virtual-user.js +11 -11
  155. package/dist/wirings/virtual-user/virtual-user-derive.js +4 -25
  156. package/dist/wirings/virtual-user/virtual-user-dispositions.js +1 -4
  157. package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +100 -3
  158. package/dist/wirings/workflow/feature.js +7 -4
  159. package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -2
  160. package/dist/wirings/workflow/graph/graph-runner.js +8 -7
  161. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -4
  162. package/dist/wirings/workflow/index.d.ts +12 -7
  163. package/dist/wirings/workflow/index.js +7 -3
  164. package/dist/wirings/workflow/pikku-scenario-service.d.ts +17 -3
  165. package/dist/wirings/workflow/pikku-scenario-service.js +64 -10
  166. package/dist/wirings/workflow/pikku-workflow-service.d.ts +28 -147
  167. package/dist/wirings/workflow/pikku-workflow-service.js +85 -493
  168. package/dist/wirings/workflow/scenario-step.types.d.ts +8 -0
  169. package/dist/wirings/workflow/workflow-approval-audit.d.ts +16 -0
  170. package/dist/wirings/workflow/workflow-approval-audit.js +40 -0
  171. package/dist/wirings/workflow/workflow-approval-policy.d.ts +20 -0
  172. package/dist/wirings/workflow/workflow-approval-policy.js +48 -0
  173. package/dist/wirings/workflow/workflow-approval.d.ts +67 -0
  174. package/dist/wirings/workflow/workflow-approval.js +177 -0
  175. package/dist/wirings/workflow/workflow-constants.d.ts +26 -0
  176. package/dist/wirings/workflow/workflow-constants.js +35 -0
  177. package/dist/wirings/workflow/workflow-errors.d.ts +58 -0
  178. package/dist/wirings/workflow/workflow-errors.js +112 -0
  179. package/dist/wirings/workflow/workflow-meta-resolver.d.ts +11 -0
  180. package/dist/wirings/workflow/workflow-meta-resolver.js +31 -0
  181. package/dist/wirings/workflow/workflow-queue-routing.d.ts +8 -0
  182. package/dist/wirings/workflow/workflow-queue-routing.js +38 -0
  183. package/dist/wirings/workflow/workflow-queue-wiring.d.ts +20 -0
  184. package/dist/wirings/workflow/workflow-queue-wiring.js +79 -0
  185. package/dist/wirings/workflow/workflow-recovery.d.ts +68 -0
  186. package/dist/wirings/workflow/workflow-recovery.js +101 -0
  187. package/dist/wirings/workflow/workflow-run-engine.types.d.ts +54 -0
  188. package/dist/wirings/workflow/workflow-run-ownership.d.ts +17 -0
  189. package/dist/wirings/workflow/workflow-run-ownership.js +30 -0
  190. package/dist/wirings/workflow/workflow-suspend.d.ts +12 -0
  191. package/dist/wirings/workflow/workflow-suspend.js +33 -0
  192. package/dist/wirings/workflow/workflow.types.d.ts +8 -1
  193. package/knowledge/decisions/internals/a-non-streaming-agent-run-registers-with-airunstate-too.md +22 -0
  194. package/knowledge/decisions/internals/a-resumed-agent-turn-is-as-interruptible-as-the-first.md +20 -0
  195. package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +21 -0
  196. package/knowledge/decisions/internals/a-virtual-user-decides-whether-to-trust-memory-once-per-turn.md +21 -0
  197. package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +46 -0
  198. package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +45 -0
  199. package/knowledge/decisions/internals/addon-pikku-meta-ships-at-the-package-root-or-under-dist.md +32 -0
  200. package/knowledge/decisions/internals/agent-context-waits-for-a-tool-result-still-being-written.md +21 -0
  201. package/knowledge/decisions/internals/agent-speech-travels-as-a-custom-agui-event.md +22 -0
  202. package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +39 -0
  203. package/knowledge/decisions/internals/an-agent-interrupt-is-not-a-failure.md +23 -0
  204. package/knowledge/decisions/internals/an-agent-run-owned-by-another-instance-says-so.md +25 -0
  205. package/knowledge/decisions/internals/an-agent-stream-send-must-return-the-inner-sends-promise.md +22 -0
  206. package/knowledge/decisions/internals/an-empty-text-part-is-omitted-from-an-agent-message.md +20 -0
  207. package/knowledge/decisions/internals/an-empty-transcript-is-not-recorded.md +22 -0
  208. package/knowledge/decisions/internals/an-unref-d-timer-cannot-be-awaited-under-node-test.md +66 -0
  209. package/knowledge/decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md +33 -0
  210. package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +43 -0
  211. package/knowledge/decisions/internals/hot-reload-writes-into-the-function-map-captured-at-startup.md +26 -0
  212. package/knowledge/decisions/internals/index.md +42 -3
  213. package/knowledge/decisions/internals/only-exposed-functions-enter-a-virtual-user-catalogue.md +21 -0
  214. package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +24 -0
  215. package/knowledge/decisions/internals/side-effects-are-an-allowlist-not-a-boolean.md +34 -0
  216. package/knowledge/decisions/internals/speech-synthesis-picks-a-voice-per-sentence-and-warns-once.md +24 -0
  217. package/knowledge/decisions/internals/the-actor-prompt-says-json-because-of-json-object-mode.md +22 -0
  218. package/knowledge/decisions/internals/the-agent-done-event-goes-through-the-middleware-and-is-awaited.md +26 -0
  219. package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +43 -0
  220. package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +58 -0
  221. package/knowledge/decisions/internals/the-middleware-resolution-cache-is-deliberately-unbounded.md +40 -0
  222. package/knowledge/decisions/internals/the-per-invocation-rpc-view-is-a-class.md +40 -0
  223. package/knowledge/decisions/internals/the-persona-runtime-is-exported-from-the-persona-entry-point.md +28 -0
  224. package/knowledge/decisions/internals/the-transcript-event-is-sent-ahead-of-the-run.md +25 -0
  225. package/knowledge/decisions/internals/the-virtual-user-catalogue-is-the-only-gate-on-what-may-be-called.md +21 -0
  226. package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +22 -0
  227. package/knowledge/decisions/internals/thread-history-records-the-transcript-not-the-audio.md +25 -0
  228. package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +115 -0
  229. package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +21 -0
  230. package/knowledge/decisions/internals/voice-output-speaks-unless-voice-input-explicitly-says-otherwise.md +24 -0
  231. package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +35 -0
  232. package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +4 -2
  233. package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +37 -0
  234. package/knowledge/decisions/security/a-graph-run-starts-at-an-entry-node-the-graph-declared.md +33 -0
  235. package/knowledge/decisions/security/a-permission-gets-a-wire-it-cannot-reply-on.md +33 -0
  236. package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +37 -0
  237. package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +28 -0
  238. package/knowledge/decisions/security/a-workflow-run-is-read-and-approved-by-its-owner.md +50 -0
  239. package/knowledge/decisions/security/an-agent-approval-is-claimed-before-the-tool-runs.md +33 -0
  240. package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +59 -0
  241. package/knowledge/decisions/security/an-upload-is-counted-as-it-arrives-not-buffered-then-measured.md +24 -0
  242. package/knowledge/decisions/security/index.md +9 -0
  243. package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +35 -0
  244. package/knowledge/questions/index.md +2 -1
  245. package/knowledge/questions/unauthorized-channel-replies-escape-the-declared-out-type.md +44 -0
  246. package/package.json +15 -3
  247. package/scripts/generate-api-report.d.mts +1 -0
  248. package/scripts/generate-api-report.mjs +89 -0
  249. package/scripts/generate-api-report.mts +343 -0
  250. package/src/api-report.test.ts +69 -0
  251. package/src/column-form.ts +1 -4
  252. package/src/crypto-utils.test.ts +15 -2
  253. package/src/dev/hot-reload.ts +2 -7
  254. package/src/ecosystem.ts +40 -0
  255. package/src/errors/error-handler.ts +5 -3
  256. package/src/errors/error.test.ts +4 -1
  257. package/src/errors/index.ts +1 -1
  258. package/src/function/function-runner.test.ts +53 -1
  259. package/src/function/function-runner.ts +33 -48
  260. package/src/function/functions.types.ts +15 -9
  261. package/src/function/index.ts +0 -2
  262. package/src/handle-error.ts +1 -1
  263. package/src/index.ts +3 -57
  264. package/src/middleware/auth-cookie.test.ts +50 -0
  265. package/src/middleware/auth-cookie.ts +38 -2
  266. package/src/middleware/cors.ts +2 -1
  267. package/src/middleware/index.ts +1 -1
  268. package/src/middleware/remote-auth.test.ts +43 -0
  269. package/src/middleware/remote-auth.ts +17 -3
  270. package/src/middleware-runner.ts +4 -2
  271. package/src/no-any-casts.test.ts +57 -0
  272. package/src/permissions.test.ts +3 -1
  273. package/src/permissions.ts +22 -24
  274. package/src/pikku-state.ts +22 -6
  275. package/src/public-surface.json +554 -0
  276. package/src/public-surface.json.README +25 -0
  277. package/src/public-surface.test.ts +105 -0
  278. package/src/removed-legacy-exports.test.ts +62 -0
  279. package/src/schema.test.ts +78 -0
  280. package/src/schema.ts +36 -1
  281. package/src/services/ai-agent-runner-service.ts +12 -1
  282. package/src/services/ai-run-state-service.ts +18 -1
  283. package/src/services/audit-service.ts +2 -2
  284. package/src/services/in-memory-ai-run-state-service.ts +16 -2
  285. package/src/services/in-memory-workflow-service.ts +2 -0
  286. package/src/services/index.ts +4 -47
  287. package/src/services/local-content-request-handler.test.ts +43 -5
  288. package/src/services/local-content-request-handler.ts +103 -74
  289. package/src/services/local-content.ts +15 -1
  290. package/src/services/local-email-service.ts +5 -1
  291. package/src/services/scoped-credential-service.test.ts +86 -0
  292. package/src/services/scoped-credential-service.ts +63 -0
  293. package/src/services/system-role-guard.test.ts +4 -1
  294. package/src/services/workflow-service.ts +9 -2
  295. package/src/side-effects-are-declared.test.ts +84 -0
  296. package/src/source-files-stay-composable.test.ts +41 -0
  297. package/src/testing/service-tests/agent-run-service-tests.ts +98 -0
  298. package/src/testing/service-tests/ai-storage-service-tests.ts +379 -0
  299. package/src/testing/service-tests/channel-store-tests.ts +98 -0
  300. package/src/testing/service-tests/credential-service-tests.ts +143 -0
  301. package/src/testing/service-tests/deployment-service-tests.ts +33 -0
  302. package/src/testing/service-tests/event-hub-store-tests.ts +48 -0
  303. package/src/testing/service-tests/secret-service-tests.ts +105 -0
  304. package/src/testing/service-tests/session-store-tests.ts +62 -0
  305. package/src/testing/service-tests/workflow-run-service-tests.ts +59 -0
  306. package/src/testing/service-tests/workflow-service-tests.ts +308 -0
  307. package/src/testing/service-tests.ts +31 -1111
  308. package/src/types/core.types.ts +14 -3
  309. package/src/types/state.types.ts +17 -1
  310. package/src/wirings/actor-flow/index.ts +0 -3
  311. package/src/wirings/actor-flow/run-conversation.ts +1 -6
  312. package/src/wirings/ai-agent/agent-rpc.ts +120 -0
  313. package/src/wirings/ai-agent/ai-agent-agui.ts +1 -5
  314. package/src/wirings/ai-agent/ai-agent-finalize.test.ts +186 -0
  315. package/src/wirings/ai-agent/ai-agent-finalize.ts +197 -0
  316. package/src/wirings/ai-agent/ai-agent-interrupt.test.ts +2 -1
  317. package/src/wirings/ai-agent/ai-agent-interrupt.ts +1 -0
  318. package/src/wirings/ai-agent/ai-agent-memory.ts +62 -39
  319. package/src/wirings/ai-agent/ai-agent-model-config.test.ts +72 -3
  320. package/src/wirings/ai-agent/ai-agent-model-config.ts +49 -1
  321. package/src/wirings/ai-agent/ai-agent-prepare.ts +12 -12
  322. package/src/wirings/ai-agent/ai-agent-resume-authorization.test.ts +1 -0
  323. package/src/wirings/ai-agent/ai-agent-runner.test.ts +82 -2
  324. package/src/wirings/ai-agent/ai-agent-runner.ts +120 -160
  325. package/src/wirings/ai-agent/ai-agent-stream-output-hooks.test.ts +353 -0
  326. package/src/wirings/ai-agent/ai-agent-stream.test.ts +2 -0
  327. package/src/wirings/ai-agent/ai-agent-stream.ts +152 -117
  328. package/src/wirings/ai-agent/ai-agent-thread-ownership.test.ts +1 -1
  329. package/src/wirings/ai-agent/ai-agent-turn.test.ts +67 -0
  330. package/src/wirings/ai-agent/ai-agent-turn.ts +122 -0
  331. package/src/wirings/ai-agent/ai-agent.types.ts +65 -5
  332. package/src/wirings/ai-agent/index.ts +2 -16
  333. package/src/wirings/ai-agent/voice-input.ts +1 -6
  334. package/src/wirings/ai-agent/voice-output.ts +2 -12
  335. package/src/wirings/ai-scorer/ai-scorer-grade.test.ts +106 -0
  336. package/src/wirings/ai-scorer/ai-scorer-grade.ts +55 -0
  337. package/src/wirings/ai-scorer/ai-scorer-judge.test.ts +143 -0
  338. package/src/wirings/ai-scorer/ai-scorer-judge.ts +120 -0
  339. package/src/wirings/ai-scorer/ai-scorer-live.test.ts +174 -0
  340. package/src/wirings/ai-scorer/ai-scorer-live.ts +56 -0
  341. package/src/wirings/ai-scorer/ai-scorer-registry.ts +63 -0
  342. package/src/wirings/ai-scorer/ai-scorer-sampling.test.ts +34 -0
  343. package/src/wirings/ai-scorer/ai-scorer-sampling.ts +36 -0
  344. package/src/wirings/ai-scorer/ai-scorer-snapshots.test.ts +49 -0
  345. package/src/wirings/ai-scorer/ai-scorer-snapshots.ts +46 -0
  346. package/src/wirings/ai-scorer/ai-scorer-worker.test.ts +122 -0
  347. package/src/wirings/ai-scorer/ai-scorer-worker.ts +69 -0
  348. package/src/wirings/ai-scorer/ai-scorer.ts +76 -0
  349. package/src/wirings/ai-scorer/ai-scorer.types.ts +107 -0
  350. package/src/wirings/ai-scorer/index.ts +24 -0
  351. package/src/wirings/channel/channel-common.ts +5 -2
  352. package/src/wirings/channel/channel-handler-shapes.test.ts +72 -0
  353. package/src/wirings/channel/channel-handler.ts +7 -7
  354. package/src/wirings/channel/channel-rpc-service.ts +0 -14
  355. package/src/wirings/channel/channel-rpc.test.ts +25 -4
  356. package/src/wirings/channel/channel-rpc.types.ts +14 -0
  357. package/src/wirings/channel/channel-runner.ts +33 -20
  358. package/src/wirings/channel/channel.types.ts +2 -0
  359. package/src/wirings/channel/index.ts +1 -20
  360. package/src/wirings/channel/local/local-channel-runner.test.ts +68 -0
  361. package/src/wirings/channel/local/local-channel-runner.ts +9 -2
  362. package/src/wirings/channel/pikku-abstract-channel-handler.ts +2 -1
  363. package/src/wirings/channel/serverless/serverless-channel-runner.ts +6 -3
  364. package/src/wirings/cli/channel/cli-channel-runner.ts +3 -1
  365. package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +23 -0
  366. package/src/wirings/cli/channel/cli-raw-channel-runner.ts +12 -1
  367. package/src/wirings/cli/channel/cli-raw-client-runner.ts +4 -1
  368. package/src/wirings/cli/channel/index.ts +0 -7
  369. package/src/wirings/cli/cli-runner.test.ts +68 -0
  370. package/src/wirings/cli/cli-runner.ts +25 -5
  371. package/src/wirings/cli/cli.types.ts +0 -39
  372. package/src/wirings/cli/command-parser.test.ts +19 -0
  373. package/src/wirings/cli/command-parser.ts +17 -1
  374. package/src/wirings/credential/index.ts +0 -1
  375. package/src/wirings/gateway/gateway-channel-meta.test.ts +44 -0
  376. package/src/wirings/gateway/gateway-runner.ts +27 -19
  377. package/src/wirings/gateway/index.ts +0 -3
  378. package/src/wirings/http/http-routes.ts +4 -1
  379. package/src/wirings/http/http-runner.test.ts +66 -0
  380. package/src/wirings/http/http-runner.ts +21 -28
  381. package/src/wirings/http/http.types.ts +0 -15
  382. package/src/wirings/http/index.ts +2 -8
  383. package/src/wirings/http/pikku-fetch-http-request.ts +2 -2
  384. package/src/wirings/http/web-request.ts +1 -1
  385. package/src/wirings/mcp/index.ts +0 -1
  386. package/src/wirings/mcp/mcp-runner.test.ts +181 -0
  387. package/src/wirings/mcp/mcp-runner.ts +37 -21
  388. package/src/wirings/persona/index.ts +0 -8
  389. package/src/wirings/persona/persona-environments.test.ts +14 -3
  390. package/src/wirings/persona/persona.test.ts +13 -3
  391. package/src/wirings/persona/validate-personas.ts +5 -1
  392. package/src/wirings/queue/index.ts +0 -14
  393. package/src/wirings/queue/queue-runner.ts +1 -1
  394. package/src/wirings/rpc/addon-auth-tags.test.ts +1 -5
  395. package/src/wirings/rpc/addon-runner.ts +34 -3
  396. package/src/wirings/rpc/addon-secrets.test.ts +261 -0
  397. package/src/wirings/rpc/rpc-runner.test.ts +2 -0
  398. package/src/wirings/rpc/rpc-runner.ts +60 -136
  399. package/src/wirings/rpc/rpc-types.ts +11 -0
  400. package/src/wirings/rpc/wire-addon.ts +20 -1
  401. package/src/wirings/scheduler/index.ts +0 -1
  402. package/src/wirings/secret/validate-secret-definitions.test.ts +22 -0
  403. package/src/wirings/secret/validate-secret-definitions.ts +2 -2
  404. package/src/wirings/trigger/index.ts +0 -1
  405. package/src/wirings/trigger/pikku-trigger-service.ts +0 -5
  406. package/src/wirings/trigger/trigger-runner.ts +7 -5
  407. package/src/wirings/virtual-user/index.ts +0 -16
  408. package/src/wirings/virtual-user/run-virtual-user.test.ts +18 -9
  409. package/src/wirings/virtual-user/run-virtual-user.ts +28 -15
  410. package/src/wirings/virtual-user/virtual-user-agents.test.ts +4 -1
  411. package/src/wirings/virtual-user/virtual-user-derive.ts +4 -25
  412. package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +7 -2
  413. package/src/wirings/virtual-user/virtual-user-dispositions.ts +1 -4
  414. package/src/wirings/virtual-user/virtual-user-intents.test.ts +13 -3
  415. package/src/wirings/workflow/dsl/workflow-dsl.types.ts +117 -4
  416. package/src/wirings/workflow/feature.ts +7 -4
  417. package/src/wirings/workflow/graph/graph-node.ts +1 -1
  418. package/src/wirings/workflow/graph/graph-runner.test.ts +76 -2
  419. package/src/wirings/workflow/graph/graph-runner.ts +13 -16
  420. package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -5
  421. package/src/wirings/workflow/index.ts +14 -24
  422. package/src/wirings/workflow/pikku-scenario-service.ts +101 -27
  423. package/src/wirings/workflow/pikku-workflow-service.test.ts +15 -14
  424. package/src/wirings/workflow/pikku-workflow-service.ts +214 -743
  425. package/src/wirings/workflow/scenario-expectations.test.ts +75 -0
  426. package/src/wirings/workflow/scenario-hooks.test.ts +52 -0
  427. package/src/wirings/workflow/scenario-step.types.ts +8 -0
  428. package/src/wirings/workflow/workflow-approval-audit.ts +47 -0
  429. package/src/wirings/workflow/workflow-approval-policy.test.ts +524 -0
  430. package/src/wirings/workflow/workflow-approval-policy.ts +68 -0
  431. package/src/wirings/workflow/workflow-approval.ts +289 -0
  432. package/src/wirings/workflow/workflow-child-run-session.test.ts +89 -0
  433. package/src/wirings/workflow/workflow-constants.ts +47 -0
  434. package/src/wirings/workflow/workflow-dispatch-durability.test.ts +1 -1
  435. package/src/wirings/workflow/workflow-errors.ts +128 -0
  436. package/src/wirings/workflow/workflow-inline-authority.test.ts +12 -6
  437. package/src/wirings/workflow/workflow-meta-resolver.ts +45 -0
  438. package/src/wirings/workflow/workflow-missing-meta.test.ts +92 -0
  439. package/src/wirings/workflow/workflow-queue-routing.ts +85 -0
  440. package/src/wirings/workflow/workflow-queue-wiring.ts +149 -0
  441. package/src/wirings/workflow/workflow-recovery.ts +162 -0
  442. package/src/wirings/workflow/workflow-retry-policy.test.ts +1 -1
  443. package/src/wirings/workflow/workflow-run-authority.test.ts +212 -0
  444. package/src/wirings/workflow/workflow-run-engine.types.ts +91 -0
  445. package/src/wirings/workflow/workflow-run-ownership.ts +37 -0
  446. package/src/wirings/workflow/workflow-suspend.ts +61 -0
  447. package/src/wirings/workflow/workflow.types.ts +7 -9
  448. package/src/wirings-stay-decoupled.test.ts +127 -0
  449. package/tsconfig.json +1 -1
  450. package/tsconfig.tsbuildinfo +1 -1
  451. package/dist/internal.d.ts +0 -3
  452. package/dist/internal.js +0 -2
  453. package/dist/middleware/timeout.d.ts +0 -9
  454. package/dist/middleware/timeout.js +0 -15
  455. package/dist/pikku-response.d.ts +0 -6
  456. package/dist/pikku-response.js +0 -6
  457. package/dist/services/gopass-secrets.d.ts +0 -15
  458. package/dist/services/gopass-secrets.js +0 -76
  459. package/dist/services/http-scenario-actors.d.ts +0 -75
  460. package/dist/services/http-scenario-actors.js +0 -195
  461. package/dist/services/http-user-flow-actors.d.ts +0 -67
  462. package/dist/services/http-user-flow-actors.js +0 -193
  463. package/dist/services/scenario-actors-service.d.ts +0 -127
  464. package/dist/services/scenario-actors-service.js +0 -40
  465. package/dist/services/user-flow-actors-service.d.ts +0 -39
  466. package/dist/wirings/credential/wire-credential.d.ts +0 -48
  467. package/dist/wirings/credential/wire-credential.js +0 -47
  468. package/dist/wirings/oauth2/oauth2-client.d.ts +0 -47
  469. package/dist/wirings/oauth2/oauth2-client.js +0 -263
  470. package/dist/wirings/oauth2/oauth2-routes.d.ts +0 -35
  471. package/dist/wirings/oauth2/oauth2-routes.js +0 -146
  472. package/dist/wirings/scope/wire-scope.d.ts +0 -33
  473. package/dist/wirings/scope/wire-scope.js +0 -32
  474. package/dist/wirings/workflow/dsl/index.d.ts +0 -5
  475. package/dist/wirings/workflow/dsl/index.js +0 -4
  476. package/dist/wirings/workflow/graph/index.d.ts +0 -5
  477. package/dist/wirings/workflow/graph/index.js +0 -4
  478. package/src/internal.ts +0 -10
  479. /package/dist/{services/user-flow-actors-service.js → wirings/workflow/workflow-run-engine.types.js} +0 -0
@@ -0,0 +1,6 @@
1
+ export { pikkuAIScorer, pikkuAIJudge } from './ai-scorer.js';
2
+ export { addAIScorer, getAIScorers, getAIScorersMeta, } from './ai-scorer-registry.js';
3
+ export { gradeRun } from './ai-scorer-grade.js';
4
+ export { enableScoreSnapshots, getScoreSnapshot, } from './ai-scorer-snapshots.js';
5
+ export { wireAIScorerQueueWorkers, } from './ai-scorer-worker.js';
6
+ export type { AIRunScore, PikkuAIScorer, ScoreJob, ScorerInput, ScorerJudgeConfig, ScorerLane, ScorerMeta, ScorerOutput, } from './ai-scorer.types.js';
@@ -0,0 +1,5 @@
1
+ export { pikkuAIScorer, pikkuAIJudge } from './ai-scorer.js';
2
+ export { addAIScorer, getAIScorers, getAIScorersMeta, } from './ai-scorer-registry.js';
3
+ export { gradeRun } from './ai-scorer-grade.js';
4
+ export { enableScoreSnapshots, getScoreSnapshot, } from './ai-scorer-snapshots.js';
5
+ export { wireAIScorerQueueWorkers, } from './ai-scorer-worker.js';
@@ -12,6 +12,7 @@ export const runChannelLifecycleWithMiddleware = async ({ channelConfig, meta, l
12
12
  });
13
13
  const allChannelMiddleware = combineChannelMiddleware('channel', `${channelConfig.name}:${lifecycleType}:cm`, {
14
14
  wireInheritedChannelMiddleware: channelMiddlewareMeta,
15
+ // knowledge: questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md
15
16
  wireChannelMiddleware: channelConfig.channelMiddleware,
16
17
  });
17
18
  let wire = {
@@ -46,7 +46,7 @@ export const processMessageHandlers = (services, channelConfig, channelHandler,
46
46
  ? `route '${routingProperty}:${routerValue}'`
47
47
  : 'the default message route';
48
48
  logger.error(`Channel ${channelConfig.name} with id ${channelHandler.getChannel().channelId} requires a session for ${routeMessage}. No session is attached to this websocket connection. Ensure auth middleware establishes a session during websocket upgrade, and configure sessionStore when the runtime needs persisted sessions.`);
49
- // TODO: Send error message back breaks typescript, but should be implemented somehow
49
+ // knowledge: questions/unauthorized-channel-replies-escape-the-declared-out-type.md
50
50
  channelHandler.getChannel().send(`Unauthorized for ${routeMessage}`);
51
51
  return;
52
52
  }
@@ -55,10 +55,7 @@ export const processMessageHandlers = (services, channelConfig, channelHandler,
55
55
  const pikkuFuncId = routeMeta.pikkuFuncId;
56
56
  // Get wire middleware: channel-level middleware + message-specific middleware
57
57
  const channelWireMiddleware = channelConfig.middleware || [];
58
- // Check if onMessage is a wrapper object vs direct function config:
59
- // - Direct config: onMessage.func is a plain Function
60
- // - Wrapper: onMessage.func is a CorePikkuFunctionConfig (has onMessage.func.func)
61
- // - Simple wrapper: onMessage has both func (plain Function) and middleware properties
58
+ // knowledge: decisions/internals/channel-message-handlers-accept-three-config-shapes.md
62
59
  const isWrapper = onMessage &&
63
60
  typeof onMessage === 'object' &&
64
61
  'func' in onMessage &&
@@ -83,6 +80,7 @@ export const processMessageHandlers = (services, channelConfig, channelHandler,
83
80
  inheritedMiddleware,
84
81
  wireMiddleware,
85
82
  inheritedChannelMiddleware: channelMeta?.channelMiddleware,
83
+ // knowledge: questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md
86
84
  wireChannelMiddleware: wireChannelMiddleware,
87
85
  coerceDataFromSchema: true,
88
86
  tags: channelConfig.tags,
@@ -1,12 +1,6 @@
1
1
  import type { DeploymentService } from '../../services/deployment-service.js';
2
2
  import { ChannelRPCRegistry } from './channel-rpc-registry.js';
3
3
  import { type ChannelRPCValidator } from './channel-rpc.types.js';
4
- /**
5
- * `remote` for channels that only ever flow one way — a server-sent stream, an
6
- * agent's output, a local CLI. Nothing is listening for a request on them, so
7
- * the call is refused rather than waiting out a timeout.
8
- */
9
- export declare const unsupportedChannelRemote: (funcName: string) => Promise<never>;
10
4
  /**
11
5
  * A `DeploymentService` whose transport is an open channel rather than an
12
6
  * address, so a server-side function can call back into a peer that has no
@@ -1,13 +1,5 @@
1
1
  import { ChannelRPCRegistry } from './channel-rpc-registry.js';
2
2
  import { CHANNEL_RPC_REQUEST, CHANNEL_RPC_RESPONSE, ChannelRPCError, isChannelRPCPending, isChannelRPCResponse, } from './channel-rpc.types.js';
3
- /**
4
- * `remote` for channels that only ever flow one way — a server-sent stream, an
5
- * agent's output, a local CLI. Nothing is listening for a request on them, so
6
- * the call is refused rather than waiting out a timeout.
7
- */
8
- export const unsupportedChannelRemote = async (funcName) => {
9
- throw new ChannelRPCError(`Cannot call "${funcName}" remotely: this channel has no peer that answers`, 'unsupported');
10
- };
11
3
  /**
12
4
  * A `DeploymentService` whose transport is an open channel rather than an
13
5
  * address, so a server-side function can call back into a peer that has no
@@ -88,3 +88,9 @@ export type ApprovalRequester = (request: {
88
88
  }) => Promise<boolean> | boolean;
89
89
  /** Checks one end of a call — arguments going out, or the answer coming back. */
90
90
  export type ChannelRPCValidator = (funcName: string, value: unknown) => Promise<void> | void;
91
+ /**
92
+ * `remote` for wires with no peer that answers — a server-sent stream, an
93
+ * agent's output, a local CLI. Nothing is listening for a request on them, so
94
+ * the call is refused rather than waiting out a timeout.
95
+ */
96
+ export declare const unsupportedChannelRemote: (funcName: string) => Promise<never>;
@@ -48,3 +48,11 @@ export const isCapabilityDef = (capability) => typeof capability === 'object' &&
48
48
  export const resolveCapability = (capability) => isCapabilityDef(capability)
49
49
  ? capability
50
50
  : { execute: capability, needsApproval: true };
51
+ /**
52
+ * `remote` for wires with no peer that answers — a server-sent stream, an
53
+ * agent's output, a local CLI. Nothing is listening for a request on them, so
54
+ * the call is refused rather than waiting out a timeout.
55
+ */
56
+ export const unsupportedChannelRemote = async (funcName) => {
57
+ throw new ChannelRPCError(`Cannot call "${funcName}" remotely: this channel has no peer that answers`, 'unsupported');
58
+ };
@@ -1,8 +1,6 @@
1
- import type { CorePikkuPermission } from '../../function/functions.types.js';
2
1
  import type { SessionService } from '../../services/user-session-service.js';
3
- import type { CorePikkuMiddleware } from '../../types/core.types.js';
4
2
  import type { ChannelMeta, CoreChannel, RunChannelOptions, RunChannelParams } from './channel.types.js';
5
- export declare const wireChannel: <In, Channel extends string, PikkuPermission extends CorePikkuPermission<In>, PikkuMiddleware extends CorePikkuMiddleware, ChannelFunction>(channel: CoreChannel<In, Channel, PikkuPermission, PikkuMiddleware, ChannelFunction>) => void;
3
+ export declare const wireChannel: <In, Channel extends string, ChannelConnect, ChannelDisconnect, ChannelFunctionMessage>(channel: CoreChannel<In, Channel, ChannelConnect, ChannelDisconnect, ChannelFunctionMessage>) => void;
6
4
  export declare const openChannel: ({ route, coerceDataFromSchema, request, }: Pick<CoreChannel<unknown, string>, "route"> & RunChannelParams<unknown> & {
7
5
  userSession: SessionService<any>;
8
6
  } & RunChannelOptions) => Promise<{
@@ -3,6 +3,18 @@ import { addFunction } from '../../function/function-runner.js';
3
3
  import { pikkuState, getSingletonServices } from '../../pikku-state.js';
4
4
  import { coerceTopLevelDataFromSchema, validateSchema } from '../../schema.js';
5
5
  import { httpRouter } from '../http/routers/http-router.js';
6
+ /**
7
+ * The config to register for a channel handler: the handler itself when it is a
8
+ * direct function config, or its inner `func` when it is a wrapper.
9
+ *
10
+ * knowledge: decisions/internals/channel-message-handlers-accept-three-config-shapes.md
11
+ */
12
+ const registeredHandler = (handler) => {
13
+ const candidate = handler;
14
+ return typeof candidate.func === 'function'
15
+ ? handler
16
+ : candidate.func;
17
+ };
6
18
  export const wireChannel = (channel) => {
7
19
  const channelsMeta = pikkuState(null, 'channel', 'meta');
8
20
  const channelMeta = channelsMeta[channel.name];
@@ -11,15 +23,13 @@ export const wireChannel = (channel) => {
11
23
  return;
12
24
  }
13
25
  if (channel.onConnect && channelMeta.connect) {
14
- addFunction(channelMeta.connect.pikkuFuncId, channel.onConnect);
26
+ addFunction(channelMeta.connect.pikkuFuncId, registeredHandler(channel.onConnect));
15
27
  }
16
28
  if (channel.onDisconnect && channelMeta.disconnect) {
17
- addFunction(channelMeta.disconnect.pikkuFuncId, channel.onDisconnect);
29
+ addFunction(channelMeta.disconnect.pikkuFuncId, registeredHandler(channel.onDisconnect));
18
30
  }
19
31
  if (channel.onMessage && channelMeta.message?.pikkuFuncId) {
20
- addFunction(channelMeta.message.pikkuFuncId, channel.onMessage.func instanceof Function
21
- ? channel.onMessage
22
- : channel.onMessage.func);
32
+ addFunction(channelMeta.message.pikkuFuncId, registeredHandler(channel.onMessage));
23
33
  }
24
34
  if (channel.onMessageWiring && channelMeta.messageWirings) {
25
35
  Object.entries(channel.onMessageWiring).forEach(([channelKey, wirings]) => {
@@ -30,9 +40,7 @@ export const wireChannel = (channel) => {
30
40
  const wiringMeta = channelWirings[wiringKey];
31
41
  if (!wiringMeta)
32
42
  return;
33
- addFunction(wiringMeta.pikkuFuncId, handler.func instanceof Function
34
- ? handler
35
- : handler.func);
43
+ addFunction(wiringMeta.pikkuFuncId, registeredHandler(handler));
36
44
  });
37
45
  });
38
46
  }
@@ -37,6 +37,8 @@ export interface ChannelMeta {
37
37
  message: ChannelMessageMeta | null;
38
38
  messageWirings: Record<string, Record<string, ChannelMessageMeta>>;
39
39
  binary?: boolean | null;
40
+ /** Set when the channel was wired by a gateway rather than declared directly. */
41
+ gateway?: boolean;
40
42
  summary?: string;
41
43
  description?: string;
42
44
  errors?: string[];
@@ -1,13 +1,12 @@
1
- export { wireChannel, openChannel } from './channel-runner.js';
2
- export { addChannelMiddleware, combineChannelMiddleware, wrapChannelWithMiddleware, } from './channel-middleware-runner.js';
1
+ export { wireChannel } from './channel-runner.js';
2
+ export { addChannelMiddleware, combineChannelMiddleware, } from './channel-middleware-runner.js';
3
3
  export { logChannels } from './log-channels.js';
4
4
  export { PikkuAbstractChannelHandler } from './pikku-abstract-channel-handler.js';
5
5
  export type { EventHubService } from './eventhub-service.js';
6
6
  export { ChannelStore } from './channel-store.js';
7
7
  export type { Channel } from './channel-store.js';
8
8
  export { EventHubStore } from './eventhub-store.js';
9
- export type { BinaryData, ChannelsMeta, CoreChannel, CorePikkuChannelMiddleware, CorePikkuChannelMiddlewareFactory, ChannelMessageMeta, ChannelMeta, ChannelRemote, PikkuChannel, PikkuChannelHandlerFactory, } from './channel.types.js';
9
+ export type { BinaryData, ChannelsMeta, CoreChannel, CorePikkuChannelMiddleware, CorePikkuChannelMiddlewareFactory, ChannelMessageMeta, ChannelMeta, PikkuChannel, PikkuChannelHandlerFactory, } from './channel.types.js';
10
10
  export { defineChannelRoutes } from './define-channel-routes.js';
11
- export { CHANNEL_RPC_PENDING, CHANNEL_RPC_REQUEST, CHANNEL_RPC_RESPONSE, ChannelDeploymentService, ChannelRPCError, ChannelRPCRegistry, createChannelRPCResponder, createChannelRPCInputValidator, createChannelRPCResultValidator, isChannelRPCPending, isChannelRPCRequest, isChannelRPCResponse, resolveCapability, unsupportedChannelRemote, } from './channel-rpc.js';
12
- export type { ApprovalPolicy, ApprovalRequester, Capabilities, Capability, CapabilityDef, CapabilityHandler, ChannelRPCPending, ChannelRPCRequest, ChannelRPCResponse, ChannelRPCValidator, } from './channel-rpc.js';
13
- export { channelRemote, getChannelHostRPC, handleChannelRPCResponse, releaseChannelHostRPC, } from './channel-host-rpc.js';
11
+ export { ChannelDeploymentService, ChannelRPCError, ChannelRPCRegistry, unsupportedChannelRemote, } from './channel-rpc.js';
12
+ export type { ApprovalPolicy, ApprovalRequester, Capabilities, Capability, CapabilityHandler, ChannelRPCPending, ChannelRPCRequest, ChannelRPCResponse, ChannelRPCValidator, } from './channel-rpc.js';
@@ -1,9 +1,8 @@
1
- export { wireChannel, openChannel } from './channel-runner.js';
2
- export { addChannelMiddleware, combineChannelMiddleware, wrapChannelWithMiddleware, } from './channel-middleware-runner.js';
1
+ export { wireChannel } from './channel-runner.js';
2
+ export { addChannelMiddleware, combineChannelMiddleware, } from './channel-middleware-runner.js';
3
3
  export { logChannels } from './log-channels.js';
4
4
  export { PikkuAbstractChannelHandler } from './pikku-abstract-channel-handler.js';
5
5
  export { ChannelStore } from './channel-store.js';
6
6
  export { EventHubStore } from './eventhub-store.js';
7
7
  export { defineChannelRoutes } from './define-channel-routes.js';
8
- export { CHANNEL_RPC_PENDING, CHANNEL_RPC_REQUEST, CHANNEL_RPC_RESPONSE, ChannelDeploymentService, ChannelRPCError, ChannelRPCRegistry, createChannelRPCResponder, createChannelRPCInputValidator, createChannelRPCResultValidator, isChannelRPCPending, isChannelRPCRequest, isChannelRPCResponse, resolveCapability, unsupportedChannelRemote, } from './channel-rpc.js';
9
- export { channelRemote, getChannelHostRPC, handleChannelRPCResponse, releaseChannelHostRPC, } from './channel-host-rpc.js';
8
+ export { ChannelDeploymentService, ChannelRPCError, ChannelRPCRegistry, unsupportedChannelRemote, } from './channel-rpc.js';
@@ -135,7 +135,14 @@ export const runLocalChannel = async ({ channelId, request, response, route, ski
135
135
  channelHandler.registerOnMessage(async (data) => {
136
136
  try {
137
137
  const result = await onMessage(data);
138
- await channel.send(result);
138
+ // Guarded exactly as the connect path above is. A handler with nothing
139
+ // to say is normal — a gateway websocket's generated message handler
140
+ // always returns undefined — and sending that raised `send requires a
141
+ // non-empty message`, which surfaced as a channel that accepted a
142
+ // connection and then silently delivered nothing.
143
+ if (result !== undefined) {
144
+ await channel.send(result);
145
+ }
139
146
  }
140
147
  catch (e) {
141
148
  singletonServices.logger.error(e);
@@ -22,6 +22,7 @@ export class PikkuAbstractChannelHandler {
22
22
  setState: (s) => {
23
23
  channelState = s;
24
24
  },
25
+ // knowledge: decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md
25
26
  getState: () => channelState,
26
27
  clearState: () => {
27
28
  channelState = undefined;
@@ -55,6 +55,7 @@ export const runChannelConnect = async ({ channelId, channelObject, request, res
55
55
  channelName: channelConfig.name,
56
56
  });
57
57
  channel.setState = (state) => channelStore.setState(channelId, state);
58
+ // knowledge: decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md
58
59
  channel.getState = () => channelStore.getState(channelId);
59
60
  channel.clearState = () => channelStore.clearState(channelId);
60
61
  const wire = {
@@ -116,6 +117,7 @@ export const runChannelDisconnect = async ({ channelId, channelStore, channelHan
116
117
  channelName,
117
118
  });
118
119
  channel.setState = (state) => channelStore.setState(channelId, state);
120
+ // knowledge: decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md
119
121
  channel.getState = () => channelStore.getState(channelId);
120
122
  channel.clearState = () => channelStore.clearState(channelId);
121
123
  const userSession = new PikkuSessionService(singletonServices.sessionStore);
@@ -171,6 +173,7 @@ export const runChannelMessage = async ({ channelId, channelStore, channelHandle
171
173
  channelName,
172
174
  });
173
175
  channel.setState = (state) => channelStore.setState(channelId, state);
176
+ // knowledge: decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md
174
177
  channel.getState = () => channelStore.getState(channelId);
175
178
  channel.clearState = () => channelStore.clearState(channelId);
176
179
  const userSession = new PikkuSessionService(singletonServices.sessionStore);
@@ -50,6 +50,8 @@ export async function executeCLIViaChannel({ programName, pikkuWS, args = proces
50
50
  resolve(undefined);
51
51
  return;
52
52
  }
53
+ // A CLI channel response is rendered off-process: there are no services
54
+ // to hand the renderer, and every CLI renderer ignores the argument.
53
55
  renderer(null, response, undefined);
54
56
  };
55
57
  commandRoute.subscribe(commandId, responseHandler);
@@ -1,4 +1,5 @@
1
1
  import { pikkuState } from '../../../pikku-state.js';
2
+ import { isProduction } from '../../../env.js';
2
3
  import { parseCLIArguments, generateCommandHelp } from '../command-parser.js';
3
4
  import { runCLICommand } from '../cli-runner.js';
4
5
  /**
@@ -61,6 +62,13 @@ export async function handleRawCLI({ programName, args, singletonServices, creat
61
62
  // A command can throw anything; `.message` off a string is undefined, and
62
63
  // the run would then exit 1 saying nothing at all.
63
64
  const message = e instanceof Error ? e.message : String(e);
64
- return { error: message || 'Command failed', exitCode: 1, commandId };
65
+ // The raw message can carry internals (a stack, a DB error, a path). This
66
+ // runs over a channel that may be remote, so return a generic error in
67
+ // production and keep the detail server-side. Dev keeps the message inline.
68
+ singletonServices.logger.error?.(`CLI channel command failed: ${message}`, e);
69
+ const clientError = isProduction()
70
+ ? 'Command failed'
71
+ : message || 'Command failed';
72
+ return { error: clientError, exitCode: 1, commandId };
65
73
  }
66
74
  }
@@ -2,6 +2,5 @@ export { executeCLIViaChannel } from './cli-channel-runner.js';
2
2
  export { handleRawCLI } from './cli-raw-channel-runner.js';
3
3
  export type { RawCLIFrame, RawCLIResult } from './cli-raw-channel-runner.js';
4
4
  export { executeRawCLIViaChannel } from './cli-raw-client-runner.js';
5
- export type { ClientCLIRenderServices, CorePikkuCLIClientRender, } from './cli-raw-client-runner.js';
6
- export { APPROVAL_FLAGS, approverForMode, createTerminalApprover, takeApprovalFlags, } from './cli-approval.js';
5
+ export type { CorePikkuCLIClientRender, } from './cli-raw-client-runner.js';
7
6
  export type { ApprovalMode } from './cli-approval.js';
@@ -1,4 +1,3 @@
1
1
  export { executeCLIViaChannel } from './cli-channel-runner.js';
2
2
  export { handleRawCLI } from './cli-raw-channel-runner.js';
3
3
  export { executeRawCLIViaChannel } from './cli-raw-client-runner.js';
4
- export { APPROVAL_FLAGS, approverForMode, createTerminalApprover, takeApprovalFlags, } from './cli-approval.js';
@@ -2,7 +2,7 @@ import { NotFoundError } from '../../errors/errors.js';
2
2
  import { isExpectedError } from '../../errors/error-handler.js';
3
3
  import { addFunction, runPikkuFunc } from '../../function/function-runner.js';
4
4
  import { pikkuState } from '../../pikku-state.js';
5
- import { unsupportedChannelRemote } from '../channel/channel-rpc.js';
5
+ import { unsupportedChannelRemote } from '../channel/channel-rpc.types.js';
6
6
  import { PikkuSessionService, createMiddlewareSessionWireProps, } from '../../services/user-session-service.js';
7
7
  import { LocalVariablesService } from '../../services/local-variables.js';
8
8
  import { generateCommandHelp, parseCLIArguments } from './command-parser.js';
@@ -87,7 +87,19 @@ function registerCLICommands(commands, path = [], inheritedOptions = {}, program
87
87
  programs[program].commandMiddleware[commandId] = command.middleware;
88
88
  }
89
89
  }
90
- addFunction(funcName, unwrapFunc(command), currentMeta?.packageName);
90
+ // Merge the command-level auth/permissions into the registered config so
91
+ // they are actually enforced by the function runner. They were accepted by
92
+ // the types but dropped here, making a command's declared access control a
93
+ // silent no-op. Command-level wins over the handler's own, then falls back
94
+ // to it.
95
+ const unwrapped = unwrapFunc(command);
96
+ const commandAuth = typeof command === 'object' ? command.auth : undefined;
97
+ const commandPermissions = typeof command === 'object' ? command.permissions : undefined;
98
+ addFunction(funcName, {
99
+ ...unwrapped,
100
+ auth: commandAuth ?? unwrapped.auth,
101
+ permissions: commandPermissions ?? unwrapped.permissions,
102
+ }, currentMeta?.packageName);
91
103
  if (typeof command === 'object' && command.render) {
92
104
  if (programs[program]) {
93
105
  programs[program].renderers[commandId] = command.render;
@@ -186,6 +198,7 @@ export async function runCLICommand({ program, commandPath, data, singletonServi
186
198
  setState: (s) => {
187
199
  cliState = s;
188
200
  },
201
+ // knowledge: decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md
189
202
  getState: () => cliState,
190
203
  clearState: () => {
191
204
  cliState = undefined;
@@ -230,7 +243,8 @@ export async function runCLICommand({ program, commandPath, data, singletonServi
230
243
  // caller, and emitting it here too would deliver it twice.
231
244
  if (result !== undefined && !onOutput) {
232
245
  const commandRenderer = programData?.renderers[commandId];
233
- const jsonMode = data.json === true || data.output === 'json';
246
+ const jsonMode = data.json === true ||
247
+ data.output === 'json';
234
248
  const finalRenderer = jsonMode && commandRenderer !== undefined
235
249
  ? defaultJSONRenderer
236
250
  : (commandRenderer ?? programData?.defaultRenderer);
@@ -135,10 +135,6 @@ type AllParamsValid<Params extends readonly any[], Input> = Params extends reado
135
135
  * Validate that all parameter names are valid keys of the function input
136
136
  */
137
137
  export type ValidateParameters<Params extends string, Input> = AllParamsValid<ExtractParameterNames<Params>, Input> extends true ? Params : never;
138
- /**
139
- * Extract output type from a Pikku function config type
140
- */
141
- export type ExtractFunctionOutput<Func> = Func extends CorePikkuFunctionConfig<infer FuncType, any, any> ? FuncType extends CorePikkuFunction<any, infer Output, any, any, any> | CorePikkuFunctionSessionless<any, infer Output, any, any, any> ? Output : never : never;
142
138
  /**
143
139
  * CLI command configuration that infers options from function input type.
144
140
  * This is a helper type for creating type-safe CLI commands.
@@ -184,10 +180,6 @@ export interface CoreCLICommand<In, Out, PikkuFunctionConfig extends CorePikkuFu
184
180
  * Shorthand command definition (just a function)
185
181
  */
186
182
  export type CLICommandShorthand<In, Out, PikkuFunctionConfig extends CorePikkuFunctionConfig<CorePikkuFunction<In, Out, any, any, any> | CorePikkuFunctionSessionless<In, Out, any, any, any>>> = PikkuFunctionConfig;
187
- /**
188
- * Command definition (either full or shorthand)
189
- */
190
- export type CLICommandDefinition<In, Out, PikkuFunctionConfig extends CorePikkuFunctionConfig<CorePikkuFunction<In, Out, any, any, any> | CorePikkuFunctionSessionless<In, Out, any, any, any>>, PikkuPermission extends CorePikkuPermission<any, any, any>, PikkuMiddleware extends CorePikkuMiddleware, Options = any, Subcommands extends Record<string, CoreCLICommandConfig<any, any, any>> = Record<string, CoreCLICommandConfig<any, any, any>>> = CoreCLICommand<In, Out, PikkuFunctionConfig, PikkuPermission, PikkuMiddleware, Options, Subcommands> | CLICommandShorthand<In, Out, PikkuFunctionConfig>;
191
183
  /**
192
184
  * CLI wiring configuration
193
185
  */
@@ -49,6 +49,14 @@ function warnUnknownOption(typed, availableOptions, result) {
49
49
  result.warnings.push(`Unknown option: --${typed} (ignored)` +
50
50
  (suggestion ? ` Did you mean --${suggestion}?` : ''));
51
51
  }
52
+ /**
53
+ * A real short-flag cluster is a handful of characters (`-abc`). Anything past
54
+ * this is treated as a single malformed token rather than scanned per
55
+ * character — the parser runs over untrusted CLI-channel frames, and a
56
+ * multi-megabyte `-aaaa…` would otherwise be O(length) work that also pushed
57
+ * one error per character.
58
+ */
59
+ const MAX_SHORT_FLAG_CLUSTER = 64;
52
60
  export function parseCLIArguments(args, programName, allMeta) {
53
61
  const result = {
54
62
  program: programName,
@@ -176,6 +184,11 @@ export function parseCLIArguments(args, programName, allMeta) {
176
184
  }
177
185
  }
178
186
  else if (arg.startsWith('-') && arg.length > 1) {
187
+ if (arg.length > MAX_SHORT_FLAG_CLUSTER) {
188
+ result.errors.push(`Unknown option: ${arg.slice(0, MAX_SHORT_FLAG_CLUSTER)}… (too long)`);
189
+ currentIndex++;
190
+ continue;
191
+ }
179
192
  for (let i = 1; i < arg.length; i++) {
180
193
  const shortFlag = arg[i];
181
194
  const longOption = findLongOption(shortFlag, availableOptions);
@@ -1,3 +1,3 @@
1
1
  export { defineCredential } from './define-credential.js';
2
2
  export { validateAndBuildCredentialDefinitionsMeta } from './validate-credential-definitions.js';
3
- export type { CoreCredential, CredentialDefinitionMeta, CredentialDefinitionsMeta, CredentialDefinitions, } from './credential.types.js';
3
+ export type { CoreCredential, CredentialDefinitionsMeta, CredentialDefinitions, } from './credential.types.js';
@@ -97,6 +97,9 @@ const wireWebhookGateway = (config) => {
97
97
  route,
98
98
  func: postHandler,
99
99
  auth: false,
100
+ // A gateway handler takes (services, data, wire) rather than a pikku
101
+ // function's shape, so it never matches CorePikkuFunctionConfig. It is only
102
+ // ever invoked through runPikkuFunc, which is what makes that safe.
100
103
  });
101
104
  // knowledge: decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md
102
105
  if (typeof adapter === 'function' || adapter.verifyWebhook) {
@@ -151,7 +154,7 @@ const createWebhookPostHandler = (config) => {
151
154
  data: () => parsed,
152
155
  auth: config.auth,
153
156
  inheritedMiddleware,
154
- wire: wire,
157
+ wire,
155
158
  });
156
159
  };
157
160
  const gatewayMiddleware = userMiddleware;
@@ -211,8 +214,11 @@ const wireWebsocketGateway = (config) => {
211
214
  name,
212
215
  route,
213
216
  gateway: true,
217
+ input: null,
214
218
  connect: { pikkuFuncId: connectFuncId },
219
+ disconnect: null,
215
220
  message: { pikkuFuncId: messageFuncId },
221
+ messageWirings: {},
216
222
  };
217
223
  const userMiddleware = config.middleware;
218
224
  const handlerFuncId = registerGatewayHandler(config);
@@ -254,7 +260,7 @@ const wireWebsocketGateway = (config) => {
254
260
  data: () => parsed,
255
261
  auth: config.auth,
256
262
  inheritedMiddleware,
257
- wire: wire,
263
+ wire,
258
264
  });
259
265
  };
260
266
  const gatewayMiddleware = userMiddleware;
@@ -307,6 +313,7 @@ export const createListenerMessageHandler = (name, config, singletonServices) =>
307
313
  wire,
308
314
  });
309
315
  };
316
+ // knowledge: decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md
310
317
  const result = userMiddleware?.length
311
318
  ? await runMiddleware(singletonServices, wire, userMiddleware, invoke)
312
319
  : await invoke();
@@ -1,2 +1,2 @@
1
1
  export { wireGateway, createListenerMessageHandler, resolveGatewayAdapter, } from './gateway-runner.js';
2
- export type { GatewayAdapter, GatewayAdapterFactory, GatewayAttachment, GatewayInboundMessage, GatewayOutboundMessage, GatewayMeta, GatewaysMeta, GatewayTransportType, CoreGateway, PikkuGateway, WebhookVerificationResult, } from './gateway.types.js';
2
+ export type { GatewayAdapter, GatewayAdapterFactory, GatewayInboundMessage, GatewayOutboundMessage, GatewaysMeta, GatewayTransportType, CoreGateway, WebhookVerificationResult, } from './gateway.types.js';
@@ -54,6 +54,8 @@ function registerRoute(route, groupConfig) {
54
54
  timeout: route.timeout,
55
55
  headers: route.headers,
56
56
  sse: route.sse,
57
+ // `CoreHTTPFunctionWiring` is discriminated by `method`, and a group builds
58
+ // its routes from a method chosen at runtime — no arm can be narrowed to.
57
59
  });
58
60
  }
59
61
  function isRouteConfig(value) {
@@ -3,16 +3,6 @@ import type { CorePikkuFunction, CorePikkuFunctionSessionless, CorePikkuPermissi
3
3
  import type { CorePikkuMiddleware, CorePikkuMiddlewareGroup } from '../../types/core.types.js';
4
4
  import { PikkuFetchHTTPResponse } from './pikku-fetch-http-response.js';
5
5
  export declare const addHTTPMiddleware: <PikkuMiddleware extends CorePikkuMiddleware>(pattern: string, middleware: CorePikkuMiddlewareGroup, packageName?: string | null) => CorePikkuMiddlewareGroup;
6
- /**
7
- * @deprecated HTTP-route-level permissions were removed in #972 — permissions
8
- * are now function-scoped only (declare them on the function via
9
- * `pikkuFunc({ permissions })`). This throwing stub exists solely so the pinned
10
- * bootstrap CLI (which still generates an `addHTTPPermission` wrapper) can
11
- * resolve the import at build time; it is never called. Delete once
12
- * `PIKKU_CLI_VERSION` in the CLI build is bumped past the release that removes
13
- * HTTP-route permissions.
14
- */
15
- export declare const addHTTPPermission: (_pattern: string, _permissions: Record<string, CorePikkuPermission | CorePikkuPermission[]> | CorePikkuPermission[]) => never;
16
6
  export declare const wireHTTP: <In, Out, Route extends string, PikkuFunction extends CorePikkuFunction<In, Out> = CorePikkuFunction<In, Out>, PikkuFunctionSessionless extends CorePikkuFunctionSessionless<In, Out> = CorePikkuFunctionSessionless<In, Out>, PikkuPermissionGroup extends CorePikkuPermission<In> = CorePikkuPermission<In>, PikkuMiddleware extends CorePikkuMiddleware = CorePikkuMiddleware>(httpWiring: CoreHTTPFunctionWiring<In, Out, Route, PikkuFunction, PikkuFunctionSessionless, PikkuPermissionGroup, PikkuMiddleware>) => void;
17
7
  export declare const createHTTPWire: (request: PikkuHTTPRequest | undefined, response: PikkuHTTPResponse | undefined) => PikkuHTTP | undefined;
18
8
  export declare const fetch: <In, Out>(request: Request, params?: RunHTTPWiringOptions) => Promise<Response>;
@@ -8,7 +8,9 @@ import { isProduction } from '../../env.js';
8
8
  import { pikkuState } from '../../pikku-state.js';
9
9
  import { PikkuFetchHTTPResponse } from './pikku-fetch-http-response.js';
10
10
  import { PikkuFetchHTTPRequest } from './pikku-fetch-http-request.js';
11
- import { unsupportedChannelRemote } from '../channel/channel-rpc.js';
11
+ // The leaf module, not the channel-rpc barrel: http needs one refusal
12
+ // function, and the barrel drags in 4,932 lines of channel RPC runtime.
13
+ import { unsupportedChannelRemote } from '../channel/channel-rpc.types.js';
12
14
  import { addFunction, runPikkuFunc } from '../../function/function-runner.js';
13
15
  import { applyWebResponse } from './web-request.js';
14
16
  import { httpRouter } from './routers/http-router.js';
@@ -32,18 +34,6 @@ export const addHTTPMiddleware = (pattern, middleware, packageName = null) => {
32
34
  : middleware;
33
35
  return middleware;
34
36
  };
35
- /**
36
- * @deprecated HTTP-route-level permissions were removed in #972 — permissions
37
- * are now function-scoped only (declare them on the function via
38
- * `pikkuFunc({ permissions })`). This throwing stub exists solely so the pinned
39
- * bootstrap CLI (which still generates an `addHTTPPermission` wrapper) can
40
- * resolve the import at build time; it is never called. Delete once
41
- * `PIKKU_CLI_VERSION` in the CLI build is bumped past the release that removes
42
- * HTTP-route permissions.
43
- */
44
- export const addHTTPPermission = (_pattern, _permissions) => {
45
- throw new Error('addHTTPPermission was removed in #972 — HTTP-route-level permissions no longer exist. Declare permissions on the function definition instead: pikkuFunc({ permissions }).');
46
- };
47
37
  export const wireHTTP = (httpWiring) => {
48
38
  const httpMeta = pikkuState(null, 'http', 'meta');
49
39
  const routeMeta = httpMeta[httpWiring.method][httpWiring.route];
@@ -60,6 +50,7 @@ export const wireHTTP = (httpWiring) => {
60
50
  }
61
51
  pikkuState(null, 'http', 'routes')
62
52
  .get(httpWiring.method)
53
+ // knowledge: decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md
63
54
  ?.set(httpWiring.route, httpWiring);
64
55
  };
65
56
  const getMatchingRoute = (requestType, requestPath) => {
@@ -144,6 +135,7 @@ const executeRoute = async (services, matchedRoute, http, options) => {
144
135
  setState: (s) => {
145
136
  sseState = s;
146
137
  },
138
+ // knowledge: decisions/internals/channel-state-accessors-are-unsound-generics-that-every-implementation-asserts.md
147
139
  getState: () => sseState,
148
140
  clearState: () => {
149
141
  sseState = undefined;
@@ -181,6 +173,7 @@ const executeRoute = async (services, matchedRoute, http, options) => {
181
173
  getSession: () => userSession.get(),
182
174
  hasSessionChanged: () => userSession.sessionChanged,
183
175
  };
176
+ const statusBeforeRoute = http?.response?.statusCode;
184
177
  try {
185
178
  result = await runPikkuFunc('http', `${meta.method}:${meta.route}`, meta.pikkuFuncId, {
186
179
  singletonServices,
@@ -217,17 +210,22 @@ const executeRoute = async (services, matchedRoute, http, options) => {
217
210
  http?.response?.flushHeaders?.();
218
211
  }
219
212
  else {
213
+ const statusSetByRoute = http?.response?.statusCode !== statusBeforeRoute;
220
214
  if (result instanceof Response) {
221
215
  await applyWebResponse(http.response, result);
222
216
  }
223
217
  else if (result === undefined || result === null) {
224
- http?.response?.status(204);
218
+ if (!statusSetByRoute) {
219
+ http?.response?.status(204);
220
+ }
225
221
  }
226
222
  else if (route.returnsJSON === false) {
227
223
  http?.response?.arrayBuffer(result);
228
224
  }
229
225
  else {
230
- http?.response?.status(200);
226
+ if (!statusSetByRoute) {
227
+ http?.response?.status(200);
228
+ }
231
229
  http?.response?.json(result);
232
230
  }
233
231
  }
@@ -272,6 +270,7 @@ export const fetchData = async (request, response, { skipUserSession = false, re
272
270
  if (globalMiddleware) {
273
271
  await runMiddleware(singletonServices, wire, globalMiddleware);
274
272
  }
273
+ // 204 carries no body, and `json` has no no-content overload.
275
274
  response.status(204).json(undefined);
276
275
  return;
277
276
  }
@@ -39,7 +39,6 @@ export interface PikkuHTTP<In = unknown> {
39
39
  request?: PikkuHTTPRequest<In>;
40
40
  response?: PikkuHTTPResponse;
41
41
  }
42
- export type RequestHeaders = Record<string, string | string[] | undefined> | ((headerName: string) => string | string[] | undefined);
43
42
  export type PikkuQuery<T = Record<string, string | undefined>> = Record<string, string | T | null | Array<T | null>>;
44
43
  export type CoreHTTPFunctionWiring<In, Out, R extends string, PikkuFunction extends CorePikkuFunction<In, Out, any, any, any> = CorePikkuFunction<In, Out>, PikkuFunctionSessionless extends CorePikkuFunctionSessionless<In, Out, any, any, any> = CorePikkuFunctionSessionless<In, Out>, PikkuPermission extends CorePikkuPermission<In, any, any> = CorePikkuPermission<In, any, any>, PikkuMiddleware extends CorePikkuMiddleware<any, any> = CorePikkuMiddleware<any, any>> = (CoreHTTPFunction & {
45
44
  route: R;
@@ -114,15 +113,6 @@ export type HTTPWiringMeta = CommonWireMeta & {
114
113
  groupBasePath?: string;
115
114
  };
116
115
  export type HTTPWiringsMeta = Record<HTTPMethod, Record<string, HTTPWiringMeta>>;
117
- export type HTTPFunctionsMeta = Array<{
118
- name: string;
119
- inputs: string[] | null;
120
- outputs: string[] | null;
121
- }>;
122
- export type HTTPWiringMiddleware = {
123
- route: string;
124
- middleware: CorePikkuMiddleware[];
125
- };
126
116
  export interface PikkuHTTPRequest<In = unknown> {
127
117
  method(): HTTPMethod;
128
118
  path(): string;
@@ -1,8 +1,7 @@
1
1
  export { PikkuFetchHTTPRequest, DEFAULT_MAX_BODY_SIZE, } from './pikku-fetch-http-request.js';
2
- export type { PikkuFetchHTTPRequestOptions } from './pikku-fetch-http-request.js';
3
2
  export { PikkuFetchHTTPResponse } from './pikku-fetch-http-response.js';
4
3
  export { logRoutes } from './log-http-routes.js';
5
- export { fetch, fetchData, wireHTTP, addHTTPMiddleware, addHTTPPermission, } from './http-runner.js';
4
+ export { fetch, fetchData, wireHTTP, addHTTPMiddleware } from './http-runner.js';
6
5
  export { wireHTTPRoutes, defineHTTPRoutes } from './http-routes.js';
7
6
  export { toWebRequest, applyWebResponse } from './web-request.js';
8
- export type { AssertHTTPWiringParams, CoreHTTPFunctionWiring, HTTPMethod, HTTPRouteBaseConfig, HTTPRouteContract, HTTPRouteMap, HTTPWiringsMeta, PikkuHTTPRequest, PikkuHTTPResponse, PikkuQuery, RunHTTPWiringOptions, } from './http.types.js';
7
+ export type { AssertHTTPWiringParams, CoreHTTPFunctionWiring, HTTPMethod, HTTPRouteBaseConfig, HTTPRouteContract, HTTPRouteMap, HTTPWiringsMeta, PikkuHTTP, PikkuHTTPRequest, PikkuHTTPResponse, PikkuQuery, RunHTTPWiringOptions, } from './http.types.js';