@pikku/core 0.12.84 → 0.12.86

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (564) hide show
  1. package/CHANGELOG.md +424 -0
  2. package/dist/bootstrap-compat/root.d.ts +20 -0
  3. package/dist/classification/column-form.d.ts +32 -0
  4. package/dist/classification/column-form.js +42 -0
  5. package/dist/classification/data-classification.d.ts +64 -0
  6. package/dist/classification/index.d.ts +13 -0
  7. package/dist/classification/index.js +2 -0
  8. package/dist/classification/secret-value.d.ts +56 -0
  9. package/dist/classification/secret-value.js +46 -0
  10. package/dist/crypto-utils.d.ts +1 -1
  11. package/dist/ecosystem/agent-scorer.d.ts +1 -1
  12. package/dist/ecosystem/agent.d.ts +4 -1
  13. package/dist/ecosystem/channel/local.d.ts +2 -0
  14. package/dist/ecosystem/channel/local.js +2 -0
  15. package/dist/ecosystem/channel/serverless.d.ts +9 -0
  16. package/dist/ecosystem/channel/serverless.js +1 -0
  17. package/dist/ecosystem/channel.d.ts +3 -0
  18. package/dist/ecosystem/channel.js +1 -0
  19. package/dist/ecosystem/cli.d.ts +1 -1
  20. package/dist/ecosystem/cli.js +1 -1
  21. package/dist/ecosystem/credential.d.ts +1 -0
  22. package/dist/ecosystem/crypto-utils.d.ts +8 -0
  23. package/dist/ecosystem/crypto-utils.js +1 -0
  24. package/dist/ecosystem/dev.d.ts +1 -0
  25. package/dist/ecosystem/dev.js +1 -0
  26. package/{src/ecosystem/testing.ts → dist/ecosystem/errors.d.ts} +3 -3
  27. package/dist/ecosystem/errors.js +2 -0
  28. package/dist/ecosystem/function.d.ts +1 -1
  29. package/dist/ecosystem/function.js +1 -1
  30. package/dist/ecosystem/http.d.ts +3 -1
  31. package/dist/ecosystem/http.js +3 -1
  32. package/dist/ecosystem/mcp.d.ts +1 -1
  33. package/dist/ecosystem/mcp.js +1 -1
  34. package/dist/ecosystem/middleware.d.ts +2 -1
  35. package/dist/ecosystem/middleware.js +2 -1
  36. package/dist/ecosystem/persona.d.ts +4 -2
  37. package/dist/ecosystem/persona.js +2 -1
  38. package/dist/ecosystem/queue.d.ts +4 -2
  39. package/dist/ecosystem/queue.js +3 -1
  40. package/dist/ecosystem/role.d.ts +1 -0
  41. package/dist/ecosystem/rpc.d.ts +2 -0
  42. package/dist/ecosystem/rpc.js +1 -0
  43. package/dist/ecosystem/scenario.d.ts +8 -2
  44. package/dist/ecosystem/scenario.js +5 -1
  45. package/dist/ecosystem/scheduler.d.ts +2 -1
  46. package/dist/ecosystem/scheduler.js +2 -1
  47. package/dist/ecosystem/schema.d.ts +2 -1
  48. package/dist/ecosystem/schema.js +1 -1
  49. package/dist/ecosystem/scope.d.ts +2 -0
  50. package/dist/ecosystem/scope.js +1 -0
  51. package/dist/ecosystem/secret.d.ts +2 -0
  52. package/dist/ecosystem/secret.js +1 -0
  53. package/dist/ecosystem/services/local-content.d.ts +2 -1
  54. package/dist/ecosystem/services/local-content.js +1 -1
  55. package/dist/ecosystem/services/local-meta.d.ts +1 -0
  56. package/dist/ecosystem/services/local-meta.js +1 -0
  57. package/dist/ecosystem/services.d.ts +11 -3
  58. package/dist/ecosystem/services.js +7 -1
  59. package/dist/ecosystem/trigger.d.ts +1 -0
  60. package/dist/ecosystem/trigger.js +1 -1
  61. package/dist/ecosystem/types.d.ts +6 -3
  62. package/dist/ecosystem/types.js +3 -2
  63. package/dist/ecosystem/variable.d.ts +1 -0
  64. package/dist/ecosystem/virtual-user.d.ts +3 -0
  65. package/dist/ecosystem/virtual-user.js +3 -0
  66. package/dist/ecosystem/workflow.d.ts +2 -0
  67. package/dist/ecosystem/workflow.js +2 -0
  68. package/dist/errors/index.d.ts +8 -0
  69. package/dist/errors/index.js +1 -0
  70. package/dist/errors/serialized-error.d.ts +7 -0
  71. package/dist/function/function-meta.types.d.ts +139 -0
  72. package/dist/function/function-runner.d.ts +3 -2
  73. package/dist/function/function-runner.js +31 -11
  74. package/dist/function/functions.types.d.ts +10 -2
  75. package/dist/function/index.d.ts +8 -2
  76. package/dist/function/index.js +4 -1
  77. package/dist/function/pikku-request.d.ts +8 -0
  78. package/dist/function/pikku-request.js +15 -0
  79. package/dist/middleware/auth-apikey.d.ts +2 -10
  80. package/dist/middleware/auth-apikey.js +1 -1
  81. package/dist/middleware/auth-bearer.d.ts +2 -10
  82. package/dist/middleware/auth-bearer.js +1 -1
  83. package/dist/middleware/auth-cookie.d.ts +2 -10
  84. package/dist/middleware/auth-cookie.js +1 -1
  85. package/dist/middleware/cors.d.ts +5 -11
  86. package/dist/middleware/cors.js +13 -6
  87. package/dist/middleware/index.d.ts +3 -0
  88. package/dist/middleware/index.js +1 -0
  89. package/dist/middleware/middleware-factories.d.ts +9 -0
  90. package/dist/middleware/middleware-factories.js +19 -0
  91. package/dist/middleware/middleware.types.d.ts +27 -0
  92. package/dist/middleware/middleware.types.js +1 -0
  93. package/dist/middleware/remote-auth.d.ts +2 -2
  94. package/dist/middleware/remote-auth.js +1 -1
  95. package/dist/middleware/telemetry.d.ts +4 -20
  96. package/dist/middleware/telemetry.js +1 -1
  97. package/dist/middleware-runner.d.ts +2 -1
  98. package/dist/pikku-state.d.ts +2 -1
  99. package/dist/services/audit-service.d.ts +1 -1
  100. package/dist/services/credential-wire-service.js +1 -1
  101. package/dist/services/email-service.d.ts +1 -1
  102. package/dist/services/file-scenario-run-store.d.ts +58 -0
  103. package/dist/services/file-scenario-run-store.js +214 -0
  104. package/dist/services/in-memory-workflow-service.d.ts +1 -1
  105. package/dist/services/index.d.ts +5 -1
  106. package/dist/services/index.js +3 -0
  107. package/dist/services/local-secrets.d.ts +1 -1
  108. package/dist/services/local-secrets.js +1 -1
  109. package/dist/services/logger.d.ts +7 -7
  110. package/dist/services/meta-service.d.ts +2 -1
  111. package/dist/services/scoped-secret-service.d.ts +1 -1
  112. package/dist/services/secret-service.d.ts +1 -1
  113. package/dist/services/typed-secret-service.d.ts +16 -2
  114. package/dist/services/typed-secret-service.js +5 -0
  115. package/dist/services/webhook-service.d.ts +1 -1
  116. package/dist/services/workflow-service.d.ts +2 -1
  117. package/dist/testing/index.d.ts +1 -0
  118. package/dist/testing/index.js +1 -0
  119. package/dist/types/core.types.d.ts +30 -180
  120. package/dist/types/core.types.js +1 -19
  121. package/dist/types/index.d.ts +2 -0
  122. package/dist/types/index.js +1 -0
  123. package/dist/types/state.types.d.ts +3 -1
  124. package/dist/utils.d.ts +13 -0
  125. package/dist/utils.js +2 -0
  126. package/dist/wirings/addon/addon-runner.d.ts +17 -0
  127. package/dist/wirings/addon/addon-runner.js +150 -0
  128. package/dist/wirings/addon/index.d.ts +6 -0
  129. package/dist/wirings/addon/index.js +3 -0
  130. package/dist/wirings/addon/remote-addon-auth.d.ts +16 -0
  131. package/dist/wirings/addon/remote-addon-auth.js +39 -0
  132. package/dist/wirings/addon/wire-addon.d.ts +80 -0
  133. package/dist/wirings/addon/wire-addon.js +120 -0
  134. package/dist/wirings/addon/wire-remote-addon.d.ts +22 -0
  135. package/dist/wirings/addon/wire-remote-addon.js +11 -0
  136. package/dist/wirings/agent/agent-prepare.d.ts +3 -3
  137. package/dist/wirings/agent/agent-prepare.js +1 -1
  138. package/dist/wirings/agent/agent-runner.js +2 -3
  139. package/dist/wirings/agent/agent-stream.js +2 -2
  140. package/dist/wirings/agent/agent-utils.d.ts +13 -0
  141. package/dist/wirings/agent/agent-utils.js +16 -0
  142. package/dist/wirings/agent/agent.types.d.ts +3 -2
  143. package/dist/wirings/agent/index.d.ts +1 -1
  144. package/dist/wirings/agent/voice-input.js +1 -1
  145. package/dist/wirings/agent/voice-output.js +1 -1
  146. package/dist/wirings/agent-scorer/agent-scorer-judge.d.ts +13 -0
  147. package/dist/wirings/agent-scorer/agent-scorer-judge.js +52 -0
  148. package/dist/wirings/agent-scorer/agent-scorer.d.ts +7 -1
  149. package/dist/wirings/agent-scorer/agent-scorer.js +1 -0
  150. package/dist/wirings/agent-scorer/agent-scorer.types.d.ts +20 -0
  151. package/dist/wirings/agent-scorer/index.d.ts +1 -1
  152. package/dist/wirings/channel/channel-common.d.ts +2 -1
  153. package/dist/wirings/channel/channel-middleware-runner.d.ts +2 -1
  154. package/dist/wirings/channel/channel.types.d.ts +1 -1
  155. package/dist/wirings/channel/serverless/index.d.ts +1 -0
  156. package/dist/wirings/cli/channel/index.d.ts +1 -1
  157. package/dist/wirings/cli/cli-runner.d.ts +2 -1
  158. package/dist/wirings/cli/cli-runner.js +4 -1
  159. package/dist/wirings/cli/cli.types.d.ts +21 -2
  160. package/dist/wirings/cli/command-parser.js +157 -23
  161. package/dist/wirings/gateway/gateway.types.d.ts +2 -1
  162. package/dist/wirings/http/http-runner.d.ts +1 -1
  163. package/dist/wirings/http/http-runner.js +1 -1
  164. package/dist/wirings/http/http.types.d.ts +2 -2
  165. package/dist/wirings/http/index.d.ts +1 -0
  166. package/dist/wirings/http/index.js +1 -0
  167. package/dist/wirings/http/pikku-fetch-http-request.js +1 -1
  168. package/dist/wirings/http/pikku-fetch-http-response.js +2 -2
  169. package/dist/wirings/mcp/mcp.types.d.ts +1 -1
  170. package/dist/wirings/persona/index.d.ts +1 -1
  171. package/dist/wirings/persona/index.js +1 -1
  172. package/dist/wirings/persona/persona.types.d.ts +14 -0
  173. package/dist/wirings/queue/queue.types.d.ts +1 -1
  174. package/dist/wirings/queue/signed-queue-service.d.ts +1 -1
  175. package/dist/wirings/rpc/index.d.ts +0 -6
  176. package/dist/wirings/rpc/index.js +0 -3
  177. package/dist/wirings/rpc/remote-addon-auth.d.ts +1 -1
  178. package/dist/wirings/rpc/remote-addon-auth.js +1 -1
  179. package/dist/wirings/rpc/rpc-runner.js +2 -2
  180. package/dist/wirings/rpc/wire-addon.d.ts +1 -1
  181. package/dist/wirings/scheduler/scheduler.types.d.ts +2 -1
  182. package/dist/wirings/scope/index.d.ts +1 -0
  183. package/dist/wirings/scope/index.js +1 -0
  184. package/dist/wirings/secret/secret.types.d.ts +10 -0
  185. package/dist/wirings/secret/validate-secret-definitions.js +2 -0
  186. package/dist/wirings/variable/validate-variable-definitions.js +2 -0
  187. package/dist/wirings/variable/variable.types.d.ts +9 -0
  188. package/dist/wirings/virtual-user/index.d.ts +1 -1
  189. package/dist/wirings/virtual-user/index.js +1 -1
  190. package/dist/wirings/virtual-user/prepare-virtual-user-run.d.ts +1 -1
  191. package/dist/wirings/virtual-user/virtual-user-derive.d.ts +1 -1
  192. package/dist/wirings/workflow/graph/graph-node.d.ts +9 -2
  193. package/dist/wirings/workflow/graph/graph-node.js +2 -0
  194. package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -0
  195. package/dist/wirings/workflow/graph/graph-runner.js +283 -31
  196. package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +16 -1
  197. package/dist/wirings/workflow/index.d.ts +2 -0
  198. package/dist/wirings/workflow/index.js +1 -0
  199. package/dist/wirings/workflow/pikku-scenario-service.d.ts +14 -4
  200. package/dist/wirings/workflow/pikku-scenario-service.js +44 -16
  201. package/dist/wirings/workflow/pikku-workflow-service.d.ts +2 -1
  202. package/dist/wirings/workflow/pikku-workflow-service.js +3 -4
  203. package/dist/wirings/workflow/run-timeline.d.ts +1 -1
  204. package/dist/wirings/workflow/scenario-run.types.d.ts +171 -0
  205. package/dist/wirings/workflow/scenario-run.types.js +1 -0
  206. package/dist/wirings/workflow/scenario-step-guards.d.ts +1 -2
  207. package/dist/wirings/workflow/scenario-step-guards.js +0 -8
  208. package/dist/wirings/workflow/scenario-step.types.d.ts +27 -12
  209. package/dist/wirings/workflow/workflow-approval.js +2 -1
  210. package/dist/wirings/workflow/workflow-run-engine.types.d.ts +2 -1
  211. package/dist/wirings/workflow/workflow.types.d.ts +2 -1
  212. package/knowledge/decisions/index.md +2 -0
  213. package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +1 -1
  214. package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +1 -1
  215. package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-and-not-a-queued-job.md +2 -2
  216. package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +6 -6
  217. package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +1 -1
  218. package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +1 -1
  219. package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +1 -1
  220. package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +1 -1
  221. package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +1 -1
  222. package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +1 -1
  223. package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +1 -1
  224. package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +1 -1
  225. package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +1 -1
  226. package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +1 -1
  227. package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +4 -4
  228. package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +1 -1
  229. package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +3 -3
  230. package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +2 -2
  231. package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +2 -2
  232. package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +1 -1
  233. package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +1 -1
  234. package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +3 -3
  235. package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +1 -1
  236. package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +4 -4
  237. package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +1 -1
  238. package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +1 -1
  239. package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +1 -1
  240. package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +1 -1
  241. package/knowledge/decisions/internals/index.md +4 -2
  242. package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +1 -1
  243. package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +1 -1
  244. package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +1 -1
  245. package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +1 -1
  246. package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +1 -1
  247. package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +2 -2
  248. package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +5 -5
  249. package/knowledge/decisions/internals/the-actor-prompt-says-json-because-of-json-object-mode.md +1 -1
  250. package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +1 -1
  251. package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +43 -19
  252. package/knowledge/decisions/internals/the-persona-runtime-is-exported-from-the-persona-entry-point.md +1 -1
  253. package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +1 -1
  254. package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +3 -3
  255. package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +1 -1
  256. package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +1 -1
  257. package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +1 -1
  258. package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +1 -1
  259. package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +1 -1
  260. package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +1 -1
  261. package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +1 -1
  262. package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +1 -1
  263. package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +1 -1
  264. package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +9 -5
  265. package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +1 -1
  266. package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +2 -2
  267. package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +1 -1
  268. package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +1 -1
  269. package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +1 -1
  270. package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +2 -3
  271. package/knowledge/decisions/security/actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +1 -1
  272. package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +1 -1
  273. package/knowledge/decisions/security/agent-gate-requires-a-session-only-when-auth-is-true.md +1 -1
  274. package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +3 -3
  275. package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +4 -3
  276. package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +1 -1
  277. package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +2 -2
  278. package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +1 -1
  279. package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +2 -2
  280. package/knowledge/decisions/security/index.md +2 -0
  281. package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +1 -1
  282. package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +3 -3
  283. package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +1 -1
  284. package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +2 -2
  285. package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +1 -1
  286. package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +2 -2
  287. package/knowledge/index.md +3 -1
  288. package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +1 -1
  289. package/knowledge/questions/index.md +2 -0
  290. package/package.json +14 -13
  291. package/run-tests.sh +0 -0
  292. package/scripts/generate-api-report.d.mts +1 -1
  293. package/scripts/generate-api-report.mjs +67 -60
  294. package/scripts/generate-api-report.mts +11 -45
  295. package/src/api-report.test.ts +70 -1
  296. package/src/app-alias-surface.test.ts +179 -0
  297. package/src/app-leaf-surface.test.ts +217 -0
  298. package/src/bootstrap-compat/root.ts +20 -0
  299. package/src/{column-form.test.ts → classification/column-form.test.ts} +2 -2
  300. package/src/{data-classification.ts → classification/data-classification.ts} +1 -5
  301. package/src/classification/index.ts +38 -0
  302. package/src/{secret-value.test.ts → classification/secret-value.test.ts} +2 -2
  303. package/src/{secret-value.ts → classification/secret-value.ts} +1 -6
  304. package/src/crypto-utils.ts +1 -1
  305. package/src/dev/reload-meta.test.ts +1 -1
  306. package/src/errors/index.ts +9 -0
  307. package/src/errors/serialized-error.ts +9 -0
  308. package/src/factory-functions.test.ts +4 -2
  309. package/src/function/function-meta.types.ts +151 -0
  310. package/src/function/function-runner.test.ts +4 -2
  311. package/src/function/function-runner.ts +47 -14
  312. package/src/function/functions.types.ts +11 -7
  313. package/src/function/index.ts +24 -5
  314. package/src/function/list.types.ts +1 -3
  315. package/src/middleware/auth-apikey.ts +4 -2
  316. package/src/middleware/auth-bearer.test.ts +1 -1
  317. package/src/middleware/auth-bearer.ts +4 -2
  318. package/src/middleware/auth-cookie.ts +4 -1
  319. package/src/middleware/cors.test.ts +126 -5
  320. package/src/middleware/cors.ts +19 -8
  321. package/src/middleware/index.ts +16 -0
  322. package/src/middleware/middleware-factories.ts +62 -0
  323. package/src/middleware/middleware.types.ts +61 -0
  324. package/src/middleware/remote-auth.test.ts +1 -1
  325. package/src/middleware/remote-auth.ts +1 -1
  326. package/src/middleware/telemetry.ts +4 -2
  327. package/src/middleware-runner.test.ts +2 -3
  328. package/src/middleware-runner.ts +2 -2
  329. package/src/no-root-barrel.test.ts +114 -0
  330. package/src/permissions.ts +2 -4
  331. package/src/pikku-state.ts +3 -1
  332. package/src/public-surface.json +56 -241
  333. package/src/public-surface.json.README +3 -3
  334. package/src/public-surface.test.ts +5 -5
  335. package/src/remote.test.ts +1 -1
  336. package/src/removed-legacy-exports.test.ts +5 -1
  337. package/src/services/audit-service.ts +1 -1
  338. package/src/services/credential-wire-service.ts +1 -1
  339. package/src/services/email-service.ts +2 -4
  340. package/src/services/file-scenario-run-store.test.ts +349 -0
  341. package/src/services/file-scenario-run-store.ts +282 -0
  342. package/src/services/in-memory-workflow-service.ts +1 -1
  343. package/src/services/index.ts +13 -1
  344. package/src/services/local-content-request-handler.ts +1 -2
  345. package/src/services/local-secrets.ts +1 -1
  346. package/src/services/logger.ts +7 -7
  347. package/src/services/meta-service.ts +2 -2
  348. package/src/services/queue-webhook-service.test.ts +1 -1
  349. package/src/services/scoped-secret-service.ts +1 -1
  350. package/src/services/secret-service.ts +1 -1
  351. package/src/services/typed-secret-service.test.ts +52 -0
  352. package/src/services/typed-secret-service.ts +26 -2
  353. package/src/services/webhook-service.ts +1 -1
  354. package/src/services/workflow-service.ts +2 -1
  355. package/src/template-alias-surface.test.ts +240 -0
  356. package/src/testing/index.ts +1 -0
  357. package/src/types/core.types.ts +33 -285
  358. package/src/types/index.ts +2 -0
  359. package/src/types/state.types.ts +6 -5
  360. package/src/types/typed-credentials.test.ts +72 -0
  361. package/src/utils.ts +34 -0
  362. package/src/wirings/{rpc → addon}/addon-scopes.test.ts +1 -1
  363. package/src/wirings/addon/index.ts +12 -0
  364. package/src/wirings/{rpc → addon}/remote-addon-auth.ts +4 -1
  365. package/src/wirings/{rpc → addon}/wire-addon.ts +37 -2
  366. package/src/wirings/agent/agent-prepare.ts +8 -5
  367. package/src/wirings/agent/agent-runner.ts +2 -3
  368. package/src/wirings/agent/agent-stream.ts +2 -3
  369. package/src/wirings/agent/agent-utils.ts +19 -0
  370. package/src/wirings/agent/agent.types.ts +3 -3
  371. package/src/wirings/agent/index.ts +1 -0
  372. package/src/wirings/agent/voice-input.ts +1 -1
  373. package/src/wirings/agent/voice-output.test.ts +2 -4
  374. package/src/wirings/agent/voice-output.ts +1 -1
  375. package/src/wirings/agent-scorer/agent-scorer-judge.test.ts +145 -0
  376. package/src/wirings/agent-scorer/agent-scorer-judge.ts +60 -0
  377. package/src/wirings/agent-scorer/agent-scorer.ts +8 -0
  378. package/src/wirings/agent-scorer/agent-scorer.types.ts +21 -0
  379. package/src/wirings/agent-scorer/index.ts +1 -0
  380. package/src/wirings/channel/channel-common.ts +4 -2
  381. package/src/wirings/channel/channel-handler.ts +2 -5
  382. package/src/wirings/channel/channel-middleware-runner.ts +1 -1
  383. package/src/wirings/channel/channel-rpc.types.ts +1 -5
  384. package/src/wirings/channel/channel.types.ts +1 -2
  385. package/src/wirings/channel/local/local-channel-runner.test.ts +1 -2
  386. package/src/wirings/channel/serverless/index.ts +1 -0
  387. package/src/wirings/cli/channel/cli-raw-channel-runner.ts +2 -2
  388. package/src/wirings/cli/channel/index.ts +1 -3
  389. package/src/wirings/cli/cli-runner.test.ts +1 -1
  390. package/src/wirings/cli/cli-runner.ts +11 -7
  391. package/src/wirings/cli/cli.types.ts +24 -3
  392. package/src/wirings/cli/command-parser.test.ts +388 -1
  393. package/src/wirings/cli/command-parser.ts +189 -29
  394. package/src/wirings/gateway/gateway-runner.test.ts +1 -2
  395. package/src/wirings/gateway/gateway-runner.ts +3 -6
  396. package/src/wirings/gateway/gateway.types.ts +5 -4
  397. package/src/wirings/http/http-routes.test.ts +1 -2
  398. package/src/wirings/http/http-runner-addon-ref.test.ts +238 -0
  399. package/src/wirings/http/http-runner.test.ts +3 -8
  400. package/src/wirings/http/http-runner.ts +9 -3
  401. package/src/wirings/http/http.types.ts +3 -12
  402. package/src/wirings/http/index.ts +1 -0
  403. package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
  404. package/src/wirings/http/pikku-fetch-http-response.ts +3 -2
  405. package/src/wirings/mcp/mcp-runner.test.ts +1 -1
  406. package/src/wirings/mcp/mcp.types.ts +1 -2
  407. package/src/wirings/persona/index.ts +1 -4
  408. package/src/wirings/persona/persona.types.ts +14 -0
  409. package/src/wirings/queue/queue-identity.test.ts +1 -1
  410. package/src/wirings/queue/queue.types.ts +2 -6
  411. package/src/wirings/queue/signed-queue-service.ts +1 -1
  412. package/src/wirings/rpc/index.ts +0 -12
  413. package/src/wirings/rpc/rpc-runner.test.ts +4 -4
  414. package/src/wirings/rpc/rpc-runner.ts +3 -3
  415. package/src/wirings/scheduler/scheduler.types.ts +2 -5
  416. package/src/wirings/scope/index.ts +1 -0
  417. package/src/wirings/secret/secret.types.ts +10 -0
  418. package/src/wirings/secret/validate-secret-definitions.test.ts +23 -0
  419. package/src/wirings/secret/validate-secret-definitions.ts +2 -0
  420. package/src/wirings/variable/validate-variable-definitions.test.ts +23 -0
  421. package/src/wirings/variable/validate-variable-definitions.ts +2 -0
  422. package/src/wirings/variable/variable.types.ts +9 -0
  423. package/src/wirings/virtual-user/index.ts +1 -4
  424. package/src/wirings/virtual-user/prepare-virtual-user-run.ts +1 -1
  425. package/src/wirings/virtual-user/virtual-user-derive.test.ts +1 -1
  426. package/src/wirings/virtual-user/virtual-user-derive.ts +1 -1
  427. package/src/wirings/virtual-user/virtual-user.types.ts +1 -5
  428. package/src/wirings/workflow/graph/graph-foreach-queued.test.ts +569 -0
  429. package/src/wirings/workflow/graph/graph-foreach.test.ts +626 -0
  430. package/src/wirings/workflow/graph/graph-node.ts +16 -1
  431. package/src/wirings/workflow/graph/graph-runner.ts +387 -61
  432. package/src/wirings/workflow/graph/workflow-graph.types.ts +28 -3
  433. package/src/wirings/workflow/index.ts +8 -0
  434. package/src/wirings/workflow/pikku-scenario-service.ts +59 -19
  435. package/src/wirings/workflow/pikku-workflow-service.ts +6 -8
  436. package/src/wirings/workflow/run-timeline.ts +1 -1
  437. package/src/wirings/workflow/scenario-expectations.test.ts +28 -13
  438. package/src/wirings/workflow/scenario-run.types.ts +186 -0
  439. package/src/wirings/workflow/scenario-step-guards.ts +1 -14
  440. package/src/wirings/workflow/scenario-step.test.ts +32 -7
  441. package/src/wirings/workflow/scenario-step.types.ts +27 -12
  442. package/src/wirings/workflow/workflow-approval-policy.test.ts +117 -47
  443. package/src/wirings/workflow/workflow-approval.ts +2 -1
  444. package/src/wirings/workflow/workflow-run-engine.types.ts +2 -1
  445. package/src/wirings/workflow/workflow.types.ts +4 -12
  446. package/src/wirings-stay-decoupled.test.ts +6 -3
  447. package/tsconfig.tsbuildinfo +1 -1
  448. package/tsconfig.type-tests.json +3 -2
  449. package/dist/ecosystem/ai-agent.d.ts +0 -18
  450. package/dist/ecosystem/ai-agent.js +0 -6
  451. package/dist/ecosystem/ai-scorer.d.ts +0 -12
  452. package/dist/ecosystem/ai-scorer.js +0 -5
  453. package/dist/services/ai-agent-runner-service.d.ts +0 -220
  454. package/dist/services/ai-run-state-service.d.ts +0 -29
  455. package/dist/services/ai-storage-service.d.ts +0 -18
  456. package/dist/services/in-memory-ai-run-state-service.d.ts +0 -19
  457. package/dist/services/in-memory-ai-run-state-service.js +0 -54
  458. package/dist/testing/service-tests/ai-storage-service-tests.d.ts +0 -3
  459. package/dist/testing/service-tests/ai-storage-service-tests.js +0 -302
  460. package/dist/wirings/ai-agent/agent-rpc.d.ts +0 -15
  461. package/dist/wirings/ai-agent/agent-rpc.js +0 -53
  462. package/dist/wirings/ai-agent/ai-agent-agui.d.ts +0 -79
  463. package/dist/wirings/ai-agent/ai-agent-agui.js +0 -327
  464. package/dist/wirings/ai-agent/ai-agent-finalize.d.ts +0 -58
  465. package/dist/wirings/ai-agent/ai-agent-finalize.js +0 -138
  466. package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +0 -35
  467. package/dist/wirings/ai-agent/ai-agent-helpers.js +0 -47
  468. package/dist/wirings/ai-agent/ai-agent-interrupt.d.ts +0 -153
  469. package/dist/wirings/ai-agent/ai-agent-interrupt.js +0 -257
  470. package/dist/wirings/ai-agent/ai-agent-memory.d.ts +0 -42
  471. package/dist/wirings/ai-agent/ai-agent-memory.js +0 -333
  472. package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +0 -16
  473. package/dist/wirings/ai-agent/ai-agent-model-config.js +0 -51
  474. package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +0 -117
  475. package/dist/wirings/ai-agent/ai-agent-prepare.js +0 -728
  476. package/dist/wirings/ai-agent/ai-agent-registry.d.ts +0 -16
  477. package/dist/wirings/ai-agent/ai-agent-registry.js +0 -51
  478. package/dist/wirings/ai-agent/ai-agent-runner.d.ts +0 -7
  479. package/dist/wirings/ai-agent/ai-agent-runner.js +0 -580
  480. package/dist/wirings/ai-agent/ai-agent-stream.d.ts +0 -41
  481. package/dist/wirings/ai-agent/ai-agent-stream.js +0 -1029
  482. package/dist/wirings/ai-agent/ai-agent-turn.d.ts +0 -57
  483. package/dist/wirings/ai-agent/ai-agent-turn.js +0 -82
  484. package/dist/wirings/ai-agent/ai-agent-utils.d.ts +0 -1
  485. package/dist/wirings/ai-agent/ai-agent-utils.js +0 -1
  486. package/dist/wirings/ai-agent/ai-agent.types.d.ts +0 -625
  487. package/dist/wirings/ai-agent/index.d.ts +0 -12
  488. package/dist/wirings/ai-agent/index.js +0 -10
  489. package/dist/wirings/ai-agent/voice-input.d.ts +0 -69
  490. package/dist/wirings/ai-agent/voice-input.js +0 -150
  491. package/dist/wirings/ai-agent/voice-output.d.ts +0 -85
  492. package/dist/wirings/ai-agent/voice-output.js +0 -196
  493. package/dist/wirings/ai-scorer/ai-scorer-grade.d.ts +0 -26
  494. package/dist/wirings/ai-scorer/ai-scorer-grade.js +0 -33
  495. package/dist/wirings/ai-scorer/ai-scorer-judge.d.ts +0 -17
  496. package/dist/wirings/ai-scorer/ai-scorer-judge.js +0 -92
  497. package/dist/wirings/ai-scorer/ai-scorer-live.d.ts +0 -15
  498. package/dist/wirings/ai-scorer/ai-scorer-live.js +0 -38
  499. package/dist/wirings/ai-scorer/ai-scorer-registry.d.ts +0 -18
  500. package/dist/wirings/ai-scorer/ai-scorer-registry.js +0 -46
  501. package/dist/wirings/ai-scorer/ai-scorer-sampling.d.ts +0 -8
  502. package/dist/wirings/ai-scorer/ai-scorer-sampling.js +0 -31
  503. package/dist/wirings/ai-scorer/ai-scorer-snapshots.d.ts +0 -10
  504. package/dist/wirings/ai-scorer/ai-scorer-snapshots.js +0 -40
  505. package/dist/wirings/ai-scorer/ai-scorer-worker.d.ts +0 -15
  506. package/dist/wirings/ai-scorer/ai-scorer-worker.js +0 -58
  507. package/dist/wirings/ai-scorer/ai-scorer.d.ts +0 -39
  508. package/dist/wirings/ai-scorer/ai-scorer.js +0 -40
  509. package/dist/wirings/ai-scorer/ai-scorer.types.d.ts +0 -90
  510. package/dist/wirings/ai-scorer/ai-scorer.types.js +0 -4
  511. package/dist/wirings/ai-scorer/index.d.ts +0 -6
  512. package/dist/wirings/ai-scorer/index.js +0 -5
  513. package/src/ecosystem/agent-scorer.ts +0 -24
  514. package/src/ecosystem/agent.ts +0 -42
  515. package/src/ecosystem/channel/local.ts +0 -1
  516. package/src/ecosystem/channel.ts +0 -22
  517. package/src/ecosystem/cli/channel.ts +0 -25
  518. package/src/ecosystem/cli.ts +0 -21
  519. package/src/ecosystem/credential.ts +0 -10
  520. package/src/ecosystem/dev.ts +0 -12
  521. package/src/ecosystem/function.ts +0 -28
  522. package/src/ecosystem/gateway.ts +0 -4
  523. package/src/ecosystem/hmac.ts +0 -1
  524. package/src/ecosystem/http.ts +0 -22
  525. package/src/ecosystem/mcp.ts +0 -17
  526. package/src/ecosystem/middleware.ts +0 -27
  527. package/src/ecosystem/node-host-resolver.ts +0 -1
  528. package/src/ecosystem/node.ts +0 -5
  529. package/src/ecosystem/oauth2.ts +0 -4
  530. package/src/ecosystem/persona.ts +0 -30
  531. package/src/ecosystem/queue.ts +0 -23
  532. package/src/ecosystem/remote.ts +0 -9
  533. package/src/ecosystem/role.ts +0 -13
  534. package/src/ecosystem/rpc.ts +0 -7
  535. package/src/ecosystem/safe-fetch.ts +0 -8
  536. package/src/ecosystem/scenario.ts +0 -32
  537. package/src/ecosystem/scheduler.ts +0 -5
  538. package/src/ecosystem/schema.ts +0 -1
  539. package/src/ecosystem/scope.ts +0 -14
  540. package/src/ecosystem/secret.ts +0 -15
  541. package/src/ecosystem/services/istanbul-coverage.ts +0 -1
  542. package/src/ecosystem/services/local-content-request-handler.ts +0 -16
  543. package/src/ecosystem/services/local-content.ts +0 -1
  544. package/src/ecosystem/services/v8-coverage.ts +0 -1
  545. package/src/ecosystem/services.ts +0 -82
  546. package/src/ecosystem/trigger.ts +0 -7
  547. package/src/ecosystem/types.ts +0 -34
  548. package/src/ecosystem/variable.ts +0 -14
  549. package/src/ecosystem/virtual-user.ts +0 -48
  550. package/src/ecosystem/workflow.ts +0 -68
  551. package/src/ecosystem.ts +0 -40
  552. package/src/index.ts +0 -244
  553. /package/dist/{services/ai-agent-runner-service.js → bootstrap-compat/root.js} +0 -0
  554. /package/dist/{services/ai-run-state-service.js → classification/data-classification.js} +0 -0
  555. /package/dist/{services/ai-storage-service.js → errors/serialized-error.js} +0 -0
  556. /package/dist/{wirings/ai-agent/ai-agent.types.js → function/function-meta.types.js} +0 -0
  557. /package/src/{column-form.ts → classification/column-form.ts} +0 -0
  558. /package/src/{pikku-request.test.ts → function/pikku-request.test.ts} +0 -0
  559. /package/src/{pikku-request.ts → function/pikku-request.ts} +0 -0
  560. /package/src/wirings/{rpc → addon}/addon-auth-tags.test.ts +0 -0
  561. /package/src/wirings/{rpc → addon}/addon-runner.ts +0 -0
  562. /package/src/wirings/{rpc → addon}/addon-secrets.test.ts +0 -0
  563. /package/src/wirings/{rpc → addon}/wire-addon.test.ts +0 -0
  564. /package/src/wirings/{rpc → addon}/wire-remote-addon.ts +0 -0
@@ -14,7 +14,7 @@ import { finalizeAgentRun, lastUserMessageText } from './agent-finalize.js'
14
14
  import { pikkuState, getSingletonServices } from '../../pikku-state.js'
15
15
  import { applyInputMiddleware } from './agent-turn.js'
16
16
  import { AIProviderNotConfiguredError } from '../../errors/errors.js'
17
- import { randomUUID } from './agent-utils.js'
17
+ import { deniedToolResult, randomUUID } from './agent-utils.js'
18
18
  import { SPOKEN_TRANSCRIPT } from './voice-input.js'
19
19
  import {
20
20
  combineChannelMiddleware,
@@ -1099,8 +1099,7 @@ export async function resumeAgent(
1099
1099
  await agentRunState.updateRun(pending.agentRunId, { status: 'failed' })
1100
1100
  }
1101
1101
 
1102
- const denialResult =
1103
- 'The user explicitly declined this action. Inform them that it was declined and do not retry.'
1102
+ const denialResult = deniedToolResult()
1104
1103
 
1105
1104
  if (storage) {
1106
1105
  await storage.saveMessages(run.threadId, [
@@ -1 +1,20 @@
1
1
  export const randomUUID = (): string => globalThis.crypto.randomUUID()
2
+
3
+ /**
4
+ * The tool result stored and streamed when a user denies an approval.
5
+ *
6
+ * Two readers, one string. The model needs the sentence — it has to tell the
7
+ * user the action was declined and not retry it. A client needs to know a
8
+ * denial when it sees one, so it can render the call as denied rather than as
9
+ * a successful call that happened to return prose; that is what `approved`
10
+ * carries, and it is the same flag a client sets optimistically the moment the
11
+ * deny button is clicked. Emitting only the sentence made the two disagree:
12
+ * live the call showed denied, and on any re-render from storage the same call
13
+ * came back green.
14
+ */
15
+ export const deniedToolResult = (): string =>
16
+ JSON.stringify({
17
+ approved: false,
18
+ message:
19
+ 'The user explicitly declined this action. Inform them that it was declined and do not retry.',
20
+ })
@@ -5,8 +5,8 @@ import type {
5
5
  import type {
6
6
  CorePikkuMiddleware,
7
7
  MiddlewareMetadata,
8
- PermissionMetadata,
9
- } from '../../types/core.types.js'
8
+ } from '../../middleware/middleware.types.js'
9
+ import type { PermissionMetadata } from '../../function/function-meta.types.js'
10
10
  import type { AIProviderOptions } from '../../services/agent-runner-service.js'
11
11
  import type { PikkuChannel } from '../channel/channel.types.js'
12
12
  import type { CorePikkuChannelMiddleware } from '../channel/channel.types.js'
@@ -423,7 +423,7 @@ export type CoreAgent<
423
423
  * which OR together, a scope can only narrow access.
424
424
  *
425
425
  * Narrowed to the generated `ScopeId` union in a project's own
426
- * `pikku-types.gen.ts`, so an undeclared scope is a compile error.
426
+ * `#pikku/scopes`, so an undeclared scope is a compile error.
427
427
  */
428
428
  scopes?: Scope[]
429
429
  permissions?: CorePermissionGroup<PikkuPermission>
@@ -20,6 +20,7 @@ export {
20
20
  unspeakableScripts,
21
21
  voiceForText,
22
22
  type SpeakableScripts,
23
+ type VoiceOutputState,
23
24
  } from './voice-output.js'
24
25
  export { AgentInterruptedError, signalRunInterrupt } from './agent-interrupt.js'
25
26
  export type {
@@ -1,5 +1,5 @@
1
1
  import type { AgentRunnerService } from '../../services/agent-runner-service.js'
2
- import { pikkuAgentMiddleware } from '../../types/core.types.js'
2
+ import { pikkuAgentMiddleware } from '../../middleware/middleware-factories.js'
3
3
  import { safeFetch } from '../../utils/safe-fetch.js'
4
4
  import type { AgentContentPart } from './agent.types.js'
5
5
 
@@ -233,8 +233,7 @@ describe('voiceOutput', () => {
233
233
 
234
234
  assert.deepEqual(asked, [], 'nothing should have been sent for synthesis')
235
235
  const notice = stream.out.find((event) => event.type === 'data') as
236
- | { name: string; data: { scripts: string[] } }
237
- | undefined
236
+ { name: string; data: { scripts: string[] } } | undefined
238
237
  assert.equal(notice?.name, 'voice-unsupported')
239
238
  assert.deepEqual(notice?.data.scripts, ['arabic'])
240
239
  })
@@ -424,8 +423,7 @@ describe('voiceOutput', () => {
424
423
 
425
424
  assert.deepEqual(asked, [])
426
425
  const notice = stream.out.find((event) => event.type === 'data') as
427
- | { name: string; data: { scripts: string[] } }
428
- | undefined
426
+ { name: string; data: { scripts: string[] } } | undefined
429
427
  assert.deepEqual(notice?.data.scripts, ['arabic'])
430
428
  })
431
429
 
@@ -1,5 +1,5 @@
1
1
  import type { AgentRunnerService } from '../../services/agent-runner-service.js'
2
- import { pikkuAgentMiddleware } from '../../types/core.types.js'
2
+ import { pikkuAgentMiddleware } from '../../middleware/middleware-factories.js'
3
3
  import { SPOKEN_TURN } from './voice-input.js'
4
4
 
5
5
  export type VoiceOutputState = {
@@ -55,6 +55,151 @@ describe('buildJudgePrompt', () => {
55
55
  assert.match(prompt, /Grade helpfulness\./)
56
56
  })
57
57
 
58
+ test('shows which tools ran, so an answer is distinguishable from a guess', () => {
59
+ const scorer = pikkuAgentJudge({
60
+ name: 'helpfulness',
61
+ description: 'Is the answer useful',
62
+ model: 'claude-opus-5',
63
+ goal: 'Grade helpfulness.',
64
+ })
65
+
66
+ const prompt = buildJudgePrompt(
67
+ scorer.judge!,
68
+ input({
69
+ toolCalls: [
70
+ { name: 'listTodos', args: {}, result: { todos: ['Buy groceries'] } },
71
+ ],
72
+ })
73
+ )
74
+
75
+ assert.match(prompt, /Tools the assistant ran:\n- listTodos/)
76
+ })
77
+
78
+ test('the default disclosure sends the judge no arguments and no results', () => {
79
+ const scorer = pikkuAgentJudge({
80
+ name: 'helpfulness',
81
+ description: 'Is the answer useful',
82
+ model: 'claude-opus-5',
83
+ goal: 'Grade helpfulness.',
84
+ })
85
+
86
+ const prompt = buildJudgePrompt(
87
+ scorer.judge!,
88
+ input({
89
+ toolCalls: [
90
+ {
91
+ name: 'lookupCustomer',
92
+ args: { email: 'ada@example.com' },
93
+ result: { address: '12 Mill Lane' },
94
+ },
95
+ ],
96
+ })
97
+ )
98
+
99
+ assert.doesNotMatch(prompt, /ada@example\.com/)
100
+ assert.doesNotMatch(prompt, /Mill Lane/)
101
+ })
102
+
103
+ test('a run that called nothing gets no tool section rather than an empty one', () => {
104
+ const scorer = pikkuAgentJudge({
105
+ name: 'helpfulness',
106
+ description: 'Is the answer useful',
107
+ model: 'claude-opus-5',
108
+ goal: 'Grade helpfulness.',
109
+ })
110
+
111
+ assert.doesNotMatch(buildJudgePrompt(scorer.judge!, input()), /Tools the/)
112
+ })
113
+
114
+ test('a failed call is shown as failed, which is not the same as no call', () => {
115
+ const scorer = pikkuAgentJudge({
116
+ name: 'helpfulness',
117
+ description: 'Is the answer useful',
118
+ model: 'claude-opus-5',
119
+ goal: 'Grade helpfulness.',
120
+ })
121
+
122
+ const prompt = buildJudgePrompt(
123
+ scorer.judge!,
124
+ input({
125
+ toolCalls: [
126
+ {
127
+ name: 'listTodos',
128
+ args: {},
129
+ error: 'no such user ada@example.com',
130
+ },
131
+ ],
132
+ })
133
+ )
134
+
135
+ assert.match(prompt, /- listTodos \(failed\)/)
136
+ assert.doesNotMatch(prompt, /ada@example\.com/)
137
+ })
138
+
139
+ test("'full' shows the arguments and results, for a judge that grades against them", () => {
140
+ const scorer = pikkuAgentJudge({
141
+ name: 'helpfulness',
142
+ description: 'Is the answer useful',
143
+ model: 'claude-opus-5',
144
+ goal: 'Grade helpfulness.',
145
+ toolCalls: 'full',
146
+ })
147
+
148
+ const prompt = buildJudgePrompt(
149
+ scorer.judge!,
150
+ input({
151
+ toolCalls: [
152
+ { name: 'listTodos', args: {}, result: { todos: ['Buy groceries'] } },
153
+ { name: 'save', args: {}, error: 'store unreachable' },
154
+ ],
155
+ })
156
+ )
157
+
158
+ assert.match(
159
+ prompt,
160
+ /listTodos\(\{\}\) returned \{"todos":\["Buy groceries"\]\}/
161
+ )
162
+ assert.match(prompt, /save\(\{\}\) failed: store unreachable/)
163
+ })
164
+
165
+ test("'off' withholds the trajectory entirely, even from a run that used tools", () => {
166
+ const scorer = pikkuAgentJudge({
167
+ name: 'helpfulness',
168
+ description: 'Is the answer useful',
169
+ model: 'claude-opus-5',
170
+ goal: 'Grade helpfulness.',
171
+ toolCalls: 'off',
172
+ })
173
+
174
+ const prompt = buildJudgePrompt(
175
+ scorer.judge!,
176
+ input({ toolCalls: [{ name: 'listTodos', args: {}, result: {} }] })
177
+ )
178
+
179
+ assert.doesNotMatch(prompt, /Tools the/)
180
+ assert.doesNotMatch(prompt, /listTodos/)
181
+ })
182
+
183
+ test('a large tool result is truncated rather than crowding out the answer', () => {
184
+ const scorer = pikkuAgentJudge({
185
+ name: 'helpfulness',
186
+ description: 'Is the answer useful',
187
+ model: 'claude-opus-5',
188
+ goal: 'Grade helpfulness.',
189
+ toolCalls: 'full',
190
+ })
191
+
192
+ const prompt = buildJudgePrompt(
193
+ scorer.judge!,
194
+ input({
195
+ toolCalls: [{ name: 'search', args: {}, result: 'x'.repeat(5000) }],
196
+ })
197
+ )
198
+
199
+ assert.match(prompt, /… \(truncated\)/)
200
+ assert.ok(prompt.length < 1500, `prompt was ${prompt.length} characters`)
201
+ })
202
+
58
203
  test('a scorer that supplies its own prompt replaces the framing entirely', () => {
59
204
  const scorer = pikkuAgentJudge({
60
205
  name: 'custom',
@@ -26,11 +26,64 @@ const JUDGE_OUTPUT_SCHEMA = {
26
26
  additionalProperties: false,
27
27
  }
28
28
 
29
+ /**
30
+ * The default disclosure: which tools ran and which failed, and nothing about
31
+ * what went in or came back. A judge that can see a run reached `listTodos`
32
+ * can tell a retrieved list from an invented one, which is the whole of what
33
+ * the trajectory is needed for — the rows themselves it does not need, and an
34
+ * error string is a tool's own words about the caller's data, so it is
35
+ * summarised rather than quoted.
36
+ */
37
+ const describeToolCallName = (call: ScorerInput['toolCalls'][number]): string =>
38
+ `- ${call.name}${call.error ? ' (failed)' : ''}`
39
+
40
+ /** Everything about a call, for a judge that grades against what came back. */
41
+ const describeToolCall = (call: ScorerInput['toolCalls'][number]): string => {
42
+ const outcome = call.error
43
+ ? `failed: ${call.error}`
44
+ : `returned ${formatToolValue(call.result)}`
45
+ return `- ${call.name}(${formatToolValue(call.args)}) ${outcome}`
46
+ }
47
+
48
+ /**
49
+ * A tool's arguments and result are arbitrary JSON, and some of it is large —
50
+ * a listing, a document, a page of search results. Truncating keeps a single
51
+ * fat call from crowding the answer out of the judge's context; what survives
52
+ * is the head, which is where the shape of a value is.
53
+ */
54
+ const TOOL_VALUE_LIMIT = 500
55
+
56
+ const formatToolValue = (value: unknown): string => {
57
+ if (value === undefined) {
58
+ return 'nothing'
59
+ }
60
+ const text = typeof value === 'string' ? value : JSON.stringify(value)
61
+ if (text === undefined) {
62
+ return 'nothing'
63
+ }
64
+ return text.length > TOOL_VALUE_LIMIT
65
+ ? `${text.slice(0, TOOL_VALUE_LIMIT)}… (truncated)`
66
+ : text
67
+ }
68
+
29
69
  /**
30
70
  * The message a judge grades when its scorer supplies no `prompt`.
31
71
  *
32
72
  * A reference-based judge is shown the answer key; a reference-free one is not,
33
73
  * and grades the answer on its own merits.
74
+ *
75
+ * The tool calls are shown because without them a judge cannot tell a fact from
76
+ * a fabrication. Grading a todo agent that had just listed the user's todos
77
+ * correctly, a judge given only the answer called it "a plausible-looking list"
78
+ * that "offers no real access to your actual list, making it effectively a
79
+ * guess", and scored 0.2 what it scored 1 on other runs — right by its rubric,
80
+ * on the evidence it was given, and wrong about the run. An agent that answers
81
+ * from a tool and one that invents the same sentence are indistinguishable in
82
+ * the output alone; they differ only in what the run did to get there.
83
+ *
84
+ * How much of that to show is `judge.toolCalls`, and the default stops at the
85
+ * names: the 0.2 was the judge doubting the run had any access, and a name
86
+ * settles that without handing a third-party model the rows.
34
87
  */
35
88
  export const buildJudgePrompt = (
36
89
  judge: ScorerJudgeConfig,
@@ -43,6 +96,13 @@ export const buildJudgePrompt = (
43
96
  sections.push(`Reference answer:\n${input.reference}`)
44
97
  }
45
98
  sections.push(`Assistant answered:\n${input.output}`)
99
+ if (judge.toolCalls !== 'off' && input.toolCalls.length > 0) {
100
+ const describe =
101
+ judge.toolCalls === 'full' ? describeToolCall : describeToolCallName
102
+ sections.push(
103
+ `Tools the assistant ran:\n${input.toolCalls.map(describe).join('\n')}`
104
+ )
105
+ }
46
106
  sections.push(judge.goal)
47
107
  sections.push('Respond with a score 0..1 and a brief reason.')
48
108
  return sections.join('\n\n')
@@ -1,4 +1,5 @@
1
1
  import type {
2
+ JudgeToolCallDisclosure,
2
3
  PikkuAgentScorer,
3
4
  ScorerInput,
4
5
  ScorerOutput,
@@ -61,6 +62,12 @@ export const pikkuAgentJudge = <Services = any>(config: {
61
62
  requiresReference?: boolean
62
63
  model: string
63
64
  goal: string
65
+ /**
66
+ * How much of the run's trajectory to disclose to the judge. Defaults to
67
+ * `names`: enough to tell a tool-backed answer from an invented one, without
68
+ * sending a third-party model the rows the tools returned.
69
+ */
70
+ toolCalls?: JudgeToolCallDisclosure
64
71
  prompt?: (input: ScorerInput) => string
65
72
  }): PikkuAgentScorer<Services> => ({
66
73
  name: config.name,
@@ -71,6 +78,7 @@ export const pikkuAgentJudge = <Services = any>(config: {
71
78
  judge: {
72
79
  model: config.model,
73
80
  goal: config.goal,
81
+ toolCalls: config.toolCalls ?? 'names',
74
82
  ...(config.prompt ? { prompt: config.prompt } : {}),
75
83
  },
76
84
  })
@@ -50,6 +50,25 @@ export const SCORER_LANE_QUEUES: Record<ScorerLane, string> = {
50
50
  slow: 'agent-score-slow',
51
51
  }
52
52
 
53
+ /**
54
+ * How much of the run's trajectory the default judge prompt discloses.
55
+ *
56
+ * A judge is a third-party model, and a tool's arguments and results are the
57
+ * most sensitive thing a run touches — the row it read, the address it looked
58
+ * up, the message it sent. Output middleware has already had its pass by the
59
+ * time a scorer sees any of this, so what a judge is shown is what was stored;
60
+ * this is the second gate, for a judge that should be told less than the
61
+ * database was.
62
+ *
63
+ * - `names` — which tools ran, and whether each failed. No arguments, no
64
+ * results. Enough to tell an answer backed by a tool from an invented one,
65
+ * which is the failure this exists to catch, while disclosing no row data.
66
+ * - `full` — names, arguments and results, truncated. For a judge that must
67
+ * check the answer *against* what the tool returned.
68
+ * - `off` — no trajectory at all. The judge grades the answer alone.
69
+ */
70
+ export type JudgeToolCallDisclosure = 'off' | 'names' | 'full'
71
+
53
72
  /**
54
73
  * A judge's model call. Present only on a scorer built with `pikkuAgentJudge`;
55
74
  * `score` is present only on one built with `pikkuAgentScorer`. Exactly one of the
@@ -58,6 +77,8 @@ export const SCORER_LANE_QUEUES: Record<ScorerLane, string> = {
58
77
  export type ScorerJudgeConfig = {
59
78
  model: string
60
79
  goal: string
80
+ /** Always set: `pikkuAgentJudge` resolves the default. */
81
+ toolCalls: JudgeToolCallDisclosure
61
82
  prompt?: (input: ScorerInput) => string
62
83
  }
63
84
 
@@ -12,6 +12,7 @@ export {
12
12
  export { wireAgentScorerQueueWorkers } from './agent-scorer-worker.js'
13
13
  export type {
14
14
  AgentRunScore,
15
+ JudgeToolCallDisclosure,
15
16
  PikkuAgentScorer,
16
17
  ScoreJob,
17
18
  ScorerInput,
@@ -1,11 +1,13 @@
1
1
  import type { CorePikkuChannelMiddleware } from './channel.types.js'
2
2
  import type {
3
3
  CoreSingletonServices,
4
- CorePikkuMiddleware,
5
4
  PikkuRawWire,
6
5
  PikkuWire,
7
- MiddlewareMetadata,
8
6
  } from '../../types/core.types.js'
7
+ import type {
8
+ CorePikkuMiddleware,
9
+ MiddlewareMetadata,
10
+ } from '../../middleware/middleware.types.js'
9
11
  import type { CoreChannel, ChannelMessageMeta } from './channel.types.js'
10
12
  import { combineMiddleware, runMiddleware } from '../../middleware-runner.js'
11
13
  import { runPikkuFunc } from '../../function/function-runner.js'
@@ -1,8 +1,5 @@
1
- import type {
2
- CoreServices,
3
- JSONValue,
4
- CoreUserSession,
5
- } from '../../types/core.types.js'
1
+ import type { CoreServices, CoreUserSession } from '../../types/core.types.js'
2
+ import type { JSONValue } from '../../utils.js'
6
3
  import type {
7
4
  CorePikkuChannelMiddleware,
8
5
  BinaryData,
@@ -1,8 +1,8 @@
1
1
  import type {
2
2
  CoreSingletonServices,
3
- MiddlewareMetadata,
4
3
  PikkuRawWire,
5
4
  } from '../../types/core.types.js'
5
+ import type { MiddlewareMetadata } from '../../middleware/middleware.types.js'
6
6
  import type { CorePikkuChannelMiddleware } from './channel.types.js'
7
7
  import { pikkuState } from '../../pikku-state.js'
8
8
  import { freezeDedupe, getTagGroups } from '../../utils.js'
@@ -77,11 +77,7 @@ export class ChannelRPCError extends Error {
77
77
  constructor(
78
78
  message: string,
79
79
  public readonly reason:
80
- | 'timeout'
81
- | 'closed'
82
- | 'remote'
83
- | 'invalid'
84
- | 'unsupported'
80
+ 'timeout' | 'closed' | 'remote' | 'invalid' | 'unsupported'
85
81
  ) {
86
82
  super(message)
87
83
  this.name = 'ChannelRPCError'
@@ -6,8 +6,7 @@ import type {
6
6
  import type {
7
7
  CorePikkuMiddleware,
8
8
  MiddlewareMetadata,
9
- } from '../../types/core.types.js'
10
-
9
+ } from '../../middleware/middleware.types.js'
11
10
  export type BinaryData = ArrayBuffer | Uint8Array
12
11
 
13
12
  export type CorePikkuChannelMiddleware<Services = any, Event = unknown> = (
@@ -13,8 +13,7 @@ import type {
13
13
  } from '../../http/http.types.js'
14
14
  import type { SerializeOptions } from 'cookie'
15
15
  import { httpRouter } from '../../http/routers/http-router.js'
16
- import { pikkuMiddleware } from '../../../types/core.types.js'
17
-
16
+ import { pikkuMiddleware } from '../../../middleware/middleware-factories.js'
18
17
  const mockLogger = {
19
18
  info: () => {},
20
19
  error: () => {},
@@ -3,3 +3,4 @@ export {
3
3
  runChannelDisconnect,
4
4
  runChannelMessage,
5
5
  } from './serverless-channel-runner.js'
6
+ export type { RunServerlessChannelParams } from './serverless-channel-runner.js'
@@ -99,8 +99,8 @@ export async function handleRawCLI({
99
99
  }
100
100
 
101
101
  let current:
102
- | { pikkuFuncId?: string; subcommands?: Record<string, any> }
103
- | undefined = programMeta.commands[parsed.commandPath[0]]
102
+ { pikkuFuncId?: string; subcommands?: Record<string, any> } | undefined =
103
+ programMeta.commands[parsed.commandPath[0]]
104
104
  for (let i = 1; i < parsed.commandPath.length; i++) {
105
105
  current = current?.subcommands?.[parsed.commandPath[i]]
106
106
  }
@@ -2,7 +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 {
6
- CorePikkuCLIClientRender,
7
- } from './cli-raw-client-runner.js'
5
+ export type { CorePikkuCLIClientRender } from './cli-raw-client-runner.js'
8
6
  export type { ApprovalMode } from './cli-approval.js'
@@ -1,7 +1,7 @@
1
1
  import { test, describe, beforeEach, afterEach } from 'node:test'
2
2
  import * as assert from 'assert'
3
3
  import { NotFoundError } from '../../errors/errors.js'
4
- import type { CorePikkuMiddleware } from '../../types/core.types.js'
4
+ import type { CorePikkuMiddleware } from '../../middleware/middleware.types.js'
5
5
  import {
6
6
  CLIError,
7
7
  executeCLI,
@@ -2,10 +2,8 @@ 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 type {
6
- CorePikkuMiddleware,
7
- CoreUserSession,
8
- } from '../../types/core.types.js'
5
+ import type { CoreUserSession } from '../../types/core.types.js'
6
+ import type { CorePikkuMiddleware } from '../../middleware/middleware.types.js'
9
7
  import type {
10
8
  CoreCLI,
11
9
  CLICommandMeta,
@@ -449,8 +447,7 @@ export async function executeCLI({
449
447
 
450
448
  try {
451
449
  const allCLIMeta = pikkuState(null, 'cli', 'meta') as unknown as
452
- | CLIMeta
453
- | undefined
450
+ CLIMeta | undefined
454
451
  if (!allCLIMeta) {
455
452
  throw new Error(
456
453
  '[PKU342] CLI metadata not found. No CLI wirings were registered. See https://pikku.dev/docs/pikku-cli/errors/pku342 for more information.'
@@ -509,8 +506,15 @@ export async function executeCLI({
509
506
 
510
507
  const data = { ...parsed.positionals, ...parsed.options }
511
508
 
509
+ // The command path is passed through so a config factory can tell which
510
+ // command is about to run. Some commands are meant to work outside a
511
+ // project, and cannot be gated behind loading that project's config.
512
512
  const config = createConfig
513
- ? await createConfig(new LocalVariablesService(), data)
513
+ ? await createConfig(
514
+ new LocalVariablesService(),
515
+ data,
516
+ parsed.commandPath
517
+ )
514
518
  : ({} as CoreConfig)
515
519
 
516
520
  const singletonServices = await createSingletonServices(config)
@@ -1,10 +1,12 @@
1
1
  import type {
2
- CorePikkuMiddleware,
3
2
  CoreSingletonServices,
4
3
  CoreUserSession,
5
4
  CoreServices,
6
- MiddlewareMetadata,
7
5
  } from '../../types/core.types.js'
6
+ import type {
7
+ CorePikkuMiddleware,
8
+ MiddlewareMetadata,
9
+ } from '../../middleware/middleware.types.js'
8
10
  import type {
9
11
  CorePikkuFunctionConfig,
10
12
  CorePikkuPermission,
@@ -13,15 +15,27 @@ import type {
13
15
  } from '../../function/functions.types.js'
14
16
  import type { ChannelRemote, PikkuChannel } from '../channel/channel.types.js'
15
17
 
18
+ /**
19
+ * The shape an option's value is parsed into. `'string[]'` splits a single
20
+ * value on commas; `'boolean'` is a flag that consumes the next token only
21
+ * when it is an explicit literal (`true`/`false`/`1`/`0`/`yes`/`no`); every
22
+ * other type consumes one token verbatim, so a value may start with `-`. Left
23
+ * unset — which is the usual case — it is read from the command function's
24
+ * input schema, then from `default`, and otherwise falls back to `'string'`.
25
+ * Declare it only where neither can say: an option belonging to no function
26
+ * input, such as one the config factory reads straight off the CLI data.
27
+ */
28
+ export type CLIOptionType = 'string' | 'number' | 'boolean' | 'string[]'
29
+
16
30
  /**
17
31
  * CLI option definition
18
32
  */
19
33
  export interface CLIOption<T = any> {
20
34
  description: string
21
35
  short?: string
36
+ type?: CLIOptionType
22
37
  default?: T
23
38
  choices?: T[]
24
- array?: boolean
25
39
  required?: boolean
26
40
  }
27
41
 
@@ -222,7 +236,14 @@ export type CoreCLICommandConfig<
222
236
  [K in keyof ExtractFunctionInput<FuncConfig>]?: {
223
237
  description?: string
224
238
  short?: string
239
+ type?: CLIOptionType
225
240
  default?: ExtractFunctionInput<FuncConfig>[K]
241
+ /**
242
+ * The values this option accepts. Rejected by the parser and listed in
243
+ * `--help`, so a flag with a fixed vocabulary says so once rather than
244
+ * repeating itself in its description.
245
+ */
246
+ choices?: ReadonlyArray<ExtractFunctionInput<FuncConfig>[K]>
226
247
  }
227
248
  }
228
249
  middleware?: PikkuMiddleware[]