@pikku/core 0.12.71 → 0.12.74
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 +848 -0
- package/dist/crypto-utils.d.ts +30 -5
- package/dist/crypto-utils.js +146 -41
- package/dist/dev/hot-reload.js +11 -30
- package/dist/dev/module-runner.d.ts +3 -7
- package/dist/dev/module-runner.js +4 -10
- package/dist/dev/reload-meta.d.ts +8 -20
- package/dist/dev/reload-meta.js +9 -29
- package/dist/errors/error-handler.d.ts +5 -30
- package/dist/errors/error-handler.js +16 -32
- package/dist/errors/errors.d.ts +32 -151
- package/dist/errors/errors.js +55 -157
- package/dist/function/abort-scope.d.ts +47 -0
- package/dist/function/abort-scope.js +63 -0
- package/dist/function/function-runner.js +40 -30
- package/dist/function/functions.types.d.ts +44 -136
- package/dist/function/functions.types.js +0 -58
- package/dist/function/list.types.d.ts +12 -62
- package/dist/function/list.types.js +4 -25
- package/dist/handle-error.d.ts +0 -11
- package/dist/handle-error.js +6 -18
- package/dist/index.d.ts +5 -2
- package/dist/index.js +4 -1
- package/dist/middleware/auth-apikey.d.ts +3 -18
- package/dist/middleware/auth-apikey.js +0 -17
- package/dist/middleware/auth-bearer.d.ts +6 -41
- package/dist/middleware/auth-bearer.js +3 -40
- package/dist/middleware/auth-cookie.d.ts +5 -27
- package/dist/middleware/auth-cookie.js +2 -26
- package/dist/middleware/cors.d.ts +7 -34
- package/dist/middleware/cors.js +7 -34
- package/dist/middleware/remote-auth.d.ts +3 -1
- package/dist/middleware/remote-auth.js +3 -2
- package/dist/middleware/telemetry.d.ts +8 -33
- package/dist/middleware/telemetry.js +2 -31
- package/dist/middleware-runner.d.ts +4 -55
- package/dist/middleware-runner.js +5 -74
- package/dist/permissions.d.ts +3 -44
- package/dist/permissions.js +19 -71
- package/dist/pikku-request.d.ts +0 -6
- package/dist/pikku-request.js +0 -6
- package/dist/pikku-state.d.ts +0 -26
- package/dist/pikku-state.js +2 -30
- package/dist/remote.d.ts +3 -5
- package/dist/remote.js +8 -7
- package/dist/schema.d.ts +7 -17
- package/dist/schema.js +30 -18
- package/dist/scopes.d.ts +4 -23
- package/dist/scopes.js +7 -48
- package/dist/services/ai-agent-runner-service.d.ts +20 -0
- package/dist/services/ai-embedding-service.d.ts +2 -25
- package/dist/services/audit-service.js +1 -2
- package/dist/services/content-service.d.ts +1 -46
- package/dist/services/credential-service.d.ts +3 -40
- package/dist/services/deployment-service.d.ts +3 -9
- package/dist/services/gateway-service.d.ts +0 -15
- package/dist/services/http-personas.d.ts +80 -0
- package/dist/services/http-personas.js +233 -0
- package/dist/services/in-memory-queue-service.d.ts +0 -14
- package/dist/services/in-memory-queue-service.js +1 -15
- package/dist/services/in-memory-trigger-service.d.ts +0 -18
- package/dist/services/in-memory-trigger-service.js +1 -18
- package/dist/services/in-memory-workflow-service.d.ts +0 -16
- package/dist/services/in-memory-workflow-service.js +4 -33
- package/dist/services/index.d.ts +5 -6
- package/dist/services/index.js +2 -5
- package/dist/services/istanbul-coverage-service.d.ts +1 -5
- package/dist/services/istanbul-coverage-service.js +2 -8
- package/dist/services/jwt-service.d.ts +1 -16
- package/dist/services/local-content.d.ts +13 -2
- package/dist/services/local-content.js +40 -13
- package/dist/services/local-gateway-service.d.ts +0 -16
- package/dist/services/local-gateway-service.js +2 -17
- package/dist/services/local-secrets.d.ts +0 -4
- package/dist/services/local-secrets.js +0 -4
- package/dist/services/logger-console.d.ts +3 -7
- package/dist/services/logger-console.js +3 -7
- package/dist/services/logger.d.ts +2 -37
- package/dist/services/meta-service.d.ts +23 -26
- package/dist/services/meta-service.js +22 -36
- package/dist/services/personas-service.d.ts +134 -0
- package/dist/services/personas-service.js +40 -0
- package/dist/services/pikku-user-id.js +0 -4
- package/dist/services/queue-webhook-service.d.ts +2 -36
- package/dist/services/queue-webhook-service.js +9 -41
- package/dist/services/scheduler-service.d.ts +1 -50
- package/dist/services/scheduler-service.js +0 -10
- package/dist/services/schema-service.d.ts +1 -24
- package/dist/services/scope-service.d.ts +49 -34
- package/dist/services/scoped-secret-service.d.ts +0 -4
- package/dist/services/scoped-secret-service.js +0 -4
- package/dist/services/secret-host-binding.d.ts +8 -0
- package/dist/services/secret-host-binding.js +36 -0
- package/dist/services/secret-service.d.ts +5 -33
- package/dist/services/secretless.d.ts +6 -0
- package/dist/services/secretless.js +21 -0
- package/dist/services/stub-tracker.d.ts +7 -18
- package/dist/services/stub-tracker.js +8 -18
- package/dist/services/system-role-guard.d.ts +33 -0
- package/dist/services/system-role-guard.js +38 -0
- package/dist/services/trigger-service.d.ts +0 -12
- package/dist/services/typed-secret-service.d.ts +0 -7
- package/dist/services/typed-secret-service.js +1 -7
- package/dist/services/v8-coverage-service.d.ts +2 -3
- package/dist/services/v8-coverage-service.js +1 -2
- package/dist/services/variables-service.d.ts +1 -8
- package/dist/services/webhook-service.d.ts +19 -63
- package/dist/services/webhook-service.js +6 -20
- package/dist/services/workflow-service.d.ts +3 -15
- package/dist/testing/service-tests.js +0 -17
- package/dist/time-utils.d.ts +0 -16
- package/dist/time-utils.js +1 -19
- package/dist/types/core.types.d.ts +99 -219
- package/dist/types/core.types.js +0 -42
- package/dist/types/state.types.d.ts +4 -9
- package/dist/utils/hmac.d.ts +4 -10
- package/dist/utils/hmac.js +4 -10
- package/dist/utils/safe-fetch.d.ts +7 -35
- package/dist/utils/safe-fetch.js +13 -53
- package/dist/utils.d.ts +1 -6
- package/dist/utils.js +6 -15
- package/dist/wirings/actor-flow/actor-flow.types.d.ts +1 -34
- package/dist/wirings/actor-flow/index.d.ts +0 -9
- package/dist/wirings/actor-flow/run-conversation.d.ts +5 -5
- package/dist/wirings/actor-flow/run-conversation.js +14 -7
- package/dist/wirings/ai-agent/ai-agent-agui.d.ts +0 -5
- package/dist/wirings/ai-agent/ai-agent-agui.js +34 -12
- package/dist/wirings/ai-agent/ai-agent-helpers.d.ts +7 -0
- package/dist/wirings/ai-agent/ai-agent-helpers.js +7 -0
- package/dist/wirings/ai-agent/ai-agent-interrupt.d.ts +153 -0
- package/dist/wirings/ai-agent/ai-agent-interrupt.js +256 -0
- package/dist/wirings/ai-agent/ai-agent-memory.js +0 -2
- package/dist/wirings/ai-agent/ai-agent-model-config.d.ts +0 -9
- package/dist/wirings/ai-agent/ai-agent-model-config.js +1 -9
- package/dist/wirings/ai-agent/ai-agent-prepare.d.ts +10 -99
- package/dist/wirings/ai-agent/ai-agent-prepare.js +58 -131
- package/dist/wirings/ai-agent/ai-agent-registry.d.ts +2 -1
- package/dist/wirings/ai-agent/ai-agent-registry.js +5 -1
- package/dist/wirings/ai-agent/ai-agent-runner.js +49 -20
- package/dist/wirings/ai-agent/ai-agent-stream.d.ts +25 -2
- package/dist/wirings/ai-agent/ai-agent-stream.js +153 -63
- package/dist/wirings/ai-agent/ai-agent.types.d.ts +84 -4
- package/dist/wirings/ai-agent/index.d.ts +6 -4
- package/dist/wirings/ai-agent/index.js +5 -4
- package/dist/wirings/ai-agent/voice-input.d.ts +39 -1
- package/dist/wirings/ai-agent/voice-input.js +46 -3
- package/dist/wirings/ai-agent/voice-output.d.ts +54 -1
- package/dist/wirings/ai-agent/voice-output.js +153 -50
- package/dist/wirings/channel/channel-common.d.ts +7 -20
- package/dist/wirings/channel/channel-common.js +7 -21
- package/dist/wirings/channel/channel-handler.js +25 -6
- package/dist/wirings/channel/channel-host-rpc.d.ts +25 -0
- package/dist/wirings/channel/channel-host-rpc.js +38 -0
- package/dist/wirings/channel/channel-middleware-runner.d.ts +0 -12
- package/dist/wirings/channel/channel-middleware-runner.js +0 -12
- package/dist/wirings/channel/channel-rpc-registry.d.ts +31 -0
- package/dist/wirings/channel/channel-rpc-registry.js +89 -0
- package/dist/wirings/channel/channel-rpc-responder.d.ts +15 -0
- package/dist/wirings/channel/channel-rpc-responder.js +71 -0
- package/dist/wirings/channel/channel-rpc-service.d.ts +40 -0
- package/dist/wirings/channel/channel-rpc-service.js +106 -0
- package/dist/wirings/channel/channel-rpc-validators.d.ts +14 -0
- package/dist/wirings/channel/channel-rpc-validators.js +30 -0
- package/dist/wirings/channel/channel-rpc.d.ts +5 -0
- package/dist/wirings/channel/channel-rpc.js +5 -0
- package/dist/wirings/channel/channel-rpc.types.d.ts +90 -0
- package/dist/wirings/channel/channel-rpc.types.js +50 -0
- package/dist/wirings/channel/channel-runner.d.ts +0 -4
- package/dist/wirings/channel/channel-runner.js +0 -14
- package/dist/wirings/channel/channel-store.d.ts +0 -10
- package/dist/wirings/channel/channel.types.d.ts +12 -1
- package/dist/wirings/channel/define-channel-routes.d.ts +0 -20
- package/dist/wirings/channel/define-channel-routes.js +0 -20
- package/dist/wirings/channel/eventhub-service.d.ts +0 -18
- package/dist/wirings/channel/index.d.ts +4 -1
- package/dist/wirings/channel/index.js +2 -0
- package/dist/wirings/channel/local/local-channel-runner.js +3 -1
- package/dist/wirings/channel/local/local-eventhub-service.d.ts +0 -33
- package/dist/wirings/channel/local/local-eventhub-service.js +2 -36
- package/dist/wirings/channel/log-channels.d.ts +0 -4
- package/dist/wirings/channel/log-channels.js +0 -4
- package/dist/wirings/channel/pikku-abstract-channel-handler.js +6 -0
- package/dist/wirings/channel/serverless/serverless-channel-runner.js +2 -5
- package/dist/wirings/cli/channel/cli-approval.d.ts +41 -0
- package/dist/wirings/cli/channel/cli-approval.js +81 -0
- package/dist/wirings/cli/channel/cli-channel-runner.d.ts +0 -4
- package/dist/wirings/cli/channel/cli-channel-runner.js +3 -25
- package/dist/wirings/cli/channel/cli-raw-channel-runner.d.ts +47 -9
- package/dist/wirings/cli/channel/cli-raw-channel-runner.js +24 -16
- package/dist/wirings/cli/channel/cli-raw-client-runner.d.ts +20 -0
- package/dist/wirings/cli/channel/cli-raw-client-runner.js +121 -0
- package/dist/wirings/cli/channel/index.d.ts +4 -0
- package/dist/wirings/cli/channel/index.js +2 -0
- package/dist/wirings/cli/cli-runner.d.ts +20 -20
- package/dist/wirings/cli/cli-runner.js +28 -89
- package/dist/wirings/cli/cli.types.d.ts +14 -3
- package/dist/wirings/cli/command-parser.d.ts +1 -10
- package/dist/wirings/cli/command-parser.js +10 -87
- package/dist/wirings/cli/define-cli-commands.d.ts +1 -17
- package/dist/wirings/cli/define-cli-commands.js +1 -17
- package/dist/wirings/credential/credential.types.d.ts +0 -12
- package/dist/wirings/credential/define-credential.d.ts +48 -0
- package/dist/wirings/credential/define-credential.js +47 -0
- package/dist/wirings/credential/index.d.ts +1 -1
- package/dist/wirings/credential/index.js +1 -1
- package/dist/wirings/credential/validate-credential-definitions.d.ts +2 -4
- package/dist/wirings/gateway/gateway-runner.d.ts +1 -20
- package/dist/wirings/gateway/gateway-runner.js +8 -105
- package/dist/wirings/gateway/gateway.types.d.ts +7 -80
- package/dist/wirings/http/http-routes.d.ts +0 -63
- package/dist/wirings/http/http-routes.js +0 -63
- package/dist/wirings/http/http-runner.d.ts +1 -100
- package/dist/wirings/http/http-runner.js +12 -166
- package/dist/wirings/http/http.types.d.ts +16 -55
- package/dist/wirings/http/index.d.ts +2 -1
- package/dist/wirings/http/index.js +1 -1
- package/dist/wirings/http/log-http-routes.d.ts +0 -4
- package/dist/wirings/http/log-http-routes.js +0 -4
- package/dist/wirings/http/pikku-fetch-http-request.d.ts +6 -36
- package/dist/wirings/http/pikku-fetch-http-request.js +56 -50
- package/dist/wirings/http/pikku-fetch-http-response.js +0 -3
- package/dist/wirings/http/routers/path-to-regex.js +2 -13
- package/dist/wirings/http/web-request.d.ts +0 -8
- package/dist/wirings/http/web-request.js +25 -17
- package/dist/wirings/mcp/mcp-runner.d.ts +2 -0
- package/dist/wirings/mcp/mcp-runner.js +6 -16
- package/dist/wirings/mcp/mcp.types.d.ts +2 -35
- package/dist/wirings/oauth2/oauth2.types.d.ts +0 -28
- package/dist/wirings/oauth2/oauth2.types.js +0 -3
- package/dist/wirings/persona/define-personas.d.ts +28 -0
- package/dist/wirings/persona/define-personas.js +27 -0
- package/dist/wirings/persona/index.d.ts +21 -0
- package/dist/wirings/persona/index.js +17 -0
- package/dist/wirings/persona/persona-email.d.ts +37 -0
- package/dist/wirings/persona/persona-email.js +69 -0
- package/dist/wirings/persona/persona-environments.d.ts +45 -0
- package/dist/wirings/persona/persona-environments.js +81 -0
- package/dist/wirings/persona/persona-mailbox.d.ts +101 -0
- package/dist/wirings/persona/persona-mailbox.js +53 -0
- package/dist/wirings/persona/persona.types.d.ts +125 -0
- package/dist/wirings/persona/persona.types.js +1 -0
- package/dist/wirings/persona/validate-personas.d.ts +53 -0
- package/dist/wirings/persona/validate-personas.js +94 -0
- package/dist/wirings/queue/index.d.ts +3 -0
- package/dist/wirings/queue/index.js +2 -3
- package/dist/wirings/queue/queue-identity.d.ts +28 -0
- package/dist/wirings/queue/queue-identity.js +102 -0
- package/dist/wirings/queue/queue-runner.d.ts +0 -19
- package/dist/wirings/queue/queue-runner.js +9 -30
- package/dist/wirings/queue/queue.types.d.ts +18 -89
- package/dist/wirings/queue/register-queue-helper.d.ts +0 -12
- package/dist/wirings/queue/register-queue-helper.js +0 -11
- package/dist/wirings/queue/signed-queue-service.d.ts +16 -0
- package/dist/wirings/queue/signed-queue-service.js +42 -0
- package/dist/wirings/queue/validate-worker-config.d.ts +2 -23
- package/dist/wirings/queue/validate-worker-config.js +0 -14
- package/dist/wirings/role/define-system-role.d.ts +32 -0
- package/dist/wirings/role/define-system-role.js +31 -0
- package/dist/wirings/role/index.d.ts +3 -0
- package/dist/wirings/role/index.js +2 -0
- package/dist/wirings/role/role.types.d.ts +43 -0
- package/dist/wirings/role/role.types.js +1 -0
- package/dist/wirings/role/validate-role-definitions.d.ts +21 -0
- package/dist/wirings/role/validate-role-definitions.js +71 -0
- package/dist/wirings/rpc/addon-runner.d.ts +0 -19
- package/dist/wirings/rpc/addon-runner.js +0 -51
- package/dist/wirings/rpc/remote-addon-auth.d.ts +1 -12
- package/dist/wirings/rpc/remote-addon-auth.js +1 -9
- package/dist/wirings/rpc/rpc-runner.d.ts +11 -18
- package/dist/wirings/rpc/rpc-runner.js +88 -105
- package/dist/wirings/rpc/rpc-types.d.ts +7 -6
- package/dist/wirings/rpc/wire-addon.d.ts +25 -0
- package/dist/wirings/rpc/wire-addon.js +62 -0
- package/dist/wirings/rpc/wire-remote-addon.d.ts +3 -28
- package/dist/wirings/rpc/wire-remote-addon.js +0 -8
- package/dist/wirings/scheduler/log-schedulers.d.ts +0 -4
- package/dist/wirings/scheduler/log-schedulers.js +0 -4
- package/dist/wirings/scheduler/scheduler-runner.d.ts +0 -1
- package/dist/wirings/scheduler/scheduler-runner.js +0 -1
- package/dist/wirings/scheduler/scheduler.types.d.ts +1 -14
- package/dist/wirings/scope/define-scope.d.ts +32 -0
- package/dist/wirings/scope/define-scope.js +31 -0
- package/dist/wirings/scope/index.d.ts +1 -1
- package/dist/wirings/scope/index.js +1 -1
- package/dist/wirings/scope/scope.types.d.ts +7 -9
- package/dist/wirings/scope/validate-scope-definitions.d.ts +2 -21
- package/dist/wirings/scope/validate-scope-definitions.js +3 -21
- package/dist/wirings/secret/index.d.ts +1 -1
- package/dist/wirings/secret/index.js +1 -1
- package/dist/wirings/secret/secret.types.d.ts +19 -15
- package/dist/wirings/secret/secret.types.js +1 -1
- package/dist/wirings/secret/validate-secret-definitions.d.ts +2 -4
- package/dist/wirings/trigger/trigger-runner.d.ts +0 -27
- package/dist/wirings/trigger/trigger-runner.js +1 -24
- package/dist/wirings/trigger/trigger.types.d.ts +1 -82
- package/dist/wirings/trigger/trigger.types.js +0 -34
- package/dist/wirings/variable/index.d.ts +1 -1
- package/dist/wirings/variable/index.js +1 -1
- package/dist/wirings/variable/validate-variable-definitions.d.ts +2 -4
- package/dist/wirings/variable/variable.types.d.ts +1 -13
- package/dist/wirings/variable/variable.types.js +1 -1
- package/dist/wirings/virtual-user/index.d.ts +27 -0
- package/dist/wirings/virtual-user/index.js +8 -0
- package/dist/wirings/virtual-user/run-virtual-user.d.ts +92 -0
- package/dist/wirings/virtual-user/run-virtual-user.js +478 -0
- package/dist/wirings/virtual-user/virtual-user-agents.d.ts +38 -0
- package/dist/wirings/virtual-user/virtual-user-agents.js +24 -0
- package/dist/wirings/virtual-user/virtual-user-catalogue.d.ts +92 -0
- package/dist/wirings/virtual-user/virtual-user-catalogue.js +134 -0
- package/dist/wirings/virtual-user/virtual-user-derive.d.ts +26 -0
- package/dist/wirings/virtual-user/virtual-user-derive.js +137 -0
- package/dist/wirings/virtual-user/virtual-user-dispositions.d.ts +79 -0
- package/dist/wirings/virtual-user/virtual-user-dispositions.js +128 -0
- package/dist/wirings/virtual-user/virtual-user-intents.d.ts +78 -0
- package/dist/wirings/virtual-user/virtual-user-intents.js +142 -0
- package/dist/wirings/virtual-user/virtual-user-rng.d.ts +24 -0
- package/dist/wirings/virtual-user/virtual-user-rng.js +44 -0
- package/dist/wirings/virtual-user/virtual-user-target.d.ts +21 -0
- package/dist/wirings/virtual-user/virtual-user-target.js +34 -0
- package/dist/wirings/virtual-user/virtual-user.types.d.ts +199 -0
- package/dist/wirings/virtual-user/virtual-user.types.js +8 -0
- package/dist/wirings/workflow/dsl/workflow-dsl.types.d.ts +5 -5
- package/dist/wirings/workflow/dsl/workflow-runner.d.ts +0 -4
- package/dist/wirings/workflow/dsl/workflow-runner.js +0 -4
- package/dist/wirings/workflow/feature.d.ts +0 -19
- package/dist/wirings/workflow/feature.js +0 -19
- package/dist/wirings/workflow/graph/graph-node.d.ts +0 -98
- package/dist/wirings/workflow/graph/graph-node.js +0 -34
- package/dist/wirings/workflow/graph/graph-runner.js +6 -41
- package/dist/wirings/workflow/graph/wire-workflow-graph.d.ts +0 -4
- package/dist/wirings/workflow/graph/workflow-graph.types.d.ts +0 -58
- package/dist/wirings/workflow/graph/workflow-graph.types.js +0 -6
- package/dist/wirings/workflow/index.d.ts +5 -7
- package/dist/wirings/workflow/index.js +3 -17
- package/dist/wirings/workflow/pikku-scenario-service.d.ts +87 -5
- package/dist/wirings/workflow/pikku-scenario-service.js +204 -42
- package/dist/wirings/workflow/pikku-workflow-service.d.ts +7 -459
- package/dist/wirings/workflow/pikku-workflow-service.js +58 -551
- package/dist/wirings/workflow/run-timeline.d.ts +0 -47
- package/dist/wirings/workflow/run-timeline.js +0 -22
- package/dist/wirings/workflow/scenario-cookie-jar.d.ts +0 -23
- package/dist/wirings/workflow/scenario-cookie-jar.js +0 -16
- package/dist/wirings/workflow/scenario-poll.d.ts +0 -15
- package/dist/wirings/workflow/scenario-poll.js +0 -12
- package/dist/wirings/workflow/scenario-prose.d.ts +0 -28
- package/dist/wirings/workflow/scenario-prose.js +0 -18
- package/dist/wirings/workflow/scenario-step-guards.d.ts +0 -13
- package/dist/wirings/workflow/scenario-step-guards.js +1 -14
- package/dist/wirings/workflow/scenario-step.types.d.ts +72 -6
- package/dist/wirings/workflow/scenario-step.types.js +5 -1
- package/dist/wirings/workflow/scenario-surface.d.ts +16 -0
- package/dist/wirings/workflow/scenario-surface.js +56 -0
- package/dist/wirings/workflow/workflow-invocation-id.d.ts +0 -18
- package/dist/wirings/workflow/workflow-invocation-id.js +2 -22
- package/dist/wirings/workflow/workflow-queue-workers.d.ts +0 -20
- package/dist/wirings/workflow/workflow-queue-workers.js +0 -19
- package/dist/wirings/workflow/workflow.types.d.ts +0 -197
- package/knowledge/decisions/index.md +19 -0
- package/knowledge/decisions/internals/a-secret-that-fails-to-decrypt-fails-the-whole-read.md +49 -0
- package/knowledge/decisions/internals/actor-flow-conversations-seed-a-hidden-kickoff-message.md +23 -0
- package/knowledge/decisions/internals/actor-flow-drives-the-target-through-a-transport-seam.md +24 -0
- package/knowledge/decisions/internals/actor-flow-verdicts-are-llm-self-evaluations.md +25 -0
- package/knowledge/decisions/internals/addon-package-roots-resolve-by-walking-node-module-search-paths.md +26 -0
- package/knowledge/decisions/internals/addon-singleton-services-are-cached-per-namespace-not-per-package.md +33 -0
- package/knowledge/decisions/internals/addon-workflow-names-are-prefixed-with-the-consumer-namespace.md +28 -0
- package/knowledge/decisions/internals/ai-agent-agui-bridge-obeys-the-client-ordering-contract.md +29 -0
- package/knowledge/decisions/internals/ai-agent-audio-chunks-carry-the-format-the-provider-returned.md +20 -0
- package/knowledge/decisions/internals/ai-agent-credential-suspensions-hide-the-tool-result.md +26 -0
- package/knowledge/decisions/internals/ai-agent-delegate-and-supervise-hide-different-text.md +26 -0
- package/knowledge/decisions/internals/ai-agent-llm-tool-arguments-have-nulls-stripped.md +23 -0
- package/knowledge/decisions/internals/ai-agent-model-config-stays-a-single-resolution-seam.md +25 -0
- package/knowledge/decisions/internals/ai-agent-onerror-hooks-cannot-change-the-failure.md +22 -0
- package/knowledge/decisions/internals/ai-agent-runner-methods-must-keep-their-receiver.md +22 -0
- package/knowledge/decisions/internals/ai-agent-stream-persistence-is-best-effort.md +27 -0
- package/knowledge/decisions/internals/ai-agent-sub-agents-inherit-the-parent-context-block.md +26 -0
- package/knowledge/decisions/internals/ai-agent-tool-execute-failures-are-logged-unconditionally.md +25 -0
- package/knowledge/decisions/internals/ai-agent-voice-input-transcribes-audio-parts-in-place.md +22 -0
- package/knowledge/decisions/internals/ai-agent-working-memory-is-persisted-only-when-valid.md +25 -0
- package/knowledge/decisions/internals/channel-message-handlers-accept-three-config-shapes.md +30 -0
- package/knowledge/decisions/internals/channel-middleware-caches-only-statically-resolved-middleware.md +31 -0
- package/knowledge/decisions/internals/channel-state-is-per-socket-session-state-is-per-user.md +29 -0
- package/knowledge/decisions/internals/channel-user-id-is-persisted-after-onconnect-middleware-runs.md +28 -0
- package/knowledge/decisions/internals/cli-option-names-are-camelcase-in-state-and-kebab-on-the-command-line.md +27 -0
- package/knowledge/decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md +28 -0
- package/knowledge/decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md +34 -0
- package/knowledge/decisions/internals/cli-unknown-long-options-warn-instead-of-failing.md +29 -0
- package/knowledge/decisions/internals/core-data-classification-brand-is-an-optional-property.md +34 -0
- package/knowledge/decisions/internals/core-function-runner-restores-the-wire-fields-it-overwrites.md +44 -0
- package/knowledge/decisions/internals/core-hot-reload-merges-generated-meta-never-replaces-it.md +39 -0
- package/knowledge/decisions/internals/core-hot-reload-owns-its-module-registry.md +42 -0
- package/knowledge/decisions/internals/core-middleware-order-is-scope-then-priority.md +39 -0
- package/knowledge/decisions/internals/core-schema-defaults-apply-on-every-transport.md +43 -0
- package/knowledge/decisions/internals/core-scopes-are-an-and-gate-separate-from-permissions.md +38 -0
- package/knowledge/decisions/internals/core-state-is-a-global-map-written-only-at-registration-time.md +44 -0
- package/knowledge/decisions/internals/email-meta-is-read-uncached-because-codegen-rewrites-it-mid-session.md +27 -0
- package/knowledge/decisions/internals/gateway-adapters-resolve-lazily-and-are-promise-cached.md +32 -0
- package/knowledge/decisions/internals/gateway-webhook-challenges-echo-bytes-not-json.md +28 -0
- package/knowledge/decisions/internals/gateway-wiring-is-a-meta-wiring-over-http-and-channels.md +31 -0
- package/knowledge/decisions/internals/generated-src-paths-in-pikku-meta-are-absolute.md +26 -0
- package/knowledge/decisions/internals/http-request-bodies-are-read-once-and-shared.md +32 -0
- package/knowledge/decisions/internals/http-route-groups-cascade-config-in-a-fixed-order.md +28 -0
- package/knowledge/decisions/internals/http-router-matches-normalized-paths-but-returns-registered-ones.md +30 -0
- package/knowledge/decisions/internals/http-runner-logs-through-a-trace-scoped-logger-functions-do-not.md +26 -0
- package/knowledge/decisions/internals/http-set-cookie-headers-are-appended-never-joined.md +28 -0
- package/knowledge/decisions/internals/http-sse-streams-flush-headers-only-after-middleware.md +32 -0
- package/knowledge/decisions/internals/http-wiring-without-metadata-is-skipped-not-fatal.md +26 -0
- package/knowledge/decisions/internals/in-a-scenario-a-4xx-is-data-not-an-exception.md +25 -0
- package/knowledge/decisions/internals/in-memory-workflow-history-aliases-the-live-step-object.md +26 -0
- package/knowledge/decisions/internals/index.md +113 -0
- package/knowledge/decisions/internals/istanbul-statement-counts-attach-to-the-start-line-only.md +25 -0
- package/knowledge/decisions/internals/local-trigger-and-gateway-services-assume-a-single-process.md +26 -0
- package/knowledge/decisions/internals/node-only-builtins-are-imported-dynamically.md +24 -0
- package/knowledge/decisions/internals/queue-group-concurrency-keeps-one-shared-queue-fair.md +28 -0
- package/knowledge/decisions/internals/queue-jobs-always-carry-an-explicit-attempts-count.md +27 -0
- package/knowledge/decisions/internals/remote-addons-dispatch-over-http-instead-of-local-meta.md +31 -0
- package/knowledge/decisions/internals/rpc-names-resolve-through-package-scope-before-root.md +32 -0
- package/knowledge/decisions/internals/scenario-agent-calls-sign-in-on-401-only.md +27 -0
- package/knowledge/decisions/internals/scenario-meta-lives-apart-from-app-meta-but-merges-when-read-off-disk.md +26 -0
- package/knowledge/decisions/internals/scenario-steps-return-drained-response-records.md +27 -0
- package/knowledge/decisions/internals/scope-roots-may-be-co-declared-by-an-addon-and-its-host-app.md +30 -0
- package/knowledge/decisions/internals/serverless-channel-disconnect-must-tolerate-a-missing-channel.md +28 -0
- package/knowledge/decisions/internals/the-dev-queue-copies-prod-timing-and-serialization-semantics.md +30 -0
- package/knowledge/decisions/internals/the-embedding-model-is-pinned-per-service-and-doc-query-embedding-is-split.md +29 -0
- package/knowledge/decisions/internals/the-in-memory-workflow-service-is-inline-only-and-single-process.md +27 -0
- package/knowledge/decisions/internals/the-kek-salt-is-scoped-to-the-key-version.md +40 -0
- package/knowledge/decisions/internals/the-schema-service-is-never-stubbed.md +26 -0
- package/knowledge/decisions/internals/trigger-declaration-is-split-from-trigger-source.md +33 -0
- package/knowledge/decisions/internals/typed-secret-service-caches-for-the-process-lifetime.md +26 -0
- package/knowledge/decisions/internals/webhook-delivery-history-records-every-attempt-best-effort.md +26 -0
- package/knowledge/decisions/internals/webhook-service-collaborators-are-constructor-args-not-locator-lookups.md +25 -0
- package/knowledge/decisions/internals/whether-a-run-is-inline-is-read-from-the-run-record.md +58 -0
- package/knowledge/decisions/internals/workflow-approval-expiry-is-decided-from-a-recorded-deadline.md +34 -0
- package/knowledge/decisions/internals/workflow-core-never-imports-a-browser-driver.md +42 -0
- package/knowledge/decisions/internals/workflow-dsl-meta-separates-runtime-expressions-from-literals.md +38 -0
- package/knowledge/decisions/internals/workflow-features-resolve-scenarios-by-object-identity.md +29 -0
- package/knowledge/decisions/internals/workflow-graph-inline-and-queued-runs-share-one-planner.md +42 -0
- package/knowledge/decisions/internals/workflow-graph-node-notes-are-excluded-from-the-graph-hash.md +25 -0
- package/knowledge/decisions/internals/workflow-inline-runs-report-their-run-id-before-they-can-fail.md +29 -0
- package/knowledge/decisions/internals/workflow-invocation-id-is-the-dedupe-key-not-step-id.md +43 -0
- package/knowledge/decisions/internals/workflow-queued-step-dispatch-requires-an-explicit-opt-in.md +29 -0
- package/knowledge/decisions/internals/workflow-queues-are-per-workflow-by-default.md +42 -0
- package/knowledge/decisions/internals/workflow-repeated-step-names-get-an-ordinal-suffix.md +33 -0
- package/knowledge/decisions/internals/workflow-replay-reads-its-steps-once-and-caches-only-the-immutable-half.md +32 -0
- package/knowledge/decisions/internals/workflow-retries-are-owned-by-the-workflow-not-the-queue.md +31 -0
- package/knowledge/decisions/internals/workflow-run-capabilities-are-extensions-not-subclasses.md +39 -0
- package/knowledge/decisions/internals/workflow-run-mirror-is-never-a-source-of-truth.md +29 -0
- package/knowledge/decisions/internals/workflow-run-polling-backs-off-to-the-callers-ceiling.md +33 -0
- package/knowledge/decisions/internals/workflow-run-timeline-is-a-pure-fold-over-durable-history.md +37 -0
- package/knowledge/decisions/internals/workflow-scenario-assertions-never-retry-and-record-one-step.md +50 -0
- package/knowledge/decisions/internals/workflow-scenario-hooks-are-a-scenario-only-affordance.md +43 -0
- package/knowledge/decisions/internals/workflow-scenario-prose-is-rendered-from-typed-calls-not-parsed-from-english.md +32 -0
- package/knowledge/decisions/internals/workflow-scenario-quarantine-reason-lives-in-code.md +18 -0
- package/knowledge/decisions/internals/workflow-scenario-step-targets-are-string-literals-for-the-inspector.md +34 -0
- package/knowledge/decisions/internals/workflow-step-compensation-runs-as-its-own-durable-step.md +26 -0
- package/knowledge/decisions/internals/workflow-step-dispatch-failure-is-transient-not-a-run-failure.md +33 -0
- package/knowledge/decisions/internals/workflow-step-lock-is-held-only-to-claim-the-step.md +27 -0
- package/knowledge/decisions/internals/workflow-step-rpc-name-is-provenance-only.md +34 -0
- package/knowledge/decisions/internals/workflow-suspend-and-approval-reasons-are-durable-step-identities.md +38 -0
- package/knowledge/decisions/internals/workflow-suspended-runs-keep-their-in-process-context.md +30 -0
- package/knowledge/decisions/security/a-dropped-audit-write-is-always-logged.md +26 -0
- package/knowledge/decisions/security/actor-flow-missing-approval-decisions-default-to-denied.md +22 -0
- package/knowledge/decisions/security/actor-sign-in-is-proven-by-set-cookie-not-a-non-empty-jar.md +27 -0
- package/knowledge/decisions/security/actor-sign-in-only-works-for-actor-flagged-users.md +27 -0
- package/knowledge/decisions/security/addon-auth-and-tags-only-tighten.md +43 -0
- package/knowledge/decisions/security/addon-config-gates-apply-only-at-the-namespaced-rpc-boundary.md +52 -0
- package/knowledge/decisions/security/addon-scopes-are-resolved-where-the-function-runs.md +46 -0
- package/knowledge/decisions/security/ai-agent-approval-forwarding-requires-a-symbol-brand.md +27 -0
- package/knowledge/decisions/security/ai-agent-credential-requests-are-symbol-branded.md +37 -0
- package/knowledge/decisions/security/ai-agent-gate-requires-a-session-only-when-auth-is-true.md +31 -0
- package/knowledge/decisions/security/ai-agent-ownership-failures-never-echo-the-resource.md +23 -0
- package/knowledge/decisions/security/ai-agent-resume-re-runs-the-authorization-gate.md +22 -0
- package/knowledge/decisions/security/ai-agent-sessionless-deployments-have-no-thread-ownership.md +39 -0
- package/knowledge/decisions/security/ai-agent-thread-ownership-composes-the-session-principal.md +30 -0
- package/knowledge/decisions/security/ai-agent-tool-filtering-reads-the-live-function-config.md +24 -0
- package/knowledge/decisions/security/an-empty-owners-constraint-matches-nothing.md +30 -0
- package/knowledge/decisions/security/an-exposed-ungated-function-is-a-codegen-warning.md +49 -0
- package/knowledge/decisions/security/console-addon-privileged-functions-gate-themselves.md +76 -0
- package/knowledge/decisions/security/core-safe-fetch-blocks-ssrf-by-host-literal-not-dns.md +39 -0
- package/knowledge/decisions/security/core-secrets-use-a-per-secret-dek-wrapped-by-a-kek.md +37 -0
- package/knowledge/decisions/security/gateway-handlers-run-through-the-function-runner-gate.md +31 -0
- package/knowledge/decisions/security/gateway-middleware-sessions-must-be-bridged-onto-the-wire.md +30 -0
- package/knowledge/decisions/security/global-permissions-and-function-permissions-are-independent-gates.md +40 -0
- package/knowledge/decisions/security/http-error-detail-is-withheld-from-clients-in-production.md +33 -0
- package/knowledge/decisions/security/http-request-bodies-are-bounded-before-they-are-buffered.md +46 -0
- package/knowledge/decisions/security/index.md +55 -0
- package/knowledge/decisions/security/mcp-internal-error-details-are-double-gated-on-production.md +27 -0
- package/knowledge/decisions/security/passphrases-are-stretched-key-material-is-expanded.md +40 -0
- package/knowledge/decisions/security/permission-auth-filtering-requires-live-permission-functions.md +31 -0
- package/knowledge/decisions/security/pikku-carries-actor-scopes-as-data-and-the-app-grants-them.md +26 -0
- package/knowledge/decisions/security/queue-job-identities-are-signed-at-enqueue.md +69 -0
- package/knowledge/decisions/security/queue-jobs-carry-the-producers-pikku-user-id.md +39 -0
- package/knowledge/decisions/security/remote-addon-tokens-are-client-credentials-not-mesh-trust.md +34 -0
- package/knowledge/decisions/security/scaffold-features-are-authenticated-unless-opted-out.md +49 -0
- package/knowledge/decisions/security/scenario-step-functions-are-never-externally-invocable.md +30 -0
- package/knowledge/decisions/security/scope-resolution-happens-at-the-session-boundary-and-sync-never-deletes.md +28 -0
- package/knowledge/decisions/security/self-authentication-is-declared-not-detected.md +34 -0
- package/knowledge/decisions/security/signed-content-urls-bind-the-request-path.md +37 -0
- package/knowledge/decisions/security/webhook-bodies-are-signed-before-they-are-enqueued.md +25 -0
- package/knowledge/decisions/security/workflow-actor-steps-always-use-the-real-transport.md +34 -0
- package/knowledge/decisions/security/workflow-approval-payloads-are-validated-on-replay-inside-the-workflow.md +40 -0
- package/knowledge/decisions/security/workflow-queued-steps-rehydrate-their-session-from-the-run-wire.md +32 -0
- package/knowledge/decisions/security/workflow-scenario-sessions-are-isolated-per-actor-and-per-scenario.md +32 -0
- package/knowledge/decisions/security/workflow-scenario-steps-are-never-network-invocable.md +31 -0
- package/knowledge/index.md +24 -0
- package/knowledge/questions/index.md +15 -0
- package/package.json +4 -2
- package/run-tests.sh +0 -0
- package/src/crypto-utils.test.ts +460 -19
- package/src/crypto-utils.ts +283 -55
- package/src/data-classification.ts +1 -7
- package/src/dev/hot-reload.test.ts +0 -4
- package/src/dev/hot-reload.ts +11 -30
- package/src/dev/module-runner.ts +7 -32
- package/src/dev/reload-meta.ts +9 -29
- package/src/errors/error-handler.ts +20 -35
- package/src/errors/error.test.ts +30 -1
- package/src/errors/errors.ts +73 -157
- package/src/function/abort-scope.test.ts +97 -0
- package/src/function/abort-scope.ts +80 -0
- package/src/function/function-runner.test.ts +75 -7
- package/src/function/function-runner.ts +73 -30
- package/src/function/functions.types.ts +56 -136
- package/src/function/list.types.test.ts +3 -25
- package/src/function/list.types.ts +12 -62
- package/src/gopass-secrets-removed.test.ts +51 -0
- package/src/handle-error.test.ts +108 -1
- package/src/handle-error.ts +8 -18
- package/src/index.ts +60 -1
- package/src/middleware/auth-apikey.test.ts +0 -1
- package/src/middleware/auth-apikey.ts +0 -17
- package/src/middleware/auth-bearer.test.ts +0 -3
- package/src/middleware/auth-bearer.ts +3 -40
- package/src/middleware/auth-cookie.test.ts +0 -6
- package/src/middleware/auth-cookie.ts +2 -26
- package/src/middleware/cors.test.ts +34 -0
- package/src/middleware/cors.ts +12 -33
- package/src/middleware/remote-auth.test.ts +24 -9
- package/src/middleware/remote-auth.ts +10 -2
- package/src/middleware/telemetry.ts +2 -31
- package/src/middleware-runner.test.ts +0 -2
- package/src/middleware-runner.ts +5 -74
- package/src/permissions.test.ts +30 -0
- package/src/permissions.ts +24 -74
- package/src/pikku-request.ts +0 -6
- package/src/pikku-state.ts +2 -30
- package/src/production-barrels-stay-lean.test.ts +110 -0
- package/src/remote.test.ts +172 -0
- package/src/remote.ts +17 -7
- package/src/schema.test.ts +103 -0
- package/src/schema.ts +35 -18
- package/src/scopes.ts +7 -48
- package/src/services/ai-agent-runner-service.ts +20 -0
- package/src/services/ai-embedding-service.ts +3 -25
- package/src/services/audit-service.ts +1 -2
- package/src/services/content-service.ts +1 -46
- package/src/services/credential-service.ts +3 -40
- package/src/services/credential-wire-service.test.ts +0 -2
- package/src/services/deployment-service.ts +3 -9
- package/src/services/gateway-service.ts +0 -15
- package/src/services/{http-scenario-actors-converse.test.ts → http-personas-converse.test.ts} +38 -9
- package/src/services/{http-scenario-actors.test.ts → http-personas.test.ts} +39 -22
- package/src/services/{http-scenario-actors.ts → http-personas.ts} +85 -45
- package/src/services/in-memory-queue-service.ts +1 -15
- package/src/services/in-memory-trigger-service.ts +1 -18
- package/src/services/in-memory-workflow-service.test.ts +0 -13
- package/src/services/in-memory-workflow-service.ts +4 -38
- package/src/services/index.ts +20 -15
- package/src/services/istanbul-coverage-service.ts +2 -8
- package/src/services/jwt-service.ts +1 -16
- package/src/services/local-content.test.ts +159 -27
- package/src/services/local-content.ts +55 -23
- package/src/services/local-gateway-service.ts +2 -17
- package/src/services/local-secrets.ts +0 -4
- package/src/services/logger-console.test.ts +0 -1
- package/src/services/logger-console.ts +3 -7
- package/src/services/logger.ts +2 -37
- package/src/services/meta-service.test.ts +1 -5
- package/src/services/meta-service.ts +41 -61
- package/src/services/{scenario-actors-service.ts → personas-service.ts} +48 -43
- package/src/services/pikku-user-id.ts +0 -4
- package/src/services/queue-webhook-service.ts +9 -41
- package/src/services/scheduler-service.ts +1 -50
- package/src/services/schema-service.ts +1 -24
- package/src/services/scope-service.ts +50 -34
- package/src/services/scoped-secret-service.ts +0 -4
- package/src/services/secret-host-binding.test.ts +138 -0
- package/src/services/secret-host-binding.ts +51 -0
- package/src/services/secret-service.ts +5 -33
- package/src/services/secretless.test.ts +54 -0
- package/src/services/secretless.ts +29 -0
- package/src/services/stub-tracker.ts +8 -18
- package/src/services/system-role-guard.test.ts +93 -0
- package/src/services/system-role-guard.ts +71 -0
- package/src/services/trigger-service.ts +0 -12
- package/src/services/typed-secret-service.ts +1 -7
- package/src/services/v8-coverage-service.ts +3 -6
- package/src/services/variables-service.ts +1 -8
- package/src/services/webhook-service.ts +19 -63
- package/src/services/workflow-service.ts +3 -20
- package/src/testing/service-tests.ts +0 -26
- package/src/time-utils.ts +1 -19
- package/src/types/core.types.ts +116 -229
- package/src/types/state.types.ts +7 -9
- package/src/utils/hmac.ts +4 -10
- package/src/utils/safe-fetch.ts +13 -54
- package/src/utils.test.ts +11 -2
- package/src/utils.ts +6 -15
- package/src/wirings/actor-flow/actor-flow.types.ts +1 -34
- package/src/wirings/actor-flow/index.ts +0 -9
- package/src/wirings/actor-flow/run-conversation.test.ts +11 -6
- package/src/wirings/actor-flow/run-conversation.ts +19 -12
- package/src/wirings/ai-agent/ai-agent-agui.test.ts +75 -10
- package/src/wirings/ai-agent/ai-agent-agui.ts +36 -17
- package/src/wirings/ai-agent/ai-agent-helpers.ts +20 -0
- package/src/wirings/ai-agent/ai-agent-interrupt.test.ts +842 -0
- package/src/wirings/ai-agent/ai-agent-interrupt.ts +399 -0
- package/src/wirings/ai-agent/ai-agent-memory.ts +0 -2
- package/src/wirings/ai-agent/ai-agent-model-config.ts +1 -9
- package/src/wirings/ai-agent/ai-agent-prepare.test.ts +202 -31
- package/src/wirings/ai-agent/ai-agent-prepare.ts +82 -138
- package/src/wirings/ai-agent/ai-agent-registry.test.ts +191 -6
- package/src/wirings/ai-agent/ai-agent-registry.ts +18 -1
- package/src/wirings/ai-agent/ai-agent-resume-authorization.test.ts +0 -2
- package/src/wirings/ai-agent/ai-agent-runner.test.ts +11 -9
- package/src/wirings/ai-agent/ai-agent-runner.ts +67 -33
- package/src/wirings/ai-agent/ai-agent-stream.test.ts +205 -103
- package/src/wirings/ai-agent/ai-agent-stream.ts +192 -75
- package/src/wirings/ai-agent/ai-agent-thread-ownership.test.ts +301 -0
- package/src/wirings/ai-agent/ai-agent.types.ts +85 -4
- package/src/wirings/ai-agent/index.ts +35 -3
- package/src/wirings/ai-agent/voice-input.test.ts +72 -7
- package/src/wirings/ai-agent/voice-input.ts +48 -3
- package/src/wirings/ai-agent/voice-output.test.ts +422 -0
- package/src/wirings/ai-agent/voice-output.ts +216 -56
- package/src/wirings/channel/channel-common.ts +15 -20
- package/src/wirings/channel/channel-handler.test.ts +50 -0
- package/src/wirings/channel/channel-handler.ts +32 -11
- package/src/wirings/channel/channel-host-rpc.test.ts +150 -0
- package/src/wirings/channel/channel-host-rpc.ts +69 -0
- package/src/wirings/channel/channel-middleware-runner.test.ts +0 -1
- package/src/wirings/channel/channel-middleware-runner.ts +0 -12
- package/src/wirings/channel/channel-rpc-registry.ts +116 -0
- package/src/wirings/channel/channel-rpc-responder.ts +117 -0
- package/src/wirings/channel/channel-rpc-service.ts +146 -0
- package/src/wirings/channel/channel-rpc-validators.ts +65 -0
- package/src/wirings/channel/channel-rpc.test.ts +820 -0
- package/src/wirings/channel/channel-rpc.ts +5 -0
- package/src/wirings/channel/channel-rpc.types.ts +150 -0
- package/src/wirings/channel/channel-runner.ts +0 -14
- package/src/wirings/channel/channel-store.ts +0 -10
- package/src/wirings/channel/channel.types.ts +19 -8
- package/src/wirings/channel/define-channel-routes.ts +0 -20
- package/src/wirings/channel/eventhub-service.ts +0 -18
- package/src/wirings/channel/index.ts +35 -0
- package/src/wirings/channel/local/local-channel-handler.ts +3 -1
- package/src/wirings/channel/local/local-channel-runner.test.ts +0 -10
- package/src/wirings/channel/local/local-channel-runner.ts +3 -1
- package/src/wirings/channel/local/local-eventhub-service.test.ts +0 -13
- package/src/wirings/channel/local/local-eventhub-service.ts +2 -37
- package/src/wirings/channel/log-channels.ts +0 -4
- package/src/wirings/channel/pikku-abstract-channel-handler.test.ts +83 -2
- package/src/wirings/channel/pikku-abstract-channel-handler.ts +7 -0
- package/src/wirings/channel/serverless/serverless-channel-runner.ts +2 -5
- package/src/wirings/cli/channel/cli-approval.test.ts +177 -0
- package/src/wirings/cli/channel/cli-approval.ts +135 -0
- package/src/wirings/cli/channel/cli-channel-runner.ts +4 -26
- package/src/wirings/cli/channel/cli-raw-channel-runner.test.ts +169 -0
- package/src/wirings/cli/channel/cli-raw-channel-runner.ts +59 -16
- package/src/wirings/cli/channel/cli-raw-client-runner.test.ts +480 -0
- package/src/wirings/cli/channel/cli-raw-client-runner.ts +155 -0
- package/src/wirings/cli/channel/index.ts +9 -0
- package/src/wirings/cli/cli-runner.test.ts +0 -1
- package/src/wirings/cli/cli-runner.ts +46 -88
- package/src/wirings/cli/cli.types.ts +14 -3
- package/src/wirings/cli/command-parser.test.ts +0 -4
- package/src/wirings/cli/command-parser.ts +11 -91
- package/src/wirings/cli/define-cli-commands.ts +1 -17
- package/src/wirings/credential/credential.types.ts +0 -12
- package/src/wirings/credential/{wire-credential.ts → define-credential.ts} +7 -7
- package/src/wirings/credential/index.ts +1 -1
- package/src/wirings/credential/validate-credential-definitions.ts +2 -4
- package/src/wirings/gateway/gateway-runner.test.ts +1 -21
- package/src/wirings/gateway/gateway-runner.ts +8 -110
- package/src/wirings/gateway/gateway.types.ts +7 -80
- package/src/wirings/http/http-routes.test.ts +0 -3
- package/src/wirings/http/http-routes.ts +0 -86
- package/src/wirings/http/http-runner.test.ts +0 -1
- package/src/wirings/http/http-runner.ts +12 -168
- package/src/wirings/http/http.types.ts +17 -62
- package/src/wirings/http/index.ts +5 -1
- package/src/wirings/http/log-http-routes.ts +0 -4
- package/src/wirings/http/pikku-fetch-http-request.test.ts +88 -7
- package/src/wirings/http/pikku-fetch-http-request.ts +74 -50
- package/src/wirings/http/pikku-fetch-http-response.test.ts +1 -1
- package/src/wirings/http/pikku-fetch-http-response.ts +0 -3
- package/src/wirings/http/routers/path-to-regex.test.ts +4 -17
- package/src/wirings/http/routers/path-to-regex.ts +2 -13
- package/src/wirings/http/web-request.test.ts +33 -2
- package/src/wirings/http/web-request.ts +30 -17
- package/src/wirings/mcp/mcp-endpoint-registry.test.ts +0 -1
- package/src/wirings/mcp/mcp-runner.test.ts +40 -0
- package/src/wirings/mcp/mcp-runner.ts +9 -15
- package/src/wirings/mcp/mcp.types.ts +7 -42
- package/src/wirings/oauth2/oauth2.types.ts +0 -30
- package/src/wirings/persona/define-personas.ts +29 -0
- package/src/wirings/persona/index.ts +62 -0
- package/src/wirings/persona/persona-email.ts +87 -0
- package/src/wirings/persona/persona-environments.test.ts +183 -0
- package/src/wirings/persona/persona-environments.ts +138 -0
- package/src/wirings/persona/persona-mailbox.ts +156 -0
- package/src/wirings/persona/persona.test.ts +220 -0
- package/src/wirings/persona/persona.types.ts +131 -0
- package/src/wirings/persona/validate-personas.ts +133 -0
- package/src/wirings/queue/index.ts +13 -3
- package/src/wirings/queue/queue-identity.test.ts +453 -0
- package/src/wirings/queue/queue-identity.ts +173 -0
- package/src/wirings/queue/queue-runner.ts +12 -31
- package/src/wirings/queue/queue.types.ts +19 -89
- package/src/wirings/queue/register-queue-helper.ts +0 -14
- package/src/wirings/queue/signed-queue-service.ts +59 -0
- package/src/wirings/queue/validate-worker-config.ts +2 -28
- package/src/wirings/role/define-system-role.ts +33 -0
- package/src/wirings/role/index.ts +13 -0
- package/src/wirings/role/role.test.ts +104 -0
- package/src/wirings/role/role.types.ts +47 -0
- package/src/wirings/role/validate-role-definitions.ts +93 -0
- package/src/wirings/rpc/addon-auth-tags.test.ts +223 -0
- package/src/wirings/rpc/addon-runner.ts +0 -56
- package/src/wirings/rpc/addon-scopes.test.ts +225 -0
- package/src/wirings/rpc/remote-addon-auth.ts +1 -13
- package/src/wirings/rpc/rpc-runner.test.ts +186 -2
- package/src/wirings/rpc/rpc-runner.ts +145 -127
- package/src/wirings/rpc/rpc-types.ts +11 -6
- package/src/wirings/rpc/wire-addon.test.ts +43 -1
- package/src/wirings/rpc/wire-addon.ts +99 -0
- package/src/wirings/rpc/wire-remote-addon.ts +9 -29
- package/src/wirings/scheduler/log-schedulers.ts +0 -4
- package/src/wirings/scheduler/scheduler-runner.test.ts +1 -8
- package/src/wirings/scheduler/scheduler-runner.ts +0 -2
- package/src/wirings/scheduler/scheduler.types.ts +1 -14
- package/src/wirings/scope/{wire-scope.ts → define-scope.ts} +5 -6
- package/src/wirings/scope/index.ts +1 -1
- package/src/wirings/scope/scope.test.ts +1 -2
- package/src/wirings/scope/scope.types.ts +7 -9
- package/src/wirings/scope/validate-scope-definitions.ts +3 -21
- package/src/wirings/secret/index.ts +1 -1
- package/src/wirings/secret/secret.types.ts +19 -15
- package/src/wirings/secret/validate-secret-definitions.ts +2 -4
- package/src/wirings/trigger/trigger-runner.ts +1 -27
- package/src/wirings/trigger/trigger.types.ts +1 -82
- package/src/wirings/variable/index.ts +1 -1
- package/src/wirings/variable/validate-variable-definitions.ts +2 -4
- package/src/wirings/variable/variable.types.ts +1 -13
- package/src/wirings/virtual-user/index.ts +76 -0
- package/src/wirings/virtual-user/run-virtual-user.test.ts +765 -0
- package/src/wirings/virtual-user/run-virtual-user.ts +671 -0
- package/src/wirings/virtual-user/virtual-user-agents.test.ts +65 -0
- package/src/wirings/virtual-user/virtual-user-agents.ts +57 -0
- package/src/wirings/virtual-user/virtual-user-catalogue.test.ts +215 -0
- package/src/wirings/virtual-user/virtual-user-catalogue.ts +184 -0
- package/src/wirings/virtual-user/virtual-user-derive.test.ts +398 -0
- package/src/wirings/virtual-user/virtual-user-derive.ts +173 -0
- package/src/wirings/virtual-user/virtual-user-dispositions.test.ts +63 -0
- package/src/wirings/virtual-user/virtual-user-dispositions.ts +213 -0
- package/src/wirings/virtual-user/virtual-user-intents.test.ts +208 -0
- package/src/wirings/virtual-user/virtual-user-intents.ts +185 -0
- package/src/wirings/virtual-user/virtual-user-rng.test.ts +72 -0
- package/src/wirings/virtual-user/virtual-user-rng.ts +50 -0
- package/src/wirings/virtual-user/virtual-user-target.ts +47 -0
- package/src/wirings/virtual-user/virtual-user.types.ts +219 -0
- package/src/wirings/workflow/dsl/workflow-dsl.types.ts +5 -4
- package/src/wirings/workflow/dsl/workflow-runner.ts +0 -4
- package/src/wirings/workflow/feature.ts +0 -19
- package/src/wirings/workflow/graph/graph-node.ts +0 -136
- package/src/wirings/workflow/graph/graph-runner.test.ts +20 -19
- package/src/wirings/workflow/graph/graph-runner.ts +6 -41
- package/src/wirings/workflow/graph/wire-workflow-graph.ts +0 -4
- package/src/wirings/workflow/graph/workflow-graph.types.ts +0 -58
- package/src/wirings/workflow/index.ts +10 -44
- package/src/wirings/workflow/pikku-scenario-service.ts +235 -52
- package/src/wirings/workflow/pikku-workflow-service.test.ts +0 -39
- package/src/wirings/workflow/pikku-workflow-service.ts +77 -674
- package/src/wirings/workflow/run-timeline.test.ts +7 -19
- package/src/wirings/workflow/run-timeline.ts +0 -56
- package/src/wirings/workflow/scenario-cookie-jar.test.ts +0 -1
- package/src/wirings/workflow/scenario-cookie-jar.ts +0 -25
- package/src/wirings/workflow/scenario-expectations.test.ts +2 -7
- package/src/wirings/workflow/scenario-hooks.test.ts +2 -7
- package/src/wirings/workflow/scenario-poll.test.ts +0 -2
- package/src/wirings/workflow/scenario-poll.ts +0 -15
- package/src/wirings/workflow/scenario-prose.ts +0 -28
- package/src/wirings/workflow/scenario-service.test.ts +2 -9
- package/src/wirings/workflow/scenario-step-guards.ts +1 -14
- package/src/wirings/workflow/scenario-step.test.ts +159 -14
- package/src/wirings/workflow/scenario-step.types.ts +82 -6
- package/src/wirings/workflow/scenario-surface.test.ts +145 -0
- package/src/wirings/workflow/scenario-surface.ts +71 -0
- package/src/wirings/workflow/workflow-dispatch-durability.test.ts +14 -15
- package/src/wirings/workflow/workflow-dispatch-payload.test.ts +0 -4
- package/src/wirings/workflow/workflow-inline-authority.test.ts +169 -0
- package/src/wirings/workflow/workflow-invocation-id.test.ts +0 -2
- package/src/wirings/workflow/workflow-invocation-id.ts +2 -22
- package/src/wirings/workflow/workflow-mirror.test.ts +0 -7
- package/src/wirings/workflow/workflow-on-error.test.ts +0 -9
- package/src/wirings/workflow/workflow-queue-workers.ts +0 -21
- package/src/wirings/workflow/workflow-replay-snapshot.test.ts +8 -7
- package/src/wirings/workflow/workflow-retry-policy.test.ts +0 -5
- package/src/wirings/workflow/workflow-run-context.test.ts +5 -10
- package/src/wirings/workflow/workflow-run-polling.test.ts +0 -5
- package/src/wirings/workflow/workflow-step-ordinal.test.ts +19 -4
- package/src/wirings/workflow/workflow-step-session.test.ts +0 -7
- package/src/wirings/workflow/workflow.types.ts +0 -203
- package/tsconfig.tsbuildinfo +1 -1
- package/src/middleware/timeout.ts +0 -22
- package/src/pikku-response.ts +0 -5
- package/src/services/gopass-secrets.ts +0 -78
- package/src/wirings/mcp/mcp-endpoint-registry.test.d.ts +0 -1
- package/src/wirings/workflow/dsl/index.ts +0 -36
- package/src/wirings/workflow/graph/index.ts +0 -15
|
@@ -2,46 +2,47 @@ import { pikkuState } from '../../../pikku-state.js';
|
|
|
2
2
|
import { parseCLIArguments, generateCommandHelp } from '../command-parser.js';
|
|
3
3
|
import { runCLICommand } from '../cli-runner.js';
|
|
4
4
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
5
|
+
* The client sends argv untouched and this side owns parsing, so the command
|
|
6
|
+
* tree lives with the server and a client binary never needs to know it.
|
|
7
7
|
*/
|
|
8
|
-
export async function handleRawCLI({ programName, args, singletonServices, createWireServices, }) {
|
|
8
|
+
export async function handleRawCLI({ programName, args, singletonServices, createWireServices, onOutput, session, transport, }) {
|
|
9
9
|
const allCLIMeta = pikkuState(null, 'cli', 'meta');
|
|
10
10
|
if (!allCLIMeta) {
|
|
11
|
-
return { error: 'CLI metadata not found' };
|
|
11
|
+
return { error: 'CLI metadata not found', exitCode: 1 };
|
|
12
12
|
}
|
|
13
13
|
const programMeta = allCLIMeta.programs[programName];
|
|
14
14
|
if (!programMeta) {
|
|
15
|
-
return { error: `Program "${programName}" not found
|
|
15
|
+
return { error: `Program "${programName}" not found`, exitCode: 1 };
|
|
16
16
|
}
|
|
17
|
-
// Handle empty input or explicit help
|
|
18
17
|
if (args.length === 0 ||
|
|
19
18
|
args.includes('--help') ||
|
|
20
19
|
args.includes('-h') ||
|
|
21
20
|
args[0] === 'help') {
|
|
22
21
|
const helpArgs = args.filter((a) => a !== 'help' && a !== '--help' && a !== '-h');
|
|
23
22
|
const helpText = generateCommandHelp(programName, allCLIMeta, helpArgs);
|
|
24
|
-
return { help: helpText };
|
|
23
|
+
return { help: helpText, exitCode: 0 };
|
|
25
24
|
}
|
|
26
|
-
// Parse the args
|
|
27
25
|
const parsed = parseCLIArguments(args, programName, allCLIMeta);
|
|
28
|
-
// If there are errors or the command resolves to a group (no function), show help
|
|
29
26
|
if (parsed.errors.length > 0 || parsed.commandPath.length === 0) {
|
|
30
27
|
const helpText = generateCommandHelp(programName, allCLIMeta, parsed.commandPath);
|
|
31
|
-
|
|
28
|
+
// Help says what is available, not what they got wrong — so the parser's
|
|
29
|
+
// reason rides alongside it.
|
|
30
|
+
return {
|
|
31
|
+
help: helpText,
|
|
32
|
+
error: parsed.errors.length > 0 ? parsed.errors.join('\n') : undefined,
|
|
33
|
+
exitCode: 1,
|
|
34
|
+
};
|
|
32
35
|
}
|
|
33
|
-
// Check if the resolved command has a pikkuFuncId (is executable)
|
|
34
36
|
let current = programMeta.commands[parsed.commandPath[0]];
|
|
35
37
|
for (let i = 1; i < parsed.commandPath.length; i++) {
|
|
36
38
|
current = current?.subcommands?.[parsed.commandPath[i]];
|
|
37
39
|
}
|
|
38
40
|
if (!current?.pikkuFuncId) {
|
|
39
|
-
// It's a group command — show help scoped to that group
|
|
40
41
|
const helpText = generateCommandHelp(programName, allCLIMeta, parsed.commandPath);
|
|
41
|
-
return { help: helpText };
|
|
42
|
+
return { help: helpText, exitCode: 0 };
|
|
42
43
|
}
|
|
43
|
-
// Execute the command
|
|
44
44
|
const data = { ...parsed.positionals, ...parsed.options };
|
|
45
|
+
const commandId = parsed.commandPath.join('.');
|
|
45
46
|
try {
|
|
46
47
|
const result = await runCLICommand({
|
|
47
48
|
program: programName,
|
|
@@ -49,10 +50,17 @@ export async function handleRawCLI({ programName, args, singletonServices, creat
|
|
|
49
50
|
data,
|
|
50
51
|
singletonServices,
|
|
51
52
|
createWireServices,
|
|
53
|
+
session,
|
|
54
|
+
// Not known until parsing finishes here, so it is supplied per-frame.
|
|
55
|
+
onOutput: onOutput && ((data) => onOutput(data, commandId)),
|
|
56
|
+
transport,
|
|
52
57
|
});
|
|
53
|
-
return { result };
|
|
58
|
+
return { result, exitCode: 0, commandId };
|
|
54
59
|
}
|
|
55
60
|
catch (e) {
|
|
56
|
-
|
|
61
|
+
// A command can throw anything; `.message` off a string is undefined, and
|
|
62
|
+
// the run would then exit 1 saying nothing at all.
|
|
63
|
+
const message = e instanceof Error ? e.message : String(e);
|
|
64
|
+
return { error: message || 'Command failed', exitCode: 1, commandId };
|
|
57
65
|
}
|
|
58
66
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { ApprovalRequester, Capabilities } from '../../channel/channel-rpc.js';
|
|
2
|
+
import type { CorePikkuCLIRender } from '../cli.types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Runs a CLI command entirely on the server. Unlike `executeCLIViaChannel`,
|
|
5
|
+
* argv is forwarded untouched and never parsed here, so the client carries no
|
|
6
|
+
* command metadata and its version may drift from the server's.
|
|
7
|
+
*
|
|
8
|
+
* `capabilities` are the functions this client agrees to run on the server's
|
|
9
|
+
* behalf: the map says what *can* run, and approval whether a call *should*.
|
|
10
|
+
* `approve` overrides the mode otherwise read from argv and from whether there
|
|
11
|
+
* is a terminal to ask at.
|
|
12
|
+
*/
|
|
13
|
+
export declare function executeRawCLIViaChannel({ pikkuWS, args, renderers, defaultRenderer, capabilities, approve, }: {
|
|
14
|
+
pikkuWS: any;
|
|
15
|
+
args?: string[];
|
|
16
|
+
renderers?: Record<string, CorePikkuCLIRender<any>>;
|
|
17
|
+
defaultRenderer?: CorePikkuCLIRender<any>;
|
|
18
|
+
capabilities?: Capabilities;
|
|
19
|
+
approve?: ApprovalRequester;
|
|
20
|
+
}): Promise<number>;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { createChannelRPCResponder, isChannelRPCRequest, } from '../../channel/channel-rpc.js';
|
|
2
|
+
import { approverForMode, takeApprovalFlags } from './cli-approval.js';
|
|
3
|
+
/** The normal case once the server owns the command tree. */
|
|
4
|
+
const defaultJSONRenderer = (_services, data) => {
|
|
5
|
+
console.log(JSON.stringify(data));
|
|
6
|
+
};
|
|
7
|
+
/**
|
|
8
|
+
* The command ran on the server, so there are no services here — but a renderer
|
|
9
|
+
* written for local execution can still reach for `services.logger`.
|
|
10
|
+
*/
|
|
11
|
+
const clientServices = { logger: console };
|
|
12
|
+
/**
|
|
13
|
+
* Runs a CLI command entirely on the server. Unlike `executeCLIViaChannel`,
|
|
14
|
+
* argv is forwarded untouched and never parsed here, so the client carries no
|
|
15
|
+
* command metadata and its version may drift from the server's.
|
|
16
|
+
*
|
|
17
|
+
* `capabilities` are the functions this client agrees to run on the server's
|
|
18
|
+
* behalf: the map says what *can* run, and approval whether a call *should*.
|
|
19
|
+
* `approve` overrides the mode otherwise read from argv and from whether there
|
|
20
|
+
* is a terminal to ask at.
|
|
21
|
+
*/
|
|
22
|
+
export async function executeRawCLIViaChannel({ pikkuWS, args = process.argv.slice(2), renderers = {}, defaultRenderer, capabilities = {}, approve, }) {
|
|
23
|
+
// Stripped before argv goes to the server: a flag the server can see is one
|
|
24
|
+
// the server could act on.
|
|
25
|
+
const { mode, args: commandArgs } = takeApprovalFlags(args);
|
|
26
|
+
// Aborted when the run ends, so a prompt still on stdin stops holding the
|
|
27
|
+
// event loop open.
|
|
28
|
+
const runEnded = new AbortController();
|
|
29
|
+
const approver = approve ?? approverForMode(mode, { signal: runEnded.signal });
|
|
30
|
+
const render = (commandId, data) => {
|
|
31
|
+
const renderer = (commandId ? renderers[commandId] : undefined) ||
|
|
32
|
+
defaultRenderer ||
|
|
33
|
+
defaultJSONRenderer;
|
|
34
|
+
renderer(clientServices, data, undefined);
|
|
35
|
+
};
|
|
36
|
+
return new Promise((resolve) => {
|
|
37
|
+
const commandRoute = pikkuWS.getRoute('command');
|
|
38
|
+
let settled = false;
|
|
39
|
+
// Plain frames, not a command route: the server takes these off the socket
|
|
40
|
+
// before routing.
|
|
41
|
+
const respond = createChannelRPCResponder({
|
|
42
|
+
capabilities,
|
|
43
|
+
approve: approver,
|
|
44
|
+
send: (data) => {
|
|
45
|
+
// A capability can still be resolving when the run settles. `respond`
|
|
46
|
+
// is dispatched without a handler, so a throw here would surface as an
|
|
47
|
+
// unhandled rejection — and by then the answer is moot.
|
|
48
|
+
if (settled || pikkuWS.ws.readyState !== 1) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
pikkuWS.ws.send(JSON.stringify(data));
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
const finish = (code) => {
|
|
55
|
+
if (settled) {
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
settled = true;
|
|
59
|
+
runEnded.abort();
|
|
60
|
+
pikkuWS.unsubscribe(handler);
|
|
61
|
+
try {
|
|
62
|
+
pikkuWS.ws.close();
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// Already closing — the exit code is what matters.
|
|
66
|
+
}
|
|
67
|
+
resolve(code);
|
|
68
|
+
};
|
|
69
|
+
// Every frame, not a command id: the server owns the command tree, and
|
|
70
|
+
// progressive `channel.send` frames carry no routing key at all.
|
|
71
|
+
const handler = (message) => {
|
|
72
|
+
// Classified synchronously so a request never also reaches the renderer.
|
|
73
|
+
// Answering is deliberately not awaited, so a slow capability cannot
|
|
74
|
+
// stall the output stream behind it.
|
|
75
|
+
if (isChannelRPCRequest(message)) {
|
|
76
|
+
void respond(message);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
// Only declared shapes: the channel also carries the runtime's routing
|
|
80
|
+
// echo, and rendering that would print noise between real output.
|
|
81
|
+
switch (message?.action) {
|
|
82
|
+
case 'cli-output':
|
|
83
|
+
render(message.commandId, message.data);
|
|
84
|
+
break;
|
|
85
|
+
case 'cli-result':
|
|
86
|
+
render(message.commandId, message.result);
|
|
87
|
+
break;
|
|
88
|
+
case 'cli-help':
|
|
89
|
+
console.log(message.help);
|
|
90
|
+
break;
|
|
91
|
+
case 'cli-error':
|
|
92
|
+
console.error(message.error);
|
|
93
|
+
break;
|
|
94
|
+
case 'cli-control':
|
|
95
|
+
if (message.event === 'complete') {
|
|
96
|
+
finish(message.exitCode ?? 0);
|
|
97
|
+
}
|
|
98
|
+
break;
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
pikkuWS.subscribe(handler);
|
|
102
|
+
// Only the server's `complete` frame reports success: a socket that closes
|
|
103
|
+
// before one means the command did not finish.
|
|
104
|
+
pikkuWS.ws.addEventListener('close', () => finish(1));
|
|
105
|
+
// A transport failure exits like a failed command rather than rejecting —
|
|
106
|
+
// to a CLI user both are simply a run that did not work.
|
|
107
|
+
pikkuWS.ws.addEventListener('error', (error) => {
|
|
108
|
+
if (!settled) {
|
|
109
|
+
console.error(error?.message ?? String(error));
|
|
110
|
+
finish(1);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
const sendCommand = () => commandRoute.send('__raw', { args: commandArgs });
|
|
114
|
+
if (pikkuWS.ws.readyState === 1) {
|
|
115
|
+
sendCommand();
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
pikkuWS.ws.addEventListener('open', sendCommand);
|
|
119
|
+
}
|
|
120
|
+
});
|
|
121
|
+
}
|
|
@@ -1,2 +1,6 @@
|
|
|
1
1
|
export { executeCLIViaChannel } from './cli-channel-runner.js';
|
|
2
2
|
export { handleRawCLI } from './cli-raw-channel-runner.js';
|
|
3
|
+
export type { RawCLIFrame, RawCLIResult } from './cli-raw-channel-runner.js';
|
|
4
|
+
export { executeRawCLIViaChannel } from './cli-raw-client-runner.js';
|
|
5
|
+
export { APPROVAL_FLAGS, approverForMode, createTerminalApprover, takeApprovalFlags, } from './cli-approval.js';
|
|
6
|
+
export type { ApprovalMode } from './cli-approval.js';
|
|
@@ -1,2 +1,4 @@
|
|
|
1
1
|
export { executeCLIViaChannel } from './cli-channel-runner.js';
|
|
2
2
|
export { handleRawCLI } from './cli-raw-channel-runner.js';
|
|
3
|
+
export { executeRawCLIViaChannel } from './cli-raw-client-runner.js';
|
|
4
|
+
export { APPROVAL_FLAGS, approverForMode, createTerminalApprover, takeApprovalFlags, } from './cli-approval.js';
|
|
@@ -1,38 +1,38 @@
|
|
|
1
1
|
import type { CorePikkuMiddleware, CoreUserSession } from '../../types/core.types.js';
|
|
2
2
|
import type { CoreCLI, CorePikkuCLIRender, CoreCLICommandConfig } from './cli.types.js';
|
|
3
3
|
import type { CoreSingletonServices, CoreServices, CreateWireServices, CreateConfig, CreateSingletonServices } from '../../types/core.types.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
* Should be caught by the wrapper to call process.exit()
|
|
7
|
-
*/
|
|
4
|
+
import type { PikkuChannel } from '../channel/channel.types.js';
|
|
5
|
+
/** The caller is expected to catch this and call `process.exit(exitCode)`. */
|
|
8
6
|
export declare class CLIError extends Error {
|
|
9
7
|
exitCode: number;
|
|
10
8
|
constructor(message: string, exitCode?: number);
|
|
11
9
|
}
|
|
12
|
-
/**
|
|
13
|
-
* Registers a CLI command tree and all its functions
|
|
14
|
-
*/
|
|
15
10
|
export declare const wireCLI: <Commands extends Record<string, CoreCLICommandConfig<any, any, any>>, GlobalOptions, PikkuMiddleware extends CorePikkuMiddleware, GlobalOutput>(cli: CoreCLI<Commands, GlobalOptions, PikkuMiddleware, GlobalOutput>) => void;
|
|
16
|
-
|
|
17
|
-
* Executes a CLI command for a specific program
|
|
18
|
-
*/
|
|
19
|
-
export declare function runCLICommand({ program, commandPath, data, singletonServices, createWireServices, }: {
|
|
11
|
+
export declare function runCLICommand({ program, commandPath, data, singletonServices, createWireServices, onOutput, session, transport, }: {
|
|
20
12
|
program: string;
|
|
21
13
|
commandPath: string[];
|
|
22
14
|
data: Record<string, any>;
|
|
23
15
|
singletonServices: CoreSingletonServices;
|
|
24
16
|
createWireServices?: CreateWireServices;
|
|
17
|
+
/**
|
|
18
|
+
* A locally run CLI has none — the process is the user. Over a channel the
|
|
19
|
+
* command inherits what the connection authenticated as, or no authenticated
|
|
20
|
+
* command is reachable remotely.
|
|
21
|
+
*/
|
|
22
|
+
session?: CoreUserSession;
|
|
23
|
+
/**
|
|
24
|
+
* Diverts everything the command emits to a sink instead of the local
|
|
25
|
+
* renderer: when running on behalf of a remote CLI, rendering here would
|
|
26
|
+
* print to the *server's* stdout.
|
|
27
|
+
*/
|
|
28
|
+
onOutput?: (data: unknown) => Promise<void> | void;
|
|
29
|
+
/**
|
|
30
|
+
* The connection the command arrived on. The CLI wire's own channel is
|
|
31
|
+
* synthetic, so reaching the caller is delegated to the real one underneath.
|
|
32
|
+
*/
|
|
33
|
+
transport?: PikkuChannel<unknown, any, any>;
|
|
25
34
|
}): Promise<any>;
|
|
26
|
-
/**
|
|
27
|
-
* Factory function for CLI-specific renderers
|
|
28
|
-
*/
|
|
29
35
|
export declare const pikkuCLIRender: <Data, Services extends CoreSingletonServices = CoreServices, Session extends CoreUserSession = CoreUserSession>(renderer: (services: Services, data: Data, session?: Session) => void | Promise<void>) => CorePikkuCLIRender<Data, Services, Session>;
|
|
30
|
-
/**
|
|
31
|
-
* Execute a CLI program with the given arguments
|
|
32
|
-
* This is the main entry point for CLI programs
|
|
33
|
-
*
|
|
34
|
-
* @throws {CLIError} When CLI execution fails - should be caught by wrapper to call process.exit()
|
|
35
|
-
*/
|
|
36
36
|
export declare function executeCLI({ programName, args, createConfig, createSingletonServices, createWireServices, }: {
|
|
37
37
|
programName: string;
|
|
38
38
|
args?: string[];
|
|
@@ -2,13 +2,11 @@ import { NotFoundError } from '../../errors/errors.js';
|
|
|
2
2
|
import { isExpectedError } from '../../errors/error-handler.js';
|
|
3
3
|
import { addFunction, runPikkuFunc } from '../../function/function-runner.js';
|
|
4
4
|
import { pikkuState } from '../../pikku-state.js';
|
|
5
|
+
import { unsupportedChannelRemote } from '../channel/channel-rpc.js';
|
|
5
6
|
import { PikkuSessionService, createMiddlewareSessionWireProps, } from '../../services/user-session-service.js';
|
|
6
7
|
import { LocalVariablesService } from '../../services/local-variables.js';
|
|
7
8
|
import { generateCommandHelp, parseCLIArguments } from './command-parser.js';
|
|
8
|
-
/**
|
|
9
|
-
* CLI command execution error - thrown when CLI execution fails
|
|
10
|
-
* Should be caught by the wrapper to call process.exit()
|
|
11
|
-
*/
|
|
9
|
+
/** The caller is expected to catch this and call `process.exit(exitCode)`. */
|
|
12
10
|
export class CLIError extends Error {
|
|
13
11
|
exitCode;
|
|
14
12
|
constructor(message, exitCode = 1) {
|
|
@@ -17,25 +15,16 @@ export class CLIError extends Error {
|
|
|
17
15
|
this.name = 'CLIError';
|
|
18
16
|
}
|
|
19
17
|
}
|
|
20
|
-
|
|
21
|
-
* Default JSON renderer for CLI output. Emits single-line NDJSON so
|
|
22
|
-
* the output stays machine-parseable when the CLI is run with
|
|
23
|
-
* `--output json`; pretty-printing here would break NDJSON consumers.
|
|
24
|
-
*/
|
|
18
|
+
// knowledge: decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md
|
|
25
19
|
const defaultJSONRenderer = (_services, data) => {
|
|
26
20
|
console.log(JSON.stringify(data));
|
|
27
21
|
};
|
|
28
|
-
/**
|
|
29
|
-
* Registers a CLI command tree and all its functions
|
|
30
|
-
*/
|
|
31
22
|
export const wireCLI = (cli) => {
|
|
32
|
-
// Get the existing metadata that was generated during inspection
|
|
33
23
|
const cliMeta = pikkuState(null, 'cli', 'meta') || {};
|
|
34
24
|
if (!cliMeta.programs?.[cli.program]) {
|
|
35
25
|
console.warn(`[pikku] Skipping CLI program '${cli.program}' — metadata not found. Consider moving this wiring to its own file.`);
|
|
36
26
|
return;
|
|
37
27
|
}
|
|
38
|
-
// Get existing programs state and add this program
|
|
39
28
|
const programs = pikkuState(null, 'cli', 'programs') || {};
|
|
40
29
|
programs[cli.program] = {
|
|
41
30
|
defaultRenderer: (cli.render ||
|
|
@@ -45,18 +34,12 @@ export const wireCLI = (cli) => {
|
|
|
45
34
|
tags: cli.tags,
|
|
46
35
|
};
|
|
47
36
|
pikkuState(null, 'cli', 'programs', programs);
|
|
48
|
-
// Register all command functions recursively
|
|
49
37
|
registerCLICommands(cli.commands, [], cli.options || {}, cli.program);
|
|
50
38
|
};
|
|
51
|
-
/**
|
|
52
|
-
* Unwraps a function from pikku wrappers (pikkuFunc, pikkuSessionlessFunc, etc.)
|
|
53
|
-
* These wrappers return { func, middleware, ... } but we need the actual function
|
|
54
|
-
*/
|
|
55
39
|
function unwrapFunc(command) {
|
|
56
40
|
if (typeof command === 'function') {
|
|
57
41
|
return { func: command };
|
|
58
42
|
}
|
|
59
|
-
// If command has a func property that's an object with func, unwrap it
|
|
60
43
|
if (command.func &&
|
|
61
44
|
typeof command.func === 'object' &&
|
|
62
45
|
'func' in command.func) {
|
|
@@ -68,27 +51,20 @@ function unwrapFunc(command) {
|
|
|
68
51
|
tags: command.func.tags,
|
|
69
52
|
};
|
|
70
53
|
}
|
|
71
|
-
// Otherwise return as-is
|
|
72
54
|
return command;
|
|
73
55
|
}
|
|
74
|
-
/**
|
|
75
|
-
* Registers CLI commands and their functions recursively
|
|
76
|
-
*/
|
|
77
56
|
function registerCLICommands(commands, path = [], inheritedOptions = {}, program) {
|
|
78
|
-
// Get the CLI metadata to find actual function names
|
|
79
57
|
const cliMeta = pikkuState(null, 'cli', 'meta').programs[program];
|
|
80
58
|
for (const [name, command] of Object.entries(commands)) {
|
|
81
59
|
const fullPath = [...path, name];
|
|
82
60
|
const commandId = fullPath.join('.');
|
|
83
|
-
// Navigate metadata to find the actual function name
|
|
84
61
|
let currentMeta = cliMeta?.commands[fullPath[0]];
|
|
85
62
|
for (let i = 1; i < fullPath.length; i++) {
|
|
86
63
|
currentMeta = currentMeta?.subcommands?.[fullPath[i]];
|
|
87
64
|
}
|
|
88
65
|
const funcName = currentMeta?.pikkuFuncId;
|
|
89
|
-
//
|
|
66
|
+
// A command group has no function of its own.
|
|
90
67
|
if (!funcName) {
|
|
91
|
-
// Recursively register subcommands if they exist
|
|
92
68
|
if (typeof command === 'object' && command.subcommands) {
|
|
93
69
|
const commandOptions = command.options || {};
|
|
94
70
|
const mergedOptions = { ...inheritedOptions, ...commandOptions };
|
|
@@ -96,17 +72,14 @@ function registerCLICommands(commands, path = [], inheritedOptions = {}, program
|
|
|
96
72
|
}
|
|
97
73
|
continue;
|
|
98
74
|
}
|
|
99
|
-
// Merge options (inherited + local)
|
|
100
75
|
const commandOptions = typeof command === 'object' ? command.options || {} : {};
|
|
101
76
|
const mergedOptions = { ...inheritedOptions, ...commandOptions };
|
|
102
|
-
// Store the options and middleware in program state for use during execution
|
|
103
77
|
const programs = pikkuState(null, 'cli', 'programs');
|
|
104
78
|
if (programs[program]) {
|
|
105
79
|
if (!programs[program].commandOptions) {
|
|
106
80
|
programs[program].commandOptions = {};
|
|
107
81
|
}
|
|
108
82
|
programs[program].commandOptions[commandId] = mergedOptions;
|
|
109
|
-
// Store command middleware from the wire config
|
|
110
83
|
if (typeof command === 'object' && command.middleware) {
|
|
111
84
|
if (!programs[program].commandMiddleware) {
|
|
112
85
|
programs[program].commandMiddleware = {};
|
|
@@ -115,21 +88,16 @@ function registerCLICommands(commands, path = [], inheritedOptions = {}, program
|
|
|
115
88
|
}
|
|
116
89
|
}
|
|
117
90
|
addFunction(funcName, unwrapFunc(command), currentMeta?.packageName);
|
|
118
|
-
// Register renderer if provided
|
|
119
91
|
if (typeof command === 'object' && command.render) {
|
|
120
92
|
if (programs[program]) {
|
|
121
93
|
programs[program].renderers[commandId] = command.render;
|
|
122
94
|
}
|
|
123
95
|
}
|
|
124
|
-
// Recursively register subcommands
|
|
125
96
|
if (typeof command === 'object' && command.subcommands) {
|
|
126
97
|
registerCLICommands(command.subcommands, fullPath, mergedOptions, program);
|
|
127
98
|
}
|
|
128
99
|
}
|
|
129
100
|
}
|
|
130
|
-
/**
|
|
131
|
-
* Plucks only the data that the function expects based on its schema
|
|
132
|
-
*/
|
|
133
101
|
function pluckCLIData(mergedData, funcName, availableOptions) {
|
|
134
102
|
const funcMeta = pikkuState(null, 'function', 'meta')[funcName];
|
|
135
103
|
const schemaName = funcMeta?.inputSchemaName;
|
|
@@ -137,12 +105,11 @@ function pluckCLIData(mergedData, funcName, availableOptions) {
|
|
|
137
105
|
? pikkuState(funcMeta?.packageName ?? null, 'misc', 'schemas').get(schemaName)
|
|
138
106
|
: null;
|
|
139
107
|
if (schema && schema.properties) {
|
|
140
|
-
// If we have a schema, only include fields that are in the schema
|
|
141
108
|
const result = {};
|
|
142
109
|
for (const key of Object.keys(schema.properties)) {
|
|
143
110
|
if (key in mergedData) {
|
|
111
|
+
// CLI values always arrive as strings; split comma lists the schema wants as arrays.
|
|
144
112
|
let value = mergedData[key];
|
|
145
|
-
// CLI passes all values as strings — coerce to array when schema expects one
|
|
146
113
|
const propSchema = schema.properties[key];
|
|
147
114
|
if (propSchema?.type === 'array' && !Array.isArray(value)) {
|
|
148
115
|
value = typeof value === 'string' ? value.split(',') : [value];
|
|
@@ -150,28 +117,21 @@ function pluckCLIData(mergedData, funcName, availableOptions) {
|
|
|
150
117
|
result[key] = value;
|
|
151
118
|
}
|
|
152
119
|
else if (availableOptions[key]?.default !== undefined) {
|
|
153
|
-
// Apply default if not provided
|
|
154
120
|
result[key] = availableOptions[key].default;
|
|
155
121
|
}
|
|
156
122
|
}
|
|
157
123
|
return result;
|
|
158
124
|
}
|
|
159
125
|
else {
|
|
160
|
-
// No schema, include all data
|
|
161
126
|
return { ...mergedData };
|
|
162
127
|
}
|
|
163
128
|
}
|
|
164
|
-
|
|
165
|
-
* Executes a CLI command for a specific program
|
|
166
|
-
*/
|
|
167
|
-
export async function runCLICommand({ program, commandPath, data, singletonServices, createWireServices, }) {
|
|
168
|
-
// Get the command metadata to find the function name
|
|
129
|
+
export async function runCLICommand({ program, commandPath, data, singletonServices, createWireServices, onOutput, session, transport, }) {
|
|
169
130
|
const cliMeta = pikkuState(null, 'cli', 'meta');
|
|
170
131
|
const programMeta = cliMeta.programs?.[program];
|
|
171
132
|
if (!programMeta) {
|
|
172
133
|
throw new NotFoundError(`Program not found: ${program}`);
|
|
173
134
|
}
|
|
174
|
-
// Navigate command tree to find the function name
|
|
175
135
|
let currentCommand = programMeta.commands[commandPath[0]];
|
|
176
136
|
if (!currentCommand) {
|
|
177
137
|
throw new NotFoundError(`Command not found: ${commandPath.join(' ')}`);
|
|
@@ -184,14 +144,11 @@ export async function runCLICommand({ program, commandPath, data, singletonServi
|
|
|
184
144
|
currentCommand = currentCommand.subcommands[commandPath[i]];
|
|
185
145
|
}
|
|
186
146
|
const funcName = currentCommand.pikkuFuncId;
|
|
187
|
-
// Get program-specific data
|
|
188
147
|
const programs = pikkuState(null, 'cli', 'programs') || {};
|
|
189
148
|
const programData = programs[program];
|
|
190
|
-
// Combine program middleware + command middleware from the hierarchy
|
|
191
149
|
const allWireMiddleware = [
|
|
192
150
|
...(programData?.middleware || []),
|
|
193
151
|
];
|
|
194
|
-
// Walk through the command path and collect middleware from the runtime config
|
|
195
152
|
const commandParts = [];
|
|
196
153
|
for (const part of commandPath) {
|
|
197
154
|
commandParts.push(part);
|
|
@@ -201,20 +158,19 @@ export async function runCLICommand({ program, commandPath, data, singletonServi
|
|
|
201
158
|
allWireMiddleware.push(...middleware);
|
|
202
159
|
}
|
|
203
160
|
}
|
|
204
|
-
// Get command ID and options
|
|
205
161
|
const commandId = commandPath.join('.');
|
|
206
162
|
const availableOptions = programData?.commandOptions?.[commandId] || {};
|
|
207
|
-
// Pluck only the fields the function expects
|
|
208
163
|
const pluckedData = () => pluckCLIData(data, funcName, availableOptions);
|
|
209
|
-
// Get the renderer
|
|
210
164
|
const renderer = programData?.renderers[commandId] || programData?.defaultRenderer;
|
|
211
|
-
// Create a CLI channel for progressive output
|
|
212
165
|
let cliState;
|
|
213
166
|
const channel = {
|
|
214
167
|
channelId: `cli:${program}:${commandId}`,
|
|
215
168
|
openingData: pluckedData,
|
|
216
169
|
send: async (data) => {
|
|
217
|
-
if (
|
|
170
|
+
if (onOutput) {
|
|
171
|
+
await onOutput(data);
|
|
172
|
+
}
|
|
173
|
+
else if (renderer) {
|
|
218
174
|
await Promise.resolve(renderer(singletonServices, data, undefined));
|
|
219
175
|
}
|
|
220
176
|
},
|
|
@@ -234,8 +190,16 @@ export async function runCLICommand({ program, commandPath, data, singletonServi
|
|
|
234
190
|
clearState: () => {
|
|
235
191
|
cliState = undefined;
|
|
236
192
|
},
|
|
193
|
+
// A locally-run command is already on the machine it would call back to,
|
|
194
|
+
// so there is no peer to answer.
|
|
195
|
+
remote: transport
|
|
196
|
+
? (funcName, data) => transport.remote(funcName, data)
|
|
197
|
+
: unsupportedChannelRemote,
|
|
237
198
|
};
|
|
238
199
|
const userSession = new PikkuSessionService(singletonServices.sessionStore);
|
|
200
|
+
if (session) {
|
|
201
|
+
userSession.setInitial(session);
|
|
202
|
+
}
|
|
239
203
|
const wire = {
|
|
240
204
|
cli: {
|
|
241
205
|
program,
|
|
@@ -259,12 +223,12 @@ export async function runCLICommand({ program, commandPath, data, singletonServi
|
|
|
259
223
|
sessionService: userSession,
|
|
260
224
|
packageName: currentCommand.packageName,
|
|
261
225
|
});
|
|
262
|
-
//
|
|
263
|
-
//
|
|
264
|
-
//
|
|
265
|
-
//
|
|
266
|
-
//
|
|
267
|
-
if (result !== undefined) {
|
|
226
|
+
// knowledge: decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md
|
|
227
|
+
// A void function has already emitted its own output.
|
|
228
|
+
//
|
|
229
|
+
// `onOutput` is progressive output only — the result goes back to the
|
|
230
|
+
// caller, and emitting it here too would deliver it twice.
|
|
231
|
+
if (result !== undefined && !onOutput) {
|
|
268
232
|
const commandRenderer = programData?.renderers[commandId];
|
|
269
233
|
const jsonMode = data.json === true || data.output === 'json';
|
|
270
234
|
const finalRenderer = jsonMode && commandRenderer !== undefined
|
|
@@ -277,28 +241,17 @@ export async function runCLICommand({ program, commandPath, data, singletonServi
|
|
|
277
241
|
return result;
|
|
278
242
|
}
|
|
279
243
|
finally {
|
|
280
|
-
// Close the channel
|
|
281
244
|
channel.close();
|
|
282
245
|
}
|
|
283
246
|
}
|
|
284
|
-
/**
|
|
285
|
-
* Factory function for CLI-specific renderers
|
|
286
|
-
*/
|
|
287
247
|
export const pikkuCLIRender = (renderer) => {
|
|
288
248
|
return renderer;
|
|
289
249
|
};
|
|
290
|
-
/**
|
|
291
|
-
* Execute a CLI program with the given arguments
|
|
292
|
-
* This is the main entry point for CLI programs
|
|
293
|
-
*
|
|
294
|
-
* @throws {CLIError} When CLI execution fails - should be caught by wrapper to call process.exit()
|
|
295
|
-
*/
|
|
296
250
|
export async function executeCLI({ programName, args, createConfig, createSingletonServices, createWireServices, }) {
|
|
297
251
|
if (!args) {
|
|
298
252
|
throw new Error('CLI arguments are required, this is to satisfy release diffs');
|
|
299
253
|
}
|
|
300
254
|
try {
|
|
301
|
-
// Get CLI metadata from state
|
|
302
255
|
const allCLIMeta = pikkuState(null, 'cli', 'meta');
|
|
303
256
|
if (!allCLIMeta) {
|
|
304
257
|
throw new Error('[PKU342] CLI metadata not found. No CLI wirings were registered. See https://pikku.dev/docs/pikku-cli/errors/pku342 for more information.');
|
|
@@ -307,10 +260,8 @@ export async function executeCLI({ programName, args, createConfig, createSingle
|
|
|
307
260
|
if (!programMeta) {
|
|
308
261
|
throw new CLIError(`CLI program "${programName}" not found`, 1);
|
|
309
262
|
}
|
|
310
|
-
// Parse arguments for this specific program
|
|
311
263
|
const parsed = parseCLIArguments(args, programName, allCLIMeta);
|
|
312
|
-
//
|
|
313
|
-
// Show help if --help/-h is present, or if no args AND no default command
|
|
264
|
+
// Parsed first so that `<command> --help` resolves to that command's help.
|
|
314
265
|
const shouldShowHelp = args.includes('--help') ||
|
|
315
266
|
args.includes('-h') ||
|
|
316
267
|
(args.length === 0 && parsed.commandPath.length === 0);
|
|
@@ -319,37 +270,30 @@ export async function executeCLI({ programName, args, createConfig, createSingle
|
|
|
319
270
|
console.log(helpText);
|
|
320
271
|
return;
|
|
321
272
|
}
|
|
322
|
-
//
|
|
323
|
-
// so they never pollute a command's machine-readable stdout.
|
|
273
|
+
// knowledge: decisions/internals/cli-stdout-is-reserved-for-machine-readable-output.md
|
|
324
274
|
parsed.warnings.forEach((warning) => console.error(`Warning: ${warning}`));
|
|
325
275
|
if (parsed.errors.length > 0) {
|
|
326
|
-
//
|
|
276
|
+
// knowledge: decisions/internals/cli-parse-errors-are-routed-by-message-prefix.md
|
|
327
277
|
const hasUnknownCommand = parsed.errors.some((error) => error.startsWith('Unknown command:') ||
|
|
328
278
|
error.startsWith('Command not found:') ||
|
|
329
279
|
error.startsWith('Missing subcommand:'));
|
|
330
280
|
if (hasUnknownCommand) {
|
|
331
|
-
// Show help instead of error for unknown commands
|
|
332
281
|
const helpText = generateCommandHelp(programName, allCLIMeta, parsed.commandPath);
|
|
333
282
|
console.log(helpText);
|
|
334
283
|
throw new CLIError('Unknown command', 1);
|
|
335
284
|
}
|
|
336
285
|
else {
|
|
337
|
-
// Show errors for other types of errors
|
|
338
286
|
console.error('Errors:');
|
|
339
287
|
parsed.errors.forEach((error) => console.error(` ${error}`));
|
|
340
288
|
throw new CLIError(parsed.errors.join('\n'), 1);
|
|
341
289
|
}
|
|
342
290
|
}
|
|
343
|
-
// Merge positionals and options into single data object
|
|
344
291
|
const data = { ...parsed.positionals, ...parsed.options };
|
|
345
|
-
// Create config (pass data in case it needs to use any parsed options)
|
|
346
292
|
const config = createConfig
|
|
347
293
|
? await createConfig(new LocalVariablesService(), data)
|
|
348
294
|
: {};
|
|
349
|
-
// Create services with config and register in global state
|
|
350
295
|
const singletonServices = await createSingletonServices(config);
|
|
351
296
|
pikkuState(null, 'package', 'singletonServices', singletonServices);
|
|
352
|
-
// Execute the command
|
|
353
297
|
await runCLICommand({
|
|
354
298
|
program: programName,
|
|
355
299
|
commandPath: parsed.commandPath,
|
|
@@ -359,21 +303,16 @@ export async function executeCLI({ programName, args, createConfig, createSingle
|
|
|
359
303
|
});
|
|
360
304
|
}
|
|
361
305
|
catch (error) {
|
|
362
|
-
// Re-throw CLIError as-is
|
|
363
306
|
if (error instanceof CLIError) {
|
|
364
307
|
throw error;
|
|
365
308
|
}
|
|
366
|
-
// An expected
|
|
367
|
-
// tripping) — its message says everything, so print that alone (no
|
|
368
|
-
// `Error:` prefix). Anything else is an uncaught error: log the object so
|
|
369
|
-
// its stack shows.
|
|
309
|
+
// An expected PikkuError's message is written to be the whole output.
|
|
370
310
|
if (isExpectedError(error)) {
|
|
371
311
|
console.error(error.message);
|
|
372
312
|
}
|
|
373
313
|
else {
|
|
374
314
|
console.error('Error:', error);
|
|
375
315
|
}
|
|
376
|
-
// Show stack trace in verbose mode (even for expected errors).
|
|
377
316
|
if (args.includes('--verbose') || args.includes('-v')) {
|
|
378
317
|
console.error('Stack trace:', error.stack);
|
|
379
318
|
}
|