@pikku/skills 0.12.1 → 0.12.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/skills.gen.js +1 -1
- package/package.json +1 -1
- package/skills/pikku-addon/SKILL.md +1 -1
- package/skills/pikku-ai-agent/SKILL.md +1 -1
- package/skills/pikku-ai-vercel/SKILL.md +1 -1
- package/skills/pikku-ai-voice/SKILL.md +1 -1
- package/skills/pikku-aws/SKILL.md +1 -1
- package/skills/pikku-backblaze/SKILL.md +1 -1
- package/skills/pikku-better-auth/SKILL.md +35 -24
- package/skills/pikku-cli/SKILL.md +1 -1
- package/skills/pikku-concepts/SKILL.md +8 -1
- package/skills/pikku-concepts/references/concept-mapping.md +2 -2
- package/skills/pikku-config/SKILL.md +80 -40
- package/skills/pikku-cron/SKILL.md +1 -1
- package/skills/pikku-deploy-azure/SKILL.md +1 -1
- package/skills/pikku-deploy-cloudflare/SKILL.md +1 -1
- package/skills/pikku-deploy-express/SKILL.md +1 -1
- package/skills/pikku-deploy-fastify/SKILL.md +1 -1
- package/skills/pikku-deploy-lambda/SKILL.md +1 -1
- package/skills/pikku-deploy-nextjs/SKILL.md +1 -1
- package/skills/pikku-deploy-uws/SKILL.md +1 -1
- package/skills/pikku-fabric/SKILL.md +6 -6
- package/skills/pikku-feature/SKILL.md +7 -7
- package/skills/pikku-gateway-slack/SKILL.md +1 -1
- package/skills/pikku-http/SKILL.md +1 -1
- package/skills/pikku-info/SKILL.md +1 -1
- package/skills/pikku-jose/SKILL.md +1 -1
- package/skills/pikku-knowledge/SKILL.md +207 -0
- package/skills/pikku-kysely/SKILL.md +1 -1
- package/skills/pikku-mcp/SKILL.md +1 -1
- package/skills/pikku-mongodb/SKILL.md +1 -1
- package/skills/pikku-pino/SKILL.md +1 -1
- package/skills/pikku-queue/SKILL.md +1 -1
- package/skills/pikku-react/SKILL.md +1 -1
- package/skills/pikku-react-query/SKILL.md +1 -1
- package/skills/pikku-realtime/SKILL.md +1 -1
- package/skills/pikku-redis/SKILL.md +1 -1
- package/skills/pikku-rpc/SKILL.md +1 -1
- package/skills/pikku-scenario/SKILL.md +208 -6
- package/skills/pikku-schedule/SKILL.md +1 -1
- package/skills/pikku-schema-ajv/SKILL.md +1 -1
- package/skills/pikku-schema-cfworker/SKILL.md +1 -1
- package/skills/pikku-services/SKILL.md +1 -1
- package/skills/pikku-software-archaeology/README.md +16 -6
- package/skills/pikku-software-archaeology/references/pikku-mapping.md +30 -30
- package/skills/pikku-trigger/SKILL.md +1 -1
- package/skills/pikku-versioning/SKILL.md +1 -1
- package/skills/pikku-websocket/SKILL.md +1 -1
- package/skills/pikku-workflows-client/SKILL.md +1 -1
- package/skills/pikku-ws/SKILL.md +1 -1
package/package.json
CHANGED
|
@@ -16,7 +16,7 @@ installGroups: [core]
|
|
|
16
16
|
|
|
17
17
|
Use this skill as an execution checklist, not reference material.
|
|
18
18
|
|
|
19
|
-
1. Discover before editing.
|
|
19
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
20
20
|
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.
|
|
21
21
|
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
22
22
|
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.
|
|
@@ -15,7 +15,7 @@ installGroups: [core]
|
|
|
15
15
|
|
|
16
16
|
Use this skill as an execution checklist, not reference material.
|
|
17
17
|
|
|
18
|
-
1. Discover before editing.
|
|
18
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
19
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
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
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.
|
|
@@ -15,7 +15,7 @@ installGroups: [core]
|
|
|
15
15
|
|
|
16
16
|
Use this skill as an execution checklist, not reference material.
|
|
17
17
|
|
|
18
|
-
1. Discover before editing.
|
|
18
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
19
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
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
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.
|
|
@@ -14,7 +14,7 @@ description: >-
|
|
|
14
14
|
|
|
15
15
|
Use this skill as an execution checklist, not reference material.
|
|
16
16
|
|
|
17
|
-
1. Discover before editing.
|
|
17
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
18
18
|
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.
|
|
19
19
|
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
20
20
|
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.
|
|
@@ -14,7 +14,7 @@ description: >-
|
|
|
14
14
|
|
|
15
15
|
Use this skill as an execution checklist, not reference material.
|
|
16
16
|
|
|
17
|
-
1. Discover before editing.
|
|
17
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
18
18
|
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.
|
|
19
19
|
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
20
20
|
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.
|
|
@@ -12,7 +12,7 @@ description: >-
|
|
|
12
12
|
|
|
13
13
|
Use this skill as an execution checklist, not reference material.
|
|
14
14
|
|
|
15
|
-
1. Discover before editing.
|
|
15
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
16
16
|
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.
|
|
17
17
|
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
18
18
|
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.
|
|
@@ -54,7 +54,7 @@ Better Auth owns its own HTTP surface, database tables, and session cookie. The
|
|
|
54
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
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
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 `
|
|
57
|
+
4. **Generated `auth-secrets.gen.ts`** — a `defineSecret` for `BETTER_AUTH_SECRET` and for each social provider's OAuth credentials, plus a `defineVariable` for any non-secret provider config (e.g. `tenantId`).
|
|
58
58
|
|
|
59
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
60
|
|
|
@@ -86,7 +86,12 @@ export const auth = pikkuBetterAuth(async ({ secrets }) => {
|
|
|
86
86
|
secret: BETTER_AUTH_SECRET,
|
|
87
87
|
// memoryAdapter needs an array per model — `{}` throws "Model user not found"
|
|
88
88
|
// at runtime. Swap for the Kysely adapter in production (see below).
|
|
89
|
-
database: memoryAdapter({
|
|
89
|
+
database: memoryAdapter({
|
|
90
|
+
user: [],
|
|
91
|
+
session: [],
|
|
92
|
+
account: [],
|
|
93
|
+
verification: [],
|
|
94
|
+
}),
|
|
90
95
|
emailAndPassword: { enabled: true },
|
|
91
96
|
// ALWAYS enable for deployed apps — see "Stateless session" below.
|
|
92
97
|
session: { cookieCache: { enabled: true } },
|
|
@@ -98,7 +103,8 @@ export const auth = pikkuBetterAuth(async ({ secrets }) => {
|
|
|
98
103
|
```
|
|
99
104
|
|
|
100
105
|
**Key points:**
|
|
101
|
-
|
|
106
|
+
|
|
107
|
+
- `socialProviders` keys must be string literals — the CLI reads them statically to emit a `defineSecret` per provider. Provider keys mirror better-auth's built-in ids exactly (e.g. `microsoft`, NOT `microsoft-entra-id`; `cognito`; `github`).
|
|
102
108
|
- The factory runs lazily on the first auth request, so it pulls secrets/DB off the injected `services`.
|
|
103
109
|
- The default `basePath` is `/api/auth`. Override it by passing `basePath` to `betterAuth`.
|
|
104
110
|
- **Enable `session: { cookieCache: { enabled: true } }`** so non-auth units tree-shake the better-auth server out (see below).
|
|
@@ -115,7 +121,7 @@ Enabling `session: { cookieCache: { enabled: true } }` makes the CLI split out a
|
|
|
115
121
|
|
|
116
122
|
**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
123
|
|
|
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
|
|
124
|
+
- **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
125
|
- **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
126
|
|
|
121
127
|
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.
|
|
@@ -129,22 +135,22 @@ hold independently, which a single `role` string cannot express. Every gate the
|
|
|
129
135
|
package owns therefore resolves the caller's scopes through the registered
|
|
130
136
|
`ScopeService` and checks the `admin:*` tree:
|
|
131
137
|
|
|
132
|
-
| Gate
|
|
133
|
-
|
|
|
134
|
-
| `impersonation` (`betterAuthSession` / `betterAuthStatelessSession`) | `admin:impersonate`
|
|
135
|
-
| `credentialOAuth`'s `canLinkSingleton`
|
|
136
|
-
| the console's user directory
|
|
138
|
+
| Gate | Scope required |
|
|
139
|
+
| -------------------------------------------------------------------- | ------------------------ |
|
|
140
|
+
| `impersonation` (`betterAuthSession` / `betterAuthStatelessSession`) | `admin:impersonate` |
|
|
141
|
+
| `credentialOAuth`'s `canLinkSingleton` | `admin:credentials:link` |
|
|
142
|
+
| the console's user directory | `admin:users:list` |
|
|
137
143
|
|
|
138
144
|
Holding the bare `admin` scope satisfies all of them — a parent grant covers
|
|
139
145
|
everything nested beneath it — so `admin` is the direct replacement for the old
|
|
140
146
|
`role === 'admin'`.
|
|
141
147
|
|
|
142
|
-
Declare the tree in your own `
|
|
148
|
+
Declare the tree in your own `defineScope` (the CLI extracts it by AST, so it must
|
|
143
149
|
be an inline literal; `ADMIN_SCOPE_TREE` is exported from `@pikku/better-auth`
|
|
144
150
|
as the reference shape). Apps wiring `@pikku/addon-console` inherit it already.
|
|
145
151
|
|
|
146
152
|
```typescript
|
|
147
|
-
|
|
153
|
+
defineScope({
|
|
148
154
|
admin: {
|
|
149
155
|
displayName: 'Administration',
|
|
150
156
|
description: 'Capabilities that act on the application as a whole',
|
|
@@ -173,7 +179,7 @@ that is a configuration bug rather than a permissions decision. Pass your own
|
|
|
173
179
|
`canImpersonate` / `canLinkSingleton` to override the default entirely.
|
|
174
180
|
|
|
175
181
|
Sibling concerns — banning a user, listing users from your own screens — are
|
|
176
|
-
actions your app
|
|
182
|
+
actions your app _invokes_, not things pikku gates. Put them on your own
|
|
177
183
|
functions with `scopes: ['admin:users:ban']` and friends.
|
|
178
184
|
|
|
179
185
|
### 2. Production database adapter
|
|
@@ -184,9 +190,9 @@ For real deployments swap `memoryAdapter` for the Kysely adapter backed by an in
|
|
|
184
190
|
import { kyselyAdapter } from 'better-auth/adapters/kysely'
|
|
185
191
|
|
|
186
192
|
export const auth = pikkuBetterAuth(async ({ secrets, kysely }) => {
|
|
187
|
-
const { BETTER_AUTH_SECRET } = await secrets.getSecrets<{
|
|
188
|
-
|
|
189
|
-
])
|
|
193
|
+
const { BETTER_AUTH_SECRET } = await secrets.getSecrets<{
|
|
194
|
+
BETTER_AUTH_SECRET: string
|
|
195
|
+
}>(['BETTER_AUTH_SECRET'])
|
|
190
196
|
return betterAuth({
|
|
191
197
|
secret: BETTER_AUTH_SECRET,
|
|
192
198
|
database: kyselyAdapter(kysely, { type: 'postgres' }),
|
|
@@ -204,7 +210,7 @@ If you place `auth.ts` under `srcDirectories` it is inspected automatically. The
|
|
|
204
210
|
|
|
205
211
|
## Social Providers needing extra config
|
|
206
212
|
|
|
207
|
-
Some providers require non-secret config alongside the OAuth secret — the CLI emits a `
|
|
213
|
+
Some providers require non-secret config alongside the OAuth secret — the CLI emits a `defineVariable` for these:
|
|
208
214
|
|
|
209
215
|
- `microsoft` → `MICROSOFT_TENANT_ID` (or `"common"`)
|
|
210
216
|
- `cognito` → `COGNITO_DOMAIN`, `COGNITO_REGION`, `COGNITO_USER_POOL_ID`
|
|
@@ -221,7 +227,12 @@ export const auth = pikkuBetterAuth(async ({ secrets, variables }) => {
|
|
|
221
227
|
|
|
222
228
|
return betterAuth({
|
|
223
229
|
secret: BETTER_AUTH_SECRET,
|
|
224
|
-
database: memoryAdapter({
|
|
230
|
+
database: memoryAdapter({
|
|
231
|
+
user: [],
|
|
232
|
+
session: [],
|
|
233
|
+
account: [],
|
|
234
|
+
verification: [],
|
|
235
|
+
}),
|
|
225
236
|
socialProviders: {
|
|
226
237
|
microsoft: { ...MICROSOFT_OAUTH, tenantId: MICROSOFT_TENANT_ID },
|
|
227
238
|
},
|
|
@@ -258,13 +269,13 @@ For public endpoints that optionally vary by viewer, use `pikkuSessionlessFunc`
|
|
|
258
269
|
|
|
259
270
|
Better Auth serves everything under `basePath` (default `/api/auth`). Call these directly — the Pikku SDK does not wrap them.
|
|
260
271
|
|
|
261
|
-
| Action
|
|
262
|
-
|
|
263
|
-
| Sign up
|
|
264
|
-
| Log in
|
|
265
|
-
| Session
|
|
266
|
-
| Social sign-in | `POST /api/auth/sign-in/social` `{ provider, callbackURL }` | 200 `{ url, redirect }` (authorize URL)
|
|
267
|
-
| Sign out
|
|
272
|
+
| Action | Request | Result |
|
|
273
|
+
| -------------- | ----------------------------------------------------------- | ----------------------------------------------------------------------- |
|
|
274
|
+
| Sign up | `POST /api/auth/sign-up/email` `{ name, email, password }` | 200 + `better-auth.session_token` cookie |
|
|
275
|
+
| Log in | `POST /api/auth/sign-in/email` `{ email, password }` | 200 + cookie; wrong creds → 401 `{ code: "INVALID_EMAIL_OR_PASSWORD" }` |
|
|
276
|
+
| Session | `GET /api/auth/get-session` | `{ session, user }` or `null` |
|
|
277
|
+
| Social sign-in | `POST /api/auth/sign-in/social` `{ provider, callbackURL }` | 200 `{ url, redirect }` (authorize URL) |
|
|
278
|
+
| Sign out | `POST /api/auth/sign-out` | 200, clears cookie |
|
|
268
279
|
|
|
269
280
|
**`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
281
|
|
|
@@ -15,7 +15,7 @@ installGroups: [core]
|
|
|
15
15
|
|
|
16
16
|
Use this skill as an execution checklist, not reference material.
|
|
17
17
|
|
|
18
|
-
1. Discover before editing.
|
|
18
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
19
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
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
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.
|
|
@@ -17,7 +17,7 @@ installGroups: [core]
|
|
|
17
17
|
|
|
18
18
|
Use this skill as an execution checklist, not reference material.
|
|
19
19
|
|
|
20
|
-
1. Discover before editing.
|
|
20
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
21
21
|
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.
|
|
22
22
|
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
23
23
|
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.
|
|
@@ -221,6 +221,13 @@ const apiKey = services.variables.get('API_KEY')
|
|
|
221
221
|
|
|
222
222
|
`process.env` belongs in server bootstrap code (`start.ts`) only.
|
|
223
223
|
|
|
224
|
+
## Secrets
|
|
225
|
+
|
|
226
|
+
`secrets` is not part of a function's services. It is available only in
|
|
227
|
+
`pikkuServices`, `pikkuWireServices`, addon service factories and middleware —
|
|
228
|
+
read it there, give the value to a service, and have the function ask that
|
|
229
|
+
service. Reaching for it through a cast throws at runtime.
|
|
230
|
+
|
|
224
231
|
## Testing
|
|
225
232
|
|
|
226
233
|
Functions are easily testable because they're pure:
|
|
@@ -18,8 +18,8 @@ Authoritative mapping table plus side-by-side code examples showing how common b
|
|
|
18
18
|
| **Cron / Scheduled tasks** | `wireScheduler` | `pikku-cron` |
|
|
19
19
|
| **Module / Feature grouping** | Tags + wiring files | `pikku-concepts` |
|
|
20
20
|
| **Error handling** | Throw typed errors (`NotFoundError`, `ForbiddenError`) | `pikku-concepts` |
|
|
21
|
-
| **Type-safe API client** | `npx pikku all` generates clients
|
|
22
|
-
| **Secrets / Config** | `
|
|
21
|
+
| **Type-safe API client** | `npx pikku all` generates clients | `pikku-concepts` |
|
|
22
|
+
| **Secrets / Config** | `defineSecret`, `defineVariable`, `services.variables` | `pikku-config` |
|
|
23
23
|
|
|
24
24
|
## Route Handler / Controller → pikkuFunc
|
|
25
25
|
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
name: pikku-config
|
|
3
3
|
description: >-
|
|
4
4
|
Use when managing secrets, environment variables, config, or OAuth2 credentials in a Pikku app.
|
|
5
|
-
Covers
|
|
6
|
-
code uses
|
|
5
|
+
Covers defineSecret, defineVariable, defineCredential, and typed config access. TRIGGER when:
|
|
6
|
+
code uses defineSecret/defineVariable/defineCredential, user asks about env vars, secrets,
|
|
7
7
|
config, OAuth2, or "how do I access environment variables". DO NOT TRIGGER when: user asks about
|
|
8
8
|
API versioning/breaking changes (use pikku-versioning), service factories (use pikku-services),
|
|
9
9
|
or auth middleware (use pikku-security).
|
|
@@ -16,7 +16,7 @@ installGroups: [core]
|
|
|
16
16
|
|
|
17
17
|
Use this skill as an execution checklist, not reference material.
|
|
18
18
|
|
|
19
|
-
1. Discover before editing.
|
|
19
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
20
20
|
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.
|
|
21
21
|
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
22
22
|
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.
|
|
@@ -35,34 +35,53 @@ See `pikku-concepts` for the core mental model.
|
|
|
35
35
|
|
|
36
36
|
## Secrets & Variables
|
|
37
37
|
|
|
38
|
-
### `
|
|
38
|
+
### `defineSecret(config)`
|
|
39
39
|
|
|
40
40
|
Declare a secret with a Zod schema for type-safe access:
|
|
41
41
|
|
|
42
42
|
```typescript
|
|
43
|
-
|
|
43
|
+
defineSecret({
|
|
44
44
|
name: string, // Secret identifier
|
|
45
45
|
schema: ZodSchema, // Shape and validation
|
|
46
46
|
})
|
|
47
47
|
```
|
|
48
48
|
|
|
49
|
-
### `
|
|
49
|
+
### `defineVariable(config)`
|
|
50
50
|
|
|
51
51
|
Declare a variable (non-sensitive config) with a Zod schema:
|
|
52
52
|
|
|
53
53
|
```typescript
|
|
54
|
-
|
|
54
|
+
defineVariable({
|
|
55
55
|
name: string,
|
|
56
56
|
schema: ZodSchema,
|
|
57
57
|
})
|
|
58
58
|
```
|
|
59
59
|
|
|
60
|
-
### Accessing
|
|
60
|
+
### Accessing Secrets
|
|
61
|
+
|
|
62
|
+
`secrets` is **not available inside functions, AI agents, workflows, permissions
|
|
63
|
+
or any wire** — it is removed from their services type and throws at runtime if
|
|
64
|
+
reached through a cast. Read it where you wire the app and hand the value to a
|
|
65
|
+
service:
|
|
61
66
|
|
|
62
67
|
```typescript
|
|
63
|
-
//
|
|
64
|
-
const
|
|
68
|
+
// services.ts — allowed
|
|
69
|
+
const createSingletonServices = pikkuServices(async (config, { secrets }) => ({
|
|
70
|
+
stripe: new StripeService(await secrets.getSecret('STRIPE_CONFIG')),
|
|
71
|
+
}))
|
|
72
|
+
|
|
73
|
+
// functions/*.ts — ask the service, never the secret store
|
|
74
|
+
export const charge = pikkuFunc({
|
|
75
|
+
func: async ({ stripe }, data) => stripe.charge(data.amount),
|
|
76
|
+
})
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Allowed: `pikkuServices`, `pikkuWireServices`, addon service factories,
|
|
80
|
+
middleware. Everywhere else, the service you constructed is the interface.
|
|
81
|
+
|
|
82
|
+
### Accessing Variables in Functions
|
|
65
83
|
|
|
84
|
+
```typescript
|
|
66
85
|
// Variables — plain-text configuration
|
|
67
86
|
const flags = await services.variables.getVariableJSON('VARIABLE_NAME')
|
|
68
87
|
|
|
@@ -85,7 +104,7 @@ const createSingletonServices = pikkuServices(async (config) => ({
|
|
|
85
104
|
|
|
86
105
|
```typescript
|
|
87
106
|
// Declare secrets with typed schemas
|
|
88
|
-
|
|
107
|
+
defineSecret({
|
|
89
108
|
name: 'STRIPE_CONFIG',
|
|
90
109
|
schema: z.object({
|
|
91
110
|
apiKey: z.string().startsWith('sk_'),
|
|
@@ -93,13 +112,13 @@ wireSecret({
|
|
|
93
112
|
}),
|
|
94
113
|
})
|
|
95
114
|
|
|
96
|
-
// In your
|
|
115
|
+
// In your services factory — fully typed
|
|
97
116
|
const config = await secrets.getSecret('STRIPE_CONFIG')
|
|
98
117
|
// config.apiKey → string (autocompleted)
|
|
99
118
|
// config.webhookSecret → string (autocompleted)
|
|
100
119
|
|
|
101
120
|
// Declare variables
|
|
102
|
-
|
|
121
|
+
defineVariable({
|
|
103
122
|
name: 'FEATURE_FLAGS',
|
|
104
123
|
schema: z.object({
|
|
105
124
|
darkMode: z.boolean(),
|
|
@@ -113,33 +132,50 @@ const flags = await variables.getVariableJSON('FEATURE_FLAGS')
|
|
|
113
132
|
// flags.maxUploadMB → number
|
|
114
133
|
```
|
|
115
134
|
|
|
116
|
-
##
|
|
135
|
+
## Credentials
|
|
117
136
|
|
|
118
|
-
### `
|
|
137
|
+
### `defineCredential(config)`
|
|
119
138
|
|
|
120
139
|
```typescript
|
|
121
|
-
|
|
122
|
-
name: string,
|
|
123
|
-
displayName: string,
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
140
|
+
defineCredential({
|
|
141
|
+
name: string, // Credential identifier
|
|
142
|
+
displayName: string, // Human-readable name
|
|
143
|
+
type: 'wire' | 'singleton', // Per-user ('wire') or platform-level ('singleton')
|
|
144
|
+
schema: ZodSchema, // Shape of the stored credential
|
|
145
|
+
oauth2?: { // Omit entirely for a plain API key
|
|
146
|
+
appCredentialSecretId: string, // Secret holding { clientId, clientSecret }
|
|
147
|
+
tokenSecretId: string, // Secret for token storage (auto-refreshed)
|
|
148
|
+
authorizationUrl: string, // OAuth2 authorization endpoint
|
|
149
|
+
tokenUrl: string, // OAuth2 token endpoint
|
|
150
|
+
scopes: string[], // Required OAuth2 scopes
|
|
151
|
+
},
|
|
129
152
|
})
|
|
130
153
|
```
|
|
131
154
|
|
|
132
155
|
### Usage
|
|
133
156
|
|
|
134
157
|
```typescript
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
158
|
+
// Per-user API key — no oauth2 block
|
|
159
|
+
defineCredential({
|
|
160
|
+
name: 'stripe',
|
|
161
|
+
displayName: 'Stripe API Key',
|
|
162
|
+
type: 'wire',
|
|
163
|
+
schema: z.object({ apiKey: z.string() }),
|
|
164
|
+
})
|
|
165
|
+
|
|
166
|
+
// Platform-level OAuth (singleton)
|
|
167
|
+
defineCredential({
|
|
168
|
+
name: 'slack',
|
|
169
|
+
displayName: 'Slack',
|
|
170
|
+
type: 'singleton',
|
|
171
|
+
schema: z.object({ accessToken: z.string(), refreshToken: z.string() }),
|
|
172
|
+
oauth2: {
|
|
173
|
+
appCredentialSecretId: 'SLACK_OAUTH_APP',
|
|
174
|
+
tokenSecretId: 'SLACK_OAUTH_TOKENS',
|
|
175
|
+
authorizationUrl: 'https://slack.com/oauth/v2/authorize',
|
|
176
|
+
tokenUrl: 'https://slack.com/api/oauth.v2.access',
|
|
177
|
+
scopes: ['chat:write', 'channels:read'],
|
|
178
|
+
},
|
|
143
179
|
})
|
|
144
180
|
|
|
145
181
|
// In your function — tokens refresh automatically
|
|
@@ -171,7 +207,7 @@ const apiKey = services.variables.get('API_KEY')
|
|
|
171
207
|
|
|
172
208
|
```typescript
|
|
173
209
|
// schemas/config.ts
|
|
174
|
-
|
|
210
|
+
defineSecret({
|
|
175
211
|
name: 'DATABASE_CONFIG',
|
|
176
212
|
schema: z.object({
|
|
177
213
|
connectionString: z.string().url(),
|
|
@@ -179,7 +215,7 @@ wireSecret({
|
|
|
179
215
|
}),
|
|
180
216
|
})
|
|
181
217
|
|
|
182
|
-
|
|
218
|
+
defineVariable({
|
|
183
219
|
name: 'APP_CONFIG',
|
|
184
220
|
schema: z.object({
|
|
185
221
|
appName: z.string(),
|
|
@@ -188,20 +224,24 @@ wireVariable({
|
|
|
188
224
|
}),
|
|
189
225
|
})
|
|
190
226
|
|
|
191
|
-
|
|
227
|
+
defineCredential({
|
|
192
228
|
name: 'githubOAuth',
|
|
193
229
|
displayName: 'GitHub OAuth',
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
230
|
+
type: 'wire',
|
|
231
|
+
schema: z.object({ accessToken: z.string(), refreshToken: z.string() }),
|
|
232
|
+
oauth2: {
|
|
233
|
+
appCredentialSecretId: 'GITHUB_OAUTH_APP',
|
|
234
|
+
tokenSecretId: 'GITHUB_OAUTH_TOKENS',
|
|
235
|
+
authorizationUrl: 'https://github.com/login/oauth/authorize',
|
|
236
|
+
tokenUrl: 'https://github.com/login/oauth/access_token',
|
|
237
|
+
scopes: ['read:user', 'repo'],
|
|
238
|
+
},
|
|
199
239
|
})
|
|
200
240
|
|
|
201
241
|
// functions/admin.functions.ts
|
|
202
242
|
export const getAppStatus = pikkuSessionlessFunc({
|
|
203
243
|
title: 'Get App Status',
|
|
204
|
-
func: async ({ variables
|
|
244
|
+
func: async ({ variables }) => {
|
|
205
245
|
const appConfig = await variables.getVariableJSON('APP_CONFIG')
|
|
206
246
|
return {
|
|
207
247
|
appName: appConfig.appName,
|
|
@@ -14,7 +14,7 @@ description: >-
|
|
|
14
14
|
|
|
15
15
|
Use this skill as an execution checklist, not reference material.
|
|
16
16
|
|
|
17
|
-
1. Discover before editing.
|
|
17
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
18
18
|
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.
|
|
19
19
|
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
20
20
|
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.
|
|
@@ -13,7 +13,7 @@ description: >-
|
|
|
13
13
|
|
|
14
14
|
Use this skill as an execution checklist, not reference material.
|
|
15
15
|
|
|
16
|
-
1. Discover before editing.
|
|
16
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
17
17
|
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.
|
|
18
18
|
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
19
19
|
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.
|
|
@@ -14,7 +14,7 @@ installGroups: [fabric]
|
|
|
14
14
|
|
|
15
15
|
Use this skill as an execution checklist, not reference material.
|
|
16
16
|
|
|
17
|
-
1. Discover before editing.
|
|
17
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
18
18
|
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.
|
|
19
19
|
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
20
20
|
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.
|
|
@@ -14,7 +14,7 @@ description: >-
|
|
|
14
14
|
|
|
15
15
|
Use this skill as an execution checklist, not reference material.
|
|
16
16
|
|
|
17
|
-
1. Discover before editing.
|
|
17
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
18
18
|
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.
|
|
19
19
|
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
20
20
|
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.
|
|
@@ -14,7 +14,7 @@ description: >-
|
|
|
14
14
|
|
|
15
15
|
Use this skill as an execution checklist, not reference material.
|
|
16
16
|
|
|
17
|
-
1. Discover before editing.
|
|
17
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
18
18
|
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.
|
|
19
19
|
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
20
20
|
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.
|
|
@@ -14,7 +14,7 @@ description: >-
|
|
|
14
14
|
|
|
15
15
|
Use this skill as an execution checklist, not reference material.
|
|
16
16
|
|
|
17
|
-
1. Discover before editing.
|
|
17
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
18
18
|
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.
|
|
19
19
|
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
20
20
|
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.
|
|
@@ -13,7 +13,7 @@ description: >-
|
|
|
13
13
|
|
|
14
14
|
Use this skill as an execution checklist, not reference material.
|
|
15
15
|
|
|
16
|
-
1. Discover before editing.
|
|
16
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
17
17
|
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.
|
|
18
18
|
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
19
19
|
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.
|
|
@@ -14,7 +14,7 @@ description: >-
|
|
|
14
14
|
|
|
15
15
|
Use this skill as an execution checklist, not reference material.
|
|
16
16
|
|
|
17
|
-
1. Discover before editing.
|
|
17
|
+
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
18
18
|
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.
|
|
19
19
|
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
20
20
|
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.
|
|
@@ -15,7 +15,7 @@ Use this skill as an execution checklist, not reference material.
|
|
|
15
15
|
pikku fabric validate --json
|
|
16
16
|
```
|
|
17
17
|
This prints every missing file, misconfigured field, and dependency gap with a `fixHint`. Address all `error` findings before proceeding — they block deploy. Resolve `warn` findings before testing — they cause runtime failures. `info` findings are best-practice gaps that are safe to defer.
|
|
18
|
-
2. Discover before editing.
|
|
18
|
+
2. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
19
19
|
3. 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
20
|
4. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
21
21
|
5. Validate with the narrowest relevant command first, then run `pikku-verify` or `pikku all` when functions, wirings, schemas, or generated clients may have changed.
|
|
@@ -31,7 +31,7 @@ Always run project discovery first:
|
|
|
31
31
|
yarn pikku meta context --json
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
Call the `pikku-meta` tool before grepping or editing a Fabric app.
|
|
35
35
|
|
|
36
36
|
- Use `section: "context"` for the project map: functions, wires, workflows, capabilities, and source files.
|
|
37
37
|
- Use `section: "clients"` before frontend/RPC work.
|
|
@@ -40,7 +40,7 @@ In OpenCode, call the `pikku-meta` tool before grepping or editing a Fabric app.
|
|
|
40
40
|
|
|
41
41
|
Do not load every schema body by default; that wastes context and usually makes the model worse.
|
|
42
42
|
|
|
43
|
-
For database work
|
|
43
|
+
For database work:
|
|
44
44
|
|
|
45
45
|
- Use `pikku-db` for the actual attached Fabric database state: tables, columns, foreign keys, and applied migrations.
|
|
46
46
|
- Use `pikku-meta` `section: "schemas"` for code-level JSON Schema contracts, not database introspection.
|
|
@@ -183,7 +183,7 @@ Links the repo to a Fabric project and declares its frontends:
|
|
|
183
183
|
```
|
|
184
184
|
|
|
185
185
|
- `projectId`: written by `pikku fabric init` / `link`. Templates ship the
|
|
186
|
-
`__PROJECT_ID__` placeholder — that is
|
|
186
|
+
`__PROJECT_ID__` placeholder — that is _not_ a link, and the CLI treats it as
|
|
187
187
|
unlinked.
|
|
188
188
|
- `production.domain`: optional custom domain. Production always maps to `main`;
|
|
189
189
|
without a domain it lives on the platform `*.pikkufabric.app` hostnames.
|
|
@@ -290,7 +290,7 @@ The output card shows whether any breaking changes were detected.
|
|
|
290
290
|
|
|
291
291
|
These apply in every Fabric app:
|
|
292
292
|
|
|
293
|
-
- **No `process.env`** — use `variables.get('NAME')` and `secrets.getSecret('NAME')`. Declare with `
|
|
293
|
+
- **No `process.env`** — use `variables.get('NAME')` and `secrets.getSecret('NAME')`. Declare with `defineVariable` / `defineSecret`.
|
|
294
294
|
- **No `as any`** — fix types properly.
|
|
295
295
|
- **No generic `Error`** — throw `NotFoundError`, `ConflictError`, `BadRequestError`, `UnauthorizedError` from `@pikku/core/errors`.
|
|
296
296
|
- **No auth checks in function bodies** — use `permissions:` field on the function config with a `pikkuPermission` factory.
|
|
@@ -311,7 +311,7 @@ Fix every `error` and `warn` in the output before continuing. Then:
|
|
|
311
311
|
1. **Replace the database layer**: swap PostgreSQL/MySQL queries for Kysely + libSQL. Convert schema to SQLite-compatible SQL migrations in `db/sqlite/`.
|
|
312
312
|
2. **Replace route handlers with pikkuFuncs**: extract business logic into `pikkuFunc`/`pikkuSessionlessFunc`, add `wireHTTP` or `expose: true` for transport.
|
|
313
313
|
3. **Replace DI/IoC with pikkuServices**: move service construction to `createSingletonServices` in `services.ts`.
|
|
314
|
-
4. **Replace `process.env` calls
|
|
314
|
+
4. **Replace `process.env` calls**: plain config becomes `defineVariable` + `variables.get()`, anything sensitive becomes `defineSecret` + `secrets.getSecret()`.
|
|
315
315
|
5. **Add `pikku.config.json`** at project root with `srcDirectories`, `outDir`, and `clientFiles`.
|
|
316
316
|
6. **Add `fabric.config.json`** at project root with `projectId`, `production.branch`, and `frontends`.
|
|
317
317
|
7. **Run `pikku all`** — verify codegen succeeds and there are no type errors.
|