@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,32 @@
|
|
|
1
|
+
import type { HashedValue, SealedValue, WrappedValue } from './data-classification.js';
|
|
2
|
+
/**
|
|
3
|
+
* SHA-256 of a credential, lowercase hex — the sole producer of `HashedValue`.
|
|
4
|
+
*
|
|
5
|
+
* Deliberately unpeppered. These are high-entropy random bearer tokens, not
|
|
6
|
+
* passwords: there is no candidate set to search, so a pepper would add a key
|
|
7
|
+
* to manage and a rotation story to own while buying nothing. A column holding
|
|
8
|
+
* a *low*-entropy secret is not a `hashed` column — it wants a password KDF and
|
|
9
|
+
* a different type entirely.
|
|
10
|
+
*
|
|
11
|
+
* Async because it runs on WebCrypto rather than `node:crypto`, so the same
|
|
12
|
+
* code path works in a Worker. Callers that hash a bearer token on every
|
|
13
|
+
* request are already async.
|
|
14
|
+
*/
|
|
15
|
+
export declare const hashToken: (raw: string) => Promise<HashedValue>;
|
|
16
|
+
/**
|
|
17
|
+
* Assert that a string already in storage is ciphertext of the given form.
|
|
18
|
+
*
|
|
19
|
+
* The brands exist so that new writes must come from a real encrypt/hash call,
|
|
20
|
+
* but three paths legitimately hold such a value as a bare `string`: a
|
|
21
|
+
* migration backfilling rows written before the column declared its form, a
|
|
22
|
+
* test fixture, and a value arriving over the wire from a service that sealed
|
|
23
|
+
* it elsewhere. Each of those is a promise the caller is making, not something
|
|
24
|
+
* the type system can check — which is why these are named to be greppable and
|
|
25
|
+
* why there is no non-`unsafe` spelling. If one of these appears in ordinary
|
|
26
|
+
* request-handling code, that is the bug.
|
|
27
|
+
*/
|
|
28
|
+
export declare const unsafeAsWrapped: (stored: string) => WrappedValue;
|
|
29
|
+
/** See `unsafeAsWrapped`. */
|
|
30
|
+
export declare const unsafeAsSealed: (stored: string) => SealedValue;
|
|
31
|
+
/** See `unsafeAsWrapped`. */
|
|
32
|
+
export declare const unsafeAsHashed: (stored: string) => HashedValue;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SHA-256 of a credential, lowercase hex — the sole producer of `HashedValue`.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately unpeppered. These are high-entropy random bearer tokens, not
|
|
5
|
+
* passwords: there is no candidate set to search, so a pepper would add a key
|
|
6
|
+
* to manage and a rotation story to own while buying nothing. A column holding
|
|
7
|
+
* a *low*-entropy secret is not a `hashed` column — it wants a password KDF and
|
|
8
|
+
* a different type entirely.
|
|
9
|
+
*
|
|
10
|
+
* Async because it runs on WebCrypto rather than `node:crypto`, so the same
|
|
11
|
+
* code path works in a Worker. Callers that hash a bearer token on every
|
|
12
|
+
* request are already async.
|
|
13
|
+
*/
|
|
14
|
+
export const hashToken = async (raw) => {
|
|
15
|
+
const subtle = globalThis.crypto?.subtle;
|
|
16
|
+
if (!subtle) {
|
|
17
|
+
throw new Error('WebCrypto not available');
|
|
18
|
+
}
|
|
19
|
+
const digest = await subtle.digest('SHA-256', new TextEncoder().encode(raw));
|
|
20
|
+
let hex = '';
|
|
21
|
+
for (const byte of new Uint8Array(digest)) {
|
|
22
|
+
hex += byte.toString(16).padStart(2, '0');
|
|
23
|
+
}
|
|
24
|
+
return hex;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Assert that a string already in storage is ciphertext of the given form.
|
|
28
|
+
*
|
|
29
|
+
* The brands exist so that new writes must come from a real encrypt/hash call,
|
|
30
|
+
* but three paths legitimately hold such a value as a bare `string`: a
|
|
31
|
+
* migration backfilling rows written before the column declared its form, a
|
|
32
|
+
* test fixture, and a value arriving over the wire from a service that sealed
|
|
33
|
+
* it elsewhere. Each of those is a promise the caller is making, not something
|
|
34
|
+
* the type system can check — which is why these are named to be greppable and
|
|
35
|
+
* why there is no non-`unsafe` spelling. If one of these appears in ordinary
|
|
36
|
+
* request-handling code, that is the bug.
|
|
37
|
+
*/
|
|
38
|
+
export const unsafeAsWrapped = (stored) => stored;
|
|
39
|
+
/** See `unsafeAsWrapped`. */
|
|
40
|
+
export const unsafeAsSealed = (stored) => stored;
|
|
41
|
+
/** See `unsafeAsWrapped`. */
|
|
42
|
+
export const unsafeAsHashed = (stored) => stored;
|
package/dist/crypto-utils.d.ts
CHANGED
|
@@ -1,12 +1,48 @@
|
|
|
1
|
+
import type { WrappedValue } from './data-classification.js';
|
|
1
2
|
export declare const encryptJSON: (secret: string, value: unknown) => Promise<string>;
|
|
2
3
|
export declare const decryptJSON: <T>(secret: string, token: string) => Promise<T>;
|
|
4
|
+
/**
|
|
5
|
+
* Namespaces the remote-RPC session key so the same deployment secret used for
|
|
6
|
+
* another purpose derives a different key. See knowledge/crypto.md.
|
|
7
|
+
*/
|
|
8
|
+
export declare const REMOTE_SESSION_INFO = "pikku:remote-session";
|
|
9
|
+
export declare const MIN_KEY_MATERIAL_LENGTH = 32;
|
|
10
|
+
export declare const assertStrongKeyMaterial: (name: string, keyMaterial: string) => void;
|
|
11
|
+
export declare const encryptWithKeyMaterial: (name: string, keyMaterial: string, info: string, value: unknown) => Promise<string>;
|
|
12
|
+
export declare const decryptWithKeyMaterial: <T>(name: string, keyMaterial: string, info: string, token: string) => Promise<T>;
|
|
13
|
+
export declare const encodeBase64UrlText: (value: string) => string;
|
|
14
|
+
export declare const decodeBase64UrlText: (value: string) => string;
|
|
15
|
+
/**
|
|
16
|
+
* HMAC-SHA256 over `payload` under a key expanded from high-entropy key
|
|
17
|
+
* material, base64url-encoded. The salt is empty by design so the verifier can
|
|
18
|
+
* re-derive the key from `keyMaterial` and `info` alone.
|
|
19
|
+
*/
|
|
20
|
+
export declare const signWithKeyMaterial: (name: string, keyMaterial: string, info: string, payload: string) => Promise<string>;
|
|
21
|
+
/** False — never throws — for a malformed, truncated or mismatched signature. */
|
|
22
|
+
export declare const verifyWithKeyMaterial: (name: string, keyMaterial: string, info: string, payload: string, signature: string) => Promise<boolean>;
|
|
3
23
|
export declare const generateDEK: () => Promise<string>;
|
|
4
|
-
|
|
5
|
-
|
|
24
|
+
/**
|
|
25
|
+
* One salt per (deployment, key version), stored beside the wrapped DEKs.
|
|
26
|
+
* See knowledge/crypto.md.
|
|
27
|
+
*/
|
|
28
|
+
export declare const generateKEKSalt: () => string;
|
|
29
|
+
export declare const deriveKEK: (passphrase: string, salt: string) => Promise<CryptoKey>;
|
|
30
|
+
export declare const wrapDEK: (kek: CryptoKey, plaintextDEK: string) => Promise<WrappedValue>;
|
|
31
|
+
export declare const unwrapDEK: (kek: CryptoKey, wrappedDEK: string) => Promise<string>;
|
|
6
32
|
export interface EnvelopeEncryptResult {
|
|
7
|
-
ciphertext:
|
|
8
|
-
wrappedDEK:
|
|
33
|
+
ciphertext: WrappedValue;
|
|
34
|
+
wrappedDEK: WrappedValue;
|
|
9
35
|
}
|
|
10
|
-
export declare const envelopeEncrypt: (kek:
|
|
11
|
-
|
|
12
|
-
|
|
36
|
+
export declare const envelopeEncrypt: (kek: CryptoKey, value: unknown) => Promise<EnvelopeEncryptResult>;
|
|
37
|
+
/**
|
|
38
|
+
* Note the inputs are plain `string`, not `WrappedValue`.
|
|
39
|
+
*
|
|
40
|
+
* The brand exists to stop plaintext being *written* to a wrapped column, and
|
|
41
|
+
* a `WrappedValue` is assignable to `string`, so a branded caller still passes
|
|
42
|
+
* without a cast. Demanding the brand here would buy nothing — feeding the
|
|
43
|
+
* wrong string in already fails at the AEAD tag — while forcing a cast into
|
|
44
|
+
* every path that reads ciphertext back out of a row, a parsed envelope, or the
|
|
45
|
+
* wire, which is exactly where casts are least reviewable.
|
|
46
|
+
*/
|
|
47
|
+
export declare const envelopeDecrypt: <T>(kek: CryptoKey, ciphertext: string, wrappedDEK: string) => Promise<T>;
|
|
48
|
+
export declare const envelopeRewrap: (oldKEK: CryptoKey, newKEK: CryptoKey, wrappedDEK: string) => Promise<WrappedValue>;
|
package/dist/crypto-utils.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { WeakKeyMaterialError } from './errors/errors.js';
|
|
1
2
|
const encoder = new TextEncoder();
|
|
2
3
|
const decoder = new TextDecoder();
|
|
3
4
|
const getSubtle = () => {
|
|
@@ -40,13 +41,19 @@ const fromBase64Url = (input) => {
|
|
|
40
41
|
base64 += '=';
|
|
41
42
|
return base64Decode(base64);
|
|
42
43
|
};
|
|
43
|
-
const
|
|
44
|
+
const SALT_BYTES = 16;
|
|
45
|
+
const IV_BYTES = 12;
|
|
46
|
+
const TAG_BYTES = 16;
|
|
47
|
+
const PBKDF2_ITERATIONS = 600_000;
|
|
48
|
+
const deriveKey = async (secret, salt) => {
|
|
44
49
|
const subtle = getSubtle();
|
|
45
|
-
const
|
|
46
|
-
return subtle.
|
|
47
|
-
'
|
|
48
|
-
|
|
49
|
-
|
|
50
|
+
const material = await subtle.importKey('raw', encoder.encode(secret), { name: 'PBKDF2' }, false, ['deriveKey']);
|
|
51
|
+
return subtle.deriveKey({
|
|
52
|
+
name: 'PBKDF2',
|
|
53
|
+
salt: salt,
|
|
54
|
+
iterations: PBKDF2_ITERATIONS,
|
|
55
|
+
hash: 'SHA-256',
|
|
56
|
+
}, material, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']);
|
|
50
57
|
};
|
|
51
58
|
export const encryptJSON = async (secret, value) => {
|
|
52
59
|
const crypto = globalThis.crypto;
|
|
@@ -54,82 +61,196 @@ export const encryptJSON = async (secret, value) => {
|
|
|
54
61
|
throw new Error('WebCrypto not available');
|
|
55
62
|
}
|
|
56
63
|
const subtle = getSubtle();
|
|
57
|
-
const
|
|
58
|
-
const
|
|
64
|
+
const salt = crypto.getRandomValues(new Uint8Array(SALT_BYTES));
|
|
65
|
+
const iv = crypto.getRandomValues(new Uint8Array(IV_BYTES));
|
|
66
|
+
const key = await deriveKey(secret, salt);
|
|
59
67
|
const plaintext = encoder.encode(JSON.stringify(value));
|
|
60
68
|
const encrypted = await subtle.encrypt({ name: 'AES-GCM', iv }, key, plaintext);
|
|
61
69
|
const cipherBytes = new Uint8Array(encrypted);
|
|
62
|
-
const out = new Uint8Array(iv.length + cipherBytes.length);
|
|
63
|
-
out.set(
|
|
64
|
-
out.set(
|
|
70
|
+
const out = new Uint8Array(salt.length + iv.length + cipherBytes.length);
|
|
71
|
+
out.set(salt, 0);
|
|
72
|
+
out.set(iv, salt.length);
|
|
73
|
+
out.set(cipherBytes, salt.length + iv.length);
|
|
65
74
|
return toBase64Url(out);
|
|
66
75
|
};
|
|
67
76
|
export const decryptJSON = async (secret, token) => {
|
|
68
77
|
const subtle = getSubtle();
|
|
69
78
|
const data = fromBase64Url(token);
|
|
70
|
-
if (data.length
|
|
79
|
+
if (data.length <= SALT_BYTES + IV_BYTES + TAG_BYTES) {
|
|
71
80
|
throw new Error('Invalid encrypted payload');
|
|
72
81
|
}
|
|
73
|
-
const
|
|
74
|
-
const
|
|
75
|
-
const
|
|
82
|
+
const salt = data.slice(0, SALT_BYTES);
|
|
83
|
+
const iv = data.slice(SALT_BYTES, SALT_BYTES + IV_BYTES);
|
|
84
|
+
const ciphertext = data.slice(SALT_BYTES + IV_BYTES);
|
|
85
|
+
const key = await deriveKey(secret, salt);
|
|
76
86
|
const decrypted = await subtle.decrypt({ name: 'AES-GCM', iv }, key, ciphertext);
|
|
77
87
|
return JSON.parse(decoder.decode(new Uint8Array(decrypted)));
|
|
78
88
|
};
|
|
79
89
|
/**
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
* Each secret gets its own random DEK (data encryption key).
|
|
83
|
-
* The DEK is wrapped (encrypted) by a KEK (key encryption key) — typically an env var.
|
|
84
|
-
* The actual secret is encrypted with the DEK.
|
|
85
|
-
*
|
|
86
|
-
* KEK rotation only re-wraps the DEK, never touches the ciphertext.
|
|
90
|
+
* Namespaces the remote-RPC session key so the same deployment secret used for
|
|
91
|
+
* another purpose derives a different key. See knowledge/crypto.md.
|
|
87
92
|
*/
|
|
88
|
-
const
|
|
93
|
+
export const REMOTE_SESSION_INFO = 'pikku:remote-session';
|
|
94
|
+
export const MIN_KEY_MATERIAL_LENGTH = 32;
|
|
95
|
+
export const assertStrongKeyMaterial = (name, keyMaterial) => {
|
|
96
|
+
if (keyMaterial.length < MIN_KEY_MATERIAL_LENGTH) {
|
|
97
|
+
throw new WeakKeyMaterialError(name, MIN_KEY_MATERIAL_LENGTH, keyMaterial.length);
|
|
98
|
+
}
|
|
99
|
+
};
|
|
100
|
+
const expandKeyMaterial = async (keyMaterial, info, salt) => {
|
|
89
101
|
const subtle = getSubtle();
|
|
90
|
-
|
|
102
|
+
const material = await subtle.importKey('raw', encoder.encode(keyMaterial), 'HKDF', false, ['deriveKey']);
|
|
103
|
+
return subtle.deriveKey({
|
|
104
|
+
name: 'HKDF',
|
|
105
|
+
hash: 'SHA-256',
|
|
106
|
+
salt: salt,
|
|
107
|
+
info: encoder.encode(info),
|
|
108
|
+
}, material, { name: 'AES-GCM', length: 256 }, false, ['encrypt', 'decrypt']);
|
|
91
109
|
};
|
|
92
|
-
export const
|
|
93
|
-
|
|
94
|
-
|
|
110
|
+
export const encryptWithKeyMaterial = async (name, keyMaterial, info, value) => {
|
|
111
|
+
assertStrongKeyMaterial(name, keyMaterial);
|
|
112
|
+
const crypto = globalThis.crypto;
|
|
113
|
+
if (!crypto?.getRandomValues) {
|
|
114
|
+
throw new Error('WebCrypto not available');
|
|
115
|
+
}
|
|
116
|
+
const subtle = getSubtle();
|
|
117
|
+
const salt = crypto.getRandomValues(new Uint8Array(SALT_BYTES));
|
|
118
|
+
const iv = crypto.getRandomValues(new Uint8Array(IV_BYTES));
|
|
119
|
+
const key = await expandKeyMaterial(keyMaterial, info, salt);
|
|
120
|
+
const encrypted = await subtle.encrypt({ name: 'AES-GCM', iv }, key, encoder.encode(JSON.stringify(value)));
|
|
121
|
+
const cipherBytes = new Uint8Array(encrypted);
|
|
122
|
+
const out = new Uint8Array(salt.length + iv.length + cipherBytes.length);
|
|
123
|
+
out.set(salt, 0);
|
|
124
|
+
out.set(iv, salt.length);
|
|
125
|
+
out.set(cipherBytes, salt.length + iv.length);
|
|
126
|
+
return toBase64Url(out);
|
|
95
127
|
};
|
|
96
|
-
export const
|
|
97
|
-
|
|
128
|
+
export const decryptWithKeyMaterial = async (name, keyMaterial, info, token) => {
|
|
129
|
+
assertStrongKeyMaterial(name, keyMaterial);
|
|
130
|
+
const subtle = getSubtle();
|
|
131
|
+
const data = fromBase64Url(token);
|
|
132
|
+
if (data.length <= SALT_BYTES + IV_BYTES + TAG_BYTES) {
|
|
133
|
+
throw new Error('Invalid encrypted payload');
|
|
134
|
+
}
|
|
135
|
+
const salt = data.slice(0, SALT_BYTES);
|
|
136
|
+
const iv = data.slice(SALT_BYTES, SALT_BYTES + IV_BYTES);
|
|
137
|
+
const ciphertext = data.slice(SALT_BYTES + IV_BYTES);
|
|
138
|
+
const key = await expandKeyMaterial(keyMaterial, info, salt);
|
|
139
|
+
const decrypted = await subtle.decrypt({ name: 'AES-GCM', iv }, key, ciphertext);
|
|
140
|
+
return JSON.parse(decoder.decode(new Uint8Array(decrypted)));
|
|
98
141
|
};
|
|
99
|
-
export const
|
|
100
|
-
|
|
142
|
+
export const encodeBase64UrlText = (value) => toBase64Url(encoder.encode(value));
|
|
143
|
+
export const decodeBase64UrlText = (value) => decoder.decode(fromBase64Url(value));
|
|
144
|
+
const expandSigningKeyMaterial = async (keyMaterial, info) => {
|
|
145
|
+
const subtle = getSubtle();
|
|
146
|
+
const material = await subtle.importKey('raw', encoder.encode(keyMaterial), 'HKDF', false, ['deriveKey']);
|
|
147
|
+
return subtle.deriveKey({
|
|
148
|
+
name: 'HKDF',
|
|
149
|
+
hash: 'SHA-256',
|
|
150
|
+
salt: new Uint8Array(0),
|
|
151
|
+
info: encoder.encode(info),
|
|
152
|
+
}, material, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign', 'verify']);
|
|
101
153
|
};
|
|
102
|
-
|
|
154
|
+
/**
|
|
155
|
+
* HMAC-SHA256 over `payload` under a key expanded from high-entropy key
|
|
156
|
+
* material, base64url-encoded. The salt is empty by design so the verifier can
|
|
157
|
+
* re-derive the key from `keyMaterial` and `info` alone.
|
|
158
|
+
*/
|
|
159
|
+
export const signWithKeyMaterial = async (name, keyMaterial, info, payload) => {
|
|
160
|
+
assertStrongKeyMaterial(name, keyMaterial);
|
|
161
|
+
const key = await expandSigningKeyMaterial(keyMaterial, info);
|
|
162
|
+
const signature = await getSubtle().sign('HMAC', key, encoder.encode(payload));
|
|
163
|
+
return toBase64Url(new Uint8Array(signature));
|
|
164
|
+
};
|
|
165
|
+
/** False — never throws — for a malformed, truncated or mismatched signature. */
|
|
166
|
+
export const verifyWithKeyMaterial = async (name, keyMaterial, info, payload, signature) => {
|
|
167
|
+
assertStrongKeyMaterial(name, keyMaterial);
|
|
168
|
+
const key = await expandSigningKeyMaterial(keyMaterial, info);
|
|
169
|
+
try {
|
|
170
|
+
return await getSubtle().verify('HMAC', key, fromBase64Url(signature), encoder.encode(payload));
|
|
171
|
+
}
|
|
172
|
+
catch {
|
|
173
|
+
return false;
|
|
174
|
+
}
|
|
175
|
+
};
|
|
176
|
+
const importRawKey = async (rawBytes) => {
|
|
177
|
+
const subtle = getSubtle();
|
|
178
|
+
return subtle.importKey('raw', rawBytes.buffer, { name: 'AES-GCM' }, true, ['encrypt', 'decrypt']);
|
|
179
|
+
};
|
|
180
|
+
const encryptWithCryptoKey = async (key, value) => {
|
|
103
181
|
const crypto = globalThis.crypto;
|
|
104
182
|
const subtle = getSubtle();
|
|
105
|
-
const iv = crypto.getRandomValues(new Uint8Array(
|
|
106
|
-
const
|
|
107
|
-
const plaintext = encoder.encode(JSON.stringify(value));
|
|
108
|
-
const encrypted = await subtle.encrypt({ name: 'AES-GCM', iv }, key, plaintext);
|
|
183
|
+
const iv = crypto.getRandomValues(new Uint8Array(IV_BYTES));
|
|
184
|
+
const encrypted = await subtle.encrypt({ name: 'AES-GCM', iv }, key, encoder.encode(JSON.stringify(value)));
|
|
109
185
|
const cipherBytes = new Uint8Array(encrypted);
|
|
110
186
|
const out = new Uint8Array(iv.length + cipherBytes.length);
|
|
111
187
|
out.set(iv, 0);
|
|
112
188
|
out.set(cipherBytes, iv.length);
|
|
113
189
|
return toBase64Url(out);
|
|
114
190
|
};
|
|
115
|
-
const
|
|
191
|
+
const decryptWithCryptoKey = async (key, token) => {
|
|
116
192
|
const subtle = getSubtle();
|
|
117
193
|
const data = fromBase64Url(token);
|
|
118
|
-
if (data.length <
|
|
194
|
+
if (data.length < IV_BYTES + TAG_BYTES) {
|
|
119
195
|
throw new Error('Invalid encrypted payload');
|
|
120
196
|
}
|
|
121
|
-
const iv = data.slice(0,
|
|
122
|
-
const ciphertext = data.slice(
|
|
123
|
-
const key = await importRawKey(fromBase64Url(dekBase64));
|
|
197
|
+
const iv = data.slice(0, IV_BYTES);
|
|
198
|
+
const ciphertext = data.slice(IV_BYTES);
|
|
124
199
|
const decrypted = await subtle.decrypt({ name: 'AES-GCM', iv }, key, ciphertext);
|
|
125
200
|
return JSON.parse(decoder.decode(new Uint8Array(decrypted)));
|
|
126
201
|
};
|
|
202
|
+
export const generateDEK = async () => {
|
|
203
|
+
const raw = globalThis.crypto.getRandomValues(new Uint8Array(32));
|
|
204
|
+
return toBase64Url(raw);
|
|
205
|
+
};
|
|
206
|
+
/**
|
|
207
|
+
* One salt per (deployment, key version), stored beside the wrapped DEKs.
|
|
208
|
+
* See knowledge/crypto.md.
|
|
209
|
+
*/
|
|
210
|
+
export const generateKEKSalt = () => {
|
|
211
|
+
const crypto = globalThis.crypto;
|
|
212
|
+
if (!crypto?.getRandomValues) {
|
|
213
|
+
throw new Error('WebCrypto not available');
|
|
214
|
+
}
|
|
215
|
+
return toBase64Url(crypto.getRandomValues(new Uint8Array(SALT_BYTES)));
|
|
216
|
+
};
|
|
217
|
+
export const deriveKEK = async (passphrase, salt) => {
|
|
218
|
+
return deriveKey(passphrase, fromBase64Url(salt));
|
|
219
|
+
};
|
|
220
|
+
/**
|
|
221
|
+
* The one place a `WrappedValue` is minted. Every branded return below routes
|
|
222
|
+
* through here, so the assertion "these bytes really are ciphertext" is made
|
|
223
|
+
* once and audited once instead of at each call site.
|
|
224
|
+
*/
|
|
225
|
+
const asWrapped = (ciphertext) => ciphertext;
|
|
226
|
+
export const wrapDEK = async (kek, plaintextDEK) => {
|
|
227
|
+
return asWrapped(await encryptWithCryptoKey(kek, plaintextDEK));
|
|
228
|
+
};
|
|
229
|
+
export const unwrapDEK = async (kek, wrappedDEK) => {
|
|
230
|
+
return decryptWithCryptoKey(kek, wrappedDEK);
|
|
231
|
+
};
|
|
232
|
+
const encryptWithDEK = async (dekBase64, value) => {
|
|
233
|
+
return encryptWithCryptoKey(await importRawKey(fromBase64Url(dekBase64)), value);
|
|
234
|
+
};
|
|
235
|
+
const decryptWithDEK = async (dekBase64, token) => {
|
|
236
|
+
return decryptWithCryptoKey(await importRawKey(fromBase64Url(dekBase64)), token);
|
|
237
|
+
};
|
|
127
238
|
export const envelopeEncrypt = async (kek, value) => {
|
|
128
239
|
const dek = await generateDEK();
|
|
129
|
-
const ciphertext = await encryptWithDEK(dek, value);
|
|
240
|
+
const ciphertext = asWrapped(await encryptWithDEK(dek, value));
|
|
130
241
|
const wrappedDEK = await wrapDEK(kek, dek);
|
|
131
242
|
return { ciphertext, wrappedDEK };
|
|
132
243
|
};
|
|
244
|
+
/**
|
|
245
|
+
* Note the inputs are plain `string`, not `WrappedValue`.
|
|
246
|
+
*
|
|
247
|
+
* The brand exists to stop plaintext being *written* to a wrapped column, and
|
|
248
|
+
* a `WrappedValue` is assignable to `string`, so a branded caller still passes
|
|
249
|
+
* without a cast. Demanding the brand here would buy nothing — feeding the
|
|
250
|
+
* wrong string in already fails at the AEAD tag — while forcing a cast into
|
|
251
|
+
* every path that reads ciphertext back out of a row, a parsed envelope, or the
|
|
252
|
+
* wire, which is exactly where casts are least reviewable.
|
|
253
|
+
*/
|
|
133
254
|
export const envelopeDecrypt = async (kek, ciphertext, wrappedDEK) => {
|
|
134
255
|
const dek = await unwrapDEK(kek, wrappedDEK);
|
|
135
256
|
return decryptWithDEK(dek, ciphertext);
|
|
@@ -9,12 +9,56 @@ export type Secret<T> = T & {
|
|
|
9
9
|
};
|
|
10
10
|
export type Classification = 'public' | 'private' | 'pii' | 'secret';
|
|
11
11
|
export type AnonymizeStrategy = 'fake:email' | 'fake:name' | 'hash' | 'keep' | null;
|
|
12
|
+
/**
|
|
13
|
+
* How a column's bytes are represented at rest, as distinct from how sensitive
|
|
14
|
+
* the value is (`Classification`). The two are independent: a token hash is
|
|
15
|
+
* `secret` + `hashed` and must never be encrypted, because the hash *is* the
|
|
16
|
+
* lookup key; a live bearer token is `secret` + `plain` today and should not be.
|
|
17
|
+
*
|
|
18
|
+
* `wrapped` and `sealed` are siblings rather than one being "encrypted": both
|
|
19
|
+
* are ciphertext, and what separates them is who can read it back. Wrapped is
|
|
20
|
+
* symmetric and the application holds the key. Sealed is asymmetric and the
|
|
21
|
+
* application holds only the public half, so it can write the value and never
|
|
22
|
+
* read it. Storing one where the other is expected is silent, permanent data
|
|
23
|
+
* loss, which is why they are not collapsed into a single `encrypted`.
|
|
24
|
+
*/
|
|
25
|
+
export type ColumnForm = 'plain' | 'hashed' | 'wrapped' | 'sealed';
|
|
26
|
+
declare const wrappedBrand: unique symbol;
|
|
27
|
+
declare const sealedBrand: unique symbol;
|
|
28
|
+
declare const hashedBrand: unique symbol;
|
|
29
|
+
/**
|
|
30
|
+
* Ciphertext under a symmetric key the application holds — the output of
|
|
31
|
+
* `envelopeEncrypt`, `wrapDEK` or `envelopeRewrap`.
|
|
32
|
+
*
|
|
33
|
+
* Unlike `Secret<T>` the brand is REQUIRED, so a plain `string` is not
|
|
34
|
+
* assignable and a column declared `form: 'wrapped'` cannot be written with
|
|
35
|
+
* anything but genuine ciphertext. It stays assignable *to* `string`, so it
|
|
36
|
+
* still works as a query operand and serializes normally — the constraint is on
|
|
37
|
+
* construction, not on use.
|
|
38
|
+
*/
|
|
39
|
+
export type WrappedValue = string & {
|
|
40
|
+
readonly [wrappedBrand]: true;
|
|
41
|
+
};
|
|
42
|
+
/** Ciphertext under a public key whose private half the application does not
|
|
43
|
+
* hold. Deliberately not assignable to `WrappedValue`: writing one where the
|
|
44
|
+
* other belongs produces a row nobody can ever open. */
|
|
45
|
+
export type SealedValue = string & {
|
|
46
|
+
readonly [sealedBrand]: true;
|
|
47
|
+
};
|
|
48
|
+
/** A one-way digest of a secret input. The brand's job is narrow — stop a *raw*
|
|
49
|
+
* credential being written into the column that should hold its hash. */
|
|
50
|
+
export type HashedValue = string & {
|
|
51
|
+
readonly [hashedBrand]: true;
|
|
52
|
+
};
|
|
12
53
|
export interface ColumnClassification {
|
|
13
54
|
classification: Classification;
|
|
14
55
|
anonymize_strategy: AnonymizeStrategy;
|
|
56
|
+
/** At-rest representation. Absent means `plain`. */
|
|
57
|
+
form?: ColumnForm;
|
|
15
58
|
description?: string;
|
|
16
59
|
}
|
|
17
60
|
export type ClassificationManifest = {
|
|
18
61
|
version: 1;
|
|
19
62
|
tables: Record<string, Record<string, ColumnClassification>>;
|
|
20
63
|
};
|
|
64
|
+
export {};
|
package/dist/dev/hot-reload.js
CHANGED
|
@@ -32,12 +32,6 @@ const findCompiledFile = async (tsFile, srcDir, pikkuDir) => {
|
|
|
32
32
|
}
|
|
33
33
|
return null;
|
|
34
34
|
};
|
|
35
|
-
// Changed user files are re-run through an evictable module runner keyed by a
|
|
36
|
-
// stable path (createModuleRunner), NOT re-imported under a fresh URL. A
|
|
37
|
-
// fresh-URL import (a `data:` URL on Node, a uniquely-named temp sibling on
|
|
38
|
-
// Bun) permanently leaks a record in the native ESM loader map on every
|
|
39
|
-
// reload, OOMing long editing sessions; the runner overwrites a single slot so
|
|
40
|
-
// the previous module is collected. See ./module-runner.ts.
|
|
41
35
|
const isWatchedTsFile = (filename) => {
|
|
42
36
|
return (filename.endsWith('.ts') &&
|
|
43
37
|
!filename.endsWith('.test.ts') &&
|
|
@@ -67,17 +61,12 @@ export async function pikkuDevReloader(options) {
|
|
|
67
61
|
logger.error(`Failed to import: ${relative(process.cwd(), importPath)} (keeping old code)`);
|
|
68
62
|
return;
|
|
69
63
|
}
|
|
70
|
-
// Register every function-config export
|
|
71
|
-
// adding new ones
|
|
72
|
-
//
|
|
73
|
-
//
|
|
74
|
-
//
|
|
75
|
-
//
|
|
76
|
-
// that map is silently discarded when it restores the original.
|
|
77
|
-
// Schemas are NOT touched here: `input`/`output` hold raw zod schemas,
|
|
78
|
-
// while the schema map carries codegen-generated JSON schemas — mixing the
|
|
79
|
-
// two crashed every reload. Fresh JSON schemas arrive via
|
|
80
|
-
// reloadGeneratedMeta once codegen has re-emitted them.
|
|
64
|
+
// Register every function-config export, replacing known functions and
|
|
65
|
+
// adding new ones. Write into the map captured at startup, NOT pikkuState's
|
|
66
|
+
// current one: a dev-server watcher may have temporarily swapped in a
|
|
67
|
+
// codegen-scoped map, whose writes are discarded when it restores.
|
|
68
|
+
// Schemas are NOT touched here: `input`/`output` hold raw zod schemas while
|
|
69
|
+
// the schema map carries codegen JSON schemas; mixing them crashed reloads.
|
|
81
70
|
for (const [exportName, exportValue] of Object.entries(mod)) {
|
|
82
71
|
if (!isFunctionConfig(exportValue))
|
|
83
72
|
continue;
|
|
@@ -88,10 +77,9 @@ export async function pikkuDevReloader(options) {
|
|
|
88
77
|
else
|
|
89
78
|
reloadedNames.push(exportName);
|
|
90
79
|
}
|
|
91
|
-
// Re-importing
|
|
92
|
-
//
|
|
93
|
-
//
|
|
94
|
-
// wiring-only file edit rebuilds the route matchers too.
|
|
80
|
+
// Re-importing re-ran the module’s wire* side effects, so reset the router
|
|
81
|
+
// and caches even when no function export changed — a wiring-only edit has
|
|
82
|
+
// to rebuild the route matchers too.
|
|
95
83
|
clearMiddlewareCache();
|
|
96
84
|
clearPermissionsCache();
|
|
97
85
|
clearChannelMiddlewareCache();
|
|
@@ -108,9 +96,8 @@ export async function pikkuDevReloader(options) {
|
|
|
108
96
|
};
|
|
109
97
|
let debounceTimer;
|
|
110
98
|
const pendingChanges = new Set();
|
|
111
|
-
// Files re-imported since the last reimportPending() drain
|
|
112
|
-
//
|
|
113
|
-
// were skipped for missing meta (a NEW route) run again with fresh meta.
|
|
99
|
+
// Files re-imported since the last reimportPending() drain, re-run after the
|
|
100
|
+
// dev server's codegen pass so registrations skipped for missing meta retry.
|
|
114
101
|
const postCodegenQueue = new Set();
|
|
115
102
|
const safeHandleFileChange = async (file) => {
|
|
116
103
|
try {
|
|
@@ -156,12 +143,6 @@ export async function pikkuDevReloader(options) {
|
|
|
156
143
|
}
|
|
157
144
|
moduleRunner.clear();
|
|
158
145
|
},
|
|
159
|
-
// Drain the queue of recently re-imported files and import them again.
|
|
160
|
-
// A dev-server watcher calls this AFTER its codegen pass has refreshed
|
|
161
|
-
// the generated meta (reloadGeneratedMeta): wire* registrations skip
|
|
162
|
-
// routes whose meta doesn't exist yet, so a wiring file changed
|
|
163
|
-
// alongside a NEW function only registers its new route when
|
|
164
|
-
// re-imported after the fresh meta has landed.
|
|
165
146
|
reimportPending: async () => {
|
|
166
147
|
const files = [...postCodegenQueue];
|
|
167
148
|
postCodegenQueue.clear();
|
|
@@ -1,14 +1,10 @@
|
|
|
1
1
|
export interface PikkuModuleRunner {
|
|
2
|
-
/** Run a user module by absolute path
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* caller can keep the previously-loaded code. */
|
|
2
|
+
/** Run a user module by absolute path. Repeated runs of one path overwrite a
|
|
3
|
+
* single registry slot. Returns `null` on failure so the caller can keep the
|
|
4
|
+
* previously-loaded code. */
|
|
6
5
|
run: (absPath: string) => Promise<Record<string, unknown> | null>;
|
|
7
|
-
/** Drop a single module from the registry. */
|
|
8
6
|
evict: (absPath: string) => void;
|
|
9
|
-
/** Drop every module from the registry. */
|
|
10
7
|
clear: () => void;
|
|
11
|
-
/** Number of modules currently held. */
|
|
12
8
|
readonly size: number;
|
|
13
9
|
}
|
|
14
10
|
export declare const createModuleRunner: () => PikkuModuleRunner;
|
|
@@ -7,9 +7,8 @@ let transformSync;
|
|
|
7
7
|
const loadTransform = async () => {
|
|
8
8
|
if (transformSync)
|
|
9
9
|
return transformSync;
|
|
10
|
-
// esbuild is a dev-only dependency
|
|
11
|
-
//
|
|
12
|
-
// in production runtimes (the `./dev` export is dev-only).
|
|
10
|
+
// esbuild is a dev-only dependency hoisted from @pikku/cli at runtime; the
|
|
11
|
+
// `./dev` export is dev-only so it is never loaded in production runtimes.
|
|
13
12
|
const esbuild = await import('esbuild');
|
|
14
13
|
transformSync = esbuild.transformSync;
|
|
15
14
|
return transformSync;
|
|
@@ -21,10 +20,6 @@ export const createModuleRunner = () => {
|
|
|
21
20
|
try {
|
|
22
21
|
const transform = await loadTransform();
|
|
23
22
|
const source = await readFile(absPath, 'utf-8');
|
|
24
|
-
// No sourcemap: an inline sourcemap embeds a base64 copy of the source
|
|
25
|
-
// that the engine retains per compile, reintroducing linear growth on
|
|
26
|
-
// Node — the exact leak this runner exists to remove. `filename` still
|
|
27
|
-
// anchors stack traces to the user file.
|
|
28
23
|
const { code } = transform(source, {
|
|
29
24
|
loader: absPath.endsWith('.ts') ? 'ts' : 'js',
|
|
30
25
|
format: 'cjs',
|
|
@@ -38,9 +33,8 @@ export const createModuleRunner = () => {
|
|
|
38
33
|
return moduleObj.exports;
|
|
39
34
|
}
|
|
40
35
|
catch {
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
// `cjs` form). Return null so the caller keeps the previously-loaded code.
|
|
36
|
+
// A bad edit, or the one known limitation: a file using top-level
|
|
37
|
+
// `await`, which cannot be emitted in `cjs` form.
|
|
44
38
|
return null;
|
|
45
39
|
}
|
|
46
40
|
};
|
|
@@ -9,29 +9,17 @@ export interface ReloadGeneratedMetaOptions {
|
|
|
9
9
|
schemaService?: SchemaService;
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
|
-
* Re-reads
|
|
13
|
-
* process so new and changed functions become callable without a
|
|
14
|
-
*
|
|
15
|
-
* `
|
|
16
|
-
* re-imported after a dev-time codegen — the ESM cache pins both the wrapper
|
|
17
|
-
* and its JSON import — so this reads the JSON sources directly and applies
|
|
18
|
-
* the same state.
|
|
19
|
-
*
|
|
20
|
-
* Meant to be called by a dev-server watcher after each codegen pass. Routes
|
|
21
|
-
* registered by NEW `wireHTTP` files are not picked up (their modules were
|
|
22
|
-
* never imported); those still need a restart.
|
|
12
|
+
* Re-reads codegen output (wiring meta + JSON schemas) into the running
|
|
13
|
+
* process, so new and changed functions become callable without a restart.
|
|
14
|
+
* Called by a dev-server watcher after each codegen pass. Routes registered by
|
|
15
|
+
* NEW `wireHTTP` files are not picked up — their modules were never imported.
|
|
23
16
|
*/
|
|
24
17
|
export declare function reloadGeneratedMeta(options: ReloadGeneratedMetaOptions): Promise<void>;
|
|
25
18
|
/**
|
|
26
|
-
* Prunes the live addon registry
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
* leaves its `wireAddon` entry stranded in `pikkuState(null,'addons','packages')`
|
|
30
|
-
* until a full restart — the reason `getInstalledAddons` reports removed addons.
|
|
31
|
-
* The Map holds definitions (namespace → package config), not runtime state, so
|
|
32
|
-
* dropping any namespace the fresh inspection no longer declares is safe.
|
|
19
|
+
* Prunes the live addon registry to the namespaces the current source still
|
|
20
|
+
* declares. Hot reload only re-imports files that exist, so a deleted
|
|
21
|
+
* `*.addon.ts` otherwise leaves its `wireAddon` entry stranded until a restart.
|
|
33
22
|
*
|
|
34
|
-
* `declaredNamespaces` is
|
|
35
|
-
* inspection (`inspectorState.rpc.wireAddonDeclarations.keys()`).
|
|
23
|
+
* `declaredNamespaces` is `inspectorState.rpc.wireAddonDeclarations.keys()`.
|
|
36
24
|
*/
|
|
37
25
|
export declare function reconcileAddonRegistry(declaredNamespaces: Iterable<string>, logger?: Logger): void;
|