@pikku/core 0.12.107 → 0.12.111
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 +344 -0
- package/dist/analytics/analytics.d.ts +6 -0
- package/dist/analytics/analytics.js +58 -0
- package/dist/analytics/analytics.types.d.ts +156 -0
- package/dist/analytics/analytics.types.js +1 -0
- package/dist/analytics/anonymous-analytics-identity.d.ts +23 -0
- package/dist/analytics/anonymous-analytics-identity.js +27 -0
- package/dist/analytics/compose-analytics-identity.d.ts +14 -0
- package/dist/analytics/compose-analytics-identity.js +33 -0
- package/dist/analytics/cookie-analytics-identity.d.ts +24 -0
- package/dist/analytics/cookie-analytics-identity.js +37 -0
- package/dist/analytics/define-analytics-events.d.ts +22 -0
- package/dist/analytics/define-analytics-events.js +9 -0
- package/dist/analytics/fan-out-analytics.d.ts +15 -0
- package/dist/analytics/fan-out-analytics.js +36 -0
- package/dist/analytics/index.d.ts +13 -0
- package/dist/analytics/index.js +8 -0
- package/dist/analytics/logger-analytics-service.d.ts +14 -0
- package/dist/analytics/logger-analytics-service.js +23 -0
- package/dist/analytics/mint-cookie.d.ts +44 -0
- package/dist/analytics/mint-cookie.js +55 -0
- package/dist/errors/errors.d.ts +7 -0
- package/dist/errors/errors.js +17 -0
- package/dist/function/function-meta.types.d.ts +2 -0
- package/dist/function/function-runner.js +29 -0
- package/dist/function/functions.types.d.ts +22 -3
- package/dist/middleware/auth-apikey.d.ts +1 -1
- package/dist/pikku-state.d.ts +1 -1
- package/dist/scopes.d.ts +11 -0
- package/dist/scopes.js +17 -0
- package/dist/services/credential-wire-service.d.ts +1 -1
- package/dist/services/feature-flag-service.d.ts +100 -0
- package/dist/services/feature-flag-service.js +1 -0
- package/dist/services/index.d.ts +1 -0
- package/dist/services/meta-service.d.ts +16 -0
- package/dist/services/meta-service.js +19 -0
- package/dist/services/webhook-service.d.ts +7 -2
- package/dist/services/webhook-service.js +11 -6
- package/dist/testing/service-tests/agent-run-service-tests.d.ts +2 -2
- package/dist/testing/service-tests/agent-storage-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/channel-store-tests.d.ts +1 -1
- package/dist/testing/service-tests/credential-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/deployment-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/event-hub-store-tests.d.ts +1 -1
- package/dist/testing/service-tests/secret-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/session-store-tests.d.ts +1 -1
- package/dist/testing/service-tests/workflow-run-service-tests.d.ts +1 -1
- package/dist/testing/service-tests/workflow-service-tests.d.ts +1 -1
- package/dist/types/core.types.d.ts +23 -0
- package/dist/wirings/agent/agent-rpc.d.ts +1 -1
- package/dist/wirings/agent/agent-turn.d.ts +1 -1
- package/dist/wirings/agent-scorer/agent-scorer-live.d.ts +1 -1
- package/dist/wirings/channel/channel-common.d.ts +1 -1
- package/dist/wirings/channel/channel-rpc-validators.d.ts +2 -2
- package/dist/wirings/channel/channel-runner.d.ts +1 -1
- package/dist/wirings/channel/local/local-channel-runner.d.ts +1 -1
- package/dist/wirings/channel/serverless/serverless-channel-runner.d.ts +1 -1
- package/dist/wirings/cli/channel/cli-approval.d.ts +2 -2
- package/dist/wirings/flag/assert-feature-available.d.ts +15 -0
- package/dist/wirings/flag/assert-feature-available.js +23 -0
- package/dist/wirings/flag/cached-flag-source.d.ts +73 -0
- package/dist/wirings/flag/cached-flag-source.js +96 -0
- package/dist/wirings/flag/define-feature-flags.d.ts +33 -0
- package/dist/wirings/flag/define-feature-flags.js +32 -0
- package/dist/wirings/flag/flag.types.d.ts +97 -0
- package/dist/wirings/flag/flag.types.js +1 -0
- package/dist/wirings/flag/index.d.ts +7 -0
- package/dist/wirings/flag/index.js +5 -0
- package/dist/wirings/flag/resolve-flag.d.ts +52 -0
- package/dist/wirings/flag/resolve-flag.js +90 -0
- package/dist/wirings/flag/validate-flag-definitions.d.ts +26 -0
- package/dist/wirings/flag/validate-flag-definitions.js +103 -0
- package/dist/wirings/virtual-user/virtual-user-scaffold.d.ts +8 -8
- package/dist/wirings/virtual-user/virtual-user-schedule.d.ts +1 -1
- package/dist/wirings/workflow/workflow-queue-routing.d.ts +1 -1
- package/package.json +11 -5
- package/run-tests.sh +17 -9
- package/src/public-surface.json +26 -0
- package/src/agent-naming.test.ts +0 -68
- package/src/api-report.test.ts +0 -138
- package/src/app-alias-surface.test.ts +0 -179
- package/src/app-leaf-surface.test.ts +0 -222
- package/src/bootstrap-compat/root.ts +0 -20
- package/src/classification/column-form.test.ts +0 -97
- package/src/classification/column-form.ts +0 -55
- package/src/classification/data-classification.ts +0 -73
- package/src/classification/index.ts +0 -40
- package/src/classification/key-ids.ts +0 -2
- package/src/classification/secret-value.test.ts +0 -204
- package/src/classification/secret-value.ts +0 -106
- package/src/crypto-utils.test.ts +0 -668
- package/src/crypto-utils.ts +0 -460
- package/src/dev/hot-reload.test.ts +0 -587
- package/src/dev/hot-reload.ts +0 -225
- package/src/dev/module-runner.test.ts +0 -235
- package/src/dev/module-runner.ts +0 -138
- package/src/dev/reload-meta.test.ts +0 -183
- package/src/dev/reload-meta.ts +0 -144
- package/src/ecosystem-tier-removed.test.ts +0 -72
- package/src/env.ts +0 -1
- package/src/errors/error-handler.ts +0 -77
- package/src/errors/error.test.ts +0 -229
- package/src/errors/errors.ts +0 -393
- package/src/errors/index.ts +0 -11
- package/src/errors/serialized-error.ts +0 -12
- package/src/factory-functions.test.ts +0 -111
- package/src/function/abort-scope.test.ts +0 -97
- package/src/function/abort-scope.ts +0 -80
- package/src/function/function-meta.types.ts +0 -151
- package/src/function/function-runner.test.ts +0 -1619
- package/src/function/function-runner.ts +0 -499
- package/src/function/functions.types.ts +0 -319
- package/src/function/index.ts +0 -40
- package/src/function/list.types.test.ts +0 -100
- package/src/function/list.types.ts +0 -69
- package/src/function/pikku-request.test.ts +0 -35
- package/src/function/pikku-request.ts +0 -17
- package/src/gopass-secrets-removed.test.ts +0 -51
- package/src/handle-error.test.ts +0 -532
- package/src/handle-error.ts +0 -64
- package/src/middleware/auth-apikey.test.ts +0 -362
- package/src/middleware/auth-apikey.ts +0 -39
- package/src/middleware/auth-bearer.test.ts +0 -566
- package/src/middleware/auth-bearer.ts +0 -83
- package/src/middleware/auth-cookie.test.ts +0 -572
- package/src/middleware/auth-cookie.ts +0 -107
- package/src/middleware/cors.test.ts +0 -579
- package/src/middleware/cors.ts +0 -103
- package/src/middleware/index.ts +0 -30
- package/src/middleware/middleware-factories.ts +0 -76
- package/src/middleware/middleware.types.ts +0 -61
- package/src/middleware/remote-auth.test.ts +0 -547
- package/src/middleware/remote-auth.ts +0 -95
- package/src/middleware/remote-jobs-secret.ts +0 -35
- package/src/middleware/require-origin.test.ts +0 -115
- package/src/middleware/require-origin.ts +0 -79
- package/src/middleware/telemetry.ts +0 -83
- package/src/middleware-runner.test.ts +0 -578
- package/src/middleware-runner.ts +0 -232
- package/src/no-any-casts.test.ts +0 -57
- package/src/no-root-barrel.test.ts +0 -122
- package/src/permissions.test.ts +0 -256
- package/src/permissions.ts +0 -217
- package/src/pikku-state.test.ts +0 -198
- package/src/pikku-state.ts +0 -206
- package/src/production-barrels-stay-lean.test.ts +0 -110
- package/src/public-surface.test.ts +0 -133
- package/src/remote.test.ts +0 -173
- package/src/remote.ts +0 -56
- package/src/removed-legacy-exports.test.ts +0 -66
- package/src/run-tests-script.test.ts +0 -67
- package/src/schema.test.ts +0 -430
- package/src/schema.ts +0 -204
- package/src/scopes.test.ts +0 -203
- package/src/scopes.ts +0 -67
- package/src/services/agent-run-state-service.ts +0 -37
- package/src/services/agent-runner-service.ts +0 -238
- package/src/services/agent-storage-service.ts +0 -39
- package/src/services/ai-embedding-service.ts +0 -9
- package/src/services/audit-service.test.ts +0 -44
- package/src/services/audit-service.ts +0 -280
- package/src/services/content-service.ts +0 -65
- package/src/services/credential-service.ts +0 -20
- package/src/services/credential-wire-service.test.ts +0 -235
- package/src/services/credential-wire-service.ts +0 -120
- package/src/services/deployment-service.ts +0 -32
- package/src/services/email-service.test.ts +0 -100
- package/src/services/email-service.ts +0 -60
- package/src/services/email-template.test.ts +0 -311
- package/src/services/email-template.ts +0 -254
- package/src/services/file-scenario-run-store.test.ts +0 -349
- package/src/services/file-scenario-run-store.ts +0 -282
- package/src/services/gateway-service.ts +0 -5
- package/src/services/http-personas-converse.test.ts +0 -274
- package/src/services/http-personas.test.ts +0 -379
- package/src/services/http-personas.ts +0 -508
- package/src/services/in-memory-agent-run-state-service.ts +0 -87
- package/src/services/in-memory-queue-service.test.ts +0 -162
- package/src/services/in-memory-queue-service.ts +0 -78
- package/src/services/in-memory-session-store.test.ts +0 -58
- package/src/services/in-memory-session-store.ts +0 -20
- package/src/services/in-memory-trigger-service.ts +0 -47
- package/src/services/in-memory-workflow-service.test.ts +0 -430
- package/src/services/in-memory-workflow-service.ts +0 -595
- package/src/services/index.ts +0 -192
- package/src/services/istanbul-coverage-service.test.ts +0 -66
- package/src/services/istanbul-coverage-service.ts +0 -59
- package/src/services/jwt-service.ts +0 -15
- package/src/services/local-content-request-handler.test.ts +0 -240
- package/src/services/local-content-request-handler.ts +0 -295
- package/src/services/local-content.test.ts +0 -186
- package/src/services/local-content.ts +0 -242
- package/src/services/local-credential-service.ts +0 -63
- package/src/services/local-email-service.test.ts +0 -182
- package/src/services/local-email-service.ts +0 -43
- package/src/services/local-gateway-service.ts +0 -51
- package/src/services/local-secrets.test.ts +0 -95
- package/src/services/local-secrets.ts +0 -71
- package/src/services/local-variables.test.ts +0 -61
- package/src/services/local-variables.ts +0 -45
- package/src/services/logger-console.test.ts +0 -117
- package/src/services/logger-console.ts +0 -174
- package/src/services/logger.ts +0 -48
- package/src/services/meta-service.test.ts +0 -75
- package/src/services/meta-service.ts +0 -767
- package/src/services/persona-actor-secret.test.ts +0 -68
- package/src/services/persona-actor-secret.ts +0 -70
- package/src/services/persona-sign-in.test.ts +0 -219
- package/src/services/persona-sign-in.ts +0 -238
- package/src/services/personas-service.ts +0 -191
- package/src/services/pikku-user-id.test.ts +0 -62
- package/src/services/pikku-user-id.ts +0 -13
- package/src/services/queue-webhook-service.test.ts +0 -409
- package/src/services/queue-webhook-service.ts +0 -150
- package/src/services/remote-jobs.test.ts +0 -106
- package/src/services/remote-jobs.ts +0 -92
- package/src/services/scheduler-service.ts +0 -37
- package/src/services/schema-service.ts +0 -10
- package/src/services/scope-service.ts +0 -91
- package/src/services/scoped-credential-service.test.ts +0 -86
- package/src/services/scoped-credential-service.ts +0 -63
- package/src/services/scoped-secret-service.test.ts +0 -93
- package/src/services/scoped-secret-service.ts +0 -40
- package/src/services/secret-host-binding.test.ts +0 -138
- package/src/services/secret-host-binding.ts +0 -51
- package/src/services/secret-service.ts +0 -25
- package/src/services/secretless.test.ts +0 -54
- package/src/services/secretless.ts +0 -29
- package/src/services/session-store.ts +0 -9
- package/src/services/stub-tracker.test.ts +0 -104
- package/src/services/stub-tracker.ts +0 -175
- package/src/services/system-role-guard.test.ts +0 -96
- package/src/services/system-role-guard.ts +0 -71
- package/src/services/temporary-file-service.ts +0 -76
- package/src/services/trigger-service.ts +0 -5
- package/src/services/typed-credential-service.ts +0 -83
- package/src/services/typed-secret-service.test.ts +0 -204
- package/src/services/typed-secret-service.ts +0 -132
- package/src/services/typed-variables-service.test.ts +0 -166
- package/src/services/typed-variables-service.ts +0 -166
- package/src/services/user-session-service.test.ts +0 -147
- package/src/services/user-session-service.ts +0 -85
- package/src/services/v8-coverage-service.test.ts +0 -69
- package/src/services/v8-coverage-service.ts +0 -163
- package/src/services/variables-service.ts +0 -13
- package/src/services/webhook-service.ts +0 -147
- package/src/services/workflow-service.ts +0 -120
- package/src/side-effects-are-declared.test.ts +0 -84
- package/src/source-files-stay-composable.test.ts +0 -41
- package/src/template-alias-surface.test.ts +0 -240
- package/src/test-utils.ts +0 -38
- package/src/testing/index.ts +0 -3
- package/src/testing/service-tests/agent-run-service-tests.ts +0 -98
- package/src/testing/service-tests/agent-storage-service-tests.ts +0 -379
- package/src/testing/service-tests/channel-store-tests.ts +0 -98
- package/src/testing/service-tests/credential-service-tests.ts +0 -143
- package/src/testing/service-tests/deployment-service-tests.ts +0 -33
- package/src/testing/service-tests/event-hub-store-tests.ts +0 -48
- package/src/testing/service-tests/secret-service-tests.ts +0 -105
- package/src/testing/service-tests/session-store-tests.ts +0 -62
- package/src/testing/service-tests/workflow-run-service-tests.ts +0 -59
- package/src/testing/service-tests/workflow-service-tests.ts +0 -308
- package/src/testing/service-tests.ts +0 -95
- package/src/time-utils.test.ts +0 -56
- package/src/time-utils.ts +0 -89
- package/src/types/core.types.ts +0 -446
- package/src/types/index.ts +0 -25
- package/src/types/state.types.ts +0 -226
- package/src/types/typed-credentials.test.ts +0 -72
- package/src/utils/hash.test.ts +0 -68
- package/src/utils/hash.ts +0 -26
- package/src/utils/hmac.ts +0 -21
- package/src/utils/node-host-resolver.ts +0 -20
- package/src/utils/safe-fetch.test.ts +0 -515
- package/src/utils/safe-fetch.ts +0 -347
- package/src/utils.test.ts +0 -359
- package/src/utils.ts +0 -165
- package/src/version.test.ts +0 -80
- package/src/version.ts +0 -25
- package/src/wirings/actor-flow/actor-flow.types.ts +0 -40
- package/src/wirings/actor-flow/index.ts +0 -10
- package/src/wirings/actor-flow/run-conversation.test.ts +0 -187
- package/src/wirings/actor-flow/run-conversation.ts +0 -280
- package/src/wirings/addon/addon-auth-tags.test.ts +0 -219
- package/src/wirings/addon/addon-runner.ts +0 -236
- package/src/wirings/addon/addon-scopes.test.ts +0 -225
- package/src/wirings/addon/addon-secrets.test.ts +0 -391
- package/src/wirings/addon/index.ts +0 -12
- package/src/wirings/addon/remote-addon-auth.ts +0 -65
- package/src/wirings/addon/wire-addon.test.ts +0 -102
- package/src/wirings/addon/wire-addon.ts +0 -202
- package/src/wirings/addon/wire-remote-addon.ts +0 -41
- package/src/wirings/agent/agent-agui.test.ts +0 -1213
- package/src/wirings/agent/agent-agui.ts +0 -405
- package/src/wirings/agent/agent-authorization.test.ts +0 -208
- package/src/wirings/agent/agent-finalize.test.ts +0 -187
- package/src/wirings/agent/agent-finalize.ts +0 -197
- package/src/wirings/agent/agent-helpers.test.ts +0 -215
- package/src/wirings/agent/agent-helpers.ts +0 -96
- package/src/wirings/agent/agent-interrupt.test.ts +0 -833
- package/src/wirings/agent/agent-interrupt.ts +0 -400
- package/src/wirings/agent/agent-memory.test.ts +0 -397
- package/src/wirings/agent/agent-memory.ts +0 -496
- package/src/wirings/agent/agent-middleware.types.test.ts +0 -41
- package/src/wirings/agent/agent-model-config.test.ts +0 -103
- package/src/wirings/agent/agent-model-config.ts +0 -59
- package/src/wirings/agent/agent-prepare.test.ts +0 -977
- package/src/wirings/agent/agent-prepare.ts +0 -1083
- package/src/wirings/agent/agent-registry.test.ts +0 -455
- package/src/wirings/agent/agent-registry.ts +0 -99
- package/src/wirings/agent/agent-resume-authorization.test.ts +0 -206
- package/src/wirings/agent/agent-rpc.ts +0 -116
- package/src/wirings/agent/agent-runner.test.ts +0 -1229
- package/src/wirings/agent/agent-runner.ts +0 -858
- package/src/wirings/agent/agent-stream-delegate.test.ts +0 -381
- package/src/wirings/agent/agent-stream-output-hooks.test.ts +0 -353
- package/src/wirings/agent/agent-stream.test.ts +0 -1800
- package/src/wirings/agent/agent-stream.ts +0 -1639
- package/src/wirings/agent/agent-thread-ownership.test.ts +0 -297
- package/src/wirings/agent/agent-turn.test.ts +0 -65
- package/src/wirings/agent/agent-turn.ts +0 -122
- package/src/wirings/agent/agent-utils.ts +0 -20
- package/src/wirings/agent/agent.types.ts +0 -676
- package/src/wirings/agent/index.ts +0 -58
- package/src/wirings/agent/voice-input.test.ts +0 -220
- package/src/wirings/agent/voice-input.ts +0 -180
- package/src/wirings/agent/voice-output.test.ts +0 -510
- package/src/wirings/agent/voice-output.ts +0 -311
- package/src/wirings/agent-scorer/agent-scorer-grade.test.ts +0 -106
- package/src/wirings/agent-scorer/agent-scorer-grade.ts +0 -55
- package/src/wirings/agent-scorer/agent-scorer-judge.test.ts +0 -285
- package/src/wirings/agent-scorer/agent-scorer-judge.ts +0 -180
- package/src/wirings/agent-scorer/agent-scorer-live.test.ts +0 -174
- package/src/wirings/agent-scorer/agent-scorer-live.ts +0 -56
- package/src/wirings/agent-scorer/agent-scorer-registry.ts +0 -66
- package/src/wirings/agent-scorer/agent-scorer-sampling.test.ts +0 -34
- package/src/wirings/agent-scorer/agent-scorer-sampling.ts +0 -36
- package/src/wirings/agent-scorer/agent-scorer-snapshots.test.ts +0 -49
- package/src/wirings/agent-scorer/agent-scorer-snapshots.ts +0 -46
- package/src/wirings/agent-scorer/agent-scorer-worker.test.ts +0 -122
- package/src/wirings/agent-scorer/agent-scorer-worker.ts +0 -71
- package/src/wirings/agent-scorer/agent-scorer.ts +0 -102
- package/src/wirings/agent-scorer/agent-scorer.types.ts +0 -128
- package/src/wirings/agent-scorer/index.ts +0 -23
- package/src/wirings/channel/channel-common.ts +0 -102
- package/src/wirings/channel/channel-handler-shapes.test.ts +0 -72
- package/src/wirings/channel/channel-handler.test.ts +0 -322
- package/src/wirings/channel/channel-handler.ts +0 -259
- package/src/wirings/channel/channel-host-rpc.test.ts +0 -150
- package/src/wirings/channel/channel-host-rpc.ts +0 -69
- package/src/wirings/channel/channel-middleware-runner.test.ts +0 -188
- package/src/wirings/channel/channel-middleware-runner.ts +0 -126
- package/src/wirings/channel/channel-rpc-registry.ts +0 -116
- package/src/wirings/channel/channel-rpc-responder.ts +0 -117
- package/src/wirings/channel/channel-rpc-service.ts +0 -132
- package/src/wirings/channel/channel-rpc-validators.ts +0 -65
- package/src/wirings/channel/channel-rpc.test.ts +0 -841
- package/src/wirings/channel/channel-rpc.ts +0 -5
- package/src/wirings/channel/channel-rpc.types.ts +0 -160
- package/src/wirings/channel/channel-runner.ts +0 -164
- package/src/wirings/channel/channel-store.ts +0 -35
- package/src/wirings/channel/channel.types.ts +0 -193
- package/src/wirings/channel/define-channel-routes.ts +0 -5
- package/src/wirings/channel/eventhub-service.ts +0 -16
- package/src/wirings/channel/eventhub-store.ts +0 -13
- package/src/wirings/channel/index.ts +0 -40
- package/src/wirings/channel/local/index.ts +0 -3
- package/src/wirings/channel/local/local-channel-handler.ts +0 -98
- package/src/wirings/channel/local/local-channel-runner.test.ts +0 -339
- package/src/wirings/channel/local/local-channel-runner.ts +0 -271
- package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -77
- package/src/wirings/channel/local/local-eventhub-service.ts +0 -69
- package/src/wirings/channel/log-channels.ts +0 -16
- package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +0 -135
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +0 -60
- package/src/wirings/channel/serverless/index.ts +0 -6
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +0 -328
- package/src/wirings/cli/channel/cli-approval.test.ts +0 -177
- package/src/wirings/cli/channel/cli-approval.ts +0 -135
- package/src/wirings/cli/channel/cli-channel-runner.ts +0 -118
- package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +0 -192
- package/src/wirings/cli/channel/cli-raw-channel-runner.ts +0 -148
- package/src/wirings/cli/channel/cli-raw-client-runner.test.ts +0 -480
- package/src/wirings/cli/channel/cli-raw-client-runner.ts +0 -188
- package/src/wirings/cli/channel/index.ts +0 -6
- package/src/wirings/cli/cli-runner.test.ts +0 -969
- package/src/wirings/cli/cli-runner.ts +0 -538
- package/src/wirings/cli/cli.types.ts +0 -388
- package/src/wirings/cli/command-parser.test.ts +0 -1120
- package/src/wirings/cli/command-parser.ts +0 -713
- package/src/wirings/cli/define-cli-commands.ts +0 -13
- package/src/wirings/cli/format-cli-error.test.ts +0 -91
- package/src/wirings/cli/format-cli-error.ts +0 -96
- package/src/wirings/cli/index.ts +0 -19
- package/src/wirings/credential/credential.types.ts +0 -37
- package/src/wirings/credential/define-credential.ts +0 -49
- package/src/wirings/credential/index.ts +0 -7
- package/src/wirings/credential/validate-credential-definitions.ts +0 -63
- package/src/wirings/gateway/gateway-authorization.test.ts +0 -575
- package/src/wirings/gateway/gateway-channel-meta.test.ts +0 -44
- package/src/wirings/gateway/gateway-runner.test.ts +0 -581
- package/src/wirings/gateway/gateway-runner.ts +0 -411
- package/src/wirings/gateway/gateway.types.ts +0 -137
- package/src/wirings/gateway/index.ts +0 -15
- package/src/wirings/http/http-routes.test.ts +0 -318
- package/src/wirings/http/http-routes.ts +0 -111
- package/src/wirings/http/http-runner-addon-ref.test.ts +0 -238
- package/src/wirings/http/http-runner.test.ts +0 -503
- package/src/wirings/http/http-runner.ts +0 -462
- package/src/wirings/http/http.types.ts +0 -307
- package/src/wirings/http/index.ts +0 -27
- package/src/wirings/http/log-http-routes.ts +0 -18
- package/src/wirings/http/pikku-fetch-http-request.test.ts +0 -318
- package/src/wirings/http/pikku-fetch-http-request.ts +0 -260
- package/src/wirings/http/pikku-fetch-http-response.test.ts +0 -123
- package/src/wirings/http/pikku-fetch-http-response.ts +0 -149
- package/src/wirings/http/routers/http-router.ts +0 -13
- package/src/wirings/http/routers/path-to-regex.test.ts +0 -306
- package/src/wirings/http/routers/path-to-regex.ts +0 -115
- package/src/wirings/http/web-request.test.ts +0 -382
- package/src/wirings/http/web-request.ts +0 -162
- package/src/wirings/mcp/index.ts +0 -26
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -388
- package/src/wirings/mcp/mcp-endpoint-registry.ts +0 -159
- package/src/wirings/mcp/mcp-runner.test.ts +0 -588
- package/src/wirings/mcp/mcp-runner.ts +0 -330
- package/src/wirings/mcp/mcp.types.ts +0 -199
- package/src/wirings/node/index.ts +0 -2
- package/src/wirings/node/node.types.ts +0 -23
- package/src/wirings/oauth2/index.ts +0 -1
- package/src/wirings/oauth2/oauth2.types.ts +0 -12
- package/src/wirings/persona/define-personas.ts +0 -33
- package/src/wirings/persona/index.ts +0 -75
- package/src/wirings/persona/persona-app-scopes.test.ts +0 -47
- package/src/wirings/persona/persona-app-scopes.ts +0 -74
- package/src/wirings/persona/persona-email.ts +0 -87
- package/src/wirings/persona/persona-environments.test.ts +0 -194
- package/src/wirings/persona/persona-environments.ts +0 -138
- package/src/wirings/persona/persona-mailbox.ts +0 -156
- package/src/wirings/persona/persona.test.ts +0 -230
- package/src/wirings/persona/persona.types.ts +0 -156
- package/src/wirings/persona/validate-personas.ts +0 -137
- package/src/wirings/queue/index.ts +0 -29
- package/src/wirings/queue/queue-identity.test.ts +0 -454
- package/src/wirings/queue/queue-identity.ts +0 -176
- package/src/wirings/queue/queue-runner.test.ts +0 -705
- package/src/wirings/queue/queue-runner.ts +0 -181
- package/src/wirings/queue/queue.types.ts +0 -161
- package/src/wirings/queue/register-queue-helper.ts +0 -46
- package/src/wirings/queue/signed-queue-service.ts +0 -60
- package/src/wirings/queue/validate-worker-config.test.ts +0 -108
- package/src/wirings/queue/validate-worker-config.ts +0 -90
- package/src/wirings/role/define-system-role.ts +0 -33
- package/src/wirings/role/index.ts +0 -13
- package/src/wirings/role/role.test.ts +0 -104
- package/src/wirings/role/role.types.ts +0 -47
- package/src/wirings/role/validate-role-definitions.ts +0 -93
- package/src/wirings/rpc/index.ts +0 -8
- package/src/wirings/rpc/rpc-runner.test.ts +0 -1130
- package/src/wirings/rpc/rpc-runner.ts +0 -569
- package/src/wirings/rpc/rpc-types.ts +0 -87
- package/src/wirings/scheduler/index.ts +0 -11
- package/src/wirings/scheduler/log-schedulers.ts +0 -16
- package/src/wirings/scheduler/scheduler-runner.test.ts +0 -835
- package/src/wirings/scheduler/scheduler-runner.ts +0 -138
- package/src/wirings/scheduler/scheduler.types.ts +0 -42
- package/src/wirings/scope/define-scope.ts +0 -33
- package/src/wirings/scope/index.ts +0 -15
- package/src/wirings/scope/scope.test.ts +0 -159
- package/src/wirings/scope/scope.types.ts +0 -42
- package/src/wirings/scope/validate-scope-definitions.ts +0 -107
- package/src/wirings/secret/index.ts +0 -9
- package/src/wirings/secret/secret.types.ts +0 -70
- package/src/wirings/secret/validate-secret-definitions.test.ts +0 -232
- package/src/wirings/secret/validate-secret-definitions.ts +0 -88
- package/src/wirings/trigger/index.ts +0 -9
- package/src/wirings/trigger/pikku-trigger-service.ts +0 -107
- package/src/wirings/trigger/trigger-runner.test.ts +0 -78
- package/src/wirings/trigger/trigger-runner.ts +0 -113
- package/src/wirings/trigger/trigger.types.ts +0 -100
- package/src/wirings/variable/index.ts +0 -8
- package/src/wirings/variable/validate-variable-definitions.test.ts +0 -115
- package/src/wirings/variable/validate-variable-definitions.ts +0 -71
- package/src/wirings/variable/variable.types.ts +0 -40
- package/src/wirings/virtual-user/index.ts +0 -107
- package/src/wirings/virtual-user/prepare-virtual-user-run.test.ts +0 -115
- package/src/wirings/virtual-user/prepare-virtual-user-run.ts +0 -95
- package/src/wirings/virtual-user/run-virtual-user.test.ts +0 -774
- package/src/wirings/virtual-user/run-virtual-user.ts +0 -684
- package/src/wirings/virtual-user/virtual-user-agents.test.ts +0 -72
- package/src/wirings/virtual-user/virtual-user-agents.ts +0 -62
- package/src/wirings/virtual-user/virtual-user-catalogue.test.ts +0 -215
- package/src/wirings/virtual-user/virtual-user-catalogue.ts +0 -184
- package/src/wirings/virtual-user/virtual-user-derive.test.ts +0 -426
- package/src/wirings/virtual-user/virtual-user-derive.ts +0 -161
- package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +0 -68
- package/src/wirings/virtual-user/virtual-user-dispositions.ts +0 -210
- package/src/wirings/virtual-user/virtual-user-intents.test.ts +0 -218
- package/src/wirings/virtual-user/virtual-user-intents.ts +0 -185
- package/src/wirings/virtual-user/virtual-user-rng.test.ts +0 -72
- package/src/wirings/virtual-user/virtual-user-rng.ts +0 -50
- package/src/wirings/virtual-user/virtual-user-run-store.ts +0 -131
- package/src/wirings/virtual-user/virtual-user-scaffold.test.ts +0 -854
- package/src/wirings/virtual-user/virtual-user-scaffold.ts +0 -664
- package/src/wirings/virtual-user/virtual-user-schedule-store.ts +0 -93
- package/src/wirings/virtual-user/virtual-user-schedule.test.ts +0 -280
- package/src/wirings/virtual-user/virtual-user-schedule.ts +0 -156
- package/src/wirings/virtual-user/virtual-user-target.ts +0 -47
- package/src/wirings/virtual-user/virtual-user.types.ts +0 -215
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +0 -709
- package/src/wirings/workflow/dsl/workflow-runner.ts +0 -25
- package/src/wirings/workflow/feature.test.ts +0 -131
- package/src/wirings/workflow/feature.ts +0 -59
- package/src/wirings/workflow/graph/graph-foreach-queued.test.ts +0 -569
- package/src/wirings/workflow/graph/graph-foreach.test.ts +0 -626
- package/src/wirings/workflow/graph/graph-node.ts +0 -115
- package/src/wirings/workflow/graph/graph-runner.test.ts +0 -1049
- package/src/wirings/workflow/graph/graph-runner.ts +0 -1376
- package/src/wirings/workflow/graph/graph-validation.test.ts +0 -27
- package/src/wirings/workflow/graph/graph-validation.ts +0 -41
- package/src/wirings/workflow/graph/template.test.ts +0 -49
- package/src/wirings/workflow/graph/template.ts +0 -42
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -39
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -75
- package/src/wirings/workflow/index.ts +0 -107
- package/src/wirings/workflow/pikku-scenario-service.ts +0 -1013
- package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -963
- package/src/wirings/workflow/pikku-workflow-service.ts +0 -1993
- package/src/wirings/workflow/run-timeline.test.ts +0 -199
- package/src/wirings/workflow/run-timeline.ts +0 -185
- package/src/wirings/workflow/scenario-cookie-jar.test.ts +0 -107
- package/src/wirings/workflow/scenario-cookie-jar.ts +0 -57
- package/src/wirings/workflow/scenario-expectations.test.ts +0 -238
- package/src/wirings/workflow/scenario-hooks.test.ts +0 -259
- package/src/wirings/workflow/scenario-poll.test.ts +0 -64
- package/src/wirings/workflow/scenario-poll.ts +0 -27
- package/src/wirings/workflow/scenario-prose.test.ts +0 -275
- package/src/wirings/workflow/scenario-prose.ts +0 -86
- package/src/wirings/workflow/scenario-run.types.ts +0 -193
- package/src/wirings/workflow/scenario-service.test.ts +0 -147
- package/src/wirings/workflow/scenario-step-guards.ts +0 -23
- package/src/wirings/workflow/scenario-step.test.ts +0 -800
- package/src/wirings/workflow/scenario-step.types.ts +0 -262
- package/src/wirings/workflow/scenario-surface.test.ts +0 -146
- package/src/wirings/workflow/scenario-surface.ts +0 -71
- package/src/wirings/workflow/scenario.types.ts +0 -63
- package/src/wirings/workflow/workflow-approval-audit.ts +0 -47
- package/src/wirings/workflow/workflow-approval-policy.test.ts +0 -594
- package/src/wirings/workflow/workflow-approval-policy.ts +0 -68
- package/src/wirings/workflow/workflow-approval.ts +0 -290
- package/src/wirings/workflow/workflow-child-run-session.test.ts +0 -168
- package/src/wirings/workflow/workflow-constants.ts +0 -66
- package/src/wirings/workflow/workflow-dispatch-durability.test.ts +0 -116
- package/src/wirings/workflow/workflow-dispatch-payload.test.ts +0 -55
- package/src/wirings/workflow/workflow-dispatch-relay.test.ts +0 -128
- package/src/wirings/workflow/workflow-errors.ts +0 -132
- package/src/wirings/workflow/workflow-inline-authority.test.ts +0 -175
- package/src/wirings/workflow/workflow-invocation-id.test.ts +0 -51
- package/src/wirings/workflow/workflow-invocation-id.ts +0 -28
- package/src/wirings/workflow/workflow-meta-resolver.ts +0 -45
- package/src/wirings/workflow/workflow-mirror.test.ts +0 -171
- package/src/wirings/workflow/workflow-missing-meta.test.ts +0 -92
- package/src/wirings/workflow/workflow-on-error.test.ts +0 -145
- package/src/wirings/workflow/workflow-queue-routing.ts +0 -129
- package/src/wirings/workflow/workflow-queue-wiring.ts +0 -149
- package/src/wirings/workflow/workflow-queue-workers.test.ts +0 -131
- package/src/wirings/workflow/workflow-queue-workers.ts +0 -66
- package/src/wirings/workflow/workflow-recovery.ts +0 -192
- package/src/wirings/workflow/workflow-replay-snapshot.test.ts +0 -140
- package/src/wirings/workflow/workflow-retry-policy.test.ts +0 -113
- package/src/wirings/workflow/workflow-run-authority.test.ts +0 -212
- package/src/wirings/workflow/workflow-run-context.test.ts +0 -172
- package/src/wirings/workflow/workflow-run-engine.types.ts +0 -92
- package/src/wirings/workflow/workflow-run-ownership.ts +0 -37
- package/src/wirings/workflow/workflow-run-polling.test.ts +0 -127
- package/src/wirings/workflow/workflow-stalled-recovery.test.ts +0 -152
- package/src/wirings/workflow/workflow-status-stream.test.ts +0 -354
- package/src/wirings/workflow/workflow-status-stream.ts +0 -144
- package/src/wirings/workflow/workflow-step-claim.ts +0 -46
- package/src/wirings/workflow/workflow-step-ordinal.test.ts +0 -94
- package/src/wirings/workflow/workflow-step-session.test.ts +0 -87
- package/src/wirings/workflow/workflow-suspend.ts +0 -61
- package/src/wirings/workflow/workflow-terminal-run-guard.test.ts +0 -105
- package/src/wirings/workflow/workflow.types.ts +0 -268
- package/src/wirings-stay-decoupled.test.ts +0 -130
- package/tsconfig.json +0 -14
- package/tsconfig.tsbuildinfo +0 -1
- package/tsconfig.type-tests.json +0 -15
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { compiledFallbackSnapshot } from './validate-flag-definitions.js';
|
|
2
|
+
const DEFAULT_TTL_MS = 30_000;
|
|
3
|
+
/**
|
|
4
|
+
* The caching every flag source needs, so no adapter has to get it right twice.
|
|
5
|
+
*
|
|
6
|
+
* Three layers, in descending order of truth: a fresh read, the last good read,
|
|
7
|
+
* and the compiled declaration. The middle layer is the one that matters —
|
|
8
|
+
* dropping straight to the compiled fallback on a blip would switch on every
|
|
9
|
+
* flag an operator had deliberately left off, which is the opposite of what a
|
|
10
|
+
* dark launch is for. The compiled fallback is reached only on a cold start
|
|
11
|
+
* that has never managed a read, where there is nothing better to say.
|
|
12
|
+
*
|
|
13
|
+
* Refresh is pull-on-demand rather than a background poller on purpose. A
|
|
14
|
+
* poller assumes a long-lived process; an isolate on a serverless runtime is
|
|
15
|
+
* neither long-lived nor allowed to hold a timer between requests, so a vendor
|
|
16
|
+
* SDK built around one either never refreshes or leaks. Fetching inside the
|
|
17
|
+
* request that noticed the snapshot was stale works in both places.
|
|
18
|
+
*/
|
|
19
|
+
export class CachedFlagSource {
|
|
20
|
+
cached;
|
|
21
|
+
cachedAt = 0;
|
|
22
|
+
inflight;
|
|
23
|
+
/**
|
|
24
|
+
* Bumped by every `invalidate()`. A read that started before the signal
|
|
25
|
+
* arrived carries the generation it started in, and stores nothing if that
|
|
26
|
+
* generation is no longer current — otherwise a webhook that landed
|
|
27
|
+
* mid-fetch would be answered by the pre-webhook snapshot, stamped fresh,
|
|
28
|
+
* and the kill switch would sit stale for another whole TTL.
|
|
29
|
+
*/
|
|
30
|
+
generation = 0;
|
|
31
|
+
fallback;
|
|
32
|
+
declared;
|
|
33
|
+
ttlMs;
|
|
34
|
+
constructor(options = {}) {
|
|
35
|
+
this.ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;
|
|
36
|
+
this.declared = options.declared ?? [];
|
|
37
|
+
this.fallback = compiledFallbackSnapshot(this.declared);
|
|
38
|
+
}
|
|
39
|
+
/** Replaces the cold-start fallback, once the declared set is known. */
|
|
40
|
+
setDeclared(declared) {
|
|
41
|
+
this.declared = declared;
|
|
42
|
+
this.fallback = compiledFallbackSnapshot(declared);
|
|
43
|
+
}
|
|
44
|
+
declaredFlags() {
|
|
45
|
+
return this.declared;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Drops the cache, so the next read goes to the store.
|
|
49
|
+
*
|
|
50
|
+
* Public because the signal usually arrives from outside: PostHog and Unleash
|
|
51
|
+
* both emit a webhook on a flag change, and an HTTP wiring that receives one
|
|
52
|
+
* calls this to cut the kill-switch latency from the TTL to delivery time. A
|
|
53
|
+
* LaunchDarkly stream is the same call from a held-open connection rather
|
|
54
|
+
* than a request.
|
|
55
|
+
*
|
|
56
|
+
* It does not fetch. An eager refetch makes a burst of webhooks N round
|
|
57
|
+
* trips, and on a serverless runtime the isolate that received the signal may
|
|
58
|
+
* be gone before anything reads the result. The request that next notices the
|
|
59
|
+
* cache is empty pays for the read, and it is the one that needs it.
|
|
60
|
+
*/
|
|
61
|
+
invalidate() {
|
|
62
|
+
this.cachedAt = 0;
|
|
63
|
+
this.generation++;
|
|
64
|
+
this.inflight = undefined;
|
|
65
|
+
}
|
|
66
|
+
async snapshot() {
|
|
67
|
+
if (this.cached && Date.now() - this.cachedAt < this.ttlMs) {
|
|
68
|
+
return this.cached;
|
|
69
|
+
}
|
|
70
|
+
if (!this.inflight) {
|
|
71
|
+
const generation = this.generation;
|
|
72
|
+
const read = this.fetchSnapshot().then((snapshot) => {
|
|
73
|
+
if (generation === this.generation) {
|
|
74
|
+
this.cached = snapshot;
|
|
75
|
+
this.cachedAt = Date.now();
|
|
76
|
+
if (this.inflight === read) {
|
|
77
|
+
this.inflight = undefined;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return snapshot;
|
|
81
|
+
});
|
|
82
|
+
read.catch(() => {
|
|
83
|
+
if (this.inflight === read) {
|
|
84
|
+
this.inflight = undefined;
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
this.inflight = read;
|
|
88
|
+
}
|
|
89
|
+
try {
|
|
90
|
+
return await this.inflight;
|
|
91
|
+
}
|
|
92
|
+
catch {
|
|
93
|
+
return this.cached ?? this.fallback;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { CoreFeatureFlags } from './flag.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* No-op function for declaring feature flags.
|
|
4
|
+
* This exists purely for TypeScript type checking and will be tree-shaken.
|
|
5
|
+
* The CLI extracts metadata via AST parsing and generates a `FeatureFlagName`
|
|
6
|
+
* union, so `flags.calList` is a compile error rather than a silent `false`.
|
|
7
|
+
*
|
|
8
|
+
* That typing is load-bearing rather than a convenience: flags fail closed, so
|
|
9
|
+
* a typo'd flag reads `false`, hides its feature permanently, and leaves every
|
|
10
|
+
* test, screenshot and gate green. An untyped key makes a missing product
|
|
11
|
+
* indistinguishable from a working one.
|
|
12
|
+
*
|
|
13
|
+
* Removal is deliberately not destructive. Deleting a declaration leaves the
|
|
14
|
+
* row in the store, marked undeclared and inert, until `pikku flags prune` —
|
|
15
|
+
* the same additive contract `defineScope` and `defineSystemRole` have, and for
|
|
16
|
+
* the same reason: a mid-deploy revocation is not something a code edit should
|
|
17
|
+
* be able to cause.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```typescript
|
|
21
|
+
* defineFeatureFlags({
|
|
22
|
+
* takeInBike: {
|
|
23
|
+
* description: 'Book a bike in at the counter',
|
|
24
|
+
* anyOf: ['bikes:intake'],
|
|
25
|
+
* },
|
|
26
|
+
* aiAssistant: {
|
|
27
|
+
* description: 'The assistant panel',
|
|
28
|
+
* // no anyOf — the switch is the whole answer
|
|
29
|
+
* },
|
|
30
|
+
* })
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare const defineFeatureFlags: (_config: CoreFeatureFlags) => void;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* No-op function for declaring feature flags.
|
|
3
|
+
* This exists purely for TypeScript type checking and will be tree-shaken.
|
|
4
|
+
* The CLI extracts metadata via AST parsing and generates a `FeatureFlagName`
|
|
5
|
+
* union, so `flags.calList` is a compile error rather than a silent `false`.
|
|
6
|
+
*
|
|
7
|
+
* That typing is load-bearing rather than a convenience: flags fail closed, so
|
|
8
|
+
* a typo'd flag reads `false`, hides its feature permanently, and leaves every
|
|
9
|
+
* test, screenshot and gate green. An untyped key makes a missing product
|
|
10
|
+
* indistinguishable from a working one.
|
|
11
|
+
*
|
|
12
|
+
* Removal is deliberately not destructive. Deleting a declaration leaves the
|
|
13
|
+
* row in the store, marked undeclared and inert, until `pikku flags prune` —
|
|
14
|
+
* the same additive contract `defineScope` and `defineSystemRole` have, and for
|
|
15
|
+
* the same reason: a mid-deploy revocation is not something a code edit should
|
|
16
|
+
* be able to cause.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```typescript
|
|
20
|
+
* defineFeatureFlags({
|
|
21
|
+
* takeInBike: {
|
|
22
|
+
* description: 'Book a bike in at the counter',
|
|
23
|
+
* anyOf: ['bikes:intake'],
|
|
24
|
+
* },
|
|
25
|
+
* aiAssistant: {
|
|
26
|
+
* description: 'The assistant panel',
|
|
27
|
+
* // no anyOf — the switch is the whole answer
|
|
28
|
+
* },
|
|
29
|
+
* })
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export const defineFeatureFlags = (_config) => { };
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A feature flag: a UI-facing name a client can ask about without knowing
|
|
3
|
+
* anything about the capability vocabulary.
|
|
4
|
+
*
|
|
5
|
+
* The flag is the indirection that keeps scopes a server concern. Returning
|
|
6
|
+
* `session.scopes` to the client would work and is wrong three times over: it
|
|
7
|
+
* publishes the vocabulary to every screen, it makes a scope rename a frontend
|
|
8
|
+
* refactor, and it forces each call site to reimplement parent-grant
|
|
9
|
+
* resolution — which some will get wrong in the permissive direction.
|
|
10
|
+
*/
|
|
11
|
+
export type CoreFeatureFlag = {
|
|
12
|
+
/** Surfaced in the console beside the switch. */
|
|
13
|
+
description?: string;
|
|
14
|
+
/**
|
|
15
|
+
* The session satisfies this flag by holding ANY of these — deliberately the
|
|
16
|
+
* opposite of `scopes:`, which is AND, because a flag usually reveals one
|
|
17
|
+
* entry point several roles can reach. Named `anyOf` and not `scopes` so the
|
|
18
|
+
* inverted semantics are visible at the call site.
|
|
19
|
+
*
|
|
20
|
+
* Every id must be declared with `defineScope`; the inspector fails the
|
|
21
|
+
* build otherwise, the same rule `defineSystemRole` already enforces.
|
|
22
|
+
*
|
|
23
|
+
* Omitted means no capability constraint — NOT "always on". The switch,
|
|
24
|
+
* the rollout bucket and any override still apply, which is what makes a
|
|
25
|
+
* flag usable as a pure kill switch. An explicit `anyOf: []` is a
|
|
26
|
+
* declaration error: write no key, or write scopes.
|
|
27
|
+
*/
|
|
28
|
+
anyOf?: string[];
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Feature flags to declare, keyed by name. A key must be non-empty and must
|
|
32
|
+
* not contain `:` — that separator belongs to scopes, and a flag that looks
|
|
33
|
+
* like a scope id invites exactly the confusion this exists to prevent.
|
|
34
|
+
*/
|
|
35
|
+
export type CoreFeatureFlags = Record<string, CoreFeatureFlag>;
|
|
36
|
+
export type FeatureFlagDefinitionMeta = {
|
|
37
|
+
name: string;
|
|
38
|
+
description?: string;
|
|
39
|
+
anyOf?: string[];
|
|
40
|
+
sourceFile?: string;
|
|
41
|
+
};
|
|
42
|
+
export type FeatureFlagDefinitions = FeatureFlagDefinitionMeta[];
|
|
43
|
+
export type FeatureFlagDefinitionsMeta = Record<string, FeatureFlagDefinitionMeta>;
|
|
44
|
+
/** A declared flag, ready to sync into a flag store. */
|
|
45
|
+
export type DeclaredFlag = {
|
|
46
|
+
name: string;
|
|
47
|
+
description?: string;
|
|
48
|
+
anyOf?: string[];
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Who a rollout bucket and an override are keyed on.
|
|
52
|
+
*
|
|
53
|
+
* The organization is preferred over the user wherever both are known: two
|
|
54
|
+
* colleagues on a screen-share seeing different UIs is a support ticket.
|
|
55
|
+
*/
|
|
56
|
+
export type FlagSubject = {
|
|
57
|
+
organizationId?: string;
|
|
58
|
+
userId?: string;
|
|
59
|
+
};
|
|
60
|
+
/** The runtime half of one flag: what an operator set, not what code declared. */
|
|
61
|
+
export type FlagConfig = {
|
|
62
|
+
enabled: boolean;
|
|
63
|
+
/** 0–100, or null for no rollout constraint. */
|
|
64
|
+
rolloutPercent: number | null;
|
|
65
|
+
/**
|
|
66
|
+
* Per-subject short-circuits, keyed by subject id. The one genuine OR in the
|
|
67
|
+
* model: "off for everyone, but these three orgs see it." An override wins
|
|
68
|
+
* over both the switch and the bucket, in either direction, so QA can enter a
|
|
69
|
+
* 5% rollout and a single tenant can be excluded from a bad one.
|
|
70
|
+
*/
|
|
71
|
+
overrides: Record<string, boolean>;
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* The global config half, keyed by flag name. One small blob shared by every
|
|
75
|
+
* user, which is why it is not baked into the session: writing it per-session
|
|
76
|
+
* would make killing a feature an unbounded fan-out over every active session,
|
|
77
|
+
* with users on both sides of the flip for its duration.
|
|
78
|
+
*/
|
|
79
|
+
export type FlagConfigSnapshot = Record<string, FlagConfig>;
|
|
80
|
+
/**
|
|
81
|
+
* A flag resolves to two booleans, not one. One bit cannot distinguish "you may
|
|
82
|
+
* not" (a 403, the caller's own situation) from "nobody may right now" (a 503,
|
|
83
|
+
* ours) — and collapsing them is what leaves a kill switch with nothing to
|
|
84
|
+
* enforce.
|
|
85
|
+
*/
|
|
86
|
+
export type FlagState = {
|
|
87
|
+
/** The feature is switched on at all. Global, caller-blind, and the only half
|
|
88
|
+
* the runner enforces. */
|
|
89
|
+
available: boolean;
|
|
90
|
+
/** This session holds a satisfying scope. Advisory to the client; hides UI and
|
|
91
|
+
* protects nothing, forever. */
|
|
92
|
+
capable: boolean;
|
|
93
|
+
};
|
|
94
|
+
/** What a client renders on. */
|
|
95
|
+
export type ResolvedFlag = FlagState & {
|
|
96
|
+
show: boolean;
|
|
97
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { CachedFlagSource } from './cached-flag-source.js';
|
|
2
|
+
export type { CachedFlagSourceOptions } from './cached-flag-source.js';
|
|
3
|
+
export { assertFeatureAvailable } from './assert-feature-available.js';
|
|
4
|
+
export { defineFeatureFlags } from './define-feature-flags.js';
|
|
5
|
+
export { bucketOf, resolveFlag, resolveFlagForClient, resolveFlagsForClient, subjectIdOf, } from './resolve-flag.js';
|
|
6
|
+
export { compiledFallbackSnapshot, flattenFeatureFlagDefinitions, validateAndBuildFeatureFlagDefinitionsMeta, } from './validate-flag-definitions.js';
|
|
7
|
+
export type { CoreFeatureFlag, CoreFeatureFlags, DeclaredFlag, FeatureFlagDefinitionMeta, FeatureFlagDefinitions, FeatureFlagDefinitionsMeta, FlagConfig, FlagConfigSnapshot, FlagState, FlagSubject, ResolvedFlag, } from './flag.types.js';
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { CachedFlagSource } from './cached-flag-source.js';
|
|
2
|
+
export { assertFeatureAvailable } from './assert-feature-available.js';
|
|
3
|
+
export { defineFeatureFlags } from './define-feature-flags.js';
|
|
4
|
+
export { bucketOf, resolveFlag, resolveFlagForClient, resolveFlagsForClient, subjectIdOf, } from './resolve-flag.js';
|
|
5
|
+
export { compiledFallbackSnapshot, flattenFeatureFlagDefinitions, validateAndBuildFeatureFlagDefinitionsMeta, } from './validate-flag-definitions.js';
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { CoreUserSession } from '../../types/core.types.js';
|
|
2
|
+
import type { DeclaredFlag, FlagConfigSnapshot, FlagState, FlagSubject, ResolvedFlag } from './flag.types.js';
|
|
3
|
+
/**
|
|
4
|
+
* FNV-1a over `${flag}:${subject}`.
|
|
5
|
+
*
|
|
6
|
+
* Salted by flag key so two flags at 50% do not select the same half and
|
|
7
|
+
* concurrent rollouts stay independent. Sync and non-crypto on purpose:
|
|
8
|
+
* WebCrypto's digest is async and this runs inside resolution, which does no
|
|
9
|
+
* I/O and cannot await.
|
|
10
|
+
*/
|
|
11
|
+
export declare const bucketOf: (flag: string, subject: string) => number;
|
|
12
|
+
/**
|
|
13
|
+
* The subject a bucket and an override are keyed on.
|
|
14
|
+
*
|
|
15
|
+
* Organization first: a percentage rollout that splits colleagues inside one
|
|
16
|
+
* account is a support ticket, not an experiment.
|
|
17
|
+
*/
|
|
18
|
+
export declare const subjectIdOf: (subject: FlagSubject | undefined) => string | undefined;
|
|
19
|
+
/**
|
|
20
|
+
* Resolves one flag from the session and the config snapshot. Pure, sync, and
|
|
21
|
+
* the only thing on the request path — the I/O is the snapshot read, which the
|
|
22
|
+
* caller has already done and which implementations cache.
|
|
23
|
+
*
|
|
24
|
+
* `subject` is passed explicitly rather than read off the session because the
|
|
25
|
+
* subject is not always in one: a queue worker, a cron task or a workflow step
|
|
26
|
+
* knows its organization from its input, and resolving those against no subject
|
|
27
|
+
* would skip every per-org override and deny an org that was explicitly
|
|
28
|
+
* granted. Where it is omitted the session is used.
|
|
29
|
+
*
|
|
30
|
+
* A flag absent from the snapshot fails OPEN on availability, falling back to
|
|
31
|
+
* the declaration compiled into the bundle. Treating an unreadable config as
|
|
32
|
+
* everything-off turns a transient store blip into a total outage of your own
|
|
33
|
+
* product. It is safe only because `capable` comes from the session and
|
|
34
|
+
* `scopes:` is untouched, so failing open cannot expose anything the caller was
|
|
35
|
+
* not already authorized for.
|
|
36
|
+
*/
|
|
37
|
+
export declare const resolveFlag: (key: string, anyOf: readonly string[] | undefined, session: CoreUserSession | undefined, config: FlagConfigSnapshot, subject?: FlagSubject) => FlagState;
|
|
38
|
+
/** {@link resolveFlag} plus the `show` a client renders on. */
|
|
39
|
+
export declare const resolveFlagForClient: (key: string, anyOf: readonly string[] | undefined, session: CoreUserSession | undefined, config: FlagConfigSnapshot, subject?: FlagSubject) => ResolvedFlag;
|
|
40
|
+
/**
|
|
41
|
+
* Every declared flag resolved for one caller, as a client consumes them.
|
|
42
|
+
*
|
|
43
|
+
* A client asks once per session and reads the map synchronously after, rather
|
|
44
|
+
* than asking per flag: a flag is checked wherever a component renders, and a
|
|
45
|
+
* request from each would put the network in front of a paint. The snapshot is
|
|
46
|
+
* already in isolate memory, so this is a map over a cached object.
|
|
47
|
+
*
|
|
48
|
+
* Bare booleans, not `FlagState`. `show` is the collapse of the two halves, and
|
|
49
|
+
* sending them apart would tell a client which features exist but are dark —
|
|
50
|
+
* a roadmap nobody meant to publish.
|
|
51
|
+
*/
|
|
52
|
+
export declare const resolveFlagsForClient: (declared: readonly DeclaredFlag[], session: CoreUserSession | undefined, config: FlagConfigSnapshot, subject?: FlagSubject) => Record<string, boolean>;
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { hasAnyScope } from '../../scopes.js';
|
|
2
|
+
/**
|
|
3
|
+
* FNV-1a over `${flag}:${subject}`.
|
|
4
|
+
*
|
|
5
|
+
* Salted by flag key so two flags at 50% do not select the same half and
|
|
6
|
+
* concurrent rollouts stay independent. Sync and non-crypto on purpose:
|
|
7
|
+
* WebCrypto's digest is async and this runs inside resolution, which does no
|
|
8
|
+
* I/O and cannot await.
|
|
9
|
+
*/
|
|
10
|
+
export const bucketOf = (flag, subject) => {
|
|
11
|
+
let h = 0x811c9dc5;
|
|
12
|
+
const s = `${flag}:${subject}`;
|
|
13
|
+
for (let i = 0; i < s.length; i++) {
|
|
14
|
+
h ^= s.charCodeAt(i);
|
|
15
|
+
h = Math.imul(h, 0x01000193) >>> 0;
|
|
16
|
+
}
|
|
17
|
+
return h % 10_000;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The subject a bucket and an override are keyed on.
|
|
21
|
+
*
|
|
22
|
+
* Organization first: a percentage rollout that splits colleagues inside one
|
|
23
|
+
* account is a support ticket, not an experiment.
|
|
24
|
+
*/
|
|
25
|
+
export const subjectIdOf = (subject) => {
|
|
26
|
+
const usable = (id) => id === undefined || id === '' ? undefined : id;
|
|
27
|
+
return usable(subject?.organizationId) ?? usable(subject?.userId);
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Resolves one flag from the session and the config snapshot. Pure, sync, and
|
|
31
|
+
* the only thing on the request path — the I/O is the snapshot read, which the
|
|
32
|
+
* caller has already done and which implementations cache.
|
|
33
|
+
*
|
|
34
|
+
* `subject` is passed explicitly rather than read off the session because the
|
|
35
|
+
* subject is not always in one: a queue worker, a cron task or a workflow step
|
|
36
|
+
* knows its organization from its input, and resolving those against no subject
|
|
37
|
+
* would skip every per-org override and deny an org that was explicitly
|
|
38
|
+
* granted. Where it is omitted the session is used.
|
|
39
|
+
*
|
|
40
|
+
* A flag absent from the snapshot fails OPEN on availability, falling back to
|
|
41
|
+
* the declaration compiled into the bundle. Treating an unreadable config as
|
|
42
|
+
* everything-off turns a transient store blip into a total outage of your own
|
|
43
|
+
* product. It is safe only because `capable` comes from the session and
|
|
44
|
+
* `scopes:` is untouched, so failing open cannot expose anything the caller was
|
|
45
|
+
* not already authorized for.
|
|
46
|
+
*/
|
|
47
|
+
export const resolveFlag = (key, anyOf, session, config, subject) => {
|
|
48
|
+
const capable = anyOf === undefined ? true : hasAnyScope(anyOf, session?.scopes);
|
|
49
|
+
const row = config[key];
|
|
50
|
+
if (!row) {
|
|
51
|
+
return { available: true, capable };
|
|
52
|
+
}
|
|
53
|
+
const id = subjectIdOf(subject) ??
|
|
54
|
+
subjectIdOf({ organizationId: session?.orgId, userId: session?.userId });
|
|
55
|
+
const override = id === undefined ? undefined : row.overrides[id];
|
|
56
|
+
if (override !== undefined) {
|
|
57
|
+
return { available: override, capable };
|
|
58
|
+
}
|
|
59
|
+
// No subject skips the bucket rather than failing it. A sessionless caller
|
|
60
|
+
// has nothing to hash, and hashing a constant would put every cron run in one
|
|
61
|
+
// bucket — making a 10% rollout either 0% or 100% of background work at
|
|
62
|
+
// random. A percentage is a statement about users; background work is either
|
|
63
|
+
// on or off.
|
|
64
|
+
const inBucket = row.rolloutPercent === null || id === undefined
|
|
65
|
+
? true
|
|
66
|
+
: bucketOf(key, id) < Math.round(row.rolloutPercent * 100);
|
|
67
|
+
return { available: row.enabled && inBucket, capable };
|
|
68
|
+
};
|
|
69
|
+
/** {@link resolveFlag} plus the `show` a client renders on. */
|
|
70
|
+
export const resolveFlagForClient = (key, anyOf, session, config, subject) => {
|
|
71
|
+
const state = resolveFlag(key, anyOf, session, config, subject);
|
|
72
|
+
return { ...state, show: state.available && state.capable };
|
|
73
|
+
};
|
|
74
|
+
/**
|
|
75
|
+
* Every declared flag resolved for one caller, as a client consumes them.
|
|
76
|
+
*
|
|
77
|
+
* A client asks once per session and reads the map synchronously after, rather
|
|
78
|
+
* than asking per flag: a flag is checked wherever a component renders, and a
|
|
79
|
+
* request from each would put the network in front of a paint. The snapshot is
|
|
80
|
+
* already in isolate memory, so this is a map over a cached object.
|
|
81
|
+
*
|
|
82
|
+
* Bare booleans, not `FlagState`. `show` is the collapse of the two halves, and
|
|
83
|
+
* sending them apart would tell a client which features exist but are dark —
|
|
84
|
+
* a roadmap nobody meant to publish.
|
|
85
|
+
*/
|
|
86
|
+
export const resolveFlagsForClient = (declared, session, config, subject) => Object.fromEntries(declared.map((flag) => [
|
|
87
|
+
flag.name,
|
|
88
|
+
resolveFlagForClient(flag.name, flag.anyOf, session, config, subject)
|
|
89
|
+
.show,
|
|
90
|
+
]));
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { DeclaredFlag, FeatureFlagDefinitions, FeatureFlagDefinitionsMeta, FlagConfigSnapshot } from './flag.types.js';
|
|
2
|
+
/**
|
|
3
|
+
* The declared flags as a flat list, deduplicated by name.
|
|
4
|
+
*
|
|
5
|
+
* A flag may legitimately be declared more than once — an addon and its host
|
|
6
|
+
* app both contributing one — and
|
|
7
|
+
* {@link validateAndBuildFeatureFlagDefinitionsMeta} has already guaranteed
|
|
8
|
+
* those declarations are identical.
|
|
9
|
+
*/
|
|
10
|
+
export declare const flattenFeatureFlagDefinitions: (definitions: FeatureFlagDefinitions) => DeclaredFlag[];
|
|
11
|
+
/**
|
|
12
|
+
* Validates declared flags and keys them by name.
|
|
13
|
+
*
|
|
14
|
+
* Definitions sharing a name must name the same scope set; a conflicting
|
|
15
|
+
* redeclaration is a hard error naming both source files. Order within `anyOf`
|
|
16
|
+
* is not significant.
|
|
17
|
+
*/
|
|
18
|
+
export declare function validateAndBuildFeatureFlagDefinitionsMeta(definitions: FeatureFlagDefinitions): FeatureFlagDefinitionsMeta;
|
|
19
|
+
/**
|
|
20
|
+
* The snapshot a flag source falls back to when its store cannot be read: every
|
|
21
|
+
* declared flag on, no rollout, no overrides.
|
|
22
|
+
*
|
|
23
|
+
* This is the compiled declaration, not a database read — putting a fallback
|
|
24
|
+
* query on the request path is how a slow store becomes a slow product.
|
|
25
|
+
*/
|
|
26
|
+
export declare const compiledFallbackSnapshot: (flags: readonly DeclaredFlag[]) => FlagConfigSnapshot;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
const SEPARATOR = ':';
|
|
2
|
+
/**
|
|
3
|
+
* Names that already exist on every object literal. Declaring one makes the
|
|
4
|
+
* meta lookup below find `Object.prototype`'s member, treat the flag as
|
|
5
|
+
* already declared, and drop it — a flag that validated but never reached the
|
|
6
|
+
* snapshot, which is the one failure a typed flag key exists to prevent.
|
|
7
|
+
*/
|
|
8
|
+
const INHERITED_NAMES = new Set(['__proto__', 'constructor', 'prototype']);
|
|
9
|
+
const assertFlagName = (name) => {
|
|
10
|
+
if (name.length === 0) {
|
|
11
|
+
throw new Error('A feature flag is declared with an empty name.');
|
|
12
|
+
}
|
|
13
|
+
if (INHERITED_NAMES.has(name)) {
|
|
14
|
+
throw new Error(`Feature flag '${name}' is named after a property every object already ` +
|
|
15
|
+
`carries, so it cannot be told apart from one. Pick another name.`);
|
|
16
|
+
}
|
|
17
|
+
if (name.includes(SEPARATOR)) {
|
|
18
|
+
throw new Error(`Feature flag '${name}' contains the '${SEPARATOR}' separator. ` +
|
|
19
|
+
`'${SEPARATOR}' delimits scope ids; a flag named like a scope reads as one.`);
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* The declared flags as a flat list, deduplicated by name.
|
|
24
|
+
*
|
|
25
|
+
* A flag may legitimately be declared more than once — an addon and its host
|
|
26
|
+
* app both contributing one — and
|
|
27
|
+
* {@link validateAndBuildFeatureFlagDefinitionsMeta} has already guaranteed
|
|
28
|
+
* those declarations are identical.
|
|
29
|
+
*/
|
|
30
|
+
export const flattenFeatureFlagDefinitions = (definitions) => {
|
|
31
|
+
const seen = new Set();
|
|
32
|
+
const out = [];
|
|
33
|
+
for (const def of definitions) {
|
|
34
|
+
if (seen.has(def.name)) {
|
|
35
|
+
continue;
|
|
36
|
+
}
|
|
37
|
+
seen.add(def.name);
|
|
38
|
+
out.push({
|
|
39
|
+
name: def.name,
|
|
40
|
+
description: def.description,
|
|
41
|
+
anyOf: def.anyOf ? [...def.anyOf] : undefined,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return out;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Validates declared flags and keys them by name.
|
|
48
|
+
*
|
|
49
|
+
* Definitions sharing a name must name the same scope set; a conflicting
|
|
50
|
+
* redeclaration is a hard error naming both source files. Order within `anyOf`
|
|
51
|
+
* is not significant.
|
|
52
|
+
*/
|
|
53
|
+
export function validateAndBuildFeatureFlagDefinitionsMeta(definitions) {
|
|
54
|
+
const meta = {};
|
|
55
|
+
for (const def of definitions) {
|
|
56
|
+
assertFlagName(def.name);
|
|
57
|
+
if (def.anyOf && def.anyOf.length === 0) {
|
|
58
|
+
throw new Error(`Feature flag '${def.name}' declares 'anyOf: []'. ` +
|
|
59
|
+
`An empty list satisfies nobody, which is never what is meant: ` +
|
|
60
|
+
`omit 'anyOf' for a pure switch, or name the scopes that reveal it.`);
|
|
61
|
+
}
|
|
62
|
+
const existing = meta[def.name];
|
|
63
|
+
if (existing) {
|
|
64
|
+
const sameScopes = JSON.stringify([...(existing.anyOf ?? [])].sort()) ===
|
|
65
|
+
JSON.stringify([...(def.anyOf ?? [])].sort());
|
|
66
|
+
if (!sameScopes) {
|
|
67
|
+
throw new Error(`Feature flag '${def.name}' is declared with different scopes.\n` +
|
|
68
|
+
` First declaration: ${existing.sourceFile ?? 'unknown'}\n` +
|
|
69
|
+
` Second declaration: ${def.sourceFile ?? 'unknown'}\n` +
|
|
70
|
+
`Flags sharing a name must name the same scopes.`);
|
|
71
|
+
}
|
|
72
|
+
// The description is what an operator reads beside the switch, and the
|
|
73
|
+
// winner here is whichever file the inspector walked first. Two
|
|
74
|
+
// descriptions for one flag is a disagreement about what the switch
|
|
75
|
+
// does, and source order is not the thing that should settle it.
|
|
76
|
+
if (existing.description !== def.description) {
|
|
77
|
+
throw new Error(`Feature flag '${def.name}' is declared with different descriptions.\n` +
|
|
78
|
+
` First declaration: ${existing.sourceFile ?? 'unknown'}\n` +
|
|
79
|
+
` Second declaration: ${def.sourceFile ?? 'unknown'}\n` +
|
|
80
|
+
`Flags sharing a name must describe the same thing.`);
|
|
81
|
+
}
|
|
82
|
+
continue;
|
|
83
|
+
}
|
|
84
|
+
meta[def.name] = {
|
|
85
|
+
name: def.name,
|
|
86
|
+
description: def.description,
|
|
87
|
+
anyOf: def.anyOf ? [...def.anyOf] : undefined,
|
|
88
|
+
sourceFile: def.sourceFile,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
return meta;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* The snapshot a flag source falls back to when its store cannot be read: every
|
|
95
|
+
* declared flag on, no rollout, no overrides.
|
|
96
|
+
*
|
|
97
|
+
* This is the compiled declaration, not a database read — putting a fallback
|
|
98
|
+
* query on the request path is how a slow store becomes a slow product.
|
|
99
|
+
*/
|
|
100
|
+
export const compiledFallbackSnapshot = (flags) => Object.fromEntries(flags.map((flag) => [
|
|
101
|
+
flag.name,
|
|
102
|
+
{ enabled: true, rolloutPercent: null, overrides: {} },
|
|
103
|
+
]));
|
|
@@ -38,9 +38,9 @@ export declare const VIRTUAL_USER_VARIABLES: {
|
|
|
38
38
|
* and a server that cannot name its own public URL would be signing in
|
|
39
39
|
* somewhere it only assumed was itself.
|
|
40
40
|
*/
|
|
41
|
-
readonly apiUrl:
|
|
42
|
-
readonly secret:
|
|
43
|
-
readonly model:
|
|
41
|
+
readonly apiUrl: 'VIRTUAL_USER_API_URL';
|
|
42
|
+
readonly secret: 'SCENARIO_ACTOR_SECRET';
|
|
43
|
+
readonly model: 'VIRTUAL_USER_MODEL';
|
|
44
44
|
/**
|
|
45
45
|
* The same two variables a scenario run reads, because a virtual user signs
|
|
46
46
|
* in and calls through exactly the doors a scenario does. An app that mounts
|
|
@@ -48,15 +48,15 @@ export declare const VIRTUAL_USER_VARIABLES: {
|
|
|
48
48
|
* other way to say so, and without them the run signs in against a 404 and
|
|
49
49
|
* spends its whole budget thinking about why nothing works.
|
|
50
50
|
*/
|
|
51
|
-
readonly signInPath:
|
|
52
|
-
readonly rpcPath:
|
|
51
|
+
readonly signInPath: 'SCENARIO_SIGN_IN_PATH';
|
|
52
|
+
readonly rpcPath: 'SCENARIO_RPC_PATH';
|
|
53
53
|
/**
|
|
54
54
|
* The deployed way in. A Fabric operator token is asymmetric — a stage can
|
|
55
55
|
* verify one and can never mint one — so unlike the actor secret it is safe
|
|
56
56
|
* for a run against a real environment. Read from the environment only as the
|
|
57
57
|
* fallback for a run nobody handed a token to, which is what a schedule is.
|
|
58
58
|
*/
|
|
59
|
-
readonly operatorToken:
|
|
59
|
+
readonly operatorToken: 'FABRIC_OPERATOR_TOKEN';
|
|
60
60
|
};
|
|
61
61
|
/**
|
|
62
62
|
* Which door under the auth mount, given the credential in hand.
|
|
@@ -66,7 +66,7 @@ export declare const VIRTUAL_USER_VARIABLES: {
|
|
|
66
66
|
* to `/api/auth` says so once and both paths follow. A path that names neither
|
|
67
67
|
* plugin is left alone, since it was configured deliberately.
|
|
68
68
|
*/
|
|
69
|
-
export declare const signInPathFor: (configured: string | undefined, plugin:
|
|
69
|
+
export declare const signInPathFor: (configured: string | undefined, plugin: 'actor' | 'fabric') => string | undefined;
|
|
70
70
|
/**
|
|
71
71
|
* The declared persona behind an id, refused unless it is one a run may be.
|
|
72
72
|
*
|
|
@@ -130,7 +130,7 @@ export declare const serializeVirtualUserRun: (run: VirtualUserRunRecord) => {
|
|
|
130
130
|
persona: string;
|
|
131
131
|
disposition: VirtualUserDisposition;
|
|
132
132
|
seed: number;
|
|
133
|
-
status: "
|
|
133
|
+
status: "completed" | "failed" | "running";
|
|
134
134
|
goals: string[];
|
|
135
135
|
memory: Record<string, string>;
|
|
136
136
|
findings: {
|
|
@@ -31,7 +31,7 @@ export declare const isDue: (schedule: VirtualUserScheduleRecord, now: Date) =>
|
|
|
31
31
|
* than rejected, because a schedule is configuration and a swapped pair is a
|
|
32
32
|
* typo, not an attack.
|
|
33
33
|
*/
|
|
34
|
-
export declare const nextRunAt: (schedule: Pick<VirtualUserScheduleRecord,
|
|
34
|
+
export declare const nextRunAt: (schedule: Pick<VirtualUserScheduleRecord, 'minIntervalMs' | 'maxIntervalMs'>, now: Date, random: () => number) => Date;
|
|
35
35
|
export type VirtualUserSkipReason = 'in-flight' | 'dispatch-failed' | 'claimed-elsewhere';
|
|
36
36
|
export interface VirtualUserTickResult {
|
|
37
37
|
dispatched: {
|
|
@@ -21,6 +21,6 @@ export declare const stepWorkerQueueName: (strategy: WorkflowQueueStrategy, rpcN
|
|
|
21
21
|
* every step dispatch would pay for that — only a step that names a workflow
|
|
22
22
|
* and has a queue to reach ever asks.
|
|
23
23
|
*/
|
|
24
|
-
export declare const stepDispatchTarget: (rpcName: string, stepName: string, parentIsInline: () => Promise<boolean>) => Promise<
|
|
24
|
+
export declare const stepDispatchTarget: (rpcName: string, stepName: string, parentIsInline: () => Promise<boolean>) => Promise<'queue' | 'inline'>;
|
|
25
25
|
export declare const jobGroupFor: (strategy: WorkflowQueueStrategy, id?: string) => JobGroup | undefined;
|
|
26
26
|
export declare const stepJobOptions: (stepOptions?: WorkflowStepOptions) => JobOptions;
|