@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
|
@@ -40,11 +40,26 @@ function variableSchemaName(name, field) {
|
|
|
40
40
|
// addHTTPMiddleware('*') call as the session middleware: the inspector keys
|
|
41
41
|
// route-middleware groups by pattern, so a second '*' registration from another
|
|
42
42
|
// file would silently displace this one in deployed units.
|
|
43
|
+
//
|
|
44
|
+
// The session carries the two scope roots the console addon gates itself on.
|
|
45
|
+
// Without them this token authenticates but authorizes nothing: `wireAddon`
|
|
46
|
+
// gates the whole addon on `admin`, so every console:* RPC — reads included —
|
|
47
|
+
// answers MissingScopeError, and an external console can reach the deployment
|
|
48
|
+
// while being unable to do a single thing in it.
|
|
49
|
+
//
|
|
50
|
+
// Roots rather than a wildcard: a parent grant satisfies its children, so
|
|
51
|
+
// `admin` covers `admin:*` and `pikku` covers `pikku:scopes:*`/`pikku:audit:*`,
|
|
52
|
+
// which is every scope the console's own functions require. A `*` would also
|
|
53
|
+
// hand the token every scope the HOST app declares, which is authority the
|
|
54
|
+
// console never asks for.
|
|
43
55
|
const consoleTokenMiddlewareLines = () => [
|
|
44
56
|
` authBearer({`,
|
|
45
57
|
` token: {`,
|
|
46
58
|
` secretId: 'PIKKU_CONSOLE_TOKEN',`,
|
|
47
|
-
` userSession: {
|
|
59
|
+
` userSession: {`,
|
|
60
|
+
` userId: 'pikku-console-token',`,
|
|
61
|
+
` scopes: ['admin', 'pikku'],`,
|
|
62
|
+
` },`,
|
|
48
63
|
` },`,
|
|
49
64
|
` }),`,
|
|
50
65
|
];
|
|
@@ -59,22 +74,22 @@ export const serializeAuthGen = (definition, providers, authFile, typesDeclarati
|
|
|
59
74
|
// the package's `imports` map (e.g. a project's `pikku/` dir), where `#pikku`
|
|
60
75
|
// would not resolve. This mirrors how the console/agent scaffolds import it.
|
|
61
76
|
const pikkuTypesImportPath = getFileImportRelativePath(authFile, typesDeclarationFile, packageMappings);
|
|
62
|
-
// ─── Secrets file: Zod schemas +
|
|
77
|
+
// ─── Secrets file: Zod schemas + defineSecret/defineVariable ──────────────────
|
|
63
78
|
const secrets = [
|
|
64
79
|
'// AUTO-GENERATED by pikku CLI — do not edit',
|
|
65
80
|
'',
|
|
66
|
-
`import {
|
|
81
|
+
`import { defineSecret } from '@pikku/core/secret'`,
|
|
67
82
|
];
|
|
68
83
|
const hasVariables = known.some((name) => PROVIDER_REGISTRY[name].variables);
|
|
69
84
|
if (hasVariables) {
|
|
70
|
-
secrets.push(`import {
|
|
85
|
+
secrets.push(`import { defineVariable } from '@pikku/core/variable'`);
|
|
71
86
|
}
|
|
72
87
|
secrets.push(`import { z } from 'zod'`, '');
|
|
73
88
|
// better-auth's session-signing secret is always required (its BETTER_AUTH_SECRET
|
|
74
89
|
// env convention). Wire it so the platform collects it, regardless of providers.
|
|
75
90
|
secrets.push(`export const BetterAuthSecretSchema = z.string()`);
|
|
76
91
|
secrets.push('');
|
|
77
|
-
secrets.push(`
|
|
92
|
+
secrets.push(`defineSecret({`);
|
|
78
93
|
secrets.push(` name: 'betterAuthSecret',`);
|
|
79
94
|
secrets.push(` displayName: 'Better Auth Secret',`);
|
|
80
95
|
secrets.push(` description: 'Signing secret for better-auth sessions',`);
|
|
@@ -92,12 +107,12 @@ export const serializeAuthGen = (definition, providers, authFile, typesDeclarati
|
|
|
92
107
|
secrets.push(`})`);
|
|
93
108
|
secrets.push('');
|
|
94
109
|
}
|
|
95
|
-
//
|
|
110
|
+
// defineSecret for each provider.
|
|
96
111
|
for (const name of known) {
|
|
97
112
|
const def = PROVIDER_REGISTRY[name];
|
|
98
113
|
const schemaName = providerSchemaName(name);
|
|
99
114
|
const secretName = providerSecretName(name);
|
|
100
|
-
secrets.push(`
|
|
115
|
+
secrets.push(`defineSecret({`);
|
|
101
116
|
secrets.push(` name: '${secretName}',`);
|
|
102
117
|
secrets.push(` displayName: '${def.displayName}',`);
|
|
103
118
|
secrets.push(` secretId: '${def.secretId}',`);
|
|
@@ -105,7 +120,7 @@ export const serializeAuthGen = (definition, providers, authFile, typesDeclarati
|
|
|
105
120
|
secrets.push(`})`);
|
|
106
121
|
secrets.push('');
|
|
107
122
|
}
|
|
108
|
-
//
|
|
123
|
+
// defineVariable for providers with non-secret config (issuer, tenantId, etc.).
|
|
109
124
|
for (const name of known) {
|
|
110
125
|
const def = PROVIDER_REGISTRY[name];
|
|
111
126
|
if (!def.variables)
|
|
@@ -116,7 +131,7 @@ export const serializeAuthGen = (definition, providers, authFile, typesDeclarati
|
|
|
116
131
|
const schemaName = variableSchemaName(name, field);
|
|
117
132
|
secrets.push(`export const ${schemaName} = z.string()`);
|
|
118
133
|
secrets.push('');
|
|
119
|
-
secrets.push(`
|
|
134
|
+
secrets.push(`defineVariable({`);
|
|
120
135
|
secrets.push(` name: '${name}_${field}',`);
|
|
121
136
|
secrets.push(` displayName: '${def.displayName} ${capitalize(field)}',`);
|
|
122
137
|
secrets.push(` description: '${meta.description}',`);
|
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
* them at runtime — the same treatment addon services get from
|
|
17
17
|
* `pikkuAddonServices`. That gives the factory typed, map-aware access:
|
|
18
18
|
*
|
|
19
|
-
* socialProviders: {
|
|
19
|
+
* socialProviders: {
|
|
20
|
+
* github: (await secrets.getSecret('GITHUB_OAUTH')).reveal(),
|
|
21
|
+
* }
|
|
20
22
|
*
|
|
21
23
|
* with no inline `getSecrets<{ ... }>()` generic, because the secret types flow
|
|
22
24
|
* from the generated `CredentialsMap`.
|
|
@@ -17,7 +17,9 @@ import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
|
|
|
17
17
|
* them at runtime — the same treatment addon services get from
|
|
18
18
|
* `pikkuAddonServices`. That gives the factory typed, map-aware access:
|
|
19
19
|
*
|
|
20
|
-
* socialProviders: {
|
|
20
|
+
* socialProviders: {
|
|
21
|
+
* github: (await secrets.getSecret('GITHUB_OAUTH')).reveal(),
|
|
22
|
+
* }
|
|
21
23
|
*
|
|
22
24
|
* with no inline `getSecrets<{ ... }>()` generic, because the secret types flow
|
|
23
25
|
* from the generated `CredentialsMap`.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const pikkuChannels: import("#pikku").
|
|
1
|
+
export declare const pikkuChannels: import("#pikku").PikkuFunctionSessionlessConfig<void, void, "rpc" | "session", import("#pikku").PikkuFunctionSessionless<void, void, "rpc" | "session", import("#pikku").WiredServices>, undefined, undefined>;
|
|
@@ -109,15 +109,23 @@ function generateChannels(logger, typesMap, functionsMeta, addonFunctions, chann
|
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
|
+
/**
|
|
113
|
+
* A route or message key that is not a bare identifier has to be quoted to be
|
|
114
|
+
* a legal property name. Channel routes are author-chosen strings and a CLI
|
|
115
|
+
* channel's are command ids, where `app-smoke` and `registry.search` are the
|
|
116
|
+
* norm — unquoted, each one ends the property early and the whole map fails
|
|
117
|
+
* to parse. Quoted only when it has to be, so existing output is unchanged.
|
|
118
|
+
*/
|
|
119
|
+
const propertyKey = (key) => /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key) ? key : `'${key}'`;
|
|
112
120
|
let routesStr = 'export type ChannelsMap = {\n';
|
|
113
121
|
for (const [channelPath, { routes, message }] of Object.entries(channelsObject)) {
|
|
114
122
|
routesStr += ` readonly '${channelPath}': {\n`;
|
|
115
123
|
// Add `routes` object
|
|
116
124
|
routesStr += ` readonly routes: {\n`;
|
|
117
125
|
for (const [key, methods] of Object.entries(routes)) {
|
|
118
|
-
routesStr += ` readonly ${key}: {\n`;
|
|
126
|
+
routesStr += ` readonly ${propertyKey(key)}: {\n`;
|
|
119
127
|
for (const [method, handler] of Object.entries(methods)) {
|
|
120
|
-
routesStr += ` readonly ${method}: ChannelHandler<${formatTypeArray(handler.inputTypes) || 'void'}, ${formatTypeArray(handler.outputTypes) || 'never'}>,\n`;
|
|
128
|
+
routesStr += ` readonly ${propertyKey(method)}: ChannelHandler<${formatTypeArray(handler.inputTypes) || 'void'}, ${formatTypeArray(handler.outputTypes) || 'never'}>,\n`;
|
|
121
129
|
}
|
|
122
130
|
routesStr += ' },\n';
|
|
123
131
|
}
|
|
@@ -64,15 +64,20 @@ export const pikkuCLIEntry = pikkuSessionlessFunc({
|
|
|
64
64
|
// Generate client code if clientPath is provided
|
|
65
65
|
if (channelClientPath) {
|
|
66
66
|
const channelClientFile = join(config.rootDir, channelClientPath);
|
|
67
|
-
//
|
|
67
|
+
// A renderer for a CLI-over-channel program runs on the client, where
|
|
68
|
+
// there is no service container to resolve from — the only thing the
|
|
69
|
+
// runtime can hand it is a logger. Anything else it destructures
|
|
70
|
+
// would be undefined at runtime, so it fails generation instead.
|
|
68
71
|
const rendererNames = collectRendererNames(programMeta);
|
|
69
72
|
const problematicRenderers = [];
|
|
70
73
|
for (const rendererName of rendererNames) {
|
|
71
74
|
const rendererMeta = visitState.cli.meta.renderers[rendererName];
|
|
72
|
-
|
|
75
|
+
const services = rendererMeta?.services?.services ?? [];
|
|
76
|
+
const unavailable = services.filter((name) => name !== 'logger');
|
|
77
|
+
if (unavailable.length > 0) {
|
|
73
78
|
problematicRenderers.push({
|
|
74
79
|
name: rendererName,
|
|
75
|
-
services:
|
|
80
|
+
services: unavailable,
|
|
76
81
|
});
|
|
77
82
|
}
|
|
78
83
|
}
|
|
@@ -81,7 +86,7 @@ export const pikkuCLIEntry = pikkuSessionlessFunc({
|
|
|
81
86
|
const details = problematicRenderers
|
|
82
87
|
.map((r) => ` - ${r.name} depends on: ${r.services.join(', ')}`)
|
|
83
88
|
.join('\n');
|
|
84
|
-
logger.critical(ErrorCode.CLI_CLIENTSIDE_RENDERER_HAS_SERVICES, `Cannot generate CLI channel client for '${programName}':
|
|
89
|
+
logger.critical(ErrorCode.CLI_CLIENTSIDE_RENDERER_HAS_SERVICES, `Cannot generate CLI channel client for '${programName}': a renderer reached for a service that does not exist on the client\n${details}\n\nRenderers in a CLI-over-channel program run on the client side of the socket, where the only available service is 'logger'.`);
|
|
85
90
|
// Delete existing client file if it exists
|
|
86
91
|
if (existsSync(channelClientFile)) {
|
|
87
92
|
await rm(channelClientFile);
|
|
@@ -5,7 +5,11 @@ import type { Config } from '../../../../types/application-types.js';
|
|
|
5
5
|
*/
|
|
6
6
|
export declare function collectRendererNames(programMeta: CLIProgramMeta): Set<string>;
|
|
7
7
|
/**
|
|
8
|
-
* Serializes a CLI-over-Channel client bootstrap file
|
|
9
|
-
*
|
|
8
|
+
* Serializes a CLI-over-Channel client bootstrap file.
|
|
9
|
+
*
|
|
10
|
+
* The client deliberately does NOT import the CLI bootstrap: loading the
|
|
11
|
+
* command tree here would bind the client's version to the server's, which is
|
|
12
|
+
* the coupling running commands remotely exists to remove. Renderers are the
|
|
13
|
+
* only local artefact, and they are optional.
|
|
10
14
|
*/
|
|
11
|
-
export declare function serializeChannelCLIClient(programName: string, programMeta: CLIProgramMeta, clientFile: string, config: Config,
|
|
15
|
+
export declare function serializeChannelCLIClient(programName: string, programMeta: CLIProgramMeta, clientFile: string, config: Config, _cliBootstrapPath: string, channelRoute?: string, renderersMeta?: Record<string, any>): string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
|
|
2
|
+
import { DIRECT_EXECUTION_GUARD } from './serialize-cli-entrypoint-guard.js';
|
|
2
3
|
/**
|
|
3
4
|
* Collect all unique renderer names from CLI metadata (populated by inspector)
|
|
4
5
|
*/
|
|
@@ -65,14 +66,16 @@ function buildRenderersMap(programMeta, renderersMeta) {
|
|
|
65
66
|
return `{\n${entries.join(',\n')}\n }`;
|
|
66
67
|
}
|
|
67
68
|
/**
|
|
68
|
-
* Serializes a CLI-over-Channel client bootstrap file
|
|
69
|
-
*
|
|
69
|
+
* Serializes a CLI-over-Channel client bootstrap file.
|
|
70
|
+
*
|
|
71
|
+
* The client deliberately does NOT import the CLI bootstrap: loading the
|
|
72
|
+
* command tree here would bind the client's version to the server's, which is
|
|
73
|
+
* the coupling running commands remotely exists to remove. Renderers are the
|
|
74
|
+
* only local artefact, and they are optional.
|
|
70
75
|
*/
|
|
71
|
-
export function serializeChannelCLIClient(programName, programMeta, clientFile, config,
|
|
76
|
+
export function serializeChannelCLIClient(programName, programMeta, clientFile, config, _cliBootstrapPath, channelRoute, renderersMeta) {
|
|
72
77
|
const capitalizedName = programName.charAt(0).toUpperCase() + programName.slice(1).replace(/-/g, '');
|
|
73
78
|
const finalChannelRoute = channelRoute || `/cli/${programName}`;
|
|
74
|
-
// Get relative import path to CLI bootstrap (for metadata)
|
|
75
|
-
const bootstrapImportPath = getFileImportRelativePath(clientFile, cliBootstrapPath, config.packageMappings);
|
|
76
79
|
// Collect all unique renderer names from CLI metadata (populated by inspector)
|
|
77
80
|
const rendererNames = collectRendererNames(programMeta);
|
|
78
81
|
// Generate renderer imports from their source files
|
|
@@ -105,32 +108,48 @@ export function serializeChannelCLIClient(programName, programMeta, clientFile,
|
|
|
105
108
|
? resolveRendererBinding(programMeta.defaultRenderName, renderersMeta)
|
|
106
109
|
: null;
|
|
107
110
|
const defaultRendererCode = defaultRendererBinding
|
|
108
|
-
? `,\n defaultRenderer: ${defaultRendererBinding}
|
|
111
|
+
? `,\n defaultRenderer: ${defaultRendererBinding} as CorePikkuCLIClientRender<any>`
|
|
109
112
|
: '';
|
|
110
113
|
return `
|
|
111
|
-
import {
|
|
114
|
+
import { executeRawCLIViaChannel } from '@pikku/core/cli/channel'
|
|
115
|
+
import type { CorePikkuCLIClientRender } from '@pikku/core/cli/channel'
|
|
116
|
+
import type { Capabilities } from '@pikku/core/channel'
|
|
112
117
|
import { CorePikkuWebsocket } from '@pikku/websocket'
|
|
113
|
-
import '${bootstrapImportPath}'
|
|
114
118
|
${rendererImports}
|
|
115
119
|
/**
|
|
116
120
|
* ${capitalizedName} CLI Client (via WebSocket Channel)
|
|
117
|
-
*
|
|
121
|
+
*
|
|
122
|
+
* Forwards argv to the server untouched — the command tree is never parsed
|
|
123
|
+
* here, so this client stays valid as the server's commands change. Renderers
|
|
124
|
+
* are matched by the command id the server reports; anything it doesn't
|
|
125
|
+
* recognise falls back to JSON.
|
|
126
|
+
*
|
|
127
|
+
* \`capabilities\` are the functions this client agrees to run on the server's
|
|
128
|
+
* behalf (a git sha, a local path). It is an allowlist, not a convenience —
|
|
129
|
+
* nothing outside it is reachable from the server. A bare function is
|
|
130
|
+
* unclassified and so needs approval before every call; write
|
|
131
|
+
* \`{ execute, needsApproval: false }\` for one that may run unattended.
|
|
118
132
|
*/
|
|
119
133
|
export async function ${capitalizedName}CLIClient(
|
|
120
134
|
ws: WebSocket,
|
|
121
|
-
args?: string[]
|
|
122
|
-
|
|
135
|
+
args?: string[],
|
|
136
|
+
capabilities: Capabilities = {}
|
|
137
|
+
): Promise<number> {
|
|
123
138
|
// Create Pikku WebSocket wrapper
|
|
124
139
|
const pikkuWS = new CorePikkuWebsocket(ws)
|
|
125
140
|
|
|
126
|
-
//
|
|
127
|
-
|
|
141
|
+
// Renderers are declared against this app's \`SingletonServices\`, but on this
|
|
142
|
+
// side of the socket the only service that exists is a logger. The cast is
|
|
143
|
+
// sound because generation refuses to emit this file at all when a renderer
|
|
144
|
+
// reaches for anything else — see CLI_CLIENTSIDE_RENDERER_HAS_SERVICES. It is
|
|
145
|
+
// localised here so \`executeRawCLIViaChannel\` can keep an honest signature.
|
|
146
|
+
const renderers = ${renderersMap} as Record<string, CorePikkuCLIClientRender<any>>
|
|
128
147
|
|
|
129
|
-
|
|
130
|
-
programName: '${programName}',
|
|
148
|
+
return executeRawCLIViaChannel({
|
|
131
149
|
pikkuWS,
|
|
132
150
|
args,
|
|
133
|
-
renderers
|
|
151
|
+
renderers,
|
|
152
|
+
capabilities${defaultRendererCode},
|
|
134
153
|
})
|
|
135
154
|
}
|
|
136
155
|
|
|
@@ -138,15 +157,17 @@ export async function ${capitalizedName}CLIClient(
|
|
|
138
157
|
export default ${capitalizedName}CLIClient
|
|
139
158
|
|
|
140
159
|
// For direct execution (if this file is run directly)
|
|
141
|
-
|
|
160
|
+
${DIRECT_EXECUTION_GUARD}
|
|
161
|
+
|
|
162
|
+
if (isDirectExecution) {
|
|
142
163
|
const url = process.env.PIKKU_WS_URL || 'ws://localhost:4002${finalChannelRoute}'
|
|
143
164
|
|
|
144
165
|
// Attach credentials so the channel authenticates like any other pikku client.
|
|
145
166
|
// A machine API key (PIKKU_API_KEY -> x-api-key) takes precedence; otherwise
|
|
146
167
|
// the human session token saved by \`pikku login\` (~/.pikku/session.json ->
|
|
147
|
-
// Authorization: Bearer) is used. This block only runs
|
|
148
|
-
// execution), so reading the session file
|
|
149
|
-
//
|
|
168
|
+
// Authorization: Bearer) is used. This block only runs on a server runtime
|
|
169
|
+
// (direct execution), so reading the session file is safe — a browser could
|
|
170
|
+
// neither reach it nor set custom headers on its WebSocket.
|
|
150
171
|
const headers: Record<string, string> = {}
|
|
151
172
|
if (process.env.PIKKU_API_KEY) {
|
|
152
173
|
headers['x-api-key'] = process.env.PIKKU_API_KEY
|
|
@@ -173,21 +194,36 @@ if (import.meta.url === \`file://\${process.argv[1]}\`) {
|
|
|
173
194
|
}
|
|
174
195
|
const hasAuth = Object.keys(headers).length > 0
|
|
175
196
|
|
|
176
|
-
//
|
|
177
|
-
//
|
|
197
|
+
// Node's global WebSocket reads its second argument as subprotocols and drops
|
|
198
|
+
// custom headers on the floor, so credentials there need the 'ws' module.
|
|
199
|
+
// Bun's honours them natively, and reaching for 'ws' under Bun would load its
|
|
200
|
+
// compatibility shim for nothing. Detected once, the way the CLI picks its
|
|
201
|
+
// dev-server runner.
|
|
202
|
+
const isBun = typeof (globalThis as { Bun?: unknown }).Bun !== 'undefined'
|
|
203
|
+
|
|
204
|
+
// Only the header-carrying Bun call needs the cast: the DOM lib types the
|
|
205
|
+
// second argument as subprotocols, which is what Node implements.
|
|
206
|
+
type WebSocketWithHeaders = new (
|
|
207
|
+
url: string,
|
|
208
|
+
options: { headers: Record<string, string> }
|
|
209
|
+
) => WebSocket
|
|
210
|
+
|
|
178
211
|
let ws: WebSocket
|
|
179
|
-
if (hasAuth || typeof WebSocket === 'undefined') {
|
|
212
|
+
if (!isBun && (hasAuth || typeof WebSocket === 'undefined')) {
|
|
180
213
|
const wsModule = await import('ws')
|
|
181
214
|
ws = new wsModule.default(url, { headers }) as unknown as WebSocket
|
|
215
|
+
} else if (hasAuth) {
|
|
216
|
+
ws = new (WebSocket as unknown as WebSocketWithHeaders)(url, { headers })
|
|
182
217
|
} else {
|
|
183
218
|
ws = new WebSocket(url)
|
|
184
219
|
}
|
|
185
220
|
|
|
186
|
-
${capitalizedName}CLIClient(ws, process.argv.slice(2))
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
221
|
+
${capitalizedName}CLIClient(ws, process.argv.slice(2))
|
|
222
|
+
.then((exitCode) => process.exit(exitCode))
|
|
223
|
+
.catch(error => {
|
|
224
|
+
console.error('Fatal channel CLI error:', error)
|
|
225
|
+
process.exit(1)
|
|
226
|
+
})
|
|
191
227
|
}
|
|
192
228
|
`;
|
|
193
229
|
}
|
|
@@ -60,7 +60,7 @@ export function serializeChannelCLI(programName, programMeta, channelFile, funct
|
|
|
60
60
|
import { wireChannel } from '${channelTypesPath}'
|
|
61
61
|
import { pikkuMiddleware${hasAddonFuncs ? ', ref' : ''}, pikkuSessionlessFunc } from '${functionTypesPath}'
|
|
62
62
|
import { generateCommandHelp } from '@pikku/core/cli'
|
|
63
|
-
import { handleRawCLI } from '@pikku/core/cli/channel'
|
|
63
|
+
import { handleRawCLI, type RawCLIFrame } from '@pikku/core/cli/channel'
|
|
64
64
|
import { pikkuState } from '@pikku/core/internal'
|
|
65
65
|
${imports}
|
|
66
66
|
|
|
@@ -97,22 +97,79 @@ export const cliHelp = pikkuSessionlessFunc<{ args?: string[] }, { help: string
|
|
|
97
97
|
},
|
|
98
98
|
})
|
|
99
99
|
|
|
100
|
-
|
|
100
|
+
/**
|
|
101
|
+
* Raw entry point: the client forwards argv untouched and this side owns
|
|
102
|
+
* parsing, so a client binary never carries the command tree and its version
|
|
103
|
+
* is free to drift from the server's.
|
|
104
|
+
*
|
|
105
|
+
* Progressive output is streamed on the same channel rather than returned,
|
|
106
|
+
* and the terminating control frame carries the exit code so the client
|
|
107
|
+
* process can exit non-zero.
|
|
108
|
+
*/
|
|
109
|
+
export const cliRaw = pikkuSessionlessFunc<{ args: string[] }, RawCLIFrame>({
|
|
101
110
|
auth: false,
|
|
102
|
-
func: async (services, data: { args: string[] }) => {
|
|
103
|
-
|
|
111
|
+
func: async (services, data: { args: string[] }, { channel, session }) => {
|
|
112
|
+
const { help, result, error, exitCode, commandId } = await handleRawCLI({
|
|
104
113
|
programName: '${programName}',
|
|
105
114
|
args: data.args,
|
|
106
115
|
singletonServices: services as any,
|
|
116
|
+
createWireServices: pikkuState(null, 'package', 'factories')?.createWireServices,
|
|
117
|
+
// The connection authenticated during its upgrade — commands run as it.
|
|
118
|
+
session,
|
|
119
|
+
// The socket the command arrived on, so \`channel.remote(...)\` inside a
|
|
120
|
+
// command reaches the client that invoked it.
|
|
121
|
+
transport: channel,
|
|
122
|
+
onOutput: (output, commandId) =>
|
|
123
|
+
channel?.send({ action: 'cli-output', commandId, data: output }),
|
|
107
124
|
})
|
|
125
|
+
|
|
126
|
+
// A failed parse carries both: the error says what was wrong, the help
|
|
127
|
+
// says what was available. The error goes last so it is the line still on
|
|
128
|
+
// screen after the help text has scrolled past.
|
|
129
|
+
if (help !== undefined) {
|
|
130
|
+
await channel?.send({ action: 'cli-help', help })
|
|
131
|
+
if (error !== undefined) {
|
|
132
|
+
await channel?.send({ action: 'cli-error', error })
|
|
133
|
+
}
|
|
134
|
+
} else if (error !== undefined) {
|
|
135
|
+
await channel?.send({ action: 'cli-error', error })
|
|
136
|
+
} else if (result !== undefined) {
|
|
137
|
+
await channel?.send({ action: 'cli-result', commandId, result })
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Returned rather than sent so the runtime tags it with the routing key,
|
|
141
|
+
// and so the terminal frame cannot be emitted before the ones above it.
|
|
142
|
+
return { action: 'cli-control', event: 'complete', exitCode }
|
|
108
143
|
},
|
|
109
144
|
})
|
|
110
145
|
|
|
146
|
+
${programMeta.auth === true
|
|
147
|
+
? `/**
|
|
148
|
+
* Refuses a connection that arrives without a session.
|
|
149
|
+
*
|
|
150
|
+
* A CLI authenticates once, when it connects — there is no later message that
|
|
151
|
+
* would establish a session, so a connection that starts anonymous can never
|
|
152
|
+
* run anything. Saying so immediately and hanging up gives the caller a
|
|
153
|
+
* non-zero exit instead of a socket that silently refuses every command.
|
|
154
|
+
*/
|
|
155
|
+
export const cliRequireSession = pikkuSessionlessFunc<void, RawCLIFrame | void>({
|
|
156
|
+
auth: false,
|
|
157
|
+
func: async (_services, _data, { channel, session }) => {
|
|
158
|
+
if (session) {
|
|
159
|
+
return
|
|
160
|
+
}
|
|
161
|
+
await channel?.send({ action: 'cli-error', error: 'Authentication required' })
|
|
162
|
+
await channel?.send({ action: 'cli-control', event: 'complete', exitCode: 1 })
|
|
163
|
+
await channel?.close()
|
|
164
|
+
},
|
|
165
|
+
})
|
|
166
|
+
`
|
|
167
|
+
: ''}
|
|
111
168
|
wireChannel({
|
|
112
169
|
name: '${finalChannelName}',
|
|
113
170
|
route: '${finalChannelRoute}',
|
|
114
|
-
auth:
|
|
115
|
-
onMessageWiring: {
|
|
171
|
+
auth: ${programMeta.auth === true},
|
|
172
|
+
${programMeta.auth === true ? ' onConnect: cliRequireSession,\n' : ''} onMessageWiring: {
|
|
116
173
|
command: {
|
|
117
174
|
'__help': {
|
|
118
175
|
func: cliHelp,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The snippet every generated CLI entrypoint uses to decide whether it is being
|
|
3
|
+
* run or merely imported. It declares `isDirectExecution`; the caller writes the
|
|
4
|
+
* `if`.
|
|
5
|
+
*
|
|
6
|
+
* `import.meta.url === \`file://${process.argv[1]}\`` — the shape this replaces —
|
|
7
|
+
* is false for any CLI invoked through a symlinked bin, because Node reports the
|
|
8
|
+
* symlink in argv and the realpath in the URL, so the block never ran for an
|
|
9
|
+
* installed `node_modules/.bin/<name>`. It also fails on paths the URL has to
|
|
10
|
+
* percent-encode, such as one containing a space.
|
|
11
|
+
*/
|
|
12
|
+
export declare const DIRECT_EXECUTION_GUARD = "const isDirectExecution = await (async () => {\n if (typeof import.meta.main === 'boolean') {\n return import.meta.main\n }\n // Node exposes import.meta.main from 24.2; earlier 24.x compares realpaths,\n // which is what it is shorthand for.\n try {\n const { fileURLToPath } = await import('node:url')\n const { realpathSync } = await import('node:fs')\n return (\n process.argv[1] !== undefined &&\n realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)\n )\n } catch {\n return false\n }\n})()";
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The snippet every generated CLI entrypoint uses to decide whether it is being
|
|
3
|
+
* run or merely imported. It declares `isDirectExecution`; the caller writes the
|
|
4
|
+
* `if`.
|
|
5
|
+
*
|
|
6
|
+
* `import.meta.url === \`file://${process.argv[1]}\`` — the shape this replaces —
|
|
7
|
+
* is false for any CLI invoked through a symlinked bin, because Node reports the
|
|
8
|
+
* symlink in argv and the realpath in the URL, so the block never ran for an
|
|
9
|
+
* installed `node_modules/.bin/<name>`. It also fails on paths the URL has to
|
|
10
|
+
* percent-encode, such as one containing a space.
|
|
11
|
+
*/
|
|
12
|
+
export const DIRECT_EXECUTION_GUARD = `const isDirectExecution = await (async () => {
|
|
13
|
+
if (typeof import.meta.main === 'boolean') {
|
|
14
|
+
return import.meta.main
|
|
15
|
+
}
|
|
16
|
+
// Node exposes import.meta.main from 24.2; earlier 24.x compares realpaths,
|
|
17
|
+
// which is what it is shorthand for.
|
|
18
|
+
try {
|
|
19
|
+
const { fileURLToPath } = await import('node:url')
|
|
20
|
+
const { realpathSync } = await import('node:fs')
|
|
21
|
+
return (
|
|
22
|
+
process.argv[1] !== undefined &&
|
|
23
|
+
realpathSync(process.argv[1]) === fileURLToPath(import.meta.url)
|
|
24
|
+
)
|
|
25
|
+
} catch {
|
|
26
|
+
return false
|
|
27
|
+
}
|
|
28
|
+
})()`;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { getFileImportRelativePath } from '../../../utils/file-import-path.js';
|
|
2
|
+
import { DIRECT_EXECUTION_GUARD } from './serialize-cli-entrypoint-guard.js';
|
|
2
3
|
/**
|
|
3
4
|
* Serializes the local (in-program) CLI bootstrap code
|
|
4
5
|
*/
|
|
@@ -40,7 +41,9 @@ ${wireServicesFactory ? ' createWireServices,' : ''}
|
|
|
40
41
|
export default ${capitalizedName}CLI
|
|
41
42
|
|
|
42
43
|
// For direct execution (if this file is run directly)
|
|
43
|
-
|
|
44
|
+
${DIRECT_EXECUTION_GUARD}
|
|
45
|
+
|
|
46
|
+
if (isDirectExecution) {
|
|
44
47
|
${capitalizedName}CLI(process.argv.slice(2)).catch(error => {
|
|
45
48
|
console.error('Fatal error:', error.message)
|
|
46
49
|
process.exit(1)
|
|
@@ -40,6 +40,7 @@ import {
|
|
|
40
40
|
} from './console.schemas.gen.js'
|
|
41
41
|
|
|
42
42
|
export const pikkuConsoleSetSecret = pikkuFunc({
|
|
43
|
+
secretBroker: true,
|
|
43
44
|
tags: ['pikku'],
|
|
44
45
|
description: 'Set the value of a secret',
|
|
45
46
|
expose: true,
|
|
@@ -89,6 +90,7 @@ export const pikkuConsoleSetVariable = pikkuFunc({
|
|
|
89
90
|
})
|
|
90
91
|
|
|
91
92
|
export const pikkuConsoleHasSecret = pikkuFunc({
|
|
93
|
+
secretBroker: true,
|
|
92
94
|
tags: ['pikku'],
|
|
93
95
|
description: 'Check if a secret exists without reading its value',
|
|
94
96
|
expose: true,
|
|
@@ -101,6 +103,7 @@ export const pikkuConsoleHasSecret = pikkuFunc({
|
|
|
101
103
|
})
|
|
102
104
|
|
|
103
105
|
export const pikkuConsoleGetSecret = pikkuFunc({
|
|
106
|
+
secretBroker: true,
|
|
104
107
|
tags: ['pikku'],
|
|
105
108
|
description: 'Get the current value of a secret',
|
|
106
109
|
expose: true,
|
|
@@ -112,7 +115,7 @@ export const pikkuConsoleGetSecret = pikkuFunc({
|
|
|
112
115
|
return { exists: false, value: null }
|
|
113
116
|
}
|
|
114
117
|
const value = await secrets.getSecret(secretId)
|
|
115
|
-
return { exists: true, value }
|
|
118
|
+
return { exists: true, value: value.reveal() }
|
|
116
119
|
},
|
|
117
120
|
})
|
|
118
121
|
|
|
@@ -129,13 +132,7 @@ export const consoleRoutes = defineHTTPRoutes({
|
|
|
129
132
|
},
|
|
130
133
|
})
|
|
131
134
|
|
|
132
|
-
|
|
133
|
-
// gates the whole privileged surface (credential read/write, source editing,
|
|
134
|
-
// package install) with a single package-scoped global permission —
|
|
135
|
-
// addGlobalPermission([isAdmin], '@pikku/addon-console') — which is resolved in
|
|
136
|
-
// the addon's package namespace, so it applies to every one of its functions at
|
|
137
|
-
// once. Apps that don't register one are unaffected (no globals => allow).
|
|
138
|
-
wireAddon({ name: 'console', package: '@pikku/addon-console' })
|
|
135
|
+
wireAddon({ name: 'console', package: '@pikku/addon-console', scopes: ['admin'] })
|
|
139
136
|
wireHTTPRoutes({ basePath: '${globalHTTPPrefix}', routes: { console: consoleRoutes } })
|
|
140
137
|
`;
|
|
141
138
|
return { schemas, functions };
|
|
@@ -53,7 +53,7 @@ export const pikkuAddonConfig = <ExistingServices extends Omit<Partial<Singleton
|
|
|
53
53
|
* { secrets }
|
|
54
54
|
* ) => {
|
|
55
55
|
* const creds = await secrets.getSecret<GithubCredentials>('GITHUB_CREDENTIALS')
|
|
56
|
-
* const github = new GithubService(creds)
|
|
56
|
+
* const github = new GithubService(creds.reveal())
|
|
57
57
|
* return { github }
|
|
58
58
|
* })
|
|
59
59
|
* \`\`\`
|