@pikku/addon-console 0.12.44 → 0.12.46
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 +136 -0
- package/dist/.pikku/addon/agent/index.d.ts +1 -1
- package/dist/.pikku/addon/agent/index.js +1 -1
- package/dist/.pikku/addon/agent/pikku-agent-map.gen.d.ts +1 -1
- package/dist/.pikku/addon/agent/pikku-agent-types.gen.d.ts +42 -1
- package/dist/.pikku/addon/agent/pikku-agent-types.gen.d.ts.map +1 -1
- package/dist/.pikku/addon/agent/pikku-agent-types.gen.js +41 -0
- package/dist/.pikku/addon/agent/pikku-agent-types.gen.js.map +1 -1
- package/dist/.pikku/addon/agent/pikku-model-aliases.gen.js +1 -1
- package/dist/.pikku/addon/agent/pikku-scorer-names.gen.d.ts +1 -1
- package/dist/.pikku/addon/auth/auth.types.d.ts +1 -1
- package/dist/.pikku/addon/auth/auth.types.js +1 -1
- package/dist/.pikku/addon/auth/index.d.ts +1 -1
- package/dist/.pikku/addon/auth/index.js +1 -1
- package/dist/.pikku/addon/auth/pikku-auth-types.gen.d.ts +10 -20
- package/dist/.pikku/addon/auth/pikku-auth-types.gen.d.ts.map +1 -1
- package/dist/.pikku/addon/auth/pikku-auth-types.gen.js +2 -19
- package/dist/.pikku/addon/auth/pikku-auth-types.gen.js.map +1 -1
- package/dist/.pikku/addon/channel/index.d.ts +1 -1
- package/dist/.pikku/addon/channel/index.js +1 -1
- package/dist/.pikku/addon/channel/pikku-channel-types.gen.d.ts +8 -18
- package/dist/.pikku/addon/channel/pikku-channel-types.gen.d.ts.map +1 -1
- package/dist/.pikku/addon/channel/pikku-channel-types.gen.js +7 -1
- package/dist/.pikku/addon/channel/pikku-channel-types.gen.js.map +1 -1
- package/dist/.pikku/addon/error/index.d.ts +1 -1
- package/dist/.pikku/addon/error/index.js +1 -1
- package/dist/.pikku/addon/error/pikku-error-types.gen.d.ts +1 -1
- package/dist/.pikku/addon/error/pikku-error-types.gen.js +1 -1
- package/dist/.pikku/addon/function/index.d.ts +1 -1
- package/dist/.pikku/addon/function/index.js +1 -1
- package/dist/.pikku/addon/function/pikku-function-types.gen.d.ts +47 -38
- package/dist/.pikku/addon/function/pikku-function-types.gen.d.ts.map +1 -1
- package/dist/.pikku/addon/function/pikku-function-types.gen.js +21 -9
- package/dist/.pikku/addon/function/pikku-function-types.gen.js.map +1 -1
- package/dist/.pikku/addon/function/pikku-functions-meta-verbose.gen.json +150 -22
- package/dist/.pikku/addon/function/pikku-functions-meta.gen.js +1 -1
- package/dist/.pikku/addon/function/pikku-functions-meta.gen.json +117 -16
- package/dist/.pikku/addon/function/pikku-functions.gen.js +7 -1
- package/dist/.pikku/addon/function/pikku-functions.gen.js.map +1 -1
- package/dist/.pikku/addon/http/index.d.ts +1 -1
- package/dist/.pikku/addon/http/index.js +1 -1
- package/dist/.pikku/addon/http/pikku-http-types.gen.d.ts +3 -1
- package/dist/.pikku/addon/http/pikku-http-types.gen.d.ts.map +1 -1
- package/dist/.pikku/addon/http/pikku-http-types.gen.js +1 -1
- package/dist/.pikku/addon/http/pikku-http-types.gen.js.map +1 -1
- package/dist/.pikku/addon/mcp/index.d.ts +1 -1
- package/dist/.pikku/addon/mcp/index.js +1 -1
- package/dist/.pikku/addon/mcp/pikku-mcp-types.gen.d.ts +7 -1
- package/dist/.pikku/addon/mcp/pikku-mcp-types.gen.d.ts.map +1 -1
- package/dist/.pikku/addon/mcp/pikku-mcp-types.gen.js +1 -1
- package/dist/.pikku/addon/mcp/pikku-mcp-types.gen.js.map +1 -1
- package/dist/.pikku/addon/middleware/index.d.ts +1 -1
- package/dist/.pikku/addon/middleware/index.js +1 -1
- package/dist/.pikku/addon/middleware/pikku-middleware-types.gen.d.ts +41 -25
- package/dist/.pikku/addon/middleware/pikku-middleware-types.gen.d.ts.map +1 -1
- package/dist/.pikku/addon/middleware/pikku-middleware-types.gen.js +29 -24
- package/dist/.pikku/addon/middleware/pikku-middleware-types.gen.js.map +1 -1
- package/dist/.pikku/addon/permissions/pikku-permissions.gen.d.ts +5 -0
- package/dist/.pikku/addon/permissions/pikku-permissions.gen.d.ts.map +1 -0
- package/dist/.pikku/addon/permissions/pikku-permissions.gen.js +5 -0
- package/dist/.pikku/addon/permissions/pikku-permissions.gen.js.map +1 -0
- package/dist/.pikku/addon/pikku-bootstrap-scenarios.gen.d.ts +1 -1
- package/dist/.pikku/addon/pikku-bootstrap-scenarios.gen.js +1 -1
- package/dist/.pikku/addon/pikku-bootstrap.gen.d.ts +2 -1
- package/dist/.pikku/addon/pikku-bootstrap.gen.d.ts.map +1 -1
- package/dist/.pikku/addon/pikku-bootstrap.gen.js +2 -1
- package/dist/.pikku/addon/pikku-bootstrap.gen.js.map +1 -1
- package/dist/.pikku/addon/pikku-package.gen.js +1 -1
- package/dist/.pikku/addon/pikku-services.gen.d.ts +5 -4
- package/dist/.pikku/addon/pikku-services.gen.d.ts.map +1 -1
- package/dist/.pikku/addon/pikku-services.gen.js +3 -2
- package/dist/.pikku/addon/pikku-services.gen.js.map +1 -1
- package/dist/.pikku/addon/rpc/pikku-rpc-wirings-map.gen.d.ts +11 -2
- package/dist/.pikku/addon/rpc/pikku-rpc-wirings-map.internal.gen.d.ts +11 -2
- package/dist/.pikku/addon/rpc/pikku-rpc-wirings-map.remote.gen.d.ts +8 -2
- package/dist/.pikku/addon/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
- package/dist/.pikku/addon/rpc/pikku-rpc-wirings-meta.internal.gen.json +3 -0
- package/dist/.pikku/addon/scenarios/index.d.ts +1 -1
- package/dist/.pikku/addon/scenarios/index.js +1 -1
- package/dist/.pikku/addon/scenarios/pikku-personas.gen.d.ts +4 -0
- package/dist/.pikku/addon/scenarios/pikku-personas.gen.d.ts.map +1 -1
- package/dist/.pikku/addon/scenarios/pikku-personas.gen.js +1 -1
- package/dist/.pikku/addon/scenarios/pikku-personas.gen.js.map +1 -1
- package/dist/.pikku/addon/scenarios/pikku-scenario-functions-meta.gen.js +1 -1
- package/dist/.pikku/addon/scenarios/pikku-scenario-functions.gen.d.ts +1 -1
- package/dist/.pikku/addon/scenarios/pikku-scenario-types.gen.d.ts +13 -1
- package/dist/.pikku/addon/scenarios/pikku-scenario-types.gen.d.ts.map +1 -1
- package/dist/.pikku/addon/scenarios/pikku-scenario-types.gen.js +4 -0
- package/dist/.pikku/addon/scenarios/pikku-scenario-types.gen.js.map +1 -1
- package/dist/.pikku/addon/scenarios/pikku-scenario-wirings-meta.gen.js +1 -1
- package/dist/.pikku/addon/scenarios/pikku-scenario-wirings.gen.d.ts +1 -1
- package/dist/.pikku/addon/scenarios/schemas/register.gen.d.ts +1 -1
- package/dist/.pikku/addon/scenarios/schemas/register.gen.js +1 -1
- package/dist/.pikku/addon/schemas/register.gen.js +13 -1
- package/dist/.pikku/addon/schemas/register.gen.js.map +1 -1
- package/dist/.pikku/addon/schemas/schemas/AddonMetaPage.schema.json +1 -1
- package/dist/.pikku/addon/schemas/schemas/AddonPackageInfo.schema.json +1 -1
- package/dist/.pikku/addon/schemas/schemas/AllMeta.schema.json +1 -1
- package/dist/.pikku/addon/schemas/schemas/GetFunctionsMetaOutput.schema.json +1 -1
- package/dist/.pikku/addon/schemas/schemas/GetVirtualUserRunStepsInput.schema.json +1 -0
- package/dist/.pikku/addon/schemas/schemas/GetVirtualUserRunStepsOutput.schema.json +1 -0
- package/dist/.pikku/addon/schemas/schemas/GetVirtualUserRunsInput.schema.json +1 -0
- package/dist/.pikku/addon/schemas/schemas/GetVirtualUserRunsOutput.schema.json +1 -0
- package/dist/.pikku/addon/schemas/schemas/GetWorkflowMetaByIdOutput.schema.json +1 -1
- package/dist/.pikku/addon/schemas/schemas/StartVirtualUserRunInput.schema.json +1 -0
- package/dist/.pikku/addon/schemas/schemas/StartVirtualUserRunOutput.schema.json +1 -0
- package/dist/.pikku/addon/schemas/schemas/UpdateFunctionConfigInput.schema.json +1 -1
- package/dist/.pikku/addon/scopes/index.d.ts +1 -1
- package/dist/.pikku/addon/scopes/index.js +1 -1
- package/dist/.pikku/addon/scopes/pikku-personas.gen.js +1 -1
- package/dist/.pikku/addon/scopes/pikku-roles.gen.d.ts +1 -1
- package/dist/.pikku/addon/scopes/pikku-scope-types.gen.d.ts +1 -1
- package/dist/.pikku/addon/scopes/pikku-scope-types.gen.js +1 -1
- package/dist/.pikku/addon/scopes/pikku-scopes-meta.gen.json +11 -0
- package/dist/.pikku/addon/scopes/pikku-scopes.gen.d.ts +2 -2
- package/dist/.pikku/addon/scopes/pikku-scopes.gen.d.ts.map +1 -1
- package/dist/.pikku/addon/scopes/pikku-scopes.gen.js.map +1 -1
- package/dist/.pikku/addon/secrets/index.d.ts +1 -1
- package/dist/.pikku/addon/secrets/index.js +1 -1
- package/dist/.pikku/addon/secrets/pikku-secret-types.gen.d.ts +1 -1
- package/dist/.pikku/addon/secrets/pikku-secret-types.gen.js +1 -1
- package/dist/.pikku/addon/secrets/pikku-secrets.gen.d.ts +9 -1
- package/dist/.pikku/addon/secrets/pikku-secrets.gen.d.ts.map +1 -1
- package/dist/.pikku/addon/secrets/pikku-secrets.gen.js +5 -1
- package/dist/.pikku/addon/secrets/pikku-secrets.gen.js.map +1 -1
- package/dist/.pikku/addon/services/pikku-meta-service.gen.d.ts +1 -1
- package/dist/.pikku/addon/services/pikku-meta-service.gen.js +1 -1
- package/dist/.pikku/addon/setup/index.d.ts +1 -1
- package/dist/.pikku/addon/setup/index.js +1 -1
- package/dist/.pikku/addon/setup/pikku-addon-setup-types.gen.d.ts +1 -1
- package/dist/.pikku/addon/setup/pikku-addon-setup-types.gen.js +1 -1
- package/dist/.pikku/addon/setup/pikku-setup-types.gen.d.ts +7 -19
- package/dist/.pikku/addon/setup/pikku-setup-types.gen.d.ts.map +1 -1
- package/dist/.pikku/addon/setup/pikku-setup-types.gen.js +11 -19
- package/dist/.pikku/addon/setup/pikku-setup-types.gen.js.map +1 -1
- package/dist/.pikku/addon/trigger/index.d.ts +1 -1
- package/dist/.pikku/addon/trigger/index.js +1 -1
- package/dist/.pikku/addon/trigger/pikku-trigger-types.gen.d.ts +1 -1
- package/dist/.pikku/addon/trigger/pikku-trigger-types.gen.js +1 -1
- package/dist/.pikku/addon/variables/index.d.ts +1 -1
- package/dist/.pikku/addon/variables/index.js +1 -1
- package/dist/.pikku/addon/variables/pikku-variable-types.gen.d.ts +1 -1
- package/dist/.pikku/addon/variables/pikku-variable-types.gen.js +1 -1
- package/dist/.pikku/addon/variables/pikku-variables.gen.d.ts +9 -1
- package/dist/.pikku/addon/variables/pikku-variables.gen.d.ts.map +1 -1
- package/dist/.pikku/addon/variables/pikku-variables.gen.js +5 -1
- package/dist/.pikku/addon/variables/pikku-variables.gen.js.map +1 -1
- package/dist/.pikku/addon/workflow/index.d.ts +1 -1
- package/dist/.pikku/addon/workflow/index.js +1 -1
- package/dist/.pikku/addon/workflow/pikku-scenario-step-map.gen.d.ts +1 -1
- package/dist/.pikku/addon/workflow/pikku-workflow-map.gen.d.ts +1 -1
- package/dist/.pikku/addon/workflow/pikku-workflow-types.gen.d.ts +29 -1
- package/dist/.pikku/addon/workflow/pikku-workflow-types.gen.d.ts.map +1 -1
- package/dist/.pikku/addon/workflow/pikku-workflow-types.gen.js +8 -1
- package/dist/.pikku/addon/workflow/pikku-workflow-types.gen.js.map +1 -1
- package/dist/.pikku/addon/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
- package/dist/.pikku/addon/workflow/pikku-workflow-wirings.gen.d.ts +1 -1
- package/dist/.pikku/addon/workflow/pikku-workflow-wirings.gen.js +1 -1
- package/dist/src/functions/delete-agent-thread.function.d.ts.map +1 -1
- package/dist/src/functions/delete-agent-thread.function.js +3 -1
- package/dist/src/functions/delete-agent-thread.function.js.map +1 -1
- package/dist/src/functions/delete-agent-thread.function.test.d.ts +2 -0
- package/dist/src/functions/delete-agent-thread.function.test.d.ts.map +1 -0
- package/dist/src/functions/delete-agent-thread.function.test.js +8 -0
- package/dist/src/functions/delete-agent-thread.function.test.js.map +1 -0
- package/dist/src/functions/get-agent-thread-messages.function.d.ts.map +1 -1
- package/dist/src/functions/get-agent-thread-messages.function.js +3 -1
- package/dist/src/functions/get-agent-thread-messages.function.js.map +1 -1
- package/dist/src/functions/get-agent-thread-messages.function.test.d.ts +2 -0
- package/dist/src/functions/get-agent-thread-messages.function.test.d.ts.map +1 -0
- package/dist/src/functions/get-agent-thread-messages.function.test.js +8 -0
- package/dist/src/functions/get-agent-thread-messages.function.test.js.map +1 -0
- package/dist/src/functions/get-virtual-user-run-steps.function.d.ts +14 -0
- package/dist/src/functions/get-virtual-user-run-steps.function.d.ts.map +1 -0
- package/dist/src/functions/get-virtual-user-run-steps.function.js +31 -0
- package/dist/src/functions/get-virtual-user-run-steps.function.js.map +1 -0
- package/dist/src/functions/get-virtual-user-runs.function.d.ts +14 -0
- package/dist/src/functions/get-virtual-user-runs.function.d.ts.map +1 -0
- package/dist/src/functions/get-virtual-user-runs.function.js +39 -0
- package/dist/src/functions/get-virtual-user-runs.function.js.map +1 -0
- package/dist/src/functions/is-thread-owner.permission.d.ts +13 -0
- package/dist/src/functions/is-thread-owner.permission.d.ts.map +1 -0
- package/dist/src/functions/is-thread-owner.permission.js +23 -0
- package/dist/src/functions/is-thread-owner.permission.js.map +1 -0
- package/dist/src/functions/is-thread-owner.permission.test.d.ts +2 -0
- package/dist/src/functions/is-thread-owner.permission.test.d.ts.map +1 -0
- package/dist/src/functions/is-thread-owner.permission.test.js +25 -0
- package/dist/src/functions/is-thread-owner.permission.test.js.map +1 -0
- package/dist/src/functions/start-virtual-user-run.function.d.ts +33 -0
- package/dist/src/functions/start-virtual-user-run.function.d.ts.map +1 -0
- package/dist/src/functions/start-virtual-user-run.function.js +31 -0
- package/dist/src/functions/start-virtual-user-run.function.js.map +1 -0
- package/dist/src/functions/update-agent-config.function.d.ts +1 -1
- package/dist/src/functions/update-agent-config.function.d.ts.map +1 -1
- package/dist/src/functions/update-function-config.function.d.ts +1 -1
- package/dist/src/functions/update-function-config.function.d.ts.map +1 -1
- package/dist/src/scopes.js +11 -0
- package/dist/src/scopes.js.map +1 -1
- package/dist/src/services.js +1 -1
- package/dist/src/services.js.map +1 -1
- package/dist/types/application-types.d.ts +1 -1
- package/package.json +5 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "functions": { "type": "array", "items": { "$ref": "#/definitions/FunctionMeta" } }, "httpMeta": { "type": "array", "items": { "$ref": "#/definitions/HttpRouteMeta" } }, "cliMeta": { "type": "array", "items": { "$ref": "#/definitions/CliProgramMeta" } }, "cliRenderers": { "type": "object", "additionalProperties": { "$ref": "#/definitions/CliRendererMeta" } }, "channelsMeta": { "type": "object", "additionalProperties": { "$ref": "#/definitions/ChannelMeta" } }, "queueMeta": { "type": "object", "additionalProperties": { "$ref": "#/definitions/QueueWorkerMeta" } }, "schedulerMeta": { "type": "object", "additionalProperties": { "$ref": "#/definitions/SchedulerTaskMeta" } }, "rpcMeta": { "type": "object", "additionalProperties": { "$ref": "#/definitions/RpcMeta" } }, "mcpMeta": { "type": "array", "items": { "$ref": "#/definitions/McpItemMeta" } }, "gatewayMeta": { "type": "array", "items": { "$ref": "#/definitions/GatewayItemMeta" } }, "workflows": { "$ref": "#/definitions/WorkflowsMeta" }, "personas": { "type": "object", "additionalProperties": { "$ref": "#/definitions/ResolvedPersona" } }, "systemRoles": { "$ref": "#/definitions/SystemRoleDefinitionsMeta", "description": "The roles declared with `defineSystemRole`, keyed by name.\n\nShipped alongside the personas because a persona only ever names roles, and nothing about what they can reach is readable without the scopes each one confers." }, "features": { "$ref": "#/definitions/FeaturesMeta" }, "triggerMeta": { "type": "object", "additionalProperties": { "$ref": "#/definitions/TriggerMeta" } }, "triggerSourceMeta": { "type": "object", "additionalProperties": { "$ref": "#/definitions/TriggerSourceMeta" } }, "middlewareGroupsMeta": { "$ref": "#/definitions/MiddlewareGroupsMeta" }, "permissionsGroupsMeta": { "$ref": "#/definitions/PermissionsGroupsMeta" }, "agentsMeta": { "$ref": "#/definitions/AgentsMeta" }, "emailsMeta": { "$ref": "#/definitions/EmailsMeta" }, "secretsMeta": { "type": "object", "additionalProperties": {} }, "credentialsMeta": { "type": "object", "additionalProperties": {} }, "variablesMeta": { "type": "object", "additionalProperties": {} }, "functionUsedBy": { "type": "object", "additionalProperties": { "$ref": "#/definitions/FunctionUsedBy" } }, "counts": { "$ref": "#/definitions/MetaCounts" } }, "required": ["agentsMeta", "channelsMeta", "cliMeta", "cliRenderers", "counts", "credentialsMeta", "emailsMeta", "features", "functionUsedBy", "functions", "gatewayMeta", "httpMeta", "mcpMeta", "middlewareGroupsMeta", "permissionsGroupsMeta", "personas", "queueMeta", "rpcMeta", "schedulerMeta", "secretsMeta", "systemRoles", "triggerMeta", "triggerSourceMeta", "variablesMeta", "workflows"], "additionalProperties": false, "definitions": { "FunctionMeta": { "type": "object", "additionalProperties": false, "properties": { "name": { "type": "string" }, "functionType": { "type": "string", "enum": ["user", "inline", "helper", "remote"], "description": "`remote`: a contract with no local body, answered by a connected client." }, "funcWrapper": { "type": "string" }, "services": { "$ref": "#/definitions/FunctionServicesMeta" }, "wires": { "$ref": "#/definitions/FunctionWiresMeta" }, "inputs": { "anyOf": [{ "type": "array", "items": { "type": "string" } }, { "type": "null" }] }, "outputs": { "anyOf": [{ "type": "array", "items": { "type": "string" } }, { "type": "null" }] }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } }, "isDirectFunction": { "type": "boolean" }, "sourceFile": { "type": "string" }, "exportedName": { "type": "string" }, "bodySourceFile": { "type": "string", "description": "File containing the handler body when it differs from sourceFile (imported handlers)" }, "bodyStart": { "type": "number", "description": "1-indexed first line of the handler body (verbose meta; coverage mapping)" }, "bodyEnd": { "type": "number", "description": "1-indexed last line of the handler body (verbose meta; coverage mapping)" }, "pikkuFuncId": { "type": "string" }, "packageName": { "type": "string" }, "title": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "summary": { "type": "string" }, "description": { "type": "string" }, "errors": { "type": "array", "items": { "type": "string" } }, "inputSchemaName": { "type": ["string", "null"] }, "outputSchemaName": { "type": ["string", "null"] }, "scopes": { "type": "array", "items": { "type": "string" }, "description": "Scopes the session must hold to run this function. All are required (AND)." }, "expose": { "type": "boolean" }, "auth": { "type": "boolean", "description": "A sessionless function's own `auth: true`. `sessionless` carries the baseline — a `pikkuFunc` always requires a session — and this carries the tightening a `pikkuSessionlessFunc` applies to itself. Both are needed to know whether a function is gated without running it." }, "permissionsInBody": { "type": "boolean", "description": "The author's declaration that this function's permission check lives in its own body. Carries no runtime effect — it records a gate codegen cannot see, so an audit is not left to guess whether a sessionless function is open. Refused unless `allow.permissionsInBody` is set in `pikku.config.json`." }, "remote": { "type": "boolean" }, "scenarioStep": { "type": "boolean", "description": "A step RPC: invoked by name only from a scenario run and refused everywhere else, so it is never network-callable." }, "scenario": { "type": "boolean", "description": "The body of a `pikkuScenario(...)`. Only ever run by `pikku scenario run`, so it is held back from the app bootstrap and from every deployed unit." }, "mcp": { "type": "boolean" }, "readonly": { "type": "boolean" }, "deploy": { "type": "string", "enum": ["serverless", "server", "auto"] }, "sessionless": { "type": "boolean" }, "workflowQueued": { "type": "boolean", "description": "When true, workflow steps calling this function are dispatched via the queue. No queue service configured is a hard error." }, "workflowRetries": { "type": "number", "description": "Retry count when this function is used as a workflow step." }, "workflowTimeout": { "type": "string", "description": "Timeout when this function is used as a workflow step (e.g. '30s', '5m')." }, "scenarioStepSurfaces": { "type": "array", "items": { "$ref": "#/definitions/ScenarioSurface" }, "description": "Scenario steps only: which surfaces this step declares a binding for.\n\nThe reporter derives coverage from this — a `then` with no binding for the surface the run targeted was never actually witnessed there, which is a gap worth counting rather than excusing." }, "scenarioStepRequiresActor": { "type": "boolean", "description": "Scenario steps only: this step runs as a persona, so every call site must pass one and the runner injects it as `wire.actor`.\n\nDeclared by `actor: true`, or implied by a `browser` binding — a window is opened as somebody. Absent on a step with nobody to be: an assertion over what an earlier step returned, or one posting credentials precisely because it must not reuse an actor's session." }, "scenarioStepKind": { "$ref": "#/definitions/ScenarioStepKind", "description": "Scenario steps only: who acts. Absent means `persona` — the ordinary step, and the only kind that existed before the other two.\n\nA `platform` or `addon` step is the app or a third-party system acting, and it must never reach a virtual user's catalogue. That is not tidiness: a virtual user that can invoke \"Stripe's webhook arrives\" can forge its own payment success, and every finding downstream of that is worthless." }, "scenarioStepAddon": { "type": "string", "description": "Addon steps only: the addon whose system acts — `wireAddon`'s `name`." }, "scenarioStepTemplate": { "type": "string", "description": "Scenario steps only: the prose a reporter renders, with `{placeholders}` filled from the step's recorded input." }, "audit": { "type": "object", "properties": { "durability": { "$ref": "#/definitions/AuditDurability" } }, "required": ["durability"], "additionalProperties": false, "description": "The function's `audit` config, resolved — `audit: true` reads as `{ durability: 'best-effort' }`. Absent means the function records nothing: `auditLog.write()` from an unmarked function is dropped with a warning, so this is the only place a reader can see which functions have a trail at all without running them.\n\nInformational. The runner resolves audit from the live function config, not from here, so meta and runtime cannot disagree about whether audit is on." }, "version": { "type": "number" }, "approvalRequired": { "type": "boolean" }, "approvalDescription": { "type": "string" }, "implementationHash": { "type": "string" }, "contractHash": { "type": "string" }, "inputHash": { "type": "string" }, "outputHash": { "type": "string" } }, "required": ["inputSchemaName", "outputSchemaName", "pikkuFuncId"] }, "FunctionServicesMeta": { "type": "object", "properties": { "optimized": { "type": "boolean" }, "services": { "type": "array", "items": { "type": "string" } } }, "required": ["optimized", "services"], "additionalProperties": false }, "FunctionWiresMeta": { "type": "object", "properties": { "optimized": { "type": "boolean" }, "wires": { "type": "array", "items": { "type": "string" } } }, "required": ["optimized", "wires"], "additionalProperties": false }, "MiddlewareMetadata": { "anyOf": [{ "type": "object", "properties": { "type": { "type": "string", "const": "http" }, "route": { "type": "string" } }, "required": ["type", "route"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "tag" }, "tag": { "type": "string" } }, "required": ["type", "tag"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "wire" }, "name": { "type": "string" }, "inline": { "type": "boolean" } }, "required": ["type", "name"], "additionalProperties": false }] }, "PermissionMetadata": { "type": "object", "properties": { "type": { "type": "string", "const": "wire" }, "name": { "type": "string" }, "inline": { "type": "boolean" } }, "required": ["type", "name"], "additionalProperties": false, "description": "A reference to a permission function, resolved by name. Function-scoped only: there are no wire- or tag-level permission references." }, "ScenarioSurface": { "type": "string", "enum": ["browser", "cli", "default"], "description": "How an actor drives the system for one step.\n\nA step declares one implementation per surface it supports, and the runner picks between them — so the same ladder can run through a real browser, over the websocket, or entirely server-side.\n\n`default` is the floor: it is what every other surface falls back to, so it can never itself fall back." }, "ScenarioStepKind": { "type": "string", "enum": ["persona", "platform", "addon"], "description": "Who acts in a step.\n\n`persona` is a person driving the system through one of its surfaces — the ordinary `pikkuScenarioStep`. `platform` is the app acting on itself (\"the platform has expired the trial\"), and `addon` is a third-party system acting on it (\"Stripe's webhook arrives\"), contributed by the addon that wraps that service.\n\nThe three are separate declarations rather than a field on one, so the inspector verifies a step's kind by which function was called rather than by trusting a string literal — and so an addon package exports only addon steps, which is checkable." }, "AuditDurability": { "type": "string", "enum": ["best-effort", "transactional"] }, "HttpRouteMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" }, "route": { "type": "string" }, "method": { "type": "string" }, "params": { "type": "array", "items": { "type": "string" } }, "query": { "type": "array", "items": { "type": "string" } }, "summary": { "type": "string" }, "description": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "errors": { "type": "array", "items": { "type": "string" } }, "auth": { "type": "boolean" }, "sse": { "type": "boolean" }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } }, "inputSchemaName": { "type": "string" }, "outputSchemaName": { "type": "string" } }, "required": ["pikkuFuncId", "route", "method"], "additionalProperties": false }, "CliProgramMeta": { "type": "object", "properties": { "wireId": { "type": "string" }, "program": { "type": "string" }, "description": { "type": "string" }, "commands": { "type": "object", "additionalProperties": { "$ref": "#/definitions/CliCommandMeta" } }, "options": { "type": "object", "additionalProperties": { "$ref": "#/definitions/CliOptionMeta" } }, "defaultRenderName": { "type": "string" } }, "required": ["wireId", "program", "commands", "options"], "additionalProperties": false }, "CliCommandMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" }, "description": { "type": "string" }, "summary": { "type": "string" }, "parameters": { "type": "string" }, "positionals": { "type": "array", "items": { "$ref": "#/definitions/CliPositionalMeta" } }, "options": { "type": "object", "additionalProperties": { "$ref": "#/definitions/CliOptionMeta" } }, "renderName": { "type": "string" }, "subcommands": { "type": "object", "additionalProperties": { "$ref": "#/definitions/CliCommandMeta" } }, "isDefault": { "type": "boolean" } }, "required": ["pikkuFuncId", "positionals", "options"], "additionalProperties": false }, "CliPositionalMeta": { "type": "object", "properties": { "name": { "type": "string" }, "required": { "type": "boolean" }, "variadic": { "type": "boolean" } }, "required": ["name", "required"], "additionalProperties": false }, "CliOptionMeta": { "type": "object", "properties": { "description": { "type": "string" }, "short": { "type": "string" }, "default": {}, "choices": { "type": "array", "items": {} }, "array": { "type": "boolean" }, "required": { "type": "boolean" } }, "required": ["description"], "additionalProperties": false }, "CliRendererMeta": { "type": "object", "properties": { "name": { "type": "string" }, "exportedName": { "type": "string" }, "filePath": { "type": "string" }, "services": { "type": "object", "properties": { "optimized": { "type": "boolean" }, "services": { "type": "array", "items": { "type": "string" } } }, "required": ["optimized", "services"], "additionalProperties": false } }, "required": ["name", "filePath", "services"], "additionalProperties": false }, "ChannelMeta": { "type": "object", "properties": { "name": { "type": "string" }, "route": { "type": "string" }, "params": { "type": "array", "items": { "type": "string" } }, "query": { "type": "array", "items": { "type": "string" } }, "input": { "type": ["string", "null"] }, "connect": { "anyOf": [{ "$ref": "#/definitions/ChannelMessageMeta" }, { "type": "null" }] }, "disconnect": { "anyOf": [{ "$ref": "#/definitions/ChannelMessageMeta" }, { "type": "null" }] }, "message": { "anyOf": [{ "$ref": "#/definitions/ChannelMessageMeta" }, { "type": "null" }] }, "messageWirings": { "type": "object", "additionalProperties": { "type": "object", "additionalProperties": { "$ref": "#/definitions/ChannelMessageMeta" } } }, "summary": { "type": "string" }, "description": { "type": "string" }, "errors": { "type": "array", "items": { "type": "string" } }, "tags": { "type": "array", "items": { "type": "string" } }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } } }, "required": ["name", "route", "input", "connect", "disconnect", "message", "messageWirings"], "additionalProperties": false }, "ChannelMessageMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" }, "errors": { "type": "array", "items": { "type": "string" } }, "tags": { "type": "array", "items": { "type": "string" } }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } } }, "required": ["pikkuFuncId"], "additionalProperties": false }, "QueueWorkerMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" }, "queueName": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } }, "config": { "type": "object", "additionalProperties": {} } }, "required": ["pikkuFuncId", "queueName"], "additionalProperties": false }, "SchedulerTaskMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" }, "name": { "type": "string" }, "schedule": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } } }, "required": ["pikkuFuncId", "name", "schedule"], "additionalProperties": false }, "RpcMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" } }, "required": ["pikkuFuncId"], "additionalProperties": false }, "McpItemMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" }, "method": { "type": "string", "enum": ["resource", "tool", "prompt"] }, "name": { "type": "string" }, "wireId": { "type": "string" }, "description": { "type": "string" }, "summary": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "errors": { "type": "array", "items": { "type": "string" } }, "uri": { "type": "string" }, "arguments": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "description": { "type": "string" }, "required": { "type": "boolean" } }, "required": ["name"], "additionalProperties": false } }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } }, "inputSchemaName": { "type": "string" }, "outputSchemaName": { "type": "string" } }, "required": ["pikkuFuncId", "method"], "additionalProperties": false }, "GatewayItemMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" }, "name": { "type": "string" }, "type": { "type": "string", "enum": ["webhook", "websocket", "listener"] }, "route": { "type": "string" }, "platform": { "type": "string" }, "packageName": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "errors": { "type": "array", "items": { "type": "string" } }, "auth": { "type": "boolean" }, "gateway": { "type": "boolean", "const": true }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } } }, "required": ["pikkuFuncId", "name", "type", "gateway"], "additionalProperties": false }, "WorkflowsMeta": { "type": "object", "additionalProperties": { "type": "object", "additionalProperties": false, "properties": { "name": { "type": "string" }, "steps": { "type": "array", "items": { "$ref": "#/definitions/WorkflowStepMeta" } }, "context": { "$ref": "#/definitions/WorkflowContext" }, "dsl": { "type": "boolean" }, "expose": { "type": "boolean" }, "scenario": { "type": "boolean" }, "asserts": { "type": "boolean", "description": "The flow asserts through an expectation helper — `expectService`, `expectError`, `expectEventually` — rather than a `then` step. Those are inline steps and carry no phase, so without this PKU680 reads a scenario whose only witness is a recorded service call as asserting nothing." }, "skip": { "type": "string" }, "actors": { "type": "array", "items": { "type": "string" } }, "pikkuFuncId": { "type": "string" }, "packageName": { "type": "string" }, "title": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "summary": { "type": "string" }, "description": { "type": "string" }, "errors": { "type": "array", "items": { "type": "string" } }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } } }, "required": ["name", "pikkuFuncId", "steps"] } }, "WorkflowStepMeta": { "anyOf": [{ "$ref": "#/definitions/RpcStepMeta" }, { "$ref": "#/definitions/ScenarioStepMeta" }, { "$ref": "#/definitions/BranchStepMeta" }, { "$ref": "#/definitions/ParallelGroupStepMeta" }, { "$ref": "#/definitions/FanoutStepMeta" }, { "$ref": "#/definitions/ReturnStepMeta" }, { "$ref": "#/definitions/InlineStepMeta" }, { "$ref": "#/definitions/SleepStepMeta" }, { "$ref": "#/definitions/CancelStepMeta" }, { "$ref": "#/definitions/SuspendStepMeta" }, { "$ref": "#/definitions/ApprovalStepMeta" }, { "$ref": "#/definitions/SwitchStepMeta" }, { "$ref": "#/definitions/FilterStepMeta" }, { "$ref": "#/definitions/ArrayPredicateStepMeta" }, { "$ref": "#/definitions/SetStepMeta" }], "description": "Workflow step metadata (extracted by inspector)" }, "RpcStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "rpc", "description": "RPC form - generates queue worker" }, "stepName": { "type": "string", "description": "Cache key (stepName from workflow.do)" }, "rpcName": { "type": "string", "description": "RPC to invoke" }, "outputVar": { "type": "string", "description": "Output variable name (if assigned)" }, "inputs": { "anyOf": [{ "type": "object", "additionalProperties": { "$ref": "#/definitions/InputSource" } }, { "type": "string", "const": "passthrough" }], "description": "Input source mappings, or 'passthrough' when entire data is passed" }, "options": { "$ref": "#/definitions/WorkflowStepOptions", "description": "Step options" }, "actor": { "type": "string", "description": "Scenario actor name this step runs as ({ actor: actors.x })" }, "expectEventually": { "type": "boolean", "description": "True for workflow.expectEventually polling steps" } }, "required": ["type", "stepName", "rpcName"], "additionalProperties": false, "description": "RPC step metadata (base form)" }, "InputSource": { "anyOf": [{ "type": "object", "properties": { "from": { "type": "string", "const": "input" }, "path": { "type": "string" } }, "required": ["from", "path"], "additionalProperties": false }, { "type": "object", "properties": { "from": { "type": "string", "const": "outputVar" }, "name": { "type": "string" }, "path": { "type": "string" } }, "required": ["from", "name"], "additionalProperties": false }, { "type": "object", "properties": { "from": { "type": "string", "const": "item" }, "path": { "type": "string" } }, "required": ["from", "path"], "additionalProperties": false }, { "type": "object", "properties": { "from": { "type": "string", "const": "literal" }, "value": {} }, "required": ["from", "value"], "additionalProperties": false }, { "type": "object", "properties": { "from": { "type": "string", "const": "template" }, "parts": { "type": "array", "items": { "type": "string" } }, "expressions": { "type": "array", "items": { "$ref": "#/definitions/InputSource" } } }, "required": ["from", "parts", "expressions"], "additionalProperties": false }], "description": "Input source for step arguments in DSL workflows" }, "WorkflowStepOptions": { "type": "object", "properties": { "description": { "type": "string", "description": "Display name for logs/UI (optional, doesn't affect execution)" }, "retries": { "type": "number", "description": "Number of retry attempts for failed steps (only applies to local execution)" }, "retryDelay": { "type": ["string", "number"], "description": "Delay between retry attempts (e.g., '1s', '2s', '2min')" }, "onError": { "type": "string", "description": "RPC to invoke for compensation when this step fails after exhausting its retries. Mirrors a graph node's `onError`: the handler receives `{ error: { message } }` and the original error is still thrown, so the workflow fails — this is compensation, not recovery." }, "actor": { "$ref": "#/definitions/ScenarioPersona", "description": "Run this step as an actor (scenarios). The RPC is sent through the actor's authenticated client over the REAL transport — never dispatched internally — so auth middleware and permissions are exercised end-to-end. The step is recorded durably like any RPC step." } }, "additionalProperties": false, "description": "Workflow step options" }, "ScenarioPersona": { "type": "object", "properties": { "name": { "type": "string", "description": "The id it was declared under — what a step's `actor` slot names." }, "email": { "type": "string", "description": "Their address, computed from the id. Flows use it for invites/lookups." } }, "required": ["name", "email"], "additionalProperties": false, "description": "A declared person, signed in and acting over the real transport.\n\nThe runtime half of `definePersonas()`: sign-in materialises a user row flagged `actor: true`, and everything a step or a virtual user does goes through here." }, "ScenarioStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "scenarioStep" }, "stepName": { "type": "string", "description": "Cache key (first argument), ordinal-suffixed by the engine when repeated" }, "stepFunc": { "type": "string", "description": "Registered name of the step function being run" }, "phase": { "$ref": "#/definitions/ScenarioStepPhase", "description": "Which keyword the reporter prefixes — Given, When or Then" }, "outputVar": { "type": "string", "description": "Output variable name (if assigned)" }, "inputs": { "anyOf": [{ "type": "object", "additionalProperties": { "$ref": "#/definitions/InputSource" } }, { "type": "string", "const": "passthrough" }], "description": "Input source mappings, or 'passthrough' when entire data is passed" }, "options": { "$ref": "#/definitions/WorkflowStepOptions", "description": "Step options" }, "actor": { "type": "string", "description": "Scenario actor name this step runs as ({ actor: actors.x })" }, "surfaces": { "type": "array", "items": { "$ref": "#/definitions/ScenarioSurface" }, "description": "Mirrors the surfaces the step function declares a binding for" } }, "required": ["type", "stepName", "stepFunc", "phase"], "additionalProperties": false, "description": "Scenario step metadata — a call to `scenario.given/when/then`.\n\nDistinct from RpcStepMeta on purpose: a step runs locally through runPikkuFunc and must never be treated as dispatchable on the queue/replay path, nor registered as a callable RPC (a browser-driving step must not be network-invocable)." }, "ScenarioStepPhase": { "type": "string", "enum": ["given", "when", "then"], "description": "Which Gherkin-style keyword the reporter prefixes this step with.\n\nEvery step takes one. A scenario is read by people deciding whether it describes the behaviour they wanted, and a step that says only what it does without saying whether it is setup, action or claim is the one nobody can check — which is also why PKU680 can tell a scenario that never asserts." }, "BranchStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "branch" }, "branches": { "type": "array", "items": { "$ref": "#/definitions/BranchCase" }, "description": "Branches in order: first is \"if\", rest are \"else if\"" }, "elseSteps": { "type": "array", "items": { "$ref": "#/definitions/WorkflowStepMeta" }, "description": "Else branch steps (when no conditions match)" } }, "required": ["type", "branches"], "additionalProperties": false, "description": "Branch step metadata (if/else-if/else control flow)" }, "BranchCase": { "type": "object", "properties": { "condition": { "$ref": "#/definitions/Condition", "description": "Condition for this branch" }, "steps": { "type": "array", "items": { "$ref": "#/definitions/WorkflowStepMeta" }, "description": "Steps to execute when condition is true" } }, "required": ["condition", "steps"], "additionalProperties": false, "description": "A single branch in an if/else-if chain" }, "Condition": { "anyOf": [{ "$ref": "#/definitions/SimpleCondition" }, { "type": "object", "properties": { "type": { "type": "string", "const": "and" }, "conditions": { "type": "array", "items": { "$ref": "#/definitions/Condition" } } }, "required": ["type", "conditions"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "or" }, "conditions": { "type": "array", "items": { "$ref": "#/definitions/Condition" } } }, "required": ["type", "conditions"], "additionalProperties": false }], "description": "Nested condition structure supporting AND/OR operations" }, "SimpleCondition": { "type": "object", "properties": { "type": { "type": "string", "const": "simple" }, "expression": { "type": "string" } }, "required": ["type", "expression"], "additionalProperties": false, "description": "Simple condition expression (leaf node)" }, "ParallelGroupStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "parallel" }, "children": { "type": "array", "items": { "anyOf": [{ "$ref": "#/definitions/RpcStepMeta" }, { "$ref": "#/definitions/ScenarioStepMeta" }] }, "description": "Child steps to execute in parallel" } }, "required": ["type", "children"], "additionalProperties": false, "description": "Parallel group step metadata (Promise.all with multiple steps)" }, "FanoutStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "fanout" }, "stepName": { "type": "string", "description": "Step name for this fanout. Optional: a fanout is not itself a cached step, and node ids are step names — borrowing a body step's name would give the loop and that step the same id, collapsing one onto the other." }, "sourceVar": { "type": "string", "description": "Source array variable name" }, "itemVar": { "type": "string", "description": "Iterator variable name" }, "mode": { "type": "string", "enum": ["parallel", "sequential"], "description": "Execution mode" }, "body": { "type": "array", "items": { "anyOf": [{ "$ref": "#/definitions/RpcStepMeta" }, { "$ref": "#/definitions/SleepStepMeta" }, { "$ref": "#/definitions/SuspendStepMeta" }, { "$ref": "#/definitions/ScenarioStepMeta" }] }, "description": "Steps to execute inline per iteration, in order" }, "timeBetween": { "type": "string", "description": "Time between iterations (sequential mode only)" } }, "required": ["type", "sourceVar", "itemVar", "mode", "body"], "additionalProperties": false, "description": "Fanout step metadata (parallel or sequential iteration)" }, "SleepStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "sleep", "description": "Sleep step" }, "stepName": { "type": "string", "description": "Cache key (stepName from workflow.sleep)" }, "duration": { "type": ["string", "number"], "description": "Sleep duration" }, "expression": { "type": "string", "description": "Source text of a duration only known at runtime (e.g. a loop variable). The closure evaluates it, so it is legal DSL; it is kept separate from `duration` so regenerated code emits it raw rather than as a string literal, exactly as `expression` does on a set step." } }, "required": ["type", "stepName", "duration"], "additionalProperties": false, "description": "Sleep step metadata" }, "SuspendStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "suspend" }, "reason": { "type": "string", "description": "Reason string passed to workflow.suspend() — becomes the durable step key" } }, "required": ["type", "reason"], "additionalProperties": false, "description": "Suspend step metadata (workflow.suspend())" }, "ReturnStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "return" }, "outputs": { "type": "object", "additionalProperties": { "$ref": "#/definitions/OutputBinding" }, "description": "Output bindings" }, "spread": { "type": "array", "items": { "type": "string" }, "description": "Variables spread into the returned object (`return { ...r }`), or the sole returned variable (`return r`). Their fields are not enumerable statically, so they are recorded by name rather than expanded into `outputs`." } }, "required": ["type", "outputs"], "additionalProperties": false, "description": "Return step metadata (workflow output)" }, "OutputBinding": { "anyOf": [{ "type": "object", "properties": { "from": { "type": "string", "const": "outputVar" }, "name": { "type": "string" }, "path": { "type": "string" } }, "required": ["from", "name"], "additionalProperties": false }, { "type": "object", "properties": { "from": { "type": "string", "const": "stateVar" }, "name": { "type": "string" }, "path": { "type": "string" } }, "required": ["from", "name"], "additionalProperties": false }, { "type": "object", "properties": { "from": { "type": "string", "const": "input" }, "path": { "type": "string" } }, "required": ["from", "path"], "additionalProperties": false }, { "type": "object", "properties": { "from": { "type": "string", "const": "literal" }, "value": {} }, "required": ["from", "value"], "additionalProperties": false }, { "type": "object", "properties": { "from": { "type": "string", "const": "expression" }, "expression": { "type": "string" } }, "required": ["from", "expression"], "additionalProperties": false }], "description": "Output binding for return statements in DSL workflows" }, "InlineStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "inline", "description": "Inline form - local execution" }, "stepName": { "type": "string", "description": "Cache key (stepName from workflow.do)" }, "description": { "type": "string", "description": "Display name" }, "options": { "$ref": "#/definitions/WorkflowStepOptions", "description": "Step options" } }, "required": ["type", "stepName"], "additionalProperties": false, "description": "Inline step metadata" }, "CancelStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "cancel", "description": "Cancel step" }, "reason": { "type": "string", "description": "Optional cancellation reason" } }, "required": ["type"], "additionalProperties": false, "description": "Cancel step metadata" }, "ApprovalStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "approval" }, "reason": { "type": "string", "description": "Reason string passed to workflow.approval() — becomes the durable step key" }, "outputVar": { "type": "string", "description": "Output variable name (if assigned)" }, "expiry": { "type": ["string", "number"], "description": "Expiry duration, when one was given" }, "approvers": { "$ref": "#/definitions/WorkflowApprovalApprovers", "description": "Who may answer the gate, when the default was not used" }, "approverScope": { "type": "string", "description": "Scope the decider must hold, when one was required" } }, "required": ["type", "reason"], "additionalProperties": false, "description": "Approval step metadata (workflow.approval())" }, "WorkflowApprovalApprovers": { "type": "string", "enum": ["any", "owner", "not-initiator"], "description": "Who is allowed to answer an approval gate, relative to the user who started the run.\n\n- `any` — anyone the approve entrypoint lets through. The gate is a pause for a decision, not an authorization boundary.\n- `owner` — only the user who started the run, so a gate can be used to confirm an action against the same person who requested it.\n- `not-initiator` — anyone *except* the user who started the run: four-eyes. A run with no recorded initiator has nobody to exclude, so this degrades to requiring a signed-in decider." }, "SwitchStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "switch" }, "expression": { "type": "string", "description": "Expression being switched on" }, "cases": { "type": "array", "items": { "$ref": "#/definitions/SwitchCaseMeta" }, "description": "Case branches" }, "defaultSteps": { "type": "array", "items": { "$ref": "#/definitions/WorkflowStepMeta" }, "description": "Default case steps (optional)" } }, "required": ["type", "expression", "cases"], "additionalProperties": false, "description": "Switch step metadata (switch/case control flow)" }, "SwitchCaseMeta": { "type": "object", "properties": { "value": { "type": ["string", "number", "boolean", "null"], "description": "Case value (literal) or expression" }, "expression": { "type": "string", "description": "Case expression (for complex cases)" }, "steps": { "type": "array", "items": { "$ref": "#/definitions/WorkflowStepMeta" }, "description": "Steps to execute for this case" } }, "required": ["steps"], "additionalProperties": false, "description": "Switch case metadata" }, "FilterStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "filter" }, "sourceVar": { "type": "string", "description": "Source array variable name" }, "itemVar": { "type": "string", "description": "Iterator variable name" }, "condition": { "$ref": "#/definitions/Condition", "description": "Filter condition" }, "outputVar": { "type": "string", "description": "Output variable name (if assigned)" } }, "required": ["type", "sourceVar", "itemVar", "condition"], "additionalProperties": false, "description": "Filter step metadata (array.filter)" }, "ArrayPredicateStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "arrayPredicate" }, "mode": { "type": "string", "enum": ["some", "every"], "description": "Predicate mode" }, "sourceVar": { "type": "string", "description": "Source array variable name" }, "itemVar": { "type": "string", "description": "Iterator variable name" }, "condition": { "$ref": "#/definitions/Condition", "description": "Predicate condition" }, "outputVar": { "type": "string", "description": "Output variable name (if assigned)" } }, "required": ["type", "mode", "sourceVar", "itemVar", "condition"], "additionalProperties": false, "description": "Array predicate step metadata (array.some, array.every)" }, "SetStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "set", "description": "Set step" }, "variable": { "type": "string", "description": "Variable name to set (must be in context)" }, "value": { "description": "Literal value to assign. Mutually exclusive with `expression`." }, "expression": { "type": "string", "description": "Source text of a non-literal assignment (e.g. `count + 1`). Kept separate from `value` so regenerated code can emit it raw — a string `value` is a string literal, an `expression` is code." } }, "required": ["type", "variable"], "additionalProperties": false, "description": "Set step metadata (context variable assignment)" }, "WorkflowContext": { "type": "object", "additionalProperties": { "$ref": "#/definitions/ContextVariable" } }, "ContextVariable": { "type": "object", "properties": { "type": { "type": "string", "enum": ["string", "number", "boolean", "object", "array"] }, "default": {}, "description": { "type": "string" } }, "required": ["type"], "additionalProperties": false }, "ResolvedPersona": { "type": "object", "additionalProperties": false, "properties": { "email": { "type": "string" }, "id": { "type": "string", "description": "The key it was declared under." }, "name": { "type": "string" }, "jobTitle": { "type": "string" }, "description": { "type": "string" }, "avatarUrl": { "type": "string" }, "roles": { "type": "array", "items": { "type": "string" } }, "personality": { "type": "string" }, "goals": { "type": "array", "items": { "type": "string" } }, "tags": { "type": "array", "items": { "type": "string" } }, "disposition": { "$ref": "#/definitions/VirtualUserDisposition" }, "tuning": { "$ref": "#/definitions/VirtualUserTuning" }, "fixtures": { "type": "array", "items": { "type": "string" } }, "account": { "$ref": "#/definitions/PersonaAccountMeta" }, "linkedAccounts": { "type": "object", "additionalProperties": { "$ref": "#/definitions/PersonaAccountMeta" } }, "environments": { "type": "array", "items": { "type": "string" }, "description": "Absent means \"everywhere but production\", which is resolved, not stored." }, "runnable": { "type": "boolean" }, "app": { "type": "string", "description": "The app this person signs into; picks their base url on a browser run." }, "sourceFile": { "type": "string" } }, "required": ["email", "goals", "id", "name", "roles", "runnable", "tags"], "description": "A declared persona with its address filled in — what codegen writes and what a seed, a scenario run and a virtual-user run all read.\n\nThe address is not declared. It is derived from the persona's id and the project's persona domain, so two people can never accidentally share one and sign in as the same user row — which would silently collapse exactly the isolation scenarios a second person exists for." }, "VirtualUserDisposition": { "type": "string", "enum": ["realistic", "careless", "newcomer", "stale", "auditor", "adversarial", "accountable"], "description": "How a virtual user behaves, mechanically. A disposition changes the loop, the input generation, the memory and the oracle — anything that only changes how the user *talks* is persona prose (`ResolvedPersona.personality`) and does not belong here.\n\n- `realistic` — schema-first, goal-directed, plausible values (default).\n- `careless` — repeats, abandons, double-submits, boundary values.\n- `newcomer` — starts with empty memory and must discover everything.\n- `stale` — seeded from an earlier run's ids, some no longer valid.\n- `auditor` — pursues no goal; reads one truth from several places and compares.\n- `adversarial` — probes authorization and tenancy; a 2xx can be the finding.\n- `accountable` — pursues its goals for real; the only one production allows.\n\n`accountable` sits opposite `adversarial` on an *intent* axis — bad faith against good faith — where `careless` and `thorough` are a *care* axis. It is the one disposition whose actions carry consequences: no oracle, no rollback, and every call attributed to the persona in the audit log like anyone else's." }, "VirtualUserTuning": { "type": "object", "properties": { "moves": { "type": "object", "properties": { "continue": { "type": "number" }, "suspend": { "type": "number" }, "resume": { "type": "number" }, "abandon": { "type": "number" } }, "additionalProperties": false, "description": "Relative weights for the scheduler's moves. Merged over the profile's." }, "temperature": { "type": "number" }, "repeatRate": { "type": "number" }, "reReadRate": { "type": "number" }, "emptyMemory": { "type": "boolean" }, "readOnly": { "type": "boolean" }, "invertedOracle": { "type": "boolean" }, "instructions": { "type": "string", "description": "Extra behaviour, appended to the disposition's own instructions." } }, "additionalProperties": false, "description": "Per-user overrides for a disposition's dials.\n\nThe six profiles below are starting points, not laws — the weights are a considered guess about how people behave, and your product is allowed to know better. A user that declares `disposition: 'careless'` with a higher `repeatRate` is still a careless user; it is the same behaviour tuned to a product where double-submits actually happen.\n\n`instructions` is the one field that appends rather than replaces. Everything else is a number the engine reads, so overriding it changes the run and nothing else; instructions are the model's sense of who it is, and letting a declaration replace them wholesale is how you end up with a `careless` user that is not careless — which makes the name, and every run labelled with it, a lie." }, "PersonaAccountMeta": { "type": "object", "properties": { "provider": { "type": "string" } }, "additionalProperties": false }, "SystemRoleDefinitionsMeta": { "type": "object", "additionalProperties": { "$ref": "#/definitions/SystemRoleDefinitionMeta" } }, "SystemRoleDefinitionMeta": { "type": "object", "properties": { "name": { "type": "string" }, "displayName": { "type": "string" }, "description": { "type": "string" }, "scopes": { "type": "array", "items": { "type": "string" } }, "sourceFile": { "type": "string" } }, "required": ["name", "scopes"], "additionalProperties": false }, "FeaturesMeta": { "type": "object", "additionalProperties": { "$ref": "#/definitions/FeatureMeta" } }, "FeatureMeta": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "description": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "entries": { "type": "array", "items": { "$ref": "#/definitions/FeatureMetaEntry" } }, "unresolvedEntries": { "type": "number" }, "hasBefore": { "type": "boolean" }, "hasAfter": { "type": "boolean" } }, "required": ["id", "name", "tags", "entries", "unresolvedEntries", "hasBefore", "hasAfter"], "additionalProperties": false }, "FeatureMetaEntry": { "type": "object", "properties": { "scenario": { "type": "string" }, "data": {} }, "required": ["scenario"], "additionalProperties": false }, "TriggerMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" }, "name": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } } }, "required": ["pikkuFuncId", "name"], "additionalProperties": false }, "TriggerSourceMeta": { "type": "object", "properties": { "name": { "type": "string" }, "pikkuFuncId": { "type": "string" }, "packageName": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" } }, "required": ["name", "pikkuFuncId"], "additionalProperties": false }, "MiddlewareGroupsMeta": { "type": "object", "properties": { "definitions": { "type": "object", "additionalProperties": { "$ref": "#/definitions/MiddlewareDefinitionMeta" } }, "instances": { "type": "object", "additionalProperties": { "$ref": "#/definitions/MiddlewareInstanceMeta" } }, "httpGroups": { "type": "object", "additionalProperties": { "$ref": "#/definitions/GroupMeta" } }, "tagGroups": { "type": "object", "additionalProperties": { "$ref": "#/definitions/GroupMeta" } } }, "required": ["definitions", "instances", "httpGroups", "tagGroups"], "additionalProperties": false }, "MiddlewareDefinitionMeta": { "type": "object", "properties": { "services": { "type": "object", "properties": { "optimized": { "type": "boolean" }, "services": { "type": "array", "items": { "type": "string" } } }, "required": ["optimized", "services"], "additionalProperties": false }, "sourceFile": { "type": "string" }, "position": { "type": "number" }, "exportedName": { "type": ["string", "null"] }, "factory": { "type": "boolean" }, "name": { "type": "string" }, "description": { "type": "string" }, "package": { "type": "string" } }, "required": ["services", "sourceFile", "position", "exportedName"], "additionalProperties": false }, "MiddlewareInstanceMeta": { "type": "object", "properties": { "definitionId": { "type": "string" }, "sourceFile": { "type": "string" }, "position": { "type": "number" }, "isFactoryCall": { "type": "boolean" } }, "required": ["definitionId", "sourceFile", "position", "isFactoryCall"], "additionalProperties": false }, "GroupMeta": { "type": "object", "properties": { "exportName": { "type": ["string", "null"] }, "sourceFile": { "type": "string" }, "position": { "type": "number" }, "services": { "type": "object", "properties": { "optimized": { "type": "boolean" }, "services": { "type": "array", "items": { "type": "string" } } }, "required": ["optimized", "services"], "additionalProperties": false }, "count": { "type": "number" }, "instanceIds": { "type": "array", "items": { "type": "string" } }, "isFactory": { "type": "boolean" } }, "required": ["exportName", "sourceFile", "position", "services", "count", "instanceIds", "isFactory"], "additionalProperties": false }, "PermissionsGroupsMeta": { "type": "object", "properties": { "definitions": { "type": "object", "additionalProperties": { "$ref": "#/definitions/PermissionDefinitionMeta" } } }, "required": ["definitions"], "additionalProperties": false }, "PermissionDefinitionMeta": { "type": "object", "properties": { "services": { "type": "object", "properties": { "optimized": { "type": "boolean" }, "services": { "type": "array", "items": { "type": "string" } } }, "required": ["optimized", "services"], "additionalProperties": false }, "sourceFile": { "type": "string" }, "position": { "type": "number" }, "exportedName": { "type": ["string", "null"] }, "factory": { "type": "boolean" }, "name": { "type": "string" }, "description": { "type": "string" } }, "required": ["services", "sourceFile", "position", "exportedName"], "additionalProperties": false }, "AgentsMeta": { "type": "object", "additionalProperties": { "type": "object", "additionalProperties": false, "properties": { "tools": { "type": "array", "items": { "type": "string" } }, "agents": { "type": "array", "items": { "type": "string" } }, "workflows": { "type": "array", "items": { "type": "string" } }, "inputSchema": { "type": ["string", "null"] }, "outputSchema": { "type": ["string", "null"] }, "workingMemorySchema": { "type": ["string", "null"] }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "channelMiddleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "agentMiddleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } }, "sourceFile": { "type": "string" }, "exportedName": { "type": "string" }, "name": { "type": "string" }, "description": { "type": "string" }, "summary": { "type": "string" }, "errors": { "type": "array", "items": { "type": "string" } }, "role": { "type": "string", "description": "The three fields below are the system prompt. `buildInstructions` joins whichever are set with a blank line, always in this order — role, then personality, then goal — and appends the tool-usage rules if the agent has tools. Nothing checks them against each other: the split is there to keep a prompt legible, and text put in the wrong one still reaches the model.\n\nWho the agent is. 'You are a support engineer triaging inbound bugs.'" }, "personality": { "type": "string", "description": "How it should sound: tone, vocabulary, how much it says at a time." }, "goal": { "type": "string", "description": "What it is for — the only one of the three that is required." }, "model": { "type": "string" }, "temperature": { "type": "number" }, "sessionScope": { "$ref": "#/definitions/SessionScope", "description": "Ownership/partitioning of this agent's threads and runs. Defaults to `'user'`." }, "scorers": { "type": "array", "items": { "type": "string" }, "description": "Grades this agent's finished runs on live traffic, named by the generated `ScorerName` union rather than by `ref()` — a scorer is not a function, so there is nothing in the function map for a ref to resolve against.\n\nA reference-based judge listed here is never sampled: live traffic has no answer key. Scenarios name scorers directly and may grade with scorers an agent does not ship with." }, "agentMode": { "type": "string", "enum": ["delegate", "supervise"] }, "memory": { "$ref": "#/definitions/AgentMemoryConfig" }, "maxSteps": { "type": "number" }, "toolChoice": { "type": "string", "enum": ["auto", "required", "none"] }, "providerOptions": { "$ref": "#/definitions/AIProviderOptions", "description": "Per-provider model settings, keyed by provider id and passed through untouched — for anything only one vendor offers, which the fields above deliberately do not try to unify.\n\n`{ openai: { reasoningEffort: 'minimal' } }` is the one that matters for voice: on gpt-5-mini it measured 0.9s to first token against 2.5s at the default, and a spoken reply is waited through rather than skimmed." }, "tags": { "type": "array", "items": { "type": "string" } }, "prepareStep": { "$comment": "(ctx: {\n stepNumber: number;\n messages: AgentMessage[];\n tools: AgentToolDef[];\n toolChoice: 'auto' | 'required' | 'none';\n model: string;\n stop: () => void;\n }) => void | Promise<void>", "type": "object", "properties": { "namedArgs": { "type": "object", "properties": { "ctx": { "type": "object", "properties": { "stepNumber": { "type": "number" }, "messages": { "type": "array", "items": { "$ref": "#/definitions/AgentMessage" } }, "tools": { "type": "array", "items": { "$ref": "#/definitions/AgentToolDef" } }, "toolChoice": { "type": "string", "enum": ["auto", "required", "none"] }, "model": { "type": "string" }, "stop": { "$comment": "() => void" } }, "required": ["stepNumber", "messages", "tools", "toolChoice", "model", "stop"], "additionalProperties": false } }, "required": ["ctx"], "additionalProperties": false } } }, "auth": { "type": "boolean", "description": "Whether a session is required to run this agent. Defaults to `false`, since agents are commonly invoked from an already-authenticated `pikkuFunc` or from genuinely sessionless contexts (crons, queue workers). Set `true` to require a session at the agent itself. `scopes` and `permissions` are enforced either way." }, "scopes": { "type": "array", "items": { "type": "string" }, "description": "Scopes the session must hold to run this agent. All of them are required (AND), and they are checked before `permissions` — unlike permissions, which OR together, a scope can only narrow access.\n\nNarrowed to the generated `ScopeId` union in a project's own `#pikku/scopes`, so an undeclared scope is a compile error." } }, "required": ["description", "goal", "inputSchema", "model", "name", "outputSchema", "workingMemorySchema"] } }, "SessionScope": { "type": "string", "enum": ["user", "org"], "description": "How an agent's threads/runs are owned and partitioned.\n- `'user'` (default): owner is the authenticated `session.userId`; the caller's `resourceId` becomes a sub-partition within that user (`userId:resourceId`).\n- `'org'`: owner is the authenticated `session.orgId` (`orgId:resourceId`), so threads are shared across everyone in the org. Requires a session with an org (e.g. Better Auth's `organization` plugin) — otherwise access is denied.\n\nThe trusted principal is always the prefix, so a client-supplied `resourceId` can sub-divide within the caller's own boundary but can never widen access to another user's or org's threads." }, "AgentMemoryConfig": { "type": "object", "properties": { "storage": { "type": "string" }, "vector": { "type": "string" }, "embedder": { "type": "string" }, "lastMessages": { "type": "number" }, "workingMemory": {} }, "additionalProperties": false }, "AIProviderOptions": { "type": "object", "additionalProperties": { "type": "object", "additionalProperties": {} } }, "AgentMessage": { "type": "object", "properties": { "id": { "type": "string" }, "role": { "type": "string", "enum": ["system", "user", "assistant", "tool"] }, "content": { "anyOf": [{ "type": "string" }, { "type": "array", "items": { "$ref": "#/definitions/AgentContentPart" } }] }, "toolCalls": { "type": "array", "items": { "$ref": "#/definitions/AgentToolCall" } }, "toolResults": { "type": "array", "items": { "$ref": "#/definitions/AgentToolResult" } }, "reasoningContent": { "type": "string" }, "interrupted": { "type": "boolean", "description": "Set on an assistant message whose generation was cut short by an interrupt — the text is a mid-sentence fragment, not a reply. Carried into the next turn's context so the model can see it said only this much before being talked over, and decide for itself whether to resume, restate or move on. Storage that drops unknown fields loses the marker but keeps the fragment, which degrades to a truncated reply." }, "undelivered": { "type": "boolean", "description": "Set on a tool message whose result arrived after the run was interrupted, so the model never got to describe it. The work happened; only the reply about it was lost. It is ordinary thread context on the next turn — the model raises it unprompted (\"that deploy did go through\") rather than the result being silently dropped or replayed as a fresh tool call." }, "createdAt": { "type": "string", "format": "date-time" } }, "required": ["id", "role", "createdAt"], "additionalProperties": false }, "AgentContentPart": { "anyOf": [{ "type": "object", "properties": { "type": { "type": "string", "const": "text" }, "text": { "type": "string" } }, "required": ["type", "text"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "image" }, "data": { "type": "string" }, "url": { "type": "string" }, "mediaType": { "type": "string" } }, "required": ["type"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "file" }, "data": { "type": "string" }, "url": { "type": "string" }, "mediaType": { "type": "string" }, "filename": { "type": "string" } }, "required": ["type", "mediaType"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "data" }, "name": { "type": "string" }, "data": {} }, "required": ["type", "name", "data"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "generative-ui" }, "spec": {} }, "required": ["type", "spec"], "additionalProperties": false }] }, "AgentToolCall": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "args": { "type": "object", "additionalProperties": {} } }, "required": ["id", "name", "args"], "additionalProperties": false }, "AgentToolResult": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "result": { "type": "string" }, "error": { "type": "string", "description": "Set when the tool threw rather than returned. Carried separately from `result`, which is a rendered string by the time it is persisted — a tool may legitimately return text beginning `Error:`, so the prefix cannot be read as a failure signal." } }, "required": ["id", "name", "result"], "additionalProperties": false }, "AgentToolDef": { "type": "object", "properties": { "needsApproval": { "type": "boolean" }, "approvalDescriptionFn": { "$comment": "(input: unknown) => Promise<string> | string", "type": "object", "properties": { "namedArgs": { "type": "object", "properties": { "input": {} }, "required": ["input"], "additionalProperties": false } } }, "name": { "type": "string" }, "description": { "type": "string" }, "inputSchema": { "type": "object", "additionalProperties": {} }, "execute": { "$comment": "(input: unknown) => Promise<unknown>", "type": "object", "properties": { "namedArgs": { "type": "object", "properties": { "input": {} }, "required": ["input"], "additionalProperties": false } } }, "readonly": { "type": "boolean", "description": "Mirrors the pikku function's `readonly` flag. A read that gets interrupted is discarded rather than reported: nothing changed, and by the next turn the data may be stale anyway — re-reading is cheaper than explaining a result the user never asked to hear about." }, "forwardsApproval": { "type": "boolean", "description": "Set only by the framework on sub-agent delegating tools. Such a tool may legitimately return an `__approvalRequired` marker to forward a nested sub-agent approval. The marker is honored ONLY from a tool with this flag — a plain tool's output (which an attacker may influence) can never forge an approval request. See `checkForApprovals`." } }, "required": ["name", "description", "inputSchema", "execute"], "additionalProperties": false, "description": "`ApprovalPolicy` is shared with channel capabilities, but `Partial` here: absent `needsApproval` means \"do not ask\", which is safe because a tool is written by whoever runs the server it executes on. A capability runs on someone else's machine, so it requires the field instead." }, "EmailsMeta": { "type": "object", "properties": { "src": { "type": "string" }, "themeHash": { "type": "string" }, "templates": { "type": "object", "additionalProperties": { "$ref": "#/definitions/EmailTemplateMeta" } } }, "required": ["src", "themeHash", "templates"], "additionalProperties": false }, "EmailTemplateMeta": { "type": "object", "properties": { "variables": { "type": "array", "items": { "type": "string" } }, "hasHtml": { "type": "boolean" }, "hasSubject": { "type": "boolean" }, "hasText": { "type": "boolean" }, "locales": { "type": "object", "additionalProperties": { "$ref": "#/definitions/EmailTemplateLocaleMeta" } } }, "required": ["variables", "hasHtml", "hasSubject", "hasText", "locales"], "additionalProperties": false }, "EmailTemplateLocaleMeta": { "type": "object", "properties": { "contentHash": { "type": "string" }, "htmlHash": { "type": "string" }, "subjectHash": { "type": "string" }, "textHash": { "type": "string" } }, "required": ["contentHash", "htmlHash", "subjectHash", "textHash"], "additionalProperties": false }, "FunctionUsedBy": { "type": "object", "properties": { "transports": { "type": "array", "items": { "$ref": "#/definitions/WiringRef" } }, "jobs": { "type": "array", "items": { "$ref": "#/definitions/WiringRef" } }, "workflows": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" } }, "required": ["id", "name"], "additionalProperties": false } } }, "required": ["transports", "jobs", "workflows"], "additionalProperties": false }, "WiringRef": { "type": "object", "properties": { "type": { "type": "string" }, "id": { "type": "string" }, "name": { "type": "string" } }, "required": ["type", "id", "name"], "additionalProperties": false }, "MetaCounts": { "type": "object", "properties": { "functions": { "type": "number" }, "workflows": { "type": "number" }, "httpRoutes": { "type": "number" }, "channels": { "type": "number" }, "mcpTools": { "type": "number" }, "gateways": { "type": "number" }, "schedulers": { "type": "number" }, "queues": { "type": "number" }, "cliCommands": { "type": "number" }, "rpcMethods": { "type": "number" }, "triggers": { "type": "number" }, "triggerSources": { "type": "number" }, "agents": { "type": "number" }, "emails": { "type": "number" }, "secrets": { "type": "number" }, "variables": { "type": "number" } }, "required": ["functions", "workflows", "httpRoutes", "channels", "mcpTools", "gateways", "schedulers", "queues", "cliCommands", "rpcMethods", "triggers", "triggerSources", "agents", "emails", "secrets", "variables"], "additionalProperties": false } } }
|
|
1
|
+
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "functions": { "type": "array", "items": { "$ref": "#/definitions/FunctionMeta" } }, "httpMeta": { "type": "array", "items": { "$ref": "#/definitions/HttpRouteMeta" } }, "cliMeta": { "type": "array", "items": { "$ref": "#/definitions/CliProgramMeta" } }, "cliRenderers": { "type": "object", "additionalProperties": { "$ref": "#/definitions/CliRendererMeta" } }, "channelsMeta": { "type": "object", "additionalProperties": { "$ref": "#/definitions/ChannelMeta" } }, "queueMeta": { "type": "object", "additionalProperties": { "$ref": "#/definitions/QueueWorkerMeta" } }, "schedulerMeta": { "type": "object", "additionalProperties": { "$ref": "#/definitions/SchedulerTaskMeta" } }, "rpcMeta": { "type": "object", "additionalProperties": { "$ref": "#/definitions/RpcMeta" } }, "mcpMeta": { "type": "array", "items": { "$ref": "#/definitions/McpItemMeta" } }, "gatewayMeta": { "type": "array", "items": { "$ref": "#/definitions/GatewayItemMeta" } }, "workflows": { "$ref": "#/definitions/WorkflowsMeta" }, "personas": { "type": "object", "additionalProperties": { "$ref": "#/definitions/ResolvedPersona" } }, "systemRoles": { "$ref": "#/definitions/SystemRoleDefinitionsMeta", "description": "The roles declared with `defineSystemRole`, keyed by name.\n\nShipped alongside the personas because a persona only ever names roles, and nothing about what they can reach is readable without the scopes each one confers." }, "features": { "$ref": "#/definitions/FeaturesMeta" }, "triggerMeta": { "type": "object", "additionalProperties": { "$ref": "#/definitions/TriggerMeta" } }, "triggerSourceMeta": { "type": "object", "additionalProperties": { "$ref": "#/definitions/TriggerSourceMeta" } }, "middlewareGroupsMeta": { "$ref": "#/definitions/MiddlewareGroupsMeta" }, "permissionsGroupsMeta": { "$ref": "#/definitions/PermissionsGroupsMeta" }, "agentsMeta": { "$ref": "#/definitions/AgentsMeta" }, "emailsMeta": { "$ref": "#/definitions/EmailsMeta" }, "secretsMeta": { "type": "object", "additionalProperties": {} }, "credentialsMeta": { "type": "object", "additionalProperties": {} }, "variablesMeta": { "type": "object", "additionalProperties": {} }, "functionUsedBy": { "type": "object", "additionalProperties": { "$ref": "#/definitions/FunctionUsedBy" } }, "counts": { "$ref": "#/definitions/MetaCounts" } }, "required": ["agentsMeta", "channelsMeta", "cliMeta", "cliRenderers", "counts", "credentialsMeta", "emailsMeta", "features", "functionUsedBy", "functions", "gatewayMeta", "httpMeta", "mcpMeta", "middlewareGroupsMeta", "permissionsGroupsMeta", "personas", "queueMeta", "rpcMeta", "schedulerMeta", "secretsMeta", "systemRoles", "triggerMeta", "triggerSourceMeta", "variablesMeta", "workflows"], "additionalProperties": false, "definitions": { "FunctionMeta": { "type": "object", "additionalProperties": false, "properties": { "name": { "type": "string" }, "functionType": { "type": "string", "enum": ["user", "inline", "helper", "remote"], "description": "`remote`: a contract with no local body, answered by a connected client." }, "funcWrapper": { "type": "string" }, "services": { "$ref": "#/definitions/FunctionServicesMeta" }, "wires": { "$ref": "#/definitions/FunctionWiresMeta" }, "inputs": { "anyOf": [{ "type": "array", "items": { "type": "string" } }, { "type": "null" }] }, "outputs": { "anyOf": [{ "type": "array", "items": { "type": "string" } }, { "type": "null" }] }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } }, "isDirectFunction": { "type": "boolean" }, "sourceFile": { "type": "string" }, "exportedName": { "type": "string" }, "bodySourceFile": { "type": "string", "description": "File containing the handler body when it differs from sourceFile (imported handlers)" }, "bodyStart": { "type": "number", "description": "1-indexed first line of the handler body (verbose meta; coverage mapping)" }, "bodyEnd": { "type": "number", "description": "1-indexed last line of the handler body (verbose meta; coverage mapping)" }, "pikkuFuncId": { "type": "string" }, "packageName": { "type": "string" }, "title": { "type": "string", "description": "A human name for this wiring, shown wherever it is listed rather than called." }, "tags": { "type": "array", "items": { "type": "string" }, "description": "Filters this wiring in and out of a build — see the `tags` option on `pikku all`. It has no effect at runtime." }, "summary": { "type": "string", "description": "A one-line description for listings, where the full `description` is too long." }, "description": { "type": "string", "description": "What this does, for whoever is reading the wiring rather than writing it." }, "errors": { "type": "array", "items": { "type": "string" }, "description": "Names of error classes this may throw, so each one's registered status is used instead of a 500." }, "inputSchemaName": { "type": ["string", "null"] }, "outputSchemaName": { "type": ["string", "null"] }, "scopes": { "type": "array", "items": { "type": "string" }, "description": "Scopes the session must hold to run this function. All are required (AND)." }, "expose": { "type": "boolean" }, "auth": { "type": "boolean", "description": "A sessionless function's own `auth: true`. `sessionless` carries the baseline — a `pikkuFunc` always requires a session — and this carries the tightening a `pikkuSessionlessFunc` applies to itself. Both are needed to know whether a function is gated without running it." }, "permissionsInBody": { "type": "boolean", "description": "The author's declaration that this function's permission check lives in its own body. Carries no runtime effect — it records a gate codegen cannot see, so an audit is not left to guess whether a sessionless function is open. Refused unless `allow.permissionsInBody` is set in `pikku.config.json`." }, "remote": { "type": "boolean" }, "scenarioStep": { "type": "boolean", "description": "A step RPC: invoked by name only from a scenario run and refused everywhere else, so it is never network-callable." }, "scenario": { "type": "boolean", "description": "The body of a `pikkuScenario(...)`. Only ever run by `pikku scenario run`, so it is held back from the app bootstrap and from every deployed unit." }, "mcp": { "type": "boolean" }, "readonly": { "type": "boolean" }, "deploy": { "type": "string", "enum": ["serverless", "server", "auto"] }, "sessionless": { "type": "boolean" }, "workflowQueued": { "type": "boolean", "description": "When true, workflow steps calling this function are dispatched via the queue. No queue service configured is a hard error." }, "workflowRetries": { "type": "number", "description": "Retry count when this function is used as a workflow step." }, "workflowTimeout": { "type": "string", "description": "Timeout when this function is used as a workflow step (e.g. '30s', '5m')." }, "scenarioStepSurfaces": { "type": "array", "items": { "$ref": "#/definitions/ScenarioSurface" }, "description": "Scenario steps only: which surfaces this step declares a binding for.\n\nThe reporter derives coverage from this — a `then` with no binding for the surface the run targeted was never actually witnessed there, which is a gap worth counting rather than excusing." }, "scenarioStepRequiresActor": { "type": "boolean", "description": "Scenario steps only: this step runs as a persona, so every call site must pass one and the runner injects it as `wire.actor`.\n\nDeclared by `actor: true`, or implied by a `browser` binding — a window is opened as somebody. Absent on a step with nobody to be: an assertion over what an earlier step returned, or one posting credentials precisely because it must not reuse an actor's session." }, "scenarioStepKind": { "$ref": "#/definitions/ScenarioStepKind", "description": "Scenario steps only: who acts. Absent means `persona` — the ordinary step, and the only kind that existed before the other two.\n\nA `platform` or `addon` step is the app or a third-party system acting, and it must never reach a virtual user's catalogue. That is not tidiness: a virtual user that can invoke \"Stripe's webhook arrives\" can forge its own payment success, and every finding downstream of that is worthless." }, "scenarioStepAddon": { "type": "string", "description": "Addon steps only: the addon whose system acts — `wireAddon`'s `name`." }, "scenarioStepTemplate": { "type": "string", "description": "Scenario steps only: the prose a reporter renders, with `{placeholders}` filled from the step's recorded input." }, "audit": { "type": "object", "properties": { "durability": { "$ref": "#/definitions/AuditDurability" } }, "required": ["durability"], "additionalProperties": false, "description": "The function's `audit` config, resolved — `audit: true` reads as `{ durability: 'best-effort' }`. Absent means the function records nothing: `auditLog.write()` from an unmarked function is dropped with a warning, so this is the only place a reader can see which functions have a trail at all without running them.\n\nInformational. The runner resolves audit from the live function config, not from here, so meta and runtime cannot disagree about whether audit is on." }, "version": { "type": "number" }, "approvalRequired": { "type": "boolean" }, "approvalDescription": { "type": "string" }, "implementationHash": { "type": "string" }, "contractHash": { "type": "string" }, "inputHash": { "type": "string" }, "outputHash": { "type": "string" } }, "required": ["inputSchemaName", "outputSchemaName", "pikkuFuncId"] }, "FunctionServicesMeta": { "type": "object", "properties": { "optimized": { "type": "boolean" }, "services": { "type": "array", "items": { "type": "string" } } }, "required": ["optimized", "services"], "additionalProperties": false }, "FunctionWiresMeta": { "type": "object", "properties": { "optimized": { "type": "boolean" }, "wires": { "type": "array", "items": { "type": "string" } } }, "required": ["optimized", "wires"], "additionalProperties": false }, "MiddlewareMetadata": { "anyOf": [{ "type": "object", "properties": { "type": { "type": "string", "const": "http" }, "route": { "type": "string" } }, "required": ["type", "route"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "tag" }, "tag": { "type": "string" } }, "required": ["type", "tag"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "wire" }, "name": { "type": "string" }, "inline": { "type": "boolean" } }, "required": ["type", "name"], "additionalProperties": false }] }, "PermissionMetadata": { "type": "object", "properties": { "type": { "type": "string", "const": "wire" }, "name": { "type": "string" }, "inline": { "type": "boolean" } }, "required": ["type", "name"], "additionalProperties": false, "description": "A reference to a permission function, resolved by name. Function-scoped only: there are no wire- or tag-level permission references." }, "ScenarioSurface": { "type": "string", "enum": ["browser", "cli", "default"], "description": "How an actor drives the system for one step.\n\nA step declares one implementation per surface it supports, and the runner picks between them — so the same ladder can run through a real browser, over the websocket, or entirely server-side.\n\n`default` is the floor: it is what every other surface falls back to, so it can never itself fall back." }, "ScenarioStepKind": { "type": "string", "enum": ["persona", "platform", "addon"], "description": "Who acts in a step.\n\n`persona` is a person driving the system through one of its surfaces — the ordinary `pikkuScenarioStep`. `platform` is the app acting on itself (\"the platform has expired the trial\"), and `addon` is a third-party system acting on it (\"Stripe's webhook arrives\"), contributed by the addon that wraps that service.\n\nThe three are separate declarations rather than a field on one, so the inspector verifies a step's kind by which function was called rather than by trusting a string literal — and so an addon package exports only addon steps, which is checkable." }, "AuditDurability": { "type": "string", "enum": ["best-effort", "transactional"] }, "HttpRouteMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" }, "route": { "type": "string" }, "method": { "type": "string" }, "params": { "type": "array", "items": { "type": "string" } }, "query": { "type": "array", "items": { "type": "string" } }, "summary": { "type": "string" }, "description": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "errors": { "type": "array", "items": { "type": "string" } }, "auth": { "type": "boolean" }, "sse": { "type": "boolean" }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } }, "inputSchemaName": { "type": "string" }, "outputSchemaName": { "type": "string" } }, "required": ["pikkuFuncId", "route", "method"], "additionalProperties": false }, "CliProgramMeta": { "type": "object", "properties": { "wireId": { "type": "string" }, "program": { "type": "string" }, "description": { "type": "string" }, "commands": { "type": "object", "additionalProperties": { "$ref": "#/definitions/CliCommandMeta" } }, "options": { "type": "object", "additionalProperties": { "$ref": "#/definitions/CliOptionMeta" } }, "defaultRenderName": { "type": "string" } }, "required": ["wireId", "program", "commands", "options"], "additionalProperties": false }, "CliCommandMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" }, "description": { "type": "string" }, "summary": { "type": "string" }, "parameters": { "type": "string" }, "positionals": { "type": "array", "items": { "$ref": "#/definitions/CliPositionalMeta" } }, "options": { "type": "object", "additionalProperties": { "$ref": "#/definitions/CliOptionMeta" } }, "renderName": { "type": "string" }, "subcommands": { "type": "object", "additionalProperties": { "$ref": "#/definitions/CliCommandMeta" } }, "isDefault": { "type": "boolean" } }, "required": ["pikkuFuncId", "positionals", "options"], "additionalProperties": false }, "CliPositionalMeta": { "type": "object", "properties": { "name": { "type": "string" }, "required": { "type": "boolean" }, "variadic": { "type": "boolean" } }, "required": ["name", "required"], "additionalProperties": false }, "CliOptionMeta": { "type": "object", "properties": { "description": { "type": "string" }, "short": { "type": "string" }, "default": {}, "choices": { "type": "array", "items": {} }, "array": { "type": "boolean" }, "required": { "type": "boolean" } }, "required": ["description"], "additionalProperties": false }, "CliRendererMeta": { "type": "object", "properties": { "name": { "type": "string" }, "exportedName": { "type": "string" }, "filePath": { "type": "string" }, "services": { "type": "object", "properties": { "optimized": { "type": "boolean" }, "services": { "type": "array", "items": { "type": "string" } } }, "required": ["optimized", "services"], "additionalProperties": false } }, "required": ["name", "filePath", "services"], "additionalProperties": false }, "ChannelMeta": { "type": "object", "properties": { "name": { "type": "string" }, "route": { "type": "string" }, "params": { "type": "array", "items": { "type": "string" } }, "query": { "type": "array", "items": { "type": "string" } }, "input": { "type": ["string", "null"] }, "connect": { "anyOf": [{ "$ref": "#/definitions/ChannelMessageMeta" }, { "type": "null" }] }, "disconnect": { "anyOf": [{ "$ref": "#/definitions/ChannelMessageMeta" }, { "type": "null" }] }, "message": { "anyOf": [{ "$ref": "#/definitions/ChannelMessageMeta" }, { "type": "null" }] }, "messageWirings": { "type": "object", "additionalProperties": { "type": "object", "additionalProperties": { "$ref": "#/definitions/ChannelMessageMeta" } } }, "summary": { "type": "string" }, "description": { "type": "string" }, "errors": { "type": "array", "items": { "type": "string" } }, "tags": { "type": "array", "items": { "type": "string" } }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } } }, "required": ["name", "route", "input", "connect", "disconnect", "message", "messageWirings"], "additionalProperties": false }, "ChannelMessageMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" }, "errors": { "type": "array", "items": { "type": "string" } }, "tags": { "type": "array", "items": { "type": "string" } }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } } }, "required": ["pikkuFuncId"], "additionalProperties": false }, "QueueWorkerMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" }, "queueName": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } }, "config": { "type": "object", "additionalProperties": {} } }, "required": ["pikkuFuncId", "queueName"], "additionalProperties": false }, "SchedulerTaskMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" }, "name": { "type": "string" }, "schedule": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } } }, "required": ["pikkuFuncId", "name", "schedule"], "additionalProperties": false }, "RpcMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" } }, "required": ["pikkuFuncId"], "additionalProperties": false }, "McpItemMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" }, "method": { "type": "string", "enum": ["resource", "tool", "prompt"] }, "name": { "type": "string" }, "wireId": { "type": "string" }, "description": { "type": "string" }, "summary": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "errors": { "type": "array", "items": { "type": "string" } }, "uri": { "type": "string" }, "arguments": { "type": "array", "items": { "type": "object", "properties": { "name": { "type": "string" }, "description": { "type": "string" }, "required": { "type": "boolean" } }, "required": ["name"], "additionalProperties": false } }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } }, "inputSchemaName": { "type": "string" }, "outputSchemaName": { "type": "string" } }, "required": ["pikkuFuncId", "method"], "additionalProperties": false }, "GatewayItemMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" }, "name": { "type": "string" }, "type": { "type": "string", "enum": ["webhook", "websocket", "listener"] }, "route": { "type": "string" }, "platform": { "type": "string" }, "packageName": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "errors": { "type": "array", "items": { "type": "string" } }, "auth": { "type": "boolean" }, "gateway": { "type": "boolean", "const": true }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } } }, "required": ["pikkuFuncId", "name", "type", "gateway"], "additionalProperties": false }, "WorkflowsMeta": { "type": "object", "additionalProperties": { "type": "object", "additionalProperties": false, "properties": { "name": { "type": "string" }, "steps": { "type": "array", "items": { "$ref": "#/definitions/WorkflowStepMeta" } }, "context": { "$ref": "#/definitions/WorkflowContext" }, "dsl": { "type": "boolean" }, "expose": { "type": "boolean" }, "scenario": { "type": "boolean" }, "asserts": { "type": "boolean", "description": "The flow asserts through an expectation helper — `expectService`, `expectError`, `expectEventually` — rather than a `then` step. Those are inline steps and carry no phase, so without this PKU680 reads a scenario whose only witness is a recorded service call as asserting nothing." }, "skip": { "type": "string" }, "actors": { "type": "array", "items": { "type": "string" } }, "pikkuFuncId": { "type": "string" }, "packageName": { "type": "string" }, "title": { "type": "string", "description": "A human name for this wiring, shown wherever it is listed rather than called." }, "tags": { "type": "array", "items": { "type": "string" }, "description": "Filters this wiring in and out of a build — see the `tags` option on `pikku all`. It has no effect at runtime." }, "summary": { "type": "string", "description": "A one-line description for listings, where the full `description` is too long." }, "description": { "type": "string", "description": "What this does, for whoever is reading the wiring rather than writing it." }, "errors": { "type": "array", "items": { "type": "string" }, "description": "Names of error classes this may throw, so each one's registered status is used instead of a 500." }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } } }, "required": ["name", "pikkuFuncId", "steps"] } }, "WorkflowStepMeta": { "anyOf": [{ "$ref": "#/definitions/RpcStepMeta" }, { "$ref": "#/definitions/ScenarioStepMeta" }, { "$ref": "#/definitions/BranchStepMeta" }, { "$ref": "#/definitions/ParallelGroupStepMeta" }, { "$ref": "#/definitions/FanoutStepMeta" }, { "$ref": "#/definitions/ReturnStepMeta" }, { "$ref": "#/definitions/InlineStepMeta" }, { "$ref": "#/definitions/SleepStepMeta" }, { "$ref": "#/definitions/CancelStepMeta" }, { "$ref": "#/definitions/SuspendStepMeta" }, { "$ref": "#/definitions/ApprovalStepMeta" }, { "$ref": "#/definitions/SwitchStepMeta" }, { "$ref": "#/definitions/FilterStepMeta" }, { "$ref": "#/definitions/ArrayPredicateStepMeta" }, { "$ref": "#/definitions/SetStepMeta" }], "description": "Workflow step metadata (extracted by inspector)" }, "RpcStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "rpc", "description": "RPC form - generates queue worker" }, "stepName": { "type": "string", "description": "Cache key (stepName from workflow.do)" }, "rpcName": { "type": "string", "description": "RPC to invoke" }, "outputVar": { "type": "string", "description": "Output variable name (if assigned)" }, "inputs": { "anyOf": [{ "type": "object", "additionalProperties": { "$ref": "#/definitions/InputSource" } }, { "type": "string", "const": "passthrough" }], "description": "Input source mappings, or 'passthrough' when entire data is passed" }, "options": { "$ref": "#/definitions/WorkflowStepOptions", "description": "Step options" }, "actor": { "type": "string", "description": "Scenario actor name this step runs as ({ actor: actors.x })" }, "expectEventually": { "type": "boolean", "description": "True for workflow.expectEventually polling steps" } }, "required": ["type", "stepName", "rpcName"], "additionalProperties": false, "description": "RPC step metadata (base form)" }, "InputSource": { "anyOf": [{ "type": "object", "properties": { "from": { "type": "string", "const": "input" }, "path": { "type": "string" } }, "required": ["from", "path"], "additionalProperties": false }, { "type": "object", "properties": { "from": { "type": "string", "const": "outputVar" }, "name": { "type": "string" }, "path": { "type": "string" } }, "required": ["from", "name"], "additionalProperties": false }, { "type": "object", "properties": { "from": { "type": "string", "const": "item" }, "path": { "type": "string" } }, "required": ["from", "path"], "additionalProperties": false }, { "type": "object", "properties": { "from": { "type": "string", "const": "literal" }, "value": {} }, "required": ["from", "value"], "additionalProperties": false }, { "type": "object", "properties": { "from": { "type": "string", "const": "template" }, "parts": { "type": "array", "items": { "type": "string" } }, "expressions": { "type": "array", "items": { "$ref": "#/definitions/InputSource" } } }, "required": ["from", "parts", "expressions"], "additionalProperties": false }], "description": "Input source for step arguments in DSL workflows" }, "WorkflowStepOptions": { "type": "object", "properties": { "description": { "type": "string", "description": "Display name for logs/UI (optional, doesn't affect execution)" }, "retries": { "type": "number", "description": "Number of retry attempts for failed steps (only applies to local execution)" }, "retryDelay": { "type": ["string", "number"], "description": "Delay between retry attempts (e.g., '1s', '2s', '2min')" }, "onError": { "type": "string", "description": "RPC to invoke for compensation when this step fails after exhausting its retries. Mirrors a graph node's `onError`: the handler receives `{ error: { message } }` and the original error is still thrown, so the workflow fails — this is compensation, not recovery." }, "actor": { "$ref": "#/definitions/ScenarioPersona", "description": "Run this step as an actor (scenarios). The RPC is sent through the actor's authenticated client over the REAL transport — never dispatched internally — so auth middleware and permissions are exercised end-to-end. The step is recorded durably like any RPC step." } }, "additionalProperties": false, "description": "Workflow step options" }, "ScenarioPersona": { "type": "object", "properties": { "name": { "type": "string", "description": "The id it was declared under — what a step's `actor` slot names." }, "email": { "type": "string", "description": "Their address, computed from the id. Flows use it for invites/lookups." } }, "required": ["name", "email"], "additionalProperties": false, "description": "A declared person, signed in and acting over the real transport.\n\nThe runtime half of `definePersonas()`: sign-in materialises a user row flagged `actor: true`, and everything a step or a virtual user does goes through here." }, "ScenarioStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "scenarioStep" }, "stepName": { "type": "string", "description": "Cache key (first argument), ordinal-suffixed by the engine when repeated" }, "stepFunc": { "type": "string", "description": "Registered name of the step function being run" }, "phase": { "$ref": "#/definitions/ScenarioStepPhase", "description": "Which keyword the reporter prefixes — Given, When or Then" }, "outputVar": { "type": "string", "description": "Output variable name (if assigned)" }, "inputs": { "anyOf": [{ "type": "object", "additionalProperties": { "$ref": "#/definitions/InputSource" } }, { "type": "string", "const": "passthrough" }], "description": "Input source mappings, or 'passthrough' when entire data is passed" }, "options": { "$ref": "#/definitions/WorkflowStepOptions", "description": "Step options" }, "actor": { "type": "string", "description": "Scenario actor name this step runs as ({ actor: actors.x })" }, "surfaces": { "type": "array", "items": { "$ref": "#/definitions/ScenarioSurface" }, "description": "Mirrors the surfaces the step function declares a binding for" } }, "required": ["type", "stepName", "stepFunc", "phase"], "additionalProperties": false, "description": "Scenario step metadata — a call to `scenario.given/when/then`.\n\nDistinct from RpcStepMeta on purpose: a step runs locally through runPikkuFunc and must never be treated as dispatchable on the queue/replay path, nor registered as a callable RPC (a browser-driving step must not be network-invocable)." }, "ScenarioStepPhase": { "type": "string", "enum": ["given", "when", "then"], "description": "Which Gherkin-style keyword the reporter prefixes this step with.\n\nEvery step takes one. A scenario is read by people deciding whether it describes the behaviour they wanted, and a step that says only what it does without saying whether it is setup, action or claim is the one nobody can check — which is also why PKU680 can tell a scenario that never asserts." }, "BranchStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "branch" }, "branches": { "type": "array", "items": { "$ref": "#/definitions/BranchCase" }, "description": "Branches in order: first is \"if\", rest are \"else if\"" }, "elseSteps": { "type": "array", "items": { "$ref": "#/definitions/WorkflowStepMeta" }, "description": "Else branch steps (when no conditions match)" } }, "required": ["type", "branches"], "additionalProperties": false, "description": "Branch step metadata (if/else-if/else control flow)" }, "BranchCase": { "type": "object", "properties": { "condition": { "$ref": "#/definitions/Condition", "description": "Condition for this branch" }, "steps": { "type": "array", "items": { "$ref": "#/definitions/WorkflowStepMeta" }, "description": "Steps to execute when condition is true" } }, "required": ["condition", "steps"], "additionalProperties": false, "description": "A single branch in an if/else-if chain" }, "Condition": { "anyOf": [{ "$ref": "#/definitions/SimpleCondition" }, { "type": "object", "properties": { "type": { "type": "string", "const": "and" }, "conditions": { "type": "array", "items": { "$ref": "#/definitions/Condition" } } }, "required": ["type", "conditions"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "or" }, "conditions": { "type": "array", "items": { "$ref": "#/definitions/Condition" } } }, "required": ["type", "conditions"], "additionalProperties": false }], "description": "Nested condition structure supporting AND/OR operations" }, "SimpleCondition": { "type": "object", "properties": { "type": { "type": "string", "const": "simple" }, "expression": { "type": "string" } }, "required": ["type", "expression"], "additionalProperties": false, "description": "Simple condition expression (leaf node)" }, "ParallelGroupStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "parallel" }, "children": { "type": "array", "items": { "anyOf": [{ "$ref": "#/definitions/RpcStepMeta" }, { "$ref": "#/definitions/ScenarioStepMeta" }] }, "description": "Child steps to execute in parallel" } }, "required": ["type", "children"], "additionalProperties": false, "description": "Parallel group step metadata (Promise.all with multiple steps)" }, "FanoutStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "fanout" }, "stepName": { "type": "string", "description": "Step name for this fanout. Optional: a fanout is not itself a cached step, and node ids are step names — borrowing a body step's name would give the loop and that step the same id, collapsing one onto the other." }, "sourceVar": { "type": "string", "description": "Source array variable name" }, "itemVar": { "type": "string", "description": "Iterator variable name" }, "mode": { "type": "string", "enum": ["parallel", "sequential"], "description": "Execution mode" }, "body": { "type": "array", "items": { "anyOf": [{ "$ref": "#/definitions/RpcStepMeta" }, { "$ref": "#/definitions/SleepStepMeta" }, { "$ref": "#/definitions/SuspendStepMeta" }, { "$ref": "#/definitions/ScenarioStepMeta" }] }, "description": "Steps to execute inline per iteration, in order" }, "timeBetween": { "type": "string", "description": "Time between iterations (sequential mode only)" } }, "required": ["type", "sourceVar", "itemVar", "mode", "body"], "additionalProperties": false, "description": "Fanout step metadata (parallel or sequential iteration)" }, "SleepStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "sleep", "description": "Sleep step" }, "stepName": { "type": "string", "description": "Cache key (stepName from workflow.sleep)" }, "duration": { "type": ["string", "number"], "description": "Sleep duration" }, "expression": { "type": "string", "description": "Source text of a duration only known at runtime (e.g. a loop variable). The closure evaluates it, so it is legal DSL; it is kept separate from `duration` so regenerated code emits it raw rather than as a string literal, exactly as `expression` does on a set step." } }, "required": ["type", "stepName", "duration"], "additionalProperties": false, "description": "Sleep step metadata" }, "SuspendStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "suspend" }, "reason": { "type": "string", "description": "Reason string passed to workflow.suspend() — becomes the durable step key" } }, "required": ["type", "reason"], "additionalProperties": false, "description": "Suspend step metadata (workflow.suspend())" }, "ReturnStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "return" }, "outputs": { "type": "object", "additionalProperties": { "$ref": "#/definitions/OutputBinding" }, "description": "Output bindings" }, "spread": { "type": "array", "items": { "type": "string" }, "description": "Variables spread into the returned object (`return { ...r }`), or the sole returned variable (`return r`). Their fields are not enumerable statically, so they are recorded by name rather than expanded into `outputs`." } }, "required": ["type", "outputs"], "additionalProperties": false, "description": "Return step metadata (workflow output)" }, "OutputBinding": { "anyOf": [{ "type": "object", "properties": { "from": { "type": "string", "const": "outputVar" }, "name": { "type": "string" }, "path": { "type": "string" } }, "required": ["from", "name"], "additionalProperties": false }, { "type": "object", "properties": { "from": { "type": "string", "const": "stateVar" }, "name": { "type": "string" }, "path": { "type": "string" } }, "required": ["from", "name"], "additionalProperties": false }, { "type": "object", "properties": { "from": { "type": "string", "const": "input" }, "path": { "type": "string" } }, "required": ["from", "path"], "additionalProperties": false }, { "type": "object", "properties": { "from": { "type": "string", "const": "literal" }, "value": {} }, "required": ["from", "value"], "additionalProperties": false }, { "type": "object", "properties": { "from": { "type": "string", "const": "expression" }, "expression": { "type": "string" } }, "required": ["from", "expression"], "additionalProperties": false }], "description": "Output binding for return statements in DSL workflows" }, "InlineStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "inline", "description": "Inline form - local execution" }, "stepName": { "type": "string", "description": "Cache key (stepName from workflow.do)" }, "description": { "type": "string", "description": "Display name" }, "options": { "$ref": "#/definitions/WorkflowStepOptions", "description": "Step options" } }, "required": ["type", "stepName"], "additionalProperties": false, "description": "Inline step metadata" }, "CancelStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "cancel", "description": "Cancel step" }, "reason": { "type": "string", "description": "Optional cancellation reason" } }, "required": ["type"], "additionalProperties": false, "description": "Cancel step metadata" }, "ApprovalStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "approval" }, "reason": { "type": "string", "description": "Reason string passed to workflow.approval() — becomes the durable step key" }, "outputVar": { "type": "string", "description": "Output variable name (if assigned)" }, "expiry": { "type": ["string", "number"], "description": "Expiry duration, when one was given" }, "approvers": { "$ref": "#/definitions/WorkflowApprovalApprovers", "description": "Who may answer the gate, when the default was not used" }, "approverScope": { "type": "string", "description": "Scope the decider must hold, when one was required" } }, "required": ["type", "reason"], "additionalProperties": false, "description": "Approval step metadata (workflow.approval())" }, "WorkflowApprovalApprovers": { "type": "string", "enum": ["any", "owner", "not-initiator"], "description": "Who is allowed to answer an approval gate, relative to the user who started the run.\n\n- `any` — anyone the approve entrypoint lets through. The gate is a pause for a decision, not an authorization boundary.\n- `owner` — only the user who started the run, so a gate can be used to confirm an action against the same person who requested it.\n- `not-initiator` — anyone *except* the user who started the run: four-eyes. A run with no recorded initiator has nobody to exclude, so this degrades to requiring a signed-in decider." }, "SwitchStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "switch" }, "expression": { "type": "string", "description": "Expression being switched on" }, "cases": { "type": "array", "items": { "$ref": "#/definitions/SwitchCaseMeta" }, "description": "Case branches" }, "defaultSteps": { "type": "array", "items": { "$ref": "#/definitions/WorkflowStepMeta" }, "description": "Default case steps (optional)" } }, "required": ["type", "expression", "cases"], "additionalProperties": false, "description": "Switch step metadata (switch/case control flow)" }, "SwitchCaseMeta": { "type": "object", "properties": { "value": { "type": ["string", "number", "boolean", "null"], "description": "Case value (literal) or expression" }, "expression": { "type": "string", "description": "Case expression (for complex cases)" }, "steps": { "type": "array", "items": { "$ref": "#/definitions/WorkflowStepMeta" }, "description": "Steps to execute for this case" } }, "required": ["steps"], "additionalProperties": false, "description": "Switch case metadata" }, "FilterStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "filter" }, "sourceVar": { "type": "string", "description": "Source array variable name" }, "itemVar": { "type": "string", "description": "Iterator variable name" }, "condition": { "$ref": "#/definitions/Condition", "description": "Filter condition" }, "outputVar": { "type": "string", "description": "Output variable name (if assigned)" } }, "required": ["type", "sourceVar", "itemVar", "condition"], "additionalProperties": false, "description": "Filter step metadata (array.filter)" }, "ArrayPredicateStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "arrayPredicate" }, "mode": { "type": "string", "enum": ["some", "every"], "description": "Predicate mode" }, "sourceVar": { "type": "string", "description": "Source array variable name" }, "itemVar": { "type": "string", "description": "Iterator variable name" }, "condition": { "$ref": "#/definitions/Condition", "description": "Predicate condition" }, "outputVar": { "type": "string", "description": "Output variable name (if assigned)" } }, "required": ["type", "mode", "sourceVar", "itemVar", "condition"], "additionalProperties": false, "description": "Array predicate step metadata (array.some, array.every)" }, "SetStepMeta": { "type": "object", "properties": { "type": { "type": "string", "const": "set", "description": "Set step" }, "variable": { "type": "string", "description": "Variable name to set (must be in context)" }, "value": { "description": "Literal value to assign. Mutually exclusive with `expression`." }, "expression": { "type": "string", "description": "Source text of a non-literal assignment (e.g. `count + 1`). Kept separate from `value` so regenerated code can emit it raw — a string `value` is a string literal, an `expression` is code." } }, "required": ["type", "variable"], "additionalProperties": false, "description": "Set step metadata (context variable assignment)" }, "WorkflowContext": { "type": "object", "additionalProperties": { "$ref": "#/definitions/ContextVariable" } }, "ContextVariable": { "type": "object", "properties": { "type": { "type": "string", "enum": ["string", "number", "boolean", "object", "array"] }, "default": {}, "description": { "type": "string" } }, "required": ["type"], "additionalProperties": false }, "ResolvedPersona": { "type": "object", "additionalProperties": false, "properties": { "email": { "type": "string" }, "id": { "type": "string", "description": "The key it was declared under." }, "name": { "type": "string" }, "jobTitle": { "type": "string" }, "description": { "type": "string" }, "avatarUrl": { "type": "string" }, "roles": { "type": "array", "items": { "type": "string" } }, "personality": { "type": "string" }, "goals": { "type": "array", "items": { "type": "string" } }, "tags": { "type": "array", "items": { "type": "string" } }, "disposition": { "$ref": "#/definitions/VirtualUserDisposition" }, "tuning": { "$ref": "#/definitions/VirtualUserTuning" }, "fixtures": { "type": "array", "items": { "type": "string" } }, "account": { "$ref": "#/definitions/PersonaAccountMeta" }, "linkedAccounts": { "type": "object", "additionalProperties": { "$ref": "#/definitions/PersonaAccountMeta" } }, "environments": { "type": "array", "items": { "type": "string" }, "description": "Absent means \"everywhere but production\", which is resolved, not stored." }, "runnable": { "type": "boolean" }, "app": { "type": "string", "description": "The app this person signs into; picks their base url on a browser run." }, "sourceFile": { "type": "string" } }, "required": ["email", "goals", "id", "name", "roles", "runnable", "tags"], "description": "A declared persona with its address filled in — what codegen writes and what a seed, a scenario run and a virtual-user run all read.\n\nThe address is not declared. It is derived from the persona's id and the project's persona domain, so two people can never accidentally share one and sign in as the same user row — which would silently collapse exactly the isolation scenarios a second person exists for." }, "VirtualUserDisposition": { "type": "string", "enum": ["realistic", "careless", "newcomer", "stale", "auditor", "adversarial", "accountable"], "description": "How a virtual user behaves, mechanically. A disposition changes the loop, the input generation, the memory and the oracle — anything that only changes how the user *talks* is persona prose (`ResolvedPersona.personality`) and does not belong here.\n\n- `realistic` — schema-first, goal-directed, plausible values (default).\n- `careless` — repeats, abandons, double-submits, boundary values.\n- `newcomer` — starts with empty memory and must discover everything.\n- `stale` — seeded from an earlier run's ids, some no longer valid.\n- `auditor` — pursues no goal; reads one truth from several places and compares.\n- `adversarial` — probes authorization and tenancy; a 2xx can be the finding.\n- `accountable` — pursues its goals for real; the only one production allows.\n\n`accountable` sits opposite `adversarial` on an *intent* axis — bad faith against good faith — where `careless` and `thorough` are a *care* axis. It is the one disposition whose actions carry consequences: no oracle, no rollback, and every call attributed to the persona in the audit log like anyone else's." }, "VirtualUserTuning": { "type": "object", "properties": { "moves": { "type": "object", "properties": { "continue": { "type": "number" }, "suspend": { "type": "number" }, "resume": { "type": "number" }, "abandon": { "type": "number" } }, "additionalProperties": false, "description": "Relative weights for the scheduler's moves. Merged over the profile's." }, "temperature": { "type": "number" }, "repeatRate": { "type": "number" }, "reReadRate": { "type": "number" }, "emptyMemory": { "type": "boolean" }, "readOnly": { "type": "boolean" }, "invertedOracle": { "type": "boolean" }, "instructions": { "type": "string", "description": "Extra behaviour, appended to the disposition's own instructions." } }, "additionalProperties": false, "description": "Per-user overrides for a disposition's dials.\n\nThe six profiles below are starting points, not laws — the weights are a considered guess about how people behave, and your product is allowed to know better. A user that declares `disposition: 'careless'` with a higher `repeatRate` is still a careless user; it is the same behaviour tuned to a product where double-submits actually happen.\n\n`instructions` is the one field that appends rather than replaces. Everything else is a number the engine reads, so overriding it changes the run and nothing else; instructions are the model's sense of who it is, and letting a declaration replace them wholesale is how you end up with a `careless` user that is not careless — which makes the name, and every run labelled with it, a lie." }, "PersonaAccountMeta": { "type": "object", "properties": { "provider": { "type": "string" } }, "additionalProperties": false }, "SystemRoleDefinitionsMeta": { "type": "object", "additionalProperties": { "$ref": "#/definitions/SystemRoleDefinitionMeta" } }, "SystemRoleDefinitionMeta": { "type": "object", "properties": { "name": { "type": "string" }, "displayName": { "type": "string" }, "description": { "type": "string" }, "scopes": { "type": "array", "items": { "type": "string" } }, "sourceFile": { "type": "string" } }, "required": ["name", "scopes"], "additionalProperties": false }, "FeaturesMeta": { "type": "object", "additionalProperties": { "$ref": "#/definitions/FeatureMeta" } }, "FeatureMeta": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "description": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "entries": { "type": "array", "items": { "$ref": "#/definitions/FeatureMetaEntry" } }, "unresolvedEntries": { "type": "number" }, "hasBefore": { "type": "boolean" }, "hasAfter": { "type": "boolean" } }, "required": ["id", "name", "tags", "entries", "unresolvedEntries", "hasBefore", "hasAfter"], "additionalProperties": false }, "FeatureMetaEntry": { "type": "object", "properties": { "scenario": { "type": "string" }, "data": {} }, "required": ["scenario"], "additionalProperties": false }, "TriggerMeta": { "type": "object", "properties": { "pikkuFuncId": { "type": "string" }, "name": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } } }, "required": ["pikkuFuncId", "name"], "additionalProperties": false }, "TriggerSourceMeta": { "type": "object", "properties": { "name": { "type": "string" }, "pikkuFuncId": { "type": "string" }, "packageName": { "type": "string" }, "summary": { "type": "string" }, "description": { "type": "string" } }, "required": ["name", "pikkuFuncId"], "additionalProperties": false }, "MiddlewareGroupsMeta": { "type": "object", "properties": { "definitions": { "type": "object", "additionalProperties": { "$ref": "#/definitions/MiddlewareDefinitionMeta" } }, "instances": { "type": "object", "additionalProperties": { "$ref": "#/definitions/MiddlewareInstanceMeta" } }, "httpGroups": { "type": "object", "additionalProperties": { "$ref": "#/definitions/GroupMeta" } }, "tagGroups": { "type": "object", "additionalProperties": { "$ref": "#/definitions/GroupMeta" } } }, "required": ["definitions", "instances", "httpGroups", "tagGroups"], "additionalProperties": false }, "MiddlewareDefinitionMeta": { "type": "object", "properties": { "services": { "type": "object", "properties": { "optimized": { "type": "boolean" }, "services": { "type": "array", "items": { "type": "string" } } }, "required": ["optimized", "services"], "additionalProperties": false }, "sourceFile": { "type": "string" }, "position": { "type": "number" }, "exportedName": { "type": ["string", "null"] }, "factory": { "type": "boolean" }, "name": { "type": "string" }, "description": { "type": "string" }, "package": { "type": "string" } }, "required": ["services", "sourceFile", "position", "exportedName"], "additionalProperties": false }, "MiddlewareInstanceMeta": { "type": "object", "properties": { "definitionId": { "type": "string" }, "sourceFile": { "type": "string" }, "position": { "type": "number" }, "isFactoryCall": { "type": "boolean" } }, "required": ["definitionId", "sourceFile", "position", "isFactoryCall"], "additionalProperties": false }, "GroupMeta": { "type": "object", "properties": { "exportName": { "type": ["string", "null"] }, "sourceFile": { "type": "string" }, "position": { "type": "number" }, "services": { "type": "object", "properties": { "optimized": { "type": "boolean" }, "services": { "type": "array", "items": { "type": "string" } } }, "required": ["optimized", "services"], "additionalProperties": false }, "count": { "type": "number" }, "instanceIds": { "type": "array", "items": { "type": "string" } }, "isFactory": { "type": "boolean" } }, "required": ["exportName", "sourceFile", "position", "services", "count", "instanceIds", "isFactory"], "additionalProperties": false }, "PermissionsGroupsMeta": { "type": "object", "properties": { "definitions": { "type": "object", "additionalProperties": { "$ref": "#/definitions/PermissionDefinitionMeta" } } }, "required": ["definitions"], "additionalProperties": false }, "PermissionDefinitionMeta": { "type": "object", "properties": { "services": { "type": "object", "properties": { "optimized": { "type": "boolean" }, "services": { "type": "array", "items": { "type": "string" } } }, "required": ["optimized", "services"], "additionalProperties": false }, "sourceFile": { "type": "string" }, "position": { "type": "number" }, "exportedName": { "type": ["string", "null"] }, "factory": { "type": "boolean" }, "name": { "type": "string" }, "description": { "type": "string" } }, "required": ["services", "sourceFile", "position", "exportedName"], "additionalProperties": false }, "AgentsMeta": { "type": "object", "additionalProperties": { "type": "object", "additionalProperties": false, "properties": { "tools": { "type": "array", "items": { "type": "string" } }, "agents": { "type": "array", "items": { "type": "string" } }, "workflows": { "type": "array", "items": { "type": "string" } }, "inputSchema": { "type": ["string", "null"] }, "outputSchema": { "type": ["string", "null"] }, "workingMemorySchema": { "type": ["string", "null"] }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "channelMiddleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "agentMiddleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } }, "sourceFile": { "type": "string" }, "exportedName": { "type": "string" }, "name": { "type": "string", "description": "Unique across the project. It is how the agent is invoked and how its runs are grouped." }, "description": { "type": "string", "description": "What the agent is for. Another agent choosing whether to delegate to this one reads it, so write it for that reader." }, "summary": { "type": "string", "description": "A one-line description for listings, where the full `description` is too long." }, "errors": { "type": "array", "items": { "type": "string" }, "description": "Names of error classes this may throw, so each one's registered status is used instead of a 500." }, "role": { "type": "string", "description": "Who the agent is. Joined with `personality` and `goal`, in that order, to form the system prompt." }, "personality": { "type": "string", "description": "How it should sound: tone, vocabulary, how much it says at a time." }, "goal": { "type": "string", "description": "What it is for — the only one of the three that is required." }, "model": { "type": "string", "description": "Which model to run on, as the provider names it." }, "temperature": { "type": "number", "description": "How much the model is allowed to vary its answer. Lower is more repeatable, which is what a tool-driving agent usually wants." }, "sessionScope": { "$ref": "#/definitions/SessionScope", "description": "Ownership/partitioning of this agent's threads and runs. Defaults to `'user'`." }, "scorers": { "type": "array", "items": { "type": "string" }, "description": "Grades finished runs on live traffic. A reference-based judge is never sampled here — live traffic has no answer key." }, "agentMode": { "type": "string", "enum": ["delegate", "supervise"], "description": "`delegate` hands a sub-agent the task and takes its answer; `supervise` keeps this agent in the loop over each step." }, "memory": { "$ref": "#/definitions/AgentMemoryConfig", "description": "What the agent carries between runs, and how much of it." }, "maxSteps": { "type": "number", "description": "How many model turns a single run may take before it is stopped. The guard against a tool loop that never converges." }, "toolChoice": { "type": "string", "enum": ["auto", "required", "none"], "description": "Whether the model may answer without calling a tool (`auto`), must call one (`required`), or may not (`none`)." }, "providerOptions": { "$ref": "#/definitions/AIProviderOptions", "description": "Per-provider settings passed through untouched, for what only one vendor offers." }, "tags": { "type": "array", "items": { "type": "string" }, "description": "Filters this agent in and out of a build — see the `tags` option on `pikku all`. It has no effect at runtime." }, "prepareStep": { "$comment": "(ctx: {\n stepNumber: number;\n messages: AgentMessage[];\n tools: AgentToolDef[];\n toolChoice: 'auto' | 'required' | 'none';\n model: string;\n stop: () => void;\n }) => void | Promise<void>", "type": "object", "properties": { "namedArgs": { "type": "object", "properties": { "ctx": { "type": "object", "properties": { "stepNumber": { "type": "number" }, "messages": { "type": "array", "items": { "$ref": "#/definitions/AgentMessage" } }, "tools": { "type": "array", "items": { "$ref": "#/definitions/AgentToolDef" } }, "toolChoice": { "type": "string", "enum": ["auto", "required", "none"] }, "model": { "type": "string" }, "stop": { "$comment": "() => void" } }, "required": ["stepNumber", "messages", "tools", "toolChoice", "model", "stop"], "additionalProperties": false } }, "required": ["ctx"], "additionalProperties": false } }, "description": "Runs before each model turn, to change what that turn sees or to stop the run. This is where a step budget or a tool narrowing goes." }, "auth": { "type": "boolean", "description": "Whether a session is required to run this agent. Defaults to `false`, since agents are commonly invoked from an already-authenticated `pikkuFunc` or from genuinely sessionless contexts (crons, queue workers). Set `true` to require a session at the agent itself. `scopes` and `permissions` are enforced either way." }, "scopes": { "type": "array", "items": { "type": "string" }, "description": "Scopes the session must hold to run this agent. All of them are required (AND), and they are checked before `permissions` — unlike permissions, which OR together, a scope can only narrow access.\n\nNarrowed to the generated `ScopeId` union in a project's own `#pikku/scopes`, so an undeclared scope is a compile error." } }, "required": ["description", "goal", "inputSchema", "model", "name", "outputSchema", "workingMemorySchema"] } }, "SessionScope": { "type": "string", "enum": ["user", "org"], "description": "How an agent's threads/runs are owned and partitioned.\n- `'user'` (default): owner is the authenticated `session.userId`; the caller's `resourceId` becomes a sub-partition within that user (`userId:resourceId`).\n- `'org'`: owner is the authenticated `session.orgId` (`orgId:resourceId`), so threads are shared across everyone in the org. Requires a session with an org (e.g. Better Auth's `organization` plugin) — otherwise access is denied.\n\nThe trusted principal is always the prefix, so a client-supplied `resourceId` can sub-divide within the caller's own boundary but can never widen access to another user's or org's threads." }, "AgentMemoryConfig": { "type": "object", "properties": { "storage": { "type": "string" }, "vector": { "type": "string" }, "embedder": { "type": "string" }, "lastMessages": { "type": "number" }, "workingMemory": {} }, "additionalProperties": false }, "AIProviderOptions": { "type": "object", "additionalProperties": { "type": "object", "additionalProperties": {} } }, "AgentMessage": { "type": "object", "properties": { "id": { "type": "string" }, "role": { "type": "string", "enum": ["system", "user", "assistant", "tool"] }, "content": { "anyOf": [{ "type": "string" }, { "type": "array", "items": { "$ref": "#/definitions/AgentContentPart" } }] }, "toolCalls": { "type": "array", "items": { "$ref": "#/definitions/AgentToolCall" } }, "toolResults": { "type": "array", "items": { "$ref": "#/definitions/AgentToolResult" } }, "reasoningContent": { "type": "string" }, "interrupted": { "type": "boolean", "description": "Set on an assistant message whose generation was cut short by an interrupt — the text is a mid-sentence fragment, not a reply. Carried into the next turn's context so the model can see it said only this much before being talked over, and decide for itself whether to resume, restate or move on. Storage that drops unknown fields loses the marker but keeps the fragment, which degrades to a truncated reply." }, "undelivered": { "type": "boolean", "description": "Set on a tool message whose result arrived after the run was interrupted, so the model never got to describe it. The work happened; only the reply about it was lost. It is ordinary thread context on the next turn — the model raises it unprompted (\"that deploy did go through\") rather than the result being silently dropped or replayed as a fresh tool call." }, "createdAt": { "type": "string", "format": "date-time" } }, "required": ["id", "role", "createdAt"], "additionalProperties": false }, "AgentContentPart": { "anyOf": [{ "type": "object", "properties": { "type": { "type": "string", "const": "text" }, "text": { "type": "string" } }, "required": ["type", "text"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "image" }, "data": { "type": "string" }, "url": { "type": "string" }, "mediaType": { "type": "string" } }, "required": ["type"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "file" }, "data": { "type": "string" }, "url": { "type": "string" }, "mediaType": { "type": "string" }, "filename": { "type": "string" } }, "required": ["type", "mediaType"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "data" }, "name": { "type": "string" }, "data": {} }, "required": ["type", "name", "data"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "generative-ui" }, "spec": {} }, "required": ["type", "spec"], "additionalProperties": false }] }, "AgentToolCall": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "args": { "type": "object", "additionalProperties": {} } }, "required": ["id", "name", "args"], "additionalProperties": false }, "AgentToolResult": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" }, "result": { "type": "string" }, "error": { "type": "string", "description": "Set when the tool threw rather than returned. Carried separately from `result`, which is a rendered string by the time it is persisted — a tool may legitimately return text beginning `Error:`, so the prefix cannot be read as a failure signal." } }, "required": ["id", "name", "result"], "additionalProperties": false }, "AgentToolDef": { "type": "object", "properties": { "needsApproval": { "type": "boolean" }, "approvalDescriptionFn": { "$comment": "(input: unknown) => Promise<string> | string", "type": "object", "properties": { "namedArgs": { "type": "object", "properties": { "input": {} }, "required": ["input"], "additionalProperties": false } } }, "name": { "type": "string" }, "description": { "type": "string" }, "inputSchema": { "type": "object", "additionalProperties": {} }, "execute": { "$comment": "(input: unknown) => Promise<unknown>", "type": "object", "properties": { "namedArgs": { "type": "object", "properties": { "input": {} }, "required": ["input"], "additionalProperties": false } } }, "readonly": { "type": "boolean", "description": "Mirrors the pikku function's `readonly` flag. A read that gets interrupted is discarded rather than reported: nothing changed, and by the next turn the data may be stale anyway — re-reading is cheaper than explaining a result the user never asked to hear about." }, "forwardsApproval": { "type": "boolean", "description": "Set only by the framework on sub-agent delegating tools. Such a tool may legitimately return an `__approvalRequired` marker to forward a nested sub-agent approval. The marker is honored ONLY from a tool with this flag — a plain tool's output (which an attacker may influence) can never forge an approval request. See `checkForApprovals`." } }, "required": ["name", "description", "inputSchema", "execute"], "additionalProperties": false, "description": "`ApprovalPolicy` is shared with channel capabilities, but `Partial` here: absent `needsApproval` means \"do not ask\", which is safe because a tool is written by whoever runs the server it executes on. A capability runs on someone else's machine, so it requires the field instead." }, "EmailsMeta": { "type": "object", "properties": { "src": { "type": "string" }, "themeHash": { "type": "string" }, "templates": { "type": "object", "additionalProperties": { "$ref": "#/definitions/EmailTemplateMeta" } } }, "required": ["src", "themeHash", "templates"], "additionalProperties": false }, "EmailTemplateMeta": { "type": "object", "properties": { "variables": { "type": "array", "items": { "type": "string" } }, "hasHtml": { "type": "boolean" }, "hasSubject": { "type": "boolean" }, "hasText": { "type": "boolean" }, "locales": { "type": "object", "additionalProperties": { "$ref": "#/definitions/EmailTemplateLocaleMeta" } } }, "required": ["variables", "hasHtml", "hasSubject", "hasText", "locales"], "additionalProperties": false }, "EmailTemplateLocaleMeta": { "type": "object", "properties": { "contentHash": { "type": "string" }, "htmlHash": { "type": "string" }, "subjectHash": { "type": "string" }, "textHash": { "type": "string" } }, "required": ["contentHash", "htmlHash", "subjectHash", "textHash"], "additionalProperties": false }, "FunctionUsedBy": { "type": "object", "properties": { "transports": { "type": "array", "items": { "$ref": "#/definitions/WiringRef" } }, "jobs": { "type": "array", "items": { "$ref": "#/definitions/WiringRef" } }, "workflows": { "type": "array", "items": { "type": "object", "properties": { "id": { "type": "string" }, "name": { "type": "string" } }, "required": ["id", "name"], "additionalProperties": false } } }, "required": ["transports", "jobs", "workflows"], "additionalProperties": false }, "WiringRef": { "type": "object", "properties": { "type": { "type": "string" }, "id": { "type": "string" }, "name": { "type": "string" } }, "required": ["type", "id", "name"], "additionalProperties": false }, "MetaCounts": { "type": "object", "properties": { "functions": { "type": "number" }, "workflows": { "type": "number" }, "httpRoutes": { "type": "number" }, "channels": { "type": "number" }, "mcpTools": { "type": "number" }, "gateways": { "type": "number" }, "schedulers": { "type": "number" }, "queues": { "type": "number" }, "cliCommands": { "type": "number" }, "rpcMethods": { "type": "number" }, "triggers": { "type": "number" }, "triggerSources": { "type": "number" }, "agents": { "type": "number" }, "emails": { "type": "number" }, "secrets": { "type": "number" }, "variables": { "type": "number" } }, "required": ["functions", "workflows", "httpRoutes", "channels", "mcpTools", "gateways", "schedulers", "queues", "cliCommands", "rpcMethods", "triggers", "triggerSources", "agents", "emails", "secrets", "variables"], "additionalProperties": false } } }
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "$ref": "#/definitions/FunctionMetaWithVersions" }, "definitions": { "FunctionMetaWithVersions": { "type": "object", "additionalProperties": false, "properties": { "version": { "type": "number" }, "versions": { "type": "array", "items": { "$ref": "#/definitions/FunctionVersionEntry" } }, "name": { "type": "string" }, "functionType": { "type": "string", "enum": ["user", "inline", "helper", "remote"], "description": "`remote`: a contract with no local body, answered by a connected client." }, "funcWrapper": { "type": "string" }, "services": { "$ref": "#/definitions/FunctionServicesMeta" }, "wires": { "$ref": "#/definitions/FunctionWiresMeta" }, "inputs": { "anyOf": [{ "type": "array", "items": { "type": "string" } }, { "type": "null" }] }, "outputs": { "anyOf": [{ "type": "array", "items": { "type": "string" } }, { "type": "null" }] }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } }, "isDirectFunction": { "type": "boolean" }, "sourceFile": { "type": "string" }, "exportedName": { "type": "string" }, "bodySourceFile": { "type": "string", "description": "File containing the handler body when it differs from sourceFile (imported handlers)" }, "bodyStart": { "type": "number", "description": "1-indexed first line of the handler body (verbose meta; coverage mapping)" }, "bodyEnd": { "type": "number", "description": "1-indexed last line of the handler body (verbose meta; coverage mapping)" }, "pikkuFuncId": { "type": "string" }, "packageName": { "type": "string" }, "title": { "type": "string" }, "tags": { "type": "array", "items": { "type": "string" } }, "summary": { "type": "string" }, "description": { "type": "string" }, "errors": { "type": "array", "items": { "type": "string" } }, "inputSchemaName": { "type": ["string", "null"] }, "outputSchemaName": { "type": ["string", "null"] }, "scopes": { "type": "array", "items": { "type": "string" }, "description": "Scopes the session must hold to run this function. All are required (AND)." }, "expose": { "type": "boolean" }, "auth": { "type": "boolean", "description": "A sessionless function's own `auth: true`. `sessionless` carries the baseline — a `pikkuFunc` always requires a session — and this carries the tightening a `pikkuSessionlessFunc` applies to itself. Both are needed to know whether a function is gated without running it." }, "permissionsInBody": { "type": "boolean", "description": "The author's declaration that this function's permission check lives in its own body. Carries no runtime effect — it records a gate codegen cannot see, so an audit is not left to guess whether a sessionless function is open. Refused unless `allow.permissionsInBody` is set in `pikku.config.json`." }, "remote": { "type": "boolean" }, "scenarioStep": { "type": "boolean", "description": "A step RPC: invoked by name only from a scenario run and refused everywhere else, so it is never network-callable." }, "scenario": { "type": "boolean", "description": "The body of a `pikkuScenario(...)`. Only ever run by `pikku scenario run`, so it is held back from the app bootstrap and from every deployed unit." }, "mcp": { "type": "boolean" }, "readonly": { "type": "boolean" }, "deploy": { "type": "string", "enum": ["serverless", "server", "auto"] }, "sessionless": { "type": "boolean" }, "workflowQueued": { "type": "boolean", "description": "When true, workflow steps calling this function are dispatched via the queue. No queue service configured is a hard error." }, "workflowRetries": { "type": "number", "description": "Retry count when this function is used as a workflow step." }, "workflowTimeout": { "type": "string", "description": "Timeout when this function is used as a workflow step (e.g. '30s', '5m')." }, "scenarioStepSurfaces": { "type": "array", "items": { "$ref": "#/definitions/ScenarioSurface" }, "description": "Scenario steps only: which surfaces this step declares a binding for.\n\nThe reporter derives coverage from this — a `then` with no binding for the surface the run targeted was never actually witnessed there, which is a gap worth counting rather than excusing." }, "scenarioStepRequiresActor": { "type": "boolean", "description": "Scenario steps only: this step runs as a persona, so every call site must pass one and the runner injects it as `wire.actor`.\n\nDeclared by `actor: true`, or implied by a `browser` binding — a window is opened as somebody. Absent on a step with nobody to be: an assertion over what an earlier step returned, or one posting credentials precisely because it must not reuse an actor's session." }, "scenarioStepKind": { "$ref": "#/definitions/ScenarioStepKind", "description": "Scenario steps only: who acts. Absent means `persona` — the ordinary step, and the only kind that existed before the other two.\n\nA `platform` or `addon` step is the app or a third-party system acting, and it must never reach a virtual user's catalogue. That is not tidiness: a virtual user that can invoke \"Stripe's webhook arrives\" can forge its own payment success, and every finding downstream of that is worthless." }, "scenarioStepAddon": { "type": "string", "description": "Addon steps only: the addon whose system acts — `wireAddon`'s `name`." }, "scenarioStepTemplate": { "type": "string", "description": "Scenario steps only: the prose a reporter renders, with `{placeholders}` filled from the step's recorded input." }, "audit": { "type": "object", "properties": { "durability": { "$ref": "#/definitions/AuditDurability" } }, "required": ["durability"], "additionalProperties": false, "description": "The function's `audit` config, resolved — `audit: true` reads as `{ durability: 'best-effort' }`. Absent means the function records nothing: `auditLog.write()` from an unmarked function is dropped with a warning, so this is the only place a reader can see which functions have a trail at all without running them.\n\nInformational. The runner resolves audit from the live function config, not from here, so meta and runtime cannot disagree about whether audit is on." }, "approvalRequired": { "type": "boolean" }, "approvalDescription": { "type": "string" }, "implementationHash": { "type": "string" }, "contractHash": { "type": "string" }, "inputHash": { "type": "string" }, "outputHash": { "type": "string" } }, "required": ["inputSchemaName", "outputSchemaName", "pikkuFuncId"] }, "FunctionVersionEntry": { "type": "object", "properties": { "version": { "type": "number" }, "inputHash": { "type": "string" }, "outputHash": { "type": "string" } }, "required": ["version", "inputHash", "outputHash"], "additionalProperties": false }, "FunctionServicesMeta": { "type": "object", "properties": { "optimized": { "type": "boolean" }, "services": { "type": "array", "items": { "type": "string" } } }, "required": ["optimized", "services"], "additionalProperties": false }, "FunctionWiresMeta": { "type": "object", "properties": { "optimized": { "type": "boolean" }, "wires": { "type": "array", "items": { "type": "string" } } }, "required": ["optimized", "wires"], "additionalProperties": false }, "MiddlewareMetadata": { "anyOf": [{ "type": "object", "properties": { "type": { "type": "string", "const": "http" }, "route": { "type": "string" } }, "required": ["type", "route"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "tag" }, "tag": { "type": "string" } }, "required": ["type", "tag"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "wire" }, "name": { "type": "string" }, "inline": { "type": "boolean" } }, "required": ["type", "name"], "additionalProperties": false }] }, "PermissionMetadata": { "type": "object", "properties": { "type": { "type": "string", "const": "wire" }, "name": { "type": "string" }, "inline": { "type": "boolean" } }, "required": ["type", "name"], "additionalProperties": false, "description": "A reference to a permission function, resolved by name. Function-scoped only: there are no wire- or tag-level permission references." }, "ScenarioSurface": { "type": "string", "enum": ["browser", "cli", "default"], "description": "How an actor drives the system for one step.\n\nA step declares one implementation per surface it supports, and the runner picks between them — so the same ladder can run through a real browser, over the websocket, or entirely server-side.\n\n`default` is the floor: it is what every other surface falls back to, so it can never itself fall back." }, "ScenarioStepKind": { "type": "string", "enum": ["persona", "platform", "addon"], "description": "Who acts in a step.\n\n`persona` is a person driving the system through one of its surfaces — the ordinary `pikkuScenarioStep`. `platform` is the app acting on itself (\"the platform has expired the trial\"), and `addon` is a third-party system acting on it (\"Stripe's webhook arrives\"), contributed by the addon that wraps that service.\n\nThe three are separate declarations rather than a field on one, so the inspector verifies a step's kind by which function was called rather than by trusting a string literal — and so an addon package exports only addon steps, which is checkable." }, "AuditDurability": { "type": "string", "enum": ["best-effort", "transactional"] } } }
|
|
1
|
+
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": { "$ref": "#/definitions/FunctionMetaWithVersions" }, "definitions": { "FunctionMetaWithVersions": { "type": "object", "additionalProperties": false, "properties": { "version": { "type": "number" }, "versions": { "type": "array", "items": { "$ref": "#/definitions/FunctionVersionEntry" } }, "name": { "type": "string" }, "functionType": { "type": "string", "enum": ["user", "inline", "helper", "remote"], "description": "`remote`: a contract with no local body, answered by a connected client." }, "funcWrapper": { "type": "string" }, "services": { "$ref": "#/definitions/FunctionServicesMeta" }, "wires": { "$ref": "#/definitions/FunctionWiresMeta" }, "inputs": { "anyOf": [{ "type": "array", "items": { "type": "string" } }, { "type": "null" }] }, "outputs": { "anyOf": [{ "type": "array", "items": { "type": "string" } }, { "type": "null" }] }, "middleware": { "type": "array", "items": { "$ref": "#/definitions/MiddlewareMetadata" } }, "permissions": { "type": "array", "items": { "$ref": "#/definitions/PermissionMetadata" } }, "isDirectFunction": { "type": "boolean" }, "sourceFile": { "type": "string" }, "exportedName": { "type": "string" }, "bodySourceFile": { "type": "string", "description": "File containing the handler body when it differs from sourceFile (imported handlers)" }, "bodyStart": { "type": "number", "description": "1-indexed first line of the handler body (verbose meta; coverage mapping)" }, "bodyEnd": { "type": "number", "description": "1-indexed last line of the handler body (verbose meta; coverage mapping)" }, "pikkuFuncId": { "type": "string" }, "packageName": { "type": "string" }, "title": { "type": "string", "description": "A human name for this wiring, shown wherever it is listed rather than called." }, "tags": { "type": "array", "items": { "type": "string" }, "description": "Filters this wiring in and out of a build — see the `tags` option on `pikku all`. It has no effect at runtime." }, "summary": { "type": "string", "description": "A one-line description for listings, where the full `description` is too long." }, "description": { "type": "string", "description": "What this does, for whoever is reading the wiring rather than writing it." }, "errors": { "type": "array", "items": { "type": "string" }, "description": "Names of error classes this may throw, so each one's registered status is used instead of a 500." }, "inputSchemaName": { "type": ["string", "null"] }, "outputSchemaName": { "type": ["string", "null"] }, "scopes": { "type": "array", "items": { "type": "string" }, "description": "Scopes the session must hold to run this function. All are required (AND)." }, "expose": { "type": "boolean" }, "auth": { "type": "boolean", "description": "A sessionless function's own `auth: true`. `sessionless` carries the baseline — a `pikkuFunc` always requires a session — and this carries the tightening a `pikkuSessionlessFunc` applies to itself. Both are needed to know whether a function is gated without running it." }, "permissionsInBody": { "type": "boolean", "description": "The author's declaration that this function's permission check lives in its own body. Carries no runtime effect — it records a gate codegen cannot see, so an audit is not left to guess whether a sessionless function is open. Refused unless `allow.permissionsInBody` is set in `pikku.config.json`." }, "remote": { "type": "boolean" }, "scenarioStep": { "type": "boolean", "description": "A step RPC: invoked by name only from a scenario run and refused everywhere else, so it is never network-callable." }, "scenario": { "type": "boolean", "description": "The body of a `pikkuScenario(...)`. Only ever run by `pikku scenario run`, so it is held back from the app bootstrap and from every deployed unit." }, "mcp": { "type": "boolean" }, "readonly": { "type": "boolean" }, "deploy": { "type": "string", "enum": ["serverless", "server", "auto"] }, "sessionless": { "type": "boolean" }, "workflowQueued": { "type": "boolean", "description": "When true, workflow steps calling this function are dispatched via the queue. No queue service configured is a hard error." }, "workflowRetries": { "type": "number", "description": "Retry count when this function is used as a workflow step." }, "workflowTimeout": { "type": "string", "description": "Timeout when this function is used as a workflow step (e.g. '30s', '5m')." }, "scenarioStepSurfaces": { "type": "array", "items": { "$ref": "#/definitions/ScenarioSurface" }, "description": "Scenario steps only: which surfaces this step declares a binding for.\n\nThe reporter derives coverage from this — a `then` with no binding for the surface the run targeted was never actually witnessed there, which is a gap worth counting rather than excusing." }, "scenarioStepRequiresActor": { "type": "boolean", "description": "Scenario steps only: this step runs as a persona, so every call site must pass one and the runner injects it as `wire.actor`.\n\nDeclared by `actor: true`, or implied by a `browser` binding — a window is opened as somebody. Absent on a step with nobody to be: an assertion over what an earlier step returned, or one posting credentials precisely because it must not reuse an actor's session." }, "scenarioStepKind": { "$ref": "#/definitions/ScenarioStepKind", "description": "Scenario steps only: who acts. Absent means `persona` — the ordinary step, and the only kind that existed before the other two.\n\nA `platform` or `addon` step is the app or a third-party system acting, and it must never reach a virtual user's catalogue. That is not tidiness: a virtual user that can invoke \"Stripe's webhook arrives\" can forge its own payment success, and every finding downstream of that is worthless." }, "scenarioStepAddon": { "type": "string", "description": "Addon steps only: the addon whose system acts — `wireAddon`'s `name`." }, "scenarioStepTemplate": { "type": "string", "description": "Scenario steps only: the prose a reporter renders, with `{placeholders}` filled from the step's recorded input." }, "audit": { "type": "object", "properties": { "durability": { "$ref": "#/definitions/AuditDurability" } }, "required": ["durability"], "additionalProperties": false, "description": "The function's `audit` config, resolved — `audit: true` reads as `{ durability: 'best-effort' }`. Absent means the function records nothing: `auditLog.write()` from an unmarked function is dropped with a warning, so this is the only place a reader can see which functions have a trail at all without running them.\n\nInformational. The runner resolves audit from the live function config, not from here, so meta and runtime cannot disagree about whether audit is on." }, "approvalRequired": { "type": "boolean" }, "approvalDescription": { "type": "string" }, "implementationHash": { "type": "string" }, "contractHash": { "type": "string" }, "inputHash": { "type": "string" }, "outputHash": { "type": "string" } }, "required": ["inputSchemaName", "outputSchemaName", "pikkuFuncId"] }, "FunctionVersionEntry": { "type": "object", "properties": { "version": { "type": "number" }, "inputHash": { "type": "string" }, "outputHash": { "type": "string" } }, "required": ["version", "inputHash", "outputHash"], "additionalProperties": false }, "FunctionServicesMeta": { "type": "object", "properties": { "optimized": { "type": "boolean" }, "services": { "type": "array", "items": { "type": "string" } } }, "required": ["optimized", "services"], "additionalProperties": false }, "FunctionWiresMeta": { "type": "object", "properties": { "optimized": { "type": "boolean" }, "wires": { "type": "array", "items": { "type": "string" } } }, "required": ["optimized", "wires"], "additionalProperties": false }, "MiddlewareMetadata": { "anyOf": [{ "type": "object", "properties": { "type": { "type": "string", "const": "http" }, "route": { "type": "string" } }, "required": ["type", "route"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "tag" }, "tag": { "type": "string" } }, "required": ["type", "tag"], "additionalProperties": false }, { "type": "object", "properties": { "type": { "type": "string", "const": "wire" }, "name": { "type": "string" }, "inline": { "type": "boolean" } }, "required": ["type", "name"], "additionalProperties": false }] }, "PermissionMetadata": { "type": "object", "properties": { "type": { "type": "string", "const": "wire" }, "name": { "type": "string" }, "inline": { "type": "boolean" } }, "required": ["type", "name"], "additionalProperties": false, "description": "A reference to a permission function, resolved by name. Function-scoped only: there are no wire- or tag-level permission references." }, "ScenarioSurface": { "type": "string", "enum": ["browser", "cli", "default"], "description": "How an actor drives the system for one step.\n\nA step declares one implementation per surface it supports, and the runner picks between them — so the same ladder can run through a real browser, over the websocket, or entirely server-side.\n\n`default` is the floor: it is what every other surface falls back to, so it can never itself fall back." }, "ScenarioStepKind": { "type": "string", "enum": ["persona", "platform", "addon"], "description": "Who acts in a step.\n\n`persona` is a person driving the system through one of its surfaces — the ordinary `pikkuScenarioStep`. `platform` is the app acting on itself (\"the platform has expired the trial\"), and `addon` is a third-party system acting on it (\"Stripe's webhook arrives\"), contributed by the addon that wraps that service.\n\nThe three are separate declarations rather than a field on one, so the inspector verifies a step's kind by which function was called rather than by trusting a string literal — and so an addon package exports only addon steps, which is checkable." }, "AuditDurability": { "type": "string", "enum": ["best-effort", "transactional"] } } }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "runId": { "type": "string" }, "limit": { "type": "number" }, "offset": { "type": "number" } }, "required": ["runId"], "additionalProperties": false, "definitions": {} }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": {}, "definitions": {} }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "object", "properties": { "persona": { "type": "string" }, "limit": { "type": "number" }, "offset": { "type": "number" } }, "additionalProperties": false, "definitions": {} }
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "$schema": "http://json-schema.org/draft-07/schema#", "type": "array", "items": {}, "definitions": {} }
|