@pikku/skills 0.12.21 → 0.12.25

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 (101) hide show
  1. package/CHANGELOG.md +125 -0
  2. package/dist/skills.gen.js +1 -1
  3. package/package.json +1 -1
  4. package/skills/pikku-addon/SKILL.md +10 -9
  5. package/skills/pikku-agent/SKILL.md +67 -316
  6. package/skills/pikku-agent/references/agents.md +299 -0
  7. package/skills/{pikku-ai-vercel/SKILL.md → pikku-agent/references/runner-vercel.md} +2 -24
  8. package/skills/{pikku-ai-voice/SKILL.md → pikku-agent/references/voice.md} +1 -22
  9. package/skills/pikku-architect/SKILL.md +264 -0
  10. package/skills/pikku-auth/SKILL.md +89 -0
  11. package/skills/{pikku-better-auth/SKILL.md → pikku-auth/references/better-auth.md} +42 -47
  12. package/skills/{pikku-jose/SKILL.md → pikku-auth/references/jose.md} +1 -23
  13. package/skills/{pikku-machine-auth/SKILL.md → pikku-auth/references/machine-auth.md} +0 -23
  14. package/skills/{pikku-permissions/SKILL.md → pikku-auth/references/permissions.md} +5 -24
  15. package/skills/{pikku-security/SKILL.md → pikku-auth/references/sessions.md} +3 -23
  16. package/skills/pikku-build/SKILL.md +87 -0
  17. package/skills/{pikku-build-app/SKILL.md → pikku-build/references/app.md} +77 -25
  18. package/skills/{pikku-feature/SKILL.md → pikku-build/references/feature.md} +1 -8
  19. package/skills/{pikku-build-app → pikku-build}/references/multi-app.md +1 -1
  20. package/skills/{pikku-build-platform/SKILL.md → pikku-build/references/platform.md} +22 -37
  21. package/skills/{pikku-template-clone/SKILL.md → pikku-build/references/post-clone.md} +0 -6
  22. package/skills/{pikku-build-quick/SKILL.md → pikku-build/references/quick.md} +6 -22
  23. package/skills/{pikku-build-app → pikku-build}/references/ship.md +7 -1
  24. package/skills/pikku-concepts/SKILL.md +75 -8
  25. package/skills/pikku-concepts/references/concept-mapping.md +8 -8
  26. package/skills/pikku-deploy/SKILL.md +158 -0
  27. package/skills/{pikku-deploy-azure/SKILL.md → pikku-deploy/references/azure.md} +18 -50
  28. package/skills/pikku-deploy/references/cloudflare.md +104 -0
  29. package/skills/pikku-deploy/references/express.md +92 -0
  30. package/skills/{pikku-deploy-fastify/SKILL.md → pikku-deploy/references/fastify.md} +8 -32
  31. package/skills/{pikku-deploy-lambda/SKILL.md → pikku-deploy/references/lambda.md} +6 -27
  32. package/skills/{pikku-deploy-nextjs/SKILL.md → pikku-deploy/references/nextjs.md} +9 -33
  33. package/skills/pikku-deploy/references/uws.md +72 -0
  34. package/skills/pikku-deploy/references/ws.md +75 -0
  35. package/skills/pikku-emails/SKILL.md +3 -2
  36. package/skills/pikku-fabric/SKILL.md +20 -10
  37. package/skills/{pikku-fabric-debug/SKILL.md → pikku-fabric/references/debugging.md} +0 -6
  38. package/skills/pikku-i18n/SKILL.md +60 -207
  39. package/skills/{pikku-paraglide/SKILL.md → pikku-i18n/references/enum-labels.md} +0 -6
  40. package/skills/pikku-i18n/references/messages.md +218 -0
  41. package/skills/{pikku-rtl/SKILL.md → pikku-i18n/references/rtl.md} +3 -9
  42. package/skills/pikku-knowledge/SKILL.md +14 -0
  43. package/skills/pikku-kysely/SKILL.md +13 -13
  44. package/skills/pikku-meta/SKILL.md +58 -130
  45. package/skills/{pikku-deps/SKILL.md → pikku-meta/references/audit.md} +1 -17
  46. package/skills/pikku-meta/references/meta.md +114 -0
  47. package/skills/{pikku-versioning/SKILL.md → pikku-meta/references/versioning.md} +0 -26
  48. package/skills/pikku-middleware/SKILL.md +8 -8
  49. package/skills/pikku-n8n-import/SKILL.md +0 -1
  50. package/skills/pikku-react/SKILL.md +50 -298
  51. package/skills/pikku-react/references/client.md +293 -0
  52. package/skills/{pikku-react-query/SKILL.md → pikku-react/references/react-query.md} +2 -22
  53. package/skills/{pikku-workflows-client/SKILL.md → pikku-react/references/workflows.md} +1 -22
  54. package/skills/pikku-scenario/SKILL.md +64 -49
  55. package/skills/pikku-scenario/references/persona-run.md +148 -0
  56. package/skills/pikku-service-backends/SKILL.md +154 -0
  57. package/skills/pikku-service-backends/references/aws.md +106 -0
  58. package/skills/pikku-service-backends/references/backblaze.md +57 -0
  59. package/skills/pikku-service-backends/references/mongodb.md +90 -0
  60. package/skills/pikku-service-backends/references/redis.md +75 -0
  61. package/skills/pikku-service-backends/references/schema.md +63 -0
  62. package/skills/pikku-services/SKILL.md +68 -291
  63. package/skills/{pikku-audit/SKILL.md → pikku-services/references/audit.md} +0 -22
  64. package/skills/{pikku-config/SKILL.md → pikku-services/references/config.md} +1 -25
  65. package/skills/{pikku-pino/SKILL.md → pikku-services/references/pino.md} +0 -20
  66. package/skills/pikku-services/references/services.md +272 -0
  67. package/skills/pikku-software-archaeology/README.md +5 -1
  68. package/skills/pikku-software-archaeology/SKILL.md +15 -2
  69. package/skills/{pikku-product-second-opinion/example/sample-report.md → pikku-software-archaeology/example/second-opinion-sample-report.md} +1 -1
  70. package/skills/pikku-software-archaeology/references/blueprint.schema.json +1 -1
  71. package/skills/pikku-software-archaeology/references/pikku-mapping.md +3 -3
  72. package/skills/{pikku-product-second-opinion/SKILL.md → pikku-software-archaeology/references/second-opinion.md} +4 -9
  73. package/skills/pikku-webhook/SKILL.md +199 -0
  74. package/skills/pikku-wiring/SKILL.md +180 -0
  75. package/skills/{pikku-websocket/SKILL.md → pikku-wiring/references/channel.md} +2 -35
  76. package/skills/{pikku-cli/SKILL.md → pikku-wiring/references/cli.md} +1 -33
  77. package/skills/{pikku-gateway-slack/SKILL.md → pikku-wiring/references/gateway-slack.md} +0 -23
  78. package/skills/{pikku-http/SKILL.md → pikku-wiring/references/http.md} +4 -40
  79. package/skills/{pikku-mcp/SKILL.md → pikku-wiring/references/mcp.md} +0 -33
  80. package/skills/{pikku-queue/SKILL.md → pikku-wiring/references/queue.md} +1 -33
  81. package/skills/{pikku-realtime/SKILL.md → pikku-wiring/references/realtime.md} +2 -25
  82. package/skills/{pikku-rpc/SKILL.md → pikku-wiring/references/rpc.md} +0 -32
  83. package/skills/{pikku-schedule/SKILL.md → pikku-wiring/references/scheduler.md} +1 -35
  84. package/skills/{pikku-trigger/SKILL.md → pikku-wiring/references/trigger.md} +0 -43
  85. package/skills/pikku-workflow/SKILL.md +3 -3
  86. package/skills/pikku-aws/SKILL.md +0 -161
  87. package/skills/pikku-backblaze/SKILL.md +0 -104
  88. package/skills/pikku-deploy-cloudflare/SKILL.md +0 -123
  89. package/skills/pikku-deploy-express/SKILL.md +0 -122
  90. package/skills/pikku-deploy-uws/SKILL.md +0 -144
  91. package/skills/pikku-mongodb/SKILL.md +0 -113
  92. package/skills/pikku-product-second-opinion/README.md +0 -43
  93. package/skills/pikku-redis/SKILL.md +0 -99
  94. package/skills/pikku-schema-ajv/SKILL.md +0 -83
  95. package/skills/pikku-schema-cfworker/SKILL.md +0 -82
  96. package/skills/pikku-ws/SKILL.md +0 -87
  97. /package/skills/{pikku-build-app → pikku-build}/references/theming.md +0 -0
  98. /package/skills/{pikku-product-second-opinion/references/report-template.md → pikku-software-archaeology/references/second-opinion-report-template.md} +0 -0
  99. /package/skills/{pikku-cli/references/complete-example.md → pikku-wiring/references/cli-complete-example.md} +0 -0
  100. /package/skills/{pikku-http → pikku-wiring}/references/http-options.md +0 -0
  101. /package/skills/{pikku-realtime/references/other-routes.md → pikku-wiring/references/realtime-other-routes.md} +0 -0
@@ -0,0 +1,89 @@
1
+ ---
2
+ name: pikku-auth
3
+ description: >-
4
+ Use for anything about identity in a Pikku app — authenticating a caller (login, logout,
5
+ sessions, cookies, bearer tokens, API keys, JWT, OAuth/social providers, MFA, Better Auth) and
6
+ authorizing one (pikkuPermission, pikkuAuth, scopes, defineScope, global permissions). Covers
7
+ which of the two a problem actually is, the built-in auth strategies, machine-to-machine auth
8
+ and `pikku login`, and the JWT service. TRIGGER when: user asks about login, logout, session,
9
+ cookie auth, bearer tokens, API keys, JWT, Better Auth, social providers, restricting who may
10
+ call a function, resource ownership, roles, scopes, or hits MissingScopeError or
11
+ InvalidSessionError. DO NOT TRIGGER when: user asks about middleware mechanics with no identity
12
+ involved (use pikku-middleware) or about secrets and env vars (use pikku-services).
13
+ installGroups: [core]
14
+ ---
15
+
16
+ # Pikku Auth
17
+
18
+ Signatures and option keys come from `pikku doc` — run `pikku doc --ai` for the
19
+ installed surface. This skill is the part the compiler cannot tell you: which of
20
+ the two problems you actually have, and what goes wrong in each.
21
+
22
+ ## First: authentication or authorization?
23
+
24
+ They are separate gates, and confusing them is the most common mistake in a
25
+ Pikku app.
26
+
27
+ **Authentication** answers _who is calling_. It happens in middleware, before the
28
+ function runs, and ends in a call to `setSession`.
29
+
30
+ **Authorization** answers _may this caller do this_. It is declared on the
31
+ function — `scopes` and `permissions` — never checked inside its body.
32
+
33
+ A `permissions` entry that verifies a bearer token and returns `true` is
34
+ authentication wearing an authorization hat: it leaves the function sessionless,
35
+ so every body still has to work out who called it. Resolve the credential in
36
+ middleware instead.
37
+
38
+ ## Pick the reference
39
+
40
+ | You are… | Read |
41
+ | --- | --- |
42
+ | Restricting who may call a function — ownership, roles, scopes | `references/permissions.md` |
43
+ | Reading or setting the session, or wiring `authBearer`/`authCookie`/`authAPIKey` | `references/sessions.md` |
44
+ | Standing up user sign-in — OAuth, email+password, MFA, organizations | `references/better-auth.md` |
45
+ | Authenticating a CLI, agent, sandbox or worker — API keys, `pikku login` | `references/machine-auth.md` |
46
+ | Configuring the JWT service, or rotating a signing secret | `references/jose.md` |
47
+
48
+ ## All authentication goes through `@pikku/better-auth`
49
+
50
+ There is no second auth story. A hand-rolled user table, a bespoke password
51
+ hash, a custom OAuth dance — all of them are the wrong answer, and the console
52
+ will not work against them. `references/better-auth.md` has the setup; the
53
+ built-in strategies in `references/sessions.md` are how a resolved credential
54
+ becomes a Pikku session, not a replacement for it.
55
+
56
+ ## The three gates
57
+
58
+ Authorization is three independent gates, all of which must pass, in this order:
59
+
60
+ 1. **Scopes** (`scopes`) — AND'd, checked before input validation, fails closed.
61
+ 2. **Global permissions** (`addGlobalPermission`) — AND'd, an app-wide baseline.
62
+ 3. **The function's own `permissions`** — OR'd groups of AND'd entries.
63
+
64
+ They are independent: a broad global gate can never satisfy a function's own
65
+ requirement, and a scope can only ever narrow access, never grant it.
66
+
67
+ ## What NOT to do
68
+
69
+ - **Do not check authorization inside `func`.** The `permissions` field is
70
+ visible to the inspector; a check in the body is invisible to `pikku info
71
+ permissions` and to an audit. The one sanctioned exception is
72
+ `permissionsInBody`, which is purely declarative — see
73
+ `references/permissions.md`.
74
+ - **Do not write an "is signed in" permission.** `auth: true` (the default on
75
+ `pikkuFunc`) already requires the session. A checker returning `!!session`
76
+ gates nothing.
77
+ - **Do not put `scopes` on a `pikkuSessionlessFunc`.** Scopes fail closed and an
78
+ anonymous caller holds none, so it would reject every caller it exists to
79
+ serve. Gate those with `permissions`, which receive an optional session.
80
+ - **Do not expect the built-in strategies to authenticate a non-HTTP caller.**
81
+ `authBearer`, `authCookie` and `authAPIKey` all step aside when there is no
82
+ HTTP request — a queue job, a scheduled task or a channel message needs its
83
+ session set another way.
84
+ - **Do not share one header between the human and machine paths.**
85
+ `Authorization: Bearer` is the human session; `x-api-key` is the machine key.
86
+ Merging them reintroduces the ambiguity the split exists to remove.
87
+ - **Do not reach for wire-, tag- or route-level permissions.** They were removed
88
+ in #972. Permissions live on the function, plus the optional global gate; tags
89
+ are organizational only.
@@ -1,18 +1,3 @@
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: user asks
9
- about the actor plugin, /sign-in/actor, signing in as a scenario persona, or SCENARIO_ACTOR_SECRET. TRIGGER when:
10
- user asks about ANY form of authentication, login, logout, sessions, or user identity — always
11
- answer with this skill. DO NOT TRIGGER when: user asks about JWT middleware (use pikku-security)
12
- or custom session services (use pikku-services).
13
- installGroups: [fabric]
14
- ---
15
-
16
1
  # Pikku Better Auth Integration
17
2
 
18
3
  ## ⚠️ MANDATORY RULE — READ FIRST
@@ -30,17 +15,6 @@ The only acceptable auth implementation in a Pikku app is the one described in t
30
15
 
31
16
  ---
32
17
 
33
- ## Agent Operating Procedure
34
-
35
- Use this skill as an execution checklist, not reference material.
36
-
37
- 1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
38
- 2. Identify the source files that own the behavior. Do not start by reading generated output, `.pikku`, `node_modules`, or build artifacts.
39
- 3. Make the smallest source change that satisfies the task. Keep generated files generated.
40
- 4. Validate with the narrowest relevant command first, then run `pikku all` when functions, wirings, schemas, or generated clients may have changed.
41
- 5. If validation fails, fix the source cause and rerun. Do not edit generated files.
42
-
43
- `@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.
44
18
 
45
19
  ## Installation
46
20
 
@@ -61,7 +35,7 @@ You do NOT hand-write routes, the session middleware, or the secret wiring — `
61
35
 
62
36
  ### The console requires Better Auth
63
37
 
64
- 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.
38
+ 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-meta` for the console's Security screen.
65
39
 
66
40
  ---
67
41
 
@@ -516,9 +490,9 @@ an `actor: true` row only under `pikku dev`. With the opt-in set, a stage signs
516
490
  in as the personas the deployment provisioned when it started and refuses
517
491
  everything else (`No actor account exists for that address`), so holding the
518
492
  secret on such a stage does not let anyone invent identities. Those rows are
519
- written by `provisionPersonas` from `@pikku/better-auth`, called in the server's
520
- own lifecycle, so provisioning needs no actor secret and works on a stage whose
521
- endpoint is shut.
493
+ written by the fabric plugin when an operator asks to act as an address the
494
+ stage has no account for, so provisioning needs no actor secret and works on a
495
+ stage whose endpoint is shut.
522
496
 
523
497
  **`SCENARIO_ACTOR_SECRET` is a credential as powerful as the most privileged
524
498
  persona.** Provisioning grants declared roles to actor accounts, so an
@@ -544,30 +518,46 @@ This is the endpoint `pikku scenario` signs its actors in through, and the one
544
518
  the frontend dev switcher posts to — see `pikku-scenario` for declaring the
545
519
  actors and `pikku-react` for `useDevActors()`.
546
520
 
547
- ### Provisioning personas (`provisionPersonas`)
521
+ ### Provisioning personas
548
522
 
549
- Anywhere but `pikku dev`, the accounts have to exist before anyone signs in.
550
- The deployment creates them itself, from its own lifecycle:
523
+ Anywhere but `pikku dev`, the accounts have to exist before anyone signs in. The
524
+ stage creates them itself, from the personas you hand `pikkuFabric`:
551
525
 
552
526
  ```ts
553
- import { provisionPersonas } from '@pikku/better-auth'
527
+ import { pikkuFabric } from '@pikku/better-auth'
554
528
  import {
555
529
  personaConfigs,
556
530
  personaEnvironments,
557
531
  } from '#pikku/pikku-personas.gen.js'
558
532
 
559
- await provisionPersonas(singletonServices, {
560
- personas: personaConfigs,
561
- environments: personaEnvironments,
533
+ pikkuFabric({
534
+ publicKey,
535
+ audience,
536
+ scopeService,
537
+ personas: {
538
+ personas: personaConfigs,
539
+ environments: personaEnvironments,
540
+ },
562
541
  })
563
542
  ```
564
543
 
565
- It runs where the database already is, which is the point: the CLI has no
566
- connection to a deployed environment's database — it resolves one from the local
567
- project config — so a `pikku persona sync staging` that wrote rows would write
568
- them to whatever database the checkout happened to point at. `pikku persona sync
569
- <environment>` still exists, and reports who that environment will provision and
570
- why anyone was skipped, which is what you run _before_ the deploy.
544
+ There is nothing else to call and nothing to schedule. The plugin's operator
545
+ endpoint resolves the address the caller wants to act as; a miss provisions the
546
+ declaration and looks again. On a stage that already holds the persona that is
547
+ one query, and the pass only runs when there is genuinely something absent to
548
+ create.
549
+
550
+ **Do not reach for `pikkuServerLifecycle`'s `afterStart` for this.** That hook is
551
+ invoked by `pikku serve` and `pikku dev` and by nothing else — no deploy runtime
552
+ calls it — so a stage on Workers or a serverless target that provisioned from
553
+ `afterStart` provisioned nothing, and every persona signed in holding no roles.
554
+
555
+ Provisioning runs where the database already is, which is the point: the CLI has
556
+ no connection to a deployed environment's database — it resolves one from the
557
+ local project config — so a `pikku persona sync staging` that wrote rows would
558
+ write them to whatever database the checkout happened to point at. `pikku persona
559
+ sync <environment>` still exists, and reports who that environment will provision
560
+ and why anyone was skipped, which is what you run _before_ the deploy.
571
561
 
572
562
  It creates missing accounts as `actor: true`, applies the roles each persona
573
563
  declares, and is additive — it never revokes. `PIKKU_ENV` (or an explicit
@@ -583,10 +573,15 @@ open. By default provisioning warns about those accounts and changes nothing.
583
573
  `orphans: 'ban'` shuts them:
584
574
 
585
575
  ```ts
586
- await provisionPersonas(singletonServices, {
587
- personas: personaConfigs,
588
- environments: personaEnvironments,
589
- orphans: 'ban',
576
+ pikkuFabric({
577
+ publicKey,
578
+ audience,
579
+ scopeService,
580
+ personas: {
581
+ personas: personaConfigs,
582
+ environments: personaEnvironments,
583
+ orphans: 'ban',
584
+ },
590
585
  })
591
586
  ```
592
587
 
@@ -1,27 +1,5 @@
1
- ---
2
- name: pikku-jose
3
- description: >-
4
- Use when setting up JWT authentication with the jose library in a Pikku app. Covers
5
- JoseJWTService constructor, secret rotation, token encoding/decoding/verification. TRIGGER when:
6
- code uses JoseJWTService, user asks about JWT setup, token signing, token verification, or
7
- @pikku/jose. DO NOT TRIGGER when: user asks about session middleware (use pikku-security) or
8
- general service setup (use pikku-services).
9
- installGroups: [fabric]
10
- ---
11
-
12
1
  # Pikku Jose (JWT Service)
13
2
 
14
- ## Agent Operating Procedure
15
-
16
- Use this skill as an execution checklist, not reference material.
17
-
18
- 1. Discover before editing. 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
- `@pikku/jose` provides JWT signing, verification, and decoding using the [jose](https://github.com/panva/jose) library. Implements the `JWTService` interface from `@pikku/core`.
25
3
 
26
4
  ## Installation
27
5
 
@@ -86,7 +64,7 @@ await jwt.init()
86
64
  A signing key is a secret, so it comes from the secrets service rather than
87
65
  `process.env` — and because `getSecrets` is a function called on demand, reading
88
66
  it there (not once at construction) is what makes the re-init-on-unknown-kid path
89
- above actually see a rotated key. See `pikku-config`.
67
+ above actually see a rotated key. See `pikku-services`.
90
68
 
91
69
  ### Secret Rotation
92
70
 
@@ -1,17 +1,3 @@
1
- ---
2
- name: pikku-machine-auth
3
- description: >-
4
- Use when authenticating a CLI/agent/service against a Pikku server, adding machine-to-machine
5
- (M2M) auth, issuing scoped API keys for sandboxes/agents/workers, or wiring better-auth sessions
6
- into Pikku middleware. Covers `pikku login` (device-authorization), the better-auth API Key
7
- plugin, machine identities, and `betterAuthSession` with the api-key branch. TRIGGER when: user
8
- asks about CLI login, `pikku login`, machine agents, service-to-service auth, API keys, client
9
- credentials, sandbox/worker tokens, or resolving a better-auth session in a Pikku function. DO
10
- NOT TRIGGER when: user asks about end-user HTTP session/cookie auth only (use pikku-http + the
11
- app betterAuth config) or about WebSocket channel mechanics (use pikku-websocket).
12
- installGroups: [fabric]
13
- ---
14
-
15
1
  # Pikku Machine Auth
16
2
 
17
3
  Unified authentication for humans **and** machines against a Pikku + better-auth
@@ -29,15 +15,6 @@ Both resolve to a Pikku `UserSession` through one middleware:
29
15
  > better-auth's oidc-provider. The API Key plugin gives the same capability (a
30
16
  > baked secret a service presents for scoped access), not the wire protocol.
31
17
 
32
- ## Agent Operating Procedure
33
-
34
- 1. Discover before editing — inspect the app's `betterAuth({ plugins: [...] })`
35
- config and existing middleware wiring before adding anything.
36
- 2. Server changes go in the auth factory + a middleware wiring file; never put
37
- auth checks in a function body (use `permissions`).
38
- 3. The API Key plugin contributes an `apikey` table — add the matching SQL
39
- migration and regenerate DB types before relying on it.
40
- 4. Validate with the narrowest command, then `pikku all`.
41
18
 
42
19
  ## Human path — `pikku login`
43
20
 
@@ -1,21 +1,8 @@
1
- ---
2
- name: pikku-permissions
3
- description: >-
4
- Use when adding authorization checks to Pikku functions — pikkuPermission, pikkuAuth, scopes and
5
- defineScope, per-function permissions, global permissions, or understanding the scope/OR/AND
6
- gating logic. TRIGGER when: user wants to restrict who can call a function, check resource
7
- ownership, add role-based or scope-based access, declares or grants scopes, hits
8
- MissingScopeError, or asks where permission checks belong. DO NOT TRIGGER when: user asks about
9
- middleware or request interception (use pikku-middleware), authentication strategies (use
10
- pikku-security), or session management.
11
- installGroups: [core]
12
- ---
13
-
14
1
  # Pikku Permissions
15
2
 
16
3
  ## ⛔ FIRST: is the caller a machine with a token? ⛔
17
4
 
18
- **Then this is NOT a permissions problem.** Resolve the token in `addHTTPMiddleware('*')` middleware that calls `setSession`, make the function a `pikkuFunc`, and gate it with `scopes`. A `permissions` check that verifies a bearer token and returns `true` is authentication wearing an authorization hat — and it leaves the function sessionless, so every body still has to work out who called it. See the machine-auth section of `pikku-middleware`. The only exception is a bootstrap endpoint whose caller has no identity yet (a shared-secret registration, a login): that one is sessionless and declares its gate here.
5
+ **Then this is NOT a permissions problem.** Resolve the token in `addHTTPMiddleware('*')` middleware that calls `setSession`, make the function a `pikkuFunc`, and gate it with `scopes`. A `permissions` check that verifies a bearer token and returns `true` is authentication wearing an authorization hat — and it leaves the function sessionless, so every body still has to work out who called it. See `references/machine-auth.md`. The only exception is a bootstrap endpoint whose caller has no identity yet (a shared-secret registration, a login): that one is sessionless and declares its gate here.
19
6
 
20
7
  ## The Rule
21
8
 
@@ -43,12 +30,6 @@ export const deleteBook = pikkuFunc({
43
30
  })
44
31
  ```
45
32
 
46
- ## Agent Operating Procedure
47
-
48
- 1. Discover before editing. Run `pikku info permissions --verbose` and `pikku info functions --verbose` to understand what permissions are already defined and applied.
49
- 2. Define permission checkers in a `src/permissions.ts` or domain-specific `src/lib/*-permissions.ts` file.
50
- 3. Apply them via the `permissions` field on the function. For an app-wide baseline that every function must additionally satisfy, use `addGlobalPermission`.
51
- 4. Validate: run `pikku all --tsc` to confirm permission checker signatures are correct.
52
33
 
53
34
  ## Permission Factories
54
35
 
@@ -58,7 +39,7 @@ Use for checks that read the session but need no request data — and that asser
58
39
  something **beyond** merely having a session (a flag, a tier, a claim).
59
40
 
60
41
  ```typescript
61
- import { pikkuAuth } from '#pikku/function'
42
+ import { pikkuAuth } from '#pikku/auth'
62
43
 
63
44
  // Good: a real gate on the session's contents, not just its existence.
64
45
  export const isVerified = pikkuAuth(
@@ -89,7 +70,7 @@ A permission answers "_may this user do this?_" (role, ownership, tier) — neve
89
70
  Use when authorization depends on the actual request data (e.g., resource ownership).
90
71
 
91
72
  ```typescript
92
- import { pikkuPermission } from '#pikku/function'
73
+ import { pikkuPermission } from '#pikku/auth'
93
74
 
94
75
  export const isBookOwner = pikkuPermission(
95
76
  async ({ db }, { bookId }, { session }) => {
@@ -139,7 +120,7 @@ export const deleteBook = pikkuFunc({
139
120
  A global permission is an app-wide baseline that **every** function must additionally pass. It is an independent AND gate: it can only ever _narrow_ access — it never grants access a function's own `permissions` would deny.
140
121
 
141
122
  ```typescript
142
- import { addGlobalPermission } from '#pikku/function'
123
+ import { addGlobalPermission } from '#pikku/auth'
143
124
 
144
125
  addGlobalPermission([isEmployee]) // every function now also requires an employee session
145
126
  ```
@@ -248,7 +229,7 @@ declared, inspectable, and reusable.
248
229
 
249
230
  ```typescript
250
231
  // src/permissions.ts
251
- import { pikkuAuth, pikkuPermission } from '#pikku/function'
232
+ import { pikkuAuth, pikkuPermission } from '#pikku/auth'
252
233
 
253
234
  export const isVerified = pikkuAuth(
254
235
  async (_services, session) => !!session?.emailVerified
@@ -1,25 +1,5 @@
1
- ---
2
- name: pikku-security
3
- description: >-
4
- Use when adding authentication or session management to a Pikku app — pikkuAuth, session
5
- lifecycle (setSession/clearSession), built-in auth strategies (authBearer, authCookie,
6
- authAPIKey), or JWT setup. TRIGGER when: user asks about login, logout, session, bearer tokens,
7
- cookie auth, API keys, or JWT. DO NOT TRIGGER when: user asks about middleware (use
8
- pikku-middleware), permissions/authorization checks (use pikku-permissions), or secrets/env vars
9
- (use pikku-config).
10
- installGroups: [core]
11
- ---
12
-
13
1
  # Pikku Security (Authentication & Sessions)
14
2
 
15
- ## Agent Operating Procedure
16
-
17
- 1. Discover before editing. Run `pikku info middleware --verbose` and `pikku info functions --verbose` to understand existing auth setup.
18
- 2. Auth strategies live in wirings files — do not put `addHTTPMiddleware` calls inside function bodies.
19
- 3. Validate with `pikku all --tsc` after changes — it regenerates and then type-checks in one pass, and fails on type errors. Use `--tsc-summary` for a compact one-line-per-error report.
20
-
21
- For **middleware** (including tag middleware and service-to-service bearer auth) see `pikku-middleware`.
22
- For **permissions** (pikkuPermission, pikkuAuth, per-function authorization) see `pikku-permissions`.
23
3
 
24
4
  ## Session Management
25
5
 
@@ -62,7 +42,7 @@ Apply these via `addHTTPMiddleware` in a wirings file:
62
42
 
63
43
  ```typescript
64
44
  import { authBearer, authCookie, authAPIKey } from '#pikku/middleware'
65
- import { addHTTPMiddleware } from '#pikku/http'
45
+ import { addHTTPMiddleware } from '#pikku/middleware'
66
46
 
67
47
  // JWT bearer token — reads Authorization header
68
48
  addHTTPMiddleware('*', [authBearer()])
@@ -118,7 +98,7 @@ response.
118
98
 
119
99
  ```typescript
120
100
  // permissions.ts
121
- import { pikkuAuth, pikkuPermission } from '#pikku/function'
101
+ import { pikkuAuth, pikkuPermission } from '#pikku/auth'
122
102
 
123
103
  export const isAuthenticated = pikkuAuth(
124
104
  async (_services, session) => !!session
@@ -129,7 +109,7 @@ export const isVerified = pikkuAuth(
129
109
 
130
110
  // wirings/auth.wiring.ts
131
111
  import { authCookie } from '#pikku/middleware'
132
- import { addHTTPMiddleware } from '#pikku/http'
112
+ import { addHTTPMiddleware } from '#pikku/middleware'
133
113
 
134
114
  addHTTPMiddleware('*', [
135
115
  authCookie({
@@ -0,0 +1,87 @@
1
+ ---
2
+ name: pikku-build
3
+ description: >-
4
+ Use to build on Pikku — turning a fresh scaffold into a working app (quick spike, real product,
5
+ or a showcase that exercises every surface), adding a feature to an app that already exists, and
6
+ the one-off cleanup right after a template is cloned. Covers the knowledge base, personas and
7
+ roles, milestone planning, the scenario that proves each one, theming, multi-app layouts and
8
+ deploying. TRIGGER when: the user asks for an app to be built on Pikku, a freshly scaffolded
9
+ project needs turning into a product, the user asks to add a feature or wire up a new endpoint
10
+ in a working app, or a template was just cloned or scaffolded. DO NOT TRIGGER when: the user
11
+ asks for a one-off edit to an existing function, asks about Pikku concepts (use pikku-concepts),
12
+ or wants one specific surface explained rather than built (use that surface's skill).
13
+ allowed-tools: Bash(yarn pikku meta *), Bash(yarn pikku all *), Bash(yarn tsc), Bash(git status *), Bash(git diff *), Bash(git switch *), Bash(git checkout *), Bash(git checkout -b *), Bash(git add *), Bash(git commit *), Bash(git rm *), Bash(git mv *), Bash(git log *), Bash(git branch *), Bash(yarn pikku fabric report *), Bash(npx --no pikku fabric report *)
14
+ argument-hint: '[feature description]'
15
+ ---
16
+
17
+ # Build on Pikku
18
+
19
+ ## Which mode
20
+
21
+ | The situation | Read |
22
+ | --- | --- |
23
+ | A template was just cloned or scaffolded, and the tree still looks like one | `references/post-clone.md` first, then come back |
24
+ | A real product, meant to be picked up by someone else | `references/app.md` — the default |
25
+ | A spike, a throwaway demo, an idea nobody has committed to | `references/quick.md` |
26
+ | A showcase meant to exercise every Pikku surface | `references/platform.md`, which is a delta on top of `references/app.md` |
27
+ | A feature added to an app that already has its knowledge base and milestones | `references/feature.md` |
28
+
29
+ **App is the default.** A small or toy-sounding app does not make it Quick;
30
+ only an explicit signal of speed or throwaway-ness does. Platform is not "App
31
+ plus more effort" — it is App plus a deliberate surface checklist, so read the
32
+ base first and follow it in full rather than blending the two into one plan.
33
+
34
+ The supporting references belong to whichever mode sends you to them:
35
+ `references/multi-app.md` (a second frontend), `references/theming.md`
36
+ (authoring the theme), `references/ship.md` (deploying, and the Fabric-readiness
37
+ contract).
38
+
39
+ ## Bootstrap before anything else
40
+
41
+ ```sh
42
+ bunx --bun pikku bootstrap
43
+ ```
44
+
45
+ Once, now — not later when you start building. It wires the `#pikku` alias the
46
+ generated code depends on, and on a fresh scaffold **every command that touches
47
+ codegen fails until it has run**, including ones you would reasonably reach for
48
+ while still planning. Those failures look alarming and are nothing but this.
49
+
50
+ ## What holds in every mode
51
+
52
+ - **The branch and the diff are the contract.** There is no plan JSON. A
53
+ reviewer sees real, compiled, working code: apply is a merge, reject is a
54
+ `git branch -D`.
55
+ - **Discover before editing.** `yarn pikku meta context --json` returns
56
+ functions, wires, middleware, permissions, workflows, `capabilities` and
57
+ `layout` in one call. Fall back to targeted `meta` commands only for a full
58
+ schema or a workflow's steps.
59
+ - **`metaLocale` in `pikku.config.json` is the language of authored meta** —
60
+ every `description`, `title` and step `template` the console renders.
61
+ Identifiers stay English whatever it says, and the product's own language
62
+ lives in `messages/*.json`.
63
+ - **`pikku all` is the gate.** Run it after touching functions, wirings or
64
+ schemas, and treat its criticals as real.
65
+ - **A milestone is planned by a different seat than the one that builds it.**
66
+ The plan — tables, functions, wires, roles, scopes, screens, scenarios, in
67
+ passes — is written through `pikku knowledge plan set` by `pikku-architect`,
68
+ and `pikku knowledge plan progress` measures the build against it from the
69
+ generated meta. A builder who writes its own plan is grading itself.
70
+
71
+ ## What NOT to do
72
+
73
+ - **Do not skip ahead in App mode.** Knowledge, then people, then milestones,
74
+ then one milestone at a time — planned, built, proven by a scenario, and
75
+ closed against its plan before the next starts. The order is the method.
76
+ - **Do not close a milestone your plan says is unfinished.** Build the missing
77
+ item, or defer it with a reason through `pikku knowledge plan defer`. Never
78
+ edit the plan to match what you built, and never drop an item silently.
79
+ - **Do not let a Quick build be mistaken for a real one.** It skips
80
+ `knowledge/`, milestone planning, design direction and refusal scenarios — say
81
+ so out loud to the user when you finish, and point at the way out.
82
+ - **Do not introduce a wire of a type whose `capabilities.<type>` is `false`**
83
+ unless the user asked for it.
84
+ - **Do not hand-edit generated files** — `.pikku/`, `*.gen.*` or the SDK. Fix the
85
+ source and regenerate.
86
+ - **Do not invent a role.** An invented role becomes invented screens; build only
87
+ the roles the user named.