@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
package/CHANGELOG.md CHANGED
@@ -1,3 +1,427 @@
1
+ ## 0.12.86
2
+
3
+ ### Patch Changes
4
+
5
+ - 5a1a962: cors: stop naming the first allowlist entry for a disallowed origin, and add jsonb binding helpers
6
+
7
+ `cors()` with an array `origin` used to fall back to `origin[0]` whenever the
8
+ request origin was not in the allowlist, so every response carried a
9
+ valid-looking `Access-Control-Allow-Origin` naming an origin the caller was not.
10
+ Browsers still blocked the request, but as an origin _mismatch_ rather than
11
+ "origin not allowed", and `curl` showed the same fixed origin for every request
12
+ including bogus ones — which sent people debugging the wrong layer. A request
13
+ origin that is not on the list now gets no `Access-Control-Allow-Origin` and no
14
+ `Access-Control-Allow-Credentials` at all, plus a debug-level log naming the
15
+ rejected origin. A request with no `Origin` header is not a cross-origin request
16
+ and likewise no longer receives a fabricated one. Wildcard and single-string
17
+ `origin` behaviour is unchanged.
18
+
19
+ `@pikku/kysely-postgres` now exports `jsonbText`, `jsonbValue` and `jsonbMerge`.
20
+ postgres.js infers a bound parameter's type from the cast that follows it and
21
+ JSON-encodes anything it believes is jsonb, so a hand-written
22
+ ``sql`coalesce(...) || ${JSON.stringify(patch)}::jsonb` `` arrives
23
+ double-encoded and merges into a two-element array instead of an object. The
24
+ helpers route the value through an intermediate `::text` cast, which is correct
25
+ on every driver.
26
+
27
+ ## 0.12.85
28
+
29
+ ### Patch Changes
30
+
31
+ - 7722ceb: Split the addon leaf so an application cannot shadow a linked addon's own
32
+
33
+ An addon authored its services through `#pikku/addon`, and so did an
34
+ application installing one. Node keeps those apart — `#pikku/*` is a
35
+ package-private subpath import, resolved against the addon's own
36
+ `package.json` — but tsconfig `paths` are global to a tsx process, and every
37
+ runtime template maps `#pikku/*` onto a sibling package. A linked addon's
38
+ `#pikku/addon` was resolved against the _application's_ leaf, which holds the
39
+ install half and none of the authoring exports, and every template failed to
40
+ boot with `does not provide an export named 'pikkuAddonServices'`.
41
+
42
+ The authoring half now sits at `#pikku/addon/setup`. An application generates a
43
+ flat `.pikku/<leaf>`, so there is nothing there for that specifier to match and
44
+ the resolver falls back to Node, which reads the addon's own imports. Addons
45
+ declaring themselves import `pikkuAddonConfig`, `pikkuAddonServices` and
46
+ `pikkuAddonWireServices` from `#pikku/addon/setup`; `wireAddon` and
47
+ `wireRemoteAddon` stay at `#pikku/addon`.
48
+
49
+ `wireAddon` and `wireRemoteAddon` also move off `@pikku/core/rpc` onto
50
+ `@pikku/core/addon`. Being reached over rpc is how an addon is called rather
51
+ than what it is, and it put the whole addon surface behind the rpc subpath for
52
+ consumers that only wanted to install one.
53
+
54
+ - 375c1ff: A `ref()`-wired addon route now reads the function's schemas, services and permissions from the addon's package rather than the consuming app's.
55
+
56
+ Resolving a namespaced target by namespace re-pointed the function's config and metadata into the addon's package state but left every other package-scoped lookup on the wire's package. The addon registers `SignDataInput` under its own package, so the runner looked it up under `main`, and the route answered 500 for every input it was given — along with the addon's package singleton services, which is what left its credentials unreachable.
57
+
58
+ The wiring itself is still the consuming app's, so middleware, addon tags, addon auth and addon scopes keep resolving against the app: those read the declarations the app made about the addon, and moving them would put back the unrun credential and session middleware that resolving by namespace was introduced to fix.
59
+
60
+ - 02a70cd: fix(core): a scenario assertion is attempted once, not six times
61
+
62
+ `given`, `when` and `then` already opted out of the workflow-wide retry
63
+ default, with a comment saying why: retrying a failed assertion is the wrong
64
+ behaviour for a test primitive. The `expect*` family did not. It passed its
65
+ options straight through to the step engine and inherited
66
+ `DEFAULT_STEP_RETRIES`, so every `expectError`, `expectService`,
67
+ `expectEventually` and `expectScore` got six attempts.
68
+
69
+ What that buys is not resilience:
70
+
71
+ - `expectError` re-invokes the RPC it is asserting against, five more times,
72
+ after it has already done the thing it was not supposed to do.
73
+ - `expectEventually` restarts a poll that has already spent its own `within`
74
+ deadline, so a 30s bound is really 3 minutes.
75
+ - `expectScore` re-runs an LLM judge until a grade lands inside the band. That
76
+ is the one that found this: a judge scored a deliberately useless answer a
77
+ full 1, and the scenario went green on the next attempt.
78
+
79
+ An assertion now defaults to `retries: 0` like every other scenario step, and
80
+ a caller that genuinely wants attempts still asks for them. The unit tests for
81
+ these helpers had each been passing `retries: 0` by hand to make a failure fail
82
+ promptly; those workarounds are gone.
83
+
84
+ A scenario that was only passing because an assertion was retried will now
85
+ report it.
86
+
87
+ - aeef159: fix(cli): let commands that seed a project run outside one
88
+
89
+ Every `pikku` invocation loaded `pikku.config.json` before the command was
90
+ dispatched — `createConfig` in the CLI's service factory called
91
+ `getPikkuCLIConfig` unconditionally. In a directory that is not a Pikku project
92
+ the upward search stops at the repo root and throws `Config file
93
+ pikku.config.json not found`, so the command never ran. That is right for
94
+ commands that read a project, and wrong for `pikku skills install`, whose entire
95
+ job is to write agent skills into a repo that has no Pikku config yet. The
96
+ command needed the thing it exists to precede.
97
+
98
+ `executeCLI` now passes the resolved command path to `createConfig`, and the CLI
99
+ treats `skills` as config-free: it still uses a project config when one is there,
100
+ so behaviour inside a project is unchanged, and falls back to an empty config
101
+ when there is none. Commands that read a project are untouched and still refuse
102
+ to run without one.
103
+
104
+ Also stops a lie in the failure path. A config that was found but could not be
105
+ loaded — a missing field tripping the resolver, malformed JSON — was reported as
106
+ `Config file not found: <path>`, naming a file that was sitting right there and
107
+ sending the reader to look for it. It now reads `Failed to load config file`.
108
+
109
+ - a281de6: A CLI option's type now drives how it is parsed, and it comes from the command function's input schema rather than a second hand-written declaration.
110
+
111
+ `CLIOption` gains `type?: 'string' | 'number' | 'boolean' | 'string[]'` (replacing the never-honoured `array` flag). Declared, it wins over whatever the schema says; left unset, the parser reads the type off the command function's input schema — the same schema the function is validated against — falling back to `default` and then to `'string'`. A `'string[]'` option consumes one token and splits it on commas; every other non-boolean option consumes the next token verbatim, so values that begin with `-` (base64url tokens, negative numbers, dash-leading name patterns) parse correctly. A boolean option is a flag: it consumes the next token only when that token is an explicit literal (`true`/`false`/`1`/`0`/`yes`/`no`), so `--watch false` still turns a default-on flag off instead of leaving `false` behind as a positional.
112
+
113
+ Because the schema is now what types an option, `pikku serve --console --port 4077` no longer reads `--port` as the value of `--console`, and a numeric option arrives as a number instead of a string. An explicit `type` is mostly needed for options that belong to no function input — the `pikku all` filters, which the config factory reads straight off the CLI data, are declared `string[]`, and the CLI's ad-hoc `parseCommaSeparated` normalisation is gone.
114
+
115
+ An array option takes either one comma list or the flag repeated. It never consumes more than one token, because `--tags alpha beta` cannot be told apart from an option followed by a positional; the stray token is reported as an unexpected argument rather than dropped.
116
+
117
+ - 266e3bc: One door per name: `@pikku/core/ecosystem/*` and the package root are gone
118
+
119
+ `@pikku/core` published every module twice. `ecosystem/http` re-exported
120
+ `./http`, `ecosystem/services` re-exported `./services`, and a name was
121
+ reachable through either — so every addition had to be made in two places, and a
122
+ consumer's import said nothing about what it actually used. The package root was
123
+ the same problem at a larger scale: a single barrel of 206 names that no bundler
124
+ could take apart, and the one specifier that revealed nothing at all.
125
+
126
+ Both are deleted. Every name now lives on the subpath that owns it, and every
127
+ import carries that subpath — `@pikku/core/http`, `@pikku/core/services`,
128
+ `@pikku/core/errors`, `@pikku/core/types`.
129
+
130
+ Deleting the facades meant the raw subpaths had to become a superset of them,
131
+ which they were not: the facade tree had accumulated 25 names with no raw home
132
+ and about 26 more filed under a different area than the module they came from.
133
+ Those names moved to the area that owns them, and three areas were published as
134
+ new entry points rather than left on a root that is going away — `./types` (the
135
+ shared type surface, the largest single destination), `./state` and
136
+ `./classification`.
137
+
138
+ `./classification` is one door onto one subject: what a value is and how it must
139
+ be handled. Its three halves would each have been an entry point — the brands
140
+ and manifest types, the stored-form helpers (`hashToken`, `unsafeAsSealed` and
141
+ friends), and `SecretValue` — split by whether a name happens to be a type or a
142
+ value, which is the same defect as the facades. The duration and versioned-id
143
+ helpers went to `./utils`, which already published, and `PikkuRequest` went to
144
+ `./function`: it is the transport-agnostic request base, not an HTTP one — HTTP
145
+ has `PikkuHTTPAbstractRequest`, and the only thing outside core that extends
146
+ `PikkuRequest` is Azure's timer request.
147
+
148
+ `./types` inherited the root barrel's habit before it inherited its contents, so
149
+ the names with an owner elsewhere were moved off it. The middleware types and the
150
+ five middleware factories — `pikkuMiddleware`, `pikkuMiddlewareFactory`,
151
+ `pikkuChannelMiddleware`, `pikkuChannelMiddlewareFactory` and
152
+ `pikkuAgentMiddleware`, runtime values on a types entry point — are now
153
+ `@pikku/core/middleware`; the function meta types are `@pikku/core/function`;
154
+ `SerializedError` is `@pikku/core/errors`; and the generic TypeScript helpers
155
+ (`MakeRequired`, `PickRequired`, `PickOptional`, `RequireAtLeastOne`,
156
+ `JSONPrimitive`, `JSONValue`) are `@pikku/core/utils`. What is left on `./types`
157
+ is the vocabulary the wirings share, which no single module owns.
158
+
159
+ `pikku` was itself a root barrel — `export * from '@pikku/core'` — and
160
+ now exports only the services it bundles.
161
+
162
+ One module survives at the old specifier, and only for the bootstrap:
163
+ `packages/cli` is generated by the _published_ CLI pinned in its `build.sh`, and
164
+ that CLI still writes a bare `@pikku/core` into the files it generates for the
165
+ CLI itself. `bootstrap-compat/root.ts` carries the eight types it names, a test
166
+ in core fails if that list grows, and it goes when the pin moves to a CLI
167
+ released from this branch. The adapter names the pinned CLI reaches for —
168
+ `pikkuState` and `CreateWireServices` — are rewritten to `@pikku/core/state` and
169
+ `@pikku/core/types` by the same `build.sh` patch pass, so no second shim is
170
+ needed for them.
171
+
172
+ A guard test keeps the root shut: it parses imports and rejects a bare
173
+ `@pikku/core` rather than grepping for it, because several tests hold a user's
174
+ file as a template literal, where `import … from '@pikku/core'` is fixture text
175
+ rather than an import this repo makes.
176
+
177
+ An agent scaffold a project generated under an older CLI is refreshed rather
178
+ than left to fail: `pikku all` already deleted one importing an entry point
179
+ `@pikku/core` no longer publishes, and the `#pikku` hub joins that list.
180
+ Without it a project that scaffolds the agent endpoint but
181
+ declares no agents keeps the old file forever — the generator that would rewrite
182
+ it only runs when agents exist, and the file being present is what stops it
183
+ being regenerated as missing.
184
+
185
+ `pikku new addon` also wrote a tsconfig `paths` map naming only the deleted hub.
186
+ An addon's `imports` map points into `dist`, so `paths` is what resolves
187
+ `#pikku/<leaf>` for the addon's own source build — it now names the two leaf
188
+ patterns, in both the addon and its test harness.
189
+
190
+ - 02a70cd: fix(core): a denied tool call still reads as denied after a reload
191
+
192
+ The result stored for a denied approval was a bare sentence written for the
193
+ model. A client has no way to tell that apart from a tool that succeeded and
194
+ returned prose, so it could only show the denial from what it had just done
195
+ itself — the optimistic `{ approved: false }` it writes when the deny button is
196
+ clicked. The moment the thread re-rendered from storage, that local knowledge
197
+ was gone and the denied call came back as a successful one, green badge and all.
198
+ In a delegated run, where the parent keeps streaming after the denial, this was
199
+ the only state a user ever saw.
200
+
201
+ The stored and streamed result now carries `approved: false` alongside the same
202
+ sentence, so the denial survives the round trip and both readers get what they
203
+ need. The action was never actually performed in either case; only the reporting
204
+ of it was wrong.
205
+
206
+ - 786dae5: Bump every dependency whose latest release is a major across the monorepo, and
207
+ port the code the majors broke: `cookie` 2's `parseCookie`/`stringifySetCookie`
208
+ API in `@pikku/core` and the three runtime HTTP adapters, and assistant-ui 0.15's
209
+ store client in `@pikku/assistant-ui`.
210
+ - 6eef0a0: Bump every dependency to its latest compatible minor/patch across the monorepo.
211
+ - 3561d67: feat(graph): per-item `forEach` fanout for declarative workflow graphs
212
+
213
+ A graph node can now run once per element of an upstream array:
214
+
215
+ ```ts
216
+ postVideo: {
217
+ forEach: 'getMyVideo', // or (ref) => ref('getMyVideo', 'rows')
218
+ mode: 'sequential', // optional, defaults to 'parallel'
219
+ input: (ref, template, $item) => ({ url: $item('URL VIDEO') }),
220
+ }
221
+ ```
222
+
223
+ Each element runs as its own step instance (`postVideo[0]`, `postVideo[1]`, …)
224
+ and the node's result is the ordered array of per-item results, so a fanned node
225
+ chains straight into another `forEach`. Downstream nodes wait for every item. A
226
+ non-array source fails the run loudly instead of coercing.
227
+
228
+ The change is additive: `forEach` and `mode` are new optional node fields, and
229
+ `$item` is appended after `template` so existing `input: (ref) => …` and
230
+ `input: (ref, template) => …` nodes are unchanged.
231
+
232
+ - a91c433: HTTP routes wired with `ref('ns:fn')` now record the addon function id as their own `pikkuFuncId`, the same way the CLI and channel wirings already do, instead of minting a per-route wrapper function and linking it back through `refTarget`. The `refTarget` field is gone from `HTTPWiringMeta`, and the runtime resolves a namespaced route function against the addon package's own metadata.
233
+ - 02a70cd: fix(core): a judge grades the run, not just the sentence it ended with
234
+
235
+ The prompt built for an LLM judge carried the user's question, the agent's
236
+ answer and, for a reference-based judge, the answer key — but never the tool
237
+ calls, although `ScorerInput` has always carried them and heuristic scorers
238
+ read them.
239
+
240
+ An answer produced from a tool and the same sentence invented by the model are
241
+ identical in the output alone; they differ only in what the run did to get
242
+ there. Asked to grade a todo agent that had just listed the user's todos
243
+ correctly, a judge given only the answer called it "a plausible-looking list"
244
+ that "offers no real access to your actual list, making it effectively a guess",
245
+ and scored 0.2 what it scored 1 on other runs with near-identical answers. It
246
+ was applying its rubric correctly to the evidence it had; the evidence was the
247
+ problem.
248
+
249
+ The default prompt now names the tools the run called, and marks the ones that
250
+ failed. `pikkuAgentJudge` takes a `toolCalls` option for how much of the
251
+ trajectory to disclose:
252
+
253
+ - `names` (default) — which tools ran and which failed. No arguments, no
254
+ results, no error text. Enough to settle whether the run had real access,
255
+ which is what the 0.2 was doubting.
256
+ - `full` — arguments and results too, truncated so one fat result cannot crowd
257
+ the answer out of the judge's context. For a judge that grades the answer
258
+ _against_ what the tool returned.
259
+ - `off` — no trajectory at all.
260
+
261
+ A judge is a third-party model, and a tool's arguments and results are the most
262
+ sensitive thing a run touches, so the default discloses the least that fixes
263
+ the bug. Output middleware still has its pass first either way: a scorer sees
264
+ the post-middleware snapshot, so anything a `modifyOutput` redacted is already
265
+ gone before `toolCalls` is consulted.
266
+
267
+ A run that called nothing gets no section rather than an empty one, and a
268
+ scorer supplying its own `prompt` is unaffected. `ScorerJudgeConfig.toolCalls`
269
+ is required — `pikkuAgentJudge` resolves the default, so only code building
270
+ that type by hand is affected.
271
+
272
+ - 9537f74: Every definer an app calls is now reachable through its `#pikku` leaf.
273
+
274
+ `defineCredential` had no generated door, so a credential file had to name
275
+ `@pikku/core/credential` directly — the one import in an otherwise
276
+ `#pikku`-only wiring that reached past the leaf. It is now generated into the
277
+ project's own `.pikku` alongside `defineSecret`, `defineVariable` and
278
+ `defineScope`, and `cors` joins the names the `#pikku/http` leaf carries.
279
+
280
+ A leaf index re-exports every entry file the leaf has rather than only the
281
+ first, so the definer and the typed service map are both reachable through
282
+ `#pikku/<leaf>` instead of one of them being left behind a relative path into
283
+ `.pikku`.
284
+
285
+ The definition types are also generated before the leaf indexes are written,
286
+ not after. They read only `config`, so nothing held them back to the inspected
287
+ pass, and running them there left the first codegen after an upgrade with a
288
+ `#pikku/credentials` that resolved but was missing `defineCredential`.
289
+
290
+ - 2b57ca8: A persona can name the `app` they sign into, and a browser run takes a url per app (`--app-url <app>=<url>`, or `appUrls` on the environment). Each actor's browser context navigates against its own app's base, so a product that is more than one frontend can be proved in one run — including a scenario that crosses from one app to the other. A run whose personas name an app nobody gave a url for is refused rather than browsing the wrong app's pages.
291
+ - 266e3bc: `#pikku` is a namespace, not a module: one subpath per wiring
292
+
293
+ The bare `#pikku` specifier resolved to `.pikku/pikku-types.gen.ts`, a hub that
294
+ re-exported all twelve wiring leaves with `export *` — undoing the split the
295
+ leaves exist for, each of which still says so in its own generated header
296
+ ("HTTP-specific type definitions for tree-shaking optimization"). Reaching that
297
+ hub put 33 distinct `@pikku/core` subpaths into the module graph, and neither
298
+ consumer could drop them again: bundlers keep `export *` chains because the app
299
+ declares no `sideEffects`, and Node and tsx do not tree-shake at all, so an app
300
+ with no queues still executed `@pikku/core/queue` at boot.
301
+
302
+ The hub is gone. An app now imports the leaf the name belongs to —
303
+ `#pikku/function`, `#pikku/http`, `#pikku/workflow` — and a project's `imports`
304
+ map declares two patterns, because both resolvers pick the more specific one:
305
+
306
+ ```json
307
+ "#pikku/*.js": "./.pikku/*.ts",
308
+ "#pikku/*": "./.pikku/*/index.ts"
309
+ ```
310
+
311
+ A source tree names the `.ts` on both. Webpack, esbuild and Bun all rewrite a
312
+ `.js` specifier to the `.ts` beside it for a relative import but not for an
313
+ imports-map target, so a `.js` target there resolves to a file that does not
314
+ exist. The two places that keep `.js` are the ones where it is the real file: a
315
+ published addon, whose map points into `dist`, and a project that imports a
316
+ declaration-only generated file such as `pikku-rpc-wirings-map.gen.d.ts`, where
317
+ naming the `.js` lets the type resolver's own mapping reach the `.d.ts`.
318
+
319
+ `pikku` generates the leaf indexes and removes the hub, and `pikku validate`
320
+ reports a barrel import as an error. The split also turns the addon boundary
321
+ from advice into a rule: an addon never generates the wiring leaves, so
322
+ `#pikku/http` fails at the specifier rather than yielding "no exported member"
323
+ from a hub that quietly dropped the re-export.
324
+
325
+ - 9fce0f1: Give a persona step its actor instead of making it unwrap one
326
+
327
+ `requireActor(scenarioStep)` was the first line of every step that acts as
328
+ somebody, and it existed because the actor lived on the `scenarioStep` wire as
329
+ an optional property. A property of a wire member is either optional for every
330
+ binding or required for all of them, so the only expressible answer was
331
+ "optional", and each step paid for it with a guard.
332
+
333
+ The actor is now its own wire member, `wire.actor`, injected by the runner. Wire
334
+ members can be required per binding, so a step declares whether it runs as
335
+ somebody and the type follows:
336
+
337
+ ```typescript
338
+ export const buysAnApple = pikkuScenarioStep<
339
+ { qty: number },
340
+ { orderId: string }
341
+ >({
342
+ name: 'buysAnApple',
343
+ actor: true,
344
+ default: async (_services, { qty }, { actor }) =>
345
+ actor.invoke('placeOrder', { qty }),
346
+ })
347
+ ```
348
+
349
+ A `browser` binding implies it — a window is opened as somebody, so every
350
+ binding of a step that has one gets the actor too. A step that declares neither
351
+ has no `actor` on its wire at all, rather than an optional one: a pure assertion
352
+ over what an earlier step returned has nobody to be, and `attemptsSignIn`
353
+ deliberately posts credentials instead of reusing an actor's established
354
+ session. That distinction is why the requirement is declared per step rather
355
+ than inferred from the step being a persona step — "persona step ⇒ has an actor"
356
+ is false, and a guard built on it rejects the 61 steps in the e2e suite that
357
+ correctly run without one.
358
+
359
+ Dispatching a step that declared an actor without `{ actor: actors.x }` now
360
+ fails before the body runs, with `ScenarioActorRequired` naming the step.
361
+ `ScenarioBrowserActorRequired` is replaced by it, and `requireActor` is gone
362
+ from `@pikku/core/scenario` and the generated `#pikku/scenario` barrel.
363
+
364
+ - 83683a0: Give the scenario test surface its own `#pikku/scenario` entry
365
+
366
+ Scenario files are app code, so they belong inside the generated alias — but
367
+ they are a distinct surface from wiring, and folding ~11 test-only names into
368
+ the main hub would crowd it for every app that never writes a scenario. They
369
+ get their own sub-entry instead.
370
+
371
+ The generated scenario barrel now re-exports the helpers a step file reaches
372
+ for — `requireScenarioEnv`, `createCookieJar`, `pollUntil`,
373
+ `createScenarioRunner`, `postScenarioJson`, `readScenarioHttpResponse` and the
374
+ types beside them — so a scenario file has one specifier to import from and
375
+ never has to know whether a helper is typed against this project or shipped by
376
+ the framework. The names come from the `@pikku/core/scenario` and
377
+ `@pikku/core/persona` subpaths that own them.
378
+
379
+ - 456c88b: Scenario runs are now kept, and the console reads them back.
380
+
381
+ Every `pikku scenario run` files a record: the run's outcome and counts, each
382
+ scenario's result with the prose of the steps as they read at the time, and the
383
+ screenshots and video it left behind. The steps are snapshotted rather than
384
+ referenced, so a run still reads correctly after the scenario that produced it
385
+ has been rewritten.
386
+
387
+ `ScenarioRunStore` is the interface, `FileScenarioRunStore` the on-disk
388
+ implementation the CLI writes to — one folder per run, `run.json` beside its
389
+ artifacts, under `<outDir>/scenario-runs`. It is a store in its own right rather
390
+ than a corner of the workflow service, so a hosted console can keep the same
391
+ records in a database and its footage in object storage without the functions
392
+ that read them knowing the difference.
393
+
394
+ The console's Scenarios page gained a Runs view (`?view=runs`) listing past
395
+ runs, with a run's results, its step ladder, failures, and the screenshots and
396
+ video inline. Reading and deleting runs are gated by the new
397
+ `pikku:console:scenarios:read` and `pikku:console:scenarios:manage` scopes.
398
+
399
+ - 456c88b: Scenario runs now record video by default and keep the footage that is worth watching.
400
+
401
+ Playwright decides recording when a window opens, which is before anyone knows
402
+ whether the scenario passed — so `--video failed` (the new default) records every
403
+ scenario and discards the passes. `--video all` keeps everything, `--video off`
404
+ records nothing. Recording costs ~0.1-0.5s per actor context, nearly all of it
405
+ finalising the file on close; only kept videos are encoded, so a green run pays
406
+ no encoding at all.
407
+
408
+ Kept recordings are filed under `<run>/<scenario>/<actor>` alongside that
409
+ scenario's screenshots, rather than landing in one flat folder under
410
+ Playwright's own generated filenames.
411
+
412
+ Encoding is now h264/mp4 rather than VP9/webm: measured on scenario footage it
413
+ runs ~11x faster and lands ~30% smaller, and mp4 plays in every browser.
414
+
415
+ `--screenshots` is unchanged and still opt-in.
416
+
417
+ - c127273: fix: type `wire.getCredential` from the generated `CredentialsMap`
418
+
419
+ `wire.getCredential('slack')` now resolves its value type from the project's
420
+ credentials codegen, the way `services.credentials.get('slack')` already did.
421
+ `PikkuWire` takes a `TypedCredentials` parameter and the generated function
422
+ types bind `CredentialsMap` into it; a name the map does not know stays callable
423
+ with an explicit type argument.
424
+
1
425
  ## 0.12.84
2
426
 
3
427
  ### Patch Changes
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Bootstrap compatibility, not a public entry point.
3
+ *
4
+ * The package root carried a 206-name barrel; it is gone, and every name now
5
+ * lives on the subpath that owns it. What is left here is the handful of types
6
+ * the CLI pinned in `packages/cli/build.sh` still writes into the files it
7
+ * generates for the CLI itself — an unresolved type there is a silent `any` in
8
+ * the CLI's own generated surface, not a build failure, which is why this
9
+ * exists rather than letting it break loudly.
10
+ *
11
+ * `bootstrap-compat.test.ts` fails if the pinned CLI's output drifts from this
12
+ * list. Delete this file and its `exports` entry once the pin moves to a CLI
13
+ * released from this branch.
14
+ */
15
+ export type { PikkuWire, SecretlessServices } from '../types/core.types.js';
16
+ export type { CorePikkuMiddleware } from '../middleware/middleware.types.js';
17
+ export type { PickRequired } from '../utils.js';
18
+ export type { CorePermissionGroup } from '../function/functions.types.js';
19
+ export type { ListInput, ListOutput } from '../function/list.types.js';
20
+ export type { SecretService } from '../services/secret-service.js';
@@ -0,0 +1,32 @@
1
+ import type { HashedValue, SealedValue, WrappedValue } from './data-classification.js';
2
+ /**
3
+ * SHA-256 of a credential, lowercase hex — the sole producer of `HashedValue`.
4
+ *
5
+ * Deliberately unpeppered. These are high-entropy random bearer tokens, not
6
+ * passwords: there is no candidate set to search, so a pepper would add a key
7
+ * to manage and a rotation story to own while buying nothing. A column holding
8
+ * a *low*-entropy secret is not a `hashed` column — it wants a password KDF and
9
+ * a different type entirely.
10
+ *
11
+ * Async because it runs on WebCrypto rather than `node:crypto`, so the same
12
+ * code path works in a Worker. Callers that hash a bearer token on every
13
+ * request are already async.
14
+ */
15
+ export declare const hashToken: (raw: string) => Promise<HashedValue>;
16
+ /**
17
+ * Assert that a string already in storage is ciphertext of the given form.
18
+ *
19
+ * The brands exist so that new writes must come from a real encrypt/hash call,
20
+ * but three paths legitimately hold such a value as a bare `string`: a
21
+ * migration backfilling rows written before the column declared its form, a
22
+ * test fixture, and a value arriving over the wire from a service that sealed
23
+ * it elsewhere. Each of those is a promise the caller is making, not something
24
+ * the type system can check — which is why these are named to be greppable and
25
+ * why there is no non-`unsafe` spelling. If one of these appears in ordinary
26
+ * request-handling code, that is the bug.
27
+ */
28
+ export declare const unsafeAsWrapped: (stored: string) => WrappedValue;
29
+ /** See `unsafeAsWrapped`. */
30
+ export declare const unsafeAsSealed: (stored: string) => SealedValue;
31
+ /** See `unsafeAsWrapped`. */
32
+ export declare const unsafeAsHashed: (stored: string) => HashedValue;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * SHA-256 of a credential, lowercase hex — the sole producer of `HashedValue`.
3
+ *
4
+ * Deliberately unpeppered. These are high-entropy random bearer tokens, not
5
+ * passwords: there is no candidate set to search, so a pepper would add a key
6
+ * to manage and a rotation story to own while buying nothing. A column holding
7
+ * a *low*-entropy secret is not a `hashed` column — it wants a password KDF and
8
+ * a different type entirely.
9
+ *
10
+ * Async because it runs on WebCrypto rather than `node:crypto`, so the same
11
+ * code path works in a Worker. Callers that hash a bearer token on every
12
+ * request are already async.
13
+ */
14
+ export const hashToken = async (raw) => {
15
+ const subtle = globalThis.crypto?.subtle;
16
+ if (!subtle) {
17
+ throw new Error('WebCrypto not available');
18
+ }
19
+ const digest = await subtle.digest('SHA-256', new TextEncoder().encode(raw));
20
+ let hex = '';
21
+ for (const byte of new Uint8Array(digest)) {
22
+ hex += byte.toString(16).padStart(2, '0');
23
+ }
24
+ return hex;
25
+ };
26
+ /**
27
+ * Assert that a string already in storage is ciphertext of the given form.
28
+ *
29
+ * The brands exist so that new writes must come from a real encrypt/hash call,
30
+ * but three paths legitimately hold such a value as a bare `string`: a
31
+ * migration backfilling rows written before the column declared its form, a
32
+ * test fixture, and a value arriving over the wire from a service that sealed
33
+ * it elsewhere. Each of those is a promise the caller is making, not something
34
+ * the type system can check — which is why these are named to be greppable and
35
+ * why there is no non-`unsafe` spelling. If one of these appears in ordinary
36
+ * request-handling code, that is the bug.
37
+ */
38
+ export const unsafeAsWrapped = (stored) => stored;
39
+ /** See `unsafeAsWrapped`. */
40
+ export const unsafeAsSealed = (stored) => stored;
41
+ /** See `unsafeAsWrapped`. */
42
+ export const unsafeAsHashed = (stored) => stored;
@@ -0,0 +1,64 @@
1
+ export type Private<T> = T & {
2
+ readonly __classification__?: 'private';
3
+ };
4
+ export type Pii<T> = T & {
5
+ readonly __classification__?: 'pii';
6
+ };
7
+ export type Secret<T> = T & {
8
+ readonly __classification__?: 'secret';
9
+ };
10
+ export type Classification = 'public' | 'private' | 'pii' | 'secret';
11
+ export type AnonymizeStrategy = 'fake:email' | 'fake:name' | 'hash' | 'keep' | null;
12
+ /**
13
+ * How a column's bytes are represented at rest, as distinct from how sensitive
14
+ * the value is (`Classification`). The two are independent: a token hash is
15
+ * `secret` + `hashed` and must never be encrypted, because the hash *is* the
16
+ * lookup key; a live bearer token is `secret` + `plain` today and should not be.
17
+ *
18
+ * `wrapped` and `sealed` are siblings rather than one being "encrypted": both
19
+ * are ciphertext, and what separates them is who can read it back. Wrapped is
20
+ * symmetric and the application holds the key. Sealed is asymmetric and the
21
+ * application holds only the public half, so it can write the value and never
22
+ * read it. Storing one where the other is expected is silent, permanent data
23
+ * loss, which is why they are not collapsed into a single `encrypted`.
24
+ */
25
+ export type ColumnForm = 'plain' | 'hashed' | 'wrapped' | 'sealed';
26
+ declare const wrappedBrand: unique symbol;
27
+ declare const sealedBrand: unique symbol;
28
+ declare const hashedBrand: unique symbol;
29
+ /**
30
+ * Ciphertext under a symmetric key the application holds — the output of
31
+ * `envelopeEncrypt`, `wrapDEK` or `envelopeRewrap`.
32
+ *
33
+ * Unlike `Secret<T>` the brand is REQUIRED, so a plain `string` is not
34
+ * assignable and a column declared `form: 'wrapped'` cannot be written with
35
+ * anything but genuine ciphertext. It stays assignable *to* `string`, so it
36
+ * still works as a query operand and serializes normally — the constraint is on
37
+ * construction, not on use.
38
+ */
39
+ export type WrappedValue = string & {
40
+ readonly [wrappedBrand]: true;
41
+ };
42
+ /** Ciphertext under a public key whose private half the application does not
43
+ * hold. Deliberately not assignable to `WrappedValue`: writing one where the
44
+ * other belongs produces a row nobody can ever open. */
45
+ export type SealedValue = string & {
46
+ readonly [sealedBrand]: true;
47
+ };
48
+ /** A one-way digest of a secret input. The brand's job is narrow — stop a *raw*
49
+ * credential being written into the column that should hold its hash. */
50
+ export type HashedValue = string & {
51
+ readonly [hashedBrand]: true;
52
+ };
53
+ export interface ColumnClassification {
54
+ classification: Classification;
55
+ anonymize_strategy: AnonymizeStrategy;
56
+ /** At-rest representation. Absent means `plain`. */
57
+ form?: ColumnForm;
58
+ description?: string;
59
+ }
60
+ export type ClassificationManifest = {
61
+ version: 1;
62
+ tables: Record<string, Record<string, ColumnClassification>>;
63
+ };
64
+ export {};
@@ -0,0 +1,13 @@
1
+ /**
2
+ * What a value is, and how it must be handled: the classification brands a
3
+ * column carries, the stored forms those brands map to, and the wrapper that
4
+ * keeps a secret out of a log.
5
+ *
6
+ * These arrived as three entry points — one for the types, one for the
7
+ * runtime helpers, one for `SecretValue` — which is the same subject behind
8
+ * three doors, split by whether a name happens to be a type or a value.
9
+ */
10
+ export type { Private, Pii, Secret, Classification, AnonymizeStrategy, ColumnForm, WrappedValue, SealedValue, HashedValue, ColumnClassification, ClassificationManifest, } from './data-classification.js';
11
+ export { hashToken, unsafeAsWrapped, unsafeAsSealed, unsafeAsHashed, } from './column-form.js';
12
+ export { REDACTED, SecretCoercionError, SecretValue, createSecretValue, isSecretValue, } from './secret-value.js';
13
+ export type { Safe } from './secret-value.js';
@@ -0,0 +1,2 @@
1
+ export { hashToken, unsafeAsWrapped, unsafeAsSealed, unsafeAsHashed, } from './column-form.js';
2
+ export { REDACTED, SecretCoercionError, SecretValue, createSecretValue, isSecretValue, } from './secret-value.js';