@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
@@ -44,7 +44,11 @@ describe('resolvePersonaEnvironments', () => {
44
44
  describe('personaEnvironmentErrors', () => {
45
45
  test('a persona that declares nothing cannot be wrong', () => {
46
46
  assert.deepEqual(
47
- personaEnvironmentErrors('shopper', { disposition: 'careless' }, ENVIRONMENTS),
47
+ personaEnvironmentErrors(
48
+ 'shopper',
49
+ { disposition: 'careless' },
50
+ ENVIRONMENTS
51
+ ),
48
52
  []
49
53
  )
50
54
  })
@@ -106,8 +110,15 @@ describe('personaEnvironmentErrors', () => {
106
110
  })
107
111
 
108
112
  test('with nothing configured it says where environments go', () => {
109
- const [error] = personaEnvironmentErrors('shopper', { environments: ['x'] }, {})
110
- assert.match(error!, /Declare it under 'environments' in pikku\.config\.json/)
113
+ const [error] = personaEnvironmentErrors(
114
+ 'shopper',
115
+ { environments: ['x'] },
116
+ {}
117
+ )
118
+ assert.match(
119
+ error!,
120
+ /Declare it under 'environments' in pikku\.config\.json/
121
+ )
111
122
  })
112
123
  })
113
124
 
@@ -23,7 +23,10 @@ describe('computed addresses', () => {
23
23
  })
24
24
 
25
25
  test('without a run id the address is the stable, seedable form', () => {
26
- assert.equal(personaEmail('susan', 'mail.example.com'), 'susan@mail.example.com')
26
+ assert.equal(
27
+ personaEmail('susan', 'mail.example.com'),
28
+ 'susan@mail.example.com'
29
+ )
27
30
  })
28
31
 
29
32
  test('an id that is not address-shaped is reduced to one', () => {
@@ -34,7 +37,10 @@ describe('computed addresses', () => {
34
37
  })
35
38
 
36
39
  test('an id with nothing usable in it is refused rather than guessed at', () => {
37
- assert.throws(() => personaEmail('...', 'example.com'), /no usable email label/)
40
+ assert.throws(
41
+ () => personaEmail('...', 'example.com'),
42
+ /no usable email label/
43
+ )
38
44
  })
39
45
 
40
46
  // A synthetic domain was rejected precisely because it makes every
@@ -97,7 +103,11 @@ describe('verifying roles at sign-in', () => {
97
103
  })
98
104
 
99
105
  test('order and duplication are not drift', () => {
100
- const v = verifyPersonaRoles('yasser', ['admin', 'buyer'], ['buyer', 'admin', 'buyer'])
106
+ const v = verifyPersonaRoles(
107
+ 'yasser',
108
+ ['admin', 'buyer'],
109
+ ['buyer', 'admin', 'buyer']
110
+ )
101
111
  assert.equal(v.ok, true)
102
112
  })
103
113
 
@@ -1,4 +1,8 @@
1
- import type { PersonaDefinitions, PersonaMeta, PersonasMeta } from './persona.types.js'
1
+ import type {
2
+ PersonaDefinitions,
3
+ PersonaMeta,
4
+ PersonasMeta,
5
+ } from './persona.types.js'
2
6
 
3
7
  /**
4
8
  * Whether a persona can actually be driven by a virtual user.
@@ -17,26 +17,12 @@ export type {
17
17
  export {
18
18
  wireQueueWorker,
19
19
  runQueueJob,
20
- getQueueWorkers,
21
- removeQueueWorker,
22
20
  QueueJobDiscardedError,
23
21
  QueueJobFailedError,
24
22
  } from './queue-runner.js'
25
-
26
- export {
27
- QUEUE_IDENTITY_CLAIM_VERSION,
28
- QUEUE_IDENTITY_INFO,
29
- QUEUE_IDENTITY_SECRET_NAME,
30
- getQueueIdentitySecret,
31
- resolveQueueJobIdentity,
32
- signQueueIdentity,
33
- verifyQueueIdentity,
34
- } from './queue-identity.js'
35
23
  export type { QueueIdentityBinding } from './queue-identity.js'
36
24
 
37
25
  export { SignedQueueService } from './signed-queue-service.js'
38
-
39
- export { validateWorkerConfig } from './validate-worker-config.js'
40
26
  export type { QueueConfigMapping } from './validate-worker-config.js'
41
27
 
42
28
  export { registerQueueWorkers } from './register-queue-helper.js'
@@ -58,7 +58,7 @@ export const wireQueueWorker = <
58
58
  func: queueWorker.func.func,
59
59
  auth: queueWorker.func.auth,
60
60
  permissions: queueWorker.func.permissions,
61
- middleware: queueWorker.func.middleware as any,
61
+ middleware: queueWorker.func.middleware,
62
62
  tags: queueWorker.func.tags,
63
63
  })
64
64
 
@@ -8,11 +8,7 @@ import {
8
8
  clearMiddlewareCache,
9
9
  } from '../../middleware-runner.js'
10
10
  import { ForbiddenError } from '../../errors/errors.js'
11
- import {
12
- resolveAddonAuth,
13
- resolveAddonTags,
14
- wireAddon,
15
- } from './wire-addon.js'
11
+ import { resolveAddonAuth, resolveAddonTags, wireAddon } from './wire-addon.js'
16
12
 
17
13
  const ADDON_PACKAGE = '@addon/console'
18
14
 
@@ -4,6 +4,8 @@ import type {
4
4
  CoreSingletonServices,
5
5
  } from '../../types/core.types.js'
6
6
  import type { SecretService } from '../../services/secret-service.js'
7
+ import { ScopedSecretService } from '../../services/scoped-secret-service.js'
8
+ import { ScopedCredentialService } from '../../services/scoped-credential-service.js'
7
9
  import type { VariablesService } from '../../services/variables-service.js'
8
10
 
9
11
  export type AddonInstance = {
@@ -11,6 +13,10 @@ export type AddonInstance = {
11
13
  secretOverrides?: Record<string, string>
12
14
  variableOverrides?: Record<string, string>
13
15
  credentialOverrides?: Record<string, string>
16
+ /** Set by the consuming app to opt this instance out of secret scoping. */
17
+ globalSecrets?: string
18
+ /** Set by the consuming app to opt this instance out of credential scoping. */
19
+ globalCredentials?: string
14
20
  }
15
21
 
16
22
  const aliasSecretService = (
@@ -111,9 +117,6 @@ export const getOrCreatePackageSingletonServices = async (
111
117
  }
112
118
 
113
119
  const factories = pikkuState(packageName, 'package', 'factories')
114
- if (!factories || !factories.createSingletonServices) {
115
- return parentServices
116
- }
117
120
 
118
121
  let existingServices = parentServices
119
122
  if (addonInstance?.secretOverrides && parentServices.secrets) {
@@ -134,6 +137,32 @@ export const getOrCreatePackageSingletonServices = async (
134
137
  ),
135
138
  }
136
139
  }
140
+ if (!addonInstance?.globalSecrets && existingServices.secrets) {
141
+ existingServices = {
142
+ ...existingServices,
143
+ secrets: new ScopedSecretService(
144
+ existingServices.secrets,
145
+ new Set(pikkuState(packageName, 'package', 'declaredSecrets') ?? [])
146
+ ),
147
+ }
148
+ }
149
+ if (!addonInstance?.globalCredentials && existingServices.credentialService) {
150
+ existingServices = {
151
+ ...existingServices,
152
+ credentialService: new ScopedCredentialService(
153
+ existingServices.credentialService,
154
+ new Set(
155
+ Object.keys(
156
+ pikkuState(packageName, 'package', 'credentialsMeta') ?? {}
157
+ )
158
+ )
159
+ ),
160
+ }
161
+ }
162
+
163
+ if (!factories || !factories.createSingletonServices) {
164
+ return existingServices
165
+ }
137
166
 
138
167
  let config: CoreConfig = existingServices.config
139
168
  if (factories.createConfig) {
@@ -173,5 +202,7 @@ export const addonInstanceForNamespace = (
173
202
  secretOverrides: cfg.secretOverrides,
174
203
  variableOverrides: cfg.variableOverrides,
175
204
  credentialOverrides: cfg.credentialOverrides,
205
+ globalSecrets: cfg.globalSecrets,
206
+ globalCredentials: cfg.globalCredentials,
176
207
  }
177
208
  }
@@ -0,0 +1,261 @@
1
+ import { beforeEach, describe, test } from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+
4
+ import { pikkuState, resetPikkuState } from '../../pikku-state.js'
5
+ import { getOrCreatePackageSingletonServices } from './addon-runner.js'
6
+ import { wireAddon } from './wire-addon.js'
7
+ import type { SecretService } from '../../services/secret-service.js'
8
+ import type { CredentialService } from '../../services/credential-service.js'
9
+ import type { CoreSingletonServices } from '../../types/core.types.js'
10
+
11
+ const ADDON_PACKAGE = '@addon/example'
12
+
13
+ const createSecretService = (): SecretService =>
14
+ ({
15
+ getSecret: async (key: string) => `value-of-${key}` as never,
16
+ hasSecret: async () => true,
17
+ setSecret: async () => {},
18
+ deleteSecret: async () => {},
19
+ getSecrets: async (keys: string[]) =>
20
+ Object.fromEntries(keys.map((k) => [k, `value-of-${k}`])) as never,
21
+ }) as SecretService
22
+
23
+ const createCredentialService = (): CredentialService =>
24
+ ({
25
+ get: async (name: string) => `credential-of-${name}`,
26
+ set: async () => {},
27
+ delete: async () => {},
28
+ has: async () => true,
29
+ getAll: async () => ({ slack: 'a', stripe: 'b' }),
30
+ getUsersWithCredential: async () => ['user-1'],
31
+ getAllUsers: async () => ['user-1'],
32
+ }) as unknown as CredentialService
33
+
34
+ const createParentServices = () =>
35
+ ({
36
+ config: {},
37
+ logger: {
38
+ debug: () => {},
39
+ info: () => {},
40
+ warn: () => {},
41
+ error: () => {},
42
+ },
43
+ secrets: createSecretService(),
44
+ credentialService: createCredentialService(),
45
+ }) as unknown as CoreSingletonServices
46
+
47
+ /**
48
+ * Registers an addon package whose singleton factory hands back whatever
49
+ * secrets service the host decided it should see.
50
+ */
51
+ const registerAddon = (
52
+ declaredSecrets: string[] | null,
53
+ declaredCredentials?: string[]
54
+ ) => {
55
+ pikkuState(ADDON_PACKAGE, 'package', 'factories', {
56
+ createSingletonServices: (async (_config: unknown, parent: any) => ({
57
+ ...parent,
58
+ secretsSeenByAddon: parent.secrets,
59
+ credentialsSeenByAddon: parent.credentialService,
60
+ })) as never,
61
+ })
62
+ if (declaredSecrets) {
63
+ pikkuState(ADDON_PACKAGE, 'package', 'declaredSecrets', declaredSecrets)
64
+ }
65
+ if (declaredCredentials) {
66
+ pikkuState(
67
+ ADDON_PACKAGE,
68
+ 'package',
69
+ 'credentialsMeta',
70
+ Object.fromEntries(
71
+ declaredCredentials.map((name) => [
72
+ name,
73
+ { name, displayName: name, type: 'singleton' },
74
+ ])
75
+ )
76
+ )
77
+ }
78
+ }
79
+
80
+ const servicesHandedToAddon = async (namespace: string) =>
81
+ (await getOrCreatePackageSingletonServices(
82
+ ADDON_PACKAGE,
83
+ createParentServices(),
84
+ pikkuState(null, 'addons', 'packages').get(namespace) as never
85
+ )) as any
86
+
87
+ const secretsHandedToAddon = async (namespace: string) =>
88
+ (await servicesHandedToAddon(namespace)).secretsSeenByAddon as SecretService
89
+
90
+ const credentialsHandedToAddon = async (namespace: string) =>
91
+ (await servicesHandedToAddon(namespace))
92
+ .credentialsSeenByAddon as CredentialService
93
+
94
+ describe('addon secrets are scoped to what the addon declared', () => {
95
+ beforeEach(() => {
96
+ resetPikkuState()
97
+ })
98
+
99
+ test('a declared secret is readable', async () => {
100
+ registerAddon(['ADDON_KEY'])
101
+ wireAddon({
102
+ name: 'example',
103
+ package: ADDON_PACKAGE,
104
+ })
105
+
106
+ const secrets = await secretsHandedToAddon('example')
107
+ assert.equal(await secrets.getSecret('ADDON_KEY'), 'value-of-ADDON_KEY')
108
+ })
109
+
110
+ test('an undeclared secret is denied', async () => {
111
+ registerAddon(['ADDON_KEY'])
112
+ wireAddon({
113
+ name: 'example',
114
+ package: ADDON_PACKAGE,
115
+ })
116
+
117
+ const secrets = await secretsHandedToAddon('example')
118
+ await assert.rejects(
119
+ () => secrets.getSecret('SOMEONE_ELSES_KEY'),
120
+ /denied/i
121
+ )
122
+ })
123
+
124
+ test('a scoped addon cannot write secrets', async () => {
125
+ registerAddon(['ADDON_KEY'])
126
+ wireAddon({
127
+ name: 'example',
128
+ package: ADDON_PACKAGE,
129
+ })
130
+
131
+ const secrets = await secretsHandedToAddon('example')
132
+ await assert.rejects(() => secrets.setSecret('ADDON_KEY', 'x'))
133
+ })
134
+
135
+ test('an addon that declares nothing is scoped to nothing', async () => {
136
+ registerAddon([])
137
+ wireAddon({
138
+ name: 'example',
139
+ package: ADDON_PACKAGE,
140
+ })
141
+
142
+ const secrets = await secretsHandedToAddon('example')
143
+ await assert.rejects(() => secrets.getSecret('ADDON_KEY'), /denied/i)
144
+ })
145
+
146
+ test('globalSecrets, set by the host, hands over the whole service', async () => {
147
+ registerAddon(['ADDON_KEY'])
148
+ wireAddon({
149
+ name: 'example',
150
+ package: ADDON_PACKAGE,
151
+ globalSecrets: 'administers secrets named by the operator at runtime',
152
+ })
153
+
154
+ const secrets = await secretsHandedToAddon('example')
155
+ assert.equal(
156
+ await secrets.getSecret('SOMEONE_ELSES_KEY'),
157
+ 'value-of-SOMEONE_ELSES_KEY'
158
+ )
159
+ await assert.doesNotReject(() => secrets.setSecret('ADDON_KEY', 'x'))
160
+ })
161
+
162
+ test('an addon with no singleton factory is still scoped', async () => {
163
+ pikkuState(ADDON_PACKAGE, 'package', 'declaredSecrets', ['ADDON_KEY'])
164
+ wireAddon({
165
+ name: 'example',
166
+ package: ADDON_PACKAGE,
167
+ })
168
+
169
+ const services = await getOrCreatePackageSingletonServices(
170
+ ADDON_PACKAGE,
171
+ createParentServices(),
172
+ pikkuState(null, 'addons', 'packages').get('example') as never
173
+ )
174
+
175
+ assert.equal(
176
+ await services.secrets.getSecret('ADDON_KEY'),
177
+ 'value-of-ADDON_KEY'
178
+ )
179
+ await assert.rejects(
180
+ () => services.secrets.getSecret('SOMEONE_ELSES_KEY'),
181
+ /denied/i
182
+ )
183
+ })
184
+
185
+ test('scoping applies to the key the addon asks for, not the aliased one', async () => {
186
+ registerAddon(['ADDON_KEY'])
187
+ wireAddon({
188
+ name: 'example',
189
+ package: ADDON_PACKAGE,
190
+ secretOverrides: { ADDON_KEY: 'PROD_ADDON_KEY' },
191
+ })
192
+
193
+ const secrets = await secretsHandedToAddon('example')
194
+ assert.equal(
195
+ await secrets.getSecret('ADDON_KEY'),
196
+ 'value-of-PROD_ADDON_KEY'
197
+ )
198
+ await assert.rejects(() => secrets.getSecret('PROD_ADDON_KEY'), /denied/i)
199
+ })
200
+ })
201
+
202
+ describe('addon credentials are scoped to what the addon declared', () => {
203
+ beforeEach(() => {
204
+ resetPikkuState()
205
+ })
206
+
207
+ test('a declared credential is reachable', async () => {
208
+ registerAddon(['ADDON_KEY'], ['slack'])
209
+ wireAddon({ name: 'example', package: ADDON_PACKAGE })
210
+
211
+ const credentials = await credentialsHandedToAddon('example')
212
+ assert.equal(await credentials.get('slack'), 'credential-of-slack')
213
+ })
214
+
215
+ test('an undeclared credential is denied', async () => {
216
+ registerAddon(['ADDON_KEY'], ['slack'])
217
+ wireAddon({ name: 'example', package: ADDON_PACKAGE })
218
+
219
+ const credentials = await credentialsHandedToAddon('example')
220
+ await assert.rejects(() => credentials.get('stripe'), /denied/i)
221
+ })
222
+
223
+ test('a scoped addon cannot enumerate the app users', async () => {
224
+ registerAddon(['ADDON_KEY'], ['slack'])
225
+ wireAddon({ name: 'example', package: ADDON_PACKAGE })
226
+
227
+ const credentials = await credentialsHandedToAddon('example')
228
+ await assert.rejects(() => credentials.getAllUsers(), /denied/i)
229
+ })
230
+
231
+ test('an addon with no singleton factory is still scoped', async () => {
232
+ pikkuState(ADDON_PACKAGE, 'package', 'credentialsMeta', {
233
+ slack: { name: 'slack', displayName: 'slack', type: 'singleton' },
234
+ } as never)
235
+ wireAddon({ name: 'example', package: ADDON_PACKAGE })
236
+
237
+ const services = await getOrCreatePackageSingletonServices(
238
+ ADDON_PACKAGE,
239
+ createParentServices(),
240
+ pikkuState(null, 'addons', 'packages').get('example') as never
241
+ )
242
+ const credentials = services.credentialService as CredentialService
243
+
244
+ assert.equal(await credentials.get('slack'), 'credential-of-slack')
245
+ await assert.rejects(() => credentials.get('stripe'), /denied/i)
246
+ await assert.rejects(() => credentials.getAllUsers(), /denied/i)
247
+ })
248
+
249
+ test('globalCredentials, set by the host, hands over the whole service', async () => {
250
+ registerAddon(['ADDON_KEY'], ['slack'])
251
+ wireAddon({
252
+ name: 'example',
253
+ package: ADDON_PACKAGE,
254
+ globalCredentials: 'links credentials an operator names at runtime',
255
+ })
256
+
257
+ const credentials = await credentialsHandedToAddon('example')
258
+ assert.equal(await credentials.get('stripe'), 'credential-of-stripe')
259
+ assert.deepEqual(await credentials.getAllUsers(), ['user-1'])
260
+ })
261
+ })
@@ -708,6 +708,7 @@ describe('multi-instance addons', () => {
708
708
  return svc
709
709
  },
710
710
  } as never)
711
+ pikkuState('@addon/slack', 'package', 'declaredSecrets', ['slackToken'])
711
712
  registerFunction(
712
713
  'send',
713
714
  async (services: any) => ({ token: services.token }),
@@ -753,6 +754,7 @@ describe('multi-instance addons', () => {
753
754
  }
754
755
  },
755
756
  } as never)
757
+ pikkuState('@addon/slack', 'package', 'declaredSecrets', ['slackToken'])
756
758
 
757
759
  registerFunction(
758
760
  'leaf',