@pikku/cli 0.12.93 → 0.12.99
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/console-app/assets/abnfDiagram-VRR7QNED-CytV-CG1.js +1 -0
- package/console-app/assets/arc-C5PvmnaA.js +1 -0
- package/console-app/assets/architecture-TIHT7OUA-C1_ScvPX.js +1 -0
- package/console-app/assets/architectureDiagram-ZJ3FMSHR-CJ2xb7C-.js +36 -0
- package/console-app/assets/array-BifhSqXX.js +1 -0
- package/console-app/assets/blockDiagram-677ZJIJ3-CCecrBrk.js +132 -0
- package/console-app/assets/c4Diagram-LMCZKHZV-CBnpukvQ.js +10 -0
- package/console-app/assets/channel-CwDOkXGI.js +1 -0
- package/console-app/assets/chunk-2Q5K7J3B-C1jixKkw.js +1 -0
- package/console-app/assets/chunk-32BRIVSS-D8qWWZRQ.js +1 -0
- package/console-app/assets/chunk-52WLFC77-BEpXHMsp.js +10 -0
- package/console-app/assets/chunk-5VM5RSS4-ZNzvKenW.js +15 -0
- package/console-app/assets/chunk-7BUUIJ7U-Bb538aSH.js +1 -0
- package/console-app/assets/chunk-C7G6YPKG-DsHUMkOp.js +1 -0
- package/console-app/assets/chunk-EX3LRPZG-mM7TjVx9.js +231 -0
- package/console-app/assets/chunk-FWX5IMBZ-CndRAn18.js +2 -0
- package/console-app/assets/chunk-HOUHSVGY-D1kT8umn.js +1 -0
- package/console-app/assets/chunk-ICXQ74PX-CeSaGyro.js +2 -0
- package/console-app/assets/chunk-JWPE2WC7-DVXcaiue.js +1 -0
- package/console-app/assets/chunk-KEIR6QF5-DNzq6p3w.js +161 -0
- package/console-app/assets/chunk-MOJQB5TN-CaZOCHYr.js +88 -0
- package/console-app/assets/chunk-OGEWGWER-CnB1CsPt.js +1 -0
- package/console-app/assets/chunk-PUDLZKDR-BbGulHJm.js +156 -0
- package/console-app/assets/chunk-Q4XR5HBZ-BywwzeeR.js +70 -0
- package/console-app/assets/chunk-RYQCIY6F-CV0R1Adv.js +1 -0
- package/console-app/assets/chunk-V7JOEXUC-DGFaAWzB.js +206 -0
- package/console-app/assets/chunk-VAUOI2AC-DxPUd8Yb.js +1 -0
- package/console-app/assets/chunk-VR4S4FIN-D4-UaW_J.js +1 -0
- package/console-app/assets/chunk-WYO6CB5R-D_TFN0d9.js +127 -0
- package/console-app/assets/chunk-XXDRQBXY-BzVuweA_.js +1 -0
- package/console-app/assets/chunk-Y2CYZVJY-DsF7k-Jl.js +1 -0
- package/console-app/assets/chunk-ZGVPDNZ5-C6hdkGQb.js +62 -0
- package/console-app/assets/chunk-ZIRB5QZD-H-kepumB.js +32 -0
- package/console-app/assets/classDiagram-OUVF2IWQ-CTYJkTT0.js +1 -0
- package/console-app/assets/classDiagram-v2-EOCWNBFH-CTYJkTT0.js +1 -0
- package/console-app/assets/cose-bilkent-JH36ORCC-B6ZPxN6v.js +1 -0
- package/console-app/assets/cynefin-VYW2F7L2-D_nmxNz_.js +1 -0
- package/console-app/assets/cynefinDiagram-TSTJHNR4-CHy5QN0S.js +62 -0
- package/console-app/assets/cytoscape.esm-h6BdjjI9.js +321 -0
- package/console-app/assets/dagre-CXRCoUWR.js +1 -0
- package/console-app/assets/dagre-VKFMJZFB-DYfukM34.js +4 -0
- package/console-app/assets/defaultLocale-C8Fc0cco.js +1 -0
- package/console-app/assets/diagram-FQU43EPY-Dgb9TPSB.js +3 -0
- package/console-app/assets/diagram-G47NLZAW-CnFNZs9Z.js +24 -0
- package/console-app/assets/diagram-NH7WQ7WH-DN7h2DU-.js +24 -0
- package/console-app/assets/diagram-OA4YK3LP-RLaQaNtK.js +30 -0
- package/console-app/assets/diagram-WEI45ONY-DxHWhVGd.js +41 -0
- package/console-app/assets/dist-BaJNIo4I.js +1 -0
- package/console-app/assets/ebnfDiagram-CCIWWBDH-UN3Z81-l.js +1 -0
- package/console-app/assets/erDiagram-Q63AITRT-C9lGAY3i.js +85 -0
- package/console-app/assets/eventmodeling-45OFAUF4-Dc5wNSSK.js +1 -0
- package/console-app/assets/flowDiagram-23GEKE2U-zPyGHMi4.js +1 -0
- package/console-app/assets/ganttDiagram-NO4QXBWP-CvBjBcdK.js +292 -0
- package/console-app/assets/gitGraph-TEB2WS4Q-Cs5Z9jMo.js +1 -0
- package/console-app/assets/gitGraphDiagram-IHSO6WYX-B0i_IJ5r.js +106 -0
- package/console-app/assets/graphlib-B8gBHxth.js +1 -0
- package/console-app/assets/{index-CmAplHjZ.js → index-71U8EEj7.js} +155 -153
- package/console-app/assets/{index-BYj7ZbUU.css → index-BXMjqLQ5.css} +1 -1
- package/console-app/assets/info-DKCQHKI2-DHL0afNl.js +1 -0
- package/console-app/assets/infoDiagram-FWYZ7A6U-CBWykodX.js +2 -0
- package/console-app/assets/init-D6jRqBbL.js +1 -0
- package/console-app/assets/ishikawaDiagram-FXEZZL3T-DM377eW_.js +70 -0
- package/console-app/assets/journeyDiagram-5HDEW3XC-BpX_-Cns.js +139 -0
- package/console-app/assets/kanban-definition-HUTT4EX6-D3xFsQkO.js +89 -0
- package/console-app/assets/katex-Vhh-h91d.js +257 -0
- package/console-app/assets/line-CTSKHTE0.js +1 -0
- package/console-app/assets/linear-R5GlBvXT.js +1 -0
- package/console-app/assets/map-DsCK-0Cs.js +1 -0
- package/console-app/assets/mermaid-parser.core-CkHk4BPi.js +7 -0
- package/console-app/assets/mermaid.core-CcjGXuV6.js +11 -0
- package/console-app/assets/mindmap-definition-LN4V7U3C-CtolazqQ.js +96 -0
- package/console-app/assets/ordinal-hYBb2elL.js +1 -0
- package/console-app/assets/packet-7NZHBO7P-BxSOj_Ny.js +1 -0
- package/console-app/assets/path-BWPyau1x.js +1 -0
- package/console-app/assets/pegDiagram-2B236MQR-BNsMtxsM.js +1 -0
- package/console-app/assets/pie-RZYD4A2V-BbkKQBA5.js +1 -0
- package/console-app/assets/pieDiagram-ENE6RG2P-BAZLIz2f.js +39 -0
- package/console-app/assets/quadrantDiagram-ABIIQ3AL-Dpvn-1Fs.js +7 -0
- package/console-app/assets/radar-I7S5WNFK-B-uKXIAH.js +1 -0
- package/console-app/assets/railroad-3IZDKUUU-BHXXK04t.js +1 -0
- package/console-app/assets/railroad-abnf-AHOZXSZD-tXSQaBvY.js +1 -0
- package/console-app/assets/railroad-ebnf-EBAXGLYW-DG3aohR0.js +1 -0
- package/console-app/assets/railroad-peg-LSFZ7HO6-DY_gBA-x.js +1 -0
- package/console-app/assets/railroadDiagram-RFXS5EU6-DfUApEQj.js +1 -0
- package/console-app/assets/requirementDiagram-TGXJPOKE-B2zX0jqo.js +84 -0
- package/console-app/assets/rough.esm-CSKSodPl.js +1 -0
- package/console-app/assets/sankeyDiagram-HTMAVEWB-CbQ2zc7z.js +40 -0
- package/console-app/assets/sequenceDiagram-DBY2YBRQ-BLT8PXI_.js +162 -0
- package/console-app/assets/sizeCapture-X5ZJPWSS-B0uUizjq.js +1 -0
- package/console-app/assets/src-BLuPUFWW.js +1 -0
- package/console-app/assets/stateDiagram-2N3HPSRC-BvEyVp85.js +1 -0
- package/console-app/assets/stateDiagram-v2-6OUMAXLB-RGKS9iU4.js +1 -0
- package/console-app/assets/swimlanes-5IMT3BWC-1AZ459s6.js +2 -0
- package/console-app/assets/swimlanesDiagram-G3AALYLV-Ck_0-rfN.js +8 -0
- package/console-app/assets/timeline-definition-FHXFAJF6-dLuvH4s2.js +120 -0
- package/console-app/assets/treeView-QDETBFTQ-xL2msjo2.js +1 -0
- package/console-app/assets/treemap-6X3UGDF4-C98ichVP.js +1 -0
- package/console-app/assets/vennDiagram-L72KCM5P-HbUmidhv.js +34 -0
- package/console-app/assets/wardley-OPB4EBWU-C4gJS-m2.js +1 -0
- package/console-app/assets/wardleyDiagram-EHGQE667-B7b-LB02.js +78 -0
- package/console-app/assets/xychartDiagram-FW5EYKEG-Cm03zUGy.js +7 -0
- package/console-app/index.html +2 -2
- package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
- package/dist/.pikku/auth/auth.types.d.ts +1 -1
- package/dist/.pikku/auth/auth.types.js +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
- package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-channel.d.ts +13 -15
- package/dist/.pikku/cli/pikku-cli-channel.js +62 -8
- package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +14 -4
- package/dist/.pikku/cli/pikku-cli-client.gen.js +55 -18
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +136 -10
- package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
- package/dist/.pikku/cli/pikku-cli.gen.js +18 -2
- package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
- package/dist/.pikku/function/pikku-function-types.gen.d.ts +64 -23
- package/dist/.pikku/function/pikku-function-types.gen.js +27 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
- package/dist/.pikku/function/pikku-functions-meta.gen.json +171 -37
- package/dist/.pikku/function/pikku-functions.gen.js +13 -3
- package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
- package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
- package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
- package/dist/.pikku/pikku-bootstrap-scenarios.gen.d.ts +1 -1
- package/dist/.pikku/pikku-bootstrap-scenarios.gen.js +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
- package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
- package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
- package/dist/.pikku/pikku-meta-service.gen.js +1 -1
- package/dist/.pikku/pikku-services.gen.d.ts +2 -1
- package/dist/.pikku/pikku-services.gen.js +1 -0
- package/dist/.pikku/pikku-types.gen.d.ts +1 -1
- package/dist/.pikku/pikku-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
- package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
- package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +8 -1
- package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.js +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-functions.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +1 -1
- package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/schemas/register.gen.d.ts +1 -1
- package/dist/.pikku/scenarios/schemas/register.gen.js +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
- package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
- package/dist/.pikku/schemas/register.gen.js +15 -5
- package/dist/.pikku/schemas/schemas/DbResetInput.schema.json +1 -1
- package/dist/.pikku/schemas/schemas/PersonaRunInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PersonaSyncInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuPersonasInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuRolesInput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/PikkuVirtualUserFunctionsOutput.schema.json +1 -0
- package/dist/.pikku/schemas/schemas/RolesPruneInput.schema.json +1 -0
- package/dist/.pikku/scopes/pikku-personas-meta.gen.json +1 -0
- package/dist/.pikku/scopes/pikku-personas.gen.d.ts +36 -0
- package/dist/.pikku/scopes/pikku-personas.gen.js +17 -0
- package/dist/.pikku/scopes/pikku-roles-meta.gen.json +1 -0
- package/dist/.pikku/scopes/pikku-roles.gen.d.ts +30 -0
- package/dist/.pikku/scopes/pikku-roles.gen.js +18 -0
- package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +4 -2
- package/dist/.pikku/scopes/pikku-scope-types.gen.js +3 -2
- package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +2 -2
- package/dist/.pikku/secrets/pikku-secret-types.gen.js +2 -2
- package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
- package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
- package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
- package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +2 -2
- package/dist/.pikku/variables/pikku-variable-types.gen.js +2 -2
- package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
- package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
- package/dist/.pikku/workflow/meta/allWorkflow.gen.json +46 -16
- package/dist/.pikku/workflow/pikku-personas.gen.d.ts +15 -0
- package/dist/.pikku/workflow/pikku-personas.gen.js +17 -0
- package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +101 -24
- package/dist/.pikku/workflow/pikku-workflow-types.gen.js +22 -2
- package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
- package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
- package/dist/bin/pikku-bin.mjs +2 -2
- package/dist/bin/pikku.js +0 -0
- package/dist/src/cli.wiring.js +108 -8
- package/dist/src/deploy/analyzer/analyzer.js +14 -0
- package/dist/src/deploy/analyzer/manifest.d.ts +11 -0
- package/dist/src/fabric/functions/validate.function.js +77 -177
- package/dist/src/functions/commands/all.d.ts +1 -1
- package/dist/src/functions/commands/bootstrap.d.ts +1 -1
- package/dist/src/functions/commands/bootstrap.js +3 -0
- package/dist/src/functions/commands/db-audit.js +1 -1
- package/dist/src/functions/commands/db-baseline.js +1 -1
- package/dist/src/functions/commands/db-check.js +6 -5
- package/dist/src/functions/commands/db-codegen.js +1 -1
- package/dist/src/functions/commands/db-generate.js +1 -1
- package/dist/src/functions/commands/db-migrate.js +1 -1
- package/dist/src/functions/commands/db-reset.d.ts +15 -1
- package/dist/src/functions/commands/db-reset.js +18 -6
- package/dist/src/functions/commands/db-shared.d.ts +14 -0
- package/dist/src/functions/commands/deploy-info.d.ts +1 -1
- package/dist/src/functions/commands/dev-ai-runner.d.ts +16 -4
- package/dist/src/functions/commands/dev-ai-runner.js +63 -29
- package/dist/src/functions/commands/dev.js +10 -5
- package/dist/src/functions/commands/enable.d.ts +8 -8
- package/dist/src/functions/commands/enable.js +15 -19
- package/dist/src/functions/commands/{scenario-environment.d.ts → environment.d.ts} +9 -6
- package/dist/src/functions/commands/{scenario-environment.js → environment.js} +5 -4
- package/dist/src/functions/commands/new-addon.js +14 -14
- package/dist/src/functions/commands/persona-sync.d.ts +33 -0
- package/dist/src/functions/commands/persona-sync.js +151 -0
- package/dist/src/functions/commands/persona.d.ts +58 -0
- package/dist/src/functions/commands/persona.js +215 -0
- package/dist/src/functions/commands/roles-audit.d.ts +1 -0
- package/dist/src/functions/commands/roles-audit.js +37 -0
- package/dist/src/functions/commands/roles-prune.d.ts +16 -0
- package/dist/src/functions/commands/roles-prune.js +52 -0
- package/dist/src/functions/commands/roles-shared.d.ts +40 -0
- package/dist/src/functions/commands/roles-shared.js +77 -0
- package/dist/src/functions/commands/scenario-browser.d.ts +3 -3
- package/dist/src/functions/commands/scenario-browser.js +1 -1
- package/dist/src/functions/commands/scenario-ladder.d.ts +44 -2
- package/dist/src/functions/commands/scenario-ladder.js +52 -3
- package/dist/src/functions/commands/scenario.d.ts +7 -0
- package/dist/src/functions/commands/scenario.js +82 -18
- package/dist/src/functions/commands/scopes-shared.d.ts +12 -0
- package/dist/src/functions/commands/scopes-shared.js +2 -2
- package/dist/src/functions/commands/serve.js +8 -4
- package/dist/src/functions/commands/versions-check.js +3 -3
- package/dist/src/functions/commands/virtual-user-formatter.d.ts +30 -0
- package/dist/src/functions/commands/virtual-user-formatter.js +65 -0
- package/dist/src/functions/db/annotation-parser.d.ts +14 -0
- package/dist/src/functions/db/annotation-parser.js +50 -2
- package/dist/src/functions/db/better-auth-schema.js +2 -1
- package/dist/src/functions/db/db-codegen.d.ts +12 -0
- package/dist/src/functions/db/db-codegen.js +149 -16
- package/dist/src/functions/db/local-db.d.ts +87 -6
- package/dist/src/functions/db/local-db.js +239 -35
- package/dist/src/functions/db/sqlite/dev-seed.d.ts +12 -0
- package/dist/src/functions/db/sqlite/dev-seed.js +23 -0
- package/dist/src/functions/db/sqlite/sqlite-runtime-bun.js +1 -1
- package/dist/src/functions/validate/bootstrap-checks.d.ts +19 -0
- package/dist/src/functions/validate/bootstrap-checks.js +90 -0
- package/dist/src/functions/validate/persona-checks.d.ts +24 -0
- package/dist/src/functions/validate/persona-checks.js +136 -0
- package/dist/src/functions/validate/scenario-file-checks.d.ts +17 -0
- package/dist/src/functions/validate/scenario-file-checks.js +123 -0
- package/dist/src/functions/validate/shared-checks.d.ts +59 -0
- package/dist/src/functions/validate/shared-checks.js +311 -0
- package/dist/src/functions/validate/workspace-validate.d.ts +1 -2
- package/dist/src/functions/validate/workspace-validate.js +4 -196
- package/dist/src/functions/wirings/ai-agent/pikku-command-public-agent.js +2 -1
- package/dist/src/functions/wirings/ai-agent/serialize-public-agent.js +1 -0
- package/dist/src/functions/wirings/auth/serialize-auth-gen.d.ts +2 -2
- package/dist/src/functions/wirings/auth/serialize-auth-gen.js +24 -9
- package/dist/src/functions/wirings/auth/serialize-auth-types.d.ts +3 -1
- package/dist/src/functions/wirings/auth/serialize-auth-types.js +3 -1
- package/dist/src/functions/wirings/channels/pikku-channels.d.ts +1 -1
- package/dist/src/functions/wirings/channels/serialize-typed-channel-map.js +10 -2
- package/dist/src/functions/wirings/cli/pikku-command-cli-entry.js +9 -4
- package/dist/src/functions/wirings/cli/serialize-channel-cli-client.d.ts +7 -3
- package/dist/src/functions/wirings/cli/serialize-channel-cli-client.js +64 -28
- package/dist/src/functions/wirings/cli/serialize-channel-cli.js +63 -6
- package/dist/src/functions/wirings/cli/serialize-cli-entrypoint-guard.d.ts +12 -0
- package/dist/src/functions/wirings/cli/serialize-cli-entrypoint-guard.js +28 -0
- package/dist/src/functions/wirings/cli/serialize-local-cli-bootstrap.js +4 -1
- package/dist/src/functions/wirings/console/serialize-console-functions.js +5 -8
- package/dist/src/functions/wirings/functions/serialize-addon-types.js +1 -1
- package/dist/src/functions/wirings/functions/serialize-function-types.js +106 -32
- package/dist/src/functions/wirings/middleware/serialize-middleware-imports.js +25 -9
- package/dist/src/functions/wirings/package/pikku-command-package-types.d.ts +3 -3
- package/dist/src/functions/wirings/package/serialize-package-types.js +5 -3
- package/dist/src/functions/wirings/personas/personas-secrets-file.d.ts +8 -0
- package/dist/src/functions/wirings/personas/personas-secrets-file.js +9 -0
- package/dist/src/functions/wirings/personas/pikku-command-personas.d.ts +7 -0
- package/dist/src/functions/wirings/personas/pikku-command-personas.js +57 -0
- package/dist/src/functions/wirings/personas/serialize-personas-secrets.d.ts +16 -0
- package/dist/src/functions/wirings/personas/serialize-personas-secrets.js +34 -0
- package/dist/src/functions/wirings/personas/serialize-personas-types.d.ts +18 -0
- package/dist/src/functions/wirings/personas/serialize-personas-types.js +76 -0
- package/dist/src/functions/wirings/queue/serialize-queue-map.js +2 -1
- package/dist/src/functions/wirings/queue/serialize-queue-wrapper.js +2 -1
- package/dist/src/functions/wirings/realtime/pikku-command-events-scaffold.js +2 -1
- package/dist/src/functions/wirings/roles/pikku-command-roles.d.ts +7 -0
- package/dist/src/functions/wirings/roles/pikku-command-roles.js +33 -0
- package/dist/src/functions/wirings/roles/serialize-roles-types.d.ts +14 -0
- package/dist/src/functions/wirings/roles/serialize-roles-types.js +55 -0
- package/dist/src/functions/wirings/rpc/pikku-command-public-rpc.js +2 -1
- package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.d.ts +3 -3
- package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.js +3 -3
- package/dist/src/functions/wirings/scopes/serialize-scopes-types.d.ts +1 -1
- package/dist/src/functions/wirings/scopes/serialize-scopes-types.js +1 -1
- package/dist/src/functions/wirings/user-admin/pikku-command-user-admin-functions.js +2 -1
- package/dist/src/functions/wirings/user-admin/serialize-user-admin-functions.js +2 -2
- package/dist/src/functions/wirings/virtual-user/pikku-command-virtual-user-functions.d.ts +1 -0
- package/dist/src/functions/wirings/virtual-user/pikku-command-virtual-user-functions.js +42 -0
- package/dist/src/functions/wirings/virtual-user/serialize-virtual-user-functions.d.ts +28 -0
- package/dist/src/functions/wirings/virtual-user/serialize-virtual-user-functions.js +439 -0
- package/dist/src/functions/wirings/workflow/pikku-command-workflow-routes.js +2 -1
- package/dist/src/functions/wirings/workflow/pikku-command-workflow.js +13 -13
- package/dist/src/functions/wirings/workflow/serialize-personas.d.ts +10 -0
- package/dist/src/functions/wirings/workflow/serialize-personas.js +46 -0
- package/dist/src/functions/wirings/workflow/serialize-scenario-step-map.js +13 -4
- package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +170 -40
- package/dist/src/functions/workflows/all.workflow.js +55 -16
- package/dist/src/server/bun-server-runner.d.ts +2 -2
- package/dist/src/server/bun-server-runner.js +5 -1
- package/dist/src/server/content-signing-jwt.d.ts +13 -0
- package/dist/src/server/content-signing-jwt.js +51 -0
- package/dist/src/server/dev-server-runner.interface.d.ts +10 -2
- package/dist/src/server/node-server-runner.d.ts +2 -2
- package/dist/src/server/node-server-runner.js +2 -1
- package/dist/src/services/cli-logger.service.d.ts +28 -16
- package/dist/src/services/cli-logger.service.js +25 -16
- package/dist/src/services.d.ts +3 -1
- package/dist/src/services.js +10 -1
- package/dist/src/utils/file-import-path.js +9 -0
- package/dist/src/utils/pikku-cli-config.js +52 -2
- package/dist/src/utils/resolve-personas.d.ts +27 -0
- package/dist/src/utils/resolve-personas.js +35 -0
- package/dist/src/utils/resolve-scaffold-feature.d.ts +19 -0
- package/dist/src/utils/resolve-scaffold-feature.js +49 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +20 -17
- package/dist/.pikku/schemas/schemas/BootstrapInput.schema.json +0 -1
- package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +0 -1
- package/dist/.pikku/schemas/schemas/ScenarioRunInput.schema.json +0 -1
- package/dist/.pikku/workflow/pikku-scenario-actors.gen.d.ts +0 -19
- package/dist/.pikku/workflow/pikku-scenario-actors.gen.js +0 -17
- package/dist/src/functions/commands/db-seed.d.ts +0 -1
- package/dist/src/functions/commands/db-seed.js +0 -24
- package/dist/src/functions/db/sqlite/seed.d.ts +0 -11
- package/dist/src/functions/db/sqlite/seed.js +0 -22
- package/dist/src/functions/wirings/workflow/serialize-scenario-actors.d.ts +0 -2
- package/dist/src/functions/wirings/workflow/serialize-scenario-actors.js +0 -40
- package/dist/src/utils/resolve-scenario-actors.d.ts +0 -23
- package/dist/src/utils/resolve-scenario-actors.js +0 -74
- /package/dist/.pikku/schemas/schemas/{DbSeedInput.schema.json → RolesAuditInput.schema.json} +0 -0
|
@@ -0,0 +1,439 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate the virtual-user functions into the project scaffold: start a run,
|
|
3
|
+
* read one back, and the sessionless function that does the work.
|
|
4
|
+
*
|
|
5
|
+
* Scaffolded rather than shipped in an addon because the whole feature is
|
|
6
|
+
* derived from what the project already generates — its personas, its function
|
|
7
|
+
* meta, its scenarios — so there is nothing to configure and nothing to author.
|
|
8
|
+
* `pikku persona run` does the same thing from a terminal; this is the same run
|
|
9
|
+
* started over RPC, from CI or from a console, with the result kept.
|
|
10
|
+
*
|
|
11
|
+
* A virtual user is NOT a workflow and NOT a queued job. It explores, so no two
|
|
12
|
+
* attempts take the same steps and there is nothing to replay; and the run
|
|
13
|
+
* record already carries the progress a queue would only be holding on the way
|
|
14
|
+
* here. So `runVirtualUser` writes the record, kicks the run off without
|
|
15
|
+
* awaiting it, and returns the id. The one cost is stated on the record: a
|
|
16
|
+
* restart mid-run strands it at `running`.
|
|
17
|
+
*
|
|
18
|
+
* Emitted as two files. The schemas are zod, and the inspector reads a zod
|
|
19
|
+
* schema by importing the module that declares it — which it cannot do for the
|
|
20
|
+
* functions file, whose relative pikku-types import per-unit deploy codegen
|
|
21
|
+
* rewrites. Keeping the schemas in a sibling module that imports nothing but
|
|
22
|
+
* zod sidesteps that entirely.
|
|
23
|
+
*/
|
|
24
|
+
export const serializeVirtualUserFunctions = (pathToPikkuTypes, pathToPersonas, requireAuth = true) => {
|
|
25
|
+
const authFlag = requireAuth ? 'true' : 'false';
|
|
26
|
+
const schemas = `/**
|
|
27
|
+
* Auto-generated virtual user schemas
|
|
28
|
+
* Do not edit manually - regenerate with 'npx pikku'
|
|
29
|
+
*/
|
|
30
|
+
import { z } from 'zod'
|
|
31
|
+
|
|
32
|
+
/** Every disposition \`DISPOSITIONS\` declares. */
|
|
33
|
+
export const Disposition = z.enum([
|
|
34
|
+
'realistic',
|
|
35
|
+
'careless',
|
|
36
|
+
'newcomer',
|
|
37
|
+
'stale',
|
|
38
|
+
'auditor',
|
|
39
|
+
'adversarial',
|
|
40
|
+
'accountable',
|
|
41
|
+
])
|
|
42
|
+
|
|
43
|
+
export const RunVirtualUserInput = z.object({
|
|
44
|
+
/** A persona id from \`definePersonas()\`. */
|
|
45
|
+
persona: z.string().min(1),
|
|
46
|
+
/**
|
|
47
|
+
* Situational goals in the caller's own words, run alongside the intents
|
|
48
|
+
* derived from the app's scenarios. Appended to what the persona durably
|
|
49
|
+
* wants, never a replacement — a run that replaces their goals is not them.
|
|
50
|
+
*/
|
|
51
|
+
goals: z.array(z.string().min(1)).max(20).optional(),
|
|
52
|
+
/**
|
|
53
|
+
* Ids and slugs from an earlier run, replayed as this user's notes on turn
|
|
54
|
+
* one. The point of a \`stale\` run: some of them no longer resolve, and what
|
|
55
|
+
* the product does about that is the thing being tested.
|
|
56
|
+
*/
|
|
57
|
+
memory: z.record(z.string(), z.string()).optional(),
|
|
58
|
+
/** Overrides the persona's declared disposition for this run only. */
|
|
59
|
+
disposition: Disposition.optional(),
|
|
60
|
+
budget: z
|
|
61
|
+
.object({
|
|
62
|
+
steps: z.number().int().min(1).max(500).optional(),
|
|
63
|
+
mutations: z.number().int().min(0).max(500).optional(),
|
|
64
|
+
durationMs: z.number().int().min(1000).max(3_600_000).optional(),
|
|
65
|
+
})
|
|
66
|
+
.optional(),
|
|
67
|
+
/** Fixed seed, so a run replays into the same finding. */
|
|
68
|
+
seed: z.number().int().optional(),
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
export const RunVirtualUserOutput = z.object({
|
|
72
|
+
runId: z.string(),
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
export const GetVirtualUserRunInput = z.object({
|
|
76
|
+
runId: z.string(),
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* What the user noticed. \`kind\` is a plain string rather than an enum of
|
|
81
|
+
* today's finding kinds: a run that turns up something new should be readable
|
|
82
|
+
* by a client built before that kind existed.
|
|
83
|
+
*/
|
|
84
|
+
export const Finding = z.object({
|
|
85
|
+
kind: z.string(),
|
|
86
|
+
detail: z.string(),
|
|
87
|
+
rpcName: z.string().optional(),
|
|
88
|
+
status: z.number().optional(),
|
|
89
|
+
intentId: z.string().optional(),
|
|
90
|
+
/** Step index within the run, so the transcript can be replayed to here. */
|
|
91
|
+
step: z.number(),
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
export const GetVirtualUserRunOutput = z.object({
|
|
95
|
+
runId: z.string(),
|
|
96
|
+
persona: z.string(),
|
|
97
|
+
disposition: Disposition,
|
|
98
|
+
seed: z.number(),
|
|
99
|
+
status: z.enum(['running', 'completed', 'failed']),
|
|
100
|
+
goals: z.array(z.string()),
|
|
101
|
+
memory: z.record(z.string(), z.string()),
|
|
102
|
+
findings: z.array(Finding),
|
|
103
|
+
/** Steps, calls, mutations, tokens and elapsed time, as the engine counted them. */
|
|
104
|
+
tally: z.record(z.string(), z.unknown()).nullable(),
|
|
105
|
+
stoppedBy: z.string().nullable(),
|
|
106
|
+
error: z.string().nullable(),
|
|
107
|
+
createdAt: z.string(),
|
|
108
|
+
finishedAt: z.string().nullable(),
|
|
109
|
+
})
|
|
110
|
+
|
|
111
|
+
/** The internal dispatch payload — everything the run was resolved down to. */
|
|
112
|
+
export const ExecuteVirtualUserRunInput = z.object({
|
|
113
|
+
runId: z.string(),
|
|
114
|
+
persona: z.string(),
|
|
115
|
+
disposition: Disposition,
|
|
116
|
+
goals: z.array(z.string()),
|
|
117
|
+
memory: z.record(z.string(), z.string()),
|
|
118
|
+
budget: z
|
|
119
|
+
.object({
|
|
120
|
+
steps: z.number().optional(),
|
|
121
|
+
mutations: z.number().optional(),
|
|
122
|
+
durationMs: z.number().optional(),
|
|
123
|
+
})
|
|
124
|
+
.optional(),
|
|
125
|
+
seed: z.number(),
|
|
126
|
+
})
|
|
127
|
+
|
|
128
|
+
export const ExecuteVirtualUserRunOutput = z.object({
|
|
129
|
+
findings: z.number(),
|
|
130
|
+
})
|
|
131
|
+
`;
|
|
132
|
+
const functions = `/**
|
|
133
|
+
* Auto-generated virtual user functions
|
|
134
|
+
* Do not edit manually - regenerate with 'npx pikku'
|
|
135
|
+
*/
|
|
136
|
+
import { pikkuFunc, pikkuSessionlessFunc, defineScope } from '${pathToPikkuTypes}'
|
|
137
|
+
import {
|
|
138
|
+
personaVirtualUserTarget,
|
|
139
|
+
prepareVirtualUserRun,
|
|
140
|
+
runVirtualUser as runVirtualUserEngine,
|
|
141
|
+
PRODUCTION_DISPOSITION,
|
|
142
|
+
type SchemaMap,
|
|
143
|
+
type VirtualUserDisposition,
|
|
144
|
+
} from '@pikku/core/virtual-user'
|
|
145
|
+
import { createPersonas, personaConfigs } from '${pathToPersonas}'
|
|
146
|
+
import {
|
|
147
|
+
ExecuteVirtualUserRunInput,
|
|
148
|
+
ExecuteVirtualUserRunOutput,
|
|
149
|
+
GetVirtualUserRunInput,
|
|
150
|
+
GetVirtualUserRunOutput,
|
|
151
|
+
RunVirtualUserInput,
|
|
152
|
+
RunVirtualUserOutput,
|
|
153
|
+
} from './virtual-user.schemas.gen.js'
|
|
154
|
+
|
|
155
|
+
defineScope({
|
|
156
|
+
virtualUser: {
|
|
157
|
+
displayName: 'Virtual Users',
|
|
158
|
+
description: 'Run personas against this application and read what they found',
|
|
159
|
+
scopes: {
|
|
160
|
+
run: { description: 'Start a virtual user run' },
|
|
161
|
+
read: { description: "Read a run's findings" },
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Where the virtual user signs in. Its own variable rather than a guess at the
|
|
168
|
+
* host's origin: a run drives real traffic through the real front door, and a
|
|
169
|
+
* server that cannot name its own public URL would be signing in somewhere it
|
|
170
|
+
* only assumed was itself.
|
|
171
|
+
*/
|
|
172
|
+
const API_URL_VARIABLE = 'VIRTUAL_USER_API_URL'
|
|
173
|
+
const SECRET_VARIABLE = 'SCENARIO_ACTOR_SECRET'
|
|
174
|
+
const MODEL_VARIABLE = 'VIRTUAL_USER_MODEL'
|
|
175
|
+
|
|
176
|
+
export const runVirtualUser = pikkuFunc({
|
|
177
|
+
tags: ['pikku'],
|
|
178
|
+
title: 'Run a Virtual User',
|
|
179
|
+
description:
|
|
180
|
+
'Turns a declared persona loose on this application and records what it finds. Returns immediately with a run id; read the result back with getVirtualUserRun.',
|
|
181
|
+
expose: true,
|
|
182
|
+
auth: ${authFlag},
|
|
183
|
+
scopes: ['virtualUser:run'],
|
|
184
|
+
input: RunVirtualUserInput,
|
|
185
|
+
output: RunVirtualUserOutput,
|
|
186
|
+
func: async (
|
|
187
|
+
{ virtualUserRunStore, config },
|
|
188
|
+
input,
|
|
189
|
+
{ session, rpc }
|
|
190
|
+
) => {
|
|
191
|
+
if (!virtualUserRunStore) {
|
|
192
|
+
throw new Error(
|
|
193
|
+
'No virtualUserRunStore is wired — a run has nowhere to be recorded. ' +
|
|
194
|
+
'Wire KyselyVirtualUserRunStore from @pikku/kysely, or your own implementation of VirtualUserRunStore.'
|
|
195
|
+
)
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
const persona = personaConfigs[input.persona as keyof typeof personaConfigs] as
|
|
199
|
+
| { id: string; runnable: boolean; disposition?: string }
|
|
200
|
+
| undefined
|
|
201
|
+
if (!persona) {
|
|
202
|
+
throw new Error(
|
|
203
|
+
\`Unknown persona "\${input.persona}" — declare it with definePersonas()\`
|
|
204
|
+
)
|
|
205
|
+
}
|
|
206
|
+
// An acted-upon persona has no session of its own, and running one would
|
|
207
|
+
// race whatever scenario acts on it.
|
|
208
|
+
if (!persona.runnable) {
|
|
209
|
+
throw new Error(
|
|
210
|
+
\`Persona "\${input.persona}" is declared as acted upon, never run\`
|
|
211
|
+
)
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const disposition = (input.disposition ??
|
|
215
|
+
persona.disposition ??
|
|
216
|
+
'realistic') as VirtualUserDisposition
|
|
217
|
+
// Every disposition other than this one exists to find out what the product
|
|
218
|
+
// does wrong, which is not a thing to do to real customers' data. Checked
|
|
219
|
+
// against the effective disposition, so the override cannot smuggle one in.
|
|
220
|
+
if (
|
|
221
|
+
config.nodeEnv === 'production' &&
|
|
222
|
+
disposition !== PRODUCTION_DISPOSITION
|
|
223
|
+
) {
|
|
224
|
+
throw new Error(
|
|
225
|
+
\`Only the '\${PRODUCTION_DISPOSITION}' disposition may run against production; "\${input.persona}" is \${disposition}\`
|
|
226
|
+
)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
// Seeded here rather than inside the engine so the record carries the seed
|
|
230
|
+
// even if the run dies before returning — an unreproducible crash costs the
|
|
231
|
+
// most.
|
|
232
|
+
const seed = input.seed ?? Math.floor(Math.random() * 2_147_483_647)
|
|
233
|
+
|
|
234
|
+
const runId = await virtualUserRunStore.start({
|
|
235
|
+
persona: persona.id,
|
|
236
|
+
disposition,
|
|
237
|
+
seed,
|
|
238
|
+
goals: input.goals ?? [],
|
|
239
|
+
memory: input.memory ?? {},
|
|
240
|
+
startedBy: session?.userId ?? null,
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
// Deliberately not awaited: a run takes minutes, and a held-open request
|
|
244
|
+
// survives neither a rollout nor a proxy timeout. executeVirtualUserRun
|
|
245
|
+
// writes both outcomes to the record itself, so the only thing left to
|
|
246
|
+
// handle here is a rejection escaping the promise — without the catch it
|
|
247
|
+
// becomes an unhandled rejection and takes the process with it.
|
|
248
|
+
void rpc!
|
|
249
|
+
.invoke('executeVirtualUserRun', {
|
|
250
|
+
runId,
|
|
251
|
+
persona: persona.id,
|
|
252
|
+
disposition,
|
|
253
|
+
goals: input.goals ?? [],
|
|
254
|
+
memory: input.memory ?? {},
|
|
255
|
+
budget: input.budget,
|
|
256
|
+
seed,
|
|
257
|
+
})
|
|
258
|
+
.catch(() => {})
|
|
259
|
+
|
|
260
|
+
return { runId }
|
|
261
|
+
},
|
|
262
|
+
})
|
|
263
|
+
|
|
264
|
+
export const getVirtualUserRun = pikkuFunc({
|
|
265
|
+
tags: ['pikku'],
|
|
266
|
+
title: 'Read a Virtual User Run',
|
|
267
|
+
description:
|
|
268
|
+
'Reads a run back: its status, what it found, and the counts the engine kept.',
|
|
269
|
+
expose: true,
|
|
270
|
+
auth: ${authFlag},
|
|
271
|
+
// Its own scope, and not the one that starts a run: an adversarial run's
|
|
272
|
+
// findings are working exploits carrying live ids, so reading them is the
|
|
273
|
+
// more sensitive of the two.
|
|
274
|
+
scopes: ['virtualUser:read'],
|
|
275
|
+
input: GetVirtualUserRunInput,
|
|
276
|
+
output: GetVirtualUserRunOutput,
|
|
277
|
+
func: async ({ virtualUserRunStore }, { runId }) => {
|
|
278
|
+
if (!virtualUserRunStore) {
|
|
279
|
+
throw new Error('No virtualUserRunStore is wired — there are no runs to read.')
|
|
280
|
+
}
|
|
281
|
+
const run = await virtualUserRunStore.get(runId)
|
|
282
|
+
if (!run) {
|
|
283
|
+
throw new Error(\`No virtual user run \${runId}\`)
|
|
284
|
+
}
|
|
285
|
+
return {
|
|
286
|
+
runId: run.runId,
|
|
287
|
+
persona: run.persona,
|
|
288
|
+
disposition: run.disposition,
|
|
289
|
+
seed: run.seed,
|
|
290
|
+
status: run.status,
|
|
291
|
+
goals: run.goals,
|
|
292
|
+
memory: run.memory,
|
|
293
|
+
// Findings are free-form by design — the engine records what it noticed,
|
|
294
|
+
// not a fixed row shape — so they cross the wire as the schema's open
|
|
295
|
+
// object rather than being narrowed to whatever kinds exist today.
|
|
296
|
+
findings: run.findings.map((finding) => ({
|
|
297
|
+
kind: finding.kind as string,
|
|
298
|
+
detail: finding.detail,
|
|
299
|
+
rpcName: finding.rpcName,
|
|
300
|
+
status: finding.status,
|
|
301
|
+
intentId: finding.intentId,
|
|
302
|
+
step: finding.step,
|
|
303
|
+
})),
|
|
304
|
+
tally: (run.tally ?? null) as Record<string, unknown> | null,
|
|
305
|
+
stoppedBy: run.stoppedBy,
|
|
306
|
+
error: run.error,
|
|
307
|
+
createdAt: run.createdAt.toISOString(),
|
|
308
|
+
finishedAt: run.finishedAt ? run.finishedAt.toISOString() : null,
|
|
309
|
+
}
|
|
310
|
+
},
|
|
311
|
+
})
|
|
312
|
+
|
|
313
|
+
/**
|
|
314
|
+
* The run itself. Not exposed: it is dispatched by \`runVirtualUser\` and has no
|
|
315
|
+
* caller of its own.
|
|
316
|
+
*
|
|
317
|
+
* Everything it needs is derived through \`metaService\` and the generated
|
|
318
|
+
* personas — the same public surface any consumer has. Nothing reaches into
|
|
319
|
+
* pikku's internals, because an app could not, and a feature built on what only
|
|
320
|
+
* the framework can see would not be this feature.
|
|
321
|
+
*/
|
|
322
|
+
export const executeVirtualUserRun = pikkuSessionlessFunc({
|
|
323
|
+
tags: ['pikku'],
|
|
324
|
+
input: ExecuteVirtualUserRunInput,
|
|
325
|
+
output: ExecuteVirtualUserRunOutput,
|
|
326
|
+
func: async (
|
|
327
|
+
{ virtualUserRunStore, metaService, aiAgentRunner, variables, logger },
|
|
328
|
+
{ runId, persona: personaId, disposition, goals, memory, budget, seed }
|
|
329
|
+
) => {
|
|
330
|
+
if (!virtualUserRunStore) {
|
|
331
|
+
throw new Error('No virtualUserRunStore is wired.')
|
|
332
|
+
}
|
|
333
|
+
try {
|
|
334
|
+
if (!metaService) {
|
|
335
|
+
throw new Error('metaService is not wired — there is no catalogue to derive')
|
|
336
|
+
}
|
|
337
|
+
if (!aiAgentRunner) {
|
|
338
|
+
throw new Error('aiAgentRunner is not wired — there is nothing to think with')
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
const apiUrl = await variables.get(API_URL_VARIABLE)
|
|
342
|
+
if (!apiUrl) {
|
|
343
|
+
throw new Error(
|
|
344
|
+
\`\${API_URL_VARIABLE} is not set — a virtual user has no address to sign in at.\`
|
|
345
|
+
)
|
|
346
|
+
}
|
|
347
|
+
const secret = await variables.get(SECRET_VARIABLE)
|
|
348
|
+
if (!secret) {
|
|
349
|
+
throw new Error(
|
|
350
|
+
\`\${SECRET_VARIABLE} is not set — actor sign-in is disabled, so there is nobody for the virtual user to be.\`
|
|
351
|
+
)
|
|
352
|
+
}
|
|
353
|
+
const model = await variables.get(MODEL_VARIABLE)
|
|
354
|
+
if (!model) {
|
|
355
|
+
throw new Error(\`\${MODEL_VARIABLE} is not set — no model to think with.\`)
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
const functionsMeta = await metaService.getFunctionsMeta()
|
|
359
|
+
// Only the schemas the catalogue can actually refer to, so a large app
|
|
360
|
+
// does not pull every schema it has ever generated into one run.
|
|
361
|
+
const schemaNames = [
|
|
362
|
+
...new Set(
|
|
363
|
+
Object.values(functionsMeta).flatMap((meta: any) =>
|
|
364
|
+
[meta.inputSchemaName, meta.outputSchemaName].filter(
|
|
365
|
+
(name: unknown): name is string => !!name
|
|
366
|
+
)
|
|
367
|
+
)
|
|
368
|
+
),
|
|
369
|
+
]
|
|
370
|
+
const schemas = (await metaService.getSchemas(schemaNames)) as SchemaMap
|
|
371
|
+
|
|
372
|
+
const persona = personaConfigs[personaId as keyof typeof personaConfigs]
|
|
373
|
+
if (!persona) {
|
|
374
|
+
throw new Error(\`Persona "\${personaId}" is no longer declared\`)
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
const { catalogue, intents, agents } = prepareVirtualUserRun({
|
|
378
|
+
persona,
|
|
379
|
+
functionsMeta,
|
|
380
|
+
schemas,
|
|
381
|
+
workflowsMeta: await metaService.getWorkflowMeta(),
|
|
382
|
+
systemRoles: await metaService.getSystemRolesMeta(),
|
|
383
|
+
agentsMeta: await metaService.getAgentsMeta(),
|
|
384
|
+
})
|
|
385
|
+
|
|
386
|
+
const signedIn = createPersonas({ apiUrl, secret, model })
|
|
387
|
+
const target = signedIn[personaId as keyof typeof signedIn]
|
|
388
|
+
if (!target) {
|
|
389
|
+
throw new Error(\`Persona "\${personaId}" cannot sign in\`)
|
|
390
|
+
}
|
|
391
|
+
|
|
392
|
+
const result = await runVirtualUserEngine({
|
|
393
|
+
persona,
|
|
394
|
+
personaId,
|
|
395
|
+
disposition: disposition as VirtualUserDisposition,
|
|
396
|
+
catalogue,
|
|
397
|
+
intents,
|
|
398
|
+
goals,
|
|
399
|
+
memory,
|
|
400
|
+
seed,
|
|
401
|
+
agents,
|
|
402
|
+
target: personaVirtualUserTarget(target, {
|
|
403
|
+
model,
|
|
404
|
+
agents: agents.map((agent) => agent.name),
|
|
405
|
+
}),
|
|
406
|
+
// \`AIAgentRunnerService.run\` IS the engine's \`ActorLLM\` — same params,
|
|
407
|
+
// same result — so a virtual user thinks through the same runner every
|
|
408
|
+
// agent in the app does, provider quirks and all.
|
|
409
|
+
llm: (params) => aiAgentRunner.run(params),
|
|
410
|
+
model,
|
|
411
|
+
budget: {
|
|
412
|
+
steps: budget?.steps,
|
|
413
|
+
mutations: budget?.mutations,
|
|
414
|
+
duration: budget?.durationMs,
|
|
415
|
+
},
|
|
416
|
+
})
|
|
417
|
+
|
|
418
|
+
await virtualUserRunStore.complete(runId, {
|
|
419
|
+
findings: result.findings,
|
|
420
|
+
tally: result.tally,
|
|
421
|
+
memory: result.memory,
|
|
422
|
+
stoppedBy: result.stoppedBy ?? null,
|
|
423
|
+
})
|
|
424
|
+
|
|
425
|
+
return { findings: result.findings.length }
|
|
426
|
+
} catch (error) {
|
|
427
|
+
// A crashed run and a run that found nothing are different states, and the
|
|
428
|
+
// record is the only place that distinction survives — leaving it at
|
|
429
|
+
// 'running' forever is what \`fail\` exists to prevent.
|
|
430
|
+
const message = error instanceof Error ? error.message : String(error)
|
|
431
|
+
logger.error(\`Virtual user run \${runId} (\${personaId}) failed: \${message}\`)
|
|
432
|
+
await virtualUserRunStore.fail(runId, message)
|
|
433
|
+
throw error
|
|
434
|
+
}
|
|
435
|
+
},
|
|
436
|
+
})
|
|
437
|
+
`;
|
|
438
|
+
return { schemas, functions };
|
|
439
|
+
};
|
|
@@ -4,13 +4,14 @@ import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
|
4
4
|
import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
|
|
5
5
|
import { removeLegacyScaffoldFile } from '../../../utils/remove-legacy-scaffold-file.js';
|
|
6
6
|
import { serializeWorkflowRoutes } from './serialize-workflow-routes.js';
|
|
7
|
+
import { resolveScaffoldFeature } from '../../../utils/resolve-scaffold-feature.js';
|
|
7
8
|
export const pikkuWorkflowRoutes = pikkuSessionlessFunc({
|
|
8
9
|
func: async ({ logger, config }) => {
|
|
9
10
|
if (config.scaffold?.workflow &&
|
|
10
11
|
config.workflowRoutesFile &&
|
|
11
12
|
config.workflowRoutesSchemasFile) {
|
|
12
13
|
const pathToPikkuTypes = getFileImportRelativePath(config.workflowRoutesFile, config.typesDeclarationFile, config.packageMappings);
|
|
13
|
-
const { schemas, functions } = serializeWorkflowRoutes(pathToPikkuTypes, config.scaffold?.workflow
|
|
14
|
+
const { schemas, functions } = serializeWorkflowRoutes(pathToPikkuTypes, resolveScaffoldFeature('workflow', config.scaffold?.workflow).auth);
|
|
14
15
|
await writeFileInDir(logger, config.workflowRoutesSchemasFile, schemas);
|
|
15
16
|
await writeFileInDir(logger, config.workflowRoutesFile, functions);
|
|
16
17
|
await removeLegacyScaffoldFile(config.workflowRoutesFile);
|
|
@@ -3,8 +3,8 @@ import { ErrorCode } from '@pikku/inspector';
|
|
|
3
3
|
import { writeFileInDir } from '../../../utils/file-writer.js';
|
|
4
4
|
import { logCommandInfoAndTime } from '../../../middleware/log-command-info-and-time.js';
|
|
5
5
|
import { serializeWorkflowTypes } from './serialize-workflow-types.js';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
6
|
+
import { serializePersonas } from './serialize-personas.js';
|
|
7
|
+
import { resolvePersonas } from '../../../utils/resolve-personas.js';
|
|
8
8
|
import { serializeWorkflowRegistration } from './serialize-workflow-registration.js';
|
|
9
9
|
import { serializeWorkflowMap } from './serialize-workflow-map.js';
|
|
10
10
|
import { serializeScenarioStepMap } from './serialize-scenario-step-map.js';
|
|
@@ -89,21 +89,21 @@ export const pikkuWorkflow = pikkuSessionlessFunc({
|
|
|
89
89
|
const agentMapImportPath = getFileImportRelativePath(workflowTypesFile, config.agentMapDeclarationFile, packageMappings);
|
|
90
90
|
const scopesImportPath = getFileImportRelativePath(workflowTypesFile, config.scopesFile, packageMappings);
|
|
91
91
|
const scenarioStepMapImportPath = getFileImportRelativePath(workflowTypesFile, config.scenarioStepMapDeclarationFile, packageMappings);
|
|
92
|
-
const
|
|
93
|
-
await writeFileInDir(logger, workflowTypesFile, serializeWorkflowTypes(functionTypesImportPath, rpcMapImportPath, workflowMapImportPath, agentMapImportPath, scopesImportPath, scenarioStepMapImportPath,
|
|
92
|
+
const personasImportPath = getFileImportRelativePath(workflowTypesFile, config.personasWiringFile, packageMappings);
|
|
93
|
+
await writeFileInDir(logger, workflowTypesFile, serializeWorkflowTypes(functionTypesImportPath, rpcMapImportPath, workflowMapImportPath, agentMapImportPath, scopesImportPath, scenarioStepMapImportPath, personasImportPath));
|
|
94
94
|
// Rides the workflow command rather than getting its own codegen node, so
|
|
95
95
|
// it can't drift out of the two hand-maintained ordering lists.
|
|
96
96
|
await writeFileInDir(logger, config.scenarioStepMapDeclarationFile, serializeScenarioStepMap(logger, config.scenarioStepMapDeclarationFile, packageMappings, typesMap, functionState.meta));
|
|
97
|
-
// Written even
|
|
98
|
-
// resolvable import for the generated function types.
|
|
99
|
-
const
|
|
97
|
+
// Written even when nobody declared a persona, so `TypedPersonas` is always
|
|
98
|
+
// a resolvable import for the generated function types.
|
|
99
|
+
const personas = resolvePersonas(visitState.personas.definitions, config.scenarios?.emailDomain);
|
|
100
100
|
{
|
|
101
|
-
const agentMapImportPath = getFileImportRelativePath(config.
|
|
102
|
-
const exposedRpcMapImportPath = getFileImportRelativePath(config.
|
|
103
|
-
await writeFileInDir(logger, config.
|
|
104
|
-
// Fixed path
|
|
105
|
-
//
|
|
106
|
-
await writeFileInDir(logger, join(config.outDir, 'workflow', '
|
|
101
|
+
const agentMapImportPath = getFileImportRelativePath(config.personasWiringFile, config.agentMapDeclarationFile, packageMappings);
|
|
102
|
+
const exposedRpcMapImportPath = getFileImportRelativePath(config.personasWiringFile, config.rpcMapDeclarationFile, packageMappings);
|
|
103
|
+
await writeFileInDir(logger, config.personasWiringFile, serializePersonas(personas, agentMapImportPath, exposedRpcMapImportPath));
|
|
104
|
+
// Fixed path getPersonasMeta() reads; kept out of workflow/meta, which
|
|
105
|
+
// getWorkflowMeta() globs as workflows.
|
|
106
|
+
await writeFileInDir(logger, join(config.outDir, 'workflow', 'personas.gen.json'), JSON.stringify(personas, null, 2));
|
|
107
107
|
}
|
|
108
108
|
// Fixed path getFeaturesMeta() reads. Written even when empty so the
|
|
109
109
|
// console can tell "no features declared" from "meta not generated yet".
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ResolvedPersona } from '@pikku/core/services';
|
|
2
|
+
/**
|
|
3
|
+
* The runtime half of `definePersonas()`.
|
|
4
|
+
*
|
|
5
|
+
* Generated rather than re-exported because the addresses are computed: nobody
|
|
6
|
+
* writes one down, and a seed, a scenario run and a virtual-user run all have
|
|
7
|
+
* to arrive at the same one. Baking them here is what makes that a single fact
|
|
8
|
+
* rather than three implementations of the same rule.
|
|
9
|
+
*/
|
|
10
|
+
export declare const serializePersonas: (personas: Record<string, ResolvedPersona>, agentMapImportPath: string, rpcMapImportPath: string) => string;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The runtime half of `definePersonas()`.
|
|
3
|
+
*
|
|
4
|
+
* Generated rather than re-exported because the addresses are computed: nobody
|
|
5
|
+
* writes one down, and a seed, a scenario run and a virtual-user run all have
|
|
6
|
+
* to arrive at the same one. Baking them here is what makes that a single fact
|
|
7
|
+
* rather than three implementations of the same rule.
|
|
8
|
+
*/
|
|
9
|
+
export const serializePersonas = (personas, agentMapImportPath, rpcMapImportPath) => {
|
|
10
|
+
return `/** Personas declared with definePersonas() */
|
|
11
|
+
import { createHttpPersonas } from '@pikku/core/persona'
|
|
12
|
+
import type {
|
|
13
|
+
HttpPersonasConfig,
|
|
14
|
+
ScenarioPersona,
|
|
15
|
+
ResolvedPersona,
|
|
16
|
+
} from '@pikku/core/services'
|
|
17
|
+
import type { AgentMap } from '${agentMapImportPath}'
|
|
18
|
+
import type { FlattenedRPCMap } from '${rpcMapImportPath}'
|
|
19
|
+
|
|
20
|
+
export const personaConfigs = ${JSON.stringify(personas, null, 2)} as const satisfies Record<string, ResolvedPersona>
|
|
21
|
+
|
|
22
|
+
export type PersonaName = keyof typeof personaConfigs
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The same personas as a list, widened to \`ResolvedPersona\`. Iterating
|
|
26
|
+
* \`personaConfigs\` directly yields the literal type of each entry, on which an
|
|
27
|
+
* optional field a persona did not declare does not exist — so a seed reading
|
|
28
|
+
* \`roles\` off every persona needs this instead.
|
|
29
|
+
*/
|
|
30
|
+
export const personaList: ResolvedPersona[] = Object.values(personaConfigs)
|
|
31
|
+
|
|
32
|
+
export type AgentName = keyof AgentMap & string
|
|
33
|
+
export type TypedPersonas = Record<
|
|
34
|
+
PersonaName,
|
|
35
|
+
ScenarioPersona<AgentName, FlattenedRPCMap>
|
|
36
|
+
>
|
|
37
|
+
|
|
38
|
+
export const createPersonas = (
|
|
39
|
+
options: Omit<HttpPersonasConfig, 'personas'>
|
|
40
|
+
): TypedPersonas =>
|
|
41
|
+
createHttpPersonas({
|
|
42
|
+
...options,
|
|
43
|
+
personas: personaConfigs,
|
|
44
|
+
}) as TypedPersonas
|
|
45
|
+
`;
|
|
46
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Generate the scenario step map: the typed set of names a scenario may pass to
|
|
3
|
-
* `scenario.
|
|
3
|
+
* `scenario.given/when/then`.
|
|
4
4
|
*
|
|
5
5
|
* Steps are referenced by string, exactly like `workflow.do` references an RPC,
|
|
6
6
|
* so type safety has to come from a generated map rather than from importing
|
|
@@ -9,10 +9,19 @@
|
|
|
9
9
|
*/
|
|
10
10
|
import { serializeImportMap } from '../../../utils/serialize-import-map.js';
|
|
11
11
|
import { generateCustomTypes } from '@pikku/inspector';
|
|
12
|
-
|
|
12
|
+
/**
|
|
13
|
+
* All three step wrappers. A scenario calls a platform or addon step by name
|
|
14
|
+
* exactly as it calls a persona one — who acts changes what the step may do, not
|
|
15
|
+
* how it is referenced — so all three belong in the map.
|
|
16
|
+
*/
|
|
17
|
+
const SCENARIO_STEP_WRAPPERS = new Set([
|
|
18
|
+
'pikkuScenarioStep',
|
|
19
|
+
'pikkuPlatformScenarioStep',
|
|
20
|
+
'pikkuAddonScenarioStep',
|
|
21
|
+
]);
|
|
13
22
|
export const serializeScenarioStepMap = (logger, relativeToPath, packageMappings, typesMap, functionsMeta) => {
|
|
14
23
|
const requiredTypes = new Set();
|
|
15
|
-
const steps = Object.entries(functionsMeta).filter(([, meta]) => meta.funcWrapper
|
|
24
|
+
const steps = Object.entries(functionsMeta).filter(([, meta]) => !!meta.funcWrapper && SCENARIO_STEP_WRAPPERS.has(meta.funcWrapper));
|
|
16
25
|
const resolveType = (name) => {
|
|
17
26
|
if (!name) {
|
|
18
27
|
return 'void';
|
|
@@ -45,7 +54,7 @@ export const serializeScenarioStepMap = (logger, relativeToPath, packageMappings
|
|
|
45
54
|
.filter((line) => !line.startsWith('import '))
|
|
46
55
|
.join('\n');
|
|
47
56
|
return `/**
|
|
48
|
-
* Scenario step map: the names \`scenario.
|
|
57
|
+
* Scenario step map: the names \`scenario.given/when/then\` accepts, with
|
|
49
58
|
* the input and output types of each step.
|
|
50
59
|
*/
|
|
51
60
|
|