@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
|
@@ -6,11 +6,6 @@ import {
|
|
|
6
6
|
UnprocessableContentError,
|
|
7
7
|
} from '../../errors/errors.js'
|
|
8
8
|
|
|
9
|
-
/**
|
|
10
|
-
* The largest request body read into memory when no limit is configured. Ample
|
|
11
|
-
* for JSON APIs and typical uploads while keeping a single request's memory
|
|
12
|
-
* footprint bounded.
|
|
13
|
-
*/
|
|
14
9
|
export const DEFAULT_MAX_BODY_SIZE = 10 * 1024 * 1024
|
|
15
10
|
|
|
16
11
|
export type PikkuFetchHTTPRequestOptions = Partial<{
|
|
@@ -19,8 +14,6 @@ export type PikkuFetchHTTPRequestOptions = Partial<{
|
|
|
19
14
|
}>
|
|
20
15
|
|
|
21
16
|
/**
|
|
22
|
-
* Abstract class representing a pikku request.
|
|
23
|
-
* @template In - The type of the request body.
|
|
24
17
|
* @group RequestResponse
|
|
25
18
|
*/
|
|
26
19
|
export class PikkuFetchHTTPRequest<
|
|
@@ -50,35 +43,15 @@ export class PikkuFetchHTTPRequest<
|
|
|
50
43
|
return this.#url.pathname
|
|
51
44
|
}
|
|
52
45
|
|
|
53
|
-
/**
|
|
54
|
-
* Retrieves the request body.
|
|
55
|
-
* @returns A promise that resolves to the request body.
|
|
56
|
-
*/
|
|
57
46
|
public async json(): Promise<In> {
|
|
58
47
|
const text = await this.#readRawText()
|
|
59
48
|
return JSON.parse(text) as In
|
|
60
49
|
}
|
|
61
50
|
|
|
62
|
-
/**
|
|
63
|
-
* Retrieves the raw request body as a Buffer.
|
|
64
|
-
* @returns A promise that resolves to the raw request body.
|
|
65
|
-
*/
|
|
66
51
|
public async arrayBuffer(): Promise<ArrayBuffer> {
|
|
67
52
|
return this.#readRawBuffer()
|
|
68
53
|
}
|
|
69
54
|
|
|
70
|
-
/**
|
|
71
|
-
* Reads the underlying single-use request body exactly once and memoises both
|
|
72
|
-
* the in-flight promise and the result. `json()`, `arrayBuffer()`, `body()`
|
|
73
|
-
* and `toWebRequest()` all funnel through here, so a request whose body is
|
|
74
|
-
* consumed in more than one place can no longer race on the underlying stream
|
|
75
|
-
* and fail with "Body has already been used".
|
|
76
|
-
*
|
|
77
|
-
* If a second consumer asks for the body while the first read is still in
|
|
78
|
-
* flight, that is the concurrent double-read that used to crash — now safe,
|
|
79
|
-
* but warned about so the redundant consumer is found and removed at the
|
|
80
|
-
* source rather than silently leaning on this cache.
|
|
81
|
-
*/
|
|
82
55
|
async #readRawBuffer(): Promise<ArrayBuffer> {
|
|
83
56
|
if (this.#rawBodyBuffer !== undefined) {
|
|
84
57
|
return this.#rawBodyBuffer
|
|
@@ -105,12 +78,6 @@ export class PikkuFetchHTTPRequest<
|
|
|
105
78
|
return this.#rawBufferPromise
|
|
106
79
|
}
|
|
107
80
|
|
|
108
|
-
/**
|
|
109
|
-
* Reads the body while refusing to buffer more than `maxBodySize` bytes. The
|
|
110
|
-
* declared `content-length` is rejected up front so an oversized body is never
|
|
111
|
-
* transferred, and the stream is measured as it arrives because that header is
|
|
112
|
-
* both optional and attacker-controlled.
|
|
113
|
-
*/
|
|
114
81
|
async #readBoundedBuffer(): Promise<ArrayBuffer> {
|
|
115
82
|
const contentLength = this.request.headers.get('content-length')
|
|
116
83
|
if (contentLength !== null) {
|
|
@@ -177,19 +144,10 @@ export class PikkuFetchHTTPRequest<
|
|
|
177
144
|
return Object.fromEntries(this.request.headers.entries())
|
|
178
145
|
}
|
|
179
146
|
|
|
180
|
-
/**
|
|
181
|
-
* Retrieves the value of a specific header.
|
|
182
|
-
* @param headerName - The name of the header to retrieve.
|
|
183
|
-
* @returns The value of the header, or undefined if the header is not found.
|
|
184
|
-
*/
|
|
185
147
|
public header(headerName: string): string | null {
|
|
186
148
|
return this.request.headers.get(headerName.toLowerCase())
|
|
187
149
|
}
|
|
188
150
|
|
|
189
|
-
/**
|
|
190
|
-
* Retrieves the cookies from the request.
|
|
191
|
-
* @returns An object containing the cookies.
|
|
192
|
-
*/
|
|
193
151
|
public cookie(cookieName: string): string | null {
|
|
194
152
|
if (this.#cookies?.[cookieName]) {
|
|
195
153
|
return this.#cookies[cookieName]
|
|
@@ -199,36 +157,20 @@ export class PikkuFetchHTTPRequest<
|
|
|
199
157
|
return this.#cookies[cookieName] || null
|
|
200
158
|
}
|
|
201
159
|
|
|
202
|
-
/**
|
|
203
|
-
* Retrieves the request parameters.
|
|
204
|
-
* @returns An object containing the request parameters.
|
|
205
|
-
*/
|
|
206
160
|
public params(): Partial<Record<string, string | string[]>> {
|
|
207
161
|
return this.#params
|
|
208
162
|
}
|
|
209
163
|
|
|
210
|
-
/**
|
|
211
|
-
* Sets the request parameters.
|
|
212
|
-
* @param params - An object containing the request parameters to set.
|
|
213
|
-
*/
|
|
214
164
|
public setParams(
|
|
215
165
|
params: Record<string, string | string[] | undefined>
|
|
216
166
|
): void {
|
|
217
167
|
this.#params = params
|
|
218
168
|
}
|
|
219
169
|
|
|
220
|
-
/**
|
|
221
|
-
* Retrieves the query parameters from the request.
|
|
222
|
-
* @returns An object containing the query parameters.
|
|
223
|
-
*/
|
|
224
170
|
public query(): PikkuQuery {
|
|
225
171
|
return parseQuery(this.#url.searchParams.toString()) as PikkuQuery
|
|
226
172
|
}
|
|
227
173
|
|
|
228
|
-
/**
|
|
229
|
-
* Retrieves the combined data from the request, including parameters, query, and body.
|
|
230
|
-
* @returns A promise that resolves to an object containing the combined data.
|
|
231
|
-
*/
|
|
232
174
|
public async data(): Promise<In> {
|
|
233
175
|
const body = await this.body()
|
|
234
176
|
const parts = [this.params(), this.query(), body]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, test } from 'node:test'
|
|
2
2
|
import assert from 'assert'
|
|
3
|
-
import { PikkuFetchHTTPResponse } from './pikku-fetch-http-response.js'
|
|
3
|
+
import { PikkuFetchHTTPResponse } from './pikku-fetch-http-response.js'
|
|
4
4
|
|
|
5
5
|
describe('PikkuFetchHTTPResponse', () => {
|
|
6
6
|
test('sets status code', () => {
|
|
@@ -118,8 +118,6 @@ export class PikkuFetchHTTPResponse implements PikkuHTTPResponse {
|
|
|
118
118
|
const cookieHeader = Array.from(this.#cookies.entries()).map(
|
|
119
119
|
([name, { value, flags }]) => serializeCookie(name, value, flags)
|
|
120
120
|
)
|
|
121
|
-
// Multiple Set-Cookie headers must be appended separately, not joined with commas
|
|
122
|
-
// per HTTP specification (RFC 6265)
|
|
123
121
|
cookieHeader.forEach((cookie) => this.#headers.append('Set-Cookie', cookie))
|
|
124
122
|
return new Response(this.#body, {
|
|
125
123
|
...args,
|
|
@@ -143,7 +141,6 @@ export class PikkuFetchHTTPResponse implements PikkuHTTPResponse {
|
|
|
143
141
|
this.#send = send
|
|
144
142
|
this.#close = close
|
|
145
143
|
|
|
146
|
-
// Force initial flush
|
|
147
144
|
controller.enqueue(encoder.encode(':\n\n'))
|
|
148
145
|
},
|
|
149
146
|
})
|
|
@@ -7,7 +7,6 @@ import type { HTTPMethod } from '../http.types.js'
|
|
|
7
7
|
describe('PathToRegexRouter', () => {
|
|
8
8
|
let router: PathToRegexRouter
|
|
9
9
|
|
|
10
|
-
// Helper to create mock route wiring
|
|
11
10
|
const mockRoute = (route: string) => ({
|
|
12
11
|
route,
|
|
13
12
|
method: 'get' as HTTPMethod,
|
|
@@ -21,7 +20,6 @@ describe('PathToRegexRouter', () => {
|
|
|
21
20
|
|
|
22
21
|
describe('Static Route Optimization', () => {
|
|
23
22
|
test('should correctly identify static routes', () => {
|
|
24
|
-
// Setup test routes
|
|
25
23
|
pikkuState(
|
|
26
24
|
null,
|
|
27
25
|
'http',
|
|
@@ -42,7 +40,6 @@ describe('PathToRegexRouter', () => {
|
|
|
42
40
|
|
|
43
41
|
router.initialize()
|
|
44
42
|
|
|
45
|
-
// Test static routes - should return exact matches with empty params
|
|
46
43
|
const staticResult = router.match('get', '/static')
|
|
47
44
|
assert.ok(staticResult, 'Static route should match')
|
|
48
45
|
assert.strictEqual(staticResult.route, '/static')
|
|
@@ -55,7 +52,6 @@ describe('PathToRegexRouter', () => {
|
|
|
55
52
|
})
|
|
56
53
|
|
|
57
54
|
test('should handle dynamic routes with parameters', () => {
|
|
58
|
-
// Setup test routes with parameters
|
|
59
55
|
pikkuState(
|
|
60
56
|
null,
|
|
61
57
|
'http',
|
|
@@ -78,7 +74,6 @@ describe('PathToRegexRouter', () => {
|
|
|
78
74
|
|
|
79
75
|
router.initialize()
|
|
80
76
|
|
|
81
|
-
// Test dynamic routes - should return matches with extracted parameters
|
|
82
77
|
const userResult = router.match('get', '/api/users/123')
|
|
83
78
|
assert.ok(userResult, 'Dynamic route should match')
|
|
84
79
|
assert.strictEqual(userResult.route, '/api/users/:id')
|
|
@@ -98,7 +93,6 @@ describe('PathToRegexRouter', () => {
|
|
|
98
93
|
})
|
|
99
94
|
|
|
100
95
|
test('should handle multi-parameter routes', () => {
|
|
101
|
-
// Setup routes with multiple parameters
|
|
102
96
|
pikkuState(
|
|
103
97
|
null,
|
|
104
98
|
'http',
|
|
@@ -124,7 +118,6 @@ describe('PathToRegexRouter', () => {
|
|
|
124
118
|
|
|
125
119
|
router.initialize()
|
|
126
120
|
|
|
127
|
-
// Test multi-parameter routes
|
|
128
121
|
const apiResult = router.match('get', '/api/v2/users/456')
|
|
129
122
|
assert.ok(apiResult, 'Multi-parameter route should match')
|
|
130
123
|
assert.strictEqual(apiResult.route, '/api/:version/users/:userId')
|
|
@@ -140,7 +133,6 @@ describe('PathToRegexRouter', () => {
|
|
|
140
133
|
})
|
|
141
134
|
|
|
142
135
|
test('should prioritize static routes over dynamic routes for performance', () => {
|
|
143
|
-
// Setup mixed routes where static could conflict with dynamic
|
|
144
136
|
pikkuState(
|
|
145
137
|
null,
|
|
146
138
|
'http',
|
|
@@ -149,8 +141,8 @@ describe('PathToRegexRouter', () => {
|
|
|
149
141
|
[
|
|
150
142
|
'get',
|
|
151
143
|
new Map([
|
|
152
|
-
['/api/users', mockRoute('/api/users')],
|
|
153
|
-
['/api/:resource', mockRoute('/api/:resource')],
|
|
144
|
+
['/api/users', mockRoute('/api/users')],
|
|
145
|
+
['/api/:resource', mockRoute('/api/:resource')],
|
|
154
146
|
]),
|
|
155
147
|
],
|
|
156
148
|
])
|
|
@@ -160,10 +152,9 @@ describe('PathToRegexRouter', () => {
|
|
|
160
152
|
|
|
161
153
|
router.initialize()
|
|
162
154
|
|
|
163
|
-
// Static route should be found first (O(1) lookup)
|
|
164
155
|
const result = router.match('get', '/api/users')
|
|
165
156
|
assert.ok(result, 'Route should match')
|
|
166
|
-
assert.strictEqual(result.route, '/api/users')
|
|
157
|
+
assert.strictEqual(result.route, '/api/users')
|
|
167
158
|
assert.deepStrictEqual(result.params, {})
|
|
168
159
|
})
|
|
169
160
|
})
|
|
@@ -178,7 +169,7 @@ describe('PathToRegexRouter', () => {
|
|
|
178
169
|
[
|
|
179
170
|
'get',
|
|
180
171
|
new Map([
|
|
181
|
-
['test', mockRoute('test')],
|
|
172
|
+
['test', mockRoute('test')],
|
|
182
173
|
['api/health', mockRoute('api/health')],
|
|
183
174
|
]),
|
|
184
175
|
],
|
|
@@ -189,7 +180,6 @@ describe('PathToRegexRouter', () => {
|
|
|
189
180
|
|
|
190
181
|
router.initialize()
|
|
191
182
|
|
|
192
|
-
// Should match with or without leading slash in request
|
|
193
183
|
const result1 = router.match('get', '/test')
|
|
194
184
|
assert.ok(result1, 'Should match /test')
|
|
195
185
|
assert.strictEqual(result1.route, 'test')
|
|
@@ -220,7 +210,6 @@ describe('PathToRegexRouter', () => {
|
|
|
220
210
|
|
|
221
211
|
router.initialize()
|
|
222
212
|
|
|
223
|
-
// Channel routes should be accessible via GET method
|
|
224
213
|
const wsResult = router.match('get', '/ws/test')
|
|
225
214
|
assert.ok(wsResult, 'Static channel route should match')
|
|
226
215
|
assert.strictEqual(wsResult.route, '/ws/test')
|
|
@@ -259,7 +248,6 @@ describe('PathToRegexRouter', () => {
|
|
|
259
248
|
|
|
260
249
|
const result = router.match('get', '/api/test')
|
|
261
250
|
assert.ok(result, 'Route should match')
|
|
262
|
-
// Router only returns route and params, middleware is handled separately
|
|
263
251
|
assert.strictEqual(result.route, '/api/test')
|
|
264
252
|
assert.deepStrictEqual(result.params, {})
|
|
265
253
|
})
|
|
@@ -310,7 +298,6 @@ describe('PathToRegexRouter', () => {
|
|
|
310
298
|
pikkuState(null, 'http', 'middleware', new Map())
|
|
311
299
|
pikkuState(null, 'channel', 'channels', new Map())
|
|
312
300
|
|
|
313
|
-
// Don't call initialize manually
|
|
314
301
|
const result = router.match('get', '/test')
|
|
315
302
|
assert.ok(result, 'Should auto-initialize and match')
|
|
316
303
|
assert.strictEqual(result.route, '/test')
|
|
@@ -29,7 +29,6 @@ export class PathToRegexRouter implements Router {
|
|
|
29
29
|
const routes = pikkuState(null, 'http', 'routes')
|
|
30
30
|
const channelRoutes = pikkuState(null, 'channel', 'channels')
|
|
31
31
|
|
|
32
|
-
// Helper function to compile routes for a given method
|
|
33
32
|
const compileRoutesForMethod = (
|
|
34
33
|
method: HTTPMethod,
|
|
35
34
|
routeEntries: Iterable<[string, any]>
|
|
@@ -40,28 +39,24 @@ export class PathToRegexRouter implements Router {
|
|
|
40
39
|
this.staticRoutes.get(method) || new Map<string, StaticRoute>()
|
|
41
40
|
|
|
42
41
|
for (const [routePath] of routeEntries) {
|
|
43
|
-
// Normalize route path - ensure it starts with /
|
|
44
42
|
const normalizedRoutePath = routePath.startsWith('/')
|
|
45
43
|
? routePath
|
|
46
44
|
: `/${routePath}`
|
|
47
45
|
|
|
48
|
-
// Check if route is static (no parameters or wildcards)
|
|
49
46
|
const isStaticRoute = !/\*|:/.test(normalizedRoutePath)
|
|
50
47
|
|
|
51
48
|
if (isStaticRoute) {
|
|
52
|
-
// Store static routes for O(1) lookup
|
|
53
49
|
methodStaticRoutes.set(normalizedRoutePath, {
|
|
54
|
-
route: routePath,
|
|
50
|
+
route: routePath,
|
|
55
51
|
})
|
|
56
52
|
} else {
|
|
57
|
-
// Compile dynamic routes with path-to-regexp
|
|
58
53
|
const matcher = match(normalizedRoutePath, {
|
|
59
54
|
decode: decodeURIComponent,
|
|
60
55
|
})
|
|
61
56
|
|
|
62
57
|
methodCompiledRoutes.set(normalizedRoutePath, {
|
|
63
58
|
matcher,
|
|
64
|
-
route: routePath,
|
|
59
|
+
route: routePath,
|
|
65
60
|
})
|
|
66
61
|
}
|
|
67
62
|
}
|
|
@@ -70,12 +65,10 @@ export class PathToRegexRouter implements Router {
|
|
|
70
65
|
this.staticRoutes.set(method, methodStaticRoutes)
|
|
71
66
|
}
|
|
72
67
|
|
|
73
|
-
// Precompile all HTTP route matchers
|
|
74
68
|
for (const [method, routeMap] of routes.entries()) {
|
|
75
69
|
compileRoutesForMethod(method, routeMap.entries())
|
|
76
70
|
}
|
|
77
71
|
|
|
78
|
-
// Precompile all channel route matchers (treating them as GET routes for WebSocket upgrades)
|
|
79
72
|
const channelRoutesArray: Array<[string, any]> = Array.from(
|
|
80
73
|
channelRoutes.entries()
|
|
81
74
|
).map(([, channel]) => [channel.route, channel])
|
|
@@ -89,10 +82,8 @@ export class PathToRegexRouter implements Router {
|
|
|
89
82
|
this.initialize()
|
|
90
83
|
}
|
|
91
84
|
|
|
92
|
-
// Normalize path - ensure it starts with /
|
|
93
85
|
const normalizedPath = path.startsWith('/') ? path : `/${path}`
|
|
94
86
|
|
|
95
|
-
// First, try static routes for O(1) lookup
|
|
96
87
|
const methodStaticRoutes = this.staticRoutes.get(method)
|
|
97
88
|
if (methodStaticRoutes) {
|
|
98
89
|
const staticRoute = methodStaticRoutes.get(normalizedPath)
|
|
@@ -104,13 +95,11 @@ export class PathToRegexRouter implements Router {
|
|
|
104
95
|
}
|
|
105
96
|
}
|
|
106
97
|
|
|
107
|
-
// If no static route matched, try dynamic routes
|
|
108
98
|
const methodRoutes = this.compiledRoutes.get(method)
|
|
109
99
|
if (!methodRoutes) {
|
|
110
100
|
return null
|
|
111
101
|
}
|
|
112
102
|
|
|
113
|
-
// Try each compiled route for this method
|
|
114
103
|
for (const [, compiledRoute] of methodRoutes.entries()) {
|
|
115
104
|
const result = compiledRoute.matcher(normalizedPath)
|
|
116
105
|
if (result) {
|
|
@@ -34,7 +34,7 @@ const createMockResponse = () => {
|
|
|
34
34
|
const state = {
|
|
35
35
|
statusCode: 0,
|
|
36
36
|
headers: {} as Record<string, string | string[]>,
|
|
37
|
-
body: null as string | null,
|
|
37
|
+
body: null as string | Uint8Array | null,
|
|
38
38
|
redirectUrl: null as string | null,
|
|
39
39
|
redirectStatus: null as number | null,
|
|
40
40
|
}
|
|
@@ -55,7 +55,9 @@ const createMockResponse = () => {
|
|
|
55
55
|
return res
|
|
56
56
|
},
|
|
57
57
|
arrayBuffer(data: any) {
|
|
58
|
-
|
|
58
|
+
// Recorded as given. Coercing a non-string to null here would have hidden
|
|
59
|
+
// a body that arrived as bytes, which is the case worth testing.
|
|
60
|
+
state.body = data ?? null
|
|
59
61
|
return res
|
|
60
62
|
},
|
|
61
63
|
redirect(location: string, status?: number) {
|
|
@@ -348,4 +350,33 @@ describe('applyWebResponse', () => {
|
|
|
348
350
|
assert.equal(state.headers['content-length'], undefined)
|
|
349
351
|
assert.equal(state.headers['transfer-encoding'], undefined)
|
|
350
352
|
})
|
|
353
|
+
|
|
354
|
+
test('passes a binary body through byte for byte', async () => {
|
|
355
|
+
// Reading a body as text is lossy for anything that is not valid UTF-8:
|
|
356
|
+
// 0x8e is not, and decoding it produces U+FFFD, which re-encodes to three
|
|
357
|
+
// bytes. A WASM module or a model file goes over the wire bigger than it
|
|
358
|
+
// started and no longer parses, with a 200 and nothing logged either side.
|
|
359
|
+
const { res, state } = createMockResponse()
|
|
360
|
+
const bytes = new Uint8Array([0x00, 0x61, 0x73, 0x6d, 0x01, 0x8e, 0xff])
|
|
361
|
+
const webRes = new Response(bytes, {
|
|
362
|
+
status: 200,
|
|
363
|
+
headers: { 'content-type': 'application/wasm' },
|
|
364
|
+
})
|
|
365
|
+
|
|
366
|
+
await applyWebResponse(res, webRes)
|
|
367
|
+
|
|
368
|
+
assert.deepEqual(new Uint8Array(state.body as Uint8Array), bytes)
|
|
369
|
+
})
|
|
370
|
+
|
|
371
|
+
test('still writes a JSON body as text', async () => {
|
|
372
|
+
const { res, state } = createMockResponse()
|
|
373
|
+
const webRes = new Response('{"ok":true}', {
|
|
374
|
+
status: 200,
|
|
375
|
+
headers: { 'content-type': 'application/json; charset=utf-8' },
|
|
376
|
+
})
|
|
377
|
+
|
|
378
|
+
await applyWebResponse(res, webRes)
|
|
379
|
+
|
|
380
|
+
assert.equal(state.body, '{"ok":true}')
|
|
381
|
+
})
|
|
351
382
|
})
|
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import type { PikkuHTTPRequest } from './http.types.js'
|
|
2
2
|
import type { PikkuHTTPResponse } from './http.types.js'
|
|
3
3
|
|
|
4
|
-
/**
|
|
5
|
-
* Converts a PikkuHTTPRequest into a Web API Request.
|
|
6
|
-
* Useful for bridging Pikku routes to libraries that expect standard Web Request objects.
|
|
7
|
-
*/
|
|
8
4
|
export function toWebRequest(req: PikkuHTTPRequest, baseUrl?: string): Request {
|
|
9
5
|
const proto = req.header('x-forwarded-proto') ?? 'http'
|
|
10
6
|
const host =
|
|
@@ -30,11 +26,6 @@ export function toWebRequest(req: PikkuHTTPRequest, baseUrl?: string): Request {
|
|
|
30
26
|
return new Request(url, {
|
|
31
27
|
method,
|
|
32
28
|
headers,
|
|
33
|
-
// `pull` (lazy) rather than `start` (eager): the body is only read from the
|
|
34
|
-
// underlying request when this stream is actually consumed. A consumer that
|
|
35
|
-
// builds a web Request just to read its headers (e.g. a session middleware
|
|
36
|
-
// calling getSession({ headers })) never touches the body, so it does zero
|
|
37
|
-
// body I/O and cannot race the route handler's read of the same request.
|
|
38
29
|
body: new ReadableStream({
|
|
39
30
|
async pull(controller) {
|
|
40
31
|
try {
|
|
@@ -42,7 +33,6 @@ export function toWebRequest(req: PikkuHTTPRequest, baseUrl?: string): Request {
|
|
|
42
33
|
if (buffer.byteLength > 0) {
|
|
43
34
|
controller.enqueue(new Uint8Array(buffer))
|
|
44
35
|
} else {
|
|
45
|
-
// arrayBuffer may be empty if body was pre-parsed (e.g., Express middleware)
|
|
46
36
|
const contentType = (
|
|
47
37
|
headers.get('content-type') || ''
|
|
48
38
|
).toLowerCase()
|
|
@@ -63,9 +53,7 @@ export function toWebRequest(req: PikkuHTTPRequest, baseUrl?: string): Request {
|
|
|
63
53
|
controller.enqueue(new TextEncoder().encode(reconstructed))
|
|
64
54
|
}
|
|
65
55
|
}
|
|
66
|
-
} catch {
|
|
67
|
-
// Empty body
|
|
68
|
-
}
|
|
56
|
+
} catch {}
|
|
69
57
|
controller.close()
|
|
70
58
|
},
|
|
71
59
|
}),
|
|
@@ -108,9 +96,34 @@ function collectSetCookieHeaders(webResponse: Response): string[] {
|
|
|
108
96
|
}
|
|
109
97
|
|
|
110
98
|
/**
|
|
111
|
-
*
|
|
112
|
-
*
|
|
99
|
+
* Content types whose bodies are text. Everything else is bytes.
|
|
100
|
+
*
|
|
101
|
+
* The distinction matters because reading a body as text is lossy for anything
|
|
102
|
+
* that is not valid UTF-8: every byte that does not decode becomes U+FFFD, and
|
|
103
|
+
* re-encoding turns each of those into three bytes. A WASM module or an ONNX
|
|
104
|
+
* model served that way arrives larger than it left and no longer parses, with
|
|
105
|
+
* a 200 and no error anywhere to say why.
|
|
106
|
+
*/
|
|
107
|
+
const TEXTUAL_CONTENT_TYPE =
|
|
108
|
+
/^(text\/|application\/(json|javascript|ecmascript|xml|x-www-form-urlencoded)|[^;]*\+(json|xml)\b)/i
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Read a response body as text where that is meaningful, and as bytes
|
|
112
|
+
* otherwise. An absent content type is treated as text, which is what a body
|
|
113
|
+
* built from a string gets by default and so preserves existing behaviour.
|
|
113
114
|
*/
|
|
115
|
+
async function readBody(
|
|
116
|
+
webResponse: Response
|
|
117
|
+
): Promise<string | Uint8Array | null> {
|
|
118
|
+
const contentType = webResponse.headers.get('content-type')
|
|
119
|
+
if (contentType === null || TEXTUAL_CONTENT_TYPE.test(contentType)) {
|
|
120
|
+
const text = await webResponse.text()
|
|
121
|
+
return text === '' ? null : text
|
|
122
|
+
}
|
|
123
|
+
const bytes = new Uint8Array(await webResponse.arrayBuffer())
|
|
124
|
+
return bytes.byteLength === 0 ? null : bytes
|
|
125
|
+
}
|
|
126
|
+
|
|
114
127
|
export async function applyWebResponse(
|
|
115
128
|
res: PikkuHTTPResponse,
|
|
116
129
|
webResponse: Response
|
|
@@ -138,8 +151,8 @@ export async function applyWebResponse(
|
|
|
138
151
|
res.header('Set-Cookie', setCookieValues)
|
|
139
152
|
}
|
|
140
153
|
|
|
141
|
-
const body = await webResponse
|
|
142
|
-
if (body) {
|
|
154
|
+
const body = await readBody(webResponse)
|
|
155
|
+
if (body !== null) {
|
|
143
156
|
if (res.send) {
|
|
144
157
|
res.send(body)
|
|
145
158
|
} else {
|
|
@@ -132,7 +132,6 @@ describe('MCPEndpointRegistry', () => {
|
|
|
132
132
|
})
|
|
133
133
|
|
|
134
134
|
test('should handle empty object gracefully', async () => {
|
|
135
|
-
// Test with empty object
|
|
136
135
|
await registry.loadFromMCPJson({})
|
|
137
136
|
assert.deepStrictEqual(registry.getTools(), [])
|
|
138
137
|
assert.deepStrictEqual(registry.getResources(), [])
|
|
@@ -13,7 +13,6 @@ import type {
|
|
|
13
13
|
} from '../../function/functions.types.js'
|
|
14
14
|
import { getErrorResponse } from '../../errors/error-handler.js'
|
|
15
15
|
import { isProduction } from '../../env.js'
|
|
16
|
-
import { closeWireServices } from '../../utils.js'
|
|
17
16
|
import {
|
|
18
17
|
pikkuState,
|
|
19
18
|
getSingletonServices,
|
|
@@ -36,10 +35,7 @@ export class MCPError extends Error {
|
|
|
36
35
|
|
|
37
36
|
export type RunMCPEndpointParams<Tools extends string = any> = {
|
|
38
37
|
mcp?: PikkuMCP<Tools>
|
|
39
|
-
/**
|
|
40
|
-
* Surface the error message + stack on unexpected internal errors.
|
|
41
|
-
* Defaults to enabled outside of production.
|
|
42
|
-
*/
|
|
38
|
+
/** Defaults to enabled outside production. */
|
|
43
39
|
exposeErrors?: boolean
|
|
44
40
|
}
|
|
45
41
|
|
|
@@ -112,13 +108,11 @@ export async function runMCPResource(
|
|
|
112
108
|
pikkuFuncId = metas[uri]?.pikkuFuncId
|
|
113
109
|
} else {
|
|
114
110
|
for (const [uriTemplate, value] of endpoints.entries()) {
|
|
115
|
-
// Extract parameter names from the template
|
|
116
111
|
const paramNames = Array.from(
|
|
117
112
|
uriTemplate.matchAll(/\{([^}]+)\}/g),
|
|
118
113
|
(m) => m[1]
|
|
119
114
|
)
|
|
120
115
|
|
|
121
|
-
// Create regex pattern to match and capture parameter values
|
|
122
116
|
const regexPattern = uriTemplate.replace(/\{[^}]+\}/g, '([^/]+)')
|
|
123
117
|
const regex = new RegExp(`^${regexPattern}$`)
|
|
124
118
|
const match = uri.match(regex)
|
|
@@ -127,7 +121,6 @@ export async function runMCPResource(
|
|
|
127
121
|
endpoint = value
|
|
128
122
|
pikkuFuncId = metas[uriTemplate]?.pikkuFuncId
|
|
129
123
|
|
|
130
|
-
// Extract parameter values and create params object
|
|
131
124
|
for (let i = 0; i < paramNames.length; i++) {
|
|
132
125
|
extractedParams[paramNames[i]!] = match[i + 1]! // match[0] is the full match
|
|
133
126
|
}
|
|
@@ -184,9 +177,6 @@ export async function runMCPPrompt(
|
|
|
184
177
|
)
|
|
185
178
|
}
|
|
186
179
|
|
|
187
|
-
/**
|
|
188
|
-
* JSON-RPC 2.0 compatible MCP endpoint runner
|
|
189
|
-
*/
|
|
190
180
|
async function runMCPPikkuFunc(
|
|
191
181
|
request: JsonRpcRequest,
|
|
192
182
|
type: 'resource' | 'tool' | 'prompt',
|
|
@@ -197,7 +187,6 @@ async function runMCPPikkuFunc(
|
|
|
197
187
|
): Promise<JsonRpcResponse> {
|
|
198
188
|
const singletonServices = getSingletonServices()
|
|
199
189
|
const createWireServices = getCreateWireServices()
|
|
200
|
-
let wireServices: any
|
|
201
190
|
|
|
202
191
|
try {
|
|
203
192
|
if (request.jsonrpc !== '2.0') {
|
|
@@ -237,7 +226,6 @@ async function runMCPPikkuFunc(
|
|
|
237
226
|
meta = pikkuState(null, 'mcp', 'promptsMeta')[name]
|
|
238
227
|
}
|
|
239
228
|
|
|
240
|
-
// Resolve namespaced function IDs (e.g., 'swaggerPetstore:findPetsByStatus')
|
|
241
229
|
let resolvedFuncName = pikkuFuncId
|
|
242
230
|
let resolvedPackageName: string | null = meta?.packageName ?? null
|
|
243
231
|
if (pikkuFuncId.includes(':')) {
|
|
@@ -295,16 +283,13 @@ async function runMCPPikkuFunc(
|
|
|
295
283
|
id: request.id,
|
|
296
284
|
code: -32603,
|
|
297
285
|
message: 'Internal error',
|
|
286
|
+
// knowledge: decisions/security/mcp-internal-error-details-are-double-gated-on-production.md
|
|
298
287
|
data:
|
|
299
288
|
exposeErrors && !isProduction() && e instanceof Error
|
|
300
289
|
? { message: e.message, stack: e.stack }
|
|
301
290
|
: undefined,
|
|
302
291
|
})
|
|
303
292
|
}
|
|
304
|
-
} finally {
|
|
305
|
-
if (wireServices) {
|
|
306
|
-
await closeWireServices(singletonServices.logger, wireServices)
|
|
307
|
-
}
|
|
308
293
|
}
|
|
309
294
|
}
|
|
310
295
|
|