@pikku/core 0.12.71 → 0.12.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +848 -0
- package/dist/crypto-utils.d.ts +30 -5
- package/dist/crypto-utils.js +146 -41
- package/dist/dev/hot-reload.js +11 -30
- package/dist/dev/module-runner.d.ts +3 -7
- package/dist/dev/module-runner.js +4 -10
- package/dist/dev/reload-meta.d.ts +8 -20
- package/dist/dev/reload-meta.js +9 -29
- package/dist/errors/error-handler.d.ts +5 -30
- package/dist/errors/error-handler.js +16 -32
- package/dist/errors/errors.d.ts +32 -151
- package/dist/errors/errors.js +55 -157
- package/dist/function/abort-scope.d.ts +47 -0
- package/dist/function/abort-scope.js +63 -0
- package/dist/function/function-runner.js +40 -30
- package/dist/function/functions.types.d.ts +44 -136
- package/dist/function/functions.types.js +0 -58
- package/dist/function/list.types.d.ts +12 -62
- package/dist/function/list.types.js +4 -25
- package/dist/handle-error.d.ts +0 -11
- package/dist/handle-error.js +6 -18
- package/dist/index.d.ts +5 -2
- package/dist/index.js +4 -1
- package/dist/middleware/auth-apikey.d.ts +3 -18
- package/dist/middleware/auth-apikey.js +0 -17
- package/dist/middleware/auth-bearer.d.ts +6 -41
- package/dist/middleware/auth-bearer.js +3 -40
- package/dist/middleware/auth-cookie.d.ts +5 -27
- package/dist/middleware/auth-cookie.js +2 -26
- package/dist/middleware/cors.d.ts +7 -34
- package/dist/middleware/cors.js +7 -34
- package/dist/middleware/remote-auth.d.ts +3 -1
- package/dist/middleware/remote-auth.js +3 -2
- package/dist/middleware/telemetry.d.ts +8 -33
- package/dist/middleware/telemetry.js +2 -31
- package/dist/middleware-runner.d.ts +4 -55
- package/dist/middleware-runner.js +5 -74
- package/dist/permissions.d.ts +3 -44
- package/dist/permissions.js +19 -71
- package/dist/pikku-request.d.ts +0 -6
- package/dist/pikku-request.js +0 -6
- package/dist/pikku-state.d.ts +0 -26
- package/dist/pikku-state.js +2 -30
- package/dist/remote.d.ts +3 -5
- package/dist/remote.js +8 -7
- package/dist/schema.d.ts +7 -17
- package/dist/schema.js +30 -18
- package/dist/scopes.d.ts +4 -23
- package/dist/scopes.js +7 -48
- package/dist/services/ai-agent-runner-service.d.ts +20 -0
- package/dist/services/ai-embedding-service.d.ts +2 -25
- package/dist/services/audit-service.js +1 -2
- package/dist/services/content-service.d.ts +1 -46
- package/dist/services/credential-service.d.ts +3 -40
- package/dist/services/deployment-service.d.ts +3 -9
- package/dist/services/gateway-service.d.ts +0 -15
- package/dist/services/http-personas.d.ts +80 -0
- package/dist/services/http-personas.js +233 -0
- package/dist/services/in-memory-queue-service.d.ts +0 -14
- package/dist/services/in-memory-queue-service.js +1 -15
- package/dist/services/in-memory-trigger-service.d.ts +0 -18
- package/dist/services/in-memory-trigger-service.js +1 -18
- package/dist/services/in-memory-workflow-service.d.ts +0 -16
- package/dist/services/in-memory-workflow-service.js +4 -33
- package/dist/services/index.d.ts +5 -6
- package/dist/services/index.js +2 -5
- package/dist/services/istanbul-coverage-service.d.ts +1 -5
- package/dist/services/istanbul-coverage-service.js +2 -8
- package/dist/services/jwt-service.d.ts +1 -16
- package/dist/services/local-content.d.ts +13 -2
- package/dist/services/local-content.js +40 -13
- package/dist/services/local-gateway-service.d.ts +0 -16
- package/dist/services/local-gateway-service.js +2 -17
- package/dist/services/local-secrets.d.ts +0 -4
- package/dist/services/local-secrets.js +0 -4
- package/dist/services/logger-console.d.ts +3 -7
- package/dist/services/logger-console.js +3 -7
- package/dist/services/logger.d.ts +2 -37
- package/dist/services/meta-service.d.ts +23 -26
- package/dist/services/meta-service.js +22 -36
- package/dist/services/personas-service.d.ts +134 -0
- package/dist/services/personas-service.js +40 -0
- package/dist/services/pikku-user-id.js +0 -4
- package/dist/services/queue-webhook-service.d.ts +2 -36
- package/dist/services/queue-webhook-service.js +9 -41
- package/dist/services/scheduler-service.d.ts +1 -50
- package/dist/services/scheduler-service.js +0 -10
- package/dist/services/schema-service.d.ts +1 -24
- package/dist/services/scope-service.d.ts +49 -34
- package/dist/services/scoped-secret-service.d.ts +0 -4
- package/dist/services/scoped-secret-service.js +0 -4
- package/dist/services/secret-host-binding.d.ts +8 -0
- package/dist/services/secret-host-binding.js +36 -0
- package/dist/services/secret-service.d.ts +5 -33
- package/dist/services/secretless.d.ts +6 -0
- package/dist/services/secretless.js +21 -0
- package/dist/services/stub-tracker.d.ts +7 -18
- package/dist/services/stub-tracker.js +8 -18
- package/dist/services/system-role-guard.d.ts +33 -0
- package/dist/services/system-role-guard.js +38 -0
- package/dist/services/trigger-service.d.ts +0 -12
- package/dist/services/typed-secret-service.d.ts +0 -7
- package/dist/services/typed-secret-service.js +1 -7
- package/dist/services/v8-coverage-service.d.ts +2 -3
- package/dist/services/v8-coverage-service.js +1 -2
- package/dist/services/variables-service.d.ts +1 -8
- package/dist/services/webhook-service.d.ts +19 -63
- package/dist/services/webhook-service.js +6 -20
- package/dist/services/workflow-service.d.ts +3 -15
- package/dist/testing/service-tests.js +0 -17
- package/dist/time-utils.d.ts +0 -16
- package/dist/time-utils.js +1 -19
- package/dist/types/core.types.d.ts +99 -219
- package/dist/types/core.types.js +0 -42
- package/dist/types/state.types.d.ts +4 -9
- package/dist/utils/hmac.d.ts +4 -10
- package/dist/utils/hmac.js +4 -10
- package/dist/utils/safe-fetch.d.ts +7 -35
- package/dist/utils/safe-fetch.js +13 -53
- package/dist/utils.d.ts +1 -6
- package/dist/utils.js +6 -15
- package/dist/wirings/actor-flow/actor-flow.types.d.ts +1 -34
- package/dist/wirings/actor-flow/index.d.ts +0 -9
- package/dist/wirings/actor-flow/run-conversation.d.ts +5 -5
- package/dist/wirings/actor-flow/run-conversation.js +14 -7
- package/dist/wirings/ai-agent/ai-agent-agui.d.ts +0 -5
- package/dist/wirings/ai-agent/ai-agent-agui.js +34 -12
- package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +7 -0
- package/dist/wirings/ai-agent/ai-agent-helpers.js +7 -0
- package/dist/wirings/ai-agent/ai-agent-interrupt.d.ts +153 -0
- package/dist/wirings/ai-agent/ai-agent-interrupt.js +256 -0
- package/dist/wirings/ai-agent/ai-agent-memory.js +0 -2
- package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +0 -9
- package/dist/wirings/ai-agent/ai-agent-model-config.js +1 -9
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +10 -99
- package/dist/wirings/ai-agent/ai-agent-prepare.js +58 -131
- package/dist/wirings/ai-agent/ai-agent-registry.d.ts +2 -1
- package/dist/wirings/ai-agent/ai-agent-registry.js +5 -1
- package/dist/wirings/ai-agent/ai-agent-runner.js +49 -20
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +25 -2
- package/dist/wirings/ai-agent/ai-agent-stream.js +153 -63
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +84 -4
- package/dist/wirings/ai-agent/index.d.ts +6 -4
- package/dist/wirings/ai-agent/index.js +5 -4
- package/dist/wirings/ai-agent/voice-input.d.ts +39 -1
- package/dist/wirings/ai-agent/voice-input.js +46 -3
- package/dist/wirings/ai-agent/voice-output.d.ts +54 -1
- package/dist/wirings/ai-agent/voice-output.js +153 -50
- package/dist/wirings/channel/channel-common.d.ts +7 -20
- package/dist/wirings/channel/channel-common.js +7 -21
- package/dist/wirings/channel/channel-handler.js +25 -6
- package/dist/wirings/channel/channel-host-rpc.d.ts +25 -0
- package/dist/wirings/channel/channel-host-rpc.js +38 -0
- package/dist/wirings/channel/channel-middleware-runner.d.ts +0 -12
- package/dist/wirings/channel/channel-middleware-runner.js +0 -12
- package/dist/wirings/channel/channel-rpc-registry.d.ts +31 -0
- package/dist/wirings/channel/channel-rpc-registry.js +89 -0
- package/dist/wirings/channel/channel-rpc-responder.d.ts +15 -0
- package/dist/wirings/channel/channel-rpc-responder.js +71 -0
- package/dist/wirings/channel/channel-rpc-service.d.ts +40 -0
- package/dist/wirings/channel/channel-rpc-service.js +106 -0
- package/dist/wirings/channel/channel-rpc-validators.d.ts +14 -0
- package/dist/wirings/channel/channel-rpc-validators.js +30 -0
- package/dist/wirings/channel/channel-rpc.d.ts +5 -0
- package/dist/wirings/channel/channel-rpc.js +5 -0
- package/dist/wirings/channel/channel-rpc.types.d.ts +90 -0
- package/dist/wirings/channel/channel-rpc.types.js +50 -0
- package/dist/wirings/channel/channel-runner.d.ts +0 -4
- package/dist/wirings/channel/channel-runner.js +0 -14
- package/dist/wirings/channel/channel-store.d.ts +0 -10
- package/dist/wirings/channel/channel.types.d.ts +12 -1
- package/dist/wirings/channel/define-channel-routes.d.ts +0 -20
- package/dist/wirings/channel/define-channel-routes.js +0 -20
- package/dist/wirings/channel/eventhub-service.d.ts +0 -18
- package/dist/wirings/channel/index.d.ts +4 -1
- package/dist/wirings/channel/index.js +2 -0
- package/dist/wirings/channel/local/local-channel-runner.js +3 -1
- package/dist/wirings/channel/local/local-eventhub-service.d.ts +0 -33
- package/dist/wirings/channel/local/local-eventhub-service.js +2 -36
- package/dist/wirings/channel/log-channels.d.ts +0 -4
- package/dist/wirings/channel/log-channels.js +0 -4
- package/dist/wirings/channel/pikku-abstract-channel-handler.js +6 -0
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +2 -5
- package/dist/wirings/cli/channel/cli-approval.d.ts +41 -0
- package/dist/wirings/cli/channel/cli-approval.js +81 -0
- package/dist/wirings/cli/channel/cli-channel-runner.d.ts +0 -4
- package/dist/wirings/cli/channel/cli-channel-runner.js +3 -25
- package/dist/wirings/cli/channel/cli-raw-channel-runner.d.ts +47 -9
- package/dist/wirings/cli/channel/cli-raw-channel-runner.js +24 -16
- package/dist/wirings/cli/channel/cli-raw-client-runner.d.ts +20 -0
- package/dist/wirings/cli/channel/cli-raw-client-runner.js +121 -0
- package/dist/wirings/cli/channel/index.d.ts +4 -0
- package/dist/wirings/cli/channel/index.js +2 -0
- package/dist/wirings/cli/cli-runner.d.ts +20 -20
- package/dist/wirings/cli/cli-runner.js +28 -89
- package/dist/wirings/cli/cli.types.d.ts +14 -3
- package/dist/wirings/cli/command-parser.d.ts +1 -10
- package/dist/wirings/cli/command-parser.js +10 -87
- package/dist/wirings/cli/define-cli-commands.d.ts +1 -17
- package/dist/wirings/cli/define-cli-commands.js +1 -17
- package/dist/wirings/credential/credential.types.d.ts +0 -12
- package/dist/wirings/credential/define-credential.d.ts +48 -0
- package/dist/wirings/credential/define-credential.js +47 -0
- package/dist/wirings/credential/index.d.ts +1 -1
- package/dist/wirings/credential/index.js +1 -1
- package/dist/wirings/credential/validate-credential-definitions.d.ts +2 -4
- package/dist/wirings/gateway/gateway-runner.d.ts +1 -20
- package/dist/wirings/gateway/gateway-runner.js +8 -105
- package/dist/wirings/gateway/gateway.types.d.ts +7 -80
- package/dist/wirings/http/http-routes.d.ts +0 -63
- package/dist/wirings/http/http-routes.js +0 -63
- package/dist/wirings/http/http-runner.d.ts +1 -100
- package/dist/wirings/http/http-runner.js +12 -166
- package/dist/wirings/http/http.types.d.ts +16 -55
- package/dist/wirings/http/index.d.ts +2 -1
- package/dist/wirings/http/index.js +1 -1
- package/dist/wirings/http/log-http-routes.d.ts +0 -4
- package/dist/wirings/http/log-http-routes.js +0 -4
- package/dist/wirings/http/pikku-fetch-http-request.d.ts +6 -36
- package/dist/wirings/http/pikku-fetch-http-request.js +56 -50
- package/dist/wirings/http/pikku-fetch-http-response.js +0 -3
- package/dist/wirings/http/routers/path-to-regex.js +2 -13
- package/dist/wirings/http/web-request.d.ts +0 -8
- package/dist/wirings/http/web-request.js +25 -17
- package/dist/wirings/mcp/mcp-runner.d.ts +2 -0
- package/dist/wirings/mcp/mcp-runner.js +6 -16
- package/dist/wirings/mcp/mcp.types.d.ts +2 -35
- package/dist/wirings/oauth2/oauth2.types.d.ts +0 -28
- package/dist/wirings/oauth2/oauth2.types.js +0 -3
- package/dist/wirings/persona/define-personas.d.ts +28 -0
- package/dist/wirings/persona/define-personas.js +27 -0
- package/dist/wirings/persona/index.d.ts +21 -0
- package/dist/wirings/persona/index.js +17 -0
- package/dist/wirings/persona/persona-email.d.ts +37 -0
- package/dist/wirings/persona/persona-email.js +69 -0
- package/dist/wirings/persona/persona-environments.d.ts +45 -0
- package/dist/wirings/persona/persona-environments.js +81 -0
- package/dist/wirings/persona/persona-mailbox.d.ts +101 -0
- package/dist/wirings/persona/persona-mailbox.js +53 -0
- package/dist/wirings/persona/persona.types.d.ts +125 -0
- package/dist/wirings/persona/persona.types.js +1 -0
- package/dist/wirings/persona/validate-personas.d.ts +53 -0
- package/dist/wirings/persona/validate-personas.js +94 -0
- package/dist/wirings/queue/index.d.ts +3 -0
- package/dist/wirings/queue/index.js +2 -3
- package/dist/wirings/queue/queue-identity.d.ts +28 -0
- package/dist/wirings/queue/queue-identity.js +102 -0
- package/dist/wirings/queue/queue-runner.d.ts +0 -19
- package/dist/wirings/queue/queue-runner.js +9 -30
- package/dist/wirings/queue/queue.types.d.ts +18 -89
- package/dist/wirings/queue/register-queue-helper.d.ts +0 -12
- package/dist/wirings/queue/register-queue-helper.js +0 -11
- package/dist/wirings/queue/signed-queue-service.d.ts +16 -0
- package/dist/wirings/queue/signed-queue-service.js +42 -0
- package/dist/wirings/queue/validate-worker-config.d.ts +2 -23
- package/dist/wirings/queue/validate-worker-config.js +0 -14
- package/dist/wirings/role/define-system-role.d.ts +32 -0
- package/dist/wirings/role/define-system-role.js +31 -0
- package/dist/wirings/role/index.d.ts +3 -0
- package/dist/wirings/role/index.js +2 -0
- package/dist/wirings/role/role.types.d.ts +43 -0
- package/dist/wirings/role/role.types.js +1 -0
- package/dist/wirings/role/validate-role-definitions.d.ts +21 -0
- package/dist/wirings/role/validate-role-definitions.js +71 -0
- package/dist/wirings/rpc/addon-runner.d.ts +0 -19
- package/dist/wirings/rpc/addon-runner.js +0 -51
- package/dist/wirings/rpc/remote-addon-auth.d.ts +1 -12
- package/dist/wirings/rpc/remote-addon-auth.js +1 -9
- package/dist/wirings/rpc/rpc-runner.d.ts +11 -18
- package/dist/wirings/rpc/rpc-runner.js +88 -105
- package/dist/wirings/rpc/rpc-types.d.ts +7 -6
- package/dist/wirings/rpc/wire-addon.d.ts +25 -0
- package/dist/wirings/rpc/wire-addon.js +62 -0
- package/dist/wirings/rpc/wire-remote-addon.d.ts +3 -28
- package/dist/wirings/rpc/wire-remote-addon.js +0 -8
- package/dist/wirings/scheduler/log-schedulers.d.ts +0 -4
- package/dist/wirings/scheduler/log-schedulers.js +0 -4
- package/dist/wirings/scheduler/scheduler-runner.d.ts +0 -1
- package/dist/wirings/scheduler/scheduler-runner.js +0 -1
- package/dist/wirings/scheduler/scheduler.types.d.ts +1 -14
- package/dist/wirings/scope/define-scope.d.ts +32 -0
- package/dist/wirings/scope/define-scope.js +31 -0
- package/dist/wirings/scope/index.d.ts +1 -1
- package/dist/wirings/scope/index.js +1 -1
- package/dist/wirings/scope/scope.types.d.ts +7 -9
- package/dist/wirings/scope/validate-scope-definitions.d.ts +2 -21
- package/dist/wirings/scope/validate-scope-definitions.js +3 -21
- package/dist/wirings/secret/index.d.ts +1 -1
- package/dist/wirings/secret/index.js +1 -1
- package/dist/wirings/secret/secret.types.d.ts +19 -15
- package/dist/wirings/secret/secret.types.js +1 -1
- package/dist/wirings/secret/validate-secret-definitions.d.ts +2 -4
- package/dist/wirings/trigger/trigger-runner.d.ts +0 -27
- package/dist/wirings/trigger/trigger-runner.js +1 -24
- package/dist/wirings/trigger/trigger.types.d.ts +1 -82
- package/dist/wirings/trigger/trigger.types.js +0 -34
- package/dist/wirings/variable/index.d.ts +1 -1
- package/dist/wirings/variable/index.js +1 -1
- package/dist/wirings/variable/validate-variable-definitions.d.ts +2 -4
- package/dist/wirings/variable/variable.types.d.ts +1 -13
- package/dist/wirings/variable/variable.types.js +1 -1
- package/dist/wirings/virtual-user/index.d.ts +27 -0
- package/dist/wirings/virtual-user/index.js +8 -0
- package/dist/wirings/virtual-user/run-virtual-user.d.ts +92 -0
- package/dist/wirings/virtual-user/run-virtual-user.js +478 -0
- package/dist/wirings/virtual-user/virtual-user-agents.d.ts +38 -0
- package/dist/wirings/virtual-user/virtual-user-agents.js +24 -0
- package/dist/wirings/virtual-user/virtual-user-catalogue.d.ts +92 -0
- package/dist/wirings/virtual-user/virtual-user-catalogue.js +134 -0
- package/dist/wirings/virtual-user/virtual-user-derive.d.ts +26 -0
- package/dist/wirings/virtual-user/virtual-user-derive.js +137 -0
- package/dist/wirings/virtual-user/virtual-user-dispositions.d.ts +79 -0
- package/dist/wirings/virtual-user/virtual-user-dispositions.js +128 -0
- package/dist/wirings/virtual-user/virtual-user-intents.d.ts +78 -0
- package/dist/wirings/virtual-user/virtual-user-intents.js +142 -0
- package/dist/wirings/virtual-user/virtual-user-rng.d.ts +24 -0
- package/dist/wirings/virtual-user/virtual-user-rng.js +44 -0
- package/dist/wirings/virtual-user/virtual-user-target.d.ts +21 -0
- package/dist/wirings/virtual-user/virtual-user-target.js +34 -0
- package/dist/wirings/virtual-user/virtual-user.types.d.ts +199 -0
- package/dist/wirings/virtual-user/virtual-user.types.js +8 -0
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +5 -5
- package/dist/wirings/workflow/dsl/workflow-runner.d.ts +0 -4
- package/dist/wirings/workflow/dsl/workflow-runner.js +0 -4
- package/dist/wirings/workflow/feature.d.ts +0 -19
- package/dist/wirings/workflow/feature.js +0 -19
- package/dist/wirings/workflow/graph/graph-node.d.ts +0 -98
- package/dist/wirings/workflow/graph/graph-node.js +0 -34
- package/dist/wirings/workflow/graph/graph-runner.js +6 -41
- package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +0 -4
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -58
- package/dist/wirings/workflow/graph/workflow-graph.types.js +0 -6
- package/dist/wirings/workflow/index.d.ts +5 -7
- package/dist/wirings/workflow/index.js +3 -17
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +87 -5
- package/dist/wirings/workflow/pikku-scenario-service.js +204 -42
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +7 -459
- package/dist/wirings/workflow/pikku-workflow-service.js +58 -551
- package/dist/wirings/workflow/run-timeline.d.ts +0 -47
- package/dist/wirings/workflow/run-timeline.js +0 -22
- package/dist/wirings/workflow/scenario-cookie-jar.d.ts +0 -23
- package/dist/wirings/workflow/scenario-cookie-jar.js +0 -16
- package/dist/wirings/workflow/scenario-poll.d.ts +0 -15
- package/dist/wirings/workflow/scenario-poll.js +0 -12
- package/dist/wirings/workflow/scenario-prose.d.ts +0 -28
- package/dist/wirings/workflow/scenario-prose.js +0 -18
- package/dist/wirings/workflow/scenario-step-guards.d.ts +0 -13
- package/dist/wirings/workflow/scenario-step-guards.js +1 -14
- package/dist/wirings/workflow/scenario-step.types.d.ts +72 -6
- package/dist/wirings/workflow/scenario-step.types.js +5 -1
- package/dist/wirings/workflow/scenario-surface.d.ts +16 -0
- package/dist/wirings/workflow/scenario-surface.js +56 -0
- package/dist/wirings/workflow/workflow-invocation-id.d.ts +0 -18
- package/dist/wirings/workflow/workflow-invocation-id.js +2 -22
- package/dist/wirings/workflow/workflow-queue-workers.d.ts +0 -20
- package/dist/wirings/workflow/workflow-queue-workers.js +0 -19
- package/dist/wirings/workflow/workflow.types.d.ts +0 -197
- package/knowledge/decisions/index.md +19 -0
- package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +49 -0
- package/knowledge/decisions/internals/actor-flow-conversations-seed-a-hidden-kickoff-message.md +23 -0
- package/knowledge/decisions/internals/actor-flow-drives-the-target-through-a-transport-seam.md +24 -0
- package/knowledge/decisions/internals/actor-flow-verdicts-are-llm-self-evaluations.md +25 -0
- package/knowledge/decisions/internals/addon-package-roots-resolve-by-walking-node-module-search-paths.md +26 -0
- package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +33 -0
- package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +28 -0
- package/knowledge/decisions/internals/ai-agent-agui-bridge-obeys-the-client-ordering-contract.md +29 -0
- package/knowledge/decisions/internals/ai-agent-audio-chunks-carry-the-format-the-provider-returned.md +20 -0
- package/knowledge/decisions/internals/ai-agent-credential-suspensions-hide-the-tool-result.md +26 -0
- package/knowledge/decisions/internals/ai-agent-delegate-and-supervise-hide-different-text.md +26 -0
- package/knowledge/decisions/internals/ai-agent-llm-tool-arguments-have-nulls-stripped.md +23 -0
- package/knowledge/decisions/internals/ai-agent-model-config-stays-a-single-resolution-seam.md +25 -0
- package/knowledge/decisions/internals/ai-agent-onerror-hooks-cannot-change-the-failure.md +22 -0
- package/knowledge/decisions/internals/ai-agent-runner-methods-must-keep-their-receiver.md +22 -0
- package/knowledge/decisions/internals/ai-agent-stream-persistence-is-best-effort.md +27 -0
- package/knowledge/decisions/internals/ai-agent-sub-agents-inherit-the-parent-context-block.md +26 -0
- package/knowledge/decisions/internals/ai-agent-tool-execute-failures-are-logged-unconditionally.md +25 -0
- package/knowledge/decisions/internals/ai-agent-voice-input-transcribes-audio-parts-in-place.md +22 -0
- package/knowledge/decisions/internals/ai-agent-working-memory-is-persisted-only-when-valid.md +25 -0
- package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +30 -0
- package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +31 -0
- package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md +29 -0
- package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +28 -0
- package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +27 -0
- package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +28 -0
- package/knowledge/decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md +34 -0
- package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +29 -0
- package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +34 -0
- package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +44 -0
- package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +39 -0
- package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +42 -0
- package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +39 -0
- package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +43 -0
- package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +38 -0
- package/knowledge/decisions/internals/core-state-is-a-global-map-written-only-at-registration-time.md +44 -0
- package/knowledge/decisions/internals/email-meta-is-read-uncached-because-codegen-rewrites-it-mid-session.md +27 -0
- package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +32 -0
- package/knowledge/decisions/internals/gateway-webhook-challenges-echo-bytes-not-json.md +28 -0
- package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +31 -0
- package/knowledge/decisions/internals/generated-src-paths-in-pikku-meta-are-absolute.md +26 -0
- package/knowledge/decisions/internals/http-request-bodies-are-read-once-and-shared.md +32 -0
- package/knowledge/decisions/internals/http-route-groups-cascade-config-in-a-fixed-order.md +28 -0
- package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +30 -0
- package/knowledge/decisions/internals/http-runner-logs-through-a-trace-scoped-logger-functions-do-not.md +26 -0
- package/knowledge/decisions/internals/http-set-cookie-headers-are-appended-never-joined.md +28 -0
- package/knowledge/decisions/internals/http-sse-streams-flush-headers-only-after-middleware.md +32 -0
- package/knowledge/decisions/internals/http-wiring-without-metadata-is-skipped-not-fatal.md +26 -0
- package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +25 -0
- package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +26 -0
- package/knowledge/decisions/internals/index.md +113 -0
- package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +25 -0
- package/knowledge/decisions/internals/local-trigger-and-gateway-services-assume-a-single-process.md +26 -0
- package/knowledge/decisions/internals/node-only-builtins-are-imported-dynamically.md +24 -0
- package/knowledge/decisions/internals/queue-group-concurrency-keeps-one-shared-queue-fair.md +28 -0
- package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +27 -0
- package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +31 -0
- package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +32 -0
- package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +27 -0
- package/knowledge/decisions/internals/scenario-meta-lives-apart-from-app-meta-but-merges-when-read-off-disk.md +26 -0
- package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +27 -0
- package/knowledge/decisions/internals/scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md +30 -0
- package/knowledge/decisions/internals/serverless-channel-disconnect-must-tolerate-a-missing-channel.md +28 -0
- package/knowledge/decisions/internals/the-dev-queue-copies-prod-timing-and-serialization-semantics.md +30 -0
- package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +29 -0
- package/knowledge/decisions/internals/the-in-memory-workflow-service-is-inline-only-and-single-process.md +27 -0
- package/knowledge/decisions/internals/the-kek-salt-is-scoped-to-the-key-version.md +40 -0
- package/knowledge/decisions/internals/the-schema-service-is-never-stubbed.md +26 -0
- package/knowledge/decisions/internals/trigger-declaration-is-split-from-trigger-source.md +33 -0
- package/knowledge/decisions/internals/typed-secret-service-caches-for-the-process-lifetime.md +26 -0
- package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +26 -0
- package/knowledge/decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md +25 -0
- package/knowledge/decisions/internals/whether-a-run-is-inline-is-read-from-the-run-record.md +58 -0
- package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +34 -0
- package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +42 -0
- package/knowledge/decisions/internals/workflow-dsl-meta-separates-runtime-expressions-from-literals.md +38 -0
- package/knowledge/decisions/internals/workflow-features-resolve-scenarios-by-object-identity.md +29 -0
- package/knowledge/decisions/internals/workflow-graph-inline-and-queued-runs-share-one-planner.md +42 -0
- package/knowledge/decisions/internals/workflow-graph-node-notes-are-excluded-from-the-graph-hash.md +25 -0
- package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +29 -0
- package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +43 -0
- package/knowledge/decisions/internals/workflow-queued-step-dispatch-requires-an-explicit-opt-in.md +29 -0
- package/knowledge/decisions/internals/workflow-queues-are-per-workflow-by-default.md +42 -0
- package/knowledge/decisions/internals/workflow-repeated-step-names-get-an-ordinal-suffix.md +33 -0
- package/knowledge/decisions/internals/workflow-replay-reads-its-steps-once-and-caches-only-the-immutable-half.md +32 -0
- package/knowledge/decisions/internals/workflow-retries-are-owned-by-the-workflow-not-the-queue.md +31 -0
- package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +39 -0
- package/knowledge/decisions/internals/workflow-run-mirror-is-never-a-source-of-truth.md +29 -0
- package/knowledge/decisions/internals/workflow-run-polling-backs-off-to-the-callers-ceiling.md +33 -0
- package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +37 -0
- package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +50 -0
- package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +43 -0
- package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +32 -0
- package/knowledge/decisions/internals/workflow-scenario-quarantine-reason-lives-in-code.md +18 -0
- package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +34 -0
- package/knowledge/decisions/internals/workflow-step-compensation-runs-as-its-own-durable-step.md +26 -0
- package/knowledge/decisions/internals/workflow-step-dispatch-failure-is-transient-not-a-run-failure.md +33 -0
- package/knowledge/decisions/internals/workflow-step-lock-is-held-only-to-claim-the-step.md +27 -0
- package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +34 -0
- package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +38 -0
- package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +30 -0
- package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +26 -0
- package/knowledge/decisions/security/actor-flow-missing-approval-decisions-default-to-denied.md +22 -0
- package/knowledge/decisions/security/actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +27 -0
- package/knowledge/decisions/security/actor-sign-in-only-works-for-actor-flagged-users.md +27 -0
- package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +43 -0
- package/knowledge/decisions/security/addon-config-gates-apply-only-at-the-namespaced-rpc-boundary.md +52 -0
- package/knowledge/decisions/security/addon-scopes-are-resolved-where-the-function-runs.md +46 -0
- package/knowledge/decisions/security/ai-agent-approval-forwarding-requires-a-symbol-brand.md +27 -0
- package/knowledge/decisions/security/ai-agent-credential-requests-are-symbol-branded.md +37 -0
- package/knowledge/decisions/security/ai-agent-gate-requires-a-session-only-when-auth-is-true.md +31 -0
- package/knowledge/decisions/security/ai-agent-ownership-failures-never-echo-the-resource.md +23 -0
- package/knowledge/decisions/security/ai-agent-resume-re-runs-the-authorization-gate.md +22 -0
- package/knowledge/decisions/security/ai-agent-sessionless-deployments-have-no-thread-ownership.md +39 -0
- package/knowledge/decisions/security/ai-agent-thread-ownership-composes-the-session-principal.md +30 -0
- package/knowledge/decisions/security/ai-agent-tool-filtering-reads-the-live-function-config.md +24 -0
- package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +30 -0
- package/knowledge/decisions/security/an-exposed-ungated-function-is-a-codegen-warning.md +49 -0
- package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +76 -0
- package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +39 -0
- package/knowledge/decisions/security/core-secrets-use-a-per-secret-dek-wrapped-by-a-kek.md +37 -0
- package/knowledge/decisions/security/gateway-handlers-run-through-the-function-runner-gate.md +31 -0
- package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +30 -0
- package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +40 -0
- package/knowledge/decisions/security/http-error-detail-is-withheld-from-clients-in-production.md +33 -0
- package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +46 -0
- package/knowledge/decisions/security/index.md +55 -0
- package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +27 -0
- package/knowledge/decisions/security/passphrases-are-stretched-key-material-is-expanded.md +40 -0
- package/knowledge/decisions/security/permission-auth-filtering-requires-live-permission-functions.md +31 -0
- package/knowledge/decisions/security/pikku-carries-actor-scopes-as-data-and-the-app-grants-them.md +26 -0
- package/knowledge/decisions/security/queue-job-identities-are-signed-at-enqueue.md +69 -0
- package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +39 -0
- package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +34 -0
- package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +49 -0
- package/knowledge/decisions/security/scenario-step-functions-are-never-externally-invocable.md +30 -0
- package/knowledge/decisions/security/scope-resolution-happens-at-the-session-boundary-and-sync-never-deletes.md +28 -0
- package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +34 -0
- package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +37 -0
- package/knowledge/decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md +25 -0
- package/knowledge/decisions/security/workflow-actor-steps-always-use-the-real-transport.md +34 -0
- package/knowledge/decisions/security/workflow-approval-payloads-are-validated-on-replay-inside-the-workflow.md +40 -0
- package/knowledge/decisions/security/workflow-queued-steps-rehydrate-their-session-from-the-run-wire.md +32 -0
- package/knowledge/decisions/security/workflow-scenario-sessions-are-isolated-per-actor-and-per-scenario.md +32 -0
- package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +31 -0
- package/knowledge/index.md +24 -0
- package/knowledge/questions/index.md +15 -0
- package/package.json +4 -2
- package/run-tests.sh +0 -0
- package/src/crypto-utils.test.ts +460 -19
- package/src/crypto-utils.ts +283 -55
- package/src/data-classification.ts +1 -7
- package/src/dev/hot-reload.test.ts +0 -4
- package/src/dev/hot-reload.ts +11 -30
- package/src/dev/module-runner.ts +7 -32
- package/src/dev/reload-meta.ts +9 -29
- package/src/errors/error-handler.ts +20 -35
- package/src/errors/error.test.ts +30 -1
- package/src/errors/errors.ts +73 -157
- package/src/function/abort-scope.test.ts +97 -0
- package/src/function/abort-scope.ts +80 -0
- package/src/function/function-runner.test.ts +75 -7
- package/src/function/function-runner.ts +73 -30
- package/src/function/functions.types.ts +56 -136
- package/src/function/list.types.test.ts +3 -25
- package/src/function/list.types.ts +12 -62
- package/src/gopass-secrets-removed.test.ts +51 -0
- package/src/handle-error.test.ts +108 -1
- package/src/handle-error.ts +8 -18
- package/src/index.ts +60 -1
- package/src/middleware/auth-apikey.test.ts +0 -1
- package/src/middleware/auth-apikey.ts +0 -17
- package/src/middleware/auth-bearer.test.ts +0 -3
- package/src/middleware/auth-bearer.ts +3 -40
- package/src/middleware/auth-cookie.test.ts +0 -6
- package/src/middleware/auth-cookie.ts +2 -26
- package/src/middleware/cors.test.ts +34 -0
- package/src/middleware/cors.ts +12 -33
- package/src/middleware/remote-auth.test.ts +24 -9
- package/src/middleware/remote-auth.ts +10 -2
- package/src/middleware/telemetry.ts +2 -31
- package/src/middleware-runner.test.ts +0 -2
- package/src/middleware-runner.ts +5 -74
- package/src/permissions.test.ts +30 -0
- package/src/permissions.ts +24 -74
- package/src/pikku-request.ts +0 -6
- package/src/pikku-state.ts +2 -30
- package/src/production-barrels-stay-lean.test.ts +110 -0
- package/src/remote.test.ts +172 -0
- package/src/remote.ts +17 -7
- package/src/schema.test.ts +103 -0
- package/src/schema.ts +35 -18
- package/src/scopes.ts +7 -48
- package/src/services/ai-agent-runner-service.ts +20 -0
- package/src/services/ai-embedding-service.ts +3 -25
- package/src/services/audit-service.ts +1 -2
- package/src/services/content-service.ts +1 -46
- package/src/services/credential-service.ts +3 -40
- package/src/services/credential-wire-service.test.ts +0 -2
- package/src/services/deployment-service.ts +3 -9
- package/src/services/gateway-service.ts +0 -15
- package/src/services/{http-scenario-actors-converse.test.ts → http-personas-converse.test.ts} +38 -9
- package/src/services/{http-scenario-actors.test.ts → http-personas.test.ts} +39 -22
- package/src/services/{http-scenario-actors.ts → http-personas.ts} +85 -45
- package/src/services/in-memory-queue-service.ts +1 -15
- package/src/services/in-memory-trigger-service.ts +1 -18
- package/src/services/in-memory-workflow-service.test.ts +0 -13
- package/src/services/in-memory-workflow-service.ts +4 -38
- package/src/services/index.ts +20 -15
- package/src/services/istanbul-coverage-service.ts +2 -8
- package/src/services/jwt-service.ts +1 -16
- package/src/services/local-content.test.ts +159 -27
- package/src/services/local-content.ts +55 -23
- package/src/services/local-gateway-service.ts +2 -17
- package/src/services/local-secrets.ts +0 -4
- package/src/services/logger-console.test.ts +0 -1
- package/src/services/logger-console.ts +3 -7
- package/src/services/logger.ts +2 -37
- package/src/services/meta-service.test.ts +1 -5
- package/src/services/meta-service.ts +41 -61
- package/src/services/{scenario-actors-service.ts → personas-service.ts} +48 -43
- package/src/services/pikku-user-id.ts +0 -4
- package/src/services/queue-webhook-service.ts +9 -41
- package/src/services/scheduler-service.ts +1 -50
- package/src/services/schema-service.ts +1 -24
- package/src/services/scope-service.ts +50 -34
- package/src/services/scoped-secret-service.ts +0 -4
- package/src/services/secret-host-binding.test.ts +138 -0
- package/src/services/secret-host-binding.ts +51 -0
- package/src/services/secret-service.ts +5 -33
- package/src/services/secretless.test.ts +54 -0
- package/src/services/secretless.ts +29 -0
- package/src/services/stub-tracker.ts +8 -18
- package/src/services/system-role-guard.test.ts +93 -0
- package/src/services/system-role-guard.ts +71 -0
- package/src/services/trigger-service.ts +0 -12
- package/src/services/typed-secret-service.ts +1 -7
- package/src/services/v8-coverage-service.ts +3 -6
- package/src/services/variables-service.ts +1 -8
- package/src/services/webhook-service.ts +19 -63
- package/src/services/workflow-service.ts +3 -20
- package/src/testing/service-tests.ts +0 -26
- package/src/time-utils.ts +1 -19
- package/src/types/core.types.ts +116 -229
- package/src/types/state.types.ts +7 -9
- package/src/utils/hmac.ts +4 -10
- package/src/utils/safe-fetch.ts +13 -54
- package/src/utils.test.ts +11 -2
- package/src/utils.ts +6 -15
- package/src/wirings/actor-flow/actor-flow.types.ts +1 -34
- package/src/wirings/actor-flow/index.ts +0 -9
- package/src/wirings/actor-flow/run-conversation.test.ts +11 -6
- package/src/wirings/actor-flow/run-conversation.ts +19 -12
- package/src/wirings/ai-agent/ai-agent-agui.test.ts +75 -10
- package/src/wirings/ai-agent/ai-agent-agui.ts +36 -17
- package/src/wirings/ai-agent/ai-agent-helpers.ts +20 -0
- package/src/wirings/ai-agent/ai-agent-interrupt.test.ts +842 -0
- package/src/wirings/ai-agent/ai-agent-interrupt.ts +399 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +0 -2
- package/src/wirings/ai-agent/ai-agent-model-config.ts +1 -9
- package/src/wirings/ai-agent/ai-agent-prepare.test.ts +202 -31
- package/src/wirings/ai-agent/ai-agent-prepare.ts +82 -138
- package/src/wirings/ai-agent/ai-agent-registry.test.ts +191 -6
- package/src/wirings/ai-agent/ai-agent-registry.ts +18 -1
- package/src/wirings/ai-agent/ai-agent-resume-authorization.test.ts +0 -2
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +11 -9
- package/src/wirings/ai-agent/ai-agent-runner.ts +67 -33
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +205 -103
- package/src/wirings/ai-agent/ai-agent-stream.ts +192 -75
- package/src/wirings/ai-agent/ai-agent-thread-ownership.test.ts +301 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +85 -4
- package/src/wirings/ai-agent/index.ts +35 -3
- package/src/wirings/ai-agent/voice-input.test.ts +72 -7
- package/src/wirings/ai-agent/voice-input.ts +48 -3
- package/src/wirings/ai-agent/voice-output.test.ts +422 -0
- package/src/wirings/ai-agent/voice-output.ts +216 -56
- package/src/wirings/channel/channel-common.ts +15 -20
- package/src/wirings/channel/channel-handler.test.ts +50 -0
- package/src/wirings/channel/channel-handler.ts +32 -11
- package/src/wirings/channel/channel-host-rpc.test.ts +150 -0
- package/src/wirings/channel/channel-host-rpc.ts +69 -0
- package/src/wirings/channel/channel-middleware-runner.test.ts +0 -1
- package/src/wirings/channel/channel-middleware-runner.ts +0 -12
- package/src/wirings/channel/channel-rpc-registry.ts +116 -0
- package/src/wirings/channel/channel-rpc-responder.ts +117 -0
- package/src/wirings/channel/channel-rpc-service.ts +146 -0
- package/src/wirings/channel/channel-rpc-validators.ts +65 -0
- package/src/wirings/channel/channel-rpc.test.ts +820 -0
- package/src/wirings/channel/channel-rpc.ts +5 -0
- package/src/wirings/channel/channel-rpc.types.ts +150 -0
- package/src/wirings/channel/channel-runner.ts +0 -14
- package/src/wirings/channel/channel-store.ts +0 -10
- package/src/wirings/channel/channel.types.ts +19 -8
- package/src/wirings/channel/define-channel-routes.ts +0 -20
- package/src/wirings/channel/eventhub-service.ts +0 -18
- package/src/wirings/channel/index.ts +35 -0
- package/src/wirings/channel/local/local-channel-handler.ts +3 -1
- package/src/wirings/channel/local/local-channel-runner.test.ts +0 -10
- package/src/wirings/channel/local/local-channel-runner.ts +3 -1
- package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -13
- package/src/wirings/channel/local/local-eventhub-service.ts +2 -37
- package/src/wirings/channel/log-channels.ts +0 -4
- package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +83 -2
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +7 -0
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +2 -5
- package/src/wirings/cli/channel/cli-approval.test.ts +177 -0
- package/src/wirings/cli/channel/cli-approval.ts +135 -0
- package/src/wirings/cli/channel/cli-channel-runner.ts +4 -26
- package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +169 -0
- package/src/wirings/cli/channel/cli-raw-channel-runner.ts +59 -16
- package/src/wirings/cli/channel/cli-raw-client-runner.test.ts +480 -0
- package/src/wirings/cli/channel/cli-raw-client-runner.ts +155 -0
- package/src/wirings/cli/channel/index.ts +9 -0
- package/src/wirings/cli/cli-runner.test.ts +0 -1
- package/src/wirings/cli/cli-runner.ts +46 -88
- package/src/wirings/cli/cli.types.ts +14 -3
- package/src/wirings/cli/command-parser.test.ts +0 -4
- package/src/wirings/cli/command-parser.ts +11 -91
- package/src/wirings/cli/define-cli-commands.ts +1 -17
- package/src/wirings/credential/credential.types.ts +0 -12
- package/src/wirings/credential/{wire-credential.ts → define-credential.ts} +7 -7
- package/src/wirings/credential/index.ts +1 -1
- package/src/wirings/credential/validate-credential-definitions.ts +2 -4
- package/src/wirings/gateway/gateway-runner.test.ts +1 -21
- package/src/wirings/gateway/gateway-runner.ts +8 -110
- package/src/wirings/gateway/gateway.types.ts +7 -80
- package/src/wirings/http/http-routes.test.ts +0 -3
- package/src/wirings/http/http-routes.ts +0 -86
- package/src/wirings/http/http-runner.test.ts +0 -1
- package/src/wirings/http/http-runner.ts +12 -168
- package/src/wirings/http/http.types.ts +17 -62
- package/src/wirings/http/index.ts +5 -1
- package/src/wirings/http/log-http-routes.ts +0 -4
- package/src/wirings/http/pikku-fetch-http-request.test.ts +88 -7
- package/src/wirings/http/pikku-fetch-http-request.ts +74 -50
- package/src/wirings/http/pikku-fetch-http-response.test.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-response.ts +0 -3
- package/src/wirings/http/routers/path-to-regex.test.ts +4 -17
- package/src/wirings/http/routers/path-to-regex.ts +2 -13
- package/src/wirings/http/web-request.test.ts +33 -2
- package/src/wirings/http/web-request.ts +30 -17
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -1
- package/src/wirings/mcp/mcp-runner.test.ts +40 -0
- package/src/wirings/mcp/mcp-runner.ts +9 -15
- package/src/wirings/mcp/mcp.types.ts +7 -42
- package/src/wirings/oauth2/oauth2.types.ts +0 -30
- package/src/wirings/persona/define-personas.ts +29 -0
- package/src/wirings/persona/index.ts +62 -0
- package/src/wirings/persona/persona-email.ts +87 -0
- package/src/wirings/persona/persona-environments.test.ts +183 -0
- package/src/wirings/persona/persona-environments.ts +138 -0
- package/src/wirings/persona/persona-mailbox.ts +156 -0
- package/src/wirings/persona/persona.test.ts +220 -0
- package/src/wirings/persona/persona.types.ts +131 -0
- package/src/wirings/persona/validate-personas.ts +133 -0
- package/src/wirings/queue/index.ts +13 -3
- package/src/wirings/queue/queue-identity.test.ts +453 -0
- package/src/wirings/queue/queue-identity.ts +173 -0
- package/src/wirings/queue/queue-runner.ts +12 -31
- package/src/wirings/queue/queue.types.ts +19 -89
- package/src/wirings/queue/register-queue-helper.ts +0 -14
- package/src/wirings/queue/signed-queue-service.ts +59 -0
- package/src/wirings/queue/validate-worker-config.ts +2 -28
- package/src/wirings/role/define-system-role.ts +33 -0
- package/src/wirings/role/index.ts +13 -0
- package/src/wirings/role/role.test.ts +104 -0
- package/src/wirings/role/role.types.ts +47 -0
- package/src/wirings/role/validate-role-definitions.ts +93 -0
- package/src/wirings/rpc/addon-auth-tags.test.ts +223 -0
- package/src/wirings/rpc/addon-runner.ts +0 -56
- package/src/wirings/rpc/addon-scopes.test.ts +225 -0
- package/src/wirings/rpc/remote-addon-auth.ts +1 -13
- package/src/wirings/rpc/rpc-runner.test.ts +186 -2
- package/src/wirings/rpc/rpc-runner.ts +145 -127
- package/src/wirings/rpc/rpc-types.ts +11 -6
- package/src/wirings/rpc/wire-addon.test.ts +43 -1
- package/src/wirings/rpc/wire-addon.ts +99 -0
- package/src/wirings/rpc/wire-remote-addon.ts +9 -29
- package/src/wirings/scheduler/log-schedulers.ts +0 -4
- package/src/wirings/scheduler/scheduler-runner.test.ts +1 -8
- package/src/wirings/scheduler/scheduler-runner.ts +0 -2
- package/src/wirings/scheduler/scheduler.types.ts +1 -14
- package/src/wirings/scope/{wire-scope.ts → define-scope.ts} +5 -6
- package/src/wirings/scope/index.ts +1 -1
- package/src/wirings/scope/scope.test.ts +1 -2
- package/src/wirings/scope/scope.types.ts +7 -9
- package/src/wirings/scope/validate-scope-definitions.ts +3 -21
- package/src/wirings/secret/index.ts +1 -1
- package/src/wirings/secret/secret.types.ts +19 -15
- package/src/wirings/secret/validate-secret-definitions.ts +2 -4
- package/src/wirings/trigger/trigger-runner.ts +1 -27
- package/src/wirings/trigger/trigger.types.ts +1 -82
- package/src/wirings/variable/index.ts +1 -1
- package/src/wirings/variable/validate-variable-definitions.ts +2 -4
- package/src/wirings/variable/variable.types.ts +1 -13
- package/src/wirings/virtual-user/index.ts +76 -0
- package/src/wirings/virtual-user/run-virtual-user.test.ts +765 -0
- package/src/wirings/virtual-user/run-virtual-user.ts +671 -0
- package/src/wirings/virtual-user/virtual-user-agents.test.ts +65 -0
- package/src/wirings/virtual-user/virtual-user-agents.ts +57 -0
- package/src/wirings/virtual-user/virtual-user-catalogue.test.ts +215 -0
- package/src/wirings/virtual-user/virtual-user-catalogue.ts +184 -0
- package/src/wirings/virtual-user/virtual-user-derive.test.ts +398 -0
- package/src/wirings/virtual-user/virtual-user-derive.ts +173 -0
- package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +63 -0
- package/src/wirings/virtual-user/virtual-user-dispositions.ts +213 -0
- package/src/wirings/virtual-user/virtual-user-intents.test.ts +208 -0
- package/src/wirings/virtual-user/virtual-user-intents.ts +185 -0
- package/src/wirings/virtual-user/virtual-user-rng.test.ts +72 -0
- package/src/wirings/virtual-user/virtual-user-rng.ts +50 -0
- package/src/wirings/virtual-user/virtual-user-target.ts +47 -0
- package/src/wirings/virtual-user/virtual-user.types.ts +219 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +5 -4
- package/src/wirings/workflow/dsl/workflow-runner.ts +0 -4
- package/src/wirings/workflow/feature.ts +0 -19
- package/src/wirings/workflow/graph/graph-node.ts +0 -136
- package/src/wirings/workflow/graph/graph-runner.test.ts +20 -19
- package/src/wirings/workflow/graph/graph-runner.ts +6 -41
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -4
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -58
- package/src/wirings/workflow/index.ts +10 -44
- package/src/wirings/workflow/pikku-scenario-service.ts +235 -52
- package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -39
- package/src/wirings/workflow/pikku-workflow-service.ts +77 -674
- package/src/wirings/workflow/run-timeline.test.ts +7 -19
- package/src/wirings/workflow/run-timeline.ts +0 -56
- package/src/wirings/workflow/scenario-cookie-jar.test.ts +0 -1
- package/src/wirings/workflow/scenario-cookie-jar.ts +0 -25
- package/src/wirings/workflow/scenario-expectations.test.ts +2 -7
- package/src/wirings/workflow/scenario-hooks.test.ts +2 -7
- package/src/wirings/workflow/scenario-poll.test.ts +0 -2
- package/src/wirings/workflow/scenario-poll.ts +0 -15
- package/src/wirings/workflow/scenario-prose.ts +0 -28
- package/src/wirings/workflow/scenario-service.test.ts +2 -9
- package/src/wirings/workflow/scenario-step-guards.ts +1 -14
- package/src/wirings/workflow/scenario-step.test.ts +159 -14
- package/src/wirings/workflow/scenario-step.types.ts +82 -6
- package/src/wirings/workflow/scenario-surface.test.ts +145 -0
- package/src/wirings/workflow/scenario-surface.ts +71 -0
- package/src/wirings/workflow/workflow-dispatch-durability.test.ts +14 -15
- package/src/wirings/workflow/workflow-dispatch-payload.test.ts +0 -4
- package/src/wirings/workflow/workflow-inline-authority.test.ts +169 -0
- package/src/wirings/workflow/workflow-invocation-id.test.ts +0 -2
- package/src/wirings/workflow/workflow-invocation-id.ts +2 -22
- package/src/wirings/workflow/workflow-mirror.test.ts +0 -7
- package/src/wirings/workflow/workflow-on-error.test.ts +0 -9
- package/src/wirings/workflow/workflow-queue-workers.ts +0 -21
- package/src/wirings/workflow/workflow-replay-snapshot.test.ts +8 -7
- package/src/wirings/workflow/workflow-retry-policy.test.ts +0 -5
- package/src/wirings/workflow/workflow-run-context.test.ts +5 -10
- package/src/wirings/workflow/workflow-run-polling.test.ts +0 -5
- package/src/wirings/workflow/workflow-step-ordinal.test.ts +19 -4
- package/src/wirings/workflow/workflow-step-session.test.ts +0 -7
- package/src/wirings/workflow/workflow.types.ts +0 -203
- package/tsconfig.tsbuildinfo +1 -1
- package/src/middleware/timeout.ts +0 -22
- package/src/pikku-response.ts +0 -5
- package/src/services/gopass-secrets.ts +0 -78
- package/src/wirings/mcp/mcp-endpoint-registry.test.d.ts +0 -1
- package/src/wirings/workflow/dsl/index.ts +0 -36
- package/src/wirings/workflow/graph/index.ts +0 -15
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drain a response into the shape a step can carry: the parsed body (an empty
|
|
3
|
+
* one counting as no body at all) alongside the text it was parsed from.
|
|
4
|
+
*
|
|
5
|
+
* `invokeRaw` returns this, and a step that has to reach past a persona — a
|
|
6
|
+
* route with no RPC, an identity no persona can hold — reaches for this rather
|
|
7
|
+
* than writing the same record by hand.
|
|
8
|
+
*/
|
|
9
|
+
export const readScenarioHttpResponse = async (res) => {
|
|
10
|
+
const text = res.status === 204 ? '' : await res.text().catch(() => '');
|
|
11
|
+
return {
|
|
12
|
+
status: res.status,
|
|
13
|
+
ok: res.ok,
|
|
14
|
+
body: (text ? parseJsonBody(text) : undefined),
|
|
15
|
+
serialized: text,
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
const parseJsonBody = (text) => {
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(text);
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return text;
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* POST JSON somewhere and report what came back, without throwing on a 4xx/5xx.
|
|
28
|
+
*
|
|
29
|
+
* Every scenario that reaches past a persona was writing this by hand — the same
|
|
30
|
+
* `content-type`, the same `JSON.stringify`, the same drain — and the copies had
|
|
31
|
+
* drifted: some returned `res.json()`, which loses the status and throws
|
|
32
|
+
* outright when the target answers an empty body or an HTML error page. A
|
|
33
|
+
* refusal is the expected outcome of a permissions scenario, so it has to
|
|
34
|
+
* survive as data.
|
|
35
|
+
*/
|
|
36
|
+
export const postScenarioJson = async (url, { body, headers, method = 'POST', fetch: send = fetch, } = {}) => readScenarioHttpResponse(await send(url, {
|
|
37
|
+
method,
|
|
38
|
+
headers: { 'content-type': 'application/json', ...headers },
|
|
39
|
+
...(body === undefined ? {} : { body: JSON.stringify(body) }),
|
|
40
|
+
}));
|
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
export const defaultPikkuUserIdResolver = (wire) => {
|
|
2
|
-
// Explicit pikkuUserId on wire (set by earlier middleware or runner)
|
|
3
2
|
if (wire.pikkuUserId)
|
|
4
3
|
return wire.pikkuUserId;
|
|
5
|
-
// Session userId (from auth middleware — user-defined session shape)
|
|
6
4
|
const session = wire.session;
|
|
7
5
|
if (session?.userId && typeof session.userId === 'string')
|
|
8
6
|
return session.userId;
|
|
9
|
-
// Queue job: carried in job metadata
|
|
10
7
|
if (wire.queue?.pikkuUserId)
|
|
11
8
|
return wire.queue.pikkuUserId;
|
|
12
|
-
// Workflow: carried in run wire metadata
|
|
13
9
|
if (wire.workflow?.pikkuUserId)
|
|
14
10
|
return wire.workflow.pikkuUserId;
|
|
15
11
|
return undefined;
|
|
@@ -1,54 +1,20 @@
|
|
|
1
1
|
import type { JobOptions, QueueService } from '../wirings/queue/queue.types.js';
|
|
2
2
|
import type { Logger } from './logger.js';
|
|
3
3
|
import { type SendWebhookInput, type SendWebhookResult, type WebhookJobData, WebhookService } from './webhook-service.js';
|
|
4
|
-
/**
|
|
5
|
-
* Default {@link WebhookService} implementation: serializes and signs the
|
|
6
|
-
* payload, then enqueues a delivery job onto the `pikku-outgoing-webhooks`
|
|
7
|
-
* queue. The signature is computed at enqueue time so the signing key never
|
|
8
|
-
* enters the queue payload; the actual HTTP POST happens in
|
|
9
|
-
* {@link pikkuWebhookWorkerFunc}, and the queue's `attempts`/`backoff`
|
|
10
|
-
* options drive retries.
|
|
11
|
-
*/
|
|
12
4
|
export declare class QueueWebhookService extends WebhookService {
|
|
13
5
|
protected queueService: QueueService;
|
|
14
|
-
/**
|
|
15
|
-
* The queue is a constructor dependency rather than a `getSingletonServices()`
|
|
16
|
-
* lookup so that a project wiring up outgoing webhooks without a queue fails
|
|
17
|
-
* to compile, instead of throwing on the first `send()`.
|
|
18
|
-
*/
|
|
19
6
|
constructor(queueService: QueueService);
|
|
20
7
|
send(input: SendWebhookInput): Promise<SendWebhookResult>;
|
|
21
8
|
/**
|
|
22
|
-
*
|
|
23
|
-
* `
|
|
24
|
-
* store-backed subclass can persist a delivery row and attach its
|
|
25
|
-
* `deliveryId` without re-implementing signing or the retry policy.
|
|
9
|
+
* `protected` so a store-backed subclass can persist a delivery row and attach
|
|
10
|
+
* its `deliveryId` without re-implementing signing or the retry policy.
|
|
26
11
|
*/
|
|
27
12
|
protected prepareDelivery(input: SendWebhookInput): Promise<{
|
|
28
13
|
jobData: WebhookJobData;
|
|
29
14
|
options: JobOptions;
|
|
30
15
|
}>;
|
|
31
|
-
/**
|
|
32
|
-
* Resolve a delivery's retry policy into queue job options, mirroring the
|
|
33
|
-
* workflow service: per-call values win over `config.webhook` defaults, an
|
|
34
|
-
* explicitly-set `retries` (including 0) is always honored, and `attempts`
|
|
35
|
-
* is ALWAYS passed so the queue can never fall back to its own default.
|
|
36
|
-
* Backoff is exponential unless a concrete `retryDelay` selects a fixed one.
|
|
37
|
-
*/
|
|
38
16
|
private resolveJobOptions;
|
|
39
17
|
}
|
|
40
|
-
/**
|
|
41
|
-
* Queue worker for the `pikku-outgoing-webhooks` queue: POSTs the delivery to its
|
|
42
|
-
* target URL. Any non-2xx response (or network error) throws so the queue
|
|
43
|
-
* retries the job according to the `attempts`/`backoff` set at enqueue time;
|
|
44
|
-
* the queue runner logs each failed attempt.
|
|
45
|
-
*
|
|
46
|
-
* A `deliveryId` is only present when a store-backed `webhookService` (e.g.
|
|
47
|
-
* `KyselyWebhookService`) enqueued the job, so each attempt (success or failure)
|
|
48
|
-
* is persisted via `webhookService.recordAttempt` before the throw — the console
|
|
49
|
-
* delivery history reflects every try, not just the outcome. The queue-only
|
|
50
|
-
* default never sets a `deliveryId`, so its base `recordAttempt` is never hit.
|
|
51
|
-
*/
|
|
52
18
|
export declare function pikkuWebhookWorkerFunc(services: {
|
|
53
19
|
logger: Logger;
|
|
54
20
|
webhookService?: WebhookService;
|
|
@@ -2,23 +2,11 @@ import { getSingletonServices } from '../pikku-state.js';
|
|
|
2
2
|
import { getDurationInMilliseconds } from '../time-utils.js';
|
|
3
3
|
import { safeFetch } from '../utils/safe-fetch.js';
|
|
4
4
|
import { DEFAULT_WEBHOOK_RETRIES, DEFAULT_WEBHOOK_SIGNATURE_HEADER, PIKKU_OUTGOING_WEBHOOK_QUEUE_NAME, WebhookService, } from './webhook-service.js';
|
|
5
|
-
/** Cap on the response body captured on a failed attempt. */
|
|
6
5
|
const MAX_CAPTURED_RESPONSE_BODY = 2_000;
|
|
7
|
-
|
|
8
|
-
* Default {@link WebhookService} implementation: serializes and signs the
|
|
9
|
-
* payload, then enqueues a delivery job onto the `pikku-outgoing-webhooks`
|
|
10
|
-
* queue. The signature is computed at enqueue time so the signing key never
|
|
11
|
-
* enters the queue payload; the actual HTTP POST happens in
|
|
12
|
-
* {@link pikkuWebhookWorkerFunc}, and the queue's `attempts`/`backoff`
|
|
13
|
-
* options drive retries.
|
|
14
|
-
*/
|
|
6
|
+
// knowledge: decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md
|
|
15
7
|
export class QueueWebhookService extends WebhookService {
|
|
16
8
|
queueService;
|
|
17
|
-
|
|
18
|
-
* The queue is a constructor dependency rather than a `getSingletonServices()`
|
|
19
|
-
* lookup so that a project wiring up outgoing webhooks without a queue fails
|
|
20
|
-
* to compile, instead of throwing on the first `send()`.
|
|
21
|
-
*/
|
|
9
|
+
// knowledge: decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md
|
|
22
10
|
constructor(queueService) {
|
|
23
11
|
super();
|
|
24
12
|
this.queueService = queueService;
|
|
@@ -29,10 +17,8 @@ export class QueueWebhookService extends WebhookService {
|
|
|
29
17
|
return { jobId };
|
|
30
18
|
}
|
|
31
19
|
/**
|
|
32
|
-
*
|
|
33
|
-
* `
|
|
34
|
-
* store-backed subclass can persist a delivery row and attach its
|
|
35
|
-
* `deliveryId` without re-implementing signing or the retry policy.
|
|
20
|
+
* `protected` so a store-backed subclass can persist a delivery row and attach
|
|
21
|
+
* its `deliveryId` without re-implementing signing or the retry policy.
|
|
36
22
|
*/
|
|
37
23
|
async prepareDelivery(input) {
|
|
38
24
|
const services = getSingletonServices();
|
|
@@ -45,7 +31,7 @@ export class QueueWebhookService extends WebhookService {
|
|
|
45
31
|
};
|
|
46
32
|
let secret = input.secret;
|
|
47
33
|
if (secret === undefined && webhookConfig?.secret) {
|
|
48
|
-
// Naive read
|
|
34
|
+
// Naive read: caching is the secret service's concern, not ours.
|
|
49
35
|
secret = await services.secrets.getSecret(webhookConfig.secret);
|
|
50
36
|
if (!secret) {
|
|
51
37
|
services.logger.error(`Webhook signing secret '${webhookConfig.secret}' (config.webhook.secret) resolved to nothing — outgoing webhooks will be sent UNSIGNED.`);
|
|
@@ -63,13 +49,7 @@ export class QueueWebhookService extends WebhookService {
|
|
|
63
49
|
};
|
|
64
50
|
return { jobData, options: this.resolveJobOptions(input) };
|
|
65
51
|
}
|
|
66
|
-
|
|
67
|
-
* Resolve a delivery's retry policy into queue job options, mirroring the
|
|
68
|
-
* workflow service: per-call values win over `config.webhook` defaults, an
|
|
69
|
-
* explicitly-set `retries` (including 0) is always honored, and `attempts`
|
|
70
|
-
* is ALWAYS passed so the queue can never fall back to its own default.
|
|
71
|
-
* Backoff is exponential unless a concrete `retryDelay` selects a fixed one.
|
|
72
|
-
*/
|
|
52
|
+
// knowledge: decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md
|
|
73
53
|
resolveJobOptions(input) {
|
|
74
54
|
const webhookConfig = getSingletonServices().config?.webhook;
|
|
75
55
|
const retries = input.retries ?? webhookConfig?.retries ?? DEFAULT_WEBHOOK_RETRIES;
|
|
@@ -82,18 +62,7 @@ export class QueueWebhookService extends WebhookService {
|
|
|
82
62
|
return { attempts: retries + 1, ...(backoff ? { backoff } : {}) };
|
|
83
63
|
}
|
|
84
64
|
}
|
|
85
|
-
|
|
86
|
-
* Queue worker for the `pikku-outgoing-webhooks` queue: POSTs the delivery to its
|
|
87
|
-
* target URL. Any non-2xx response (or network error) throws so the queue
|
|
88
|
-
* retries the job according to the `attempts`/`backoff` set at enqueue time;
|
|
89
|
-
* the queue runner logs each failed attempt.
|
|
90
|
-
*
|
|
91
|
-
* A `deliveryId` is only present when a store-backed `webhookService` (e.g.
|
|
92
|
-
* `KyselyWebhookService`) enqueued the job, so each attempt (success or failure)
|
|
93
|
-
* is persisted via `webhookService.recordAttempt` before the throw — the console
|
|
94
|
-
* delivery history reflects every try, not just the outcome. The queue-only
|
|
95
|
-
* default never sets a `deliveryId`, so its base `recordAttempt` is never hit.
|
|
96
|
-
*/
|
|
65
|
+
// knowledge: decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md
|
|
97
66
|
export async function pikkuWebhookWorkerFunc(services, { url, body, headers, deliveryId }) {
|
|
98
67
|
let statusCode;
|
|
99
68
|
let responseBody;
|
|
@@ -104,8 +73,8 @@ export async function pikkuWebhookWorkerFunc(services, { url, body, headers, del
|
|
|
104
73
|
allowedHosts = getSingletonServices().config?.webhook?.allowedHosts;
|
|
105
74
|
}
|
|
106
75
|
catch {
|
|
107
|
-
//
|
|
108
|
-
//
|
|
76
|
+
// Uninitialised singletons (a bare worker invocation): fall back to the
|
|
77
|
+
// default private-host block rather than failing the delivery.
|
|
109
78
|
}
|
|
110
79
|
try {
|
|
111
80
|
const response = await safeFetch(url, {
|
|
@@ -125,7 +94,6 @@ export async function pikkuWebhookWorkerFunc(services, { url, body, headers, del
|
|
|
125
94
|
error = e instanceof Error ? e.message : String(e);
|
|
126
95
|
}
|
|
127
96
|
if (deliveryId && services.webhookService) {
|
|
128
|
-
// Best-effort history: a store failure must not mask the delivery result.
|
|
129
97
|
await services.webhookService
|
|
130
98
|
.recordAttempt(deliveryId, { statusCode, responseBody, error, delivered })
|
|
131
99
|
.catch((storeError) => services.logger.error(`Failed to record webhook delivery attempt for ${deliveryId}`, storeError));
|
|
@@ -1,71 +1,22 @@
|
|
|
1
1
|
import type { CoreUserSession } from '../types/core.types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Minimal metadata for listing scheduled tasks
|
|
4
|
-
*/
|
|
5
2
|
export interface ScheduledTaskSummary {
|
|
6
|
-
/** Unique task ID */
|
|
7
3
|
taskId: string;
|
|
8
|
-
/** RPC function name to invoke */
|
|
9
4
|
rpcName: string;
|
|
10
|
-
/** Scheduled execution time */
|
|
11
5
|
scheduledFor: Date;
|
|
12
6
|
}
|
|
13
|
-
/**
|
|
14
|
-
* Full metadata for a scheduled task retrieved from the queue
|
|
15
|
-
*/
|
|
16
7
|
export interface ScheduledTaskInfo extends ScheduledTaskSummary {
|
|
17
|
-
/** Data to pass to the RPC function */
|
|
18
8
|
data?: any;
|
|
19
|
-
/** User session */
|
|
20
9
|
session?: CoreUserSession;
|
|
21
|
-
/** Task status */
|
|
22
10
|
status?: 'scheduled' | 'active' | 'completed' | 'failed';
|
|
23
11
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Abstract scheduler service for persistent scheduled task management
|
|
26
|
-
* Implementations use queue backends (pg-boss, BullMQ) for distributed scheduling
|
|
27
|
-
*/
|
|
28
12
|
export declare abstract class SchedulerService {
|
|
29
|
-
/**
|
|
30
|
-
* Initialize the scheduler service
|
|
31
|
-
*/
|
|
32
13
|
abstract init(): Promise<void>;
|
|
33
|
-
/**
|
|
34
|
-
* Schedule a one-off delayed RPC call
|
|
35
|
-
* @param delay - Delay before execution (number in milliseconds or duration string like "5h", "30m")
|
|
36
|
-
* @param rpcName - RPC function name to invoke
|
|
37
|
-
* @param data - Data to pass to the RPC function
|
|
38
|
-
* @param session - Optional user session
|
|
39
|
-
* @returns Task ID
|
|
40
|
-
*/
|
|
14
|
+
/** `delay` is milliseconds as a number, or a duration string such as `"5h"` / `"30m"`. */
|
|
41
15
|
abstract scheduleRPC(delay: number | string, rpcName: string, data?: any, session?: CoreUserSession): Promise<string>;
|
|
42
|
-
/**
|
|
43
|
-
* Unschedule a task by ID
|
|
44
|
-
* @param taskId - Task ID
|
|
45
|
-
* @returns Success status
|
|
46
|
-
*/
|
|
47
16
|
abstract unschedule(taskId: string): Promise<boolean>;
|
|
48
|
-
/**
|
|
49
|
-
* Get a scheduled task by ID with full details
|
|
50
|
-
* @param taskId - Task ID
|
|
51
|
-
* @returns Task info or null if not found
|
|
52
|
-
*/
|
|
53
17
|
abstract getTask(taskId: string): Promise<ScheduledTaskInfo | null>;
|
|
54
|
-
/**
|
|
55
|
-
* Get all scheduled tasks with minimal info
|
|
56
|
-
* @returns Array of task summaries with taskId, rpcName, and schedule
|
|
57
|
-
*/
|
|
58
18
|
abstract getAllTasks(): Promise<ScheduledTaskSummary[]>;
|
|
59
|
-
/**
|
|
60
|
-
* Close any open connections
|
|
61
|
-
*/
|
|
62
19
|
abstract close(): Promise<void>;
|
|
63
|
-
/**
|
|
64
|
-
* Start recurring scheduled tasks
|
|
65
|
-
*/
|
|
66
20
|
start(): Promise<void>;
|
|
67
|
-
/**
|
|
68
|
-
* Stop recurring scheduled tasks
|
|
69
|
-
*/
|
|
70
21
|
stop(): Promise<void>;
|
|
71
22
|
}
|
|
@@ -1,14 +1,4 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Abstract scheduler service for persistent scheduled task management
|
|
3
|
-
* Implementations use queue backends (pg-boss, BullMQ) for distributed scheduling
|
|
4
|
-
*/
|
|
5
1
|
export class SchedulerService {
|
|
6
|
-
/**
|
|
7
|
-
* Start recurring scheduled tasks
|
|
8
|
-
*/
|
|
9
2
|
async start() { }
|
|
10
|
-
/**
|
|
11
|
-
* Stop recurring scheduled tasks
|
|
12
|
-
*/
|
|
13
3
|
async stop() { }
|
|
14
4
|
}
|
|
@@ -1,30 +1,7 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Interface for a schema service that handles schema compilation, validation, and management.
|
|
3
|
-
*/
|
|
4
1
|
export interface SchemaService {
|
|
5
|
-
/**
|
|
6
|
-
* Compiles a schema with the provided name and value, making it available for use.
|
|
7
|
-
* @param {string} name - The unique name for the schema.
|
|
8
|
-
* @param {any} value - The schema definition or configuration to be compiled.
|
|
9
|
-
* @returns {Promise<void> | void} A promise if asynchronous, or void if synchronous.
|
|
10
|
-
*/
|
|
11
2
|
compileSchema: (name: string, value: any) => Promise<void> | void;
|
|
12
|
-
/**
|
|
13
|
-
* Validates data against a specified schema.
|
|
14
|
-
* @param {string} schema - The name of the schema to validate against.
|
|
15
|
-
* @param {any} data - The data to validate against the schema.
|
|
16
|
-
* @returns {Promise<void> | void} A promise if asynchronous, or void if synchronous.
|
|
17
|
-
*/
|
|
18
3
|
validateSchema: (schema: string, data: any) => Promise<void> | void;
|
|
19
|
-
/**
|
|
20
|
-
* Retrieves a set of all registered schema names.
|
|
21
|
-
* @returns {Set<string>} A set containing the names of all available schemas.
|
|
22
|
-
*/
|
|
23
4
|
getSchemaNames: () => Set<string>;
|
|
24
|
-
/**
|
|
25
|
-
* Retrieves the property keys from a compiled JSON schema.
|
|
26
|
-
* @param {string} schemaName - The name of the schema.
|
|
27
|
-
* @returns {string[]} An array of property keys, or empty array if schema not found.
|
|
28
|
-
*/
|
|
5
|
+
/** Empty when the schema is not registered. */
|
|
29
6
|
getSchemaKeys: (schemaName: string) => string[];
|
|
30
7
|
}
|
|
@@ -1,67 +1,82 @@
|
|
|
1
1
|
import type { FlatScope } from '../wirings/scope/scope.types.js';
|
|
2
|
-
|
|
2
|
+
import type { SystemRole } from '../wirings/role/role.types.js';
|
|
3
3
|
export interface Role {
|
|
4
4
|
name: string;
|
|
5
5
|
description?: string;
|
|
6
6
|
scopes: string[];
|
|
7
|
-
}
|
|
8
|
-
/**
|
|
9
|
-
* Resolves and administers the scopes granted to a user.
|
|
10
|
-
*
|
|
11
|
-
* Implementations are called at the **session boundary** — e.g. better-auth's
|
|
12
|
-
* `mapSession` — never by the function runner. The runner reads
|
|
13
|
-
* `session.scopes` and never performs I/O, which keeps it viable on Workers
|
|
14
|
-
* and Lambda. Because the session is rebuilt per request, a scope change takes
|
|
15
|
-
* effect on the next call with nothing cached and nothing to invalidate.
|
|
16
|
-
*
|
|
17
|
-
* `syncScopes` is deliberately additive: scopes are declared in code, so a
|
|
18
|
-
* removed declaration leaves an inert row rather than silently revoking a
|
|
19
|
-
* grant mid-deploy. Removal is an explicit operation (`pikku scopes prune`).
|
|
20
|
-
*/
|
|
21
|
-
export interface ScopeService {
|
|
22
7
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
8
|
+
* True when the role was declared in code with `defineSystemRole` rather
|
|
9
|
+
* than composed by an admin. System roles may be granted, but not renamed,
|
|
10
|
+
* re-scoped or deleted — see {@link ScopeService.syncSystemRoles}.
|
|
25
11
|
*/
|
|
26
|
-
|
|
12
|
+
system?: boolean;
|
|
27
13
|
/**
|
|
28
|
-
*
|
|
29
|
-
*
|
|
14
|
+
* False when a system role's declaration has been removed from code but its
|
|
15
|
+
* row survives: still held by whoever holds it, no longer offered for new
|
|
16
|
+
* grants, awaiting `pikku roles prune`.
|
|
30
17
|
*/
|
|
18
|
+
declared?: boolean;
|
|
19
|
+
}
|
|
20
|
+
export interface ScopeService {
|
|
21
|
+
syncScopes(scopes: FlatScope[]): Promise<void>;
|
|
22
|
+
/** The union of role-derived scopes and scopes granted directly. */
|
|
31
23
|
resolveScopes(userId: string): Promise<string[]>;
|
|
32
24
|
/**
|
|
33
|
-
* The
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
* declared in code — inert (no function can require it) and awaiting
|
|
37
|
-
* `pikku scopes prune`.
|
|
25
|
+
* The whole vocabulary a role can be composed from. `declared: false` marks a
|
|
26
|
+
* scope still in the store but no longer declared in code: inert, since no
|
|
27
|
+
* function can require it, and awaiting `pikku scopes prune`.
|
|
38
28
|
*/
|
|
39
29
|
listScopes(): Promise<Array<FlatScope & {
|
|
40
30
|
declared: boolean;
|
|
41
31
|
}>>;
|
|
32
|
+
/**
|
|
33
|
+
* Registers the roles declared with `defineSystemRole`. Additive on the same
|
|
34
|
+
* terms as {@link syncScopes}: a removed declaration leaves the row in place,
|
|
35
|
+
* marked `declared: false`, rather than revoking everyone's grant on deploy.
|
|
36
|
+
*
|
|
37
|
+
* A role's scope set *is* re-synced, because that is the declaration's whole
|
|
38
|
+
* content — editing `defineSystemRole` is how you change what a system role
|
|
39
|
+
* means, and the deploy is when it takes effect.
|
|
40
|
+
*
|
|
41
|
+
* Called once during startup with the generated role list.
|
|
42
|
+
*/
|
|
43
|
+
syncSystemRoles(roles: SystemRole[]): Promise<void>;
|
|
44
|
+
/**
|
|
45
|
+
* Creates an admin-composed role.
|
|
46
|
+
*
|
|
47
|
+
* Must throw {@link SystemRoleShadowedError} when `role.name` matches a
|
|
48
|
+
* declared system role. Two rows answering to one name make "does this user
|
|
49
|
+
* hold `buyer`?" depend on which the store returns first.
|
|
50
|
+
*/
|
|
42
51
|
createRole(role: Role): Promise<void>;
|
|
52
|
+
/** Must throw {@link SystemRoleImmutableError} for a system role. */
|
|
43
53
|
deleteRole(name: string): Promise<void>;
|
|
54
|
+
/** Must throw {@link SystemRoleImmutableError} for a system role. */
|
|
44
55
|
setRoleScopes(name: string, scopes: string[]): Promise<void>;
|
|
45
56
|
listRoles(): Promise<Role[]>;
|
|
46
57
|
addUserToRole(userId: string, role: string, grantedBy?: string): Promise<void>;
|
|
47
58
|
removeUserFromRole(userId: string, role: string): Promise<void>;
|
|
48
59
|
listUserRoles(userId: string): Promise<string[]>;
|
|
49
|
-
/**
|
|
50
|
-
* Grants a scope directly to a user, outside of any role. Additive: the
|
|
51
|
-
* resolved set is the union of role-derived and directly-granted scopes.
|
|
52
|
-
*/
|
|
60
|
+
/** Grants outside of any role; additive with the user's role-derived scopes. */
|
|
53
61
|
addScopeToUser(userId: string, scope: string, grantedBy?: string): Promise<void>;
|
|
54
62
|
removeScopeFromUser(userId: string, scope: string): Promise<void>;
|
|
55
63
|
/** Only the scopes granted directly, not those inherited from roles. */
|
|
56
64
|
listUserScopes(userId: string): Promise<string[]>;
|
|
57
|
-
/**
|
|
58
|
-
* Scopes present in the store that are no longer declared in code, with the
|
|
59
|
-
* roles that would lose them. Powers `pikku scopes audit`.
|
|
60
|
-
*/
|
|
65
|
+
/** Undeclared scopes with the roles that would lose them; powers `pikku scopes audit`. */
|
|
61
66
|
findStaleScopes(): Promise<Array<{
|
|
62
67
|
scope: string;
|
|
63
68
|
roles: string[];
|
|
64
69
|
}>>;
|
|
65
70
|
/** Removes undeclared scopes, cascading them out of roles. */
|
|
66
71
|
pruneScopes(): Promise<string[]>;
|
|
72
|
+
/**
|
|
73
|
+
* System roles in the store whose declaration has gone, with the number of
|
|
74
|
+
* users still holding each. Powers `pikku roles audit`.
|
|
75
|
+
*/
|
|
76
|
+
findStaleSystemRoles(): Promise<Array<{
|
|
77
|
+
role: string;
|
|
78
|
+
users: number;
|
|
79
|
+
}>>;
|
|
80
|
+
/** Removes undeclared system roles, cascading them out of user grants. */
|
|
81
|
+
pruneSystemRoles(): Promise<string[]>;
|
|
67
82
|
}
|
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
import type { SecretService } from './secret-service.js';
|
|
2
|
-
/**
|
|
3
|
-
* A read-only wrapper around SecretService that restricts access
|
|
4
|
-
* to only a defined set of allowed secret keys.
|
|
5
|
-
*/
|
|
6
2
|
export declare class ScopedSecretService implements SecretService {
|
|
7
3
|
private secrets;
|
|
8
4
|
private allowedKeys;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { SecretDefinitionsMeta } from '../wirings/secret/secret.types.js';
|
|
2
|
+
export declare class SecretHostNotAllowedError extends Error {
|
|
3
|
+
readonly secretId: string;
|
|
4
|
+
readonly host: string;
|
|
5
|
+
constructor(secretId: string, host: string, allowedHosts: string[] | undefined);
|
|
6
|
+
}
|
|
7
|
+
/** Refuses a secret/host pairing the declarations do not permit. */
|
|
8
|
+
export declare const assertSecretAllowedForHost: (secretId: string, url: string | URL, secretDefinitions: SecretDefinitionsMeta | undefined, requireAllowedHosts?: boolean) => void;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export class SecretHostNotAllowedError extends Error {
|
|
2
|
+
secretId;
|
|
3
|
+
host;
|
|
4
|
+
constructor(secretId, host, allowedHosts) {
|
|
5
|
+
super(allowedHosts?.length
|
|
6
|
+
? `Secret '${secretId}' may not be sent to '${host}' — it is declared for ${allowedHosts.map((h) => `'${h}'`).join(', ')}. Add the host to allowedHosts on its defineSecret if this is intended.`
|
|
7
|
+
: `Secret '${secretId}' has no allowedHosts and this project requires one. Declare the hosts it may be sent to on its defineSecret.`);
|
|
8
|
+
this.secretId = secretId;
|
|
9
|
+
this.host = host;
|
|
10
|
+
this.name = 'SecretHostNotAllowedError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
/** Exact match, or a single leading `*.` wildcard anchored on a dot. */
|
|
14
|
+
const hostMatches = (host, pattern) => {
|
|
15
|
+
const h = host.toLowerCase();
|
|
16
|
+
const p = pattern.toLowerCase();
|
|
17
|
+
if (p.startsWith('*.')) {
|
|
18
|
+
return h.endsWith(p.slice(1)) && h.length > p.length - 1;
|
|
19
|
+
}
|
|
20
|
+
return h === p;
|
|
21
|
+
};
|
|
22
|
+
/** Refuses a secret/host pairing the declarations do not permit. */
|
|
23
|
+
export const assertSecretAllowedForHost = (secretId, url, secretDefinitions, requireAllowedHosts = false) => {
|
|
24
|
+
const host = (typeof url === 'string' ? new URL(url) : url).hostname;
|
|
25
|
+
const definition = Object.values(secretDefinitions ?? {}).find((d) => d.secretId === secretId);
|
|
26
|
+
const allowedHosts = definition?.allowedHosts;
|
|
27
|
+
if (!allowedHosts?.length) {
|
|
28
|
+
if (requireAllowedHosts) {
|
|
29
|
+
throw new SecretHostNotAllowedError(secretId, host, allowedHosts);
|
|
30
|
+
}
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
if (!allowedHosts.some((pattern) => hostMatches(host, pattern))) {
|
|
34
|
+
throw new SecretHostNotAllowedError(secretId, host, allowedHosts);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
@@ -1,42 +1,14 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Interface for retrieving and managing secrets.
|
|
3
|
-
*/
|
|
4
1
|
export interface SecretService {
|
|
5
|
-
/**
|
|
6
|
-
* Retrieves a secret by key, typed as T (defaults to string).
|
|
7
|
-
* @param key - The key of the secret to retrieve.
|
|
8
|
-
* @returns A promise that resolves to the secret value.
|
|
9
|
-
* @throws If the secret is not found.
|
|
10
|
-
*/
|
|
2
|
+
/** Throws if the secret is not found. */
|
|
11
3
|
getSecret<T = string>(key: string): Promise<T>;
|
|
12
|
-
/**
|
|
13
|
-
* Checks if a secret exists without throwing.
|
|
14
|
-
* @param key - The key of the secret to check.
|
|
15
|
-
* @returns A promise that resolves to true if the secret exists, false otherwise.
|
|
16
|
-
*/
|
|
4
|
+
/** Answers for any key, including a disallowed one — it must not throw. */
|
|
17
5
|
hasSecret(key: string): Promise<boolean>;
|
|
18
|
-
/**
|
|
19
|
-
* Stores a secret value.
|
|
20
|
-
* @param key - The key to store the secret under.
|
|
21
|
-
* @param value - The value to store.
|
|
22
|
-
* @returns A promise that resolves when the secret is stored.
|
|
23
|
-
*/
|
|
24
6
|
setSecret(key: string, value: unknown): Promise<void>;
|
|
25
|
-
/**
|
|
26
|
-
* Deletes a secret by key.
|
|
27
|
-
* @param key - The key of the secret to delete.
|
|
28
|
-
* @returns A promise that resolves when the secret is deleted.
|
|
29
|
-
*/
|
|
30
7
|
deleteSecret(key: string): Promise<void>;
|
|
31
8
|
/**
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* `Partial<T>` and callers must handle keys that may be absent at runtime.
|
|
36
|
-
*
|
|
37
|
-
* Pass a shape as `T` to get a typed result without casting, e.g.
|
|
38
|
-
* `await secrets.getSecrets<{ FOO: string; BAR: { id: string } }>(['FOO', 'BAR'])`.
|
|
39
|
-
* @param keys - The keys of the secrets to retrieve.
|
|
9
|
+
* Missing keys are omitted rather than throwing, hence `Partial<T>`: callers
|
|
10
|
+
* must handle keys absent at runtime. Pass a shape as `T` to avoid casting,
|
|
11
|
+
* e.g. `getSecrets<{ FOO: string; BAR: { id: string } }>(['FOO', 'BAR'])`.
|
|
40
12
|
*/
|
|
41
13
|
getSecrets<T extends Record<string, unknown> = Record<string, unknown>>(keys: (keyof T & string)[]): Promise<Partial<T>>;
|
|
42
14
|
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { SecretlessServices } from '../types/core.types.js';
|
|
2
|
+
export declare class SecretAccessDeniedError extends Error {
|
|
3
|
+
constructor(context: string);
|
|
4
|
+
}
|
|
5
|
+
/** Returns `services` with `secrets` replaced by a throwing accessor. */
|
|
6
|
+
export declare const withoutSecrets: <T extends object>(services: T, context: string) => SecretlessServices<T>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export class SecretAccessDeniedError extends Error {
|
|
2
|
+
constructor(context) {
|
|
3
|
+
super(`'secrets' is not available inside ${context}. SecretService is confined to pikkuServices, pikkuWireServices, addon service factories and middleware — give a service the secret when you construct it and ask that service here.`);
|
|
4
|
+
this.name = 'SecretAccessDeniedError';
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
/** Returns `services` with `secrets` replaced by a throwing accessor. */
|
|
8
|
+
export const withoutSecrets = (services, context) => {
|
|
9
|
+
if (!('secrets' in services)) {
|
|
10
|
+
return services;
|
|
11
|
+
}
|
|
12
|
+
const stripped = { ...services };
|
|
13
|
+
Object.defineProperty(stripped, 'secrets', {
|
|
14
|
+
get() {
|
|
15
|
+
throw new SecretAccessDeniedError(context);
|
|
16
|
+
},
|
|
17
|
+
configurable: true,
|
|
18
|
+
enumerable: false,
|
|
19
|
+
});
|
|
20
|
+
return stripped;
|
|
21
|
+
};
|
|
@@ -4,10 +4,9 @@ export type StubCall = {
|
|
|
4
4
|
args: unknown[];
|
|
5
5
|
};
|
|
6
6
|
/**
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
* Services never touched by an assertion stay lenient.
|
|
7
|
+
* Strict per service: once a scenario asserts any call on a service, every
|
|
8
|
+
* recorded call on it must be verified by the end of the scenario or the After
|
|
9
|
+
* hook fails. A service no assertion ever touched stays lenient.
|
|
11
10
|
*/
|
|
12
11
|
export declare class StubTracker {
|
|
13
12
|
private readonly calls;
|
|
@@ -21,23 +20,13 @@ export declare class StubTracker {
|
|
|
21
20
|
assertNoCalls(service: string, method?: string, predicate?: (args: unknown[]) => boolean, description?: string): void;
|
|
22
21
|
verify(): void;
|
|
23
22
|
}
|
|
24
|
-
/**
|
|
25
|
-
* Creates a Proxy suitable for passing as `existingServices` to
|
|
26
|
-
* `createSingletonServices`. Every property returns `tracker.stub(prop)`
|
|
27
|
-
* EXCEPT `schema`, which returns `undefined` so the service factory creates
|
|
28
|
-
* a real schema service. Stubbing the schema makes validation a no-op —
|
|
29
|
-
* required fields pass silently and tests validate nothing.
|
|
30
|
-
*/
|
|
23
|
+
/** Pass as `existingServices` to `createSingletonServices`. */
|
|
31
24
|
export declare function createStubProxy(tracker: StubTracker): Record<string, unknown>;
|
|
32
|
-
/** The process-wide tracker
|
|
25
|
+
/** The process-wide tracker `stub()`/`spy()` record into; read by the console's getStubCalls/resetStubs RPCs. */
|
|
33
26
|
export declare const getStubTracker: () => StubTracker;
|
|
34
|
-
/** True when the server was started by `pikku dev --test
|
|
27
|
+
/** True when the server was started by `pikku dev --test`, which sets PIKKU_TEST_RUN. */
|
|
35
28
|
export declare const isTestRun: () => boolean;
|
|
36
|
-
/**
|
|
37
|
-
* Creates a recording fake for a service. Methods present on `impl` run and
|
|
38
|
-
* their result is returned; missing methods resolve `undefined`. Every call
|
|
39
|
-
* is recorded so scenarios can assert via workflow.expectService().
|
|
40
|
-
*/
|
|
29
|
+
/** Methods on `impl` run and return; every other method resolves `undefined`. */
|
|
41
30
|
export declare function stub<T = any>(service: string, impl?: Partial<T>): T;
|
|
42
31
|
/** Wraps a real service so every method call is recorded and passed through */
|
|
43
32
|
export declare function spy<T extends object>(service: string, real: T): T;
|