@pikku/core 0.12.71 → 0.12.74
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.
- package/CHANGELOG.md +848 -0
- package/dist/crypto-utils.d.ts +30 -5
- package/dist/crypto-utils.js +146 -41
- package/dist/dev/hot-reload.js +11 -30
- package/dist/dev/module-runner.d.ts +3 -7
- package/dist/dev/module-runner.js +4 -10
- package/dist/dev/reload-meta.d.ts +8 -20
- package/dist/dev/reload-meta.js +9 -29
- package/dist/errors/error-handler.d.ts +5 -30
- package/dist/errors/error-handler.js +16 -32
- package/dist/errors/errors.d.ts +32 -151
- package/dist/errors/errors.js +55 -157
- package/dist/function/abort-scope.d.ts +47 -0
- package/dist/function/abort-scope.js +63 -0
- package/dist/function/function-runner.js +40 -30
- package/dist/function/functions.types.d.ts +44 -136
- package/dist/function/functions.types.js +0 -58
- package/dist/function/list.types.d.ts +12 -62
- package/dist/function/list.types.js +4 -25
- package/dist/handle-error.d.ts +0 -11
- package/dist/handle-error.js +6 -18
- package/dist/index.d.ts +5 -2
- package/dist/index.js +4 -1
- package/dist/middleware/auth-apikey.d.ts +3 -18
- package/dist/middleware/auth-apikey.js +0 -17
- package/dist/middleware/auth-bearer.d.ts +6 -41
- package/dist/middleware/auth-bearer.js +3 -40
- package/dist/middleware/auth-cookie.d.ts +5 -27
- package/dist/middleware/auth-cookie.js +2 -26
- package/dist/middleware/cors.d.ts +7 -34
- package/dist/middleware/cors.js +7 -34
- package/dist/middleware/remote-auth.d.ts +3 -1
- package/dist/middleware/remote-auth.js +3 -2
- package/dist/middleware/telemetry.d.ts +8 -33
- package/dist/middleware/telemetry.js +2 -31
- package/dist/middleware-runner.d.ts +4 -55
- package/dist/middleware-runner.js +5 -74
- package/dist/permissions.d.ts +3 -44
- package/dist/permissions.js +19 -71
- package/dist/pikku-request.d.ts +0 -6
- package/dist/pikku-request.js +0 -6
- package/dist/pikku-state.d.ts +0 -26
- package/dist/pikku-state.js +2 -30
- package/dist/remote.d.ts +3 -5
- package/dist/remote.js +8 -7
- package/dist/schema.d.ts +7 -17
- package/dist/schema.js +30 -18
- package/dist/scopes.d.ts +4 -23
- package/dist/scopes.js +7 -48
- package/dist/services/ai-agent-runner-service.d.ts +20 -0
- package/dist/services/ai-embedding-service.d.ts +2 -25
- package/dist/services/audit-service.js +1 -2
- package/dist/services/content-service.d.ts +1 -46
- package/dist/services/credential-service.d.ts +3 -40
- package/dist/services/deployment-service.d.ts +3 -9
- package/dist/services/gateway-service.d.ts +0 -15
- package/dist/services/http-personas.d.ts +80 -0
- package/dist/services/http-personas.js +233 -0
- package/dist/services/in-memory-queue-service.d.ts +0 -14
- package/dist/services/in-memory-queue-service.js +1 -15
- package/dist/services/in-memory-trigger-service.d.ts +0 -18
- package/dist/services/in-memory-trigger-service.js +1 -18
- package/dist/services/in-memory-workflow-service.d.ts +0 -16
- package/dist/services/in-memory-workflow-service.js +4 -33
- package/dist/services/index.d.ts +5 -6
- package/dist/services/index.js +2 -5
- package/dist/services/istanbul-coverage-service.d.ts +1 -5
- package/dist/services/istanbul-coverage-service.js +2 -8
- package/dist/services/jwt-service.d.ts +1 -16
- package/dist/services/local-content.d.ts +13 -2
- package/dist/services/local-content.js +40 -13
- package/dist/services/local-gateway-service.d.ts +0 -16
- package/dist/services/local-gateway-service.js +2 -17
- package/dist/services/local-secrets.d.ts +0 -4
- package/dist/services/local-secrets.js +0 -4
- package/dist/services/logger-console.d.ts +3 -7
- package/dist/services/logger-console.js +3 -7
- package/dist/services/logger.d.ts +2 -37
- package/dist/services/meta-service.d.ts +23 -26
- package/dist/services/meta-service.js +22 -36
- package/dist/services/personas-service.d.ts +134 -0
- package/dist/services/personas-service.js +40 -0
- package/dist/services/pikku-user-id.js +0 -4
- package/dist/services/queue-webhook-service.d.ts +2 -36
- package/dist/services/queue-webhook-service.js +9 -41
- package/dist/services/scheduler-service.d.ts +1 -50
- package/dist/services/scheduler-service.js +0 -10
- package/dist/services/schema-service.d.ts +1 -24
- package/dist/services/scope-service.d.ts +49 -34
- package/dist/services/scoped-secret-service.d.ts +0 -4
- package/dist/services/scoped-secret-service.js +0 -4
- package/dist/services/secret-host-binding.d.ts +8 -0
- package/dist/services/secret-host-binding.js +36 -0
- package/dist/services/secret-service.d.ts +5 -33
- package/dist/services/secretless.d.ts +6 -0
- package/dist/services/secretless.js +21 -0
- package/dist/services/stub-tracker.d.ts +7 -18
- package/dist/services/stub-tracker.js +8 -18
- package/dist/services/system-role-guard.d.ts +33 -0
- package/dist/services/system-role-guard.js +38 -0
- package/dist/services/trigger-service.d.ts +0 -12
- package/dist/services/typed-secret-service.d.ts +0 -7
- package/dist/services/typed-secret-service.js +1 -7
- package/dist/services/v8-coverage-service.d.ts +2 -3
- package/dist/services/v8-coverage-service.js +1 -2
- package/dist/services/variables-service.d.ts +1 -8
- package/dist/services/webhook-service.d.ts +19 -63
- package/dist/services/webhook-service.js +6 -20
- package/dist/services/workflow-service.d.ts +3 -15
- package/dist/testing/service-tests.js +0 -17
- package/dist/time-utils.d.ts +0 -16
- package/dist/time-utils.js +1 -19
- package/dist/types/core.types.d.ts +99 -219
- package/dist/types/core.types.js +0 -42
- package/dist/types/state.types.d.ts +4 -9
- package/dist/utils/hmac.d.ts +4 -10
- package/dist/utils/hmac.js +4 -10
- package/dist/utils/safe-fetch.d.ts +7 -35
- package/dist/utils/safe-fetch.js +13 -53
- package/dist/utils.d.ts +1 -6
- package/dist/utils.js +6 -15
- package/dist/wirings/actor-flow/actor-flow.types.d.ts +1 -34
- package/dist/wirings/actor-flow/index.d.ts +0 -9
- package/dist/wirings/actor-flow/run-conversation.d.ts +5 -5
- package/dist/wirings/actor-flow/run-conversation.js +14 -7
- package/dist/wirings/ai-agent/ai-agent-agui.d.ts +0 -5
- package/dist/wirings/ai-agent/ai-agent-agui.js +34 -12
- package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +7 -0
- package/dist/wirings/ai-agent/ai-agent-helpers.js +7 -0
- package/dist/wirings/ai-agent/ai-agent-interrupt.d.ts +153 -0
- package/dist/wirings/ai-agent/ai-agent-interrupt.js +256 -0
- package/dist/wirings/ai-agent/ai-agent-memory.js +0 -2
- package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +0 -9
- package/dist/wirings/ai-agent/ai-agent-model-config.js +1 -9
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +10 -99
- package/dist/wirings/ai-agent/ai-agent-prepare.js +58 -131
- package/dist/wirings/ai-agent/ai-agent-registry.d.ts +2 -1
- package/dist/wirings/ai-agent/ai-agent-registry.js +5 -1
- package/dist/wirings/ai-agent/ai-agent-runner.js +49 -20
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +25 -2
- package/dist/wirings/ai-agent/ai-agent-stream.js +153 -63
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +84 -4
- package/dist/wirings/ai-agent/index.d.ts +6 -4
- package/dist/wirings/ai-agent/index.js +5 -4
- package/dist/wirings/ai-agent/voice-input.d.ts +39 -1
- package/dist/wirings/ai-agent/voice-input.js +46 -3
- package/dist/wirings/ai-agent/voice-output.d.ts +54 -1
- package/dist/wirings/ai-agent/voice-output.js +153 -50
- package/dist/wirings/channel/channel-common.d.ts +7 -20
- package/dist/wirings/channel/channel-common.js +7 -21
- package/dist/wirings/channel/channel-handler.js +25 -6
- package/dist/wirings/channel/channel-host-rpc.d.ts +25 -0
- package/dist/wirings/channel/channel-host-rpc.js +38 -0
- package/dist/wirings/channel/channel-middleware-runner.d.ts +0 -12
- package/dist/wirings/channel/channel-middleware-runner.js +0 -12
- package/dist/wirings/channel/channel-rpc-registry.d.ts +31 -0
- package/dist/wirings/channel/channel-rpc-registry.js +89 -0
- package/dist/wirings/channel/channel-rpc-responder.d.ts +15 -0
- package/dist/wirings/channel/channel-rpc-responder.js +71 -0
- package/dist/wirings/channel/channel-rpc-service.d.ts +40 -0
- package/dist/wirings/channel/channel-rpc-service.js +106 -0
- package/dist/wirings/channel/channel-rpc-validators.d.ts +14 -0
- package/dist/wirings/channel/channel-rpc-validators.js +30 -0
- package/dist/wirings/channel/channel-rpc.d.ts +5 -0
- package/dist/wirings/channel/channel-rpc.js +5 -0
- package/dist/wirings/channel/channel-rpc.types.d.ts +90 -0
- package/dist/wirings/channel/channel-rpc.types.js +50 -0
- package/dist/wirings/channel/channel-runner.d.ts +0 -4
- package/dist/wirings/channel/channel-runner.js +0 -14
- package/dist/wirings/channel/channel-store.d.ts +0 -10
- package/dist/wirings/channel/channel.types.d.ts +12 -1
- package/dist/wirings/channel/define-channel-routes.d.ts +0 -20
- package/dist/wirings/channel/define-channel-routes.js +0 -20
- package/dist/wirings/channel/eventhub-service.d.ts +0 -18
- package/dist/wirings/channel/index.d.ts +4 -1
- package/dist/wirings/channel/index.js +2 -0
- package/dist/wirings/channel/local/local-channel-runner.js +3 -1
- package/dist/wirings/channel/local/local-eventhub-service.d.ts +0 -33
- package/dist/wirings/channel/local/local-eventhub-service.js +2 -36
- package/dist/wirings/channel/log-channels.d.ts +0 -4
- package/dist/wirings/channel/log-channels.js +0 -4
- package/dist/wirings/channel/pikku-abstract-channel-handler.js +6 -0
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +2 -5
- package/dist/wirings/cli/channel/cli-approval.d.ts +41 -0
- package/dist/wirings/cli/channel/cli-approval.js +81 -0
- package/dist/wirings/cli/channel/cli-channel-runner.d.ts +0 -4
- package/dist/wirings/cli/channel/cli-channel-runner.js +3 -25
- package/dist/wirings/cli/channel/cli-raw-channel-runner.d.ts +47 -9
- package/dist/wirings/cli/channel/cli-raw-channel-runner.js +24 -16
- package/dist/wirings/cli/channel/cli-raw-client-runner.d.ts +20 -0
- package/dist/wirings/cli/channel/cli-raw-client-runner.js +121 -0
- package/dist/wirings/cli/channel/index.d.ts +4 -0
- package/dist/wirings/cli/channel/index.js +2 -0
- package/dist/wirings/cli/cli-runner.d.ts +20 -20
- package/dist/wirings/cli/cli-runner.js +28 -89
- package/dist/wirings/cli/cli.types.d.ts +14 -3
- package/dist/wirings/cli/command-parser.d.ts +1 -10
- package/dist/wirings/cli/command-parser.js +10 -87
- package/dist/wirings/cli/define-cli-commands.d.ts +1 -17
- package/dist/wirings/cli/define-cli-commands.js +1 -17
- package/dist/wirings/credential/credential.types.d.ts +0 -12
- package/dist/wirings/credential/define-credential.d.ts +48 -0
- package/dist/wirings/credential/define-credential.js +47 -0
- package/dist/wirings/credential/index.d.ts +1 -1
- package/dist/wirings/credential/index.js +1 -1
- package/dist/wirings/credential/validate-credential-definitions.d.ts +2 -4
- package/dist/wirings/gateway/gateway-runner.d.ts +1 -20
- package/dist/wirings/gateway/gateway-runner.js +8 -105
- package/dist/wirings/gateway/gateway.types.d.ts +7 -80
- package/dist/wirings/http/http-routes.d.ts +0 -63
- package/dist/wirings/http/http-routes.js +0 -63
- package/dist/wirings/http/http-runner.d.ts +1 -100
- package/dist/wirings/http/http-runner.js +12 -166
- package/dist/wirings/http/http.types.d.ts +16 -55
- package/dist/wirings/http/index.d.ts +2 -1
- package/dist/wirings/http/index.js +1 -1
- package/dist/wirings/http/log-http-routes.d.ts +0 -4
- package/dist/wirings/http/log-http-routes.js +0 -4
- package/dist/wirings/http/pikku-fetch-http-request.d.ts +6 -36
- package/dist/wirings/http/pikku-fetch-http-request.js +56 -50
- package/dist/wirings/http/pikku-fetch-http-response.js +0 -3
- package/dist/wirings/http/routers/path-to-regex.js +2 -13
- package/dist/wirings/http/web-request.d.ts +0 -8
- package/dist/wirings/http/web-request.js +25 -17
- package/dist/wirings/mcp/mcp-runner.d.ts +2 -0
- package/dist/wirings/mcp/mcp-runner.js +6 -16
- package/dist/wirings/mcp/mcp.types.d.ts +2 -35
- package/dist/wirings/oauth2/oauth2.types.d.ts +0 -28
- package/dist/wirings/oauth2/oauth2.types.js +0 -3
- package/dist/wirings/persona/define-personas.d.ts +28 -0
- package/dist/wirings/persona/define-personas.js +27 -0
- package/dist/wirings/persona/index.d.ts +21 -0
- package/dist/wirings/persona/index.js +17 -0
- package/dist/wirings/persona/persona-email.d.ts +37 -0
- package/dist/wirings/persona/persona-email.js +69 -0
- package/dist/wirings/persona/persona-environments.d.ts +45 -0
- package/dist/wirings/persona/persona-environments.js +81 -0
- package/dist/wirings/persona/persona-mailbox.d.ts +101 -0
- package/dist/wirings/persona/persona-mailbox.js +53 -0
- package/dist/wirings/persona/persona.types.d.ts +125 -0
- package/dist/wirings/persona/persona.types.js +1 -0
- package/dist/wirings/persona/validate-personas.d.ts +53 -0
- package/dist/wirings/persona/validate-personas.js +94 -0
- package/dist/wirings/queue/index.d.ts +3 -0
- package/dist/wirings/queue/index.js +2 -3
- package/dist/wirings/queue/queue-identity.d.ts +28 -0
- package/dist/wirings/queue/queue-identity.js +102 -0
- package/dist/wirings/queue/queue-runner.d.ts +0 -19
- package/dist/wirings/queue/queue-runner.js +9 -30
- package/dist/wirings/queue/queue.types.d.ts +18 -89
- package/dist/wirings/queue/register-queue-helper.d.ts +0 -12
- package/dist/wirings/queue/register-queue-helper.js +0 -11
- package/dist/wirings/queue/signed-queue-service.d.ts +16 -0
- package/dist/wirings/queue/signed-queue-service.js +42 -0
- package/dist/wirings/queue/validate-worker-config.d.ts +2 -23
- package/dist/wirings/queue/validate-worker-config.js +0 -14
- package/dist/wirings/role/define-system-role.d.ts +32 -0
- package/dist/wirings/role/define-system-role.js +31 -0
- package/dist/wirings/role/index.d.ts +3 -0
- package/dist/wirings/role/index.js +2 -0
- package/dist/wirings/role/role.types.d.ts +43 -0
- package/dist/wirings/role/role.types.js +1 -0
- package/dist/wirings/role/validate-role-definitions.d.ts +21 -0
- package/dist/wirings/role/validate-role-definitions.js +71 -0
- package/dist/wirings/rpc/addon-runner.d.ts +0 -19
- package/dist/wirings/rpc/addon-runner.js +0 -51
- package/dist/wirings/rpc/remote-addon-auth.d.ts +1 -12
- package/dist/wirings/rpc/remote-addon-auth.js +1 -9
- package/dist/wirings/rpc/rpc-runner.d.ts +11 -18
- package/dist/wirings/rpc/rpc-runner.js +88 -105
- package/dist/wirings/rpc/rpc-types.d.ts +7 -6
- package/dist/wirings/rpc/wire-addon.d.ts +25 -0
- package/dist/wirings/rpc/wire-addon.js +62 -0
- package/dist/wirings/rpc/wire-remote-addon.d.ts +3 -28
- package/dist/wirings/rpc/wire-remote-addon.js +0 -8
- package/dist/wirings/scheduler/log-schedulers.d.ts +0 -4
- package/dist/wirings/scheduler/log-schedulers.js +0 -4
- package/dist/wirings/scheduler/scheduler-runner.d.ts +0 -1
- package/dist/wirings/scheduler/scheduler-runner.js +0 -1
- package/dist/wirings/scheduler/scheduler.types.d.ts +1 -14
- package/dist/wirings/scope/define-scope.d.ts +32 -0
- package/dist/wirings/scope/define-scope.js +31 -0
- package/dist/wirings/scope/index.d.ts +1 -1
- package/dist/wirings/scope/index.js +1 -1
- package/dist/wirings/scope/scope.types.d.ts +7 -9
- package/dist/wirings/scope/validate-scope-definitions.d.ts +2 -21
- package/dist/wirings/scope/validate-scope-definitions.js +3 -21
- package/dist/wirings/secret/index.d.ts +1 -1
- package/dist/wirings/secret/index.js +1 -1
- package/dist/wirings/secret/secret.types.d.ts +19 -15
- package/dist/wirings/secret/secret.types.js +1 -1
- package/dist/wirings/secret/validate-secret-definitions.d.ts +2 -4
- package/dist/wirings/trigger/trigger-runner.d.ts +0 -27
- package/dist/wirings/trigger/trigger-runner.js +1 -24
- package/dist/wirings/trigger/trigger.types.d.ts +1 -82
- package/dist/wirings/trigger/trigger.types.js +0 -34
- package/dist/wirings/variable/index.d.ts +1 -1
- package/dist/wirings/variable/index.js +1 -1
- package/dist/wirings/variable/validate-variable-definitions.d.ts +2 -4
- package/dist/wirings/variable/variable.types.d.ts +1 -13
- package/dist/wirings/variable/variable.types.js +1 -1
- package/dist/wirings/virtual-user/index.d.ts +27 -0
- package/dist/wirings/virtual-user/index.js +8 -0
- package/dist/wirings/virtual-user/run-virtual-user.d.ts +92 -0
- package/dist/wirings/virtual-user/run-virtual-user.js +478 -0
- package/dist/wirings/virtual-user/virtual-user-agents.d.ts +38 -0
- package/dist/wirings/virtual-user/virtual-user-agents.js +24 -0
- package/dist/wirings/virtual-user/virtual-user-catalogue.d.ts +92 -0
- package/dist/wirings/virtual-user/virtual-user-catalogue.js +134 -0
- package/dist/wirings/virtual-user/virtual-user-derive.d.ts +26 -0
- package/dist/wirings/virtual-user/virtual-user-derive.js +137 -0
- package/dist/wirings/virtual-user/virtual-user-dispositions.d.ts +79 -0
- package/dist/wirings/virtual-user/virtual-user-dispositions.js +128 -0
- package/dist/wirings/virtual-user/virtual-user-intents.d.ts +78 -0
- package/dist/wirings/virtual-user/virtual-user-intents.js +142 -0
- package/dist/wirings/virtual-user/virtual-user-rng.d.ts +24 -0
- package/dist/wirings/virtual-user/virtual-user-rng.js +44 -0
- package/dist/wirings/virtual-user/virtual-user-target.d.ts +21 -0
- package/dist/wirings/virtual-user/virtual-user-target.js +34 -0
- package/dist/wirings/virtual-user/virtual-user.types.d.ts +199 -0
- package/dist/wirings/virtual-user/virtual-user.types.js +8 -0
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +5 -5
- package/dist/wirings/workflow/dsl/workflow-runner.d.ts +0 -4
- package/dist/wirings/workflow/dsl/workflow-runner.js +0 -4
- package/dist/wirings/workflow/feature.d.ts +0 -19
- package/dist/wirings/workflow/feature.js +0 -19
- package/dist/wirings/workflow/graph/graph-node.d.ts +0 -98
- package/dist/wirings/workflow/graph/graph-node.js +0 -34
- package/dist/wirings/workflow/graph/graph-runner.js +6 -41
- package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +0 -4
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -58
- package/dist/wirings/workflow/graph/workflow-graph.types.js +0 -6
- package/dist/wirings/workflow/index.d.ts +5 -7
- package/dist/wirings/workflow/index.js +3 -17
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +87 -5
- package/dist/wirings/workflow/pikku-scenario-service.js +204 -42
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +7 -459
- package/dist/wirings/workflow/pikku-workflow-service.js +58 -551
- package/dist/wirings/workflow/run-timeline.d.ts +0 -47
- package/dist/wirings/workflow/run-timeline.js +0 -22
- package/dist/wirings/workflow/scenario-cookie-jar.d.ts +0 -23
- package/dist/wirings/workflow/scenario-cookie-jar.js +0 -16
- package/dist/wirings/workflow/scenario-poll.d.ts +0 -15
- package/dist/wirings/workflow/scenario-poll.js +0 -12
- package/dist/wirings/workflow/scenario-prose.d.ts +0 -28
- package/dist/wirings/workflow/scenario-prose.js +0 -18
- package/dist/wirings/workflow/scenario-step-guards.d.ts +0 -13
- package/dist/wirings/workflow/scenario-step-guards.js +1 -14
- package/dist/wirings/workflow/scenario-step.types.d.ts +72 -6
- package/dist/wirings/workflow/scenario-step.types.js +5 -1
- package/dist/wirings/workflow/scenario-surface.d.ts +16 -0
- package/dist/wirings/workflow/scenario-surface.js +56 -0
- package/dist/wirings/workflow/workflow-invocation-id.d.ts +0 -18
- package/dist/wirings/workflow/workflow-invocation-id.js +2 -22
- package/dist/wirings/workflow/workflow-queue-workers.d.ts +0 -20
- package/dist/wirings/workflow/workflow-queue-workers.js +0 -19
- package/dist/wirings/workflow/workflow.types.d.ts +0 -197
- package/knowledge/decisions/index.md +19 -0
- package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +49 -0
- package/knowledge/decisions/internals/actor-flow-conversations-seed-a-hidden-kickoff-message.md +23 -0
- package/knowledge/decisions/internals/actor-flow-drives-the-target-through-a-transport-seam.md +24 -0
- package/knowledge/decisions/internals/actor-flow-verdicts-are-llm-self-evaluations.md +25 -0
- package/knowledge/decisions/internals/addon-package-roots-resolve-by-walking-node-module-search-paths.md +26 -0
- package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +33 -0
- package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +28 -0
- package/knowledge/decisions/internals/ai-agent-agui-bridge-obeys-the-client-ordering-contract.md +29 -0
- package/knowledge/decisions/internals/ai-agent-audio-chunks-carry-the-format-the-provider-returned.md +20 -0
- package/knowledge/decisions/internals/ai-agent-credential-suspensions-hide-the-tool-result.md +26 -0
- package/knowledge/decisions/internals/ai-agent-delegate-and-supervise-hide-different-text.md +26 -0
- package/knowledge/decisions/internals/ai-agent-llm-tool-arguments-have-nulls-stripped.md +23 -0
- package/knowledge/decisions/internals/ai-agent-model-config-stays-a-single-resolution-seam.md +25 -0
- package/knowledge/decisions/internals/ai-agent-onerror-hooks-cannot-change-the-failure.md +22 -0
- package/knowledge/decisions/internals/ai-agent-runner-methods-must-keep-their-receiver.md +22 -0
- package/knowledge/decisions/internals/ai-agent-stream-persistence-is-best-effort.md +27 -0
- package/knowledge/decisions/internals/ai-agent-sub-agents-inherit-the-parent-context-block.md +26 -0
- package/knowledge/decisions/internals/ai-agent-tool-execute-failures-are-logged-unconditionally.md +25 -0
- package/knowledge/decisions/internals/ai-agent-voice-input-transcribes-audio-parts-in-place.md +22 -0
- package/knowledge/decisions/internals/ai-agent-working-memory-is-persisted-only-when-valid.md +25 -0
- package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +30 -0
- package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +31 -0
- package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md +29 -0
- package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +28 -0
- package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +27 -0
- package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +28 -0
- package/knowledge/decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md +34 -0
- package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +29 -0
- package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +34 -0
- package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +44 -0
- package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +39 -0
- package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +42 -0
- package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +39 -0
- package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +43 -0
- package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +38 -0
- package/knowledge/decisions/internals/core-state-is-a-global-map-written-only-at-registration-time.md +44 -0
- package/knowledge/decisions/internals/email-meta-is-read-uncached-because-codegen-rewrites-it-mid-session.md +27 -0
- package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +32 -0
- package/knowledge/decisions/internals/gateway-webhook-challenges-echo-bytes-not-json.md +28 -0
- package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +31 -0
- package/knowledge/decisions/internals/generated-src-paths-in-pikku-meta-are-absolute.md +26 -0
- package/knowledge/decisions/internals/http-request-bodies-are-read-once-and-shared.md +32 -0
- package/knowledge/decisions/internals/http-route-groups-cascade-config-in-a-fixed-order.md +28 -0
- package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +30 -0
- package/knowledge/decisions/internals/http-runner-logs-through-a-trace-scoped-logger-functions-do-not.md +26 -0
- package/knowledge/decisions/internals/http-set-cookie-headers-are-appended-never-joined.md +28 -0
- package/knowledge/decisions/internals/http-sse-streams-flush-headers-only-after-middleware.md +32 -0
- package/knowledge/decisions/internals/http-wiring-without-metadata-is-skipped-not-fatal.md +26 -0
- package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +25 -0
- package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +26 -0
- package/knowledge/decisions/internals/index.md +113 -0
- package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +25 -0
- package/knowledge/decisions/internals/local-trigger-and-gateway-services-assume-a-single-process.md +26 -0
- package/knowledge/decisions/internals/node-only-builtins-are-imported-dynamically.md +24 -0
- package/knowledge/decisions/internals/queue-group-concurrency-keeps-one-shared-queue-fair.md +28 -0
- package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +27 -0
- package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +31 -0
- package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +32 -0
- package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +27 -0
- package/knowledge/decisions/internals/scenario-meta-lives-apart-from-app-meta-but-merges-when-read-off-disk.md +26 -0
- package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +27 -0
- package/knowledge/decisions/internals/scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md +30 -0
- package/knowledge/decisions/internals/serverless-channel-disconnect-must-tolerate-a-missing-channel.md +28 -0
- package/knowledge/decisions/internals/the-dev-queue-copies-prod-timing-and-serialization-semantics.md +30 -0
- package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +29 -0
- package/knowledge/decisions/internals/the-in-memory-workflow-service-is-inline-only-and-single-process.md +27 -0
- package/knowledge/decisions/internals/the-kek-salt-is-scoped-to-the-key-version.md +40 -0
- package/knowledge/decisions/internals/the-schema-service-is-never-stubbed.md +26 -0
- package/knowledge/decisions/internals/trigger-declaration-is-split-from-trigger-source.md +33 -0
- package/knowledge/decisions/internals/typed-secret-service-caches-for-the-process-lifetime.md +26 -0
- package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +26 -0
- package/knowledge/decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md +25 -0
- package/knowledge/decisions/internals/whether-a-run-is-inline-is-read-from-the-run-record.md +58 -0
- package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +34 -0
- package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +42 -0
- package/knowledge/decisions/internals/workflow-dsl-meta-separates-runtime-expressions-from-literals.md +38 -0
- package/knowledge/decisions/internals/workflow-features-resolve-scenarios-by-object-identity.md +29 -0
- package/knowledge/decisions/internals/workflow-graph-inline-and-queued-runs-share-one-planner.md +42 -0
- package/knowledge/decisions/internals/workflow-graph-node-notes-are-excluded-from-the-graph-hash.md +25 -0
- package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +29 -0
- package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +43 -0
- package/knowledge/decisions/internals/workflow-queued-step-dispatch-requires-an-explicit-opt-in.md +29 -0
- package/knowledge/decisions/internals/workflow-queues-are-per-workflow-by-default.md +42 -0
- package/knowledge/decisions/internals/workflow-repeated-step-names-get-an-ordinal-suffix.md +33 -0
- package/knowledge/decisions/internals/workflow-replay-reads-its-steps-once-and-caches-only-the-immutable-half.md +32 -0
- package/knowledge/decisions/internals/workflow-retries-are-owned-by-the-workflow-not-the-queue.md +31 -0
- package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +39 -0
- package/knowledge/decisions/internals/workflow-run-mirror-is-never-a-source-of-truth.md +29 -0
- package/knowledge/decisions/internals/workflow-run-polling-backs-off-to-the-callers-ceiling.md +33 -0
- package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +37 -0
- package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +50 -0
- package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +43 -0
- package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +32 -0
- package/knowledge/decisions/internals/workflow-scenario-quarantine-reason-lives-in-code.md +18 -0
- package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +34 -0
- package/knowledge/decisions/internals/workflow-step-compensation-runs-as-its-own-durable-step.md +26 -0
- package/knowledge/decisions/internals/workflow-step-dispatch-failure-is-transient-not-a-run-failure.md +33 -0
- package/knowledge/decisions/internals/workflow-step-lock-is-held-only-to-claim-the-step.md +27 -0
- package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +34 -0
- package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +38 -0
- package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +30 -0
- package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +26 -0
- package/knowledge/decisions/security/actor-flow-missing-approval-decisions-default-to-denied.md +22 -0
- package/knowledge/decisions/security/actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +27 -0
- package/knowledge/decisions/security/actor-sign-in-only-works-for-actor-flagged-users.md +27 -0
- package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +43 -0
- package/knowledge/decisions/security/addon-config-gates-apply-only-at-the-namespaced-rpc-boundary.md +52 -0
- package/knowledge/decisions/security/addon-scopes-are-resolved-where-the-function-runs.md +46 -0
- package/knowledge/decisions/security/ai-agent-approval-forwarding-requires-a-symbol-brand.md +27 -0
- package/knowledge/decisions/security/ai-agent-credential-requests-are-symbol-branded.md +37 -0
- package/knowledge/decisions/security/ai-agent-gate-requires-a-session-only-when-auth-is-true.md +31 -0
- package/knowledge/decisions/security/ai-agent-ownership-failures-never-echo-the-resource.md +23 -0
- package/knowledge/decisions/security/ai-agent-resume-re-runs-the-authorization-gate.md +22 -0
- package/knowledge/decisions/security/ai-agent-sessionless-deployments-have-no-thread-ownership.md +39 -0
- package/knowledge/decisions/security/ai-agent-thread-ownership-composes-the-session-principal.md +30 -0
- package/knowledge/decisions/security/ai-agent-tool-filtering-reads-the-live-function-config.md +24 -0
- package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +30 -0
- package/knowledge/decisions/security/an-exposed-ungated-function-is-a-codegen-warning.md +49 -0
- package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +76 -0
- package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +39 -0
- package/knowledge/decisions/security/core-secrets-use-a-per-secret-dek-wrapped-by-a-kek.md +37 -0
- package/knowledge/decisions/security/gateway-handlers-run-through-the-function-runner-gate.md +31 -0
- package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +30 -0
- package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +40 -0
- package/knowledge/decisions/security/http-error-detail-is-withheld-from-clients-in-production.md +33 -0
- package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +46 -0
- package/knowledge/decisions/security/index.md +55 -0
- package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +27 -0
- package/knowledge/decisions/security/passphrases-are-stretched-key-material-is-expanded.md +40 -0
- package/knowledge/decisions/security/permission-auth-filtering-requires-live-permission-functions.md +31 -0
- package/knowledge/decisions/security/pikku-carries-actor-scopes-as-data-and-the-app-grants-them.md +26 -0
- package/knowledge/decisions/security/queue-job-identities-are-signed-at-enqueue.md +69 -0
- package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +39 -0
- package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +34 -0
- package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +49 -0
- package/knowledge/decisions/security/scenario-step-functions-are-never-externally-invocable.md +30 -0
- package/knowledge/decisions/security/scope-resolution-happens-at-the-session-boundary-and-sync-never-deletes.md +28 -0
- package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +34 -0
- package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +37 -0
- package/knowledge/decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md +25 -0
- package/knowledge/decisions/security/workflow-actor-steps-always-use-the-real-transport.md +34 -0
- package/knowledge/decisions/security/workflow-approval-payloads-are-validated-on-replay-inside-the-workflow.md +40 -0
- package/knowledge/decisions/security/workflow-queued-steps-rehydrate-their-session-from-the-run-wire.md +32 -0
- package/knowledge/decisions/security/workflow-scenario-sessions-are-isolated-per-actor-and-per-scenario.md +32 -0
- package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +31 -0
- package/knowledge/index.md +24 -0
- package/knowledge/questions/index.md +15 -0
- package/package.json +4 -2
- package/run-tests.sh +0 -0
- package/src/crypto-utils.test.ts +460 -19
- package/src/crypto-utils.ts +283 -55
- package/src/data-classification.ts +1 -7
- package/src/dev/hot-reload.test.ts +0 -4
- package/src/dev/hot-reload.ts +11 -30
- package/src/dev/module-runner.ts +7 -32
- package/src/dev/reload-meta.ts +9 -29
- package/src/errors/error-handler.ts +20 -35
- package/src/errors/error.test.ts +30 -1
- package/src/errors/errors.ts +73 -157
- package/src/function/abort-scope.test.ts +97 -0
- package/src/function/abort-scope.ts +80 -0
- package/src/function/function-runner.test.ts +75 -7
- package/src/function/function-runner.ts +73 -30
- package/src/function/functions.types.ts +56 -136
- package/src/function/list.types.test.ts +3 -25
- package/src/function/list.types.ts +12 -62
- package/src/gopass-secrets-removed.test.ts +51 -0
- package/src/handle-error.test.ts +108 -1
- package/src/handle-error.ts +8 -18
- package/src/index.ts +60 -1
- package/src/middleware/auth-apikey.test.ts +0 -1
- package/src/middleware/auth-apikey.ts +0 -17
- package/src/middleware/auth-bearer.test.ts +0 -3
- package/src/middleware/auth-bearer.ts +3 -40
- package/src/middleware/auth-cookie.test.ts +0 -6
- package/src/middleware/auth-cookie.ts +2 -26
- package/src/middleware/cors.test.ts +34 -0
- package/src/middleware/cors.ts +12 -33
- package/src/middleware/remote-auth.test.ts +24 -9
- package/src/middleware/remote-auth.ts +10 -2
- package/src/middleware/telemetry.ts +2 -31
- package/src/middleware-runner.test.ts +0 -2
- package/src/middleware-runner.ts +5 -74
- package/src/permissions.test.ts +30 -0
- package/src/permissions.ts +24 -74
- package/src/pikku-request.ts +0 -6
- package/src/pikku-state.ts +2 -30
- package/src/production-barrels-stay-lean.test.ts +110 -0
- package/src/remote.test.ts +172 -0
- package/src/remote.ts +17 -7
- package/src/schema.test.ts +103 -0
- package/src/schema.ts +35 -18
- package/src/scopes.ts +7 -48
- package/src/services/ai-agent-runner-service.ts +20 -0
- package/src/services/ai-embedding-service.ts +3 -25
- package/src/services/audit-service.ts +1 -2
- package/src/services/content-service.ts +1 -46
- package/src/services/credential-service.ts +3 -40
- package/src/services/credential-wire-service.test.ts +0 -2
- package/src/services/deployment-service.ts +3 -9
- package/src/services/gateway-service.ts +0 -15
- package/src/services/{http-scenario-actors-converse.test.ts → http-personas-converse.test.ts} +38 -9
- package/src/services/{http-scenario-actors.test.ts → http-personas.test.ts} +39 -22
- package/src/services/{http-scenario-actors.ts → http-personas.ts} +85 -45
- package/src/services/in-memory-queue-service.ts +1 -15
- package/src/services/in-memory-trigger-service.ts +1 -18
- package/src/services/in-memory-workflow-service.test.ts +0 -13
- package/src/services/in-memory-workflow-service.ts +4 -38
- package/src/services/index.ts +20 -15
- package/src/services/istanbul-coverage-service.ts +2 -8
- package/src/services/jwt-service.ts +1 -16
- package/src/services/local-content.test.ts +159 -27
- package/src/services/local-content.ts +55 -23
- package/src/services/local-gateway-service.ts +2 -17
- package/src/services/local-secrets.ts +0 -4
- package/src/services/logger-console.test.ts +0 -1
- package/src/services/logger-console.ts +3 -7
- package/src/services/logger.ts +2 -37
- package/src/services/meta-service.test.ts +1 -5
- package/src/services/meta-service.ts +41 -61
- package/src/services/{scenario-actors-service.ts → personas-service.ts} +48 -43
- package/src/services/pikku-user-id.ts +0 -4
- package/src/services/queue-webhook-service.ts +9 -41
- package/src/services/scheduler-service.ts +1 -50
- package/src/services/schema-service.ts +1 -24
- package/src/services/scope-service.ts +50 -34
- package/src/services/scoped-secret-service.ts +0 -4
- package/src/services/secret-host-binding.test.ts +138 -0
- package/src/services/secret-host-binding.ts +51 -0
- package/src/services/secret-service.ts +5 -33
- package/src/services/secretless.test.ts +54 -0
- package/src/services/secretless.ts +29 -0
- package/src/services/stub-tracker.ts +8 -18
- package/src/services/system-role-guard.test.ts +93 -0
- package/src/services/system-role-guard.ts +71 -0
- package/src/services/trigger-service.ts +0 -12
- package/src/services/typed-secret-service.ts +1 -7
- package/src/services/v8-coverage-service.ts +3 -6
- package/src/services/variables-service.ts +1 -8
- package/src/services/webhook-service.ts +19 -63
- package/src/services/workflow-service.ts +3 -20
- package/src/testing/service-tests.ts +0 -26
- package/src/time-utils.ts +1 -19
- package/src/types/core.types.ts +116 -229
- package/src/types/state.types.ts +7 -9
- package/src/utils/hmac.ts +4 -10
- package/src/utils/safe-fetch.ts +13 -54
- package/src/utils.test.ts +11 -2
- package/src/utils.ts +6 -15
- package/src/wirings/actor-flow/actor-flow.types.ts +1 -34
- package/src/wirings/actor-flow/index.ts +0 -9
- package/src/wirings/actor-flow/run-conversation.test.ts +11 -6
- package/src/wirings/actor-flow/run-conversation.ts +19 -12
- package/src/wirings/ai-agent/ai-agent-agui.test.ts +75 -10
- package/src/wirings/ai-agent/ai-agent-agui.ts +36 -17
- package/src/wirings/ai-agent/ai-agent-helpers.ts +20 -0
- package/src/wirings/ai-agent/ai-agent-interrupt.test.ts +842 -0
- package/src/wirings/ai-agent/ai-agent-interrupt.ts +399 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +0 -2
- package/src/wirings/ai-agent/ai-agent-model-config.ts +1 -9
- package/src/wirings/ai-agent/ai-agent-prepare.test.ts +202 -31
- package/src/wirings/ai-agent/ai-agent-prepare.ts +82 -138
- package/src/wirings/ai-agent/ai-agent-registry.test.ts +191 -6
- package/src/wirings/ai-agent/ai-agent-registry.ts +18 -1
- package/src/wirings/ai-agent/ai-agent-resume-authorization.test.ts +0 -2
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +11 -9
- package/src/wirings/ai-agent/ai-agent-runner.ts +67 -33
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +205 -103
- package/src/wirings/ai-agent/ai-agent-stream.ts +192 -75
- package/src/wirings/ai-agent/ai-agent-thread-ownership.test.ts +301 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +85 -4
- package/src/wirings/ai-agent/index.ts +35 -3
- package/src/wirings/ai-agent/voice-input.test.ts +72 -7
- package/src/wirings/ai-agent/voice-input.ts +48 -3
- package/src/wirings/ai-agent/voice-output.test.ts +422 -0
- package/src/wirings/ai-agent/voice-output.ts +216 -56
- package/src/wirings/channel/channel-common.ts +15 -20
- package/src/wirings/channel/channel-handler.test.ts +50 -0
- package/src/wirings/channel/channel-handler.ts +32 -11
- package/src/wirings/channel/channel-host-rpc.test.ts +150 -0
- package/src/wirings/channel/channel-host-rpc.ts +69 -0
- package/src/wirings/channel/channel-middleware-runner.test.ts +0 -1
- package/src/wirings/channel/channel-middleware-runner.ts +0 -12
- package/src/wirings/channel/channel-rpc-registry.ts +116 -0
- package/src/wirings/channel/channel-rpc-responder.ts +117 -0
- package/src/wirings/channel/channel-rpc-service.ts +146 -0
- package/src/wirings/channel/channel-rpc-validators.ts +65 -0
- package/src/wirings/channel/channel-rpc.test.ts +820 -0
- package/src/wirings/channel/channel-rpc.ts +5 -0
- package/src/wirings/channel/channel-rpc.types.ts +150 -0
- package/src/wirings/channel/channel-runner.ts +0 -14
- package/src/wirings/channel/channel-store.ts +0 -10
- package/src/wirings/channel/channel.types.ts +19 -8
- package/src/wirings/channel/define-channel-routes.ts +0 -20
- package/src/wirings/channel/eventhub-service.ts +0 -18
- package/src/wirings/channel/index.ts +35 -0
- package/src/wirings/channel/local/local-channel-handler.ts +3 -1
- package/src/wirings/channel/local/local-channel-runner.test.ts +0 -10
- package/src/wirings/channel/local/local-channel-runner.ts +3 -1
- package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -13
- package/src/wirings/channel/local/local-eventhub-service.ts +2 -37
- package/src/wirings/channel/log-channels.ts +0 -4
- package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +83 -2
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +7 -0
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +2 -5
- package/src/wirings/cli/channel/cli-approval.test.ts +177 -0
- package/src/wirings/cli/channel/cli-approval.ts +135 -0
- package/src/wirings/cli/channel/cli-channel-runner.ts +4 -26
- package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +169 -0
- package/src/wirings/cli/channel/cli-raw-channel-runner.ts +59 -16
- package/src/wirings/cli/channel/cli-raw-client-runner.test.ts +480 -0
- package/src/wirings/cli/channel/cli-raw-client-runner.ts +155 -0
- package/src/wirings/cli/channel/index.ts +9 -0
- package/src/wirings/cli/cli-runner.test.ts +0 -1
- package/src/wirings/cli/cli-runner.ts +46 -88
- package/src/wirings/cli/cli.types.ts +14 -3
- package/src/wirings/cli/command-parser.test.ts +0 -4
- package/src/wirings/cli/command-parser.ts +11 -91
- package/src/wirings/cli/define-cli-commands.ts +1 -17
- package/src/wirings/credential/credential.types.ts +0 -12
- package/src/wirings/credential/{wire-credential.ts → define-credential.ts} +7 -7
- package/src/wirings/credential/index.ts +1 -1
- package/src/wirings/credential/validate-credential-definitions.ts +2 -4
- package/src/wirings/gateway/gateway-runner.test.ts +1 -21
- package/src/wirings/gateway/gateway-runner.ts +8 -110
- package/src/wirings/gateway/gateway.types.ts +7 -80
- package/src/wirings/http/http-routes.test.ts +0 -3
- package/src/wirings/http/http-routes.ts +0 -86
- package/src/wirings/http/http-runner.test.ts +0 -1
- package/src/wirings/http/http-runner.ts +12 -168
- package/src/wirings/http/http.types.ts +17 -62
- package/src/wirings/http/index.ts +5 -1
- package/src/wirings/http/log-http-routes.ts +0 -4
- package/src/wirings/http/pikku-fetch-http-request.test.ts +88 -7
- package/src/wirings/http/pikku-fetch-http-request.ts +74 -50
- package/src/wirings/http/pikku-fetch-http-response.test.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-response.ts +0 -3
- package/src/wirings/http/routers/path-to-regex.test.ts +4 -17
- package/src/wirings/http/routers/path-to-regex.ts +2 -13
- package/src/wirings/http/web-request.test.ts +33 -2
- package/src/wirings/http/web-request.ts +30 -17
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -1
- package/src/wirings/mcp/mcp-runner.test.ts +40 -0
- package/src/wirings/mcp/mcp-runner.ts +9 -15
- package/src/wirings/mcp/mcp.types.ts +7 -42
- package/src/wirings/oauth2/oauth2.types.ts +0 -30
- package/src/wirings/persona/define-personas.ts +29 -0
- package/src/wirings/persona/index.ts +62 -0
- package/src/wirings/persona/persona-email.ts +87 -0
- package/src/wirings/persona/persona-environments.test.ts +183 -0
- package/src/wirings/persona/persona-environments.ts +138 -0
- package/src/wirings/persona/persona-mailbox.ts +156 -0
- package/src/wirings/persona/persona.test.ts +220 -0
- package/src/wirings/persona/persona.types.ts +131 -0
- package/src/wirings/persona/validate-personas.ts +133 -0
- package/src/wirings/queue/index.ts +13 -3
- package/src/wirings/queue/queue-identity.test.ts +453 -0
- package/src/wirings/queue/queue-identity.ts +173 -0
- package/src/wirings/queue/queue-runner.ts +12 -31
- package/src/wirings/queue/queue.types.ts +19 -89
- package/src/wirings/queue/register-queue-helper.ts +0 -14
- package/src/wirings/queue/signed-queue-service.ts +59 -0
- package/src/wirings/queue/validate-worker-config.ts +2 -28
- package/src/wirings/role/define-system-role.ts +33 -0
- package/src/wirings/role/index.ts +13 -0
- package/src/wirings/role/role.test.ts +104 -0
- package/src/wirings/role/role.types.ts +47 -0
- package/src/wirings/role/validate-role-definitions.ts +93 -0
- package/src/wirings/rpc/addon-auth-tags.test.ts +223 -0
- package/src/wirings/rpc/addon-runner.ts +0 -56
- package/src/wirings/rpc/addon-scopes.test.ts +225 -0
- package/src/wirings/rpc/remote-addon-auth.ts +1 -13
- package/src/wirings/rpc/rpc-runner.test.ts +186 -2
- package/src/wirings/rpc/rpc-runner.ts +145 -127
- package/src/wirings/rpc/rpc-types.ts +11 -6
- package/src/wirings/rpc/wire-addon.test.ts +43 -1
- package/src/wirings/rpc/wire-addon.ts +99 -0
- package/src/wirings/rpc/wire-remote-addon.ts +9 -29
- package/src/wirings/scheduler/log-schedulers.ts +0 -4
- package/src/wirings/scheduler/scheduler-runner.test.ts +1 -8
- package/src/wirings/scheduler/scheduler-runner.ts +0 -2
- package/src/wirings/scheduler/scheduler.types.ts +1 -14
- package/src/wirings/scope/{wire-scope.ts → define-scope.ts} +5 -6
- package/src/wirings/scope/index.ts +1 -1
- package/src/wirings/scope/scope.test.ts +1 -2
- package/src/wirings/scope/scope.types.ts +7 -9
- package/src/wirings/scope/validate-scope-definitions.ts +3 -21
- package/src/wirings/secret/index.ts +1 -1
- package/src/wirings/secret/secret.types.ts +19 -15
- package/src/wirings/secret/validate-secret-definitions.ts +2 -4
- package/src/wirings/trigger/trigger-runner.ts +1 -27
- package/src/wirings/trigger/trigger.types.ts +1 -82
- package/src/wirings/variable/index.ts +1 -1
- package/src/wirings/variable/validate-variable-definitions.ts +2 -4
- package/src/wirings/variable/variable.types.ts +1 -13
- package/src/wirings/virtual-user/index.ts +76 -0
- package/src/wirings/virtual-user/run-virtual-user.test.ts +765 -0
- package/src/wirings/virtual-user/run-virtual-user.ts +671 -0
- package/src/wirings/virtual-user/virtual-user-agents.test.ts +65 -0
- package/src/wirings/virtual-user/virtual-user-agents.ts +57 -0
- package/src/wirings/virtual-user/virtual-user-catalogue.test.ts +215 -0
- package/src/wirings/virtual-user/virtual-user-catalogue.ts +184 -0
- package/src/wirings/virtual-user/virtual-user-derive.test.ts +398 -0
- package/src/wirings/virtual-user/virtual-user-derive.ts +173 -0
- package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +63 -0
- package/src/wirings/virtual-user/virtual-user-dispositions.ts +213 -0
- package/src/wirings/virtual-user/virtual-user-intents.test.ts +208 -0
- package/src/wirings/virtual-user/virtual-user-intents.ts +185 -0
- package/src/wirings/virtual-user/virtual-user-rng.test.ts +72 -0
- package/src/wirings/virtual-user/virtual-user-rng.ts +50 -0
- package/src/wirings/virtual-user/virtual-user-target.ts +47 -0
- package/src/wirings/virtual-user/virtual-user.types.ts +219 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +5 -4
- package/src/wirings/workflow/dsl/workflow-runner.ts +0 -4
- package/src/wirings/workflow/feature.ts +0 -19
- package/src/wirings/workflow/graph/graph-node.ts +0 -136
- package/src/wirings/workflow/graph/graph-runner.test.ts +20 -19
- package/src/wirings/workflow/graph/graph-runner.ts +6 -41
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -4
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -58
- package/src/wirings/workflow/index.ts +10 -44
- package/src/wirings/workflow/pikku-scenario-service.ts +235 -52
- package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -39
- package/src/wirings/workflow/pikku-workflow-service.ts +77 -674
- package/src/wirings/workflow/run-timeline.test.ts +7 -19
- package/src/wirings/workflow/run-timeline.ts +0 -56
- package/src/wirings/workflow/scenario-cookie-jar.test.ts +0 -1
- package/src/wirings/workflow/scenario-cookie-jar.ts +0 -25
- package/src/wirings/workflow/scenario-expectations.test.ts +2 -7
- package/src/wirings/workflow/scenario-hooks.test.ts +2 -7
- package/src/wirings/workflow/scenario-poll.test.ts +0 -2
- package/src/wirings/workflow/scenario-poll.ts +0 -15
- package/src/wirings/workflow/scenario-prose.ts +0 -28
- package/src/wirings/workflow/scenario-service.test.ts +2 -9
- package/src/wirings/workflow/scenario-step-guards.ts +1 -14
- package/src/wirings/workflow/scenario-step.test.ts +159 -14
- package/src/wirings/workflow/scenario-step.types.ts +82 -6
- package/src/wirings/workflow/scenario-surface.test.ts +145 -0
- package/src/wirings/workflow/scenario-surface.ts +71 -0
- package/src/wirings/workflow/workflow-dispatch-durability.test.ts +14 -15
- package/src/wirings/workflow/workflow-dispatch-payload.test.ts +0 -4
- package/src/wirings/workflow/workflow-inline-authority.test.ts +169 -0
- package/src/wirings/workflow/workflow-invocation-id.test.ts +0 -2
- package/src/wirings/workflow/workflow-invocation-id.ts +2 -22
- package/src/wirings/workflow/workflow-mirror.test.ts +0 -7
- package/src/wirings/workflow/workflow-on-error.test.ts +0 -9
- package/src/wirings/workflow/workflow-queue-workers.ts +0 -21
- package/src/wirings/workflow/workflow-replay-snapshot.test.ts +8 -7
- package/src/wirings/workflow/workflow-retry-policy.test.ts +0 -5
- package/src/wirings/workflow/workflow-run-context.test.ts +5 -10
- package/src/wirings/workflow/workflow-run-polling.test.ts +0 -5
- package/src/wirings/workflow/workflow-step-ordinal.test.ts +19 -4
- package/src/wirings/workflow/workflow-step-session.test.ts +0 -7
- package/src/wirings/workflow/workflow.types.ts +0 -203
- package/tsconfig.tsbuildinfo +1 -1
- package/src/middleware/timeout.ts +0 -22
- package/src/pikku-response.ts +0 -5
- package/src/services/gopass-secrets.ts +0 -78
- package/src/wirings/mcp/mcp-endpoint-registry.test.d.ts +0 -1
- package/src/wirings/workflow/dsl/index.ts +0 -36
- package/src/wirings/workflow/graph/index.ts +0 -15
|
@@ -1,21 +1,6 @@
|
|
|
1
1
|
import { pikkuMiddleware, pikkuMiddlewareFactory } from '../types/core.types.js'
|
|
2
2
|
|
|
3
|
-
/**
|
|
4
|
-
* Outer telemetry middleware that captures total request duration and outcome.
|
|
5
|
-
* Runs at `highest` priority (outermost in the middleware chain).
|
|
6
|
-
*
|
|
7
|
-
* Emits a structured JSON log entry with `__pikku_telemetry: 'end'` containing:
|
|
8
|
-
* - Total duration (including all middleware)
|
|
9
|
-
* - Outcome (ok/error)
|
|
10
|
-
* - Wire metadata (wireType, wireId, traceId)
|
|
11
|
-
* - HTTP details (method, path, status) if applicable
|
|
12
|
-
*
|
|
13
|
-
* @example
|
|
14
|
-
* ```typescript
|
|
15
|
-
* import { telemetryOuter } from '@pikku/core/middleware'
|
|
16
|
-
* addTagMiddleware('myTag', [telemetryOuter()])
|
|
17
|
-
* ```
|
|
18
|
-
*/
|
|
3
|
+
/** Outermost telemetry: total duration, including every middleware. */
|
|
19
4
|
export const telemetryOuter = pikkuMiddlewareFactory<{
|
|
20
5
|
environmentId?: string
|
|
21
6
|
orgId?: string
|
|
@@ -58,21 +43,7 @@ export const telemetryOuter = pikkuMiddlewareFactory<{
|
|
|
58
43
|
})
|
|
59
44
|
})
|
|
60
45
|
|
|
61
|
-
/**
|
|
62
|
-
* Inner telemetry middleware that captures function execution duration and user context.
|
|
63
|
-
* Runs at `lowest` priority (innermost, closest to the function).
|
|
64
|
-
*
|
|
65
|
-
* Emits a structured JSON log entry with `__pikku_telemetry: 'end'` containing:
|
|
66
|
-
* - Function-only duration (excluding outer middleware like auth)
|
|
67
|
-
* - User identity (pikkuUserId) if authenticated
|
|
68
|
-
* - Wire metadata (wireType, wireId, traceId)
|
|
69
|
-
*
|
|
70
|
-
* @example
|
|
71
|
-
* ```typescript
|
|
72
|
-
* import { telemetryInner } from '@pikku/core/middleware'
|
|
73
|
-
* addTagMiddleware('myTag', [telemetryInner()])
|
|
74
|
-
* ```
|
|
75
|
-
*/
|
|
46
|
+
/** Innermost telemetry: function-only duration, excluding outer middleware. */
|
|
76
47
|
export const telemetryInner = pikkuMiddlewareFactory<{
|
|
77
48
|
environmentId?: string
|
|
78
49
|
orgId?: string
|
|
@@ -114,7 +114,6 @@ describe('combineMiddleware', () => {
|
|
|
114
114
|
})
|
|
115
115
|
|
|
116
116
|
test('should execute middleware in correct order: wireInheritedMiddleware (tags) → wireMiddleware → funcInheritedMiddleware (tags) → funcMiddleware', () => {
|
|
117
|
-
// Setup tagged middleware
|
|
118
117
|
const wiringTagMiddleware: CorePikkuMiddleware = async (
|
|
119
118
|
services,
|
|
120
119
|
wire,
|
|
@@ -441,7 +440,6 @@ describe('runMiddleware', () => {
|
|
|
441
440
|
}
|
|
442
441
|
)
|
|
443
442
|
|
|
444
|
-
// Should only execute each middleware once
|
|
445
443
|
assert.deepEqual(executionOrder, ['middleware1', 'middleware2', 'main'])
|
|
446
444
|
})
|
|
447
445
|
|
package/src/middleware-runner.ts
CHANGED
|
@@ -31,23 +31,6 @@ const sortByPriority = (
|
|
|
31
31
|
)
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
/**
|
|
35
|
-
* Runs a chain of middleware functions in sequence before executing the main function.
|
|
36
|
-
*
|
|
37
|
-
* @param services - An object containing services (e.g., singletonServices, userSession, etc.)
|
|
38
|
-
* @param wire - The wire context, e.g., { http }.
|
|
39
|
-
* @param middlewares - An array of middleware functions to run.
|
|
40
|
-
* @param main - The main function to execute after all middleware have run.
|
|
41
|
-
* @returns A promise resolving to the result of the main function.
|
|
42
|
-
*
|
|
43
|
-
* @example
|
|
44
|
-
* runMiddleware(
|
|
45
|
-
* { ...services, userSession },
|
|
46
|
-
* { http },
|
|
47
|
-
* [middleware1, middleware2, middleware3],
|
|
48
|
-
* async () => { return await runMain(); }
|
|
49
|
-
* );
|
|
50
|
-
*/
|
|
51
34
|
export const runMiddleware = async <
|
|
52
35
|
Middleware extends CorePikkuMiddleware<any, any>,
|
|
53
36
|
>(
|
|
@@ -56,7 +39,6 @@ export const runMiddleware = async <
|
|
|
56
39
|
middlewares: readonly Middleware[],
|
|
57
40
|
main?: () => Promise<unknown>
|
|
58
41
|
): Promise<unknown> => {
|
|
59
|
-
// Sort by priority if not already sorted (cached middleware is pre-sorted)
|
|
60
42
|
const sorted = isSortedByPriority(middlewares)
|
|
61
43
|
? middlewares
|
|
62
44
|
: ([...middlewares].sort(
|
|
@@ -91,14 +73,8 @@ const isSortedByPriority = (
|
|
|
91
73
|
}
|
|
92
74
|
|
|
93
75
|
/**
|
|
94
|
-
* Registers tag-scoped middleware
|
|
95
|
-
*
|
|
96
|
-
*
|
|
97
|
-
* For tree-shaking, wrap in a factory:
|
|
98
|
-
* `export const x = () => addTagMiddleware('tag', [...])`
|
|
99
|
-
*
|
|
100
|
-
* @example
|
|
101
|
-
* export const adminMiddleware = () => addTagMiddleware('admin', [authMiddleware])
|
|
76
|
+
* Registers tag-scoped middleware for any wiring carrying the tag. Wrap in a
|
|
77
|
+
* factory (`export const x = () => addTagMiddleware(...)`) for tree-shaking.
|
|
102
78
|
*/
|
|
103
79
|
export const addTagMiddleware = <PikkuMiddleware extends CorePikkuMiddleware>(
|
|
104
80
|
tag: string,
|
|
@@ -114,14 +90,8 @@ export const addTagMiddleware = <PikkuMiddleware extends CorePikkuMiddleware>(
|
|
|
114
90
|
}
|
|
115
91
|
|
|
116
92
|
/**
|
|
117
|
-
* Registers wire-agnostic global middleware
|
|
118
|
-
* wiring's
|
|
119
|
-
* entries — across HTTP, Channel, Queue, Scheduler, MCP, CLI, Workflow, Agent.
|
|
120
|
-
*
|
|
121
|
-
* Resolution order: global → wire → tag → function.
|
|
122
|
-
*
|
|
123
|
-
* @example
|
|
124
|
-
* addGlobalMiddleware([telemetryMiddleware])
|
|
93
|
+
* Registers wire-agnostic global middleware, which runs at the top of every
|
|
94
|
+
* wiring's chain — before wire-, tag- and function-level entries.
|
|
125
95
|
*/
|
|
126
96
|
export const addGlobalMiddleware = <
|
|
127
97
|
PikkuMiddleware extends CorePikkuMiddleware,
|
|
@@ -140,17 +110,6 @@ export const addGlobalMiddleware = <
|
|
|
140
110
|
return middleware
|
|
141
111
|
}
|
|
142
112
|
|
|
143
|
-
/**
|
|
144
|
-
* Retrieves a registered middleware function by its name.
|
|
145
|
-
*
|
|
146
|
-
* This function looks up middleware that was registered with registerMiddleware.
|
|
147
|
-
* It's used internally by the framework to resolve middleware references in metadata.
|
|
148
|
-
*
|
|
149
|
-
* @param {string} name - The unique name (pikkuFuncId) of the middleware function.
|
|
150
|
-
* @returns {CorePikkuMiddleware | undefined} The middleware function, or undefined if not found.
|
|
151
|
-
*
|
|
152
|
-
* @internal
|
|
153
|
-
*/
|
|
154
113
|
const getMiddlewareByName = (name: string): CorePikkuMiddleware | undefined => {
|
|
155
114
|
const middlewareStore = pikkuState(null, 'misc', 'middleware')
|
|
156
115
|
const middleware = middlewareStore[name]
|
|
@@ -180,28 +139,6 @@ export const clearMiddlewareCache = () => {
|
|
|
180
139
|
}
|
|
181
140
|
}
|
|
182
141
|
|
|
183
|
-
/**
|
|
184
|
-
* Combines wiring-specific middleware with function-level middleware.
|
|
185
|
-
*
|
|
186
|
-
* This function resolves middleware metadata into actual middleware functions and combines them.
|
|
187
|
-
* It filters out wire middleware without tags from inheritedMiddleware to avoid duplication
|
|
188
|
-
* (those are passed separately as wireMiddleware).
|
|
189
|
-
*
|
|
190
|
-
* @param {object} options - Configuration object for combining middleware.
|
|
191
|
-
* @param {MiddlewareMetadata[] | undefined} options.inheritedMiddleware - Metadata from wiring (HTTP + tags + wire with tags).
|
|
192
|
-
* @param {CorePikkuMiddleware[] | undefined} options.wireMiddleware - Inline wire middleware.
|
|
193
|
-
* @param {MiddlewareMetadata[] | undefined} options.funcMiddleware - Function middleware metadata.
|
|
194
|
-
* @returns {CorePikkuMiddleware[]} Combined array of resolved middleware.
|
|
195
|
-
*
|
|
196
|
-
* @example
|
|
197
|
-
* ```typescript
|
|
198
|
-
* const combined = combineMiddleware(wireType, wireId, {
|
|
199
|
-
* inheritedMiddleware: meta.middleware,
|
|
200
|
-
* wireMiddleware: [inlineMiddleware],
|
|
201
|
-
* funcMiddleware: funcMeta.middleware
|
|
202
|
-
* })
|
|
203
|
-
* ```
|
|
204
|
-
*/
|
|
205
142
|
export const combineMiddleware = (
|
|
206
143
|
wireType: PikkuWiringTypes,
|
|
207
144
|
uid: string,
|
|
@@ -237,7 +174,6 @@ export const combineMiddleware = (
|
|
|
237
174
|
if (wireInheritedMiddleware) {
|
|
238
175
|
for (const meta of wireInheritedMiddleware) {
|
|
239
176
|
if (meta.type === 'http') {
|
|
240
|
-
// Look up HTTP middleware group from pikkuState
|
|
241
177
|
const group = pikkuState(packageName, 'middleware', 'httpGroup')[
|
|
242
178
|
meta.route
|
|
243
179
|
]
|
|
@@ -254,7 +190,6 @@ export const combineMiddleware = (
|
|
|
254
190
|
resolved.push(...(group as CorePikkuMiddleware[]))
|
|
255
191
|
}
|
|
256
192
|
} else if (meta.type === 'wire') {
|
|
257
|
-
// Individual wire middleware (exported, not inline)
|
|
258
193
|
const middleware = getMiddlewareByName(meta.name)
|
|
259
194
|
if (middleware) {
|
|
260
195
|
resolved.push(middleware)
|
|
@@ -263,12 +198,11 @@ export const combineMiddleware = (
|
|
|
263
198
|
}
|
|
264
199
|
}
|
|
265
200
|
|
|
266
|
-
// 2. Add inline wire middleware
|
|
267
201
|
if (wireMiddleware) {
|
|
268
202
|
resolved.push(...wireMiddleware)
|
|
269
203
|
}
|
|
270
204
|
|
|
271
|
-
//
|
|
205
|
+
// Only tags here; wire middleware is resolved via wireInheritedMiddleware.
|
|
272
206
|
if (funcInheritedMiddleware) {
|
|
273
207
|
for (const meta of funcInheritedMiddleware) {
|
|
274
208
|
if (meta.type === 'tag') {
|
|
@@ -280,16 +214,13 @@ export const combineMiddleware = (
|
|
|
280
214
|
resolved.push(...(group as CorePikkuMiddleware[]))
|
|
281
215
|
}
|
|
282
216
|
}
|
|
283
|
-
// Note: wire middleware is already handled in wireInheritedMiddleware
|
|
284
217
|
}
|
|
285
218
|
}
|
|
286
219
|
|
|
287
|
-
// 4. Add inline function middleware
|
|
288
220
|
if (funcMiddleware) {
|
|
289
221
|
resolved.push(...funcMiddleware)
|
|
290
222
|
}
|
|
291
223
|
|
|
292
|
-
// Sort by priority, deduplicate, and freeze
|
|
293
224
|
sortByPriority(resolved)
|
|
294
225
|
middlewareCache[wireType][uid] = freezeDedupe(
|
|
295
226
|
resolved
|
package/src/permissions.test.ts
CHANGED
|
@@ -164,6 +164,36 @@ describe('runPermissions — package isolation', () => {
|
|
|
164
164
|
message: 'Permission denied',
|
|
165
165
|
})
|
|
166
166
|
})
|
|
167
|
+
|
|
168
|
+
test('a root global applies inside a package too', async () => {
|
|
169
|
+
// The generated `addGlobalPermission` wrapper takes no package argument, so
|
|
170
|
+
// an application's rules always land in the root bucket. If those stopped
|
|
171
|
+
// at the addon boundary, "every request needs a signed-in user" would
|
|
172
|
+
// silently exempt every function an addon contributed.
|
|
173
|
+
addGlobalPermission([async () => false])
|
|
174
|
+
await assert.rejects(run({ packageName: 'pkg-a' }), {
|
|
175
|
+
message: 'Permission denied',
|
|
176
|
+
})
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
test('root and package globals both have to pass', async () => {
|
|
180
|
+
addGlobalPermission([async () => true])
|
|
181
|
+
addGlobalPermission([async () => false], 'pkg-a')
|
|
182
|
+
await assert.rejects(run({ packageName: 'pkg-a' }), {
|
|
183
|
+
message: 'Permission denied',
|
|
184
|
+
})
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
test('passes when the root and package globals both pass', async () => {
|
|
188
|
+
addGlobalPermission([async () => true])
|
|
189
|
+
addGlobalPermission([async () => true], 'pkg-a')
|
|
190
|
+
await run({ packageName: 'pkg-a' })
|
|
191
|
+
})
|
|
192
|
+
|
|
193
|
+
test('a package global does not leak back out to the root', async () => {
|
|
194
|
+
addGlobalPermission([async () => false], 'pkg-a')
|
|
195
|
+
await run({})
|
|
196
|
+
})
|
|
167
197
|
})
|
|
168
198
|
|
|
169
199
|
describe('checkAuthPermissions', () => {
|
package/src/permissions.ts
CHANGED
|
@@ -10,23 +10,6 @@ import type {
|
|
|
10
10
|
import { pikkuState } from './pikku-state.js'
|
|
11
11
|
import { ForbiddenError } from './errors/errors.js'
|
|
12
12
|
|
|
13
|
-
/**
|
|
14
|
-
* Evaluates a single permission group. A group ORs its branches together and
|
|
15
|
-
* ANDs the entries within a branch: the group passes if at least one branch
|
|
16
|
-
* (an array of permission functions, all of which must return true — or a lone
|
|
17
|
-
* function) is satisfied.
|
|
18
|
-
*
|
|
19
|
-
* This is the only place OR lives in authorization. Everything cross-cutting —
|
|
20
|
-
* global permissions, scopes, and auth — ANDs together; a function's own
|
|
21
|
-
* `permissions` group is the sole place where "owner OR admin"-style
|
|
22
|
-
* alternatives are expressed.
|
|
23
|
-
*
|
|
24
|
-
* @param permissions - The permission group to evaluate.
|
|
25
|
-
* @param services - The core services required for permission validation.
|
|
26
|
-
* @param data - The request data passed to each permission function.
|
|
27
|
-
* @param wire - The wire object containing request/response context and session.
|
|
28
|
-
* @returns A promise resolving to true if the group is satisfied.
|
|
29
|
-
*/
|
|
30
13
|
const verifyPermissions = async (
|
|
31
14
|
permissions: CorePermissionGroup,
|
|
32
15
|
services: CoreServices,
|
|
@@ -71,20 +54,6 @@ export const clearPermissionsCache = () => {
|
|
|
71
54
|
}
|
|
72
55
|
}
|
|
73
56
|
|
|
74
|
-
/**
|
|
75
|
-
* Registers wire-agnostic global permissions. Global permissions are an AND
|
|
76
|
-
* gate: every registered requirement must pass on every function invocation,
|
|
77
|
-
* regardless of transport. A requirement may be a single permission function
|
|
78
|
-
* or a permission group (in which case that group ORs internally, but the
|
|
79
|
-
* group as a whole must still pass).
|
|
80
|
-
*
|
|
81
|
-
* Global permissions never satisfy a function's own `permissions` — the two
|
|
82
|
-
* are independent gates that both have to pass, so a broad global can only
|
|
83
|
-
* ever narrow access.
|
|
84
|
-
*
|
|
85
|
-
* @example
|
|
86
|
-
* addGlobalPermission([signedInUser])
|
|
87
|
-
*/
|
|
88
57
|
export const addGlobalPermission = (
|
|
89
58
|
permissions: CorePermissionGroup | CorePikkuPermission[],
|
|
90
59
|
packageName: string | null = null
|
|
@@ -120,11 +89,27 @@ export const addTagPermission = (
|
|
|
120
89
|
)
|
|
121
90
|
}
|
|
122
91
|
|
|
92
|
+
const bucket = (
|
|
93
|
+
packageName: string | null
|
|
94
|
+
): (CorePermissionGroup | CorePikkuPermission)[] =>
|
|
95
|
+
(pikkuState(packageName, 'permissions', 'global') as unknown as (
|
|
96
|
+
| CorePermissionGroup
|
|
97
|
+
| CorePikkuPermission
|
|
98
|
+
)[]) ?? []
|
|
99
|
+
|
|
123
100
|
/**
|
|
124
|
-
*
|
|
125
|
-
*
|
|
126
|
-
*
|
|
127
|
-
*
|
|
101
|
+
* Global permissions in effect for a function, root ones first.
|
|
102
|
+
*
|
|
103
|
+
* A function that belongs to a package reads *both* buckets, not just its own.
|
|
104
|
+
* The generated `addGlobalPermission` wrapper always registers under the root
|
|
105
|
+
* (`null`) package — it takes no package argument — so resolving the package
|
|
106
|
+
* bucket alone meant an application's "every request needs a signed-in user"
|
|
107
|
+
* rule silently stopped at the addon boundary, and the bucket the addon's
|
|
108
|
+
* functions did read was one no host could write to. Both directions of that
|
|
109
|
+
* are wrong, and the safe union is to apply everything: globals are an AND
|
|
110
|
+
* gate, so adding the root ones can only ever tighten.
|
|
111
|
+
*
|
|
112
|
+
* knowledge: decisions/security/global-permissions-and-function-permissions-are-independent-gates.md
|
|
128
113
|
*/
|
|
129
114
|
const resolveGlobalPermissions = (
|
|
130
115
|
packageName: string | null
|
|
@@ -134,12 +119,9 @@ const resolveGlobalPermissions = (
|
|
|
134
119
|
if (cached) {
|
|
135
120
|
return cached
|
|
136
121
|
}
|
|
137
|
-
const
|
|
138
|
-
packageName
|
|
139
|
-
|
|
140
|
-
'global'
|
|
141
|
-
) as unknown as (CorePermissionGroup | CorePikkuPermission)[]
|
|
142
|
-
const resolved = globals && globals.length > 0 ? [...globals] : []
|
|
122
|
+
const resolved = packageName
|
|
123
|
+
? [...bucket(null), ...bucket(packageName)]
|
|
124
|
+
: [...bucket(null)]
|
|
143
125
|
globalPermissionsCache[key] = resolved
|
|
144
126
|
return resolved
|
|
145
127
|
}
|
|
@@ -149,17 +131,6 @@ const asGroup = (
|
|
|
149
131
|
): CorePermissionGroup =>
|
|
150
132
|
typeof entry === 'function' ? { permission: entry } : entry
|
|
151
133
|
|
|
152
|
-
/**
|
|
153
|
-
* Runs authorization for a function invocation. Two independent gates, both of
|
|
154
|
-
* which must pass:
|
|
155
|
-
*
|
|
156
|
-
* 1. Global permissions — AND. Every registered global requirement must pass.
|
|
157
|
-
* 2. Function permissions — OR. The function's own `permissions` group must be
|
|
158
|
-
* satisfied (see {@link verifyPermissions}).
|
|
159
|
-
*
|
|
160
|
-
* A passing global requirement never contributes to the function gate, so a
|
|
161
|
-
* broad global like `signedIn` can't satisfy an admin-only function.
|
|
162
|
-
*/
|
|
163
134
|
export const runPermissions = async ({
|
|
164
135
|
funcPermissions,
|
|
165
136
|
services,
|
|
@@ -197,25 +168,8 @@ export const runPermissions = async ({
|
|
|
197
168
|
}
|
|
198
169
|
}
|
|
199
170
|
|
|
200
|
-
/**
|
|
201
|
-
* Checks whether a session passes the auth checks (pikkuAuth only) for a
|
|
202
|
-
* given function/agent. Skips pikkuPermission checks since those require
|
|
203
|
-
* request data which isn't available at filter time. Global auth requirements
|
|
204
|
-
* are included so a filtered list honours app-wide auth.
|
|
205
|
-
*
|
|
206
|
-
* `funcPermissions` is the live {@link CorePermissionGroup} from the function or
|
|
207
|
-
* agent config, not the metadata form: the `pikkuAuth` brand only survives on
|
|
208
|
-
* the actual predicate objects, and the by-name registry those metadata entries
|
|
209
|
-
* would resolve against is never populated. Passing metadata here would silently
|
|
210
|
-
* collect nothing and let every gated tool through.
|
|
211
|
-
*
|
|
212
|
-
* @param funcPermissions - The live permission group from the func/agent config
|
|
213
|
-
* @param session - The user's session
|
|
214
|
-
* @param services - Singleton services
|
|
215
|
-
* @param packageName - Optional package namespace
|
|
216
|
-
* @returns true if the session passes the auth checks (or no auth checks exist)
|
|
217
|
-
*/
|
|
218
171
|
export const checkAuthPermissions = async (
|
|
172
|
+
/** Must be the live permission group from the func/agent config, never metadata. */
|
|
219
173
|
funcPermissions: CorePermissionGroup | undefined,
|
|
220
174
|
session: CoreUserSession,
|
|
221
175
|
services: CoreServices,
|
|
@@ -230,9 +184,6 @@ export const checkAuthPermissions = async (
|
|
|
230
184
|
never
|
|
231
185
|
>
|
|
232
186
|
|
|
233
|
-
// Collect auth-only (pikkuAuth) predicates from globals and the function's
|
|
234
|
-
// referenced permissions. Data-dependent permissions are ignored — they
|
|
235
|
-
// can't be evaluated without request data at filter time.
|
|
236
187
|
const authPerms: CorePikkuPermission<any, any, any>[] = []
|
|
237
188
|
|
|
238
189
|
const collect = (perm: CorePermissionGroup | CorePikkuPermission) => {
|
|
@@ -260,7 +211,6 @@ export const checkAuthPermissions = async (
|
|
|
260
211
|
collect(funcPermissions)
|
|
261
212
|
}
|
|
262
213
|
|
|
263
|
-
// No auth permissions = allowed (only data-dependent permissions exist)
|
|
264
214
|
if (authPerms.length === 0) return true
|
|
265
215
|
|
|
266
216
|
for (const perm of authPerms) {
|
package/src/pikku-request.ts
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Simplest class to represent a pikku request.
|
|
3
|
-
* @template In - The type of the request body.
|
|
4
2
|
* @group RequestResponse
|
|
5
3
|
*/
|
|
6
4
|
export abstract class PikkuRequest<In = any> {
|
|
@@ -10,10 +8,6 @@ export abstract class PikkuRequest<In = any> {
|
|
|
10
8
|
this.#data = data
|
|
11
9
|
}
|
|
12
10
|
|
|
13
|
-
/**
|
|
14
|
-
* Retrieves the data
|
|
15
|
-
* @returns A promise that resolves to an object containing the combined data.
|
|
16
|
-
*/
|
|
17
11
|
public async data(): Promise<In> {
|
|
18
12
|
if (this.#data === undefined) {
|
|
19
13
|
throw new Error('Data not found')
|
package/src/pikku-state.ts
CHANGED
|
@@ -14,7 +14,7 @@ import type { GatewaysMeta } from './wirings/gateway/gateway.types.js'
|
|
|
14
14
|
import type { ScheduledTasksMeta } from './wirings/scheduler/scheduler.types.js'
|
|
15
15
|
import type { TriggerMeta } from './wirings/trigger/trigger.types.js'
|
|
16
16
|
|
|
17
|
-
const PIKKU_STATE_KEY = Symbol('@pikku/core/state')
|
|
17
|
+
const PIKKU_STATE_KEY = Symbol.for('@pikku/core/state')
|
|
18
18
|
|
|
19
19
|
export const getAllPackageStates = (): Map<string, PikkuPackageState> => {
|
|
20
20
|
if (!(globalThis as any)[PIKKU_STATE_KEY]) {
|
|
@@ -23,22 +23,6 @@ export const getAllPackageStates = (): Map<string, PikkuPackageState> => {
|
|
|
23
23
|
return (globalThis as any)[PIKKU_STATE_KEY] as Map<string, PikkuPackageState>
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
/**
|
|
27
|
-
* Get or set package-scoped pikku state
|
|
28
|
-
*
|
|
29
|
-
* @param packageName - Package name (null for main package, '@scope/package' for addon packages)
|
|
30
|
-
* @param type - State category (function, rpc, http, etc.)
|
|
31
|
-
* @param content - Content key within the category
|
|
32
|
-
* @param value - Optional value to set
|
|
33
|
-
* @returns The current value of the state
|
|
34
|
-
*
|
|
35
|
-
* @example
|
|
36
|
-
* // Main package
|
|
37
|
-
* pikkuState(null, 'function', 'functions').get(funcName)
|
|
38
|
-
*
|
|
39
|
-
* // Addon package
|
|
40
|
-
* pikkuState('@acme/stripe-functions', 'rpc', 'meta')
|
|
41
|
-
*/
|
|
42
26
|
export const pikkuState = <
|
|
43
27
|
Type extends keyof PikkuPackageState,
|
|
44
28
|
Content extends keyof PikkuPackageState[Type],
|
|
@@ -50,7 +34,6 @@ export const pikkuState = <
|
|
|
50
34
|
): PikkuPackageState[Type][Content] => {
|
|
51
35
|
const resolvedPackageName = packageName ?? '__main__'
|
|
52
36
|
|
|
53
|
-
// Initialize package state if it doesn't exist
|
|
54
37
|
if (!getAllPackageStates().has(resolvedPackageName)) {
|
|
55
38
|
initializePikkuState(resolvedPackageName)
|
|
56
39
|
}
|
|
@@ -160,9 +143,6 @@ const createEmptyPackageState = (): PikkuPackageState => ({
|
|
|
160
143
|
},
|
|
161
144
|
})
|
|
162
145
|
|
|
163
|
-
/**
|
|
164
|
-
* Initialize state for a new package
|
|
165
|
-
*/
|
|
166
146
|
export const initializePikkuState = (packageName: string): void => {
|
|
167
147
|
if (!getAllPackageStates().has(packageName)) {
|
|
168
148
|
getAllPackageStates().set(packageName, createEmptyPackageState())
|
|
@@ -170,13 +150,12 @@ export const initializePikkuState = (packageName: string): void => {
|
|
|
170
150
|
}
|
|
171
151
|
|
|
172
152
|
export const resetPikkuState = () => {
|
|
173
|
-
//
|
|
153
|
+
// Error definitions come from module-import side effects that never re-run.
|
|
174
154
|
const existingErrors = getAllPackageStates().get('__main__')?.misc.errors
|
|
175
155
|
|
|
176
156
|
;(globalThis as any)[PIKKU_STATE_KEY] = new Map<string, PikkuPackageState>()
|
|
177
157
|
initializePikkuState('__main__')
|
|
178
158
|
|
|
179
|
-
// Restore the errors map if it existed
|
|
180
159
|
if (existingErrors) {
|
|
181
160
|
const mainState = getAllPackageStates().get('__main__')!
|
|
182
161
|
mainState.misc.errors = existingErrors
|
|
@@ -201,13 +180,6 @@ export const getCreateWireServices = (): CreateWireServices | undefined => {
|
|
|
201
180
|
return pikkuState(null, 'package', 'factories')?.createWireServices
|
|
202
181
|
}
|
|
203
182
|
|
|
204
|
-
/**
|
|
205
|
-
* Register service factories for an addon package.
|
|
206
|
-
* These factories are used to create services when the package's functions are invoked.
|
|
207
|
-
*
|
|
208
|
-
* @param packageName - The package name (e.g., '@pikku/templates-function-addon')
|
|
209
|
-
* @param factories - The service factory functions
|
|
210
|
-
*/
|
|
211
183
|
export const addPackageServiceFactories = (
|
|
212
184
|
packageName: string,
|
|
213
185
|
factories: NonNullable<PikkuPackageState['package']['factories']>
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
import { describe, test } from 'node:test'
|
|
2
|
+
import assert from 'node:assert/strict'
|
|
3
|
+
import { existsSync, readFileSync } from 'node:fs'
|
|
4
|
+
import { fileURLToPath } from 'node:url'
|
|
5
|
+
import { join, dirname, resolve, relative } from 'node:path'
|
|
6
|
+
|
|
7
|
+
const srcRoot = dirname(fileURLToPath(import.meta.url))
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Statements that only move types. TypeScript erases them, so they cost a
|
|
11
|
+
* production bundle nothing and are deliberately not followed.
|
|
12
|
+
*/
|
|
13
|
+
const TYPE_ONLY = /^\s*(?:import|export)\s+type\b/
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* The modules a production server must never load by importing a barrel.
|
|
17
|
+
*
|
|
18
|
+
* Each is scenario or virtual-user runtime: `http-personas` signs personas in
|
|
19
|
+
* and reaches the actor-flow conversation runner, which reaches the agent
|
|
20
|
+
* runner. None of it runs in production, and an unbundled Node or Lambda deploy
|
|
21
|
+
* does no tree-shaking — it loads whatever the graph names.
|
|
22
|
+
*/
|
|
23
|
+
const FORBIDDEN = [
|
|
24
|
+
'services/http-personas.ts',
|
|
25
|
+
'wirings/actor-flow/run-conversation.ts',
|
|
26
|
+
'wirings/workflow/pikku-scenario-service.ts',
|
|
27
|
+
]
|
|
28
|
+
|
|
29
|
+
const resolveSpecifier = (fromFile: string, specifier: string) => {
|
|
30
|
+
const base = resolve(dirname(fromFile), specifier.replace(/\.js$/, ''))
|
|
31
|
+
for (const candidate of [`${base}.ts`, join(base, 'index.ts')]) {
|
|
32
|
+
if (existsSync(candidate)) return candidate
|
|
33
|
+
}
|
|
34
|
+
return undefined
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Every module loaded as a side effect of importing `entry`, following value
|
|
39
|
+
* imports only.
|
|
40
|
+
*
|
|
41
|
+
* A dynamic `await import(...)` is not followed: it does not run at module
|
|
42
|
+
* init, which is the whole reason `pikku-scenario-service` reaches
|
|
43
|
+
* `http-personas` that way.
|
|
44
|
+
*/
|
|
45
|
+
const runtimeGraph = (entry: string): Set<string> => {
|
|
46
|
+
const seen = new Set<string>()
|
|
47
|
+
const queue = [entry]
|
|
48
|
+
|
|
49
|
+
while (queue.length) {
|
|
50
|
+
const file = queue.pop()!
|
|
51
|
+
if (seen.has(file)) continue
|
|
52
|
+
seen.add(file)
|
|
53
|
+
|
|
54
|
+
for (const line of readFileSync(file, 'utf-8').split('\n')) {
|
|
55
|
+
if (TYPE_ONLY.test(line)) continue
|
|
56
|
+
const specifier = line.match(/\bfrom\s+'(\.[^']+)'/)?.[1]
|
|
57
|
+
if (!specifier) continue
|
|
58
|
+
const target = resolveSpecifier(file, specifier)
|
|
59
|
+
if (target) queue.push(target)
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return seen
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
describe('production barrels stay lean', () => {
|
|
67
|
+
for (const barrel of ['services/index.ts', 'wirings/workflow/index.ts']) {
|
|
68
|
+
test(`@pikku/core ${barrel} does not load scenario runtime`, () => {
|
|
69
|
+
const reached = runtimeGraph(join(srcRoot, barrel))
|
|
70
|
+
const offenders = FORBIDDEN.filter((module) =>
|
|
71
|
+
reached.has(join(srcRoot, module))
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
assert.deepEqual(
|
|
75
|
+
offenders,
|
|
76
|
+
[],
|
|
77
|
+
`${barrel} pulls scenario runtime into every app that imports it:\n` +
|
|
78
|
+
`${offenders.join('\n')}\n` +
|
|
79
|
+
`Export the value from '@pikku/core/persona' instead — types may stay here.`
|
|
80
|
+
)
|
|
81
|
+
})
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
test('the persona entry point still exports the runtime that moved', async () => {
|
|
85
|
+
const persona = await import('./wirings/persona/index.js')
|
|
86
|
+
|
|
87
|
+
for (const name of [
|
|
88
|
+
'createHttpPersonas',
|
|
89
|
+
'HttpPersona',
|
|
90
|
+
'postScenarioJson',
|
|
91
|
+
'readScenarioHttpResponse',
|
|
92
|
+
]) {
|
|
93
|
+
assert.ok(
|
|
94
|
+
name in persona,
|
|
95
|
+
`@pikku/core/persona no longer exports ${name}; it has to live somewhere`
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
test('the graph walker actually reaches things', () => {
|
|
101
|
+
// Guards the test above: a walker that silently resolved nothing would pass
|
|
102
|
+
// no matter what the barrels imported.
|
|
103
|
+
const reached = runtimeGraph(join(srcRoot, 'wirings/persona/index.ts'))
|
|
104
|
+
assert.ok(
|
|
105
|
+
reached.has(join(srcRoot, 'services/http-personas.ts')),
|
|
106
|
+
`walker failed to reach a known value import; reached ${reached.size} files:\n` +
|
|
107
|
+
[...reached].map((f) => relative(srcRoot, f)).join('\n')
|
|
108
|
+
)
|
|
109
|
+
})
|
|
110
|
+
})
|