@pikku/cli 0.12.90 → 0.12.92

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.
Files changed (264) hide show
  1. package/LICENSE +106 -0
  2. package/README.md +25 -2
  3. package/console-app/assets/{index-CSzCJzBb.css → index-D0HG8q0B.css} +1 -1
  4. package/console-app/assets/{index-C5Bd44e4.js → index-DDpIMCpy.js} +149 -149
  5. package/console-app/index.html +2 -2
  6. package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
  7. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
  8. package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
  9. package/dist/.pikku/cli/pikku-cli-channel.js +6 -1
  10. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
  11. package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
  12. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
  13. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
  14. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.json +15 -0
  15. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
  16. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  17. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
  18. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +43 -0
  19. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  20. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  21. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  22. package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
  23. package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
  24. package/dist/.pikku/function/pikku-function-types.gen.d.ts +4 -4
  25. package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
  26. package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
  27. package/dist/.pikku/function/pikku-functions-meta.gen.json +39 -44
  28. package/dist/.pikku/function/pikku-functions.gen.js +1 -3
  29. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  30. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  31. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  32. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  33. package/dist/.pikku/pikku-bootstrap-scenarios.gen.d.ts +9 -0
  34. package/dist/.pikku/pikku-bootstrap-scenarios.gen.js +9 -0
  35. package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
  36. package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
  37. package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
  38. package/dist/.pikku/pikku-meta-service.gen.js +1 -1
  39. package/dist/.pikku/pikku-services.gen.d.ts +1 -1
  40. package/dist/.pikku/pikku-types.gen.d.ts +1 -1
  41. package/dist/.pikku/pikku-types.gen.js +1 -1
  42. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  43. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  44. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
  45. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  46. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  47. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
  48. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +1 -1
  49. package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.d.ts +1 -0
  50. package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.js +10 -0
  51. package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.json +1 -0
  52. package/dist/.pikku/scenarios/pikku-scenario-functions.gen.d.ts +4 -0
  53. package/dist/.pikku/scenarios/pikku-scenario-functions.gen.js +1 -0
  54. package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.d.ts +1 -0
  55. package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +10 -0
  56. package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.d.ts +4 -0
  57. package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.js +1 -0
  58. package/dist/.pikku/scenarios/schemas/register.gen.d.ts +4 -0
  59. package/dist/.pikku/scenarios/schemas/register.gen.js +4 -0
  60. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  61. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  62. package/dist/.pikku/schemas/register.gen.js +5 -3
  63. package/dist/.pikku/schemas/schemas/FabricSecretsListOutput.schema.json +1 -1
  64. package/dist/.pikku/schemas/schemas/FabricSecretsRotateInput.schema.json +1 -0
  65. package/dist/.pikku/schemas/schemas/FabricSecretsRotateOutput.schema.json +1 -0
  66. package/dist/.pikku/schemas/schemas/FabricSecretsSetOutput.schema.json +1 -1
  67. package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
  68. package/dist/.pikku/schemas/schemas/ScenarioRunInput.schema.json +1 -1
  69. package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +1 -1
  70. package/dist/.pikku/scopes/pikku-scope-types.gen.js +1 -1
  71. package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
  72. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
  73. package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
  74. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
  75. package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
  76. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
  77. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
  78. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
  79. package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
  80. package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
  81. package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
  82. package/dist/.pikku/workflow/meta/allWorkflow.gen.json +2 -8
  83. package/dist/.pikku/workflow/pikku-scenario-actors.gen.d.ts +19 -0
  84. package/dist/.pikku/workflow/pikku-scenario-actors.gen.js +17 -0
  85. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +152 -3
  86. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +39 -1
  87. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
  88. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
  89. package/dist/bin/pikku-bin.mjs +2 -2
  90. package/dist/src/cli.wiring.js +28 -0
  91. package/dist/src/deploy/analyzer/analyzer.js +22 -5
  92. package/dist/src/deploy/build-pipeline.js +5 -1
  93. package/dist/src/fabric/fabric-commands.d.ts +37 -9
  94. package/dist/src/fabric/fabric-commands.js +12 -0
  95. package/dist/src/fabric/functions/domains-add.function.d.ts +4 -4
  96. package/dist/src/fabric/functions/secrets-list.function.d.ts +16 -4
  97. package/dist/src/fabric/functions/secrets-list.function.js +12 -10
  98. package/dist/src/fabric/functions/secrets-rotate.function.d.ts +24 -0
  99. package/dist/src/fabric/functions/secrets-rotate.function.js +36 -0
  100. package/dist/src/fabric/functions/secrets-set.function.d.ts +8 -4
  101. package/dist/src/fabric/functions/secrets-set.function.js +18 -7
  102. package/dist/src/fabric/lib/http.d.ts +7 -1
  103. package/dist/src/fabric/lib/sealed-box.d.ts +16 -0
  104. package/dist/src/fabric/lib/sealed-box.js +72 -0
  105. package/dist/src/functions/commands/dev.js +11 -0
  106. package/dist/src/functions/commands/load-user-project.d.ts +7 -0
  107. package/dist/src/functions/commands/load-user-project.js +21 -0
  108. package/dist/src/functions/commands/pikku-command-bootstrap.js +13 -0
  109. package/dist/src/functions/commands/scenario-browser.d.ts +84 -0
  110. package/dist/src/functions/commands/scenario-browser.js +68 -0
  111. package/dist/src/functions/commands/scenario-environment.d.ts +32 -0
  112. package/dist/src/functions/commands/scenario-environment.js +61 -0
  113. package/dist/src/functions/commands/scenario-formatter.d.ts +81 -0
  114. package/dist/src/functions/commands/scenario-formatter.js +120 -0
  115. package/dist/src/functions/commands/scenario-ladder.d.ts +66 -0
  116. package/dist/src/functions/commands/scenario-ladder.js +132 -0
  117. package/dist/src/functions/commands/scenario-plan.d.ts +61 -0
  118. package/dist/src/functions/commands/scenario-plan.js +106 -0
  119. package/dist/src/functions/commands/scenario.d.ts +24 -0
  120. package/dist/src/functions/commands/scenario.js +322 -50
  121. package/dist/src/functions/commands/serve.js +2 -0
  122. package/dist/src/functions/commands/skills.js +27 -61
  123. package/dist/src/functions/db/db-codegen.d.ts +6 -0
  124. package/dist/src/functions/db/db-codegen.js +9 -0
  125. package/dist/src/functions/db/db-migrator.js +14 -0
  126. package/dist/src/functions/db/local-db.d.ts +8 -0
  127. package/dist/src/functions/db/local-db.js +24 -2
  128. package/dist/src/functions/db/migration-identifiers.d.ts +58 -0
  129. package/dist/src/functions/db/migration-identifiers.js +262 -0
  130. package/dist/src/functions/db/migration-provenance.d.ts +35 -0
  131. package/dist/src/functions/db/migration-provenance.js +80 -0
  132. package/dist/src/functions/db/schema-sql.d.ts +43 -0
  133. package/dist/src/functions/db/schema-sql.js +135 -0
  134. package/dist/src/functions/db/sqlite/sqlite-kysely.js +22 -2
  135. package/dist/src/functions/wirings/functions/pikku-command-functions.js +26 -8
  136. package/dist/src/functions/wirings/functions/schemas.js +13 -1
  137. package/dist/src/functions/wirings/functions/serialize-function-types.js +3 -3
  138. package/dist/src/functions/wirings/rpc/pikku-command-rpc.js +6 -1
  139. package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.d.ts +10 -0
  140. package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.js +102 -0
  141. package/dist/src/functions/wirings/scenarios/scenario-partition.d.ts +42 -0
  142. package/dist/src/functions/wirings/scenarios/scenario-partition.js +71 -0
  143. package/dist/src/functions/wirings/scenarios/scenario-schema-partition.d.ts +33 -0
  144. package/dist/src/functions/wirings/scenarios/scenario-schema-partition.js +49 -0
  145. package/dist/src/functions/wirings/scenarios/serialize-feature-meta.d.ts +14 -0
  146. package/dist/src/functions/wirings/scenarios/serialize-feature-meta.js +29 -0
  147. package/dist/src/functions/wirings/scenarios/serialize-scenario-meta.d.ts +12 -0
  148. package/dist/src/functions/wirings/scenarios/serialize-scenario-meta.js +56 -0
  149. package/dist/src/functions/wirings/scenarios/serialize-scenario-registration.d.ts +7 -0
  150. package/dist/src/functions/wirings/scenarios/serialize-scenario-registration.js +40 -0
  151. package/dist/src/functions/wirings/workflow/pikku-command-workflow.js +43 -8
  152. package/dist/src/functions/wirings/workflow/serialize-scenario-actors.d.ts +1 -1
  153. package/dist/src/functions/wirings/workflow/serialize-scenario-actors.js +13 -2
  154. package/dist/src/functions/wirings/workflow/serialize-scenario-step-map.d.ts +4 -0
  155. package/dist/src/functions/wirings/workflow/serialize-scenario-step-map.js +62 -0
  156. package/dist/src/functions/wirings/workflow/serialize-workflow-bootstrap-map.js +10 -3
  157. package/dist/src/functions/wirings/workflow/serialize-workflow-map.js +10 -3
  158. package/dist/src/functions/wirings/workflow/serialize-workflow-meta.js +4 -4
  159. package/dist/src/functions/wirings/workflow/serialize-workflow-types.d.ts +1 -1
  160. package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +232 -3
  161. package/dist/src/functions/workflows/all.workflow.js +2 -7
  162. package/dist/src/server/server-ready.d.ts +12 -0
  163. package/dist/src/server/server-ready.js +12 -0
  164. package/dist/src/server/spawn-dev-server.d.ts +50 -0
  165. package/dist/src/server/spawn-dev-server.js +112 -0
  166. package/dist/src/services.js +12 -1
  167. package/dist/src/utils/file-writer.js +14 -2
  168. package/dist/src/utils/meta-diff.js +5 -2
  169. package/dist/src/utils/pikku-cli-config.d.ts +14 -0
  170. package/dist/src/utils/pikku-cli-config.js +60 -0
  171. package/dist/src/utils/remove-legacy-scaffold-file.d.ts +14 -0
  172. package/dist/src/utils/remove-legacy-scaffold-file.js +23 -0
  173. package/dist/src/utils/resolve-scenario-actors.d.ts +23 -0
  174. package/dist/src/utils/resolve-scenario-actors.js +74 -0
  175. package/dist/src/utils/serialize-schemas.d.ts +3 -1
  176. package/dist/src/utils/serialize-schemas.js +39 -4
  177. package/dist/tsconfig.tsbuildinfo +1 -1
  178. package/package.json +18 -8
  179. package/dist/.pikku/schemas/schemas/PikkuScenarioFunctionsOutput.schema.json +0 -1
  180. package/dist/src/functions/wirings/scenarios/pikku-command-scenario-functions.d.ts +0 -1
  181. package/dist/src/functions/wirings/scenarios/pikku-command-scenario-functions.js +0 -31
  182. package/dist/src/functions/wirings/scenarios/serialize-scenario-functions.d.ts +0 -10
  183. package/dist/src/functions/wirings/scenarios/serialize-scenario-functions.js +0 -104
  184. package/skills/pikku-addon/SKILL.md +0 -243
  185. package/skills/pikku-addon/references/addon-package-manifest.md +0 -63
  186. package/skills/pikku-ai-agent/SKILL.md +0 -231
  187. package/skills/pikku-ai-vercel/SKILL.md +0 -82
  188. package/skills/pikku-ai-voice/SKILL.md +0 -88
  189. package/skills/pikku-audit/SKILL.md +0 -175
  190. package/skills/pikku-aws/SKILL.md +0 -111
  191. package/skills/pikku-backblaze/SKILL.md +0 -71
  192. package/skills/pikku-better-auth/SKILL.md +0 -298
  193. package/skills/pikku-cli/SKILL.md +0 -198
  194. package/skills/pikku-cli/references/complete-example.md +0 -82
  195. package/skills/pikku-concepts/SKILL.md +0 -250
  196. package/skills/pikku-concepts/references/concept-mapping.md +0 -556
  197. package/skills/pikku-concepts/references/packages.md +0 -29
  198. package/skills/pikku-config/SKILL.md +0 -212
  199. package/skills/pikku-cron/SKILL.md +0 -214
  200. package/skills/pikku-deploy-azure/SKILL.md +0 -71
  201. package/skills/pikku-deploy-cloudflare/SKILL.md +0 -82
  202. package/skills/pikku-deploy-express/SKILL.md +0 -86
  203. package/skills/pikku-deploy-fastify/SKILL.md +0 -73
  204. package/skills/pikku-deploy-lambda/SKILL.md +0 -110
  205. package/skills/pikku-deploy-nextjs/SKILL.md +0 -78
  206. package/skills/pikku-deploy-uws/SKILL.md +0 -88
  207. package/skills/pikku-deps/SKILL.md +0 -98
  208. package/skills/pikku-emails/SKILL.md +0 -163
  209. package/skills/pikku-fabric/SKILL.md +0 -318
  210. package/skills/pikku-fabric-debug/SKILL.md +0 -112
  211. package/skills/pikku-feature/SKILL.md +0 -258
  212. package/skills/pikku-gateway-slack/SKILL.md +0 -115
  213. package/skills/pikku-http/SKILL.md +0 -220
  214. package/skills/pikku-http/references/http-options.md +0 -55
  215. package/skills/pikku-i18n/SKILL.md +0 -137
  216. package/skills/pikku-info/SKILL.md +0 -100
  217. package/skills/pikku-jose/SKILL.md +0 -105
  218. package/skills/pikku-kysely/SKILL.md +0 -219
  219. package/skills/pikku-machine-auth/SKILL.md +0 -183
  220. package/skills/pikku-mcp/SKILL.md +0 -241
  221. package/skills/pikku-middleware/SKILL.md +0 -231
  222. package/skills/pikku-middleware/references/middleware-patterns.md +0 -61
  223. package/skills/pikku-mongodb/SKILL.md +0 -105
  224. package/skills/pikku-n8n-import/SKILL.md +0 -109
  225. package/skills/pikku-n8n-import/SPEC.md +0 -84
  226. package/skills/pikku-n8n-import/references/addon-mapping.md +0 -121
  227. package/skills/pikku-n8n-import/references/code-translation.md +0 -121
  228. package/skills/pikku-n8n-import/references/loops-and-control.md +0 -87
  229. package/skills/pikku-paraglide/SKILL.md +0 -117
  230. package/skills/pikku-permissions/SKILL.md +0 -192
  231. package/skills/pikku-pino/SKILL.md +0 -79
  232. package/skills/pikku-product-second-opinion/README.md +0 -43
  233. package/skills/pikku-product-second-opinion/SKILL.md +0 -158
  234. package/skills/pikku-product-second-opinion/example/sample-report.md +0 -90
  235. package/skills/pikku-product-second-opinion/references/report-template.md +0 -73
  236. package/skills/pikku-queue/SKILL.md +0 -240
  237. package/skills/pikku-react/SKILL.md +0 -212
  238. package/skills/pikku-react-query/SKILL.md +0 -242
  239. package/skills/pikku-realtime/SKILL.md +0 -236
  240. package/skills/pikku-realtime/references/other-routes.md +0 -23
  241. package/skills/pikku-redis/SKILL.md +0 -90
  242. package/skills/pikku-rpc/SKILL.md +0 -171
  243. package/skills/pikku-rtl/SKILL.md +0 -219
  244. package/skills/pikku-scenario/SKILL.md +0 -215
  245. package/skills/pikku-schedule/SKILL.md +0 -57
  246. package/skills/pikku-schema-ajv/SKILL.md +0 -62
  247. package/skills/pikku-schema-cfworker/SKILL.md +0 -63
  248. package/skills/pikku-security/SKILL.md +0 -108
  249. package/skills/pikku-services/SKILL.md +0 -248
  250. package/skills/pikku-services/references/audit-wire-service.md +0 -34
  251. package/skills/pikku-software-archaeology/README.md +0 -70
  252. package/skills/pikku-software-archaeology/SKILL.md +0 -186
  253. package/skills/pikku-software-archaeology/references/blueprint.schema.json +0 -625
  254. package/skills/pikku-software-archaeology/references/pikku-mapping.md +0 -49
  255. package/skills/pikku-software-archaeology/scripts/validate.mjs +0 -173
  256. package/skills/pikku-tag-middleware/SKILL.md +0 -13
  257. package/skills/pikku-template-clone/SKILL.md +0 -40
  258. package/skills/pikku-trigger/SKILL.md +0 -181
  259. package/skills/pikku-versioning/SKILL.md +0 -173
  260. package/skills/pikku-websocket/SKILL.md +0 -243
  261. package/skills/pikku-workflow/SKILL.md +0 -172
  262. package/skills/pikku-workflow/references/workflow-reference.md +0 -63
  263. package/skills/pikku-workflows-client/SKILL.md +0 -150
  264. package/skills/pikku-ws/SKILL.md +0 -47
@@ -1,22 +1,36 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.90
2
+ * This file was generated by @pikku/cli@0.12.92
3
3
  */
4
4
  import { WorkflowCancelledException } from '@pikku/core/workflow';
5
5
  import { template } from '@pikku/core/workflow';
6
6
  import { type PikkuWorkflowGraphConfig, type PikkuWorkflowGraphResult } from '@pikku/core/workflow';
7
- import type { PikkuWorkflowWire, PikkuScenarioWire, WorkflowStepOptions } from '@pikku/core/workflow';
7
+ import type { PikkuWorkflowWire, PikkuScenarioWire, WorkflowStepOptions, ScenarioStepOptions } from '@pikku/core/workflow';
8
8
  export { WorkflowCancelledException };
9
9
  import type { PikkuFunctionSessionless, PikkuFunctionConfig } from '../function/pikku-function-types.gen.js';
10
10
  import type { FlattenedRPCMap } from '../rpc/pikku-rpc-wirings-map.internal.gen.d.js';
11
11
  import type { FlattenedWorkflowMap } from './pikku-workflow-map.gen.d.js';
12
12
  import type { AgentMap as FlattenedAgentMap } from '../agent/pikku-agent-map.gen.d.js';
13
+ import type { FlattenedScenarioStepMap } from './pikku-scenario-step-map.gen.d.js';
14
+ import type { TypedScenarioActors } from './pikku-scenario-actors.gen.js';
15
+ export type { TypedScenarioActors };
13
16
  export { template };
14
17
  export interface TypedWorkflow extends PikkuWorkflowWire {
15
18
  do<K extends keyof FlattenedRPCMap>(stepName: string, rpcName: K, data: FlattenedRPCMap[K]['input'], options?: WorkflowStepOptions): Promise<FlattenedRPCMap[K]['output']>;
16
19
  do<K extends keyof FlattenedWorkflowMap>(stepName: string, workflowName: K, data: FlattenedWorkflowMap[K]['input'], options?: WorkflowStepOptions): Promise<FlattenedWorkflowMap[K]['output']>;
17
20
  do<T>(stepName: string, fn: () => T | Promise<T>, options?: WorkflowStepOptions): Promise<T>;
18
21
  }
19
- export type TypedScenario = TypedWorkflow & Omit<PikkuScenarioWire, keyof PikkuWorkflowWire>;
22
+ /**
23
+ * The typed half of a scenario wire: `step` and its `given`/`when`/`then`
24
+ * sugar, narrowed to the names declared by `pikkuScenarioStep` in this project.
25
+ * The phase only changes the prose the reporter renders.
26
+ */
27
+ export interface TypedScenarioSteps {
28
+ step<K extends keyof FlattenedScenarioStepMap>(stepName: string, stepFunc: K, data?: FlattenedScenarioStepMap[K]['input'], options?: ScenarioStepOptions): Promise<FlattenedScenarioStepMap[K]['output']>;
29
+ given<K extends keyof FlattenedScenarioStepMap>(stepName: string, stepFunc: K, data?: FlattenedScenarioStepMap[K]['input'], options?: ScenarioStepOptions): Promise<FlattenedScenarioStepMap[K]['output']>;
30
+ when<K extends keyof FlattenedScenarioStepMap>(stepName: string, stepFunc: K, data?: FlattenedScenarioStepMap[K]['input'], options?: ScenarioStepOptions): Promise<FlattenedScenarioStepMap[K]['output']>;
31
+ then<K extends keyof FlattenedScenarioStepMap>(stepName: string, stepFunc: K, data?: FlattenedScenarioStepMap[K]['input'], options?: ScenarioStepOptions): Promise<FlattenedScenarioStepMap[K]['output']>;
32
+ }
33
+ export type TypedScenario = TypedWorkflow & Omit<PikkuScenarioWire, keyof PikkuWorkflowWire | keyof TypedScenarioSteps> & TypedScenarioSteps;
20
34
  import type { StandardSchemaV1 } from '@standard-schema/spec';
21
35
  import type { InferSchemaOutput, PikkuPermission, PikkuMiddleware, NodeConfig, PikkuApprovalDescription } from '../function/pikku-function-types.gen.js';
22
36
  import type { ScopeId } from '../scopes/pikku-scopes.gen.js';
@@ -58,7 +72,39 @@ export declare function pikkuWorkflowComplexFunc<InputSchema extends StandardSch
58
72
  export declare function pikkuWorkflowComplexFunc<In, Out = unknown>(func: PikkuFunctionWorkflow<In, Out> | PikkuFunctionConfig<In, Out, 'workflow', PikkuFunctionWorkflow<In, Out>>): PikkuFunctionConfig<In, Out, 'workflow'>;
59
73
  export type PikkuScenarioConfigWithSchema<InputSchema extends StandardSchemaV1 | undefined = undefined, OutputSchema extends StandardSchemaV1 | undefined = undefined> = Omit<PikkuWorkflowConfigWithSchema<InputSchema, OutputSchema>, 'func' | 'auth' | 'scopes' | 'permissions'> & {
60
74
  func: PikkuFunctionScenario<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown>;
75
+ /**
76
+ * Runs before the scenario body. Same signature as `func`, but its return
77
+ * value is discarded — a hook is setup, not a step, so it is never recorded
78
+ * on the ladder. Throwing skips the body and fails the run; `after` still
79
+ * runs.
80
+ */
81
+ before?: PikkuScenarioHook<InputSchema>;
82
+ /**
83
+ * Always runs after the scenario body, in a `finally`, whether it passed or
84
+ * failed. Throwing fails a run that would otherwise have passed; on an
85
+ * already-failed run it attaches as the `cause` and never replaces the
86
+ * original error.
87
+ */
88
+ after?: PikkuScenarioHook<InputSchema>;
89
+ /**
90
+ * Why this scenario is held out of a default run, stated where the scenario
91
+ * is. The scenario still appears in the plan and is reported as skipped
92
+ * rather than quietly omitted; naming it directly with `--flows` runs it
93
+ * anyway.
94
+ */
95
+ skip?: string;
61
96
  };
97
+ /**
98
+ * A scenario lifecycle hook: the scenario's own `(services, data, wire)`
99
+ * signature with its result discarded.
100
+ */
101
+ export type PikkuScenarioHook<InputSchema extends StandardSchemaV1 | undefined = undefined> = PikkuFunctionScenario<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, void>;
102
+ /**
103
+ * Declares a scenario hook. Returns the function verbatim — a hook is never
104
+ * registered, so this exists purely to give an inline hook a call site to be
105
+ * contextually typed from, the way every other pikku primitive is.
106
+ */
107
+ export declare function pikkuScenarioHook<In = unknown>(hook: PikkuFunctionScenario<In, void>): PikkuFunctionScenario<In, void>;
62
108
  /**
63
109
  * A scenario: a complex workflow that drives the app the way users do.
64
110
  * Steps run as actors over the REAL transport — `scenario.do(step, rpc,
@@ -67,6 +113,109 @@ export type PikkuScenarioConfigWithSchema<InputSchema extends StandardSchemaV1 |
67
113
  */
68
114
  export declare function pikkuScenario<InputSchema extends StandardSchemaV1 | undefined = undefined, OutputSchema extends StandardSchemaV1 | undefined = undefined>(config: PikkuScenarioConfigWithSchema<InputSchema, OutputSchema>): PikkuFunctionConfig<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'scenario' | 'actors', PikkuFunctionScenario<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown>, InputSchema, OutputSchema>;
69
115
  export declare function pikkuScenario<In, Out = unknown>(func: PikkuFunctionScenario<In, Out> | PikkuFunctionConfig<In, Out, 'scenario' | 'actors', PikkuFunctionScenario<In, Out>>): PikkuFunctionConfig<In, Out, 'scenario' | 'actors'>;
116
+ /**
117
+ * A scenario as a feature references it. Any `pikkuScenario` export is
118
+ * assignable; `In` is recovered from it so the paired form's `data` is
119
+ * checked against that scenario's own input.
120
+ */
121
+ export type PikkuScenarioRef<In = any, Out = any> = PikkuFunctionConfig<In, Out, 'scenario' | 'actors', PikkuFunctionScenario<In, Out>, any, any>;
122
+ /**
123
+ * One entry in a feature's `scenarios` list, validated against itself: a bare
124
+ * scenario, or a scenario paired with the input to run it with. The paired form
125
+ * is gherkin's `Examples:` written as an ordinary loop.
126
+ */
127
+ export type PikkuFeatureEntry<Entry> = Entry extends {
128
+ scenario: PikkuScenarioRef<infer In>;
129
+ } ? {
130
+ scenario: PikkuScenarioRef<In>;
131
+ data: In;
132
+ } : Entry extends PikkuScenarioRef ? Entry : never;
133
+ export type PikkuFeatureConfig<Scenarios extends readonly unknown[]> = {
134
+ /** Human-readable name. The export identifier is the id. */
135
+ name: string;
136
+ description?: string;
137
+ tags?: string[];
138
+ scenarios: {
139
+ [K in keyof Scenarios]: PikkuFeatureEntry<Scenarios[K]>;
140
+ };
141
+ /**
142
+ * Runs ONCE before the whole group — not before each scenario. Per-scenario
143
+ * setup is the scenario's own `before`; gherkin's `Background:` is
144
+ * deliberately not expressible here.
145
+ */
146
+ before?: PikkuScenarioHook;
147
+ after?: PikkuScenarioHook;
148
+ };
149
+ /**
150
+ * A feature: an ordered group of scenarios, mirroring gherkin's Feature ↔
151
+ * Scenario structure. Scenarios are referenced by imported identifier, so a
152
+ * renamed or deleted scenario is a compile error rather than a silent skip.
153
+ *
154
+ * A scenario does not have to belong to a feature — a void-input scenario
155
+ * still runs standalone.
156
+ *
157
+ * ```ts
158
+ * export const credentialFeature = pikkuFeature({
159
+ * name: 'Credential API',
160
+ * tags: ['credential'],
161
+ * before: startsMockOAuthServer,
162
+ * after: stopsMockOAuthServer,
163
+ * scenarios: [
164
+ * credentialLazyLoadScenario,
165
+ * ...['stripe', 'google'].map((name) => ({
166
+ * scenario: credentialRoundTripScenario,
167
+ * data: { name },
168
+ * })),
169
+ * ],
170
+ * })
171
+ * ```
172
+ */
173
+ export declare function pikkuFeature<const Scenarios extends readonly unknown[]>(config: PikkuFeatureConfig<Scenarios>): PikkuFeatureConfig<Scenarios>;
174
+ export type PikkuFunctionScenarioStep<In = unknown, Out = never, B extends boolean = false> = PikkuFunctionSessionless<In, Out, B extends true ? 'scenarioStep' | 'browser' : 'scenarioStep'>;
175
+ export type PikkuScenarioStepConfigWithSchema<InputSchema extends StandardSchemaV1 | undefined = undefined, OutputSchema extends StandardSchemaV1 | undefined = undefined, B extends boolean = false> = {
176
+ /** Registered name — this is the string `scenario.step()` references. */
177
+ name: string;
178
+ /**
179
+ * What this step does, for the console and for whoever reads the source. It
180
+ * is also the fallback prose when no `template` is declared, in which case a
181
+ * reporter renders "Given the shopper buys an apple". Defaults to the call
182
+ * site's step name.
183
+ */
184
+ description?: string;
185
+ /**
186
+ * The prose a reporter renders for this step, with `{placeholders}` filled
187
+ * from the input the step was called with — `'sees {packageName}'` reports as
188
+ * "Then the admin sees @pikku/addon-todos". Every input field should appear,
189
+ * so the report names the values under test rather than repeating one
190
+ * sentence per call site.
191
+ */
192
+ template?: string;
193
+ /**
194
+ * This step drives a browser. The runner provisions one for the step's actor
195
+ * before calling it — which also makes an actor mandatory — and `wire.browser`
196
+ * is non-optional inside `func`.
197
+ */
198
+ browser?: B;
199
+ title?: string;
200
+ tags?: string[];
201
+ input?: InputSchema;
202
+ output?: OutputSchema;
203
+ errors?: Array<typeof PikkuError>;
204
+ func: PikkuFunctionScenarioStep<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, B>;
205
+ };
206
+ export type PikkuScenarioStepConfig<In, Out, B extends boolean = false> = Omit<PikkuScenarioStepConfigWithSchema<undefined, undefined, B>, 'func' | 'input' | 'output'> & {
207
+ func: PikkuFunctionScenarioStep<In, Out, B>;
208
+ };
209
+ /**
210
+ * A named, reusable scenario step. Unlike `scenario.do`, which can only name an
211
+ * RPC, a step's body is an ordinary pikku function — so it may drive a browser,
212
+ * invoke RPCs as its actor, or run a workflow.
213
+ *
214
+ * Steps are deliberately NOT registered as RPCs: a browser-driving step must
215
+ * never be network-callable.
216
+ */
217
+ export declare function pikkuScenarioStep<InputSchema extends StandardSchemaV1 | undefined = undefined, OutputSchema extends StandardSchemaV1 | undefined = undefined, B extends boolean = false>(config: PikkuScenarioStepConfigWithSchema<InputSchema, OutputSchema, B>): PikkuFunctionConfig<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, B extends true ? 'scenarioStep' | 'browser' : 'scenarioStep', PikkuFunctionScenarioStep<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, B>, InputSchema, OutputSchema>;
218
+ export declare function pikkuScenarioStep<In, Out = unknown, B extends boolean = false>(config: PikkuScenarioStepConfig<In, Out, B>): PikkuFunctionConfig<In, Out, B extends true ? 'scenarioStep' | 'browser' : 'scenarioStep'>;
70
219
  type TypedRef<T> = {
71
220
  $ref: string;
72
221
  path?: string;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.90
2
+ * This file was generated by @pikku/cli@0.12.92
3
3
  */
4
4
  import { WorkflowCancelledException } from '@pikku/core/workflow';
5
5
  import { template } from '@pikku/core/workflow';
@@ -12,9 +12,47 @@ export function pikkuWorkflowFunc(func) {
12
12
  export function pikkuWorkflowComplexFunc(func) {
13
13
  return typeof func === 'function' ? { func } : func;
14
14
  }
15
+ /**
16
+ * Declares a scenario hook. Returns the function verbatim — a hook is never
17
+ * registered, so this exists purely to give an inline hook a call site to be
18
+ * contextually typed from, the way every other pikku primitive is.
19
+ */
20
+ export function pikkuScenarioHook(hook) {
21
+ return hook;
22
+ }
15
23
  export function pikkuScenario(func) {
16
24
  return typeof func === 'function' ? { func } : func;
17
25
  }
26
+ /**
27
+ * A feature: an ordered group of scenarios, mirroring gherkin's Feature ↔
28
+ * Scenario structure. Scenarios are referenced by imported identifier, so a
29
+ * renamed or deleted scenario is a compile error rather than a silent skip.
30
+ *
31
+ * A scenario does not have to belong to a feature — a void-input scenario
32
+ * still runs standalone.
33
+ *
34
+ * ```ts
35
+ * export const credentialFeature = pikkuFeature({
36
+ * name: 'Credential API',
37
+ * tags: ['credential'],
38
+ * before: startsMockOAuthServer,
39
+ * after: stopsMockOAuthServer,
40
+ * scenarios: [
41
+ * credentialLazyLoadScenario,
42
+ * ...['stripe', 'google'].map((name) => ({
43
+ * scenario: credentialRoundTripScenario,
44
+ * data: { name },
45
+ * })),
46
+ * ],
47
+ * })
48
+ * ```
49
+ */
50
+ export function pikkuFeature(config) {
51
+ return config;
52
+ }
53
+ export function pikkuScenarioStep(config) {
54
+ return config;
55
+ }
18
56
  export function pikkuWorkflowGraph(config) {
19
57
  return corePikkuWorkflowGraph(config);
20
58
  }
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.90
2
+ * This file was generated by @pikku/cli@0.12.92
3
3
  */
4
4
  import { pikkuState } from '@pikku/core/internal';
5
5
  import allWorkflowMeta from './meta/allWorkflow.gen.json' with { type: 'json' };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.90
2
+ * This file was generated by @pikku/cli@0.12.92
3
3
  */
4
4
  import { addWorkflow } from '@pikku/core/workflow';
5
5
  import './pikku-workflow-wirings-meta.gen.js';
@@ -11,8 +11,8 @@ async function checkForUpdate() {
11
11
  })
12
12
  if (!res.ok) return
13
13
  const { version: latest } = await res.json()
14
- if (latest !== '0.12.90') {
15
- process.stderr.write(`\n Update available 0.12.90 → ${latest}\n brew upgrade pikku or npm install -g @pikku/cli\n\n`)
14
+ if (latest !== '0.12.92') {
15
+ process.stderr.write(`\n Update available 0.12.92 → ${latest}\n brew upgrade pikku or npm install -g @pikku/cli\n\n`)
16
16
  }
17
17
  } catch {}
18
18
  }
@@ -397,14 +397,42 @@ wireCLI({
397
397
  description: 'Comma-separated flow names to run (default: all)',
398
398
  short: 'f',
399
399
  },
400
+ features: {
401
+ description: 'Comma-separated feature names to run (pikkuFeature exports) — the feature is the run unit, so its hooks run once around the group',
402
+ },
400
403
  tags: {
401
404
  description: 'Comma-separated tags — run flows matching any',
402
405
  short: 't',
403
406
  },
407
+ excludeTags: {
408
+ description: 'Comma-separated tags to hold back — flows matching any are not run, unless named directly with --flows',
409
+ },
404
410
  coverage: {
405
411
  description: 'Reset/snapshot server coverage per scenario (target must run with --coverage); writes coverage/scenario-coverage.json',
406
412
  default: false,
407
413
  },
414
+ browser: {
415
+ description: 'Run scenarios with browser steps. --no-browser skips them (they are reported as skipped, not failed)',
416
+ default: true,
417
+ },
418
+ spawn: {
419
+ description: "Start `pikku dev` on the environment's apiUrl for the run and stop it afterwards. Without it, the environment must already be serving",
420
+ default: false,
421
+ },
422
+ keepAlive: {
423
+ description: 'With --spawn, leave the server running after the run (dev loop)',
424
+ default: false,
425
+ },
426
+ trace: {
427
+ description: 'Keep every stack frame on a failure. Without it, only the project’s own frames are shown',
428
+ default: false,
429
+ },
430
+ apiUrl: {
431
+ description: "Override the environment's apiUrl for this run — for a target that only exists at run time, such as a freshly deployed sandbox",
432
+ },
433
+ appUrl: {
434
+ description: "Override the environment's appUrl for this run (the frontend browser steps navigate against)",
435
+ },
408
436
  },
409
437
  }),
410
438
  list: pikkuCLICommand({
@@ -7,6 +7,7 @@
7
7
  * Workflow orchestrators dispatch to step units via queue or RPC (inline).
8
8
  */
9
9
  import { resolveDeployTarget, } from '@pikku/inspector';
10
+ import { isScenarioFunction, withoutScenarios, withoutScenarioWorkflows, } from '../../functions/wirings/scenarios/scenario-partition.js';
10
11
  export function analyzeDeployment(state, options) {
11
12
  const serverlessIncompatible = new Set(options.serverlessIncompatible ?? []);
12
13
  const defaultTarget = options.defaultTarget ?? 'serverless';
@@ -18,7 +19,13 @@ export function analyzeDeployment(state, options) {
18
19
  const agents = [];
19
20
  const mcpEndpoints = [];
20
21
  const workflows = [];
21
- const functionsMeta = state.functions.meta;
22
+ // Scenarios, features and steps are test artifacts that happen to be built out
23
+ // of functions and workflows, so without this they analyze like application
24
+ // code: every scenario became its own unit, its own `WorkflowDefinition` and —
25
+ // because a scenario IS a workflow — a `wf-orchestrator-<scenario>` queue that
26
+ // a provider would then create in production.
27
+ const functionsMeta = withoutScenarios(state.functions.meta);
28
+ const graphMeta = withoutScenarioWorkflows(state.workflows.graphMeta);
22
29
  const httpMeta = state.http.meta;
23
30
  // ── Step 1: Create function units ──────────────────────────────────
24
31
  // Each function gets one unit. Collect all its triggers.
@@ -190,9 +197,19 @@ export function analyzeDeployment(state, options) {
190
197
  });
191
198
  }
192
199
  // ── Step 3: MCP gateway ────────────────────────────────────────────
193
- const mcpToolIds = values(state.mcpEndpoints.toolsMeta).map((t) => t.pikkuFuncId);
194
- const mcpResourceIds = values(state.mcpEndpoints.resourcesMeta).map((r) => r.pikkuFuncId);
195
- const mcpPromptIds = values(state.mcpEndpoints.promptsMeta).map((p) => p.pikkuFuncId);
200
+ // The MCP metas are keyed by wiring, not by function, so they are the one
201
+ // place a scenario or step id can still arrive from raw state. A gateway that
202
+ // lists one would depend on a unit that was never emitted.
203
+ const deployableFuncId = (funcId) => !isScenarioFunction(state.functions.meta[funcId]);
204
+ const mcpToolIds = values(state.mcpEndpoints.toolsMeta)
205
+ .map((t) => t.pikkuFuncId)
206
+ .filter(deployableFuncId);
207
+ const mcpResourceIds = values(state.mcpEndpoints.resourcesMeta)
208
+ .map((r) => r.pikkuFuncId)
209
+ .filter(deployableFuncId);
210
+ const mcpPromptIds = values(state.mcpEndpoints.promptsMeta)
211
+ .map((p) => p.pikkuFuncId)
212
+ .filter(deployableFuncId);
196
213
  // Include functions explicitly marked mcp: true
197
214
  for (const [funcId, funcMeta] of entries(functionsMeta)) {
198
215
  if (funcMeta.mcp &&
@@ -248,7 +265,7 @@ export function analyzeDeployment(state, options) {
248
265
  });
249
266
  }
250
267
  // ── Step 5: Workflows ──────────────────────────────────────────────
251
- buildWorkflows(state.workflows.graphMeta, functionsMeta, { ...state.rpc?.exposedMeta, ...state.rpc?.internalMeta }, httpMeta, units, workflows, queues, workflowQueues);
268
+ buildWorkflows(graphMeta, functionsMeta, { ...state.rpc?.exposedMeta, ...state.rpc?.internalMeta }, httpMeta, units, workflows, queues, workflowQueues);
252
269
  // ── Step 6: Ensure function units exist for gateway dependencies ───
253
270
  // Gateways depend on function units. If a function is only used via
254
271
  // a gateway (not directly wired to HTTP/queue/cron), it still needs
@@ -8,6 +8,7 @@ import { join } from 'node:path';
8
8
  import { existsSync } from 'node:fs';
9
9
  import { mkdir, writeFile, copyFile } from 'node:fs/promises';
10
10
  import { analyzeDeployment } from './analyzer/index.js';
11
+ import { withoutScenarios } from '../functions/wirings/scenarios/scenario-partition.js';
11
12
  import { generatePerUnitCodegen } from './codegen/per-unit-codegen.js';
12
13
  import { generateServerEntrySource, SERVER_DOCKERFILE, SERVER_DOCKERIGNORE, } from './server-entry.js';
13
14
  const MERGED_SERVER_UNIT_NAME = 'pikku-server-container';
@@ -63,7 +64,10 @@ export async function runBuildPipeline(options) {
63
64
  name: unitName,
64
65
  role: 'function',
65
66
  target: 'serverless',
66
- functionIds: Object.keys(inspectorState.functions.meta),
67
+ // Scenarios and steps are excluded for the same reason the analyzer drops
68
+ // them: a single-unit bundle is still a deployment, and a test harness has
69
+ // no business inside one.
70
+ functionIds: Object.keys(withoutScenarios(inspectorState.functions.meta)),
67
71
  services: [],
68
72
  dependsOn: [],
69
73
  handlers: [],
@@ -451,37 +451,65 @@ export declare const fabricCommands: {
451
451
  value?: string | undefined;
452
452
  force?: boolean | undefined;
453
453
  }, {
454
- ok: boolean;
454
+ name: string;
455
+ keyId: string;
455
456
  }, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").PikkuFunctionSessionless<{
456
457
  name: string;
457
458
  branch: string;
458
459
  value?: string | undefined;
459
460
  force?: boolean | undefined;
460
461
  }, {
461
- ok: boolean;
462
+ name: string;
463
+ keyId: string;
462
464
  }, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").WiredServices> | import("../../.pikku/pikku-types.gen.js").PikkuFunction<{
463
465
  name: string;
464
466
  branch: string;
465
467
  value?: string | undefined;
466
468
  force?: boolean | undefined;
467
469
  }, {
468
- ok: boolean;
470
+ name: string;
471
+ keyId: string;
469
472
  }, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").WiredServices>, undefined, undefined>, import("../../.pikku/pikku-types.gen.js").PikkuMiddleware, (services: import("../../types/application-types.js").SingletonServices, data: any, session?: import("../../types/application-types.js").UserSession | undefined) => void | Promise<void>, string>;
470
473
  list: import("@pikku/core/cli").CoreCLICommandConfig<import("../../.pikku/pikku-types.gen.js").PikkuFunctionConfig<{
471
474
  branch: string;
472
475
  json?: boolean | undefined;
473
476
  }, {
474
- names: string[];
477
+ secrets: {
478
+ name: string;
479
+ updatedAt: string;
480
+ }[];
475
481
  }, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").PikkuFunctionSessionless<{
476
482
  branch: string;
477
483
  json?: boolean | undefined;
478
484
  }, {
479
- names: string[];
485
+ secrets: {
486
+ name: string;
487
+ updatedAt: string;
488
+ }[];
480
489
  }, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").WiredServices> | import("../../.pikku/pikku-types.gen.js").PikkuFunction<{
481
490
  branch: string;
482
491
  json?: boolean | undefined;
483
492
  }, {
484
- names: string[];
493
+ secrets: {
494
+ name: string;
495
+ updatedAt: string;
496
+ }[];
497
+ }, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").WiredServices>, undefined, undefined>, import("../../.pikku/pikku-types.gen.js").PikkuMiddleware, (services: import("../../types/application-types.js").SingletonServices, data: any, session?: import("../../types/application-types.js").UserSession | undefined) => void | Promise<void>, string>;
498
+ rotate: import("@pikku/core/cli").CoreCLICommandConfig<import("../../.pikku/pikku-types.gen.js").PikkuFunctionConfig<{
499
+ branch: string;
500
+ force?: boolean | undefined;
501
+ }, {
502
+ retiredKeyId: string;
503
+ }, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").PikkuFunctionSessionless<{
504
+ branch: string;
505
+ force?: boolean | undefined;
506
+ }, {
507
+ retiredKeyId: string;
508
+ }, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").WiredServices> | import("../../.pikku/pikku-types.gen.js").PikkuFunction<{
509
+ branch: string;
510
+ force?: boolean | undefined;
511
+ }, {
512
+ retiredKeyId: string;
485
513
  }, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").WiredServices>, undefined, undefined>, import("../../.pikku/pikku-types.gen.js").PikkuMiddleware, (services: import("../../types/application-types.js").SingletonServices, data: any, session?: import("../../types/application-types.js").UserSession | undefined) => void | Promise<void>, string>;
486
514
  };
487
515
  };
@@ -622,21 +650,21 @@ export declare const fabricCommands: {
622
650
  }, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").WiredServices>, undefined, undefined>, import("../../.pikku/pikku-types.gen.js").PikkuMiddleware, (services: import("../../types/application-types.js").SingletonServices, data: any, session?: import("../../types/application-types.js").UserSession | undefined) => void | Promise<void>, string>;
623
651
  add: import("@pikku/core/cli").CoreCLICommandConfig<import("../../.pikku/pikku-types.gen.js").PikkuFunctionConfig<{
624
652
  hostname: string;
625
- target?: "api" | "app" | undefined;
653
+ target?: "app" | "api" | undefined;
626
654
  apiUrl?: string | undefined;
627
655
  }, {
628
656
  hostname: string;
629
657
  cnameTarget: string;
630
658
  }, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").PikkuFunctionSessionless<{
631
659
  hostname: string;
632
- target?: "api" | "app" | undefined;
660
+ target?: "app" | "api" | undefined;
633
661
  apiUrl?: string | undefined;
634
662
  }, {
635
663
  hostname: string;
636
664
  cnameTarget: string;
637
665
  }, "rpc" | "session", import("../../.pikku/pikku-types.gen.js").WiredServices> | import("../../.pikku/pikku-types.gen.js").PikkuFunction<{
638
666
  hostname: string;
639
- target?: "api" | "app" | undefined;
667
+ target?: "app" | "api" | undefined;
640
668
  apiUrl?: string | undefined;
641
669
  }, {
642
670
  hostname: string;
@@ -31,6 +31,7 @@ import { FabricDbSchema, renderDbSchema, } from './functions/db-schema.function.
31
31
  import { FabricRollback } from './functions/rollback.function.js';
32
32
  import { FabricSecretsSet } from './functions/secrets-set.function.js';
33
33
  import { FabricSecretsList } from './functions/secrets-list.function.js';
34
+ import { FabricSecretsRotate } from './functions/secrets-rotate.function.js';
34
35
  import { FabricLogs } from './functions/logs.function.js';
35
36
  import { FabricMetrics } from './functions/metrics.function.js';
36
37
  import { FabricTrace } from './functions/trace.function.js';
@@ -241,6 +242,17 @@ export const fabricCommands = defineCLICommands({
241
242
  json: { description: 'Machine-readable output', default: false },
242
243
  },
243
244
  }),
245
+ rotate: pikkuCLICommand({
246
+ func: FabricSecretsRotate,
247
+ description: "Retire a stage's sealing key (secrets must be set again)",
248
+ options: {
249
+ branch: { description: 'Target branch', short: 'b' },
250
+ force: {
251
+ description: 'Confirm that existing secrets become unreadable',
252
+ default: false,
253
+ },
254
+ },
255
+ }),
244
256
  },
245
257
  },
246
258
  logs: pikkuCLICommand({
@@ -2,8 +2,8 @@ import { z } from 'zod';
2
2
  export declare const FabricDomainsAddInput: z.ZodObject<{
3
3
  hostname: z.ZodString;
4
4
  target: z.ZodOptional<z.ZodEnum<{
5
- api: "api";
6
5
  app: "app";
6
+ api: "api";
7
7
  }>>;
8
8
  apiUrl: z.ZodOptional<z.ZodString>;
9
9
  }, z.core.$strip>;
@@ -13,21 +13,21 @@ export declare const FabricDomainsAddOutput: z.ZodObject<{
13
13
  }, z.core.$strip>;
14
14
  export declare const FabricDomainsAdd: import("../../../.pikku/pikku-types.gen.js").PikkuFunctionConfig<{
15
15
  hostname: string;
16
- target?: "api" | "app" | undefined;
16
+ target?: "app" | "api" | undefined;
17
17
  apiUrl?: string | undefined;
18
18
  }, {
19
19
  hostname: string;
20
20
  cnameTarget: string;
21
21
  }, "rpc" | "session", import("../../../.pikku/pikku-types.gen.js").PikkuFunctionSessionless<{
22
22
  hostname: string;
23
- target?: "api" | "app" | undefined;
23
+ target?: "app" | "api" | undefined;
24
24
  apiUrl?: string | undefined;
25
25
  }, {
26
26
  hostname: string;
27
27
  cnameTarget: string;
28
28
  }, "rpc" | "session", import("../../../.pikku/pikku-types.gen.js").WiredServices> | import("../../../.pikku/pikku-types.gen.js").PikkuFunction<{
29
29
  hostname: string;
30
- target?: "api" | "app" | undefined;
30
+ target?: "app" | "api" | undefined;
31
31
  apiUrl?: string | undefined;
32
32
  }, {
33
33
  hostname: string;
@@ -4,21 +4,33 @@ export declare const FabricSecretsListInput: z.ZodObject<{
4
4
  json: z.ZodOptional<z.ZodBoolean>;
5
5
  }, z.core.$strip>;
6
6
  export declare const FabricSecretsListOutput: z.ZodObject<{
7
- names: z.ZodArray<z.ZodString>;
7
+ secrets: z.ZodArray<z.ZodObject<{
8
+ name: z.ZodString;
9
+ updatedAt: z.ZodString;
10
+ }, z.core.$strip>>;
8
11
  }, z.core.$strip>;
9
12
  export declare const FabricSecretsList: import("../../../.pikku/pikku-types.gen.js").PikkuFunctionConfig<{
10
13
  branch: string;
11
14
  json?: boolean | undefined;
12
15
  }, {
13
- names: string[];
16
+ secrets: {
17
+ name: string;
18
+ updatedAt: string;
19
+ }[];
14
20
  }, "rpc" | "session", import("../../../.pikku/pikku-types.gen.js").PikkuFunctionSessionless<{
15
21
  branch: string;
16
22
  json?: boolean | undefined;
17
23
  }, {
18
- names: string[];
24
+ secrets: {
25
+ name: string;
26
+ updatedAt: string;
27
+ }[];
19
28
  }, "rpc" | "session", import("../../../.pikku/pikku-types.gen.js").WiredServices> | import("../../../.pikku/pikku-types.gen.js").PikkuFunction<{
20
29
  branch: string;
21
30
  json?: boolean | undefined;
22
31
  }, {
23
- names: string[];
32
+ secrets: {
33
+ name: string;
34
+ updatedAt: string;
35
+ }[];
24
36
  }, "rpc" | "session", import("../../../.pikku/pikku-types.gen.js").WiredServices>, undefined, undefined>;
@@ -2,13 +2,16 @@ import { z } from 'zod';
2
2
  import { pikkuSessionlessFunc } from '../../../.pikku/pikku-types.gen.js';
3
3
  import { resolveApiContext } from '../lib/config.js';
4
4
  import { getFabricRPC } from '../lib/http.js';
5
+ import { resolveStageId } from '../lib/stage.js';
5
6
  export const FabricSecretsListInput = z.object({
6
7
  branch: z.string(),
7
8
  json: z.boolean().optional(),
8
9
  });
9
- export const FabricSecretsListOutput = z.object({ names: z.array(z.string()) });
10
+ export const FabricSecretsListOutput = z.object({
11
+ secrets: z.array(z.object({ name: z.string(), updatedAt: z.string() })),
12
+ });
10
13
  export const FabricSecretsList = pikkuSessionlessFunc({
11
- description: 'List secret names visible to a stage (values never leave the server).',
14
+ description: 'List the secrets set on a stage, by name. Values are sealed to the stage and never leave it.',
12
15
  input: FabricSecretsListInput,
13
16
  output: FabricSecretsListOutput,
14
17
  func: async (_services, { branch, json }) => {
@@ -18,19 +21,18 @@ export const FabricSecretsList = pikkuSessionlessFunc({
18
21
  if (!ctx.projectId)
19
22
  throw new Error('No fabric project linked. Run `pikku fabric link` first.');
20
23
  const rpc = getFabricRPC({ apiUrl: ctx.apiUrl, token: ctx.token });
21
- const result = await rpc.invoke('listStageSecrets', {
22
- projectId: ctx.projectId,
23
- branch,
24
- });
24
+ const stageId = await resolveStageId(rpc, ctx.projectId, branch);
25
+ const result = await rpc.invoke('listStageSecretNames', { stageId });
25
26
  if (json) {
26
- console.log(JSON.stringify({ branch, names: result.names }, null, 2));
27
+ console.log(JSON.stringify({ branch, secrets: result.secrets }, null, 2));
27
28
  }
28
- else if (result.names.length === 0) {
29
+ else if (result.secrets.length === 0) {
29
30
  console.log(`[fabric] no secrets set on ${branch}`);
30
31
  }
31
32
  else {
32
- for (const name of result.names)
33
- console.log(name);
33
+ for (const { name, updatedAt } of result.secrets) {
34
+ console.log(`${name}\t${updatedAt}`);
35
+ }
34
36
  }
35
37
  return result;
36
38
  },