@pikku/core 0.12.72 → 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 +793 -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 +37 -32
- 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 -13
- package/dist/handle-error.js +0 -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 +5 -39
- package/dist/schema.js +5 -39
- 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 +0 -99
- package/dist/wirings/http/http-runner.js +9 -165
- package/dist/wirings/http/http.types.d.ts +14 -55
- 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 +0 -40
- package/dist/wirings/http/pikku-fetch-http-request.js +0 -58
- 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 +1 -4
- package/dist/wirings/mcp/mcp-runner.js +1 -14
- 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 -1
- 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 +0 -7
- package/src/function/function-runner.ts +62 -32
- 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/handle-error.ts +0 -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.ts +5 -39
- 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 +8 -167
- package/src/wirings/http/http.types.ts +15 -62
- package/src/wirings/http/log-http-routes.ts +0 -4
- package/src/wirings/http/pikku-fetch-http-request.test.ts +2 -10
- package/src/wirings/http/pikku-fetch-http-request.ts +0 -58
- 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.ts +2 -17
- 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/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
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
|
+
})
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { describe, test, beforeEach } from 'node:test'
|
|
2
|
+
import assert from 'node:assert'
|
|
3
|
+
import { buildRemoteHeaders } from './remote.js'
|
|
4
|
+
import { pikkuRemoteAuthMiddleware } from './middleware/remote-auth.js'
|
|
5
|
+
import { resetPikkuState } from './pikku-state.js'
|
|
6
|
+
import { WeakKeyMaterialError } from './errors/errors.js'
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
resetPikkuState()
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
const STRONG_SECRET = 'a'.repeat(43)
|
|
13
|
+
const WEAK_SECRET = 'dev-remote-secret'
|
|
14
|
+
|
|
15
|
+
const createSecrets = (secret: string) => ({
|
|
16
|
+
getSecret: async (key: string) => {
|
|
17
|
+
if (key === 'PIKKU_REMOTE_SECRET') return secret
|
|
18
|
+
throw new Error(`Secret ${key} not found`)
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Signing is deliberately free here so the measurement isolates key derivation.
|
|
24
|
+
*/
|
|
25
|
+
const createJWT = () => ({
|
|
26
|
+
encode: async (_expiresIn: unknown, payload: unknown) =>
|
|
27
|
+
Buffer.from(JSON.stringify(payload)).toString('base64url'),
|
|
28
|
+
decode: async (token: string) =>
|
|
29
|
+
JSON.parse(Buffer.from(token, 'base64url').toString('utf-8')),
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
const createRequest = (
|
|
33
|
+
headers: Record<string, string>,
|
|
34
|
+
path = '/remote/rpc/myFunc'
|
|
35
|
+
) => ({
|
|
36
|
+
header: (name: string) => headers[name.toLowerCase()] || headers[name],
|
|
37
|
+
path: () => path,
|
|
38
|
+
method: () => 'POST',
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const roundTrip = async (secret: string, session: unknown) => {
|
|
42
|
+
const jwt = createJWT()
|
|
43
|
+
const secrets = createSecrets(secret)
|
|
44
|
+
|
|
45
|
+
const headers = await buildRemoteHeaders(
|
|
46
|
+
jwt as any,
|
|
47
|
+
secrets as any,
|
|
48
|
+
'myFunc',
|
|
49
|
+
session
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
let received: unknown
|
|
53
|
+
await pikkuRemoteAuthMiddleware(
|
|
54
|
+
{ secrets, jwt } as any,
|
|
55
|
+
{
|
|
56
|
+
http: {
|
|
57
|
+
request: createRequest({ authorization: headers.authorization! }),
|
|
58
|
+
},
|
|
59
|
+
setSession: async (s: unknown) => {
|
|
60
|
+
received = s
|
|
61
|
+
},
|
|
62
|
+
} as any,
|
|
63
|
+
async () => {}
|
|
64
|
+
)
|
|
65
|
+
return received
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
describe('remote RPC session round trip', () => {
|
|
69
|
+
test('round-trips the session through header build and middleware verify', async () => {
|
|
70
|
+
const session = { userId: 'user-1', role: 'admin' }
|
|
71
|
+
assert.deepStrictEqual(await roundTrip(STRONG_SECRET, session), session)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
test('a header built with one secret is rejected by a peer holding another', async () => {
|
|
75
|
+
const jwt = createJWT()
|
|
76
|
+
const headers = await buildRemoteHeaders(
|
|
77
|
+
jwt as any,
|
|
78
|
+
createSecrets(STRONG_SECRET) as any,
|
|
79
|
+
'myFunc',
|
|
80
|
+
{ userId: 'user-1' }
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
await assert.rejects(() =>
|
|
84
|
+
pikkuRemoteAuthMiddleware(
|
|
85
|
+
{ secrets: createSecrets('b'.repeat(43)), jwt } as any,
|
|
86
|
+
{
|
|
87
|
+
http: {
|
|
88
|
+
request: createRequest({ authorization: headers.authorization! }),
|
|
89
|
+
},
|
|
90
|
+
setSession: async () => {},
|
|
91
|
+
} as any,
|
|
92
|
+
async () => {}
|
|
93
|
+
)
|
|
94
|
+
)
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
test('a full round trip stays under the per-hop latency budget', async () => {
|
|
98
|
+
const session = { userId: 'user-1', role: 'admin' }
|
|
99
|
+
|
|
100
|
+
// Warm up so the measurement excludes module/JIT startup.
|
|
101
|
+
await roundTrip(STRONG_SECRET, session)
|
|
102
|
+
|
|
103
|
+
const iterations = 5
|
|
104
|
+
const start = performance.now()
|
|
105
|
+
for (let i = 0; i < iterations; i++) {
|
|
106
|
+
await roundTrip(STRONG_SECRET, session)
|
|
107
|
+
}
|
|
108
|
+
const perRoundTrip = (performance.now() - start) / iterations
|
|
109
|
+
|
|
110
|
+
assert.ok(
|
|
111
|
+
perRoundTrip < 20,
|
|
112
|
+
`remote RPC round trip took ${perRoundTrip.toFixed(1)}ms, budget is 20ms`
|
|
113
|
+
)
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
|
|
117
|
+
describe('PIKKU_REMOTE_SECRET strength', () => {
|
|
118
|
+
test('buildRemoteHeaders rejects a secret shorter than 32 characters', async () => {
|
|
119
|
+
await assert.rejects(
|
|
120
|
+
() =>
|
|
121
|
+
buildRemoteHeaders(
|
|
122
|
+
createJWT() as any,
|
|
123
|
+
createSecrets(WEAK_SECRET) as any,
|
|
124
|
+
'myFunc',
|
|
125
|
+
{ userId: 'user-1' }
|
|
126
|
+
),
|
|
127
|
+
(err: unknown) => err instanceof WeakKeyMaterialError
|
|
128
|
+
)
|
|
129
|
+
})
|
|
130
|
+
|
|
131
|
+
test('buildRemoteHeaders rejects a weak secret even with no session to encrypt', async () => {
|
|
132
|
+
await assert.rejects(
|
|
133
|
+
() =>
|
|
134
|
+
buildRemoteHeaders(
|
|
135
|
+
createJWT() as any,
|
|
136
|
+
createSecrets(WEAK_SECRET) as any,
|
|
137
|
+
'myFunc'
|
|
138
|
+
),
|
|
139
|
+
(err: unknown) => err instanceof WeakKeyMaterialError
|
|
140
|
+
)
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
test('the middleware rejects a weak secret rather than authenticating with it', async () => {
|
|
144
|
+
const jwt = createJWT()
|
|
145
|
+
const headers = await buildRemoteHeaders(
|
|
146
|
+
jwt as any,
|
|
147
|
+
createSecrets(STRONG_SECRET) as any,
|
|
148
|
+
'myFunc',
|
|
149
|
+
{ userId: 'user-1' }
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
await assert.rejects(
|
|
153
|
+
() =>
|
|
154
|
+
pikkuRemoteAuthMiddleware(
|
|
155
|
+
{ secrets: createSecrets(WEAK_SECRET), jwt } as any,
|
|
156
|
+
{
|
|
157
|
+
http: {
|
|
158
|
+
request: createRequest({ authorization: headers.authorization! }),
|
|
159
|
+
},
|
|
160
|
+
setSession: async () => {},
|
|
161
|
+
} as any,
|
|
162
|
+
async () => {}
|
|
163
|
+
),
|
|
164
|
+
(err: unknown) => err instanceof WeakKeyMaterialError
|
|
165
|
+
)
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
test('a secret of exactly 32 characters is accepted', async () => {
|
|
169
|
+
const session = { userId: 'user-1' }
|
|
170
|
+
assert.deepStrictEqual(await roundTrip('x'.repeat(32), session), session)
|
|
171
|
+
})
|
|
172
|
+
})
|
package/src/remote.ts
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import type { JWTService } from './services/jwt-service.js'
|
|
2
2
|
import type { SecretService } from './services/secret-service.js'
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
assertStrongKeyMaterial,
|
|
5
|
+
encryptWithKeyMaterial,
|
|
6
|
+
REMOTE_SESSION_INFO,
|
|
7
|
+
} from './crypto-utils.js'
|
|
4
8
|
|
|
5
9
|
/**
|
|
6
|
-
*
|
|
7
|
-
* pikkuRemoteAuthMiddleware on the receiving end.
|
|
8
|
-
*
|
|
9
|
-
* Used by all deployment services (Kysely, Redis, MongoDB, Lambda, CF, Azure)
|
|
10
|
-
* regardless of transport (HTTP, Lambda Invoke, service bindings).
|
|
10
|
+
* Authorization headers carrying a JWT-signed session and traceId for
|
|
11
|
+
* `pikkuRemoteAuthMiddleware` on the receiving end. Used by every deployment
|
|
12
|
+
* service regardless of transport (HTTP, Lambda Invoke, service bindings).
|
|
11
13
|
*/
|
|
12
14
|
export async function buildRemoteHeaders(
|
|
13
15
|
jwt: JWTService | undefined,
|
|
@@ -27,8 +29,16 @@ export async function buildRemoteHeaders(
|
|
|
27
29
|
} catch {}
|
|
28
30
|
|
|
29
31
|
if (secret && jwt) {
|
|
32
|
+
assertStrongKeyMaterial('PIKKU_REMOTE_SECRET', secret)
|
|
30
33
|
const sessionEnc = session
|
|
31
|
-
? await
|
|
34
|
+
? await encryptWithKeyMaterial(
|
|
35
|
+
'PIKKU_REMOTE_SECRET',
|
|
36
|
+
secret,
|
|
37
|
+
REMOTE_SESSION_INFO,
|
|
38
|
+
{
|
|
39
|
+
session,
|
|
40
|
+
}
|
|
41
|
+
)
|
|
32
42
|
: undefined
|
|
33
43
|
const token = await jwt.encode(
|
|
34
44
|
{ value: 5, unit: 'minute' },
|
package/src/schema.ts
CHANGED
|
@@ -9,13 +9,6 @@ import { pikkuState, getAllPackageStates } from './pikku-state.js'
|
|
|
9
9
|
const schemaKey = (name: string, packageName: string | null): string =>
|
|
10
10
|
packageName ? `${packageName}:${name}` : name
|
|
11
11
|
|
|
12
|
-
/**
|
|
13
|
-
* Adds a schema to the schemas map for a specific package.
|
|
14
|
-
* @param name - The name of the schema.
|
|
15
|
-
* @param value - The schema value.
|
|
16
|
-
* @param packageName - The package name (null for main package, '@scope/package' for addon packages).
|
|
17
|
-
* @ignore
|
|
18
|
-
*/
|
|
19
12
|
export const addSchema = (
|
|
20
13
|
name: string,
|
|
21
14
|
value: any,
|
|
@@ -25,13 +18,6 @@ export const addSchema = (
|
|
|
25
18
|
pikkuState(packageName, 'misc', 'schemas').set(name, schema)
|
|
26
19
|
}
|
|
27
20
|
|
|
28
|
-
/**
|
|
29
|
-
* Retrieves a schema from the schemas map for a specific package.
|
|
30
|
-
* @param name - The name of the schema.
|
|
31
|
-
* @param packageName - The package name (null for main package, '@scope/package' for addon packages).
|
|
32
|
-
* @returns The schema value or undefined if not found.
|
|
33
|
-
* @ignore
|
|
34
|
-
*/
|
|
35
21
|
export const getSchema = (
|
|
36
22
|
name: string,
|
|
37
23
|
packageName: string | null = null
|
|
@@ -39,10 +25,6 @@ export const getSchema = (
|
|
|
39
25
|
return pikkuState(packageName, 'misc', 'schemas').get(name)
|
|
40
26
|
}
|
|
41
27
|
|
|
42
|
-
/**
|
|
43
|
-
* Loads a schema and compiles it into a validator.
|
|
44
|
-
* @param logger - A logger for logging information.
|
|
45
|
-
*/
|
|
46
28
|
export const compileAllSchemas = (
|
|
47
29
|
logger: Logger,
|
|
48
30
|
schemaService?: SchemaService
|
|
@@ -95,27 +77,11 @@ const validateAllSchemasLoaded = (
|
|
|
95
77
|
}
|
|
96
78
|
|
|
97
79
|
/**
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
* ships with (`@cfworker/json-schema`, and Ajv unless `useDefaults` is set)
|
|
104
|
-
* annotate the instance, so the function received `undefined` for a property
|
|
105
|
-
* its generated type declares as present. That is the worst shape a mismatch
|
|
106
|
-
* can take: validation permits the omission, the type says the value is there,
|
|
107
|
-
* and the body reads `undefined`.
|
|
108
|
-
*
|
|
109
|
-
* Applied unconditionally rather than alongside `coerceTopLevelDataFromSchema`,
|
|
110
|
-
* whose `coerceDataFromSchema` flag is about decoding transport-encoded values
|
|
111
|
-
* (a query string's `"1,2"` into an array). Defaults are a property of the
|
|
112
|
-
* schema, not of how the call arrived, so gating them on that flag would apply
|
|
113
|
-
* them over HTTP and skip them on a direct RPC invocation.
|
|
114
|
-
*
|
|
115
|
-
* Returns the data to use, which is a new object only when defaults had to be
|
|
116
|
-
* added to a nullish input — a call made with no arguments at all still gets
|
|
117
|
-
* them. Values are cloned so an object or array default (`[]`, `{}`) is never
|
|
118
|
-
* shared as one mutable instance across every request.
|
|
80
|
+
* Fills in absent top-level properties from their schema `default`. Applied
|
|
81
|
+
* unconditionally: a default belongs to the schema, not to the transport the
|
|
82
|
+
* call arrived on, and runs before coercion so a defaulted and a supplied
|
|
83
|
+
* value are treated identically from here on. Values are cloned so an object
|
|
84
|
+
* or array default is never shared as one mutable instance across requests.
|
|
119
85
|
*/
|
|
120
86
|
export const applyDefaultsFromSchema = (
|
|
121
87
|
schemaName: string,
|