@pikku/cli 0.12.92 → 0.12.96

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 (196) hide show
  1. package/console-app/assets/{index-DDpIMCpy.js → index-CeQodYfg.js} +151 -149
  2. package/console-app/assets/{index-D0HG8q0B.css → index-CyYHTGWZ.css} +1 -1
  3. package/console-app/index.html +2 -2
  4. package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
  5. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
  6. package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
  7. package/dist/.pikku/cli/pikku-cli-channel.d.ts +13 -15
  8. package/dist/.pikku/cli/pikku-cli-channel.js +72 -3
  9. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +14 -4
  10. package/dist/.pikku/cli/pikku-cli-client.gen.js +20 -10
  11. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.d.ts +1 -1
  12. package/dist/.pikku/cli/pikku-cli-contracts-meta.gen.js +1 -1
  13. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
  14. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  15. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
  16. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +156 -2
  17. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  18. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  19. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  20. package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
  21. package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
  22. package/dist/.pikku/function/pikku-function-types.gen.d.ts +55 -20
  23. package/dist/.pikku/function/pikku-function-types.gen.js +27 -1
  24. package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
  25. package/dist/.pikku/function/pikku-functions-meta.gen.json +176 -13
  26. package/dist/.pikku/function/pikku-functions.gen.js +11 -1
  27. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  28. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  29. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  30. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  31. package/dist/.pikku/pikku-bootstrap-scenarios.gen.d.ts +1 -1
  32. package/dist/.pikku/pikku-bootstrap-scenarios.gen.js +1 -1
  33. package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
  34. package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
  35. package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
  36. package/dist/.pikku/pikku-meta-service.gen.js +1 -1
  37. package/dist/.pikku/pikku-services.gen.d.ts +1 -1
  38. package/dist/.pikku/pikku-types.gen.d.ts +1 -1
  39. package/dist/.pikku/pikku-types.gen.js +1 -1
  40. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  41. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  42. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
  43. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  44. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  45. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
  46. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +9 -0
  47. package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.js +1 -1
  48. package/dist/.pikku/scenarios/pikku-scenario-functions.gen.d.ts +1 -1
  49. package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +1 -1
  50. package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.d.ts +1 -1
  51. package/dist/.pikku/scenarios/schemas/register.gen.d.ts +1 -1
  52. package/dist/.pikku/scenarios/schemas/register.gen.js +1 -1
  53. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  54. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  55. package/dist/.pikku/schemas/register.gen.js +21 -3
  56. package/dist/.pikku/schemas/schemas/KnowledgeIndexInput.schema.json +1 -0
  57. package/dist/.pikku/schemas/schemas/KnowledgeIndexOutput.schema.json +1 -0
  58. package/dist/.pikku/schemas/schemas/KnowledgeValidateInput.schema.json +1 -0
  59. package/dist/.pikku/schemas/schemas/KnowledgeValidateOutput.schema.json +1 -0
  60. package/dist/.pikku/schemas/schemas/PersonaRunInput.schema.json +1 -0
  61. package/dist/.pikku/schemas/schemas/PersonaSyncInput.schema.json +1 -0
  62. package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
  63. package/dist/.pikku/schemas/schemas/PikkuPersonasInput.schema.json +1 -0
  64. package/dist/.pikku/schemas/schemas/PikkuRolesInput.schema.json +1 -0
  65. package/dist/.pikku/schemas/schemas/RolesAuditInput.schema.json +1 -0
  66. package/dist/.pikku/schemas/schemas/RolesPruneInput.schema.json +1 -0
  67. package/dist/.pikku/scopes/pikku-personas-meta.gen.json +1 -0
  68. package/dist/.pikku/scopes/pikku-personas.gen.d.ts +36 -0
  69. package/dist/.pikku/scopes/pikku-personas.gen.js +17 -0
  70. package/dist/.pikku/scopes/pikku-roles-meta.gen.json +1 -0
  71. package/dist/.pikku/scopes/pikku-roles.gen.d.ts +30 -0
  72. package/dist/.pikku/scopes/pikku-roles.gen.js +18 -0
  73. package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +4 -2
  74. package/dist/.pikku/scopes/pikku-scope-types.gen.js +3 -2
  75. package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
  76. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +2 -2
  77. package/dist/.pikku/secrets/pikku-secret-types.gen.js +2 -2
  78. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
  79. package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
  80. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
  81. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
  82. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +2 -2
  83. package/dist/.pikku/variables/pikku-variable-types.gen.js +2 -2
  84. package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
  85. package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
  86. package/dist/.pikku/workflow/meta/allWorkflow.gen.json +27 -3
  87. package/dist/.pikku/workflow/pikku-personas.gen.d.ts +15 -0
  88. package/dist/.pikku/workflow/pikku-personas.gen.js +17 -0
  89. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +96 -19
  90. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +22 -2
  91. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
  92. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
  93. package/dist/bin/pikku-bin.mjs +2 -2
  94. package/dist/bin/pikku.js +0 -0
  95. package/dist/src/cli.wiring.js +124 -2
  96. package/dist/src/deploy/analyzer/analyzer.js +14 -0
  97. package/dist/src/deploy/analyzer/manifest.d.ts +11 -0
  98. package/dist/src/fabric/functions/validate.function.js +20 -11
  99. package/dist/src/functions/commands/bootstrap.js +3 -0
  100. package/dist/src/functions/commands/dev-ai-runner.d.ts +16 -4
  101. package/dist/src/functions/commands/dev-ai-runner.js +63 -29
  102. package/dist/src/functions/commands/dev.js +9 -4
  103. package/dist/src/functions/commands/enable.js +15 -19
  104. package/dist/src/functions/commands/{scenario-environment.d.ts → environment.d.ts} +9 -6
  105. package/dist/src/functions/commands/{scenario-environment.js → environment.js} +5 -4
  106. package/dist/src/functions/commands/knowledge-index.d.ts +30 -0
  107. package/dist/src/functions/commands/knowledge-index.js +11 -0
  108. package/dist/src/functions/commands/knowledge-validate.d.ts +33 -0
  109. package/dist/src/functions/commands/knowledge-validate.js +11 -0
  110. package/dist/src/functions/commands/new-addon.d.ts +18 -0
  111. package/dist/src/functions/commands/new-addon.js +52 -36
  112. package/dist/src/functions/commands/persona-sync.d.ts +33 -0
  113. package/dist/src/functions/commands/persona-sync.js +151 -0
  114. package/dist/src/functions/commands/persona.d.ts +58 -0
  115. package/dist/src/functions/commands/persona.js +217 -0
  116. package/dist/src/functions/commands/roles-audit.d.ts +1 -0
  117. package/dist/src/functions/commands/roles-audit.js +37 -0
  118. package/dist/src/functions/commands/roles-prune.d.ts +16 -0
  119. package/dist/src/functions/commands/roles-prune.js +52 -0
  120. package/dist/src/functions/commands/roles-shared.d.ts +40 -0
  121. package/dist/src/functions/commands/roles-shared.js +77 -0
  122. package/dist/src/functions/commands/scenario-browser.d.ts +3 -3
  123. package/dist/src/functions/commands/scenario-browser.js +1 -1
  124. package/dist/src/functions/commands/scenario-ladder.d.ts +44 -2
  125. package/dist/src/functions/commands/scenario-ladder.js +51 -2
  126. package/dist/src/functions/commands/scenario.d.ts +7 -0
  127. package/dist/src/functions/commands/scenario.js +79 -17
  128. package/dist/src/functions/commands/scopes-shared.d.ts +8 -0
  129. package/dist/src/functions/commands/scopes-shared.js +1 -1
  130. package/dist/src/functions/commands/serve.js +7 -3
  131. package/dist/src/functions/commands/virtual-user-formatter.d.ts +30 -0
  132. package/dist/src/functions/commands/virtual-user-formatter.js +65 -0
  133. package/dist/src/functions/db/local-db.js +38 -1
  134. package/dist/src/functions/knowledge/render.d.ts +3 -0
  135. package/dist/src/functions/knowledge/render.js +66 -0
  136. package/dist/src/functions/knowledge/schemas.d.ts +51 -0
  137. package/dist/src/functions/knowledge/schemas.js +25 -0
  138. package/dist/src/functions/validate/workspace-validate.js +1 -1
  139. package/dist/src/functions/wirings/ai-agent/pikku-command-public-agent.js +2 -1
  140. package/dist/src/functions/wirings/ai-agent/serialize-public-agent.js +1 -0
  141. package/dist/src/functions/wirings/auth/serialize-auth-gen.d.ts +2 -2
  142. package/dist/src/functions/wirings/auth/serialize-auth-gen.js +8 -8
  143. package/dist/src/functions/wirings/cli/serialize-channel-cli-client.d.ts +7 -3
  144. package/dist/src/functions/wirings/cli/serialize-channel-cli-client.js +32 -18
  145. package/dist/src/functions/wirings/cli/serialize-channel-cli.js +63 -6
  146. package/dist/src/functions/wirings/console/serialize-console-functions.js +4 -7
  147. package/dist/src/functions/wirings/credentials/serialize-credentials-types.js +8 -1
  148. package/dist/src/functions/wirings/functions/serialize-function-types.js +88 -28
  149. package/dist/src/functions/wirings/middleware/serialize-middleware-imports.js +25 -9
  150. package/dist/src/functions/wirings/package/serialize-package-types.js +5 -3
  151. package/dist/src/functions/wirings/personas/pikku-command-personas.d.ts +7 -0
  152. package/dist/src/functions/wirings/personas/pikku-command-personas.js +43 -0
  153. package/dist/src/functions/wirings/personas/serialize-personas-types.d.ts +18 -0
  154. package/dist/src/functions/wirings/personas/serialize-personas-types.js +76 -0
  155. package/dist/src/functions/wirings/realtime/pikku-command-events-scaffold.js +2 -1
  156. package/dist/src/functions/wirings/roles/pikku-command-roles.d.ts +7 -0
  157. package/dist/src/functions/wirings/roles/pikku-command-roles.js +33 -0
  158. package/dist/src/functions/wirings/roles/serialize-roles-types.d.ts +14 -0
  159. package/dist/src/functions/wirings/roles/serialize-roles-types.js +55 -0
  160. package/dist/src/functions/wirings/rpc/pikku-command-public-rpc.js +2 -1
  161. package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.d.ts +3 -3
  162. package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.js +3 -3
  163. package/dist/src/functions/wirings/scopes/serialize-scopes-types.d.ts +1 -1
  164. package/dist/src/functions/wirings/scopes/serialize-scopes-types.js +1 -1
  165. package/dist/src/functions/wirings/secrets/serialize-secrets-types.js +10 -3
  166. package/dist/src/functions/wirings/user-admin/pikku-command-user-admin-functions.js +2 -1
  167. package/dist/src/functions/wirings/user-admin/serialize-user-admin-functions.js +2 -2
  168. package/dist/src/functions/wirings/variables/serialize-variables-types.js +8 -1
  169. package/dist/src/functions/wirings/workflow/pikku-command-workflow-routes.js +2 -1
  170. package/dist/src/functions/wirings/workflow/pikku-command-workflow.js +13 -13
  171. package/dist/src/functions/wirings/workflow/serialize-personas.d.ts +10 -0
  172. package/dist/src/functions/wirings/workflow/serialize-personas.js +46 -0
  173. package/dist/src/functions/wirings/workflow/serialize-scenario-step-map.js +11 -2
  174. package/dist/src/functions/wirings/workflow/serialize-workflow-types.js +165 -29
  175. package/dist/src/functions/workflows/all.workflow.js +7 -1
  176. package/dist/src/server/content-signing-jwt.d.ts +13 -0
  177. package/dist/src/server/content-signing-jwt.js +51 -0
  178. package/dist/src/server/dev-server-runner.interface.d.ts +10 -2
  179. package/dist/src/server/node-server-runner.d.ts +2 -2
  180. package/dist/src/server/node-server-runner.js +2 -1
  181. package/dist/src/services.d.ts +3 -1
  182. package/dist/src/services.js +2 -1
  183. package/dist/src/utils/pikku-cli-config.js +45 -2
  184. package/dist/src/utils/resolve-personas.d.ts +32 -0
  185. package/dist/src/utils/resolve-personas.js +46 -0
  186. package/dist/src/utils/resolve-scaffold-feature.d.ts +19 -0
  187. package/dist/src/utils/resolve-scaffold-feature.js +49 -0
  188. package/dist/tsconfig.tsbuildinfo +1 -1
  189. package/package.json +17 -13
  190. package/dist/.pikku/schemas/schemas/ScenarioRunInput.schema.json +0 -1
  191. package/dist/.pikku/workflow/pikku-scenario-actors.gen.d.ts +0 -19
  192. package/dist/.pikku/workflow/pikku-scenario-actors.gen.js +0 -17
  193. package/dist/src/functions/wirings/workflow/serialize-scenario-actors.d.ts +0 -2
  194. package/dist/src/functions/wirings/workflow/serialize-scenario-actors.js +0 -40
  195. package/dist/src/utils/resolve-scenario-actors.d.ts +0 -23
  196. package/dist/src/utils/resolve-scenario-actors.js +0 -74
@@ -0,0 +1,18 @@
1
+ import { flattenSystemRoleDefinitions } from '@pikku/core/role';
2
+ import definitions from './pikku-roles-meta.gen.json' with { type: 'json' };
3
+ /**
4
+ * The declared role set, for a ScopeService to sync into its store.
5
+ *
6
+ * Derived from the metadata sidecar rather than inlined, so the import above
7
+ * forces tsc to emit the .json alongside this file — an addon publishes only
8
+ * its compiled output, and a host reads that .json to merge the addon's roles
9
+ * into its own union.
10
+ *
11
+ * Additive on removal: a deleted declaration leaves an inert row rather than
12
+ * revoking everyone's grant on deploy. Use `pikku roles prune` to remove them.
13
+ */
14
+ export const SYSTEM_ROLES = flattenSystemRoleDefinitions(Object.values(definitions));
15
+ /** Declared roles, keyed by name. Rendered by the console when granting. */
16
+ export const SYSTEM_ROLES_META = Object.fromEntries(SYSTEM_ROLES.map((role) => [role.name, role]));
17
+ /** Whether a role name is declared in code, and therefore not editable. */
18
+ export const isSystemRole = (name) => Object.prototype.hasOwnProperty.call(SYSTEM_ROLES_META, name);
@@ -1,5 +1,7 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.92
2
+ * This file was generated by @pikku/cli@0.12.96
3
3
  */
4
- export { wireScope } from '@pikku/core/scope';
4
+ export { defineScope } from '@pikku/core/scope';
5
5
  export type { CoreScopes, CoreScopeNode, FlatScope, ScopeDefinitionMeta, ScopeDefinitionsMeta } from '@pikku/core/scope';
6
+ export { defineSystemRole } from '@pikku/core/role';
7
+ export type { CoreSystemRole, CoreSystemRoles, SystemRole, SystemRoleDefinitionMeta, SystemRoleDefinitionsMeta } from '@pikku/core/role';
@@ -1,4 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.92
2
+ * This file was generated by @pikku/cli@0.12.96
3
3
  */
4
- export { wireScope } from '@pikku/core/scope';
4
+ export { defineScope } from '@pikku/core/scope';
5
+ export { defineSystemRole } from '@pikku/core/role';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.92
2
+ * This file was generated by @pikku/cli@0.12.96
3
3
  */
4
4
  /**
5
5
  * This file was generated by the @pikku/cli
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.92
2
+ * This file was generated by @pikku/cli@0.12.96
3
3
  */
4
- export { wireSecret } from '@pikku/core/secret';
4
+ export { defineSecret } from '@pikku/core/secret';
5
5
  export type { CoreSecret, SecretDefinitionMeta, SecretDefinitionsMeta } from '@pikku/core/secret';
@@ -1,4 +1,4 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.92
2
+ * This file was generated by @pikku/cli@0.12.96
3
3
  */
4
- export { wireSecret } from '@pikku/core/secret';
4
+ export { defineSecret } from '@pikku/core/secret';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.92
2
+ * This file was generated by @pikku/cli@0.12.96
3
3
  */
4
4
  import { TypedSecretService as CoreTypedSecretService } from '@pikku/core/services';
5
5
  import type { SecretService } from '@pikku/core/services';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.92
2
+ * This file was generated by @pikku/cli@0.12.96
3
3
  */
4
4
  import { TypedSecretService as CoreTypedSecretService } from '@pikku/core/services';
5
5
  import secretsMeta from './pikku-secrets-meta.gen.json' with { type: 'json' };
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.92
2
+ * This file was generated by @pikku/cli@0.12.96
3
3
  */
4
4
  /**
5
5
  * Trigger-specific type definitions for tree-shaking optimization
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.92
2
+ * This file was generated by @pikku/cli@0.12.96
3
3
  */
4
4
  /**
5
5
  * Trigger-specific type definitions for tree-shaking optimization
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.92
2
+ * This file was generated by @pikku/cli@0.12.96
3
3
  */
4
- export { wireVariable } from '@pikku/core/variable';
4
+ export { defineVariable } from '@pikku/core/variable';
5
5
  export type { CoreVariable, VariableDefinitionMeta, VariableDefinitionsMeta } from '@pikku/core/variable';
@@ -1,4 +1,4 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.92
2
+ * This file was generated by @pikku/cli@0.12.96
3
3
  */
4
- export { wireVariable } from '@pikku/core/variable';
4
+ export { defineVariable } from '@pikku/core/variable';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.92
2
+ * This file was generated by @pikku/cli@0.12.96
3
3
  */
4
4
  import { TypedVariablesService as CoreTypedVariablesService } from '@pikku/core/services';
5
5
  import type { VariablesService } from '@pikku/core/services';
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.92
2
+ * This file was generated by @pikku/cli@0.12.96
3
3
  */
4
4
  import { TypedVariablesService as CoreTypedVariablesService } from '@pikku/core/services';
5
5
  import variablesMeta from './pikku-variables-meta.gen.json' with { type: 'json' };
@@ -17,9 +17,21 @@
17
17
  "Bootstrap scopes": {
18
18
  "nodeId": "Bootstrap scopes",
19
19
  "rpcName": "pikkuScopes",
20
- "next": "Bootstrap function types split",
20
+ "next": "Bootstrap roles",
21
21
  "stepHash": "41fa180b51ca"
22
22
  },
23
+ "Bootstrap roles": {
24
+ "nodeId": "Bootstrap roles",
25
+ "rpcName": "pikkuRoles",
26
+ "next": "Bootstrap personas",
27
+ "stepHash": "90dda4d88b2d"
28
+ },
29
+ "Bootstrap personas": {
30
+ "nodeId": "Bootstrap personas",
31
+ "rpcName": "pikkuPersonas",
32
+ "next": "Bootstrap function types split",
33
+ "stepHash": "f04e62ca075c"
34
+ },
23
35
  "Bootstrap function types split": {
24
36
  "nodeId": "Bootstrap function types split",
25
37
  "rpcName": "pikkuFunctionTypesSplit",
@@ -297,9 +309,21 @@
297
309
  "Scopes": {
298
310
  "nodeId": "Scopes",
299
311
  "rpcName": "pikkuScopes",
300
- "next": "Variable definition types",
312
+ "next": "Roles",
301
313
  "stepHash": "1ca929a3b6de"
302
314
  },
315
+ "Roles": {
316
+ "nodeId": "Roles",
317
+ "rpcName": "pikkuRoles",
318
+ "next": "Personas",
319
+ "stepHash": "fa13d3597a32"
320
+ },
321
+ "Personas": {
322
+ "nodeId": "Personas",
323
+ "rpcName": "pikkuPersonas",
324
+ "next": "Variable definition types",
325
+ "stepHash": "c17594d64ea5"
326
+ },
303
327
  "Variable definition types": {
304
328
  "nodeId": "Variable definition types",
305
329
  "rpcName": "pikkuVariableDefinitionTypes",
@@ -604,5 +628,5 @@
604
628
  "entryNodeIds": [
605
629
  "Bootstrap inspect"
606
630
  ],
607
- "graphHash": "a06daef26bb3"
631
+ "graphHash": "a29b47e4387d"
608
632
  }
@@ -0,0 +1,15 @@
1
+ import type { HttpPersonasConfig, ScenarioPersona, ResolvedPersona } from '@pikku/core/services';
2
+ import type { AgentMap } from '../agent/pikku-agent-map.gen.d.js';
3
+ import type { FlattenedRPCMap } from '../rpc/pikku-rpc-wirings-map.gen.d.js';
4
+ export declare const personaConfigs: {};
5
+ export type PersonaName = keyof typeof personaConfigs;
6
+ /**
7
+ * The same personas as a list, widened to `ResolvedPersona`. Iterating
8
+ * `personaConfigs` directly yields the literal type of each entry, on which an
9
+ * optional field a persona did not declare does not exist — so a seed reading
10
+ * `roles` off every persona needs this instead.
11
+ */
12
+ export declare const personaList: ResolvedPersona[];
13
+ export type AgentName = keyof AgentMap & string;
14
+ export type TypedPersonas = Record<PersonaName, ScenarioPersona<AgentName, FlattenedRPCMap>>;
15
+ export declare const createPersonas: (options: Omit<HttpPersonasConfig, "personas">) => TypedPersonas;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * This file was generated by @pikku/cli@0.12.96
3
+ */
4
+ /** Personas declared with definePersonas() */
5
+ import { createHttpPersonas } from '@pikku/core/persona';
6
+ export const personaConfigs = {};
7
+ /**
8
+ * The same personas as a list, widened to `ResolvedPersona`. Iterating
9
+ * `personaConfigs` directly yields the literal type of each entry, on which an
10
+ * optional field a persona did not declare does not exist — so a seed reading
11
+ * `roles` off every persona needs this instead.
12
+ */
13
+ export const personaList = Object.values(personaConfigs);
14
+ export const createPersonas = (options) => createHttpPersonas({
15
+ ...options,
16
+ personas: personaConfigs,
17
+ });
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.92
2
+ * This file was generated by @pikku/cli@0.12.96
3
3
  */
4
4
  import { WorkflowCancelledException } from '@pikku/core/workflow';
5
5
  import { template } from '@pikku/core/workflow';
@@ -11,8 +11,8 @@ import type { FlattenedRPCMap } from '../rpc/pikku-rpc-wirings-map.internal.gen.
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
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 };
14
+ import type { TypedPersonas } from './pikku-personas.gen.js';
15
+ export type { TypedPersonas };
16
16
  export { template };
17
17
  export interface TypedWorkflow extends PikkuWorkflowWire {
18
18
  do<K extends keyof FlattenedRPCMap>(stepName: string, rpcName: K, data: FlattenedRPCMap[K]['input'], options?: WorkflowStepOptions): Promise<FlattenedRPCMap[K]['output']>;
@@ -171,8 +171,15 @@ export type PikkuFeatureConfig<Scenarios extends readonly unknown[]> = {
171
171
  * ```
172
172
  */
173
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> = {
174
+ /**
175
+ * One surface's implementation of a step.
176
+ *
177
+ * Each binding is typed independently, so a browser binding gets a non-optional
178
+ * `wire.browser` and a cli binding a non-optional `wire.cli` without either
179
+ * leaking into the other.
180
+ */
181
+ export type PikkuFunctionScenarioStep<In = unknown, Out = never, Surface extends 'browser' | 'cli' | 'default' = 'default'> = PikkuFunctionSessionless<In, Out, Surface extends 'default' ? 'scenarioStep' : 'scenarioStep' | Surface>;
182
+ export type PikkuScenarioStepConfigWithSchema<InputSchema extends StandardSchemaV1 | undefined = undefined, OutputSchema extends StandardSchemaV1 | undefined = undefined> = {
176
183
  /** Registered name — this is the string `scenario.step()` references. */
177
184
  name: string;
178
185
  /**
@@ -190,32 +197,102 @@ export type PikkuScenarioStepConfigWithSchema<InputSchema extends StandardSchema
190
197
  * sentence per call site.
191
198
  */
192
199
  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
200
  title?: string;
200
201
  tags?: string[];
201
202
  input?: InputSchema;
202
203
  output?: OutputSchema;
203
204
  errors?: Array<typeof PikkuError>;
204
- func: PikkuFunctionScenarioStep<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, B>;
205
+ /**
206
+ * Drive this step through a real browser, as a human would. The runner
207
+ * provisions a window for the step's actor first — which makes an actor
208
+ * mandatory — and `wire.browser` is non-optional inside it.
209
+ *
210
+ * Compose shared utilities here rather than writing raw clicks: the step says
211
+ * what the actor is doing, the utilities say how.
212
+ */
213
+ browser?: PikkuFunctionScenarioStep<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'browser'>;
214
+ /** Drive this step remotely, over the websocket. */
215
+ cli?: PikkuFunctionScenarioStep<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'cli'>;
216
+ /**
217
+ * The server-side path — the fast suite, and the floor every other surface
218
+ * falls back to.
219
+ *
220
+ * On a `then`, this is not an alternative to the other bindings but a second
221
+ * **witness**: the run executes every binding it has and fails if they
222
+ * disagree, because "the row says paid" and "the page says paid" are different
223
+ * claims and the gap between them is the bug nobody catches.
224
+ */
225
+ default?: PikkuFunctionScenarioStep<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'default'>;
205
226
  };
206
- export type PikkuScenarioStepConfig<In, Out, B extends boolean = false> = Omit<PikkuScenarioStepConfigWithSchema<undefined, undefined, B>, 'func' | 'input' | 'output'> & {
207
- func: PikkuFunctionScenarioStep<In, Out, B>;
227
+ export type PikkuScenarioStepConfig<In, Out> = Omit<PikkuScenarioStepConfigWithSchema<undefined, undefined>, 'browser' | 'cli' | 'default' | 'input' | 'output'> & {
228
+ browser?: PikkuFunctionScenarioStep<In, Out, 'browser'>;
229
+ cli?: PikkuFunctionScenarioStep<In, Out, 'cli'>;
230
+ default?: PikkuFunctionScenarioStep<In, Out, 'default'>;
208
231
  };
209
232
  /**
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.
233
+ * A named, reusable scenario step, declaring one implementation per surface an
234
+ * actor can drive it through.
235
+ *
236
+ * The step's identity is what the actor is trying to do; which surface carries
237
+ * it out is a binding. That is what lets one ladder run through a real browser,
238
+ * over the websocket, or entirely server-side — and what makes "how much of this
239
+ * flow can a human actually reach" a number rather than a guess.
213
240
  *
214
241
  * Steps are deliberately NOT registered as RPCs: a browser-driving step must
215
242
  * never be network-callable.
216
243
  */
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'>;
244
+ export declare function pikkuScenarioStep<InputSchema extends StandardSchemaV1 | undefined = undefined, OutputSchema extends StandardSchemaV1 | undefined = undefined>(config: PikkuScenarioStepConfigWithSchema<InputSchema, OutputSchema>): PikkuFunctionConfig<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'scenarioStep' | 'browser' | 'cli', PikkuFunctionScenarioStep<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'browser' | 'cli' | 'default'>, InputSchema, OutputSchema>;
245
+ export declare function pikkuScenarioStep<In, Out = unknown>(config: PikkuScenarioStepConfig<In, Out>): PikkuFunctionConfig<In, Out, 'scenarioStep' | 'browser' | 'cli'>;
246
+ /**
247
+ * What a step declares when nobody drives it: one implementation, and no
248
+ * surfaces to choose between.
249
+ *
250
+ * `func` rather than `default` is the point. `default` means *the fallback when
251
+ * no other surface applies*, which implies others could exist; `func` says
252
+ * structurally that there is one way this happens. That also keeps the phase
253
+ * rule coherent — an assertion runs every witness it has and fails if they
254
+ * disagree, and this has exactly one by construction.
255
+ */
256
+ export type PikkuSubjectScenarioStepConfigWithSchema<InputSchema extends StandardSchemaV1 | undefined = undefined, OutputSchema extends StandardSchemaV1 | undefined = undefined> = Omit<PikkuScenarioStepConfigWithSchema<InputSchema, OutputSchema>, 'browser' | 'cli' | 'default'> & {
257
+ func: PikkuFunctionScenarioStep<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'default'>;
258
+ };
259
+ export type PikkuSubjectScenarioStepConfig<In, Out> = Omit<PikkuScenarioStepConfig<In, Out>, 'browser' | 'cli' | 'default'> & {
260
+ func: PikkuFunctionScenarioStep<In, Out, 'default'>;
261
+ };
262
+ /**
263
+ * A step in which the app acts on itself — "Given the platform has expired the
264
+ * trial".
265
+ *
266
+ * The grammatical subject of that sentence is not a user of your app; it **is**
267
+ * your app, which is why it is its own declaration rather than a persona with an
268
+ * asterisk. A persona is a person.
269
+ *
270
+ * Local-test-only, and never in a virtual user's catalogue: a virtual user that
271
+ * could expire its own trial is manufacturing the outcome it exists to discover.
272
+ */
273
+ export declare function pikkuPlatformScenarioStep<InputSchema extends StandardSchemaV1 | undefined = undefined, OutputSchema extends StandardSchemaV1 | undefined = undefined>(config: PikkuSubjectScenarioStepConfigWithSchema<InputSchema, OutputSchema>): PikkuFunctionConfig<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'scenarioStep', PikkuFunctionScenarioStep<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'default'>, InputSchema, OutputSchema>;
274
+ export declare function pikkuPlatformScenarioStep<In, Out = unknown>(config: PikkuSubjectScenarioStepConfig<In, Out>): PikkuFunctionConfig<In, Out, 'scenarioStep'>;
275
+ /**
276
+ * A step in which a third-party system acts — "Given Stripe's webhook arrives",
277
+ * "When Mailgun bounces it".
278
+ *
279
+ * `addon` names the addon that wraps that service, the same name its
280
+ * `wireAddon` declares. These steps *are* the mock its consumers currently
281
+ * hand-write: shipped by the addon author, maintained with the addon, and the
282
+ * same artifact that appears in the prose.
283
+ *
284
+ * Note that arranging and asserting are different — "Stripe's webhook arrives"
285
+ * stubs, "Then Stripe was charged" asserts, and only the first is a stub.
286
+ *
287
+ * Local-test-only, and never in a virtual user's catalogue: one that could
288
+ * invoke this would forge its own payment success.
289
+ */
290
+ export declare function pikkuAddonScenarioStep<InputSchema extends StandardSchemaV1 | undefined = undefined, OutputSchema extends StandardSchemaV1 | undefined = undefined>(config: PikkuSubjectScenarioStepConfigWithSchema<InputSchema, OutputSchema> & {
291
+ addon: string;
292
+ }): PikkuFunctionConfig<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'scenarioStep', PikkuFunctionScenarioStep<InputSchema extends StandardSchemaV1 ? InferSchemaOutput<InputSchema> : unknown, OutputSchema extends StandardSchemaV1 ? InferSchemaOutput<OutputSchema> : unknown, 'default'>, InputSchema, OutputSchema>;
293
+ export declare function pikkuAddonScenarioStep<In, Out = unknown>(config: PikkuSubjectScenarioStepConfig<In, Out> & {
294
+ addon: string;
295
+ }): PikkuFunctionConfig<In, Out, 'scenarioStep'>;
219
296
  type TypedRef<T> = {
220
297
  $ref: string;
221
298
  path?: string;
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.92
2
+ * This file was generated by @pikku/cli@0.12.96
3
3
  */
4
4
  import { WorkflowCancelledException } from '@pikku/core/workflow';
5
5
  import { template } from '@pikku/core/workflow';
@@ -51,7 +51,27 @@ export function pikkuFeature(config) {
51
51
  return config;
52
52
  }
53
53
  export function pikkuScenarioStep(config) {
54
- return config;
54
+ const surfaces = ['browser', 'cli', 'default'].filter((surface) => typeof config[surface] === 'function');
55
+ if (surfaces.length === 0) {
56
+ throw new Error(`[scenario] step '${config.name}' declares no surface bindings. Add at least a \`default\` (server-side) implementation.`);
57
+ }
58
+ return {
59
+ ...config,
60
+ surfaces,
61
+ // The runner sets the surface on the wire and calls this once per binding it
62
+ // resolved — every witness of a `then`, exactly one for an action step.
63
+ func: (services, data, wire) => {
64
+ const surface = wire?.scenarioStep?.surface ?? 'default';
65
+ const binding = config[surface] ?? config.default;
66
+ return binding(services, data, wire);
67
+ },
68
+ };
69
+ }
70
+ export function pikkuPlatformScenarioStep(config) {
71
+ return { ...config, surfaces: ['default'] };
72
+ }
73
+ export function pikkuAddonScenarioStep(config) {
74
+ return { ...config, surfaces: ['default'] };
55
75
  }
56
76
  export function pikkuWorkflowGraph(config) {
57
77
  return corePikkuWorkflowGraph(config);
@@ -1,5 +1,5 @@
1
1
  /**
2
- * This file was generated by @pikku/cli@0.12.92
2
+ * This file was generated by @pikku/cli@0.12.96
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.92
2
+ * This file was generated by @pikku/cli@0.12.96
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.92') {
15
- process.stderr.write(`\n Update available 0.12.92 → ${latest}\n brew upgrade pikku or npm install -g @pikku/cli\n\n`)
14
+ if (latest !== '0.12.96') {
15
+ process.stderr.write(`\n Update available 0.12.96 → ${latest}\n brew upgrade pikku or npm install -g @pikku/cli\n\n`)
16
16
  }
17
17
  } catch {}
18
18
  }
package/dist/bin/pikku.js CHANGED
File without changes
@@ -27,9 +27,15 @@ import { dbReset } from './functions/commands/db-reset.js';
27
27
  import { dbAudit } from './functions/commands/db-audit.js';
28
28
  import { scopesAudit } from './functions/commands/scopes-audit.js';
29
29
  import { scopesPrune } from './functions/commands/scopes-prune.js';
30
+ import { rolesAudit } from './functions/commands/roles-audit.js';
31
+ import { rolesPrune } from './functions/commands/roles-prune.js';
30
32
  import { pikkuAudit } from './functions/commands/audit.js';
31
33
  import { workspaceValidate, renderWorkspaceValidate, } from './functions/commands/workspace-validate.js';
34
+ import { knowledgeValidate, renderKnowledgeValidate, } from './functions/commands/knowledge-validate.js';
35
+ import { knowledgeIndex, renderKnowledgeIndex, } from './functions/commands/knowledge-index.js';
32
36
  import { scenarioRun, scenarioList } from './functions/commands/scenario.js';
37
+ import { personaList, personaRun, } from './functions/commands/persona.js';
38
+ import { personaSync } from './functions/commands/persona-sync.js';
33
39
  import { pikkuVersionsInit } from './functions/commands/versions-init.js';
34
40
  import { pikkuEmailsInit } from './functions/commands/emails-init.js';
35
41
  import { pikkuVersionsCheck } from './functions/commands/versions-check.js';
@@ -90,6 +96,10 @@ wireCLI({
90
96
  description: 'Fail the build on critical diagnostics. Always on; accepted for symmetry with --fail-on-error/--fail-on-warn.',
91
97
  default: true,
92
98
  },
99
+ strictMeta: {
100
+ description: "Fail the build when an AI agent's tool has no description. Without one the model is offered the tool under its own name, so this is a quality gate rather than a correctness one — hence off by default. A 'title' does not satisfy it.",
101
+ default: false,
102
+ },
93
103
  tsc: {
94
104
  description: "After codegen, run a real tsc --noEmit over the project's tsconfig and fail on type errors. Prints full diagnostics with code frames. Off by default.",
95
105
  default: false,
@@ -375,6 +385,47 @@ wireCLI({
375
385
  }),
376
386
  },
377
387
  },
388
+ roles: {
389
+ description: 'Inspect and maintain the roles declared with defineSystemRole',
390
+ subcommands: {
391
+ audit: pikkuCLICommand({
392
+ func: rolesAudit,
393
+ description: 'Report system roles in the database that are no longer declared in code, and how many people hold them',
394
+ }),
395
+ prune: pikkuCLICommand({
396
+ func: rolesPrune,
397
+ description: 'Remove system roles that are no longer declared in code, cascading them out of every user grant',
398
+ options: {
399
+ yes: {
400
+ description: 'Actually delete. Without it, prune only reports the blast radius',
401
+ short: 'y',
402
+ default: false,
403
+ },
404
+ },
405
+ }),
406
+ },
407
+ },
408
+ knowledge: {
409
+ description: 'Inspect and maintain the knowledge base — what this app is, in the language its users use',
410
+ subcommands: {
411
+ validate: pikkuCLICommand({
412
+ func: knowledgeValidate,
413
+ render: renderKnowledgeValidate,
414
+ description: 'Check the knowledge base against the app-project profile, including every resource: reference',
415
+ }),
416
+ index: pikkuCLICommand({
417
+ func: knowledgeIndex,
418
+ render: renderKnowledgeIndex,
419
+ description: 'Refresh every index.md so each section lists the notes actually in it',
420
+ options: {
421
+ check: {
422
+ description: 'Report stale indexes without writing anything, for use as a CI gate',
423
+ default: false,
424
+ },
425
+ },
426
+ }),
427
+ },
428
+ },
378
429
  workspace: {
379
430
  description: 'Workspace-level validation and maintenance commands',
380
431
  subcommands: {
@@ -390,7 +441,7 @@ wireCLI({
390
441
  subcommands: {
391
442
  run: pikkuCLICommand({
392
443
  func: scenarioRun,
393
- description: 'Run scenarios against a configured environment (scenarios.environments in pikku.config.json). Actor secret comes from SCENARIO_ACTOR_SECRET.',
444
+ description: 'Run scenarios against a configured environment (environments in pikku.config.json). Actor secret comes from SCENARIO_ACTOR_SECRET.',
394
445
  parameters: '<environment>',
395
446
  options: {
396
447
  flows: {
@@ -412,9 +463,17 @@ wireCLI({
412
463
  default: false,
413
464
  },
414
465
  browser: {
415
- description: 'Run scenarios with browser steps. --no-browser skips them (they are reported as skipped, not failed)',
466
+ description: 'Shorthand for --run default when false: takes the server-side path instead of driving a browser',
416
467
  default: true,
417
468
  },
469
+ run: {
470
+ description: "Which surface every actor drives the system through: 'browser' (as a human), 'cli' (over the websocket), or 'default' (server-side, the fast path)",
471
+ default: 'default',
472
+ },
473
+ strict: {
474
+ description: 'Fail rather than pass a `then` that has no witness for --run, i.e. an assertion nobody checked on the surface its prose claims',
475
+ default: false,
476
+ },
418
477
  spawn: {
419
478
  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
479
  default: false,
@@ -441,6 +500,69 @@ wireCLI({
441
500
  }),
442
501
  },
443
502
  },
503
+ persona: {
504
+ description: 'The people this app is for, and running one against a real stage',
505
+ subcommands: {
506
+ run: pikkuCLICommand({
507
+ func: personaRun,
508
+ description: 'Sign in as a declared persona and work the API in character against a configured environment. Not a test runner: it asserts nothing and reports what came back that should not have. The sign-in secret comes from SCENARIO_ACTOR_SECRET.',
509
+ parameters: '<environment> <persona>',
510
+ options: {
511
+ disposition: {
512
+ description: 'How they behave: realistic (default), careless, newcomer, stale, auditor, adversarial',
513
+ short: 'd',
514
+ },
515
+ goals: {
516
+ description: "Comma-separated goals in your own words, run alongside the persona's own and the ones derived from scenarios",
517
+ },
518
+ steps: {
519
+ description: 'Model turns before it stops (default 40)',
520
+ },
521
+ mutations: {
522
+ description: 'Non-read calls before it stops',
523
+ },
524
+ duration: {
525
+ description: "Wall clock before it stops, e.g. '30m'",
526
+ },
527
+ seed: {
528
+ description: 'Replay a previous run — the same seed schedules the same run',
529
+ },
530
+ model: {
531
+ description: 'Model they think with. Defaults to scenarios.model in pikku.config.json',
532
+ },
533
+ allowApproval: {
534
+ description: 'Offer the endpoints the app marked as needing a human\u2019s approval. Off by default: those are the ones that spend money',
535
+ },
536
+ skipRoleCheck: {
537
+ description: 'Start without verifying the declared roles against the stage. For a target whose auth reports roles somewhere pikku cannot read — findings from an unverified run may be seed drift rather than product bugs',
538
+ },
539
+ apiUrl: {
540
+ description: "Override the environment's apiUrl for this run — for a target that only exists at run time, such as a freshly deployed sandbox",
541
+ },
542
+ out: {
543
+ description: 'Write the whole run — every step, response and finding — as JSON to this path',
544
+ },
545
+ },
546
+ }),
547
+ sync: pikkuCLICommand({
548
+ func: personaSync,
549
+ description: "Provision the declared personas into an environment: create each account and apply the roles it declares. Additive — it never revokes. Needs both the environment's API (to sign in) and its database (to write the grants), and the sign-in secret from SCENARIO_ACTOR_SECRET.",
550
+ parameters: '<environment>',
551
+ options: {
552
+ dryRun: {
553
+ description: 'Report who would be provisioned, with which roles, and why anyone was skipped — without touching anything',
554
+ },
555
+ apiUrl: {
556
+ description: "Override the environment's apiUrl — for a target that only exists at run time, such as a freshly deployed sandbox",
557
+ },
558
+ },
559
+ }),
560
+ list: pikkuCLICommand({
561
+ func: personaList,
562
+ description: 'List the declared personas — who each one is, what they may do, and what they are trying to get done',
563
+ }),
564
+ },
565
+ },
444
566
  fabric: {
445
567
  description: 'PikkuFabric commands (login, link, deploy, domains, secrets, logs, …)',
446
568
  subcommands: fabricCommands,