@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
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The stack of things this user is in the middle of — and the whole of the
|
|
3
|
+
* engine's randomness.
|
|
4
|
+
*
|
|
5
|
+
* A real person does not run a flow end to end: they start something, get
|
|
6
|
+
* pulled away, do a bit of something else, come back to a world that moved
|
|
7
|
+
* underneath them, and sometimes never come back at all. Modelling that as a
|
|
8
|
+
* stack of partially-completed intents is what produces the bugs worth having —
|
|
9
|
+
* half-mutated state, a flow resumed against changed data, an invite accepted
|
|
10
|
+
* after the plan changed — none of which a scripted scenario can reach.
|
|
11
|
+
*
|
|
12
|
+
* Scheduling is the engine's job and the model's turns are not: the model
|
|
13
|
+
* decides what to do *within* the active intent, the stack decides which intent
|
|
14
|
+
* that is. Keeping the split there is what makes a run reproducible from a seed
|
|
15
|
+
* while the work inside it stays free.
|
|
16
|
+
*
|
|
17
|
+
* A feature is only where an intent comes from. Nothing here tracks whether one
|
|
18
|
+
* was "completed correctly", and the model is never told an intent boundary
|
|
19
|
+
* exists.
|
|
20
|
+
*/
|
|
21
|
+
export class IntentStack {
|
|
22
|
+
rng;
|
|
23
|
+
profile;
|
|
24
|
+
maxOpen;
|
|
25
|
+
tracked = [];
|
|
26
|
+
unstarted;
|
|
27
|
+
active = null;
|
|
28
|
+
counter = 0;
|
|
29
|
+
constructor(sources, rng, profile,
|
|
30
|
+
/** Cap on intents open at once, so a distractible user still finishes things. */
|
|
31
|
+
maxOpen = 3) {
|
|
32
|
+
this.rng = rng;
|
|
33
|
+
this.profile = profile;
|
|
34
|
+
this.maxOpen = maxOpen;
|
|
35
|
+
this.unstarted = [...sources];
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Pick the intent for this tick, or `null` when there is nothing left to do.
|
|
39
|
+
*
|
|
40
|
+
* The first tick always starts something; after that the four moves are
|
|
41
|
+
* weighted by the disposition, and a move that has nowhere to go degrades to
|
|
42
|
+
* `continue` rather than stalling the run.
|
|
43
|
+
*/
|
|
44
|
+
next(step) {
|
|
45
|
+
if (!this.active) {
|
|
46
|
+
const started = this.startOrResume();
|
|
47
|
+
if (!started)
|
|
48
|
+
return null;
|
|
49
|
+
started.steps.push(step);
|
|
50
|
+
this.active = started;
|
|
51
|
+
return { intent: started, move: 'start' };
|
|
52
|
+
}
|
|
53
|
+
const move = this.rng.weighted(this.profile.moves) ?? 'continue';
|
|
54
|
+
if (move === 'continue') {
|
|
55
|
+
this.active.steps.push(step);
|
|
56
|
+
return { intent: this.active, move: 'continue' };
|
|
57
|
+
}
|
|
58
|
+
const current = this.active;
|
|
59
|
+
if (move === 'abandon') {
|
|
60
|
+
current.status = 'abandoned';
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
current.status = 'suspended';
|
|
64
|
+
current.suspensions++;
|
|
65
|
+
}
|
|
66
|
+
this.active = null;
|
|
67
|
+
const next = move === 'resume' ? this.resumeSuspended() : this.startOrResume(current);
|
|
68
|
+
if (!next) {
|
|
69
|
+
// Nowhere to go: keep working on what we had rather than ending a run
|
|
70
|
+
// early. An abandoned intent stays abandoned — that decision stands.
|
|
71
|
+
if (current.status === 'abandoned')
|
|
72
|
+
return null;
|
|
73
|
+
current.status = 'open';
|
|
74
|
+
current.suspensions--;
|
|
75
|
+
current.steps.push(step);
|
|
76
|
+
this.active = current;
|
|
77
|
+
return { intent: current, move: 'continue' };
|
|
78
|
+
}
|
|
79
|
+
next.status = 'open';
|
|
80
|
+
next.steps.push(step);
|
|
81
|
+
this.active = next;
|
|
82
|
+
return { intent: next, move };
|
|
83
|
+
}
|
|
84
|
+
/** Mark the active intent finished; the next tick schedules something else. */
|
|
85
|
+
complete(summary) {
|
|
86
|
+
if (!this.active)
|
|
87
|
+
return;
|
|
88
|
+
this.active.status = 'completed';
|
|
89
|
+
this.active.summary = summary;
|
|
90
|
+
this.active = null;
|
|
91
|
+
}
|
|
92
|
+
/** Mark the active intent as one the user could not get through. */
|
|
93
|
+
stuck(reason) {
|
|
94
|
+
if (!this.active)
|
|
95
|
+
return;
|
|
96
|
+
this.active.status = 'stuck';
|
|
97
|
+
this.active.summary = reason;
|
|
98
|
+
this.active = null;
|
|
99
|
+
}
|
|
100
|
+
/** Every intent the run touched, in the order it first opened them. */
|
|
101
|
+
records() {
|
|
102
|
+
return this.tracked.map((intent) => ({
|
|
103
|
+
id: intent.id,
|
|
104
|
+
sourceId: intent.source.id,
|
|
105
|
+
title: intent.source.title,
|
|
106
|
+
status: intent.status,
|
|
107
|
+
steps: [...intent.steps],
|
|
108
|
+
suspensions: intent.suspensions,
|
|
109
|
+
summary: intent.summary,
|
|
110
|
+
}));
|
|
111
|
+
}
|
|
112
|
+
/** Prefer opening something new, falling back to picking a suspended one up. */
|
|
113
|
+
startOrResume(exclude) {
|
|
114
|
+
const openCount = this.tracked.filter((intent) => intent.status === 'open' || intent.status === 'suspended').length;
|
|
115
|
+
if (this.unstarted.length > 0 && openCount < this.maxOpen) {
|
|
116
|
+
const source = this.rng.pick(this.unstarted);
|
|
117
|
+
this.unstarted.splice(this.unstarted.indexOf(source), 1);
|
|
118
|
+
const intent = {
|
|
119
|
+
id: `intent_${++this.counter}`,
|
|
120
|
+
source,
|
|
121
|
+
status: 'open',
|
|
122
|
+
steps: [],
|
|
123
|
+
suspensions: 0,
|
|
124
|
+
};
|
|
125
|
+
this.tracked.push(intent);
|
|
126
|
+
return intent;
|
|
127
|
+
}
|
|
128
|
+
return this.resumeSuspended(exclude);
|
|
129
|
+
}
|
|
130
|
+
resumeSuspended(exclude) {
|
|
131
|
+
const suspended = this.tracked.filter((intent) => intent.status === 'suspended' && intent !== exclude);
|
|
132
|
+
return this.rng.pick(suspended) ?? null;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* The intents a persona may be given: those whose source names them, plus every
|
|
137
|
+
* source that names nobody.
|
|
138
|
+
*
|
|
139
|
+
* This is a free lookup rather than new authoring — scenario meta already
|
|
140
|
+
* records which personas each scenario runs as.
|
|
141
|
+
*/
|
|
142
|
+
export const intentsForPersona = (sources, personaId) => sources.filter((source) => !source.personas?.length || source.personas.includes(personaId));
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A seeded PRNG, so a run replays exactly.
|
|
3
|
+
*
|
|
4
|
+
* Reproducibility is the whole point: a virtual user that finds something has
|
|
5
|
+
* to be re-runnable into the same finding before it can be shrunk into a
|
|
6
|
+
* regression scenario. `Math.random` would make every finding a one-off story.
|
|
7
|
+
*
|
|
8
|
+
* mulberry32 — 32 bits of state, uniform enough for scheduling weights, and
|
|
9
|
+
* short enough to read.
|
|
10
|
+
*/
|
|
11
|
+
export declare const createRng: (seed: number) => {
|
|
12
|
+
next: () => number;
|
|
13
|
+
/** True with probability `p`. */
|
|
14
|
+
chance: (p: number) => boolean;
|
|
15
|
+
/** A uniform pick, or undefined for an empty list. */
|
|
16
|
+
pick: <T>(items: readonly T[]) => T | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* A weighted pick over `[key, weight]` pairs. Zero-weight keys can never be
|
|
19
|
+
* drawn, which is how a disposition switches a move off entirely.
|
|
20
|
+
*/
|
|
21
|
+
weighted: <K extends string>(weights: Readonly<Record<K, number>>) => K | undefined;
|
|
22
|
+
};
|
|
23
|
+
/** The seeded generator the engine threads through a whole run. */
|
|
24
|
+
export type VirtualUserRng = ReturnType<typeof createRng>;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A seeded PRNG, so a run replays exactly.
|
|
3
|
+
*
|
|
4
|
+
* Reproducibility is the whole point: a virtual user that finds something has
|
|
5
|
+
* to be re-runnable into the same finding before it can be shrunk into a
|
|
6
|
+
* regression scenario. `Math.random` would make every finding a one-off story.
|
|
7
|
+
*
|
|
8
|
+
* mulberry32 — 32 bits of state, uniform enough for scheduling weights, and
|
|
9
|
+
* short enough to read.
|
|
10
|
+
*/
|
|
11
|
+
export const createRng = (seed) => {
|
|
12
|
+
let state = seed >>> 0;
|
|
13
|
+
const next = () => {
|
|
14
|
+
state = (state + 0x6d2b79f5) >>> 0;
|
|
15
|
+
let t = state;
|
|
16
|
+
t = Math.imul(t ^ (t >>> 15), t | 1);
|
|
17
|
+
t ^= t + Math.imul(t ^ (t >>> 7), t | 61);
|
|
18
|
+
return ((t ^ (t >>> 14)) >>> 0) / 4294967296;
|
|
19
|
+
};
|
|
20
|
+
return {
|
|
21
|
+
next,
|
|
22
|
+
/** True with probability `p`. */
|
|
23
|
+
chance: (p) => next() < p,
|
|
24
|
+
/** A uniform pick, or undefined for an empty list. */
|
|
25
|
+
pick: (items) => items.length === 0 ? undefined : items[Math.floor(next() * items.length)],
|
|
26
|
+
/**
|
|
27
|
+
* A weighted pick over `[key, weight]` pairs. Zero-weight keys can never be
|
|
28
|
+
* drawn, which is how a disposition switches a move off entirely.
|
|
29
|
+
*/
|
|
30
|
+
weighted: (weights) => {
|
|
31
|
+
const entries = Object.entries(weights).filter(([, weight]) => weight > 0);
|
|
32
|
+
const total = entries.reduce((sum, [, weight]) => sum + weight, 0);
|
|
33
|
+
if (total <= 0)
|
|
34
|
+
return undefined;
|
|
35
|
+
let roll = next() * total;
|
|
36
|
+
for (const [key, weight] of entries) {
|
|
37
|
+
roll -= weight;
|
|
38
|
+
if (roll <= 0)
|
|
39
|
+
return key;
|
|
40
|
+
}
|
|
41
|
+
return entries[entries.length - 1]?.[0];
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { VirtualUserDisposition, VirtualUserFinding, VirtualUserTally } from './virtual-user.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* One recorded run: who ran, what they were told, and what came back.
|
|
4
|
+
*
|
|
5
|
+
* A run is dispatched and answered for later, so the record is created before
|
|
6
|
+
* the work starts and is the thing the returned `runId` addresses.
|
|
7
|
+
*
|
|
8
|
+
* This record is a run's ONLY trace. A virtual user is not a workflow — it
|
|
9
|
+
* explores, so no two attempts take the same steps and there is nothing to
|
|
10
|
+
* replay — and it is not queued either, because the record already carries the
|
|
11
|
+
* progress a queue would only be holding on the way here.
|
|
12
|
+
*
|
|
13
|
+
* The cost of that is the one thing to know when reading `status`: a restart
|
|
14
|
+
* mid-run leaves a record at `running` with nothing left to finish it. A run
|
|
15
|
+
* older than its budget window and still `running` is dead, not working.
|
|
16
|
+
*/
|
|
17
|
+
export interface VirtualUserRunRecord {
|
|
18
|
+
runId: string;
|
|
19
|
+
persona: string;
|
|
20
|
+
disposition: VirtualUserDisposition;
|
|
21
|
+
/** What makes a run replayable at all — a finding without it is an anecdote. */
|
|
22
|
+
seed: number;
|
|
23
|
+
/**
|
|
24
|
+
* `running` until the engine returns. Not derived from `finishedAt` being
|
|
25
|
+
* unset: a crashed run has no finish time either, and the two are not the
|
|
26
|
+
* same result.
|
|
27
|
+
*/
|
|
28
|
+
status: 'running' | 'completed' | 'failed';
|
|
29
|
+
/** The caller's situational goals, run alongside the derived intents. */
|
|
30
|
+
goals: string[];
|
|
31
|
+
/**
|
|
32
|
+
* Ids and slugs the user carried in, and whatever it learned on the way out.
|
|
33
|
+
* Kept because a finding only reproduces alongside the notes that produced it.
|
|
34
|
+
*/
|
|
35
|
+
memory: Record<string, string>;
|
|
36
|
+
findings: VirtualUserFinding[];
|
|
37
|
+
tally: VirtualUserTally | null;
|
|
38
|
+
/** Which budget or stopping rule ended the run. */
|
|
39
|
+
stoppedBy: string | null;
|
|
40
|
+
/**
|
|
41
|
+
* Why the run itself failed, as opposed to what it found. A run that could
|
|
42
|
+
* not start has no findings and is not a clean empty result.
|
|
43
|
+
*/
|
|
44
|
+
error: string | null;
|
|
45
|
+
/** The session that started it, where the host tracks one. */
|
|
46
|
+
startedBy: string | null;
|
|
47
|
+
createdAt: Date;
|
|
48
|
+
finishedAt: Date | null;
|
|
49
|
+
}
|
|
50
|
+
/** What a run is created with — everything else is filled in by the outcome. */
|
|
51
|
+
export interface VirtualUserRunStart {
|
|
52
|
+
persona: string;
|
|
53
|
+
disposition: VirtualUserDisposition;
|
|
54
|
+
seed: number;
|
|
55
|
+
goals?: readonly string[];
|
|
56
|
+
memory?: Record<string, string>;
|
|
57
|
+
startedBy?: string | null;
|
|
58
|
+
}
|
|
59
|
+
/** The outcome of a run that reached the end of its budget without throwing. */
|
|
60
|
+
export interface VirtualUserRunOutcome {
|
|
61
|
+
findings: readonly VirtualUserFinding[];
|
|
62
|
+
tally: VirtualUserTally;
|
|
63
|
+
memory: Record<string, string>;
|
|
64
|
+
stoppedBy: string | null;
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Where runs are kept. Declared here rather than in a database package so the
|
|
68
|
+
* scaffolded RPCs depend on the shape and not on kysely — `@pikku/kysely` ships
|
|
69
|
+
* one implementation, and an app with its own store satisfies this instead.
|
|
70
|
+
*
|
|
71
|
+
* SECURITY: findings from an `adversarial` run are working exploits carrying
|
|
72
|
+
* live ids. An implementation is a privileged store; the scaffold gates every
|
|
73
|
+
* read behind a scope for that reason, and a host exposing these records more
|
|
74
|
+
* widely is publishing its own exploits.
|
|
75
|
+
*/
|
|
76
|
+
export interface VirtualUserRunStore {
|
|
77
|
+
/** Records a run as `running` and returns its id. */
|
|
78
|
+
start(run: VirtualUserRunStart): Promise<string>;
|
|
79
|
+
/** Marks a run `completed` and stores what it found. */
|
|
80
|
+
complete(runId: string, outcome: VirtualUserRunOutcome): Promise<void>;
|
|
81
|
+
/** Marks a run `failed`. The run itself broke; it has no findings. */
|
|
82
|
+
fail(runId: string, error: string): Promise<void>;
|
|
83
|
+
get(runId: string): Promise<VirtualUserRunRecord | null>;
|
|
84
|
+
/** Newest first. `persona` narrows to one persona's history. */
|
|
85
|
+
list(options?: {
|
|
86
|
+
persona?: string;
|
|
87
|
+
limit?: number;
|
|
88
|
+
offset?: number;
|
|
89
|
+
}): Promise<VirtualUserRunRecord[]>;
|
|
90
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { ScenarioPersona } from '../../services/personas-service.js';
|
|
2
|
+
import type { VirtualUserTarget } from './virtual-user.types.js';
|
|
3
|
+
export interface PersonaTargetOptions {
|
|
4
|
+
/** Model the persona uses for its side of a conversation with an agent. */
|
|
5
|
+
model?: string;
|
|
6
|
+
/** Agents this user may talk to. Omit to leave `talkTo` unavailable. */
|
|
7
|
+
agents?: readonly string[];
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Drive a virtual user through a signed-in persona.
|
|
11
|
+
*
|
|
12
|
+
* This is the only place the engine meets the network. A persona already signs
|
|
13
|
+
* in as a real user over the app's own auth, keeps its cookies, re-logs-in when
|
|
14
|
+
* a session expires mid-run and reports a status as data rather than throwing —
|
|
15
|
+
* everything a user imitating a user needs, and none of it worth building twice.
|
|
16
|
+
*
|
|
17
|
+
* `invokeRaw` rather than `invoke` matters: to a virtual user a 403 is not an
|
|
18
|
+
* error, it is the system saying no, which is information it should be allowed
|
|
19
|
+
* to act on.
|
|
20
|
+
*/
|
|
21
|
+
export declare const personaVirtualUserTarget: (persona: ScenarioPersona, { model, agents }?: PersonaTargetOptions) => VirtualUserTarget;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Drive a virtual user through a signed-in persona.
|
|
3
|
+
*
|
|
4
|
+
* This is the only place the engine meets the network. A persona already signs
|
|
5
|
+
* in as a real user over the app's own auth, keeps its cookies, re-logs-in when
|
|
6
|
+
* a session expires mid-run and reports a status as data rather than throwing —
|
|
7
|
+
* everything a user imitating a user needs, and none of it worth building twice.
|
|
8
|
+
*
|
|
9
|
+
* `invokeRaw` rather than `invoke` matters: to a virtual user a 403 is not an
|
|
10
|
+
* error, it is the system saying no, which is information it should be allowed
|
|
11
|
+
* to act on.
|
|
12
|
+
*/
|
|
13
|
+
export const personaVirtualUserTarget = (persona, { model, agents } = {}) => ({
|
|
14
|
+
call: (rpcName, args) => persona.invokeRaw(rpcName, args),
|
|
15
|
+
talkTo: agents?.length
|
|
16
|
+
? async (agent, task) => {
|
|
17
|
+
if (!agents.includes(agent)) {
|
|
18
|
+
return {
|
|
19
|
+
passed: false,
|
|
20
|
+
reasoning: `There is no assistant called '${agent}'.`,
|
|
21
|
+
transcript: [],
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
return persona.converse({
|
|
25
|
+
agent,
|
|
26
|
+
task,
|
|
27
|
+
// A user asking for something judges the answer by whether they got
|
|
28
|
+
// what they asked for. There is no separate criterion to hold it to.
|
|
29
|
+
evaluate: `The assistant did what was asked: ${task}`,
|
|
30
|
+
model,
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
: undefined,
|
|
34
|
+
});
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import type { ScenarioHttpResponse } from '../../services/personas-service.js';
|
|
2
|
+
import type { ActorFlowVerdict } from '../actor-flow/actor-flow.types.js';
|
|
3
|
+
/**
|
|
4
|
+
* How a virtual user behaves, mechanically. A disposition changes the loop, the
|
|
5
|
+
* input generation, the memory and the oracle — anything that only changes how
|
|
6
|
+
* the user *talks* is persona prose (`ResolvedPersona.personality`) and does
|
|
7
|
+
* not belong here.
|
|
8
|
+
*
|
|
9
|
+
* - `realistic` — schema-first, goal-directed, plausible values (default).
|
|
10
|
+
* - `careless` — repeats, abandons, double-submits, boundary values.
|
|
11
|
+
* - `newcomer` — starts with empty memory and must discover everything.
|
|
12
|
+
* - `stale` — seeded from an earlier run's ids, some no longer valid.
|
|
13
|
+
* - `auditor` — pursues no goal; reads one truth from several places and compares.
|
|
14
|
+
* - `adversarial` — probes authorization and tenancy; a 2xx can be the finding.
|
|
15
|
+
* - `accountable` — pursues its goals for real; the only one production allows.
|
|
16
|
+
*
|
|
17
|
+
* `accountable` sits opposite `adversarial` on an *intent* axis — bad faith
|
|
18
|
+
* against good faith — where `careless` and `thorough` are a *care* axis. It is
|
|
19
|
+
* the one disposition whose actions carry consequences: no oracle, no rollback,
|
|
20
|
+
* and every call attributed to the persona in the audit log like anyone else's.
|
|
21
|
+
*/
|
|
22
|
+
export type VirtualUserDisposition = 'realistic' | 'careless' | 'newcomer' | 'stale' | 'auditor' | 'adversarial' | 'accountable';
|
|
23
|
+
/**
|
|
24
|
+
* The one disposition a production environment accepts.
|
|
25
|
+
*
|
|
26
|
+
* Every other disposition exists to find out what the product does wrong, which
|
|
27
|
+
* is not a thing to do to real customers' data. Named here so the declaration
|
|
28
|
+
* check and the sign-in check cannot drift apart.
|
|
29
|
+
*/
|
|
30
|
+
export declare const PRODUCTION_DISPOSITION: VirtualUserDisposition;
|
|
31
|
+
/**
|
|
32
|
+
* Hard caps the engine enforces itself. Anything the engine cannot count —
|
|
33
|
+
* money above all — belongs in {@link RunVirtualUserParams.stop} instead.
|
|
34
|
+
*/
|
|
35
|
+
export interface VirtualUserBudget {
|
|
36
|
+
/** Model turns, including ones that produced no call. */
|
|
37
|
+
steps?: number;
|
|
38
|
+
/** Non-read RPC calls. */
|
|
39
|
+
mutations?: number;
|
|
40
|
+
/** Wall clock, as ms or a duration string (`'30m'`). */
|
|
41
|
+
duration?: number | string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* The running count handed to {@link RunVirtualUserParams.stop}. Pikku collects
|
|
45
|
+
* it because only the engine sees every step; what it is *worth* is the app's,
|
|
46
|
+
* which is why no price or currency appears anywhere in core.
|
|
47
|
+
*/
|
|
48
|
+
export interface VirtualUserTally {
|
|
49
|
+
steps: number;
|
|
50
|
+
calls: number;
|
|
51
|
+
mutations: number;
|
|
52
|
+
tokensIn: number;
|
|
53
|
+
tokensOut: number;
|
|
54
|
+
model: string;
|
|
55
|
+
elapsedMs: number;
|
|
56
|
+
findings: number;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* One RPC as the virtual user sees it before reading its schema: enough to
|
|
60
|
+
* choose from, not enough to call with. The whole catalogue goes in the prompt,
|
|
61
|
+
* so this stays deliberately compact — a project with 430 RPCs renders to
|
|
62
|
+
* roughly 8k tokens, which is cheaper than any retrieval step and hides nothing.
|
|
63
|
+
*/
|
|
64
|
+
export interface ApiCatalogueEntry {
|
|
65
|
+
name: string;
|
|
66
|
+
/** Top-level input property names, for choosing between similar endpoints. */
|
|
67
|
+
inputKeys?: readonly string[];
|
|
68
|
+
/** Top-level output property names. */
|
|
69
|
+
outputKeys?: readonly string[];
|
|
70
|
+
description?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Whether the call only reads. `undefined` means nobody annotated it — which
|
|
73
|
+
* is not the same as safe, so the engine falls back to a name heuristic and
|
|
74
|
+
* reports how many entries it had to guess at.
|
|
75
|
+
*/
|
|
76
|
+
readonly?: boolean;
|
|
77
|
+
/** Declared by the app as needing a human's approval — denied by default. */
|
|
78
|
+
approvalRequired?: boolean;
|
|
79
|
+
/**
|
|
80
|
+
* Scopes the session must hold to call this, all of them.
|
|
81
|
+
*
|
|
82
|
+
* Splits the catalogue in two: what a persona's roles entitle it to reach,
|
|
83
|
+
* and what they do not. Scopes rather than permission-function names because
|
|
84
|
+
* a scope is declared and checkable, whereas a permission is arbitrary code
|
|
85
|
+
* whose verdict nobody can predict without running it.
|
|
86
|
+
*/
|
|
87
|
+
scopes?: readonly string[];
|
|
88
|
+
tags?: readonly string[];
|
|
89
|
+
/** JSON schema returned by `describe`, before the user may call. */
|
|
90
|
+
inputSchema?: Record<string, unknown>;
|
|
91
|
+
outputSchema?: Record<string, unknown>;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Where an intent comes from: a feature or scenario in the app's own words.
|
|
95
|
+
*
|
|
96
|
+
* Deliberately prose. The virtual user never receives the scenario's step graph
|
|
97
|
+
* — no rpc names, no `$ref` dataflow — because finding the API itself is the
|
|
98
|
+
* behaviour under test, and those graphs are a build-time artifact that no
|
|
99
|
+
* deployed stage carries.
|
|
100
|
+
*/
|
|
101
|
+
export interface IntentSource {
|
|
102
|
+
id: string;
|
|
103
|
+
title: string;
|
|
104
|
+
description?: string;
|
|
105
|
+
/** Step prose, as a person would be told it. Never rpc names. */
|
|
106
|
+
steps?: readonly string[];
|
|
107
|
+
tags?: readonly string[];
|
|
108
|
+
/** Persona ids this intent is available to. Empty means everyone. */
|
|
109
|
+
personas?: readonly string[];
|
|
110
|
+
}
|
|
111
|
+
/** Why the engine flagged something. */
|
|
112
|
+
export type VirtualUserFindingKind = 'server-error' | 'transport-error' | 'schema-violation' | 'unexpected-success' | 'custom';
|
|
113
|
+
/** Something worth a human's attention, found while imitating a user. */
|
|
114
|
+
export interface VirtualUserFinding {
|
|
115
|
+
kind: VirtualUserFindingKind;
|
|
116
|
+
detail: string;
|
|
117
|
+
rpcName?: string;
|
|
118
|
+
status?: number;
|
|
119
|
+
intentId?: string;
|
|
120
|
+
/** Step index within the run, so the transcript can be replayed to here. */
|
|
121
|
+
step: number;
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* The transport the virtual user acts through. HTTP in production (an
|
|
125
|
+
* `HttpPersona`), but the engine only sees this contract — which is what
|
|
126
|
+
* lets the whole loop be tested without a network.
|
|
127
|
+
*/
|
|
128
|
+
export interface VirtualUserTarget {
|
|
129
|
+
/** Invoke an RPC as this user, reporting the status as data rather than throwing. */
|
|
130
|
+
call(rpcName: string, args: unknown): Promise<ScenarioHttpResponse>;
|
|
131
|
+
/** Converse with an AI agent in persona. Omitted by apps that have no agents. */
|
|
132
|
+
talkTo?(agent: string, task: string): Promise<ActorFlowVerdict>;
|
|
133
|
+
/** Send a fixture file. Omitted by apps with no upload surface. */
|
|
134
|
+
upload?(file: string): Promise<ScenarioHttpResponse>;
|
|
135
|
+
}
|
|
136
|
+
/** What the model chose to do this turn. */
|
|
137
|
+
export type VirtualUserAction = {
|
|
138
|
+
kind: 'describe';
|
|
139
|
+
rpcName: string;
|
|
140
|
+
} | {
|
|
141
|
+
kind: 'call';
|
|
142
|
+
rpcName: string;
|
|
143
|
+
args?: unknown;
|
|
144
|
+
} | {
|
|
145
|
+
kind: 'talkTo';
|
|
146
|
+
agent: string;
|
|
147
|
+
task: string;
|
|
148
|
+
} | {
|
|
149
|
+
kind: 'upload';
|
|
150
|
+
file: string;
|
|
151
|
+
} | {
|
|
152
|
+
kind: 'complete';
|
|
153
|
+
summary?: string;
|
|
154
|
+
} | {
|
|
155
|
+
kind: 'stuck';
|
|
156
|
+
reason?: string;
|
|
157
|
+
};
|
|
158
|
+
/** How an intent ended, or that it has not. */
|
|
159
|
+
export type IntentStatus = 'open' | 'suspended' | 'completed' | 'abandoned' | 'stuck';
|
|
160
|
+
/** One intent's life within a run. */
|
|
161
|
+
export interface IntentRecord {
|
|
162
|
+
id: string;
|
|
163
|
+
sourceId: string;
|
|
164
|
+
title: string;
|
|
165
|
+
status: IntentStatus;
|
|
166
|
+
/** Step indices at which this intent was the active one. */
|
|
167
|
+
steps: number[];
|
|
168
|
+
/** How many times it was put down and picked back up. */
|
|
169
|
+
suspensions: number;
|
|
170
|
+
summary?: string;
|
|
171
|
+
}
|
|
172
|
+
/** One turn: what the engine scheduled, what the model did, what came back. */
|
|
173
|
+
export interface StepRecord {
|
|
174
|
+
index: number;
|
|
175
|
+
intentId?: string;
|
|
176
|
+
action: VirtualUserAction | {
|
|
177
|
+
kind: 'invalid';
|
|
178
|
+
detail: string;
|
|
179
|
+
};
|
|
180
|
+
status?: number;
|
|
181
|
+
ok?: boolean;
|
|
182
|
+
/** Truncated response text, so a run record stays readable. */
|
|
183
|
+
response?: string;
|
|
184
|
+
findingKinds?: VirtualUserFindingKind[];
|
|
185
|
+
tokensIn: number;
|
|
186
|
+
tokensOut: number;
|
|
187
|
+
}
|
|
188
|
+
/** Everything a run produced. Seeded, so it replays. */
|
|
189
|
+
export interface VirtualUserRunResult {
|
|
190
|
+
seed: number;
|
|
191
|
+
tally: VirtualUserTally;
|
|
192
|
+
findings: VirtualUserFinding[];
|
|
193
|
+
intents: IntentRecord[];
|
|
194
|
+
steps: StepRecord[];
|
|
195
|
+
/** Ids and slugs the user saw, for seeding a later `stale` run. */
|
|
196
|
+
memory: Record<string, string>;
|
|
197
|
+
/** Why the run ended. */
|
|
198
|
+
stoppedBy: 'no-intents' | 'budget-steps' | 'budget-mutations' | 'budget-duration' | 'stop-hook' | 'exhausted';
|
|
199
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The one disposition a production environment accepts.
|
|
3
|
+
*
|
|
4
|
+
* Every other disposition exists to find out what the product does wrong, which
|
|
5
|
+
* is not a thing to do to real customers' data. Named here so the declaration
|
|
6
|
+
* check and the sign-in check cannot drift apart.
|
|
7
|
+
*/
|
|
8
|
+
export const PRODUCTION_DISPOSITION = 'accountable';
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
*/
|
|
5
5
|
import type { StandardSchemaV1 } from '@standard-schema/spec';
|
|
6
6
|
import type { WorkflowRun } from '../workflow.types.js';
|
|
7
|
-
import type {
|
|
8
|
-
import type { ScenarioStepOptions, ScenarioStepPhase } from '../scenario-step.types.js';
|
|
7
|
+
import type { ScenarioPersona } from '../../../services/personas-service.js';
|
|
8
|
+
import type { ScenarioStepOptions, ScenarioStepPhase, ScenarioSurface } from '../scenario-step.types.js';
|
|
9
9
|
/**
|
|
10
10
|
* Workflow step options
|
|
11
11
|
*/
|
|
@@ -29,7 +29,7 @@ export interface WorkflowStepOptions {
|
|
|
29
29
|
* internally — so auth middleware and permissions are exercised end-to-end.
|
|
30
30
|
* The step is recorded durably like any RPC step.
|
|
31
31
|
*/
|
|
32
|
-
actor?:
|
|
32
|
+
actor?: ScenarioPersona;
|
|
33
33
|
}
|
|
34
34
|
/**
|
|
35
35
|
* Options for workflow.expectEventually() — a durable polling step used by
|
|
@@ -62,7 +62,7 @@ export type WorkflowWireDoRPC = <TOutput = any, TInput = any>(stepName: string,
|
|
|
62
62
|
*/
|
|
63
63
|
export type WorkflowWireDoInline = <T>(stepName: string, fn: () => Promise<T> | T, options?: WorkflowStepOptions) => Promise<T>;
|
|
64
64
|
/**
|
|
65
|
-
* Type signature for scenario.
|
|
65
|
+
* Type signature for scenario.given/when/then - used by inspector.
|
|
66
66
|
*
|
|
67
67
|
* Deliberately mirrors WorkflowWireDoRPC's shape: the target is a string, not
|
|
68
68
|
* an imported symbol, so the extractor reads it as a literal.
|
|
@@ -181,7 +181,7 @@ export interface RpcStepMeta {
|
|
|
181
181
|
expectEventually?: boolean;
|
|
182
182
|
}
|
|
183
183
|
/**
|
|
184
|
-
* Scenario step metadata — a call to `scenario.
|
|
184
|
+
* Scenario step metadata — a call to `scenario.given/when/then`.
|
|
185
185
|
*
|
|
186
186
|
* Distinct from RpcStepMeta on purpose: a step runs locally through
|
|
187
187
|
* runPikkuFunc and must never be treated as dispatchable on the queue/replay
|
|
@@ -194,7 +194,7 @@ export interface ScenarioStepMeta {
|
|
|
194
194
|
stepName: string;
|
|
195
195
|
/** Registered name of the step function being run */
|
|
196
196
|
stepFunc: string;
|
|
197
|
-
/** Which keyword the reporter prefixes —
|
|
197
|
+
/** Which keyword the reporter prefixes — Given, When or Then */
|
|
198
198
|
phase: ScenarioStepPhase;
|
|
199
199
|
/** Output variable name (if assigned) */
|
|
200
200
|
outputVar?: string;
|
|
@@ -204,8 +204,8 @@ export interface ScenarioStepMeta {
|
|
|
204
204
|
options?: WorkflowStepOptions;
|
|
205
205
|
/** Scenario actor name this step runs as ({ actor: actors.x }) */
|
|
206
206
|
actor?: string;
|
|
207
|
-
/** Mirrors the step function
|
|
208
|
-
|
|
207
|
+
/** Mirrors the surfaces the step function declares a binding for */
|
|
208
|
+
surfaces?: ScenarioSurface[];
|
|
209
209
|
}
|
|
210
210
|
/**
|
|
211
211
|
* Simple condition expression (leaf node)
|
|
@@ -484,18 +484,22 @@ export interface PikkuScenarioWire extends PikkuWorkflowWire {
|
|
|
484
484
|
/** Stub-assertion step: asserts `service.method` was called on the target server */
|
|
485
485
|
expectService: (stepName: string, serviceMethod: string, options?: WorkflowExpectServiceOptions) => Promise<void>;
|
|
486
486
|
/**
|
|
487
|
-
* Run a registered scenario step
|
|
488
|
-
*
|
|
489
|
-
*
|
|
487
|
+
* Run a registered scenario step, as the setup the scenario starts from.
|
|
488
|
+
*
|
|
489
|
+
* Shaped exactly like `do`'s RPC form — `(stepName, target, data, options)` —
|
|
490
|
+
* so the inspector reads the target as a string literal rather than resolving
|
|
491
|
+
* an imported symbol.
|
|
490
492
|
*
|
|
491
493
|
* The generated `TypedScenario` narrows these over `FlattenedScenarioStepMap`.
|
|
492
494
|
*/
|
|
493
|
-
step(stepName: string, stepFunc: string, data?: any, options?: ScenarioStepOptions): Promise<any>;
|
|
494
|
-
/** `step` with a "Given" prefix in the rendered prose */
|
|
495
495
|
given(stepName: string, stepFunc: string, data?: any, options?: ScenarioStepOptions): Promise<any>;
|
|
496
|
-
/** `
|
|
496
|
+
/** `when`: the same call as `given`, rendered as the action under test */
|
|
497
497
|
when(stepName: string, stepFunc: string, data?: any, options?: ScenarioStepOptions): Promise<any>;
|
|
498
|
-
/**
|
|
498
|
+
/**
|
|
499
|
+
* `then`: a claim about what the action left behind. Unlike `given`/`when`
|
|
500
|
+
* this is not prose alone — the step's bindings become witnesses, so every
|
|
501
|
+
* declared surface is observed and the observations must agree.
|
|
502
|
+
*/
|
|
499
503
|
then(stepName: string, stepFunc: string, data?: any, options?: ScenarioStepOptions): Promise<any>;
|
|
500
504
|
runScheduledTask: (name: string) => Promise<unknown>;
|
|
501
505
|
}
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { pikkuState } from '../../../pikku-state.js';
|
|
2
2
|
import { addFunction } from '../../../function/function-runner.js';
|
|
3
|
-
/**
|
|
4
|
-
* Add a workflow to the system
|
|
5
|
-
* This is called by the generated workflow wirings
|
|
6
|
-
*/
|
|
7
3
|
export const addWorkflow = (workflowName, workflowFunc, packageName = null) => {
|
|
8
4
|
const meta = pikkuState(packageName, 'workflows', 'meta');
|
|
9
5
|
const workflowMeta = meta[workflowName];
|