@pikku/core 0.12.84 → 0.12.86
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 +424 -0
- package/dist/bootstrap-compat/root.d.ts +20 -0
- package/dist/classification/column-form.d.ts +32 -0
- package/dist/classification/column-form.js +42 -0
- package/dist/classification/data-classification.d.ts +64 -0
- package/dist/classification/index.d.ts +13 -0
- package/dist/classification/index.js +2 -0
- package/dist/classification/secret-value.d.ts +56 -0
- package/dist/classification/secret-value.js +46 -0
- package/dist/crypto-utils.d.ts +1 -1
- package/dist/ecosystem/agent-scorer.d.ts +1 -1
- package/dist/ecosystem/agent.d.ts +4 -1
- package/dist/ecosystem/channel/local.d.ts +2 -0
- package/dist/ecosystem/channel/local.js +2 -0
- package/dist/ecosystem/channel/serverless.d.ts +9 -0
- package/dist/ecosystem/channel/serverless.js +1 -0
- package/dist/ecosystem/channel.d.ts +3 -0
- package/dist/ecosystem/channel.js +1 -0
- package/dist/ecosystem/cli.d.ts +1 -1
- package/dist/ecosystem/cli.js +1 -1
- package/dist/ecosystem/credential.d.ts +1 -0
- package/dist/ecosystem/crypto-utils.d.ts +8 -0
- package/dist/ecosystem/crypto-utils.js +1 -0
- package/dist/ecosystem/dev.d.ts +1 -0
- package/dist/ecosystem/dev.js +1 -0
- package/{src/ecosystem/testing.ts → dist/ecosystem/errors.d.ts} +3 -3
- package/dist/ecosystem/errors.js +2 -0
- package/dist/ecosystem/function.d.ts +1 -1
- package/dist/ecosystem/function.js +1 -1
- package/dist/ecosystem/http.d.ts +3 -1
- package/dist/ecosystem/http.js +3 -1
- package/dist/ecosystem/mcp.d.ts +1 -1
- package/dist/ecosystem/mcp.js +1 -1
- package/dist/ecosystem/middleware.d.ts +2 -1
- package/dist/ecosystem/middleware.js +2 -1
- package/dist/ecosystem/persona.d.ts +4 -2
- package/dist/ecosystem/persona.js +2 -1
- package/dist/ecosystem/queue.d.ts +4 -2
- package/dist/ecosystem/queue.js +3 -1
- package/dist/ecosystem/role.d.ts +1 -0
- package/dist/ecosystem/rpc.d.ts +2 -0
- package/dist/ecosystem/rpc.js +1 -0
- package/dist/ecosystem/scenario.d.ts +8 -2
- package/dist/ecosystem/scenario.js +5 -1
- package/dist/ecosystem/scheduler.d.ts +2 -1
- package/dist/ecosystem/scheduler.js +2 -1
- package/dist/ecosystem/schema.d.ts +2 -1
- package/dist/ecosystem/schema.js +1 -1
- package/dist/ecosystem/scope.d.ts +2 -0
- package/dist/ecosystem/scope.js +1 -0
- package/dist/ecosystem/secret.d.ts +2 -0
- package/dist/ecosystem/secret.js +1 -0
- package/dist/ecosystem/services/local-content.d.ts +2 -1
- package/dist/ecosystem/services/local-content.js +1 -1
- package/dist/ecosystem/services/local-meta.d.ts +1 -0
- package/dist/ecosystem/services/local-meta.js +1 -0
- package/dist/ecosystem/services.d.ts +11 -3
- package/dist/ecosystem/services.js +7 -1
- package/dist/ecosystem/trigger.d.ts +1 -0
- package/dist/ecosystem/trigger.js +1 -1
- package/dist/ecosystem/types.d.ts +6 -3
- package/dist/ecosystem/types.js +3 -2
- package/dist/ecosystem/variable.d.ts +1 -0
- package/dist/ecosystem/virtual-user.d.ts +3 -0
- package/dist/ecosystem/virtual-user.js +3 -0
- package/dist/ecosystem/workflow.d.ts +2 -0
- package/dist/ecosystem/workflow.js +2 -0
- package/dist/errors/index.d.ts +8 -0
- package/dist/errors/index.js +1 -0
- package/dist/errors/serialized-error.d.ts +7 -0
- package/dist/function/function-meta.types.d.ts +139 -0
- package/dist/function/function-runner.d.ts +3 -2
- package/dist/function/function-runner.js +31 -11
- package/dist/function/functions.types.d.ts +10 -2
- package/dist/function/index.d.ts +8 -2
- package/dist/function/index.js +4 -1
- package/dist/function/pikku-request.d.ts +8 -0
- package/dist/function/pikku-request.js +15 -0
- package/dist/middleware/auth-apikey.d.ts +2 -10
- package/dist/middleware/auth-apikey.js +1 -1
- package/dist/middleware/auth-bearer.d.ts +2 -10
- package/dist/middleware/auth-bearer.js +1 -1
- package/dist/middleware/auth-cookie.d.ts +2 -10
- package/dist/middleware/auth-cookie.js +1 -1
- package/dist/middleware/cors.d.ts +5 -11
- package/dist/middleware/cors.js +13 -6
- package/dist/middleware/index.d.ts +3 -0
- package/dist/middleware/index.js +1 -0
- package/dist/middleware/middleware-factories.d.ts +9 -0
- package/dist/middleware/middleware-factories.js +19 -0
- package/dist/middleware/middleware.types.d.ts +27 -0
- package/dist/middleware/middleware.types.js +1 -0
- package/dist/middleware/remote-auth.d.ts +2 -2
- package/dist/middleware/remote-auth.js +1 -1
- package/dist/middleware/telemetry.d.ts +4 -20
- package/dist/middleware/telemetry.js +1 -1
- package/dist/middleware-runner.d.ts +2 -1
- package/dist/pikku-state.d.ts +2 -1
- package/dist/services/audit-service.d.ts +1 -1
- package/dist/services/credential-wire-service.js +1 -1
- package/dist/services/email-service.d.ts +1 -1
- package/dist/services/file-scenario-run-store.d.ts +58 -0
- package/dist/services/file-scenario-run-store.js +214 -0
- package/dist/services/in-memory-workflow-service.d.ts +1 -1
- package/dist/services/index.d.ts +5 -1
- package/dist/services/index.js +3 -0
- package/dist/services/local-secrets.d.ts +1 -1
- package/dist/services/local-secrets.js +1 -1
- package/dist/services/logger.d.ts +7 -7
- package/dist/services/meta-service.d.ts +2 -1
- package/dist/services/scoped-secret-service.d.ts +1 -1
- package/dist/services/secret-service.d.ts +1 -1
- package/dist/services/typed-secret-service.d.ts +16 -2
- package/dist/services/typed-secret-service.js +5 -0
- package/dist/services/webhook-service.d.ts +1 -1
- package/dist/services/workflow-service.d.ts +2 -1
- package/dist/testing/index.d.ts +1 -0
- package/dist/testing/index.js +1 -0
- package/dist/types/core.types.d.ts +30 -180
- package/dist/types/core.types.js +1 -19
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +1 -0
- package/dist/types/state.types.d.ts +3 -1
- package/dist/utils.d.ts +13 -0
- package/dist/utils.js +2 -0
- package/dist/wirings/addon/addon-runner.d.ts +17 -0
- package/dist/wirings/addon/addon-runner.js +150 -0
- package/dist/wirings/addon/index.d.ts +6 -0
- package/dist/wirings/addon/index.js +3 -0
- package/dist/wirings/addon/remote-addon-auth.d.ts +16 -0
- package/dist/wirings/addon/remote-addon-auth.js +39 -0
- package/dist/wirings/addon/wire-addon.d.ts +80 -0
- package/dist/wirings/addon/wire-addon.js +120 -0
- package/dist/wirings/addon/wire-remote-addon.d.ts +22 -0
- package/dist/wirings/addon/wire-remote-addon.js +11 -0
- package/dist/wirings/agent/agent-prepare.d.ts +3 -3
- package/dist/wirings/agent/agent-prepare.js +1 -1
- package/dist/wirings/agent/agent-runner.js +2 -3
- package/dist/wirings/agent/agent-stream.js +2 -2
- package/dist/wirings/agent/agent-utils.d.ts +13 -0
- package/dist/wirings/agent/agent-utils.js +16 -0
- package/dist/wirings/agent/agent.types.d.ts +3 -2
- package/dist/wirings/agent/index.d.ts +1 -1
- package/dist/wirings/agent/voice-input.js +1 -1
- package/dist/wirings/agent/voice-output.js +1 -1
- package/dist/wirings/agent-scorer/agent-scorer-judge.d.ts +13 -0
- package/dist/wirings/agent-scorer/agent-scorer-judge.js +52 -0
- package/dist/wirings/agent-scorer/agent-scorer.d.ts +7 -1
- package/dist/wirings/agent-scorer/agent-scorer.js +1 -0
- package/dist/wirings/agent-scorer/agent-scorer.types.d.ts +20 -0
- package/dist/wirings/agent-scorer/index.d.ts +1 -1
- package/dist/wirings/channel/channel-common.d.ts +2 -1
- package/dist/wirings/channel/channel-middleware-runner.d.ts +2 -1
- package/dist/wirings/channel/channel.types.d.ts +1 -1
- package/dist/wirings/channel/serverless/index.d.ts +1 -0
- package/dist/wirings/cli/channel/index.d.ts +1 -1
- package/dist/wirings/cli/cli-runner.d.ts +2 -1
- package/dist/wirings/cli/cli-runner.js +4 -1
- package/dist/wirings/cli/cli.types.d.ts +21 -2
- package/dist/wirings/cli/command-parser.js +157 -23
- package/dist/wirings/gateway/gateway.types.d.ts +2 -1
- package/dist/wirings/http/http-runner.d.ts +1 -1
- package/dist/wirings/http/http-runner.js +1 -1
- package/dist/wirings/http/http.types.d.ts +2 -2
- package/dist/wirings/http/index.d.ts +1 -0
- package/dist/wirings/http/index.js +1 -0
- package/dist/wirings/http/pikku-fetch-http-request.js +1 -1
- package/dist/wirings/http/pikku-fetch-http-response.js +2 -2
- package/dist/wirings/mcp/mcp.types.d.ts +1 -1
- package/dist/wirings/persona/index.d.ts +1 -1
- package/dist/wirings/persona/index.js +1 -1
- package/dist/wirings/persona/persona.types.d.ts +14 -0
- package/dist/wirings/queue/queue.types.d.ts +1 -1
- package/dist/wirings/queue/signed-queue-service.d.ts +1 -1
- package/dist/wirings/rpc/index.d.ts +0 -6
- package/dist/wirings/rpc/index.js +0 -3
- package/dist/wirings/rpc/remote-addon-auth.d.ts +1 -1
- package/dist/wirings/rpc/remote-addon-auth.js +1 -1
- package/dist/wirings/rpc/rpc-runner.js +2 -2
- package/dist/wirings/rpc/wire-addon.d.ts +1 -1
- package/dist/wirings/scheduler/scheduler.types.d.ts +2 -1
- package/dist/wirings/scope/index.d.ts +1 -0
- package/dist/wirings/scope/index.js +1 -0
- package/dist/wirings/secret/secret.types.d.ts +10 -0
- package/dist/wirings/secret/validate-secret-definitions.js +2 -0
- package/dist/wirings/variable/validate-variable-definitions.js +2 -0
- package/dist/wirings/variable/variable.types.d.ts +9 -0
- package/dist/wirings/virtual-user/index.d.ts +1 -1
- package/dist/wirings/virtual-user/index.js +1 -1
- package/dist/wirings/virtual-user/prepare-virtual-user-run.d.ts +1 -1
- package/dist/wirings/virtual-user/virtual-user-derive.d.ts +1 -1
- package/dist/wirings/workflow/graph/graph-node.d.ts +9 -2
- package/dist/wirings/workflow/graph/graph-node.js +2 -0
- package/dist/wirings/workflow/graph/graph-runner.d.ts +1 -0
- package/dist/wirings/workflow/graph/graph-runner.js +283 -31
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +16 -1
- package/dist/wirings/workflow/index.d.ts +2 -0
- package/dist/wirings/workflow/index.js +1 -0
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +14 -4
- package/dist/wirings/workflow/pikku-scenario-service.js +44 -16
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +2 -1
- package/dist/wirings/workflow/pikku-workflow-service.js +3 -4
- package/dist/wirings/workflow/run-timeline.d.ts +1 -1
- package/dist/wirings/workflow/scenario-run.types.d.ts +171 -0
- package/dist/wirings/workflow/scenario-run.types.js +1 -0
- package/dist/wirings/workflow/scenario-step-guards.d.ts +1 -2
- package/dist/wirings/workflow/scenario-step-guards.js +0 -8
- package/dist/wirings/workflow/scenario-step.types.d.ts +27 -12
- package/dist/wirings/workflow/workflow-approval.js +2 -1
- package/dist/wirings/workflow/workflow-run-engine.types.d.ts +2 -1
- package/dist/wirings/workflow/workflow.types.d.ts +2 -1
- package/knowledge/decisions/index.md +2 -0
- package/knowledge/decisions/internals/a-scenario-step-template-is-offered-unfilled.md +1 -1
- package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +1 -1
- package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-and-not-a-queued-job.md +2 -2
- package/knowledge/decisions/internals/a-wall-clock-threshold-is-a-load-test-in-disguise.md +6 -6
- package/knowledge/decisions/internals/a-workflow-wire-is-built-from-the-run-not-from-the-rpc-service.md +1 -1
- package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +1 -1
- package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +1 -1
- package/knowledge/decisions/internals/an-addon-scope-root-loses-to-a-root-the-host-already-declares.md +1 -1
- package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +1 -1
- package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +1 -1
- package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +1 -1
- package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +1 -1
- package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +1 -1
- package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +1 -1
- package/knowledge/decisions/internals/core-column-form-is-an-axis-of-its-own.md +4 -4
- package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +1 -1
- package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +3 -3
- package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +2 -2
- package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +2 -2
- package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +1 -1
- package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +1 -1
- package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +3 -3
- package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +1 -1
- package/knowledge/decisions/internals/gateway-listener-middleware-runs-without-an-rpc-on-the-wire.md +4 -4
- package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +1 -1
- package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +1 -1
- package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +1 -1
- package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +1 -1
- package/knowledge/decisions/internals/index.md +4 -2
- package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +1 -1
- package/knowledge/decisions/internals/one-project-shape-check-two-validators.md +1 -1
- package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +1 -1
- package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +1 -1
- package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +1 -1
- package/knowledge/decisions/internals/scenario-given-and-when-are-sugar-but-then-is-not.md +2 -2
- package/knowledge/decisions/internals/scenarios-live-in-files-named-for-them.md +5 -5
- package/knowledge/decisions/internals/the-actor-prompt-says-json-because-of-json-object-mode.md +1 -1
- package/knowledge/decisions/internals/the-api-report-pins-members-not-just-names.md +1 -1
- package/knowledge/decisions/internals/the-ecosystem-entry-point-carries-the-adapter-surface.md +43 -19
- package/knowledge/decisions/internals/the-persona-runtime-is-exported-from-the-persona-entry-point.md +1 -1
- package/knowledge/decisions/internals/the-worker-disposition-is-the-one-that-is-not-testing.md +1 -1
- package/knowledge/decisions/internals/validate-runs-checks-by-precondition.md +3 -3
- package/knowledge/decisions/internals/virtual-user-step-order-comes-from-insertion-order.md +1 -1
- package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +1 -1
- package/knowledge/decisions/internals/wiring-registries-erase-the-generics-their-wire-functions-capture.md +1 -1
- package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +1 -1
- package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +1 -1
- package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +1 -1
- package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +1 -1
- package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +1 -1
- package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +1 -1
- package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +9 -5
- package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +1 -1
- package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +2 -2
- package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +1 -1
- package/knowledge/decisions/security/a-function-never-receives-the-secret-service.md +1 -1
- package/knowledge/decisions/security/a-step-runs-the-function-the-workflow-dispatched-it-with.md +1 -1
- package/knowledge/decisions/security/a-virtual-user-is-never-offered-a-step-that-would-forge-its-own-oracle.md +2 -3
- package/knowledge/decisions/security/actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +1 -1
- package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +1 -1
- package/knowledge/decisions/security/agent-gate-requires-a-session-only-when-auth-is-true.md +1 -1
- package/knowledge/decisions/security/an-approval-answer-outlives-the-run-it-answered.md +3 -3
- package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +4 -3
- package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +1 -1
- package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +2 -2
- package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +1 -1
- package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +2 -2
- package/knowledge/decisions/security/index.md +2 -0
- package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +1 -1
- package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +3 -3
- package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +1 -1
- package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +2 -2
- package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +1 -1
- package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +2 -2
- package/knowledge/index.md +3 -1
- package/knowledge/questions/channel-middleware-accepts-bare-factories-that-nothing-resolves.md +1 -1
- package/knowledge/questions/index.md +2 -0
- package/package.json +14 -13
- package/run-tests.sh +0 -0
- package/scripts/generate-api-report.d.mts +1 -1
- package/scripts/generate-api-report.mjs +67 -60
- package/scripts/generate-api-report.mts +11 -45
- package/src/api-report.test.ts +70 -1
- package/src/app-alias-surface.test.ts +179 -0
- package/src/app-leaf-surface.test.ts +217 -0
- package/src/bootstrap-compat/root.ts +20 -0
- package/src/{column-form.test.ts → classification/column-form.test.ts} +2 -2
- package/src/{data-classification.ts → classification/data-classification.ts} +1 -5
- package/src/classification/index.ts +38 -0
- package/src/{secret-value.test.ts → classification/secret-value.test.ts} +2 -2
- package/src/{secret-value.ts → classification/secret-value.ts} +1 -6
- package/src/crypto-utils.ts +1 -1
- package/src/dev/reload-meta.test.ts +1 -1
- package/src/errors/index.ts +9 -0
- package/src/errors/serialized-error.ts +9 -0
- package/src/factory-functions.test.ts +4 -2
- package/src/function/function-meta.types.ts +151 -0
- package/src/function/function-runner.test.ts +4 -2
- package/src/function/function-runner.ts +47 -14
- package/src/function/functions.types.ts +11 -7
- package/src/function/index.ts +24 -5
- package/src/function/list.types.ts +1 -3
- package/src/middleware/auth-apikey.ts +4 -2
- package/src/middleware/auth-bearer.test.ts +1 -1
- package/src/middleware/auth-bearer.ts +4 -2
- package/src/middleware/auth-cookie.ts +4 -1
- package/src/middleware/cors.test.ts +126 -5
- package/src/middleware/cors.ts +19 -8
- package/src/middleware/index.ts +16 -0
- package/src/middleware/middleware-factories.ts +62 -0
- package/src/middleware/middleware.types.ts +61 -0
- package/src/middleware/remote-auth.test.ts +1 -1
- package/src/middleware/remote-auth.ts +1 -1
- package/src/middleware/telemetry.ts +4 -2
- package/src/middleware-runner.test.ts +2 -3
- package/src/middleware-runner.ts +2 -2
- package/src/no-root-barrel.test.ts +114 -0
- package/src/permissions.ts +2 -4
- package/src/pikku-state.ts +3 -1
- package/src/public-surface.json +56 -241
- package/src/public-surface.json.README +3 -3
- package/src/public-surface.test.ts +5 -5
- package/src/remote.test.ts +1 -1
- package/src/removed-legacy-exports.test.ts +5 -1
- package/src/services/audit-service.ts +1 -1
- package/src/services/credential-wire-service.ts +1 -1
- package/src/services/email-service.ts +2 -4
- package/src/services/file-scenario-run-store.test.ts +349 -0
- package/src/services/file-scenario-run-store.ts +282 -0
- package/src/services/in-memory-workflow-service.ts +1 -1
- package/src/services/index.ts +13 -1
- package/src/services/local-content-request-handler.ts +1 -2
- package/src/services/local-secrets.ts +1 -1
- package/src/services/logger.ts +7 -7
- package/src/services/meta-service.ts +2 -2
- package/src/services/queue-webhook-service.test.ts +1 -1
- package/src/services/scoped-secret-service.ts +1 -1
- package/src/services/secret-service.ts +1 -1
- package/src/services/typed-secret-service.test.ts +52 -0
- package/src/services/typed-secret-service.ts +26 -2
- package/src/services/webhook-service.ts +1 -1
- package/src/services/workflow-service.ts +2 -1
- package/src/template-alias-surface.test.ts +240 -0
- package/src/testing/index.ts +1 -0
- package/src/types/core.types.ts +33 -285
- package/src/types/index.ts +2 -0
- package/src/types/state.types.ts +6 -5
- package/src/types/typed-credentials.test.ts +72 -0
- package/src/utils.ts +34 -0
- package/src/wirings/{rpc → addon}/addon-scopes.test.ts +1 -1
- package/src/wirings/addon/index.ts +12 -0
- package/src/wirings/{rpc → addon}/remote-addon-auth.ts +4 -1
- package/src/wirings/{rpc → addon}/wire-addon.ts +37 -2
- package/src/wirings/agent/agent-prepare.ts +8 -5
- package/src/wirings/agent/agent-runner.ts +2 -3
- package/src/wirings/agent/agent-stream.ts +2 -3
- package/src/wirings/agent/agent-utils.ts +19 -0
- package/src/wirings/agent/agent.types.ts +3 -3
- package/src/wirings/agent/index.ts +1 -0
- package/src/wirings/agent/voice-input.ts +1 -1
- package/src/wirings/agent/voice-output.test.ts +2 -4
- package/src/wirings/agent/voice-output.ts +1 -1
- package/src/wirings/agent-scorer/agent-scorer-judge.test.ts +145 -0
- package/src/wirings/agent-scorer/agent-scorer-judge.ts +60 -0
- package/src/wirings/agent-scorer/agent-scorer.ts +8 -0
- package/src/wirings/agent-scorer/agent-scorer.types.ts +21 -0
- package/src/wirings/agent-scorer/index.ts +1 -0
- package/src/wirings/channel/channel-common.ts +4 -2
- package/src/wirings/channel/channel-handler.ts +2 -5
- package/src/wirings/channel/channel-middleware-runner.ts +1 -1
- package/src/wirings/channel/channel-rpc.types.ts +1 -5
- package/src/wirings/channel/channel.types.ts +1 -2
- package/src/wirings/channel/local/local-channel-runner.test.ts +1 -2
- package/src/wirings/channel/serverless/index.ts +1 -0
- package/src/wirings/cli/channel/cli-raw-channel-runner.ts +2 -2
- package/src/wirings/cli/channel/index.ts +1 -3
- package/src/wirings/cli/cli-runner.test.ts +1 -1
- package/src/wirings/cli/cli-runner.ts +11 -7
- package/src/wirings/cli/cli.types.ts +24 -3
- package/src/wirings/cli/command-parser.test.ts +388 -1
- package/src/wirings/cli/command-parser.ts +189 -29
- package/src/wirings/gateway/gateway-runner.test.ts +1 -2
- package/src/wirings/gateway/gateway-runner.ts +3 -6
- package/src/wirings/gateway/gateway.types.ts +5 -4
- package/src/wirings/http/http-routes.test.ts +1 -2
- package/src/wirings/http/http-runner-addon-ref.test.ts +238 -0
- package/src/wirings/http/http-runner.test.ts +3 -8
- package/src/wirings/http/http-runner.ts +9 -3
- package/src/wirings/http/http.types.ts +3 -12
- package/src/wirings/http/index.ts +1 -0
- package/src/wirings/http/pikku-fetch-http-request.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-response.ts +3 -2
- package/src/wirings/mcp/mcp-runner.test.ts +1 -1
- package/src/wirings/mcp/mcp.types.ts +1 -2
- package/src/wirings/persona/index.ts +1 -4
- package/src/wirings/persona/persona.types.ts +14 -0
- package/src/wirings/queue/queue-identity.test.ts +1 -1
- package/src/wirings/queue/queue.types.ts +2 -6
- package/src/wirings/queue/signed-queue-service.ts +1 -1
- package/src/wirings/rpc/index.ts +0 -12
- package/src/wirings/rpc/rpc-runner.test.ts +4 -4
- package/src/wirings/rpc/rpc-runner.ts +3 -3
- package/src/wirings/scheduler/scheduler.types.ts +2 -5
- package/src/wirings/scope/index.ts +1 -0
- package/src/wirings/secret/secret.types.ts +10 -0
- package/src/wirings/secret/validate-secret-definitions.test.ts +23 -0
- package/src/wirings/secret/validate-secret-definitions.ts +2 -0
- package/src/wirings/variable/validate-variable-definitions.test.ts +23 -0
- package/src/wirings/variable/validate-variable-definitions.ts +2 -0
- package/src/wirings/variable/variable.types.ts +9 -0
- package/src/wirings/virtual-user/index.ts +1 -4
- package/src/wirings/virtual-user/prepare-virtual-user-run.ts +1 -1
- package/src/wirings/virtual-user/virtual-user-derive.test.ts +1 -1
- package/src/wirings/virtual-user/virtual-user-derive.ts +1 -1
- package/src/wirings/virtual-user/virtual-user.types.ts +1 -5
- package/src/wirings/workflow/graph/graph-foreach-queued.test.ts +569 -0
- package/src/wirings/workflow/graph/graph-foreach.test.ts +626 -0
- package/src/wirings/workflow/graph/graph-node.ts +16 -1
- package/src/wirings/workflow/graph/graph-runner.ts +387 -61
- package/src/wirings/workflow/graph/workflow-graph.types.ts +28 -3
- package/src/wirings/workflow/index.ts +8 -0
- package/src/wirings/workflow/pikku-scenario-service.ts +59 -19
- package/src/wirings/workflow/pikku-workflow-service.ts +6 -8
- package/src/wirings/workflow/run-timeline.ts +1 -1
- package/src/wirings/workflow/scenario-expectations.test.ts +28 -13
- package/src/wirings/workflow/scenario-run.types.ts +186 -0
- package/src/wirings/workflow/scenario-step-guards.ts +1 -14
- package/src/wirings/workflow/scenario-step.test.ts +32 -7
- package/src/wirings/workflow/scenario-step.types.ts +27 -12
- package/src/wirings/workflow/workflow-approval-policy.test.ts +117 -47
- package/src/wirings/workflow/workflow-approval.ts +2 -1
- package/src/wirings/workflow/workflow-run-engine.types.ts +2 -1
- package/src/wirings/workflow/workflow.types.ts +4 -12
- package/src/wirings-stay-decoupled.test.ts +6 -3
- package/tsconfig.tsbuildinfo +1 -1
- package/tsconfig.type-tests.json +3 -2
- package/dist/ecosystem/ai-agent.d.ts +0 -18
- package/dist/ecosystem/ai-agent.js +0 -6
- package/dist/ecosystem/ai-scorer.d.ts +0 -12
- package/dist/ecosystem/ai-scorer.js +0 -5
- package/dist/services/ai-agent-runner-service.d.ts +0 -220
- package/dist/services/ai-run-state-service.d.ts +0 -29
- package/dist/services/ai-storage-service.d.ts +0 -18
- package/dist/services/in-memory-ai-run-state-service.d.ts +0 -19
- package/dist/services/in-memory-ai-run-state-service.js +0 -54
- package/dist/testing/service-tests/ai-storage-service-tests.d.ts +0 -3
- package/dist/testing/service-tests/ai-storage-service-tests.js +0 -302
- package/dist/wirings/ai-agent/agent-rpc.d.ts +0 -15
- package/dist/wirings/ai-agent/agent-rpc.js +0 -53
- package/dist/wirings/ai-agent/ai-agent-agui.d.ts +0 -79
- package/dist/wirings/ai-agent/ai-agent-agui.js +0 -327
- package/dist/wirings/ai-agent/ai-agent-finalize.d.ts +0 -58
- package/dist/wirings/ai-agent/ai-agent-finalize.js +0 -138
- package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +0 -35
- package/dist/wirings/ai-agent/ai-agent-helpers.js +0 -47
- package/dist/wirings/ai-agent/ai-agent-interrupt.d.ts +0 -153
- package/dist/wirings/ai-agent/ai-agent-interrupt.js +0 -257
- package/dist/wirings/ai-agent/ai-agent-memory.d.ts +0 -42
- package/dist/wirings/ai-agent/ai-agent-memory.js +0 -333
- package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +0 -16
- package/dist/wirings/ai-agent/ai-agent-model-config.js +0 -51
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +0 -117
- package/dist/wirings/ai-agent/ai-agent-prepare.js +0 -728
- package/dist/wirings/ai-agent/ai-agent-registry.d.ts +0 -16
- package/dist/wirings/ai-agent/ai-agent-registry.js +0 -51
- package/dist/wirings/ai-agent/ai-agent-runner.d.ts +0 -7
- package/dist/wirings/ai-agent/ai-agent-runner.js +0 -580
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +0 -41
- package/dist/wirings/ai-agent/ai-agent-stream.js +0 -1029
- package/dist/wirings/ai-agent/ai-agent-turn.d.ts +0 -57
- package/dist/wirings/ai-agent/ai-agent-turn.js +0 -82
- package/dist/wirings/ai-agent/ai-agent-utils.d.ts +0 -1
- package/dist/wirings/ai-agent/ai-agent-utils.js +0 -1
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +0 -625
- package/dist/wirings/ai-agent/index.d.ts +0 -12
- package/dist/wirings/ai-agent/index.js +0 -10
- package/dist/wirings/ai-agent/voice-input.d.ts +0 -69
- package/dist/wirings/ai-agent/voice-input.js +0 -150
- package/dist/wirings/ai-agent/voice-output.d.ts +0 -85
- package/dist/wirings/ai-agent/voice-output.js +0 -196
- package/dist/wirings/ai-scorer/ai-scorer-grade.d.ts +0 -26
- package/dist/wirings/ai-scorer/ai-scorer-grade.js +0 -33
- package/dist/wirings/ai-scorer/ai-scorer-judge.d.ts +0 -17
- package/dist/wirings/ai-scorer/ai-scorer-judge.js +0 -92
- package/dist/wirings/ai-scorer/ai-scorer-live.d.ts +0 -15
- package/dist/wirings/ai-scorer/ai-scorer-live.js +0 -38
- package/dist/wirings/ai-scorer/ai-scorer-registry.d.ts +0 -18
- package/dist/wirings/ai-scorer/ai-scorer-registry.js +0 -46
- package/dist/wirings/ai-scorer/ai-scorer-sampling.d.ts +0 -8
- package/dist/wirings/ai-scorer/ai-scorer-sampling.js +0 -31
- package/dist/wirings/ai-scorer/ai-scorer-snapshots.d.ts +0 -10
- package/dist/wirings/ai-scorer/ai-scorer-snapshots.js +0 -40
- package/dist/wirings/ai-scorer/ai-scorer-worker.d.ts +0 -15
- package/dist/wirings/ai-scorer/ai-scorer-worker.js +0 -58
- package/dist/wirings/ai-scorer/ai-scorer.d.ts +0 -39
- package/dist/wirings/ai-scorer/ai-scorer.js +0 -40
- package/dist/wirings/ai-scorer/ai-scorer.types.d.ts +0 -90
- package/dist/wirings/ai-scorer/ai-scorer.types.js +0 -4
- package/dist/wirings/ai-scorer/index.d.ts +0 -6
- package/dist/wirings/ai-scorer/index.js +0 -5
- package/src/ecosystem/agent-scorer.ts +0 -24
- package/src/ecosystem/agent.ts +0 -42
- package/src/ecosystem/channel/local.ts +0 -1
- package/src/ecosystem/channel.ts +0 -22
- package/src/ecosystem/cli/channel.ts +0 -25
- package/src/ecosystem/cli.ts +0 -21
- package/src/ecosystem/credential.ts +0 -10
- package/src/ecosystem/dev.ts +0 -12
- package/src/ecosystem/function.ts +0 -28
- package/src/ecosystem/gateway.ts +0 -4
- package/src/ecosystem/hmac.ts +0 -1
- package/src/ecosystem/http.ts +0 -22
- package/src/ecosystem/mcp.ts +0 -17
- package/src/ecosystem/middleware.ts +0 -27
- package/src/ecosystem/node-host-resolver.ts +0 -1
- package/src/ecosystem/node.ts +0 -5
- package/src/ecosystem/oauth2.ts +0 -4
- package/src/ecosystem/persona.ts +0 -30
- package/src/ecosystem/queue.ts +0 -23
- package/src/ecosystem/remote.ts +0 -9
- package/src/ecosystem/role.ts +0 -13
- package/src/ecosystem/rpc.ts +0 -7
- package/src/ecosystem/safe-fetch.ts +0 -8
- package/src/ecosystem/scenario.ts +0 -32
- package/src/ecosystem/scheduler.ts +0 -5
- package/src/ecosystem/schema.ts +0 -1
- package/src/ecosystem/scope.ts +0 -14
- package/src/ecosystem/secret.ts +0 -15
- package/src/ecosystem/services/istanbul-coverage.ts +0 -1
- package/src/ecosystem/services/local-content-request-handler.ts +0 -16
- package/src/ecosystem/services/local-content.ts +0 -1
- package/src/ecosystem/services/v8-coverage.ts +0 -1
- package/src/ecosystem/services.ts +0 -82
- package/src/ecosystem/trigger.ts +0 -7
- package/src/ecosystem/types.ts +0 -34
- package/src/ecosystem/variable.ts +0 -14
- package/src/ecosystem/virtual-user.ts +0 -48
- package/src/ecosystem/workflow.ts +0 -68
- package/src/ecosystem.ts +0 -40
- package/src/index.ts +0 -244
- /package/dist/{services/ai-agent-runner-service.js → bootstrap-compat/root.js} +0 -0
- /package/dist/{services/ai-run-state-service.js → classification/data-classification.js} +0 -0
- /package/dist/{services/ai-storage-service.js → errors/serialized-error.js} +0 -0
- /package/dist/{wirings/ai-agent/ai-agent.types.js → function/function-meta.types.js} +0 -0
- /package/src/{column-form.ts → classification/column-form.ts} +0 -0
- /package/src/{pikku-request.test.ts → function/pikku-request.test.ts} +0 -0
- /package/src/{pikku-request.ts → function/pikku-request.ts} +0 -0
- /package/src/wirings/{rpc → addon}/addon-auth-tags.test.ts +0 -0
- /package/src/wirings/{rpc → addon}/addon-runner.ts +0 -0
- /package/src/wirings/{rpc → addon}/addon-secrets.test.ts +0 -0
- /package/src/wirings/{rpc → addon}/wire-addon.test.ts +0 -0
- /package/src/wirings/{rpc → addon}/wire-remote-addon.ts +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { CoreUserSession
|
|
1
|
+
import type { CoreUserSession } from '../../types/core.types.js';
|
|
2
|
+
import type { SerializedError } from '../../errors/serialized-error.js';
|
|
2
3
|
import type { GroupConcurrencyConfig, JobGroup, JobOptions } from '../queue/queue.types.js';
|
|
3
4
|
import type { PikkuWorkflowWire, StepState, StepStatus, WorkflowPlannedStep, WorkflowRun, WorkflowRunMirror, WorkflowRunStatus, WorkflowRunWire, WorkflowStatus, WorkflowVersionStatus, WorkflowQueueOptions, WorkflowStepOptions } from './workflow.types.js';
|
|
4
5
|
import type { WorkflowService } from '../../services/workflow-service.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { runPikkuFunc } from '../../function/function-runner.js';
|
|
2
2
|
import { getSingletonServices, getCreateWireServices, pikkuState, } from '../../pikku-state.js';
|
|
3
3
|
import { getDurationInMilliseconds } from '../../time-utils.js';
|
|
4
|
-
import { ChildWorkflowStartedException, continueGraph, executeGraphStep, runWorkflowGraph, runFromMeta, } from './graph/graph-runner.js';
|
|
4
|
+
import { ChildWorkflowStartedException, continueGraph, executeGraphStep, runWorkflowGraph, runFromMeta, stripInstanceOrdinal, } from './graph/graph-runner.js';
|
|
5
5
|
import { isExpectedError } from '../../errors/error-handler.js';
|
|
6
6
|
import { PikkuMissingMetaError } from '../../errors/errors.js';
|
|
7
7
|
import { RPCNotFoundError } from '../rpc/rpc-runner.js';
|
|
@@ -735,9 +735,8 @@ export class PikkuWorkflowService {
|
|
|
735
735
|
graphNodeId = stepName;
|
|
736
736
|
}
|
|
737
737
|
else {
|
|
738
|
-
const
|
|
739
|
-
|
|
740
|
-
if (base && base in workflowMeta.nodes)
|
|
738
|
+
const base = stripInstanceOrdinal(stepName);
|
|
739
|
+
if (base !== stepName && base in workflowMeta.nodes)
|
|
741
740
|
graphNodeId = base;
|
|
742
741
|
}
|
|
743
742
|
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What one `pikku scenario run` leaves behind.
|
|
3
|
+
*
|
|
4
|
+
* A run is history: the scenarios it selected, the sentences they were made of,
|
|
5
|
+
* and the images and footage they produced. The sentences are snapshotted into
|
|
6
|
+
* the record rather than looked up later, because a scenario is code and the
|
|
7
|
+
* code moves — a run from last week describes a suite that no longer exists,
|
|
8
|
+
* and re-deriving its ladder from today's source would quietly rewrite it.
|
|
9
|
+
*
|
|
10
|
+
* Everything here is plain serialisable data. That is what lets one record be
|
|
11
|
+
* a JSON file on disk in OSS and a row in Postgres on a hosted project, read
|
|
12
|
+
* back by the same console screen either way.
|
|
13
|
+
*/
|
|
14
|
+
import type { ScenarioBrowserFailure } from './scenario-step.types.js';
|
|
15
|
+
/** What a run filed, in the order it filed it. */
|
|
16
|
+
export type ScenarioArtifactKind = 'screenshot' | 'failure' | 'video';
|
|
17
|
+
/**
|
|
18
|
+
* One image or recording a scenario produced.
|
|
19
|
+
*
|
|
20
|
+
* `path` is relative to the run's artifact root and always uses forward
|
|
21
|
+
* slashes: it is a content key, not a filesystem path. Locally it resolves
|
|
22
|
+
* under the run's directory; on a hosted project it is the object key in a
|
|
23
|
+
* bucket, and the same record works unchanged.
|
|
24
|
+
*/
|
|
25
|
+
export interface ScenarioArtifact {
|
|
26
|
+
/** The scenario label this belongs to, as the report names it. */
|
|
27
|
+
scenario: string;
|
|
28
|
+
kind: ScenarioArtifactKind;
|
|
29
|
+
path: string;
|
|
30
|
+
/** Whose window it was — a two-actor scenario produces two of everything. */
|
|
31
|
+
actor?: string;
|
|
32
|
+
/** The caption the scenario author took a screenshot under. */
|
|
33
|
+
name?: string;
|
|
34
|
+
}
|
|
35
|
+
/** One step of a run, already joined to the prose that declared it. */
|
|
36
|
+
export interface ScenarioStepRow {
|
|
37
|
+
sentence: string;
|
|
38
|
+
status: string;
|
|
39
|
+
durationMs?: number;
|
|
40
|
+
error?: string;
|
|
41
|
+
}
|
|
42
|
+
/** Everything known about why one scenario failed. */
|
|
43
|
+
export interface ScenarioFailureDetail {
|
|
44
|
+
/** The rendered sentence of the failing step; absent if no step failed. */
|
|
45
|
+
sentence?: string;
|
|
46
|
+
message: string;
|
|
47
|
+
stack?: string;
|
|
48
|
+
/**
|
|
49
|
+
* True when the failure was a deliberate one (a PikkuError). Its message is
|
|
50
|
+
* the whole story, so the stack is noise.
|
|
51
|
+
*/
|
|
52
|
+
expected?: boolean;
|
|
53
|
+
browser?: ScenarioBrowserFailure[];
|
|
54
|
+
}
|
|
55
|
+
export interface ScenarioResult {
|
|
56
|
+
name: string;
|
|
57
|
+
status: 'passed' | 'failed';
|
|
58
|
+
durationMs: number;
|
|
59
|
+
output?: unknown;
|
|
60
|
+
error?: string;
|
|
61
|
+
steps?: ScenarioStepRow[];
|
|
62
|
+
failure?: ScenarioFailureDetail;
|
|
63
|
+
/** The scenario registration this ran, which the label alone does not give. */
|
|
64
|
+
scenarioName?: string;
|
|
65
|
+
/** The feature that grouped it, when one did. */
|
|
66
|
+
feature?: string;
|
|
67
|
+
tags?: string[];
|
|
68
|
+
/** Images and footage this scenario produced, filed under the run. */
|
|
69
|
+
artifacts?: ScenarioArtifact[];
|
|
70
|
+
}
|
|
71
|
+
/** One scenario that was not run, and why. */
|
|
72
|
+
export interface ScenarioSkip {
|
|
73
|
+
name: string;
|
|
74
|
+
reason: string;
|
|
75
|
+
}
|
|
76
|
+
export interface ScenarioRunReport {
|
|
77
|
+
environment: string;
|
|
78
|
+
results: ScenarioResult[];
|
|
79
|
+
/**
|
|
80
|
+
* Scenarios not run at all, each carrying why. A skip is only useful if the
|
|
81
|
+
* reader can tell a browser scenario held back by `--no-browser` from one the
|
|
82
|
+
* project itself quarantined, so the reason travels with the name rather than
|
|
83
|
+
* being assumed by the formatter.
|
|
84
|
+
*/
|
|
85
|
+
skipped: ScenarioSkip[];
|
|
86
|
+
/** Feature-level hook failures, which belong to no single scenario. */
|
|
87
|
+
hookFailures: string[];
|
|
88
|
+
}
|
|
89
|
+
export type ScenarioRunStatus = 'running' | 'passed' | 'failed';
|
|
90
|
+
/**
|
|
91
|
+
* A whole run, as it is stored and read back.
|
|
92
|
+
*
|
|
93
|
+
* `status` is `running` from the moment the run is created until it finishes,
|
|
94
|
+
* so a console watching a run in progress can tell "still going" from "nothing
|
|
95
|
+
* came back" — and a run killed halfway stays `running` forever, which is the
|
|
96
|
+
* honest record of what happened to it.
|
|
97
|
+
*/
|
|
98
|
+
export interface ScenarioRunRecord extends ScenarioRunReport {
|
|
99
|
+
runId: string;
|
|
100
|
+
status: ScenarioRunStatus;
|
|
101
|
+
/** The surface the run targeted: `default`, `browser`, … */
|
|
102
|
+
surface: string;
|
|
103
|
+
startedAt: string;
|
|
104
|
+
finishedAt?: string;
|
|
105
|
+
}
|
|
106
|
+
/** Enough of a run to list it without loading its steps and stacks. */
|
|
107
|
+
export interface ScenarioRunSummary {
|
|
108
|
+
runId: string;
|
|
109
|
+
environment: string;
|
|
110
|
+
surface: string;
|
|
111
|
+
status: ScenarioRunStatus;
|
|
112
|
+
startedAt: string;
|
|
113
|
+
finishedAt?: string;
|
|
114
|
+
durationMs?: number;
|
|
115
|
+
passed: number;
|
|
116
|
+
failed: number;
|
|
117
|
+
skipped: number;
|
|
118
|
+
/** Whether anything is there to watch, so a list can say so without a second read. */
|
|
119
|
+
artifacts: number;
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Where runs are kept.
|
|
123
|
+
*
|
|
124
|
+
* Deliberately not the workflow service: a scenario run is a workflow run under
|
|
125
|
+
* the hood, but its history has a different lifetime, a different audience, and
|
|
126
|
+
* a different home — a JSON file beside the project locally, a project-scoped
|
|
127
|
+
* table and an object store when hosted.
|
|
128
|
+
*
|
|
129
|
+
* Written progressively rather than at the end, so a suite that dies on its
|
|
130
|
+
* fortieth scenario still leaves the thirty-nine behind.
|
|
131
|
+
*/
|
|
132
|
+
export interface ScenarioRunStore {
|
|
133
|
+
/** Open a run. Called before the first scenario, with `status: 'running'`. */
|
|
134
|
+
start(record: ScenarioRunRecord): Promise<void>;
|
|
135
|
+
/** Append one finished scenario to an open run. */
|
|
136
|
+
recordScenario(runId: string, result: ScenarioResult): Promise<void>;
|
|
137
|
+
/**
|
|
138
|
+
* File the run's artifacts against the scenarios that produced them.
|
|
139
|
+
*
|
|
140
|
+
* Separate from `recordScenario` because a scenario's video does not exist
|
|
141
|
+
* when the scenario ends — it is finalised by the next scenario's reset, and
|
|
142
|
+
* renamed again when the run closes. Artifacts are matched to a result by the
|
|
143
|
+
* label the report knows it under.
|
|
144
|
+
*/
|
|
145
|
+
attachArtifacts(runId: string, artifacts: ScenarioArtifact[]): Promise<void>;
|
|
146
|
+
/** Close a run, settling everything only known once every scenario has run. */
|
|
147
|
+
finish(runId: string, outcome: Pick<ScenarioRunRecord, 'status' | 'finishedAt' | 'skipped' | 'hookFailures'>): Promise<void>;
|
|
148
|
+
/**
|
|
149
|
+
* The bytes of one artifact, by the `path` its record carries.
|
|
150
|
+
*
|
|
151
|
+
* Reading goes through the store because only the store knows where a run's
|
|
152
|
+
* files actually are — a directory beside the project, or an object store
|
|
153
|
+
* behind a bucket. Absent when the run or the path is unknown, which is also
|
|
154
|
+
* the answer for a path that tries to leave the run.
|
|
155
|
+
*
|
|
156
|
+
* The bytes are backed by their own `ArrayBuffer` so they can be handed
|
|
157
|
+
* straight to a `Response` — a view onto a pooled or shared buffer is not a
|
|
158
|
+
* valid body.
|
|
159
|
+
*/
|
|
160
|
+
readArtifact(runId: string, path: string): Promise<{
|
|
161
|
+
body: Uint8Array<ArrayBuffer>;
|
|
162
|
+
contentType: string;
|
|
163
|
+
} | undefined>;
|
|
164
|
+
/** Most recent first. */
|
|
165
|
+
list(options?: {
|
|
166
|
+
limit?: number;
|
|
167
|
+
}): Promise<ScenarioRunSummary[]>;
|
|
168
|
+
get(runId: string): Promise<ScenarioRunRecord | undefined>;
|
|
169
|
+
/** Forget a run and everything it filed. */
|
|
170
|
+
remove(runId: string): Promise<void>;
|
|
171
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
import type { PikkuScenarioStepWire, ScenarioEnvironment } from './scenario-step.types.js';
|
|
2
|
-
export declare const
|
|
3
|
-
export declare const requireScenarioEnv: (scenarioStep: PikkuScenarioStepWire<unknown> | undefined) => ScenarioEnvironment;
|
|
2
|
+
export declare const requireScenarioEnv: (scenarioStep: PikkuScenarioStepWire | undefined) => ScenarioEnvironment;
|
|
@@ -1,11 +1,3 @@
|
|
|
1
|
-
export const requireActor = (scenarioStep) => {
|
|
2
|
-
const actor = scenarioStep?.actor;
|
|
3
|
-
if (!actor) {
|
|
4
|
-
throw new Error(`[scenario] step '${scenarioStep?.name ?? 'unknown'}' was called without an actor. ` +
|
|
5
|
-
`Pass { actor: actors.<name> } so it runs as that persona.`);
|
|
6
|
-
}
|
|
7
|
-
return actor;
|
|
8
|
-
};
|
|
9
1
|
export const requireScenarioEnv = (scenarioStep) => {
|
|
10
2
|
const env = scenarioStep?.env;
|
|
11
3
|
if (!env) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { ScenarioArtifact } from './scenario-run.types.js';
|
|
2
2
|
/**
|
|
3
3
|
* Scenario steps: named, typed units of scenario behaviour.
|
|
4
4
|
*
|
|
@@ -86,7 +86,10 @@ export type ScenarioSurfaceResolution = {
|
|
|
86
86
|
* default to no retries.
|
|
87
87
|
*/
|
|
88
88
|
export interface ScenarioStepOptions {
|
|
89
|
-
/**
|
|
89
|
+
/**
|
|
90
|
+
* The actor this step runs as. Required for a step that declares `actor: true`
|
|
91
|
+
* or a `browser` binding; the runner refuses to dispatch one without it.
|
|
92
|
+
*/
|
|
90
93
|
actor?: unknown;
|
|
91
94
|
/** Overrides the step's own `description` for this call site only. */
|
|
92
95
|
description?: string;
|
|
@@ -107,11 +110,12 @@ export interface ScenarioEnvironment {
|
|
|
107
110
|
/**
|
|
108
111
|
* The `scenarioStep` wire, present on every scenario step invocation.
|
|
109
112
|
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
113
|
+
* The persona a step runs as is not here: it arrives as `wire.actor`, injected
|
|
114
|
+
* by the runner and typed as present exactly on the bindings that declared they
|
|
115
|
+
* need one. Keeping it off this interface is what makes that possible — a wire
|
|
116
|
+
* member can be required per binding, a property of one cannot.
|
|
113
117
|
*/
|
|
114
|
-
export interface PikkuScenarioStepWire
|
|
118
|
+
export interface PikkuScenarioStepWire {
|
|
115
119
|
/** Registered step name (also its pikkuFuncId) */
|
|
116
120
|
name: string;
|
|
117
121
|
/** Durable key within the run; may carry an `#ordinal` suffix when repeated */
|
|
@@ -123,12 +127,6 @@ export interface PikkuScenarioStepWire<TActor = ScenarioPersona> {
|
|
|
123
127
|
* per witness, so its body sees this change between invocations.
|
|
124
128
|
*/
|
|
125
129
|
surface: ScenarioSurface;
|
|
126
|
-
/**
|
|
127
|
-
* The actor this step runs as, when one was given. Call RPCs through it
|
|
128
|
-
* (`actor.invoke(...)`) so they run against the target environment as that
|
|
129
|
-
* persona.
|
|
130
|
-
*/
|
|
131
|
-
actor?: TActor;
|
|
132
130
|
/**
|
|
133
131
|
* The environment this run targets. A step runs in the CLI process, where
|
|
134
132
|
* there is no `variables` service — this is how a raw-HTTP step learns the
|
|
@@ -218,11 +216,28 @@ export interface ScenarioBrowserProvider {
|
|
|
218
216
|
* folder — findable only by timestamp.
|
|
219
217
|
*/
|
|
220
218
|
beginScenario?(scenario: string): void;
|
|
219
|
+
/**
|
|
220
|
+
* Report how the scenario that just ran finished.
|
|
221
|
+
*
|
|
222
|
+
* Called after each scenario, and separate from `reset()` because artifacts
|
|
223
|
+
* that only exist once a window closes — a video — are produced by the NEXT
|
|
224
|
+
* scenario's reset, long after the outcome that decides whether to keep them.
|
|
225
|
+
*/
|
|
226
|
+
endScenario?(outcome: 'passed' | 'failed'): void;
|
|
221
227
|
/**
|
|
222
228
|
* Snapshot every open window for a failed scenario. `label` identifies the
|
|
223
229
|
* scenario in artifact filenames. Never throws: a failure to capture must
|
|
224
230
|
* not replace the failure being captured.
|
|
225
231
|
*/
|
|
226
232
|
captureFailure?(label: string): Promise<ScenarioBrowserFailure[]>;
|
|
233
|
+
/**
|
|
234
|
+
* Everything the run filed, each entry naming the scenario it belongs to.
|
|
235
|
+
*
|
|
236
|
+
* Reported by the driver rather than discovered by scanning the directory:
|
|
237
|
+
* only the driver knows which window produced a file and under what caption,
|
|
238
|
+
* and a video's final name is not settled until the run closes. Read after
|
|
239
|
+
* `close()`, which is the first moment the answer is complete.
|
|
240
|
+
*/
|
|
241
|
+
artifacts?(): ScenarioArtifact[];
|
|
227
242
|
close(): Promise<void>;
|
|
228
243
|
}
|
|
@@ -103,7 +103,8 @@ export const evaluateApprovalStep = async (store, runId, reason, approvalStepNam
|
|
|
103
103
|
return stepState.result;
|
|
104
104
|
}
|
|
105
105
|
const stateKey = approvalStateKey(approvalStepName);
|
|
106
|
-
let record = ((await store.getRunState(runId))[stateKey] ??
|
|
106
|
+
let record = ((await store.getRunState(runId))[stateKey] ??
|
|
107
|
+
{});
|
|
107
108
|
const policy = {
|
|
108
109
|
approvers: options.approvers,
|
|
109
110
|
approverScope: options.approverScope,
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { PikkuRawWire
|
|
1
|
+
import type { PikkuRawWire } from '../../types/core.types.js';
|
|
2
|
+
import type { SerializedError } from '../../errors/serialized-error.js';
|
|
2
3
|
import type { CoreWorkflow, PikkuWorkflowWire, StepState, WorkflowRun, WorkflowStatus, WorkflowStepOptions } from './workflow.types.js';
|
|
3
4
|
export interface RunLifecycleContext {
|
|
4
5
|
runId: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type { CommonWireMeta } from '../../types/core.types.js';
|
|
2
|
+
import type { SerializedError } from '../../errors/serialized-error.js';
|
|
2
3
|
import type { CorePikkuFunctionConfig } from '../../function/functions.types.js';
|
|
3
4
|
import type { GroupConcurrencyConfig } from '../queue/queue.types.js';
|
|
4
5
|
export type { WorkflowService } from '../../services/workflow-service.js';
|
|
@@ -14,6 +14,8 @@ here first — several of these exist because the obvious simplification was tri
|
|
|
14
14
|
and broke something.
|
|
15
15
|
|
|
16
16
|
<!-- pikku:knowledge-index -->
|
|
17
|
+
|
|
17
18
|
- [internals](internals/index.md) — a rule about how it works under the hood, and why
|
|
18
19
|
- [security](security/index.md) — a rule about who may do what
|
|
20
|
+
|
|
19
21
|
<!-- /pikku:knowledge-index -->
|
|
@@ -14,7 +14,7 @@ A reporter fills those placeholders from a run that already happened. There is
|
|
|
14
14
|
no run yet at derivation time, so there is nothing to fill them from. More
|
|
15
15
|
importantly, filling them would answer the wrong question: "invites {email}"
|
|
16
16
|
tells the user to choose someone, where "invites ada@example.com" tells it whom
|
|
17
|
-
— and
|
|
17
|
+
— and _whom_ is the scenario author's answer, not something the virtual user
|
|
18
18
|
worked out.
|
|
19
19
|
|
|
20
20
|
**What this rules out:** substituting example or fixture values to make the
|
package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md
CHANGED
|
@@ -37,7 +37,7 @@ that turn that into a one-line fix, and they are known at the catch site and
|
|
|
37
37
|
nowhere after it.
|
|
38
38
|
|
|
39
39
|
This matters most at exactly the moment it is least convenient: a change to
|
|
40
|
-
`deriveKEK` makes
|
|
40
|
+
`deriveKEK` makes _every_ previously stored secret undecryptable at once. Loud
|
|
41
41
|
failure names the first one; silence produces an empty map and a support ticket.
|
|
42
42
|
|
|
43
43
|
**What this rules out:** a `getSecrets` that skips unreadable rows; returning
|
package/knowledge/decisions/internals/a-virtual-user-run-is-not-a-workflow-and-not-a-queued-job.md
CHANGED
|
@@ -18,9 +18,9 @@ Both of the alternatives are the obvious ones, and both are wrong for this.
|
|
|
18
18
|
resumed at the step it died on, and that the same input reaches the same step.
|
|
19
19
|
A virtual user is the opposite by construction — it is an LLM deciding what to
|
|
20
20
|
try next, so no two attempts take the same steps, and there is no step to resume
|
|
21
|
-
|
|
21
|
+
_to_. Recording a run as a workflow puts entries in the workflow store that can
|
|
22
22
|
never be replayed, and gives every operator reading that store a row that lies
|
|
23
|
-
about what it is. The seed makes a run
|
|
23
|
+
about what it is. The seed makes a run _reproducible_ — run it again and it
|
|
24
24
|
explores the same way — which is a different property from resumable, and one
|
|
25
25
|
the record already carries.
|
|
26
26
|
|
|
@@ -13,11 +13,11 @@ per secret turns a 10ms operation into a 4-second one.
|
|
|
13
13
|
|
|
14
14
|
It guarded it with `assert.ok(elapsed < 50)`. Measured on this machine:
|
|
15
15
|
|
|
16
|
-
|
|
|
17
|
-
|
|
|
18
|
-
| one `deriveKEK`
|
|
19
|
-
| 50 `envelopeDecrypt`
|
|
20
|
-
| the old 50ms threshold
|
|
16
|
+
| | |
|
|
17
|
+
| ----------------------------- | ------------------------------- |
|
|
18
|
+
| one `deriveKEK` | ~86ms |
|
|
19
|
+
| 50 `envelopeDecrypt` | 10.8ms |
|
|
20
|
+
| the old 50ms threshold | 4.6x headroom |
|
|
21
21
|
| the failure it guards against | ~4281ms — a **396x** separation |
|
|
22
22
|
|
|
23
23
|
So the assertion had 4.6x of margin to detect a 396x regression. Everything
|
|
@@ -37,7 +37,7 @@ suite grows or CI moves to a noisier runner. Any assertion of the form
|
|
|
37
37
|
ratio against something measured alongside it.
|
|
38
38
|
|
|
39
39
|
Worth knowing: `envelopeDecrypt(kek: CryptoKey, …)` takes the derived key as a
|
|
40
|
-
parameter, so it
|
|
40
|
+
parameter, so it _cannot_ derive one — the property is already enforced by the
|
|
41
41
|
signature, and [[the-api-report-pins-members-not-just-names]] would catch a
|
|
42
42
|
change to it. The test is defence in depth, which is a reason to make it cheap
|
|
43
43
|
and quiet rather than to delete it.
|
|
@@ -18,7 +18,7 @@ pikkuUserId: rpcService.wire?.pikkuUserId,
|
|
|
18
18
|
```
|
|
19
19
|
|
|
20
20
|
`PikkuRPC` has no `wire`. Neither does the object `getContextRPCService`
|
|
21
|
-
actually returns — `ContextAwareRPCService` holds its wire
|
|
21
|
+
actually returns — `ContextAwareRPCService` holds its wire _privately_ and
|
|
22
22
|
exposes `invoke`, `remote`, `exposed`, `startWorkflow`, `agent` and
|
|
23
23
|
`rpcWithWire`, and nothing else. Every one of those reads was `undefined`, and
|
|
24
24
|
the `rpcService: any` parameter type is what kept the compiler quiet about it.
|
|
@@ -17,7 +17,7 @@ One package may be wired twice — the same payments addon against a live and a
|
|
|
17
17
|
sandbox account, say — with different secret and variable names. Caching by
|
|
18
18
|
package name would build the service graph once, from whichever instance called
|
|
19
19
|
first, and silently hand the other instance the wrong credentials. Because the
|
|
20
|
-
overrides have to be visible to the addon's
|
|
20
|
+
overrides have to be visible to the addon's _own_ `createSingletonServices`, they
|
|
21
21
|
are applied by wrapping the parent `secrets` and `variables` services
|
|
22
22
|
(`aliasSecretService`, `aliasVariablesService`) so that every logical name the
|
|
23
23
|
addon reads is remapped to the real project name before resolution. A call with
|
|
@@ -15,7 +15,7 @@ instance namespace when known and otherwise the package's sole namespace via
|
|
|
15
15
|
`findAddonNamespaceForPackage`.
|
|
16
16
|
|
|
17
17
|
Workflows declared by an addon are registered under the addon's package scope,
|
|
18
|
-
but the namespace they answer to is chosen by the
|
|
18
|
+
but the namespace they answer to is chosen by the _consumer_ in `wireAddon`.
|
|
19
19
|
Without the proxy, `runToCompletion('myWorkflow')` written inside the addon
|
|
20
20
|
resolves against root meta, misses, and throws `WorkflowNotFoundError` — leaving
|
|
21
21
|
the addon author no option but to hardcode the consumer-defined namespace, which
|
|
@@ -24,7 +24,7 @@ permissions bug rather than a merge that dropped.
|
|
|
24
24
|
This is a different rule from
|
|
25
25
|
[scope roots may be co-declared by an addon and its host
|
|
26
26
|
app](scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md): that one
|
|
27
|
-
is about `flattenScopeDefinitions` deduping ids
|
|
27
|
+
is about `flattenScopeDefinitions` deduping ids _within_ a build where both
|
|
28
28
|
declarations are present and identical. This one is about the addon's copy never
|
|
29
29
|
arriving. The consequence for addon authors is the same either way — own a root
|
|
30
30
|
outright, named for the package or vendor, and nest everything under it. It is
|
package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md
CHANGED
|
@@ -14,7 +14,7 @@ things a caller may put on `onMessage` or inside `onMessageWiring`:
|
|
|
14
14
|
- a direct function config, where `onMessage.func` is a plain `Function`;
|
|
15
15
|
- a wrapper, where `onMessage.func` is itself a `CorePikkuFunctionConfig` and so
|
|
16
16
|
has its own nested `.func`;
|
|
17
|
-
- a simple wrapper, which carries a plain `Function` under `func`
|
|
17
|
+
- a simple wrapper, which carries a plain `Function` under `func` _and_ a
|
|
18
18
|
sibling `middleware` array.
|
|
19
19
|
|
|
20
20
|
The `isWrapper` check tests exactly that: an object with `func`, where either
|
|
@@ -19,7 +19,7 @@ user's stream and growing memory run over run. It is therefore appended fresh on
|
|
|
19
19
|
every call, after the cached inherited slice.
|
|
20
20
|
|
|
21
21
|
The `uid` matters as much as the cache split. `processMessageHandlers` in
|
|
22
|
-
`channel-handler.ts` builds it from the channel name
|
|
22
|
+
`channel-handler.ts` builds it from the channel name _plus_ the routing property
|
|
23
23
|
and router value (`${name}:${routingProperty}:${routerValue}`, or
|
|
24
24
|
`${name}:default`), because several message routes on one channel may point at
|
|
25
25
|
the same function — a key based on the function alone would serve one route's
|
|
@@ -10,7 +10,7 @@ tags: channel
|
|
|
10
10
|
`runChannelConnect` in
|
|
11
11
|
`packages/core/src/wirings/channel/serverless/serverless-channel-runner.ts`
|
|
12
12
|
reads `userSession.getPikkuUserId()` and calls `channelStore.setPikkuUserId`
|
|
13
|
-
|
|
13
|
+
_after_ `runChannelLifecycleWithMiddleware` has executed the `onConnect`
|
|
14
14
|
lifecycle, not before.
|
|
15
15
|
|
|
16
16
|
Auth middleware runs as part of that lifecycle — it is what inspects the upgrade
|
|
@@ -19,7 +19,7 @@ the conversion happens. The parser normalises every incoming `--from-plan` to
|
|
|
19
19
|
`fromPlan` on the way in, and both `formatOptions` (help text) and the
|
|
20
20
|
"Missing required option" / "Invalid value for" errors render back to kebab on
|
|
21
21
|
the way out. `suggestOption` deliberately compares the typed string against
|
|
22
|
-
|
|
22
|
+
_both_ forms, so `--autoApply` and `--auto-apply` both find `autoApply`.
|
|
23
23
|
|
|
24
24
|
**What this rules out:** storing option keys kebab-cased anywhere in CLI state or
|
|
25
25
|
metadata — the schema pluck would then match nothing and every option would be
|
|
@@ -18,7 +18,7 @@ mistake (show the help text) or a value mistake (print the errors) by
|
|
|
18
18
|
This is why the parser pushes `Missing subcommand: <path>` for a group command
|
|
19
19
|
that has subcommands but no `pikkuFuncId` of its own, rather than simply
|
|
20
20
|
returning the command meta and letting the runner discover it is unrunnable. The
|
|
21
|
-
message
|
|
21
|
+
message _is_ the routing signal. Rewording any of those three strings, or
|
|
22
22
|
localising them, silently turns "show me the subcommands" into a raw error dump.
|
|
23
23
|
|
|
24
24
|
**What this rules out:** editing those error message prefixes without updating
|
|
@@ -18,7 +18,7 @@ The reason is forward compatibility: a script or wrapper written against a newer
|
|
|
18
18
|
command version may pass options an older installed binary does not know, and
|
|
19
19
|
failing hard there turns a harmless extra flag into a broken pipeline.
|
|
20
20
|
`RESERVED_OPTIONS` exempts flags the runner handles itself (`help`) from the
|
|
21
|
-
warning. Unknown
|
|
21
|
+
warning. Unknown _short_ flags are treated differently — they go to
|
|
22
22
|
`result.errors` and do fail — because a bundled short-flag cluster like `-abc`
|
|
23
23
|
cannot be reliably attributed, and a typo'd short flag is far more likely than a
|
|
24
24
|
version skew.
|
|
@@ -15,13 +15,13 @@ value leave the process?".
|
|
|
15
15
|
The two axes were one field before this, with `security: 'encrypted'` sitting
|
|
16
16
|
alongside `secret` as though they were alternatives. They are not, and the
|
|
17
17
|
conflation made the field unanswerable: a token hash and a live bearer token are
|
|
18
|
-
both `secret`, one must never be encrypted — the digest
|
|
18
|
+
both `secret`, one must never be encrypted — the digest _is_ the lookup key —
|
|
19
19
|
and the other must always be. Nothing in a single enum could tell them apart, so
|
|
20
20
|
nothing could check either.
|
|
21
21
|
|
|
22
22
|
## Why `wrapped` and `sealed` rather than `encrypted`
|
|
23
23
|
|
|
24
|
-
Sealed values
|
|
24
|
+
Sealed values _are_ encrypted, so an `encrypted` member sitting beside `sealed`
|
|
25
25
|
would be a supertype posing as a sibling, and every new column would be an
|
|
26
26
|
even-odds guess. What actually separates them is who can read the value back:
|
|
27
27
|
`wrapped` is symmetric and the application holds the key; `sealed` is asymmetric
|
|
@@ -64,7 +64,7 @@ it would buy nothing — feeding in the wrong string already fails at the AEAD t
|
|
|
64
64
|
— while forcing a cast into every path that reads ciphertext out of a row or off
|
|
65
65
|
the wire, which is where casts are least reviewable.
|
|
66
66
|
|
|
67
|
-
The brand proves
|
|
67
|
+
The brand proves _provenance_, not correctness. It cannot know a value was
|
|
68
68
|
wrapped under the right key, and making it know would mean phantom-typing key
|
|
69
69
|
ids per scope, which the multi-recipient path would fight constantly.
|
|
70
70
|
|
|
@@ -75,7 +75,7 @@ error. Every project predating the axis has such columns, and failing their next
|
|
|
75
75
|
`db migrate` would be a breaking change for a diagnosis they have not had a
|
|
76
76
|
chance to act on. `pikku db --fail-on-warn` is how a project opts into the
|
|
77
77
|
ratchet. An explicit `form: 'plain'` silences it — that is the acknowledgement
|
|
78
|
-
that reading the row is
|
|
78
|
+
that reading the row is _meant_ to yield a usable credential.
|
|
79
79
|
|
|
80
80
|
**What this rules out:** collapsing `wrapped` and `sealed` back into one
|
|
81
81
|
`encrypted`; making the form brands optional (they would enforce nothing);
|
package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md
CHANGED
|
@@ -16,7 +16,7 @@ A required property would make a plain value unassignable to a branded column: a
|
|
|
16
16
|
`string` could no longer be passed where `Private<string>` is expected, which
|
|
17
17
|
breaks every ordinary Kysely query operand — `where('email', '=', someString)`,
|
|
18
18
|
inserts, and `.set(...)`. Making it optional keeps the brand structurally present
|
|
19
|
-
so static analysis still sees it, while letting plain values flow
|
|
19
|
+
so static analysis still sees it, while letting plain values flow _in_. The
|
|
20
20
|
asymmetry is the point: the brand constrains what comes out of a query, not what
|
|
21
21
|
goes into one.
|
|
22
22
|
|
package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md
CHANGED
|
@@ -9,7 +9,7 @@ tags: core
|
|
|
9
9
|
|
|
10
10
|
`runPikkuFunc` in `packages/core/src/function/function-runner.ts` does not build a
|
|
11
11
|
fresh wire per call. Nested invocations — an RPC from inside a function, an addon
|
|
12
|
-
sibling call, a workflow step — reuse the
|
|
12
|
+
sibling call, a workflow step — reuse the _same_ wire object the outer transport
|
|
13
13
|
created. So before it runs, the runner captures `functionId`, `audit`,
|
|
14
14
|
`addonNamespace` and the property descriptor for `rpc`, overwrites them for the
|
|
15
15
|
duration of this function, and restores or `delete`s them in a `finally`. Both
|
|
@@ -18,7 +18,7 @@ inner call would leave its identity on the wire and every subsequent outer step
|
|
|
18
18
|
would be attributed to the wrong function.
|
|
19
19
|
|
|
20
20
|
The same reuse is why the audit binding is re-gated inside `executeFunction`
|
|
21
|
-
rather than trusted from `createWireServices`. The audit
|
|
21
|
+
rather than trusted from `createWireServices`. The audit _gate_ is per-function
|
|
22
22
|
but the `auditLog` wire service is created per-transport-invocation. A nested or
|
|
23
23
|
exposed-RPC call would otherwise inherit an `auditLog` built while the outer
|
|
24
24
|
wire's audit config was unset (the generated `rpcCaller` declares none), and
|
|
@@ -32,7 +32,7 @@ then the auth/readonly checks, then `verifyScopes` — all of which depend only
|
|
|
32
32
|
the session — and only then `await data()`, schema defaults, coercion, validation
|
|
33
33
|
and `runPermissions`. A request denied by scope never pays to parse or validate
|
|
34
34
|
its body. `rpc` is installed as a lazily-evaluating accessor that replaces itself
|
|
35
|
-
with the resolved value on first read, capturing the
|
|
35
|
+
with the resolved value on first read, capturing the _caller's_ package name in
|
|
36
36
|
the closure so an addon's RPCs resolve in its own namespace.
|
|
37
37
|
|
|
38
38
|
**What this rules out:** dropping the save/restore blocks as duplicated
|
package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md
CHANGED
|
@@ -22,7 +22,7 @@ workflow job fails with `Function meta not found: pikkuWorkflowOrchestrator`.
|
|
|
22
22
|
`dev/reload-meta.test.ts` pins this. Meta maps that only codegen ever writes
|
|
23
23
|
(`http`, `rpc`, `agent`) are assigned outright.
|
|
24
24
|
|
|
25
|
-
Two limits are inherent rather than incidental. Routes registered by a
|
|
25
|
+
Two limits are inherent rather than incidental. Routes registered by a _new_
|
|
26
26
|
`wireHTTP` file are not picked up here — those modules were never imported — which
|
|
27
27
|
is why `hot-reload.ts` keeps a `postCodegenQueue` and exposes `reimportPending()`
|
|
28
28
|
for the dev server to drain after codegen, so registrations that were skipped for
|
|
@@ -35,5 +35,5 @@ entry stranded until a restart.
|
|
|
35
35
|
`pikkuState(null, 'function', 'meta', functionsMeta)` assignments on the grounds
|
|
36
36
|
that codegen output is authoritative — it is authoritative only for what codegen
|
|
37
37
|
emits. It also rules out folding `reimportPending()` back into the debounced
|
|
38
|
-
reload (the whole point is that it runs
|
|
38
|
+
reload (the whole point is that it runs _after_ codegen), and dropping
|
|
39
39
|
`reconcileAddonRegistry` as dead code.
|
|
@@ -23,7 +23,7 @@ edits, and eventually OOMs a long editing session. `dev/module-runner.test.ts`
|
|
|
23
23
|
asserts both the single-slot guarantee and bounded heap growth.
|
|
24
24
|
|
|
25
25
|
Two details keep the mechanism honest. `import`s inside the user file are
|
|
26
|
-
delegated to `createRequire`, whose resolution matches the native loader
|
|
26
|
+
delegated to `createRequire`, whose resolution matches the native loader _and_
|
|
27
27
|
returns the same live singletons (Node and Bun share the require/import cache) —
|
|
28
28
|
that is what lets a reloaded file's top-level `wireHTTP` side effects mutate the
|
|
29
29
|
services the running server is already using. And esbuild is invoked with no
|
|
@@ -37,6 +37,6 @@ code.
|
|
|
37
37
|
import(url + '?t=' + Date.now())` or any fresh-URL variant, and turning
|
|
38
38
|
sourcemaps back on for nicer stack traces (`filename` already anchors traces to
|
|
39
39
|
the user file). It also rules out swapping `createRequire` for a fresh `import()`
|
|
40
|
-
inside the compiled module — resolution would produce a
|
|
40
|
+
inside the compiled module — resolution would produce a _distinct_ copy of every
|
|
41
41
|
dependency, and the reloaded file would then wire itself into services nobody is
|
|
42
42
|
serving from.
|
|
@@ -19,7 +19,7 @@ finally passed through `freezeDedupe` and cached in `middlewareCache` keyed by
|
|
|
19
19
|
wire type and wire id.
|
|
20
20
|
|
|
21
21
|
Two properties fall out of that and both are load-bearing. Because the sort is
|
|
22
|
-
stable, priority is a coarse band and registration order breaks ties
|
|
22
|
+
stable, priority is a coarse band and registration order breaks ties _within_ a
|
|
23
23
|
band, so declaration order still means something. And because the result is
|
|
24
24
|
deduped by function identity, a middleware reachable through both a tag group and
|
|
25
25
|
a direct wire registration runs exactly once — a fact several tests assert
|