@pikku/cli 0.12.91 → 0.12.93

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 (241) hide show
  1. package/LICENSE +106 -0
  2. package/console-app/assets/{index-D0HG8q0B.css → index-BYj7ZbUU.css} +1 -1
  3. package/console-app/assets/{index-CpkvmAGb.js → index-CmAplHjZ.js} +151 -149
  4. package/console-app/index.html +2 -2
  5. package/dist/.pikku/agent/pikku-agent-types.gen.d.ts +1 -1
  6. package/dist/.pikku/channel/pikku-channel-types.gen.d.ts +1 -1
  7. package/dist/.pikku/channel/pikku-channel-types.gen.js +1 -1
  8. package/dist/.pikku/cli/pikku-cli-channel.js +16 -1
  9. package/dist/.pikku/cli/pikku-cli-client.gen.d.ts +1 -1
  10. package/dist/.pikku/cli/pikku-cli-client.gen.js +1 -1
  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-contracts-meta.gen.json +15 -0
  14. package/dist/.pikku/cli/pikku-cli-types.gen.d.ts +1 -1
  15. package/dist/.pikku/cli/pikku-cli-types.gen.js +1 -1
  16. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.js +1 -1
  17. package/dist/.pikku/cli/pikku-cli-wirings-meta.gen.json +48 -0
  18. package/dist/.pikku/cli/pikku-cli-wirings.gen.d.ts +1 -1
  19. package/dist/.pikku/cli/pikku-cli-wirings.gen.js +1 -1
  20. package/dist/.pikku/cli/pikku-cli.gen.d.ts +1 -1
  21. package/dist/.pikku/cli/pikku-cli.gen.js +1 -1
  22. package/dist/.pikku/console/pikku-node-types.gen.d.ts +1 -1
  23. package/dist/.pikku/function/pikku-function-types.gen.d.ts +1 -1
  24. package/dist/.pikku/function/pikku-function-types.gen.js +1 -1
  25. package/dist/.pikku/function/pikku-functions-meta.gen.js +1 -1
  26. package/dist/.pikku/function/pikku-functions-meta.gen.json +73 -40
  27. package/dist/.pikku/function/pikku-functions.gen.js +1 -3
  28. package/dist/.pikku/http/pikku-http-types.gen.d.ts +1 -1
  29. package/dist/.pikku/http/pikku-http-types.gen.js +1 -1
  30. package/dist/.pikku/mcp/pikku-mcp-types.gen.d.ts +1 -1
  31. package/dist/.pikku/mcp/pikku-mcp-types.gen.js +1 -1
  32. package/dist/.pikku/pikku-bootstrap-scenarios.gen.d.ts +2 -1
  33. package/dist/.pikku/pikku-bootstrap-scenarios.gen.js +2 -1
  34. package/dist/.pikku/pikku-bootstrap.gen.d.ts +1 -1
  35. package/dist/.pikku/pikku-bootstrap.gen.js +1 -1
  36. package/dist/.pikku/pikku-meta-service.gen.d.ts +1 -1
  37. package/dist/.pikku/pikku-meta-service.gen.js +1 -1
  38. package/dist/.pikku/pikku-services.gen.d.ts +1 -1
  39. package/dist/.pikku/pikku-types.gen.d.ts +1 -1
  40. package/dist/.pikku/pikku-types.gen.js +1 -1
  41. package/dist/.pikku/queue/pikku-queue-types.gen.d.ts +1 -1
  42. package/dist/.pikku/queue/pikku-queue-types.gen.js +1 -1
  43. package/dist/.pikku/queue/pikku-queue-workers-wirings-meta.gen.js +1 -1
  44. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.d.ts +1 -1
  45. package/dist/.pikku/queue/pikku-queue-workers-wirings.gen.js +1 -1
  46. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.js +1 -1
  47. package/dist/.pikku/rpc/pikku-rpc-wirings-meta.internal.gen.json +3 -1
  48. package/dist/.pikku/scenarios/pikku-scenario-functions-meta.gen.js +1 -1
  49. package/dist/.pikku/scenarios/pikku-scenario-functions.gen.d.ts +1 -1
  50. package/dist/.pikku/scenarios/pikku-scenario-wirings-meta.gen.js +1 -1
  51. package/dist/.pikku/scenarios/pikku-scenario-wirings.gen.d.ts +1 -1
  52. package/dist/.pikku/scenarios/schemas/register.gen.d.ts +4 -0
  53. package/dist/.pikku/scenarios/schemas/register.gen.js +4 -0
  54. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.d.ts +1 -1
  55. package/dist/.pikku/scheduler/pikku-scheduler-types.gen.js +1 -1
  56. package/dist/.pikku/schemas/register.gen.js +13 -3
  57. package/dist/.pikku/schemas/schemas/FabricSecretsListOutput.schema.json +1 -1
  58. package/dist/.pikku/schemas/schemas/FabricSecretsRotateInput.schema.json +1 -0
  59. package/dist/.pikku/schemas/schemas/FabricSecretsRotateOutput.schema.json +1 -0
  60. package/dist/.pikku/schemas/schemas/FabricSecretsSetOutput.schema.json +1 -1
  61. package/dist/.pikku/schemas/schemas/KnowledgeIndexInput.schema.json +1 -0
  62. package/dist/.pikku/schemas/schemas/KnowledgeIndexOutput.schema.json +1 -0
  63. package/dist/.pikku/schemas/schemas/KnowledgeValidateInput.schema.json +1 -0
  64. package/dist/.pikku/schemas/schemas/KnowledgeValidateOutput.schema.json +1 -0
  65. package/dist/.pikku/schemas/schemas/PikkuCLIConfig.schema.json +1 -1
  66. package/dist/.pikku/schemas/schemas/ScenarioRunInput.schema.json +1 -1
  67. package/dist/.pikku/scopes/pikku-scope-types.gen.d.ts +1 -1
  68. package/dist/.pikku/scopes/pikku-scope-types.gen.js +1 -1
  69. package/dist/.pikku/scopes/pikku-scopes.gen.d.ts +1 -1
  70. package/dist/.pikku/secrets/pikku-secret-types.gen.d.ts +1 -1
  71. package/dist/.pikku/secrets/pikku-secret-types.gen.js +1 -1
  72. package/dist/.pikku/secrets/pikku-secrets.gen.d.ts +1 -1
  73. package/dist/.pikku/secrets/pikku-secrets.gen.js +1 -1
  74. package/dist/.pikku/trigger/pikku-trigger-types.gen.d.ts +1 -1
  75. package/dist/.pikku/trigger/pikku-trigger-types.gen.js +1 -1
  76. package/dist/.pikku/variables/pikku-variable-types.gen.d.ts +1 -1
  77. package/dist/.pikku/variables/pikku-variable-types.gen.js +1 -1
  78. package/dist/.pikku/variables/pikku-variables.gen.d.ts +1 -1
  79. package/dist/.pikku/variables/pikku-variables.gen.js +1 -1
  80. package/dist/.pikku/workflow/meta/allWorkflow.gen.json +2 -8
  81. package/dist/.pikku/workflow/pikku-scenario-actors.gen.d.ts +1 -1
  82. package/dist/.pikku/workflow/pikku-scenario-actors.gen.js +1 -1
  83. package/dist/.pikku/workflow/pikku-workflow-types.gen.d.ts +1 -1
  84. package/dist/.pikku/workflow/pikku-workflow-types.gen.js +1 -1
  85. package/dist/.pikku/workflow/pikku-workflow-wirings-meta.gen.js +1 -1
  86. package/dist/.pikku/workflow/pikku-workflow-wirings.gen.js +1 -1
  87. package/dist/bin/pikku-bin.mjs +2 -2
  88. package/dist/src/cli.wiring.js +29 -0
  89. package/dist/src/deploy/analyzer/analyzer.js +22 -5
  90. package/dist/src/deploy/build-pipeline.js +5 -1
  91. package/dist/src/fabric/fabric-commands.d.ts +37 -9
  92. package/dist/src/fabric/fabric-commands.js +12 -0
  93. package/dist/src/fabric/functions/domains-add.function.d.ts +4 -4
  94. package/dist/src/fabric/functions/secrets-list.function.d.ts +16 -4
  95. package/dist/src/fabric/functions/secrets-list.function.js +12 -10
  96. package/dist/src/fabric/functions/secrets-rotate.function.d.ts +24 -0
  97. package/dist/src/fabric/functions/secrets-rotate.function.js +36 -0
  98. package/dist/src/fabric/functions/secrets-set.function.d.ts +8 -4
  99. package/dist/src/fabric/functions/secrets-set.function.js +18 -7
  100. package/dist/src/fabric/functions/validate.function.js +16 -7
  101. package/dist/src/fabric/lib/http.d.ts +7 -1
  102. package/dist/src/fabric/lib/sealed-box.d.ts +16 -0
  103. package/dist/src/fabric/lib/sealed-box.js +72 -0
  104. package/dist/src/functions/commands/dev.js +9 -0
  105. package/dist/src/functions/commands/knowledge-index.d.ts +30 -0
  106. package/dist/src/functions/commands/knowledge-index.js +11 -0
  107. package/dist/src/functions/commands/knowledge-validate.d.ts +33 -0
  108. package/dist/src/functions/commands/knowledge-validate.js +11 -0
  109. package/dist/src/functions/commands/new-addon.d.ts +18 -0
  110. package/dist/src/functions/commands/new-addon.js +40 -24
  111. package/dist/src/functions/commands/pikku-command-bootstrap.js +1 -0
  112. package/dist/src/functions/commands/scenario-browser.d.ts +17 -2
  113. package/dist/src/functions/commands/scenario-browser.js +16 -8
  114. package/dist/src/functions/commands/scenario-environment.d.ts +32 -0
  115. package/dist/src/functions/commands/scenario-environment.js +61 -0
  116. package/dist/src/functions/commands/scenario.d.ts +6 -0
  117. package/dist/src/functions/commands/scenario.js +14 -9
  118. package/dist/src/functions/commands/skills.js +27 -61
  119. package/dist/src/functions/db/db-codegen.d.ts +6 -0
  120. package/dist/src/functions/db/db-codegen.js +9 -0
  121. package/dist/src/functions/db/db-migrator.js +14 -0
  122. package/dist/src/functions/db/local-db.d.ts +8 -0
  123. package/dist/src/functions/db/local-db.js +24 -2
  124. package/dist/src/functions/db/migration-identifiers.d.ts +58 -0
  125. package/dist/src/functions/db/migration-identifiers.js +262 -0
  126. package/dist/src/functions/db/migration-provenance.d.ts +35 -0
  127. package/dist/src/functions/db/migration-provenance.js +80 -0
  128. package/dist/src/functions/db/schema-sql.d.ts +43 -0
  129. package/dist/src/functions/db/schema-sql.js +135 -0
  130. package/dist/src/functions/db/sqlite/sqlite-kysely.js +22 -2
  131. package/dist/src/functions/knowledge/render.d.ts +3 -0
  132. package/dist/src/functions/knowledge/render.js +66 -0
  133. package/dist/src/functions/knowledge/schemas.d.ts +51 -0
  134. package/dist/src/functions/knowledge/schemas.js +25 -0
  135. package/dist/src/functions/wirings/credentials/serialize-credentials-types.js +8 -1
  136. package/dist/src/functions/wirings/functions/schemas.js +13 -1
  137. package/dist/src/functions/wirings/rpc/pikku-command-rpc.js +6 -1
  138. package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.d.ts +10 -0
  139. package/dist/src/functions/wirings/scenarios/register-scenario-instrumentation.js +102 -0
  140. package/dist/src/functions/wirings/scenarios/scenario-partition.d.ts +13 -0
  141. package/dist/src/functions/wirings/scenarios/scenario-partition.js +15 -2
  142. package/dist/src/functions/wirings/scenarios/scenario-schema-partition.d.ts +33 -0
  143. package/dist/src/functions/wirings/scenarios/scenario-schema-partition.js +49 -0
  144. package/dist/src/functions/wirings/secrets/serialize-secrets-types.js +10 -3
  145. package/dist/src/functions/wirings/variables/serialize-variables-types.js +8 -1
  146. package/dist/src/functions/workflows/all.workflow.js +2 -7
  147. package/dist/src/utils/file-writer.js +14 -2
  148. package/dist/src/utils/pikku-cli-config.d.ts +14 -0
  149. package/dist/src/utils/pikku-cli-config.js +34 -0
  150. package/dist/src/utils/remove-legacy-scaffold-file.d.ts +14 -0
  151. package/dist/src/utils/remove-legacy-scaffold-file.js +23 -0
  152. package/dist/src/utils/serialize-schemas.d.ts +3 -1
  153. package/dist/src/utils/serialize-schemas.js +39 -4
  154. package/dist/tsconfig.tsbuildinfo +1 -1
  155. package/package.json +10 -9
  156. package/dist/.pikku/schemas/schemas/PikkuScenarioFunctionsOutput.schema.json +0 -1
  157. package/dist/src/functions/wirings/scenarios/pikku-command-scenario-functions.d.ts +0 -1
  158. package/dist/src/functions/wirings/scenarios/pikku-command-scenario-functions.js +0 -31
  159. package/dist/src/functions/wirings/scenarios/serialize-scenario-functions.d.ts +0 -10
  160. package/dist/src/functions/wirings/scenarios/serialize-scenario-functions.js +0 -104
  161. package/skills/pikku-addon/SKILL.md +0 -243
  162. package/skills/pikku-addon/references/addon-package-manifest.md +0 -63
  163. package/skills/pikku-ai-agent/SKILL.md +0 -231
  164. package/skills/pikku-ai-vercel/SKILL.md +0 -82
  165. package/skills/pikku-ai-voice/SKILL.md +0 -88
  166. package/skills/pikku-audit/SKILL.md +0 -175
  167. package/skills/pikku-aws/SKILL.md +0 -111
  168. package/skills/pikku-backblaze/SKILL.md +0 -71
  169. package/skills/pikku-better-auth/SKILL.md +0 -298
  170. package/skills/pikku-cli/SKILL.md +0 -198
  171. package/skills/pikku-cli/references/complete-example.md +0 -82
  172. package/skills/pikku-concepts/SKILL.md +0 -250
  173. package/skills/pikku-concepts/references/concept-mapping.md +0 -556
  174. package/skills/pikku-concepts/references/packages.md +0 -29
  175. package/skills/pikku-config/SKILL.md +0 -212
  176. package/skills/pikku-cron/SKILL.md +0 -214
  177. package/skills/pikku-deploy-azure/SKILL.md +0 -71
  178. package/skills/pikku-deploy-cloudflare/SKILL.md +0 -82
  179. package/skills/pikku-deploy-express/SKILL.md +0 -86
  180. package/skills/pikku-deploy-fastify/SKILL.md +0 -73
  181. package/skills/pikku-deploy-lambda/SKILL.md +0 -110
  182. package/skills/pikku-deploy-nextjs/SKILL.md +0 -78
  183. package/skills/pikku-deploy-uws/SKILL.md +0 -88
  184. package/skills/pikku-deps/SKILL.md +0 -98
  185. package/skills/pikku-emails/SKILL.md +0 -163
  186. package/skills/pikku-fabric/SKILL.md +0 -318
  187. package/skills/pikku-fabric-debug/SKILL.md +0 -112
  188. package/skills/pikku-feature/SKILL.md +0 -258
  189. package/skills/pikku-gateway-slack/SKILL.md +0 -115
  190. package/skills/pikku-http/SKILL.md +0 -220
  191. package/skills/pikku-http/references/http-options.md +0 -55
  192. package/skills/pikku-i18n/SKILL.md +0 -137
  193. package/skills/pikku-info/SKILL.md +0 -100
  194. package/skills/pikku-jose/SKILL.md +0 -105
  195. package/skills/pikku-kysely/SKILL.md +0 -219
  196. package/skills/pikku-machine-auth/SKILL.md +0 -183
  197. package/skills/pikku-mcp/SKILL.md +0 -241
  198. package/skills/pikku-middleware/SKILL.md +0 -231
  199. package/skills/pikku-middleware/references/middleware-patterns.md +0 -61
  200. package/skills/pikku-mongodb/SKILL.md +0 -105
  201. package/skills/pikku-n8n-import/SKILL.md +0 -109
  202. package/skills/pikku-n8n-import/SPEC.md +0 -84
  203. package/skills/pikku-n8n-import/references/addon-mapping.md +0 -121
  204. package/skills/pikku-n8n-import/references/code-translation.md +0 -121
  205. package/skills/pikku-n8n-import/references/loops-and-control.md +0 -87
  206. package/skills/pikku-paraglide/SKILL.md +0 -117
  207. package/skills/pikku-permissions/SKILL.md +0 -192
  208. package/skills/pikku-pino/SKILL.md +0 -79
  209. package/skills/pikku-product-second-opinion/README.md +0 -43
  210. package/skills/pikku-product-second-opinion/SKILL.md +0 -158
  211. package/skills/pikku-product-second-opinion/example/sample-report.md +0 -90
  212. package/skills/pikku-product-second-opinion/references/report-template.md +0 -73
  213. package/skills/pikku-queue/SKILL.md +0 -240
  214. package/skills/pikku-react/SKILL.md +0 -212
  215. package/skills/pikku-react-query/SKILL.md +0 -242
  216. package/skills/pikku-realtime/SKILL.md +0 -236
  217. package/skills/pikku-realtime/references/other-routes.md +0 -23
  218. package/skills/pikku-redis/SKILL.md +0 -90
  219. package/skills/pikku-rpc/SKILL.md +0 -171
  220. package/skills/pikku-rtl/SKILL.md +0 -219
  221. package/skills/pikku-scenario/SKILL.md +0 -382
  222. package/skills/pikku-schedule/SKILL.md +0 -57
  223. package/skills/pikku-schema-ajv/SKILL.md +0 -62
  224. package/skills/pikku-schema-cfworker/SKILL.md +0 -63
  225. package/skills/pikku-security/SKILL.md +0 -108
  226. package/skills/pikku-services/SKILL.md +0 -248
  227. package/skills/pikku-services/references/audit-wire-service.md +0 -34
  228. package/skills/pikku-software-archaeology/README.md +0 -70
  229. package/skills/pikku-software-archaeology/SKILL.md +0 -186
  230. package/skills/pikku-software-archaeology/references/blueprint.schema.json +0 -625
  231. package/skills/pikku-software-archaeology/references/pikku-mapping.md +0 -49
  232. package/skills/pikku-software-archaeology/scripts/validate.mjs +0 -173
  233. package/skills/pikku-tag-middleware/SKILL.md +0 -13
  234. package/skills/pikku-template-clone/SKILL.md +0 -40
  235. package/skills/pikku-trigger/SKILL.md +0 -181
  236. package/skills/pikku-versioning/SKILL.md +0 -173
  237. package/skills/pikku-websocket/SKILL.md +0 -243
  238. package/skills/pikku-workflow/SKILL.md +0 -172
  239. package/skills/pikku-workflow/references/workflow-reference.md +0 -63
  240. package/skills/pikku-workflows-client/SKILL.md +0 -150
  241. package/skills/pikku-ws/SKILL.md +0 -47
@@ -1,298 +0,0 @@
1
- ---
2
- name: pikku-better-auth
3
- description: >-
4
- Use when integrating Better Auth with a Pikku app. Covers pikkuBetterAuth, betterAuth config,
5
- the generated catch-all auth routes, betterAuthSession middleware, OAuth/social providers,
6
- email+password credentials, database adapters, and session mapping. TRIGGER when: code uses
7
- pikkuBetterAuth, betterAuth, betterAuthSession, createAuthHandler, user asks about Better Auth,
8
- OAuth/social providers, MFA, organizations, login/logout, or @pikku/better-auth. TRIGGER when:
9
- user asks about ANY form of authentication, login, logout, sessions, or user identity — always
10
- answer with this skill. DO NOT TRIGGER when: user asks about JWT middleware (use pikku-security)
11
- or custom session services (use pikku-services).
12
- installGroups: [core]
13
- ---
14
-
15
- # Pikku Better Auth Integration
16
-
17
- ## ⚠️ MANDATORY RULE — READ FIRST
18
-
19
- **ALL authentication in Pikku apps MUST use `@pikku/better-auth`. No exceptions.**
20
-
21
- - Do NOT write custom login/logout endpoints.
22
- - Do NOT implement JWT signing/verification by hand.
23
- - Do NOT build a custom session store.
24
- - Do NOT use passport, jose, jsonwebtoken, or any other auth library directly.
25
- - Do NOT invent a bespoke auth flow because the task seems "simple" or "custom".
26
-
27
- If the project does not yet have `@pikku/better-auth` wired up, add it. Do not work around it.
28
- The only acceptable auth implementation in a Pikku app is the one described in this skill.
29
-
30
- ---
31
-
32
- ## Agent Operating Procedure
33
-
34
- Use this skill as an execution checklist, not reference material.
35
-
36
- 1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
37
- 2. Identify the source files that own the behavior. Do not start by reading generated output, `.pikku`, `node_modules`, or build artifacts.
38
- 3. Make the smallest source change that satisfies the task. Keep generated files generated.
39
- 4. Validate with the narrowest relevant command first, then run `pikku all` when functions, wirings, schemas, or generated clients may have changed.
40
- 5. If validation fails, fix the source cause and rerun. Do not edit generated files.
41
-
42
- `@pikku/better-auth` provides [Better Auth](https://better-auth.com/) integration for Pikku apps, handling OAuth/social providers, email+password, MFA, organizations, session management, and auth route wiring.
43
-
44
- ## Installation
45
-
46
- ```bash
47
- yarn add @pikku/better-auth better-auth
48
- ```
49
-
50
- ## Core Concepts
51
-
52
- Better Auth owns its own HTTP surface, database tables, and session cookie. The Pikku integration is thin:
53
-
54
- 1. **`pikkuBetterAuth(factory)`** — you export ONE `pikkuBetterAuth` call whose factory returns a configured `betterAuth({...})` instance. The pikku CLI inspects this export and generates everything else.
55
- 2. **Generated `auth.gen.ts`** — a catch-all `${basePath}{/*splat}` HTTP route per method (GET + POST) that forwards every request under the base path to better-auth's own internal router. The enabled providers and plugins are written to `auth/pikku-auth-meta.gen.json` (read by the console SSO page via `getAuthProviders`).
56
- 3. **Generated session middleware** — with `session.cookieCache` enabled (recommended), a separate `auth-middleware.gen.ts` adds the lean stateless `betterAuthStatelessSession()`; without it, `auth.gen.ts` adds the stateful `betterAuthSession()` that bundles the full server into every unit. See "Stateless session" below.
57
- 4. **Generated `auth-secrets.gen.ts`** — a `wireSecret` for `BETTER_AUTH_SECRET` and for each social provider's OAuth credentials, plus a `wireVariable` for any non-secret provider config (e.g. `tenantId`).
58
-
59
- You do NOT hand-write routes, the session middleware, or the secret wiring — `pikkuBetterAuth` + the CLI generate all of it. Re-run `pikku all` to regenerate.
60
-
61
- ### The console requires Better Auth
62
-
63
- The Pikku console (`@pikku/addon-console`, enabled via `scaffold.console` in `pikku.config.json`) is an admin surface: **every console RPC now requires an authenticated session** (the functions are `pikkuFunc`; unauthenticated calls return `403`). So `scaffold.console` alone is **no longer the minimum** — you also need an auth strategy, and Better Auth is the supported one. `pikku all` **throws** if `scaffold.console` is set but no `pikkuBetterAuth(...)` is found in the project. Baseline is "must be logged in"; finer policy (admin-only, org scoping) is layered host-side via tag/HTTP middleware. See `pikku-deps` for the console's Security screen.
64
-
65
- ---
66
-
67
- ## Standard Setup
68
-
69
- ### 1. Auth definition — `src/auth.ts`
70
-
71
- Export ONE `pikkuBetterAuth` call. The factory **must destructure** `services` (`{ secrets, variables, ... }`) — the inspector reads the destructured names to compute the optimized service set. A non-destructured `(services) => ...` falls back to "unoptimized".
72
-
73
- ```typescript
74
- import { betterAuth } from 'better-auth'
75
- import { memoryAdapter } from 'better-auth/adapters/memory'
76
- import { pikkuBetterAuth } from '@pikku/better-auth'
77
-
78
- export const auth = pikkuBetterAuth(async ({ secrets }) => {
79
- // Fetch every secret in ONE batch rather than awaiting each individually.
80
- const { BETTER_AUTH_SECRET, GITHUB_OAUTH } = await secrets.getSecrets<{
81
- BETTER_AUTH_SECRET: string
82
- GITHUB_OAUTH: { clientId: string; clientSecret: string }
83
- }>(['BETTER_AUTH_SECRET', 'GITHUB_OAUTH'])
84
-
85
- return betterAuth({
86
- secret: BETTER_AUTH_SECRET,
87
- // memoryAdapter needs an array per model — `{}` throws "Model user not found"
88
- // at runtime. Swap for the Kysely adapter in production (see below).
89
- database: memoryAdapter({ user: [], session: [], account: [], verification: [] }),
90
- emailAndPassword: { enabled: true },
91
- // ALWAYS enable for deployed apps — see "Stateless session" below.
92
- session: { cookieCache: { enabled: true } },
93
- socialProviders: {
94
- github: GITHUB_OAUTH,
95
- },
96
- })
97
- })
98
- ```
99
-
100
- **Key points:**
101
- - `socialProviders` keys must be string literals — the CLI reads them statically to emit a `wireSecret` per provider. Provider keys mirror better-auth's built-in ids exactly (e.g. `microsoft`, NOT `microsoft-entra-id`; `cognito`; `github`).
102
- - The factory runs lazily on the first auth request, so it pulls secrets/DB off the injected `services`.
103
- - The default `basePath` is `/api/auth`. Override it by passing `basePath` to `betterAuth`.
104
- - **Enable `session: { cookieCache: { enabled: true } }`** so non-auth units tree-shake the better-auth server out (see below).
105
-
106
- ## ⚠️ Stateless session — ALWAYS enable `cookieCache` for deployed apps
107
-
108
- By default the CLI wires the **stateful** `betterAuthSession` bridge globally — it calls `services.auth()`, so EVERY unit/worker bundles the full better-auth server (~2.5MB each). On per-unit deploy targets (Fabric/Cloudflare) that bloats every bundle and the serial upload phase.
109
-
110
- Enabling `session: { cookieCache: { enabled: true } }` makes the CLI split out a lean `betterAuthStatelessSession` (`src/scaffold/auth-middleware.gen.ts`) that verifies the signed session cookie using only `BETTER_AUTH_SECRET` — no `services.auth()`, no server bundled. Non-auth units drop from ~2.5MB to ~20KB. Only the auth unit carries the server. `pikku fabric validate` warns (`better-auth-stateless-session-disabled`) when it's off.
111
-
112
- **Tradeoff:** server-side session revocation isn't seen until the cookie cache expires (sign-out is still immediate — it deletes the cookie).
113
-
114
- **Don't add a redundant default `addHTTPMiddleware('*', [betterAuthSession()])`** — with cookieCache on, that re-drags the stateful server into every unit and defeats the split (validate flags it as `better-auth-stateful-session-global`). If you don't need to customize the session, the generated middleware is enough.
115
-
116
- **Customizing the session bridge (`mapSession`, `impersonation`, `apiKey`, …):** you do NOT chain a second middleware on top of the generated one — register your OWN global session middleware and the CLI steps aside (it stops generating its default). This works on both paths and is detected the same way:
117
-
118
- - **Stateless (cookieCache on):** register `betterAuthStatelessSession({ mapSession })` **globally** — `addHTTPMiddleware('*', [...])` or `addGlobalMiddleware([...])`. The CLI sees the global registration and skips emitting `auth-middleware.gen.ts` (pikkujs/pikku#754), so you keep cookieCache's lean bundles *and* your custom fields.
119
- - **Stateful (cookieCache off):** register `betterAuthSession({ mapSession, impersonation })` **globally**. The CLI detects it (`hasUserSessionMiddleware`) and omits its own `addHTTPMiddleware('*', [betterAuthSession()])` from `auth.gen.ts` — so there's exactly one session bridge in the chain, yours.
120
-
121
- In both cases a **route-scoped** registration (`addHTTPMiddleware('/some/path', [...])`) does NOT count — only a global one suppresses the generated default. The generated middleware in a `.gen.ts` file is also ignored by the detector, so regeneration never self-suppresses.
122
-
123
- ### Admin capabilities are scopes, not a role
124
-
125
- Pikku does **not** use better-auth's `admin()` plugin, and nothing in this
126
- package reads a `role` column. A role is not a permission: "who may impersonate"
127
- and "who may rebind a shared credential" are different capabilities one user can
128
- hold independently, which a single `role` string cannot express. Every gate the
129
- package owns therefore resolves the caller's scopes through the registered
130
- `ScopeService` and checks the `admin:*` tree:
131
-
132
- | Gate | Scope required |
133
- | --- | --- |
134
- | `impersonation` (`betterAuthSession` / `betterAuthStatelessSession`) | `admin:impersonate` |
135
- | `credentialOAuth`'s `canLinkSingleton` | `admin:credentials:link` |
136
- | the console's user directory | `admin:users:list` |
137
-
138
- Holding the bare `admin` scope satisfies all of them — a parent grant covers
139
- everything nested beneath it — so `admin` is the direct replacement for the old
140
- `role === 'admin'`.
141
-
142
- Declare the tree in your own `wireScope` (the CLI extracts it by AST, so it must
143
- be an inline literal; `ADMIN_SCOPE_TREE` is exported from `@pikku/better-auth`
144
- as the reference shape). Apps wiring `@pikku/addon-console` inherit it already.
145
-
146
- ```typescript
147
- wireScope({
148
- admin: {
149
- displayName: 'Administration',
150
- description: 'Capabilities that act on the application as a whole',
151
- scopes: {
152
- impersonate: { description: 'Act as another user' },
153
- credentials: {
154
- description: 'Application-wide credentials',
155
- scopes: {
156
- link: { description: 'Bind a shared credential for every user' },
157
- },
158
- },
159
- users: {
160
- description: 'The user directory',
161
- scopes: { list: { description: 'List and search users' } },
162
- },
163
- },
164
- },
165
- })
166
- ```
167
-
168
- Then grant it — via a role (`scopeService.createRole({ name: 'admin', scopes: ['admin'] })` plus `addUserToRole`) or directly with `addScopeToUser`.
169
-
170
- Every gate **fails closed**: with no `ScopeService` registered nothing can hold
171
- a scope, so nothing is authorized, and the denial is logged at `warn` because
172
- that is a configuration bug rather than a permissions decision. Pass your own
173
- `canImpersonate` / `canLinkSingleton` to override the default entirely.
174
-
175
- Sibling concerns — banning a user, listing users from your own screens — are
176
- actions your app *invokes*, not things pikku gates. Put them on your own
177
- functions with `scopes: ['admin:users:ban']` and friends.
178
-
179
- ### 2. Production database adapter
180
-
181
- For real deployments swap `memoryAdapter` for the Kysely adapter backed by an injected DB. Better Auth owns its own tables (`user`, `session`, `account`, `verification`, plus plugin tables) — generate its schema with `npx @better-auth/cli generate` and apply it as a migration.
182
-
183
- ```typescript
184
- import { kyselyAdapter } from 'better-auth/adapters/kysely'
185
-
186
- export const auth = pikkuBetterAuth(async ({ secrets, kysely }) => {
187
- const { BETTER_AUTH_SECRET } = await secrets.getSecrets<{ BETTER_AUTH_SECRET: string }>([
188
- 'BETTER_AUTH_SECRET',
189
- ])
190
- return betterAuth({
191
- secret: BETTER_AUTH_SECRET,
192
- database: kyselyAdapter(kysely, { type: 'postgres' }),
193
- emailAndPassword: { enabled: true },
194
- session: { cookieCache: { enabled: true } },
195
- })
196
- })
197
- ```
198
-
199
- ### 3. Configure `pikku.config.json`
200
-
201
- If you place `auth.ts` under `srcDirectories` it is inspected automatically. The generated `auth.gen.ts` + `auth-secrets.gen.ts` land in the scaffold dir (`scaffold.pikkuDir`, default `src/scaffold`). No extra config is required for auth in the common case.
202
-
203
- ---
204
-
205
- ## Social Providers needing extra config
206
-
207
- Some providers require non-secret config alongside the OAuth secret — the CLI emits a `wireVariable` for these:
208
-
209
- - `microsoft` → `MICROSOFT_TENANT_ID` (or `"common"`)
210
- - `cognito` → `COGNITO_DOMAIN`, `COGNITO_REGION`, `COGNITO_USER_POOL_ID`
211
-
212
- ```typescript
213
- export const auth = pikkuBetterAuth(async ({ secrets, variables }) => {
214
- const { BETTER_AUTH_SECRET, MICROSOFT_OAUTH } = await secrets.getSecrets<{
215
- BETTER_AUTH_SECRET: string
216
- MICROSOFT_OAUTH: { clientId: string; clientSecret: string }
217
- }>(['BETTER_AUTH_SECRET', 'MICROSOFT_OAUTH'])
218
- const { MICROSOFT_TENANT_ID } = await variables.getVariables<{
219
- MICROSOFT_TENANT_ID: string
220
- }>(['MICROSOFT_TENANT_ID'])
221
-
222
- return betterAuth({
223
- secret: BETTER_AUTH_SECRET,
224
- database: memoryAdapter({ user: [], session: [], account: [], verification: [] }),
225
- socialProviders: {
226
- microsoft: { ...MICROSOFT_OAUTH, tenantId: MICROSOFT_TENANT_ID },
227
- },
228
- })
229
- })
230
- ```
231
-
232
- ---
233
-
234
- ## Auth-Protected Functions
235
-
236
- Functions that require a session use `pikkuFunc` — anonymous callers are rejected automatically. `betterAuthSession` has already bridged better-auth's session into `session`:
237
-
238
- ```typescript
239
- import { pikkuFunc } from '#pikku'
240
-
241
- export const me = pikkuFunc({
242
- expose: true,
243
- func: async ({ kysely }, _input, { session }) => {
244
- return kysely
245
- .selectFrom('appUser')
246
- .where('userId', '=', session.userId)
247
- .select(['userId', 'email', 'name'])
248
- .executeTakeFirstOrThrow()
249
- },
250
- })
251
- ```
252
-
253
- For public endpoints that optionally vary by viewer, use `pikkuSessionlessFunc` and read `await session?.get()` (`undefined` for anonymous callers).
254
-
255
- ---
256
-
257
- ## HTTP surface (call the real endpoints)
258
-
259
- Better Auth serves everything under `basePath` (default `/api/auth`). Call these directly — the Pikku SDK does not wrap them.
260
-
261
- | Action | Request | Result |
262
- |---|---|---|
263
- | Sign up | `POST /api/auth/sign-up/email` `{ name, email, password }` | 200 + `better-auth.session_token` cookie |
264
- | Log in | `POST /api/auth/sign-in/email` `{ email, password }` | 200 + cookie; wrong creds → 401 `{ code: "INVALID_EMAIL_OR_PASSWORD" }` |
265
- | Session | `GET /api/auth/get-session` | `{ session, user }` or `null` |
266
- | Social sign-in | `POST /api/auth/sign-in/social` `{ provider, callbackURL }` | 200 `{ url, redirect }` (authorize URL) |
267
- | Sign out | `POST /api/auth/sign-out` | 200, clears cookie |
268
-
269
- **`Origin` header on state-changing POSTs:** better-auth enforces an `Origin` header matching `baseURL` on POSTs such as sign-out — omit it and you get `403`. Browsers send it automatically; server-to-server callers must set it.
270
-
271
- The session cookie is `better-auth.session_token` (dev) / `__Secure-better-auth.session_token` (prod).
272
-
273
- ---
274
-
275
- ## Secret Management
276
-
277
- All auth secrets are managed through the secrets service and fetched in one batch via `secrets.getSecrets<T>(keys)` (typed — no cast). Wired automatically in the generated `auth-secrets.gen.ts`, so they show up in the Pikku console.
278
-
279
- - **`BETTER_AUTH_SECRET`** — random ≥32-char string better-auth uses to sign sessions. Always required.
280
- - **Provider credentials** — each social provider stores a JSON object, e.g. `GITHUB_OAUTH = { clientId, clientSecret }`. The secret id is `<PROVIDER>_OAUTH`.
281
-
282
- Never register `BETTER_AUTH_SECRET` as a JoseJWT signing key in `services.ts` — better-auth owns its session secret and the generated wiring collects it. The `config.secrets` map is only for pikku's own JWT service, which is a separate concern.
283
-
284
- ---
285
-
286
- ## `pikkuBetterAuth` API
287
-
288
- ```typescript
289
- import { pikkuBetterAuth } from '@pikku/better-auth'
290
-
291
- // The factory receives the singleton services (destructure them!) and must
292
- // return a betterAuth(...) instance (or a Promise of one).
293
- export const auth = pikkuBetterAuth(async ({ secrets, variables, kysely }) => betterAuth({ ... }))
294
- ```
295
-
296
- - Export exactly ONE `pikkuBetterAuth` per project; the CLI generates a single catch-all worker for all auth routes.
297
- - `betterAuthSession({ auth })` (generated) bridges the better-auth session into the Pikku session on every request — you never add it by hand.
298
- - MFA, organizations, passkeys, etc. are better-auth plugins: add them to `betterAuth({ plugins: [...] })`. The catch-all route already forwards their endpoints.
@@ -1,198 +0,0 @@
1
- ---
2
- name: pikku-cli
3
- description: >-
4
- Use when building CLI commands with Pikku. Covers wireCLI, pikkuCLICommand, subcommands,
5
- options, parameters, custom renderers, and nested command groups. TRIGGER when: code uses
6
- wireCLI/pikkuCLICommand, user asks about CLI commands, terminal tools, command-line interface,
7
- or adding subcommands. DO NOT TRIGGER when: user asks about the pikku CLI tool itself (use
8
- pikku-info) or HTTP endpoints (use pikku-http).
9
- installGroups: [core]
10
- ---
11
-
12
- # Pikku CLI Wiring
13
-
14
- ## Agent Operating Procedure
15
-
16
- Use this skill as an execution checklist, not reference material.
17
-
18
- 1. Discover before editing. Prefer OpenCode tools such as `pikku-meta` when available; otherwise run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
19
- 2. Identify the source files that own the behavior. Do not start by reading generated output, `.pikku`, `node_modules`, vendored packages, or broad build artifacts.
20
- 3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
21
- 4. Validate with the narrowest relevant command first, then run `pikku-verify` or `pikku all` when functions, wirings, schemas, or generated clients may have changed.
22
- 5. If validation fails, fix the source cause and rerun validation. Do not paper over generated errors by editing generated files.
23
-
24
- Wire Pikku functions as CLI commands with parameters, options, subcommands, and custom terminal renderers.
25
-
26
- ## Before You Start
27
-
28
- ```bash
29
- pikku info functions --verbose # See existing functions and their types
30
- pikku info tags --verbose # Understand project organization
31
- ```
32
-
33
- See `pikku-concepts` for the core mental model.
34
-
35
- ## API Reference
36
-
37
- ### `wireCLI(config)`
38
-
39
- ```typescript
40
- import { wireCLI } from '@pikku/core/cli'
41
-
42
- wireCLI({
43
- program: string, // Program name (e.g. 'todos')
44
- options?: { // Global options
45
- [key: string]: {
46
- description: string,
47
- short?: string, // Single char alias (e.g. 'v')
48
- default?: any,
49
- }
50
- },
51
- render?: PikkuCLIRender, // Default renderer for all commands
52
- commands: {
53
- [name: string]: PikkuCLICommand | {
54
- description: string,
55
- subcommands: { [name: string]: PikkuCLICommand }
56
- }
57
- },
58
- })
59
- ```
60
-
61
- ### `pikkuCLICommand(config)`
62
-
63
- ```typescript
64
- import { pikkuCLICommand } from '#pikku'
65
-
66
- pikkuCLICommand({
67
- parameters?: string, // Positional args (e.g. '<text>', '<username> <email>')
68
- func: PikkuFunc, // Business logic function
69
- description?: string,
70
- render?: PikkuCLIRender, // Custom output renderer
71
- options?: {
72
- [key: string]: {
73
- description: string,
74
- short?: string,
75
- default?: any,
76
- choices?: string[], // Restrict to values
77
- }
78
- },
79
- })
80
- ```
81
-
82
- ### `pikkuCLIRender(fn)`
83
-
84
- ```typescript
85
- import { pikkuCLIRender } from '@pikku/core/cli'
86
-
87
- const renderer = pikkuCLIRender<OutputType>((services, data) => {
88
- // Format and print output to terminal
89
- console.log(data)
90
- })
91
- ```
92
-
93
- ## Usage Patterns
94
-
95
- ### Basic Commands
96
-
97
- ```typescript
98
- wireCLI({
99
- program: 'todos',
100
- commands: {
101
- add: pikkuCLICommand({
102
- parameters: '<text>',
103
- func: createTodo,
104
- description: 'Add a new todo',
105
- render: todoRenderer,
106
- options: {
107
- priority: {
108
- description: 'Set priority',
109
- short: 'p',
110
- default: 'normal',
111
- choices: ['low', 'normal', 'high'],
112
- },
113
- },
114
- }),
115
- list: pikkuCLICommand({
116
- func: listTodos,
117
- description: 'List all todos',
118
- render: todosRenderer,
119
- options: {
120
- completed: {
121
- description: 'Show completed only',
122
- short: 'c',
123
- default: false,
124
- },
125
- },
126
- }),
127
- },
128
- })
129
- // Usage: todos add "Buy milk" -p high
130
- // Usage: todos list -c
131
- ```
132
-
133
- ### Nested Subcommands
134
-
135
- ```typescript
136
- wireCLI({
137
- program: 'app',
138
- options: {
139
- verbose: { description: 'Verbose output', short: 'v', default: false },
140
- },
141
- commands: {
142
- greet: pikkuCLICommand({
143
- parameters: '<name>',
144
- func: greetUser,
145
- render: greetRenderer,
146
- }),
147
-
148
- user: {
149
- description: 'User management',
150
- subcommands: {
151
- create: pikkuCLICommand({
152
- parameters: '<username> <email>',
153
- func: createUser,
154
- render: userRenderer,
155
- options: {
156
- admin: { description: 'Admin role', short: 'a', default: false },
157
- },
158
- }),
159
- list: pikkuCLICommand({
160
- func: listUsers,
161
- render: usersRenderer,
162
- options: {
163
- limit: { description: 'Max results', short: 'l' },
164
- },
165
- }),
166
- },
167
- },
168
- },
169
- })
170
- // Usage: app greet Alice
171
- // Usage: app user create bob bob@example.com -a
172
- // Usage: app user list -l 10
173
- // Usage: app -v user list
174
- ```
175
-
176
- ### Custom Renderers
177
-
178
- A renderer receives `(services, data)` where `data` is the func's output. Set `render` on `wireCLI` as the program-wide default; set `render` on a `pikkuCLICommand` to override it for that command.
179
-
180
- ```typescript
181
- const todoRenderer = pikkuCLIRender<{ todo: Todo }>((_services, { todo }) => {
182
- console.log(`✓ Created: ${todo.text} (priority: ${todo.priority})`)
183
- })
184
-
185
- wireCLI({
186
- program: 'todos',
187
- render: jsonRenderer, // default for all commands
188
- commands: {
189
- add: pikkuCLICommand({ func: createTodo, render: todoRenderer }), // overrides jsonRenderer
190
- },
191
- })
192
- ```
193
-
194
- The func's input is the positional `parameters` plus `options`, merged (e.g. `parameters: '<username> <email>'` + an `admin` option → func input `{ username, email, admin }`).
195
-
196
- ## Complete Example
197
-
198
- For a full functions + renderers + nested-subcommand wiring walkthrough, see `references/complete-example.md`.
@@ -1,82 +0,0 @@
1
- # Complete CLI Example
2
-
3
- End-to-end: functions + renderers + nested-subcommand wiring. Note how each func's input is the positional `parameters` plus `options`, merged (e.g. `parameters: '<username> <email>'` + option `admin` → func input `{ username, email, admin }`).
4
-
5
- ```typescript
6
- // functions/admin.functions.ts
7
- export const createUser = pikkuFunc({
8
- title: 'Create User',
9
- func: async ({ db }, { username, email, admin }) => {
10
- const user = await db.createUser({
11
- username,
12
- email,
13
- role: admin ? 'admin' : 'user',
14
- })
15
- return { user }
16
- },
17
- })
18
-
19
- export const listUsers = pikkuSessionlessFunc({
20
- title: 'List Users',
21
- func: async ({ db }, { limit }) => {
22
- return { users: await db.listUsers(limit || 50) }
23
- },
24
- })
25
-
26
- export const deleteUser = pikkuFunc({
27
- title: 'Delete User',
28
- func: async ({ db }, { username }) => {
29
- await db.deleteUser(username)
30
- return { deleted: username }
31
- },
32
- })
33
-
34
- // wirings/cli.wiring.ts
35
- const userRenderer = pikkuCLIRender<{ user: User }>((_services, { user }) => {
36
- console.log(`Created user: ${user.username} (${user.email}) [${user.role}]`)
37
- })
38
-
39
- const usersRenderer = pikkuCLIRender<{ users: User[] }>(
40
- (_services, { users }) => {
41
- console.log(`Users (${users.length}):`)
42
- users.forEach((u) =>
43
- console.log(` ${u.username} <${u.email}> [${u.role}]`)
44
- )
45
- }
46
- )
47
-
48
- wireCLI({
49
- program: 'admin',
50
- commands: {
51
- user: {
52
- description: 'User management',
53
- subcommands: {
54
- create: pikkuCLICommand({
55
- parameters: '<username> <email>',
56
- func: createUser,
57
- render: userRenderer,
58
- options: {
59
- admin: {
60
- description: 'Create as admin',
61
- short: 'a',
62
- default: false,
63
- },
64
- },
65
- }),
66
- list: pikkuCLICommand({
67
- func: listUsers,
68
- render: usersRenderer,
69
- options: {
70
- limit: { description: 'Max results', short: 'l' },
71
- },
72
- }),
73
- delete: pikkuCLICommand({
74
- parameters: '<username>',
75
- func: deleteUser,
76
- description: 'Delete a user',
77
- }),
78
- },
79
- },
80
- },
81
- })
82
- ```