@pikku/core 0.12.72 → 0.12.77
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 +1171 -0
- package/dist/column-form.d.ts +32 -0
- package/dist/column-form.js +42 -0
- package/dist/crypto-utils.d.ts +43 -7
- package/dist/crypto-utils.js +163 -42
- package/dist/data-classification.d.ts +44 -0
- 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 +57 -136
- package/dist/function/functions.types.js +0 -58
- package/dist/function/index.d.ts +1 -1
- 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 +11 -5
- package/dist/index.js +7 -2
- 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 +5 -41
- 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 +4 -3
- 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 +9 -8
- 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/secret-value.d.ts +56 -0
- package/dist/secret-value.js +46 -0
- 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.d.ts +74 -4
- package/dist/services/audit-service.js +8 -7
- package/dist/services/content-service.d.ts +1 -46
- package/dist/services/credential-service.d.ts +3 -40
- package/dist/services/credential-wire-service.d.ts +5 -0
- package/dist/services/credential-wire-service.js +9 -1
- package/dist/services/deployment-service.d.ts +3 -9
- package/dist/services/email-service.d.ts +2 -1
- 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 +8 -9
- package/dist/services/index.js +3 -6
- 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-request-handler.d.ts +29 -0
- package/dist/services/local-content-request-handler.js +176 -0
- 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 +4 -7
- package/dist/services/local-secrets.js +7 -7
- package/dist/services/logger-console.d.ts +3 -7
- package/dist/services/logger-console.js +3 -7
- package/dist/services/logger.d.ts +22 -40
- 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 +10 -42
- 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 +4 -7
- 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 +12 -35
- 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 +5 -11
- 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 +21 -64
- package/dist/services/webhook-service.js +6 -20
- package/dist/services/workflow-service.d.ts +3 -15
- package/dist/testing/service-tests.js +6 -23
- package/dist/time-utils.d.ts +0 -16
- package/dist/time-utils.js +1 -19
- package/dist/types/core.types.d.ts +120 -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 +46 -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 +65 -132
- 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 +63 -22
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +25 -2
- package/dist/wirings/ai-agent/ai-agent-stream.js +180 -64
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +124 -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 +59 -1
- package/dist/wirings/ai-agent/voice-input.js +90 -12
- package/dist/wirings/ai-agent/voice-output.d.ts +69 -1
- package/dist/wirings/ai-agent/voice-output.js +162 -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 +38 -0
- package/dist/wirings/cli/channel/cli-raw-client-runner.js +129 -0
- package/dist/wirings/cli/channel/index.d.ts +5 -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 +32 -0
- package/dist/wirings/persona/define-personas.js +31 -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 +136 -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 +103 -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 +20 -90
- 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 +17 -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 +3 -13
- package/dist/wirings/rpc/remote-addon-auth.js +7 -11
- 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 +30 -0
- package/dist/wirings/virtual-user/index.js +10 -0
- package/dist/wirings/virtual-user/prepare-virtual-user-run.d.ts +54 -0
- package/dist/wirings/virtual-user/prepare-virtual-user-run.js +49 -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-run-store.d.ts +90 -0
- package/dist/wirings/virtual-user/virtual-user-run-store.js +1 -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 +19 -15
- 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 -43
- 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 +1 -19
- 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 +84 -12
- 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 +5 -195
- 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/a-virtual-user-run-is-not-a-workflow-and-not-a-queued-job.md +48 -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-column-form-is-an-axis-of-its-own.md +84 -0
- package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +41 -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 +117 -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/one-project-shape-check-two-validators.md +53 -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/scenarios-live-in-files-named-for-them.md +48 -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/validate-checks-personas-through-a-shared-module.md +43 -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 +6 -2
- package/run-tests.sh +0 -0
- package/src/column-form.test.ts +97 -0
- package/src/column-form.ts +58 -0
- package/src/crypto-utils.test.ts +460 -19
- package/src/crypto-utils.ts +306 -59
- package/src/data-classification.ts +45 -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 +95 -138
- package/src/function/index.ts +1 -0
- 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 +84 -3
- package/src/middleware/auth-apikey.test.ts +0 -1
- package/src/middleware/auth-apikey.ts +0 -17
- package/src/middleware/auth-bearer.test.ts +3 -5
- package/src/middleware/auth-bearer.ts +5 -41
- 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 +26 -10
- package/src/middleware/remote-auth.ts +11 -3
- 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 +173 -0
- package/src/remote.ts +18 -8
- package/src/schema.ts +5 -39
- package/src/scopes.ts +7 -48
- package/src/secret-value.test.ts +204 -0
- package/src/secret-value.ts +111 -0
- 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 +88 -11
- 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/credential-wire-service.ts +9 -1
- package/src/services/deployment-service.ts +3 -9
- package/src/services/email-service.ts +3 -1
- 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 +23 -18
- package/src/services/istanbul-coverage-service.ts +2 -8
- package/src/services/jwt-service.ts +1 -16
- package/src/services/local-content-request-handler.test.ts +202 -0
- package/src/services/local-content-request-handler.ts +267 -0
- 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.test.ts +20 -5
- package/src/services/local-secrets.ts +15 -11
- package/src/services/logger-console.test.ts +0 -1
- package/src/services/logger-console.ts +3 -7
- package/src/services/logger.ts +31 -46
- 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.test.ts +2 -1
- package/src/services/queue-webhook-service.ts +10 -42
- 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 +4 -7
- 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 +12 -35
- 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 +12 -14
- package/src/services/v8-coverage-service.ts +3 -6
- package/src/services/variables-service.ts +1 -8
- package/src/services/webhook-service.ts +23 -64
- package/src/services/workflow-service.ts +3 -20
- package/src/testing/service-tests.ts +6 -32
- package/src/time-utils.ts +1 -19
- package/src/types/core.types.ts +137 -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 +91 -10
- package/src/wirings/ai-agent/ai-agent-agui.ts +49 -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 +89 -139
- 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 +85 -35
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +205 -103
- package/src/wirings/ai-agent/ai-agent-stream.ts +224 -76
- package/src/wirings/ai-agent/ai-agent-thread-ownership.test.ts +301 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +130 -5
- package/src/wirings/ai-agent/index.ts +37 -3
- package/src/wirings/ai-agent/voice-input.test.ts +137 -7
- package/src/wirings/ai-agent/voice-input.ts +96 -12
- package/src/wirings/ai-agent/voice-output.test.ts +512 -0
- package/src/wirings/ai-agent/voice-output.ts +243 -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 +185 -0
- package/src/wirings/cli/channel/index.ts +13 -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 +33 -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 +142 -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 +454 -0
- package/src/wirings/queue/queue-identity.ts +176 -0
- package/src/wirings/queue/queue-runner.ts +12 -31
- package/src/wirings/queue/queue.types.ts +25 -90
- package/src/wirings/queue/register-queue-helper.ts +0 -14
- package/src/wirings/queue/signed-queue-service.ts +60 -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 +9 -16
- package/src/wirings/rpc/rpc-runner.test.ts +192 -6
- 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 +88 -0
- package/src/wirings/virtual-user/prepare-virtual-user-run.test.ts +115 -0
- package/src/wirings/virtual-user/prepare-virtual-user-run.ts +95 -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-run-store.ts +98 -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 +19 -20
- 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 -61
- 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.test.ts +5 -7
- package/src/wirings/workflow/scenario-prose.ts +1 -29
- package/src/wirings/workflow/scenario-service.test.ts +2 -10
- package/src/wirings/workflow/scenario-step-guards.ts +1 -14
- package/src/wirings/workflow/scenario-step.test.ts +163 -19
- package/src/wirings/workflow/scenario-step.types.ts +94 -12
- package/src/wirings/workflow/scenario-surface.test.ts +146 -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 +5 -201
- package/tsconfig.tsbuildinfo +1 -1
- package/tsconfig.type-tests.json +12 -0
- 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
|
@@ -1,50 +1,20 @@
|
|
|
1
1
|
import type { SerializedError } from '../../types/core.types.js';
|
|
2
2
|
import type { StepState, StepStatus } from './workflow.types.js';
|
|
3
|
-
/**
|
|
4
|
-
* Time-travel over a workflow run.
|
|
5
|
-
*
|
|
6
|
-
* A run's durable history (`getRunHistory`) is one row per step *attempt*, each
|
|
7
|
-
* carrying lifecycle timestamps (created/scheduled/running/succeeded/failed).
|
|
8
|
-
* `buildRunTimeline` explodes those rows into a flat, chronologically-ordered
|
|
9
|
-
* event stream, and `reconstructStateAt` folds the stream up to any point to
|
|
10
|
-
* recover what the run "knew" then — the same step cache a replay would hold:
|
|
11
|
-
* per-step status, accumulated results, and the walked path.
|
|
12
|
-
*
|
|
13
|
-
* These are pure functions over history — no IO — so they're trivially testable
|
|
14
|
-
* and transport-independent (the same fold works for Redis/Kysely/in-memory).
|
|
15
|
-
*/
|
|
16
|
-
/** A single observable transition of one step attempt. */
|
|
17
3
|
export interface RunTimelineEvent {
|
|
18
|
-
/** Monotonic 0-based position in the timeline. */
|
|
19
4
|
seq: number;
|
|
20
|
-
/** When it happened. */
|
|
21
5
|
at: Date;
|
|
22
|
-
/** The step's new status at this event (matches StepStatus lifecycle). */
|
|
23
6
|
type: Extract<StepStatus, 'pending' | 'scheduled' | 'running' | 'succeeded' | 'failed'>;
|
|
24
|
-
/** Physical step name (includes revisit ordinal, e.g. `attempt#2`). */
|
|
25
7
|
stepName: string;
|
|
26
|
-
/** Which attempt this event belongs to (1-based). */
|
|
27
8
|
attemptCount: number;
|
|
28
|
-
/** Predecessor that scheduled this step — only on the `pending` (created)
|
|
29
|
-
* event; undefined for entry steps. Reconstructs the walked edge. */
|
|
30
9
|
fromStepName?: string;
|
|
31
|
-
/** Result snapshot — only on `succeeded`. */
|
|
32
10
|
result?: unknown;
|
|
33
|
-
/** Error snapshot — only on `failed`. */
|
|
34
11
|
error?: SerializedError;
|
|
35
12
|
}
|
|
36
13
|
export type RunTimeline = RunTimelineEvent[];
|
|
37
14
|
type HistoryEntry = StepState & {
|
|
38
15
|
stepName: string;
|
|
39
16
|
};
|
|
40
|
-
/**
|
|
41
|
-
* Build the ordered event stream for a run from its raw history.
|
|
42
|
-
*
|
|
43
|
-
* History is expected oldest-first but is sorted defensively by (timestamp,
|
|
44
|
-
* lifecycle, original index) so simultaneous timestamps stay deterministic.
|
|
45
|
-
*/
|
|
46
17
|
export declare function buildRunTimeline(history: HistoryEntry[]): RunTimeline;
|
|
47
|
-
/** A step's reconstructed state at a point in the timeline. */
|
|
48
18
|
export interface ReconstructedStep {
|
|
49
19
|
stepName: string;
|
|
50
20
|
status: StepStatus;
|
|
@@ -53,33 +23,16 @@ export interface ReconstructedStep {
|
|
|
53
23
|
result?: unknown;
|
|
54
24
|
error?: SerializedError;
|
|
55
25
|
}
|
|
56
|
-
/** Coarse run phase derived purely from step states (not the run's output). */
|
|
57
26
|
export type RunPhase = 'pending' | 'running' | 'failed' | 'idle';
|
|
58
|
-
/** The whole run's reconstructed state at a point in the timeline. */
|
|
59
27
|
export interface ReconstructedRunState {
|
|
60
28
|
/** seq of the last applied event, or -1 if the point precedes all events. */
|
|
61
29
|
seq: number;
|
|
62
|
-
/** Wall-clock time of the last applied event. */
|
|
63
30
|
at?: Date;
|
|
64
|
-
/** Per-step latest state, in first-seen (walked) order. */
|
|
65
31
|
steps: ReconstructedStep[];
|
|
66
|
-
/** Outputs available to downstream steps — the replay step cache at this
|
|
67
|
-
* point (succeeded steps only). */
|
|
68
32
|
results: Record<string, unknown>;
|
|
69
|
-
/** Step names in the order they were first created — the walked path. */
|
|
70
33
|
path: string[];
|
|
71
|
-
/** Derived phase: `running` if any step is in-flight, else `failed` if a step
|
|
72
|
-
* is failed with no in-flight work, else `idle` (between transitions). */
|
|
73
34
|
phase: RunPhase;
|
|
74
35
|
}
|
|
75
|
-
/**
|
|
76
|
-
* Fold the timeline up to `at` and return the run's state at that point.
|
|
77
|
-
*
|
|
78
|
-
* `at` is either a seq index (inclusive — apply events `0..at`) or a `Date`
|
|
79
|
-
* (inclusive — apply every event at or before that instant). A point before the
|
|
80
|
-
* first event yields the empty initial state.
|
|
81
|
-
*/
|
|
82
36
|
export declare function reconstructStateAt(timeline: RunTimeline, at: number | Date): ReconstructedRunState;
|
|
83
|
-
/** Reconstruct the final state (fold the whole timeline). */
|
|
84
37
|
export declare function reconstructFinalState(timeline: RunTimeline): ReconstructedRunState;
|
|
85
38
|
export {};
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/** Lifecycle tiebreak for events that share a timestamp. */
|
|
2
1
|
const LIFECYCLE_ORDER = {
|
|
3
2
|
pending: 0,
|
|
4
3
|
scheduled: 1,
|
|
@@ -6,12 +5,6 @@ const LIFECYCLE_ORDER = {
|
|
|
6
5
|
succeeded: 3,
|
|
7
6
|
failed: 3,
|
|
8
7
|
};
|
|
9
|
-
/**
|
|
10
|
-
* Build the ordered event stream for a run from its raw history.
|
|
11
|
-
*
|
|
12
|
-
* History is expected oldest-first but is sorted defensively by (timestamp,
|
|
13
|
-
* lifecycle, original index) so simultaneous timestamps stay deterministic.
|
|
14
|
-
*/
|
|
15
8
|
export function buildRunTimeline(history) {
|
|
16
9
|
const raw = [];
|
|
17
10
|
history.forEach((entry, order) => {
|
|
@@ -20,24 +13,18 @@ export function buildRunTimeline(history) {
|
|
|
20
13
|
attemptCount: entry.attemptCount,
|
|
21
14
|
order,
|
|
22
15
|
};
|
|
23
|
-
// The created event always exists; it carries provenance.
|
|
24
16
|
raw.push({
|
|
25
17
|
...base,
|
|
26
18
|
at: entry.createdAt,
|
|
27
19
|
type: 'pending',
|
|
28
20
|
fromStepName: entry.fromStepName,
|
|
29
21
|
});
|
|
30
|
-
// Intermediate events are optional enrichment — emit only if the backend
|
|
31
|
-
// recorded their timestamp.
|
|
32
22
|
if (entry.scheduledAt) {
|
|
33
23
|
raw.push({ ...base, at: entry.scheduledAt, type: 'scheduled' });
|
|
34
24
|
}
|
|
35
25
|
if (entry.runningAt) {
|
|
36
26
|
raw.push({ ...base, at: entry.runningAt, type: 'running' });
|
|
37
27
|
}
|
|
38
|
-
// The terminal event is driven by the row's authoritative status (the
|
|
39
|
-
// lifecycle timestamps aren't populated by every backend — Kysely leaves
|
|
40
|
-
// them null), falling back to updatedAt when the specific stamp is absent.
|
|
41
28
|
if (entry.status === 'succeeded') {
|
|
42
29
|
raw.push({
|
|
43
30
|
...base,
|
|
@@ -73,13 +60,6 @@ const IN_FLIGHT = new Set([
|
|
|
73
60
|
'scheduled',
|
|
74
61
|
'running',
|
|
75
62
|
]);
|
|
76
|
-
/**
|
|
77
|
-
* Fold the timeline up to `at` and return the run's state at that point.
|
|
78
|
-
*
|
|
79
|
-
* `at` is either a seq index (inclusive — apply events `0..at`) or a `Date`
|
|
80
|
-
* (inclusive — apply every event at or before that instant). A point before the
|
|
81
|
-
* first event yields the empty initial state.
|
|
82
|
-
*/
|
|
83
63
|
export function reconstructStateAt(timeline, at) {
|
|
84
64
|
const cutoff = (event) => typeof at === 'number'
|
|
85
65
|
? event.seq <= at
|
|
@@ -109,7 +89,6 @@ export function reconstructStateAt(timeline, at) {
|
|
|
109
89
|
if (event.fromStepName !== undefined) {
|
|
110
90
|
step.fromStepName = event.fromStepName;
|
|
111
91
|
}
|
|
112
|
-
// A retry's created event reopens the step — drop the prior outcome.
|
|
113
92
|
if (event.type === 'pending') {
|
|
114
93
|
delete step.result;
|
|
115
94
|
delete step.error;
|
|
@@ -138,7 +117,6 @@ export function reconstructStateAt(timeline, at) {
|
|
|
138
117
|
phase: derivePhase(orderedSteps),
|
|
139
118
|
};
|
|
140
119
|
}
|
|
141
|
-
/** Reconstruct the final state (fold the whole timeline). */
|
|
142
120
|
export function reconstructFinalState(timeline) {
|
|
143
121
|
return reconstructStateAt(timeline, timeline.length - 1);
|
|
144
122
|
}
|
|
@@ -1,29 +1,6 @@
|
|
|
1
|
-
/** A session held the way a browser holds one, for code driving a real target. */
|
|
2
1
|
export interface ScenarioCookieJar {
|
|
3
|
-
/** `fetch`, but it sends what the target has set and keeps what it sets. */
|
|
4
2
|
fetch: typeof fetch;
|
|
5
|
-
/** Forgets the session — what an actor does before signing in again. */
|
|
6
3
|
clear(): void;
|
|
7
|
-
/**
|
|
8
|
-
* Whether the target has set anything yet. This is a fact about the jar, not
|
|
9
|
-
* about the session: a target that sets a CSRF or locale cookie before anyone
|
|
10
|
-
* signs in fills the jar without establishing one. Whoever needs to know
|
|
11
|
-
* whether a sign-in happened has to track the sign-in.
|
|
12
|
-
*/
|
|
13
4
|
readonly empty: boolean;
|
|
14
5
|
}
|
|
15
|
-
/**
|
|
16
|
-
* A `fetch` that remembers cookies.
|
|
17
|
-
*
|
|
18
|
-
* A browser persists the session cookie on its own; anything driving a target
|
|
19
|
-
* from this process has to. Every response is read, not just the sign-in, so a
|
|
20
|
-
* cookie the target rotates mid-session is followed rather than dropped.
|
|
21
|
-
*
|
|
22
|
-
* The jar is a closure local, so two jars never share a session — which is what
|
|
23
|
-
* lets one scenario sign in as several people without one of them inheriting
|
|
24
|
-
* the other's session.
|
|
25
|
-
*
|
|
26
|
-
* It also stamps `Origin`, because Better Auth rejects a state-changing POST
|
|
27
|
-
* whose Origin does not match its baseURL.
|
|
28
|
-
*/
|
|
29
6
|
export declare const createCookieJar: (apiUrl: string) => ScenarioCookieJar;
|
|
@@ -1,17 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A `fetch` that remembers cookies.
|
|
3
|
-
*
|
|
4
|
-
* A browser persists the session cookie on its own; anything driving a target
|
|
5
|
-
* from this process has to. Every response is read, not just the sign-in, so a
|
|
6
|
-
* cookie the target rotates mid-session is followed rather than dropped.
|
|
7
|
-
*
|
|
8
|
-
* The jar is a closure local, so two jars never share a session — which is what
|
|
9
|
-
* lets one scenario sign in as several people without one of them inheriting
|
|
10
|
-
* the other's session.
|
|
11
|
-
*
|
|
12
|
-
* It also stamps `Origin`, because Better Auth rejects a state-changing POST
|
|
13
|
-
* whose Origin does not match its baseURL.
|
|
14
|
-
*/
|
|
15
1
|
export const createCookieJar = (apiUrl) => {
|
|
16
2
|
const jar = new Map();
|
|
17
3
|
const origin = new URL(apiUrl).origin;
|
|
@@ -31,8 +17,6 @@ export const createCookieJar = (apiUrl) => {
|
|
|
31
17
|
if (separator > 0) {
|
|
32
18
|
const name = pair.slice(0, separator);
|
|
33
19
|
const value = pair.slice(separator + 1);
|
|
34
|
-
// An empty value is how a target deletes a cookie — drop the name
|
|
35
|
-
// rather than holding a cookie whose value says it is gone.
|
|
36
20
|
if (value) {
|
|
37
21
|
jar.set(name, value);
|
|
38
22
|
}
|
|
@@ -1,20 +1,5 @@
|
|
|
1
|
-
/** How long to keep trying, and how long to wait between tries. */
|
|
2
1
|
export interface PollOptions {
|
|
3
|
-
/** Total time to keep attempting before giving up. Default 15s. */
|
|
4
2
|
timeoutMs?: number;
|
|
5
|
-
/** Gap between attempts. Default 250ms. */
|
|
6
3
|
intervalMs?: number;
|
|
7
4
|
}
|
|
8
|
-
/**
|
|
9
|
-
* Attempt something until it answers, or the deadline passes.
|
|
10
|
-
*
|
|
11
|
-
* `undefined` means "not yet" and nothing else — `false`, `0` and `''` are all
|
|
12
|
-
* answers, because a probe asking whether something happened reports `false`
|
|
13
|
-
* when it did not. Answering `undefined` at the deadline rather than throwing
|
|
14
|
-
* leaves the error to the caller, who is the only one who knows what was being
|
|
15
|
-
* waited for.
|
|
16
|
-
*
|
|
17
|
-
* A step that polls its target — a delivery reaching a terminal status, a run
|
|
18
|
-
* finishing — reaches for this rather than writing the deadline loop again.
|
|
19
|
-
*/
|
|
20
5
|
export declare const pollUntil: <T>(attempt: () => Promise<T | undefined> | T | undefined, { timeoutMs, intervalMs }?: PollOptions) => Promise<T | undefined>;
|
|
@@ -1,15 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Attempt something until it answers, or the deadline passes.
|
|
3
|
-
*
|
|
4
|
-
* `undefined` means "not yet" and nothing else — `false`, `0` and `''` are all
|
|
5
|
-
* answers, because a probe asking whether something happened reports `false`
|
|
6
|
-
* when it did not. Answering `undefined` at the deadline rather than throwing
|
|
7
|
-
* leaves the error to the caller, who is the only one who knows what was being
|
|
8
|
-
* waited for.
|
|
9
|
-
*
|
|
10
|
-
* A step that polls its target — a delivery reaching a terminal status, a run
|
|
11
|
-
* finishing — reaches for this rather than writing the deadline loop again.
|
|
12
|
-
*/
|
|
13
1
|
export const pollUntil = async (attempt, { timeoutMs = 15_000, intervalMs = 250 } = {}) => {
|
|
14
2
|
const deadline = Date.now() + timeoutMs;
|
|
15
3
|
for (;;) {
|
|
@@ -1,38 +1,10 @@
|
|
|
1
1
|
import type { ScenarioStepPhase } from './scenario-step.types.js';
|
|
2
|
-
/**
|
|
3
|
-
* Renders the English sentence a reporter shows for a scenario step.
|
|
4
|
-
*
|
|
5
|
-
* This is the inversion of cucumber: rather than parsing English into a call,
|
|
6
|
-
* we render English out of a typed call, so the readable report survives
|
|
7
|
-
* without a regex registry paying for it.
|
|
8
|
-
*
|
|
9
|
-
* Lives in core so the CLI reporter and the console render identically.
|
|
10
|
-
*/
|
|
11
|
-
/**
|
|
12
|
-
* Fill a step's `template` from the input that step was actually called with,
|
|
13
|
-
* so the reported sentence names the values under test — "sees @pikku/addon-todos"
|
|
14
|
-
* rather than "sees an addon in the gallery" repeated three times.
|
|
15
|
-
*
|
|
16
|
-
* A placeholder with no recorded value renders as nothing and the surrounding
|
|
17
|
-
* whitespace collapses, so an optional input that was omitted reads as a shorter
|
|
18
|
-
* sentence rather than a literal `{state}` leaking into the report.
|
|
19
|
-
*/
|
|
20
2
|
export declare const renderStepTemplate: (template: string, input: unknown) => string;
|
|
21
3
|
export declare const composeStepProse: ({ phase, description, template, input, actor, keywordWidth, }: {
|
|
22
4
|
phase: ScenarioStepPhase;
|
|
23
5
|
description: string;
|
|
24
|
-
/**
|
|
25
|
-
* The prose this step renders, with `{placeholders}` filled from `input`.
|
|
26
|
-
* Unlike `description`, which documents what the step does, this is what a
|
|
27
|
-
* reader of the report sees. Falls back to `description` when absent.
|
|
28
|
-
*/
|
|
29
6
|
template?: string;
|
|
30
|
-
/** The input this step was called with, as recorded on the run. */
|
|
31
7
|
input?: unknown;
|
|
32
8
|
actor?: string;
|
|
33
|
-
/**
|
|
34
|
-
* Pad the keyword to this width so a ladder of steps lines its sentences up
|
|
35
|
-
* under each other. Omit for inline prose.
|
|
36
|
-
*/
|
|
37
9
|
keywordWidth?: number;
|
|
38
10
|
}) => string;
|
|
@@ -1,21 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Renders the English sentence a reporter shows for a scenario step.
|
|
3
|
-
*
|
|
4
|
-
* This is the inversion of cucumber: rather than parsing English into a call,
|
|
5
|
-
* we render English out of a typed call, so the readable report survives
|
|
6
|
-
* without a regex registry paying for it.
|
|
7
|
-
*
|
|
8
|
-
* Lives in core so the CLI reporter and the console render identically.
|
|
9
|
-
*/
|
|
10
|
-
/**
|
|
11
|
-
* Fill a step's `template` from the input that step was actually called with,
|
|
12
|
-
* so the reported sentence names the values under test — "sees @pikku/addon-todos"
|
|
13
|
-
* rather than "sees an addon in the gallery" repeated three times.
|
|
14
|
-
*
|
|
15
|
-
* A placeholder with no recorded value renders as nothing and the surrounding
|
|
16
|
-
* whitespace collapses, so an optional input that was omitted reads as a shorter
|
|
17
|
-
* sentence rather than a literal `{state}` leaking into the report.
|
|
18
|
-
*/
|
|
19
1
|
export const renderStepTemplate = (template, input) => {
|
|
20
2
|
const values = input && typeof input === 'object' ? input : {};
|
|
21
3
|
return template
|
|
@@ -33,7 +15,7 @@ const formatValue = (value) => {
|
|
|
33
15
|
return String(value);
|
|
34
16
|
};
|
|
35
17
|
export const composeStepProse = ({ phase, description, template, input, actor, keywordWidth, }) => {
|
|
36
|
-
const keyword =
|
|
18
|
+
const keyword = capitalise(phase);
|
|
37
19
|
const subject = actor ? `the ${actor}` : '';
|
|
38
20
|
const rendered = template ? renderStepTemplate(template, input) : description;
|
|
39
21
|
const sentence = [subject, rendered].filter(Boolean).join(' ');
|
|
@@ -1,16 +1,3 @@
|
|
|
1
1
|
import type { PikkuScenarioStepWire, ScenarioEnvironment } from './scenario-step.types.js';
|
|
2
|
-
/**
|
|
3
|
-
* The actor this step was called with, or a loud error naming the step.
|
|
4
|
-
*
|
|
5
|
-
* A step that talks to the target app needs an identity, but `actor` is
|
|
6
|
-
* optional on the wire because a pure assertion step needs none. This is the
|
|
7
|
-
* one place that narrowing happens, so every step file stops writing its own
|
|
8
|
-
* `actorOf(...)` guard.
|
|
9
|
-
*/
|
|
10
2
|
export declare const requireActor: <TActor>(scenarioStep: PikkuScenarioStepWire<TActor> | undefined) => TActor;
|
|
11
|
-
/**
|
|
12
|
-
* The environment this run targets, or a loud error naming the step. A run
|
|
13
|
-
* started outside `pikku scenario run` only carries one when the server has
|
|
14
|
-
* `API_URL` configured.
|
|
15
|
-
*/
|
|
16
3
|
export declare const requireScenarioEnv: (scenarioStep: PikkuScenarioStepWire<unknown> | undefined) => ScenarioEnvironment;
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The actor this step was called with, or a loud error naming the step.
|
|
3
|
-
*
|
|
4
|
-
* A step that talks to the target app needs an identity, but `actor` is
|
|
5
|
-
* optional on the wire because a pure assertion step needs none. This is the
|
|
6
|
-
* one place that narrowing happens, so every step file stops writing its own
|
|
7
|
-
* `actorOf(...)` guard.
|
|
8
|
-
*/
|
|
9
1
|
export const requireActor = (scenarioStep) => {
|
|
10
2
|
const actor = scenarioStep?.actor;
|
|
11
3
|
if (!actor) {
|
|
@@ -14,16 +6,11 @@ export const requireActor = (scenarioStep) => {
|
|
|
14
6
|
}
|
|
15
7
|
return actor;
|
|
16
8
|
};
|
|
17
|
-
/**
|
|
18
|
-
* The environment this run targets, or a loud error naming the step. A run
|
|
19
|
-
* started outside `pikku scenario run` only carries one when the server has
|
|
20
|
-
* `API_URL` configured.
|
|
21
|
-
*/
|
|
22
9
|
export const requireScenarioEnv = (scenarioStep) => {
|
|
23
10
|
const env = scenarioStep?.env;
|
|
24
11
|
if (!env) {
|
|
25
12
|
throw new Error(`[scenario] step '${scenarioStep?.name ?? 'unknown'}' needs the target environment, but this run carries none. ` +
|
|
26
|
-
`Run it through 'pikku scenario run <environment>' with
|
|
13
|
+
`Run it through 'pikku scenario run <environment>' with environments.<environment> declared in pikku.config.json.`);
|
|
27
14
|
}
|
|
28
15
|
return env;
|
|
29
16
|
};
|
|
@@ -1,25 +1,92 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ScenarioPersona } from '../../services/personas-service.js';
|
|
2
2
|
/**
|
|
3
3
|
* Scenario steps: named, typed units of scenario behaviour.
|
|
4
4
|
*
|
|
5
5
|
* A step's body is an ordinary pikku function, so it may drive a browser, call
|
|
6
|
-
* an RPC as its actor, or run a workflow. `given
|
|
7
|
-
*
|
|
6
|
+
* an RPC as its actor, or run a workflow. `given` and `when` differ only in the
|
|
7
|
+
* prose the reporter renders; `then` also changes what runs, because its
|
|
8
|
+
* bindings are witnesses — every declared surface is observed and the
|
|
9
|
+
* observations must agree. See {@link ScenarioSurfaceResolution}.
|
|
8
10
|
*/
|
|
9
11
|
/**
|
|
10
|
-
* Which Gherkin-style keyword the reporter prefixes this step with.
|
|
11
|
-
*
|
|
12
|
+
* Which Gherkin-style keyword the reporter prefixes this step with.
|
|
13
|
+
*
|
|
14
|
+
* Every step takes one. A scenario is read by people deciding whether it
|
|
15
|
+
* describes the behaviour they wanted, and a step that says only what it does
|
|
16
|
+
* without saying whether it is setup, action or claim is the one nobody can
|
|
17
|
+
* check — which is also why PKU680 can tell a scenario that never asserts.
|
|
18
|
+
*/
|
|
19
|
+
export type ScenarioStepPhase = 'given' | 'when' | 'then';
|
|
20
|
+
/**
|
|
21
|
+
* Who acts in a step.
|
|
22
|
+
*
|
|
23
|
+
* `persona` is a person driving the system through one of its surfaces — the
|
|
24
|
+
* ordinary `pikkuScenarioStep`. `platform` is the app acting on itself ("the
|
|
25
|
+
* platform has expired the trial"), and `addon` is a third-party system acting
|
|
26
|
+
* on it ("Stripe's webhook arrives"), contributed by the addon that wraps that
|
|
27
|
+
* service.
|
|
28
|
+
*
|
|
29
|
+
* The three are separate declarations rather than a field on one, so the
|
|
30
|
+
* inspector verifies a step's kind by which function was called rather than by
|
|
31
|
+
* trusting a string literal — and so an addon package exports only addon steps,
|
|
32
|
+
* which is checkable.
|
|
12
33
|
*/
|
|
13
|
-
export type
|
|
34
|
+
export type ScenarioStepKind = 'persona' | 'platform' | 'addon';
|
|
14
35
|
/**
|
|
15
|
-
*
|
|
36
|
+
* How an actor drives the system for one step.
|
|
37
|
+
*
|
|
38
|
+
* A step declares one implementation per surface it supports, and the runner
|
|
39
|
+
* picks between them — so the same ladder can run through a real browser, over
|
|
40
|
+
* the websocket, or entirely server-side.
|
|
41
|
+
*
|
|
42
|
+
* `default` is the floor: it is what every other surface falls back to, so it
|
|
43
|
+
* can never itself fall back.
|
|
44
|
+
*/
|
|
45
|
+
export type ScenarioSurface = 'browser' | 'cli' | 'default';
|
|
46
|
+
export declare const SCENARIO_SURFACES: readonly ScenarioSurface[];
|
|
47
|
+
/**
|
|
48
|
+
* How a step's declared surfaces resolve for one run.
|
|
49
|
+
*
|
|
50
|
+
* `given`/`when` bindings are **alternatives** — clicking Buy and calling
|
|
51
|
+
* `createOrder` are two ways to cause one effect, so exactly one runs.
|
|
52
|
+
*
|
|
53
|
+
* `then` bindings are **witnesses** — "the order row says paid" and "the
|
|
54
|
+
* confirmation panel says paid" are different claims that share a name, and the
|
|
55
|
+
* gap between them is the bug nobody catches. So every declared witness runs and
|
|
56
|
+
* they must agree.
|
|
57
|
+
*/
|
|
58
|
+
export type ScenarioSurfaceResolution = {
|
|
59
|
+
kind: 'action';
|
|
60
|
+
surface: ScenarioSurface;
|
|
61
|
+
/** The run asked for a surface this step does not implement. */
|
|
62
|
+
fellBack: boolean;
|
|
63
|
+
} | {
|
|
64
|
+
kind: 'witness';
|
|
65
|
+
/**
|
|
66
|
+
* Every witness to run, surface first. Empty means the assertion has no
|
|
67
|
+
* binding this run can execute at all — nothing would check anything, so
|
|
68
|
+
* the step fails rather than reporting a pass it never earned.
|
|
69
|
+
*/
|
|
70
|
+
surfaces: ScenarioSurface[];
|
|
71
|
+
/**
|
|
72
|
+
* Something checked the assertion, but not on the surface its prose
|
|
73
|
+
* claims — so nobody looked at the UI. Reported as its own state and
|
|
74
|
+
* counted against coverage: not being in the UI *is* the finding.
|
|
75
|
+
*
|
|
76
|
+
* Disjoint from an empty `surfaces`; an assertion that ran nowhere is a
|
|
77
|
+
* failure, not a coverage statistic.
|
|
78
|
+
*/
|
|
79
|
+
unwitnessed: boolean;
|
|
80
|
+
};
|
|
81
|
+
/**
|
|
82
|
+
* Options accepted by `scenario.given/when/then`.
|
|
16
83
|
*
|
|
17
84
|
* Note the retry default differs from an ordinary workflow step: retrying a
|
|
18
85
|
* failed assertion is the wrong behaviour for a test primitive, so steps
|
|
19
86
|
* default to no retries.
|
|
20
87
|
*/
|
|
21
88
|
export interface ScenarioStepOptions {
|
|
22
|
-
/** The actor this step runs as. Required for steps declaring `browser
|
|
89
|
+
/** The actor this step runs as. Required for steps declaring a `browser` binding. */
|
|
23
90
|
actor?: unknown;
|
|
24
91
|
/** Overrides the step's own `description` for this call site only. */
|
|
25
92
|
description?: string;
|
|
@@ -29,7 +96,7 @@ export interface ScenarioStepOptions {
|
|
|
29
96
|
}
|
|
30
97
|
/**
|
|
31
98
|
* The environment a scenario run targets, as declared in pikku.config.json
|
|
32
|
-
* under `
|
|
99
|
+
* under `environments`.
|
|
33
100
|
*/
|
|
34
101
|
export interface ScenarioEnvironment {
|
|
35
102
|
/** Base API URL of the target app, INCLUDING the HTTP prefix. */
|
|
@@ -41,16 +108,21 @@ export interface ScenarioEnvironment {
|
|
|
41
108
|
* The `scenarioStep` wire, present on every scenario step invocation.
|
|
42
109
|
*
|
|
43
110
|
* `TActor` is the project's own actor type, so a step reaches only the RPCs its
|
|
44
|
-
* actors can actually call. It defaults to the open `
|
|
111
|
+
* actors can actually call. It defaults to the open `ScenarioPersona` for a
|
|
45
112
|
* project that declares no registry.
|
|
46
113
|
*/
|
|
47
|
-
export interface PikkuScenarioStepWire<TActor =
|
|
114
|
+
export interface PikkuScenarioStepWire<TActor = ScenarioPersona> {
|
|
48
115
|
/** Registered step name (also its pikkuFuncId) */
|
|
49
116
|
name: string;
|
|
50
117
|
/** Durable key within the run; may carry an `#ordinal` suffix when repeated */
|
|
51
118
|
stepName: string;
|
|
52
119
|
runId: string;
|
|
53
120
|
phase: ScenarioStepPhase;
|
|
121
|
+
/**
|
|
122
|
+
* Which of the step's bindings is currently executing. A `then` step runs once
|
|
123
|
+
* per witness, so its body sees this change between invocations.
|
|
124
|
+
*/
|
|
125
|
+
surface: ScenarioSurface;
|
|
54
126
|
/**
|
|
55
127
|
* The actor this step runs as, when one was given. Call RPCs through it
|
|
56
128
|
* (`actor.invoke(...)`) so they run against the target environment as that
|
|
@@ -89,7 +161,7 @@ export interface TestIdSelector {
|
|
|
89
161
|
}
|
|
90
162
|
/**
|
|
91
163
|
* Structural browser handle, present only when the runner provisioned a
|
|
92
|
-
* browser for this step (`browser
|
|
164
|
+
* browser for this step (a `browser` binding on the step config).
|
|
93
165
|
*
|
|
94
166
|
* `@pikku/core` deliberately never imports playwright — it must stay
|
|
95
167
|
* dependency-free for edge runtimes. `@pikku/playwright` augments this
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { ScenarioStepPhase, ScenarioSurface, ScenarioSurfaceResolution } from './scenario-step.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Resolve which of a step's declared bindings run, for one step, in one run.
|
|
4
|
+
*
|
|
5
|
+
* The asymmetry between phases is the whole point — see
|
|
6
|
+
* {@link ScenarioSurfaceResolution}.
|
|
7
|
+
*/
|
|
8
|
+
export declare const resolveScenarioSurfaces: (phase: ScenarioStepPhase, declared: readonly ScenarioSurface[], runSurface: ScenarioSurface) => ScenarioSurfaceResolution;
|
|
9
|
+
/**
|
|
10
|
+
* Structural comparison of two witnesses' observations.
|
|
11
|
+
*
|
|
12
|
+
* A witness that returns `undefined` asserted by throwing rather than by
|
|
13
|
+
* reporting what it saw, so it is not compared — that keeps assertion-style
|
|
14
|
+
* steps working without forcing every one of them to return a value.
|
|
15
|
+
*/
|
|
16
|
+
export declare const witnessesAgree: (a: unknown, b: unknown) => boolean;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve which of a step's declared bindings run, for one step, in one run.
|
|
3
|
+
*
|
|
4
|
+
* The asymmetry between phases is the whole point — see
|
|
5
|
+
* {@link ScenarioSurfaceResolution}.
|
|
6
|
+
*/
|
|
7
|
+
export const resolveScenarioSurfaces = (phase, declared, runSurface) => {
|
|
8
|
+
const has = (surface) => declared.includes(surface);
|
|
9
|
+
if (phase !== 'then') {
|
|
10
|
+
if (has(runSurface)) {
|
|
11
|
+
return { kind: 'action', surface: runSurface, fellBack: false };
|
|
12
|
+
}
|
|
13
|
+
return { kind: 'action', surface: 'default', fellBack: true };
|
|
14
|
+
}
|
|
15
|
+
const surfaces = [];
|
|
16
|
+
if (runSurface !== 'default' && has(runSurface)) {
|
|
17
|
+
surfaces.push(runSurface);
|
|
18
|
+
}
|
|
19
|
+
if (has('default')) {
|
|
20
|
+
surfaces.push('default');
|
|
21
|
+
}
|
|
22
|
+
return {
|
|
23
|
+
kind: 'witness',
|
|
24
|
+
surfaces,
|
|
25
|
+
// Only meaningful once something ran: an assertion checked server-side
|
|
26
|
+
// under `--run browser` is a coverage gap, but one checked nowhere at all
|
|
27
|
+
// is a step that did not happen, which the caller fails rather than counts.
|
|
28
|
+
unwitnessed: surfaces.length > 0 && runSurface !== 'default' && !has(runSurface),
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Structural comparison of two witnesses' observations.
|
|
33
|
+
*
|
|
34
|
+
* A witness that returns `undefined` asserted by throwing rather than by
|
|
35
|
+
* reporting what it saw, so it is not compared — that keeps assertion-style
|
|
36
|
+
* steps working without forcing every one of them to return a value.
|
|
37
|
+
*/
|
|
38
|
+
export const witnessesAgree = (a, b) => {
|
|
39
|
+
if (a === undefined || b === undefined) {
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
return stableStringify(a) === stableStringify(b);
|
|
43
|
+
};
|
|
44
|
+
const stableStringify = (value) => {
|
|
45
|
+
if (value === null || typeof value !== 'object') {
|
|
46
|
+
return JSON.stringify(value) ?? 'undefined';
|
|
47
|
+
}
|
|
48
|
+
if (Array.isArray(value)) {
|
|
49
|
+
return `[${value.map(stableStringify).join(',')}]`;
|
|
50
|
+
}
|
|
51
|
+
const entries = Object.entries(value)
|
|
52
|
+
.filter(([, v]) => v !== undefined)
|
|
53
|
+
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
|
|
54
|
+
.map(([k, v]) => `${JSON.stringify(k)}:${stableStringify(v)}`);
|
|
55
|
+
return `{${entries.join(',')}}`;
|
|
56
|
+
};
|
|
@@ -1,20 +1,2 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* RFC 4122 v5 (SHA-1, name-based) UUID. Deterministic: the same name +
|
|
3
|
-
* namespace always yields the same UUID — no `uuid` dependency needed.
|
|
4
|
-
*/
|
|
5
1
|
export declare const uuidv5: (name: string, namespace?: string) => string;
|
|
6
|
-
/**
|
|
7
|
-
* The stable identity of one step *invocation* within a run — the idempotency /
|
|
8
|
-
* dedupe key handed to a step. Unlike `stepId` (minted fresh per attempt), this
|
|
9
|
-
* stays identical across every retry of the same call, because it is derived
|
|
10
|
-
* purely from `runId` + `stepName`, both of which are stable across replays.
|
|
11
|
-
*
|
|
12
|
-
* Same inputs → same UUID, so a step can safely
|
|
13
|
-
* `INSERT … ON CONFLICT (invocation_id)` / pass it as a Stripe idempotency key,
|
|
14
|
-
* and a retry of a half-applied side effect is collapsed onto the first attempt.
|
|
15
|
-
*
|
|
16
|
-
* NOTE: calling the *same* `stepName` more than once in a run is not yet
|
|
17
|
-
* disambiguated here (the store still keys steps by `runId:stepName`); when
|
|
18
|
-
* per-invocation ordinals land, the ordinal becomes the third hash component.
|
|
19
|
-
*/
|
|
20
2
|
export declare const deriveInvocationId: (runId: string, stepName: string) => string;
|
|
@@ -1,38 +1,18 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
|
-
// Fixed namespace for pikku workflow step invocation IDs. Frozen — changing it
|
|
3
|
-
// would alter every derived invocationId and break dedupe across a deploy.
|
|
4
2
|
const PIKKU_WORKFLOW_NAMESPACE = '70696b6b-7500-5770-9f6c-6f77000a0001';
|
|
5
3
|
const parseUuid = (uuid) => Buffer.from(uuid.replace(/-/g, ''), 'hex');
|
|
6
4
|
const formatUuid = (bytes) => {
|
|
7
5
|
const hex = bytes.toString('hex');
|
|
8
6
|
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`;
|
|
9
7
|
};
|
|
10
|
-
/**
|
|
11
|
-
* RFC 4122 v5 (SHA-1, name-based) UUID. Deterministic: the same name +
|
|
12
|
-
* namespace always yields the same UUID — no `uuid` dependency needed.
|
|
13
|
-
*/
|
|
14
8
|
export const uuidv5 = (name, namespace = PIKKU_WORKFLOW_NAMESPACE) => {
|
|
15
9
|
const hash = createHash('sha1')
|
|
16
10
|
.update(parseUuid(namespace))
|
|
17
11
|
.update(name, 'utf8')
|
|
18
12
|
.digest();
|
|
19
13
|
const bytes = hash.subarray(0, 16);
|
|
20
|
-
bytes[6] = (bytes[6] & 0x0f) | 0x50;
|
|
21
|
-
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
14
|
+
bytes[6] = (bytes[6] & 0x0f) | 0x50;
|
|
15
|
+
bytes[8] = (bytes[8] & 0x3f) | 0x80;
|
|
22
16
|
return formatUuid(bytes);
|
|
23
17
|
};
|
|
24
|
-
/**
|
|
25
|
-
* The stable identity of one step *invocation* within a run — the idempotency /
|
|
26
|
-
* dedupe key handed to a step. Unlike `stepId` (minted fresh per attempt), this
|
|
27
|
-
* stays identical across every retry of the same call, because it is derived
|
|
28
|
-
* purely from `runId` + `stepName`, both of which are stable across replays.
|
|
29
|
-
*
|
|
30
|
-
* Same inputs → same UUID, so a step can safely
|
|
31
|
-
* `INSERT … ON CONFLICT (invocation_id)` / pass it as a Stripe idempotency key,
|
|
32
|
-
* and a retry of a half-applied side effect is collapsed onto the first attempt.
|
|
33
|
-
*
|
|
34
|
-
* NOTE: calling the *same* `stepName` more than once in a run is not yet
|
|
35
|
-
* disambiguated here (the store still keys steps by `runId:stepName`); when
|
|
36
|
-
* per-invocation ordinals land, the ordinal becomes the third hash component.
|
|
37
|
-
*/
|
|
38
18
|
export const deriveInvocationId = (runId, stepName) => uuidv5(`${runId}:${stepName}`);
|