@pikku/skills 0.12.22 → 0.12.26
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/CHANGELOG.md +134 -0
- package/dist/skills.gen.js +1 -1
- package/package.json +1 -1
- package/skills/pikku-a11y/SKILL.md +59 -0
- package/skills/pikku-addon/SKILL.md +2 -2
- package/skills/pikku-agent/SKILL.md +67 -316
- package/skills/pikku-agent/references/agents.md +299 -0
- package/skills/{pikku-ai-vercel/SKILL.md → pikku-agent/references/runner-vercel.md} +2 -24
- package/skills/{pikku-ai-voice/SKILL.md → pikku-agent/references/voice.md} +1 -22
- package/skills/pikku-architect/SKILL.md +265 -0
- package/skills/pikku-auth/SKILL.md +89 -0
- package/skills/{pikku-better-auth/SKILL.md → pikku-auth/references/better-auth.md} +126 -34
- package/skills/{pikku-jose/SKILL.md → pikku-auth/references/jose.md} +1 -23
- package/skills/{pikku-machine-auth/SKILL.md → pikku-auth/references/machine-auth.md} +0 -23
- package/skills/pikku-auth/references/permissions.md +261 -0
- package/skills/{pikku-security/SKILL.md → pikku-auth/references/sessions.md} +0 -20
- package/skills/pikku-build/SKILL.md +88 -0
- package/skills/{pikku-build-app/SKILL.md → pikku-build/references/app.md} +76 -24
- package/skills/{pikku-feature/SKILL.md → pikku-build/references/feature.md} +1 -8
- package/skills/{pikku-build-app → pikku-build}/references/multi-app.md +56 -1
- package/skills/{pikku-build-platform/SKILL.md → pikku-build/references/platform.md} +22 -37
- package/skills/{pikku-template-clone/SKILL.md → pikku-build/references/post-clone.md} +0 -6
- package/skills/{pikku-build-quick/SKILL.md → pikku-build/references/quick.md} +4 -20
- package/skills/{pikku-build-app → pikku-build}/references/ship.md +9 -3
- package/skills/pikku-concepts/SKILL.md +72 -7
- package/skills/pikku-concepts/references/concept-mapping.md +8 -8
- package/skills/pikku-deploy/SKILL.md +158 -0
- package/skills/{pikku-deploy-azure/SKILL.md → pikku-deploy/references/azure.md} +18 -50
- package/skills/pikku-deploy/references/cloudflare.md +104 -0
- package/skills/pikku-deploy/references/express.md +92 -0
- package/skills/{pikku-deploy-fastify/SKILL.md → pikku-deploy/references/fastify.md} +8 -32
- package/skills/{pikku-deploy-lambda/SKILL.md → pikku-deploy/references/lambda.md} +6 -27
- package/skills/{pikku-deploy-nextjs/SKILL.md → pikku-deploy/references/nextjs.md} +9 -33
- package/skills/pikku-deploy/references/uws.md +72 -0
- package/skills/pikku-deploy/references/ws.md +75 -0
- package/skills/pikku-emails/SKILL.md +3 -2
- package/skills/pikku-fabric/SKILL.md +47 -20
- package/skills/{pikku-fabric-debug/SKILL.md → pikku-fabric/references/debugging.md} +0 -6
- package/skills/pikku-i18n/SKILL.md +62 -207
- package/skills/{pikku-paraglide/SKILL.md → pikku-i18n/references/enum-labels.md} +0 -6
- package/skills/pikku-i18n/references/messages.md +218 -0
- package/skills/{pikku-rtl/SKILL.md → pikku-i18n/references/rtl.md} +3 -9
- package/skills/pikku-knowledge/SKILL.md +15 -0
- package/skills/pikku-kysely/SKILL.md +13 -13
- package/skills/pikku-list-query/SKILL.md +163 -0
- package/skills/pikku-meta/SKILL.md +58 -130
- package/skills/{pikku-deps/SKILL.md → pikku-meta/references/audit.md} +1 -17
- package/skills/pikku-meta/references/meta.md +114 -0
- package/skills/{pikku-versioning/SKILL.md → pikku-meta/references/versioning.md} +0 -26
- package/skills/pikku-middleware/SKILL.md +5 -5
- package/skills/pikku-n8n-import/SKILL.md +0 -1
- package/skills/pikku-permissions/SKILL.md +75 -229
- package/skills/pikku-react/SKILL.md +50 -298
- package/skills/pikku-react/references/client.md +313 -0
- package/skills/{pikku-react-query/SKILL.md → pikku-react/references/react-query.md} +2 -22
- package/skills/{pikku-workflows-client/SKILL.md → pikku-react/references/workflows.md} +1 -22
- package/skills/pikku-realtime/SKILL.md +110 -251
- package/skills/pikku-scenario/SKILL.md +60 -45
- package/skills/pikku-scenario/references/persona-run.md +148 -0
- package/skills/pikku-seo/SKILL.md +133 -0
- package/skills/pikku-service-backends/SKILL.md +154 -0
- package/skills/pikku-service-backends/references/aws.md +106 -0
- package/skills/pikku-service-backends/references/backblaze.md +57 -0
- package/skills/pikku-service-backends/references/mongodb.md +90 -0
- package/skills/pikku-service-backends/references/redis.md +75 -0
- package/skills/pikku-service-backends/references/schema.md +63 -0
- package/skills/pikku-services/SKILL.md +68 -291
- package/skills/{pikku-audit/SKILL.md → pikku-services/references/audit.md} +0 -22
- package/skills/{pikku-config/SKILL.md → pikku-services/references/config.md} +1 -25
- package/skills/{pikku-pino/SKILL.md → pikku-services/references/pino.md} +0 -20
- package/skills/pikku-services/references/services.md +272 -0
- package/skills/pikku-software-archaeology/README.md +5 -1
- package/skills/pikku-software-archaeology/SKILL.md +16 -2
- package/skills/{pikku-product-second-opinion/example/sample-report.md → pikku-software-archaeology/example/second-opinion-sample-report.md} +1 -1
- package/skills/pikku-software-archaeology/references/blueprint.schema.json +1 -1
- package/skills/pikku-software-archaeology/references/pikku-mapping.md +3 -3
- package/skills/{pikku-product-second-opinion/SKILL.md → pikku-software-archaeology/references/second-opinion.md} +4 -9
- package/skills/pikku-webhook/SKILL.md +224 -0
- package/skills/pikku-wiring/SKILL.md +180 -0
- package/skills/{pikku-websocket/SKILL.md → pikku-wiring/references/channel.md} +2 -35
- package/skills/{pikku-cli/SKILL.md → pikku-wiring/references/cli.md} +1 -33
- package/skills/{pikku-gateway-slack/SKILL.md → pikku-wiring/references/gateway-slack.md} +0 -23
- package/skills/{pikku-http/SKILL.md → pikku-wiring/references/http.md} +3 -39
- package/skills/{pikku-mcp/SKILL.md → pikku-wiring/references/mcp.md} +0 -33
- package/skills/{pikku-queue/SKILL.md → pikku-wiring/references/queue.md} +1 -33
- package/skills/pikku-wiring/references/realtime.md +265 -0
- package/skills/{pikku-rpc/SKILL.md → pikku-wiring/references/rpc.md} +0 -32
- package/skills/{pikku-schedule/SKILL.md → pikku-wiring/references/scheduler.md} +1 -35
- package/skills/{pikku-trigger/SKILL.md → pikku-wiring/references/trigger.md} +0 -43
- package/skills/pikku-workflow/SKILL.md +39 -2
- package/skills/pikku-aws/SKILL.md +0 -161
- package/skills/pikku-backblaze/SKILL.md +0 -104
- package/skills/pikku-deploy-cloudflare/SKILL.md +0 -123
- package/skills/pikku-deploy-express/SKILL.md +0 -122
- package/skills/pikku-deploy-uws/SKILL.md +0 -144
- package/skills/pikku-mongodb/SKILL.md +0 -113
- package/skills/pikku-product-second-opinion/README.md +0 -43
- package/skills/pikku-redis/SKILL.md +0 -99
- package/skills/pikku-schema-ajv/SKILL.md +0 -83
- package/skills/pikku-schema-cfworker/SKILL.md +0 -82
- package/skills/pikku-ws/SKILL.md +0 -87
- /package/skills/{pikku-build-app → pikku-build}/references/theming.md +0 -0
- /package/skills/{pikku-product-second-opinion/references/report-template.md → pikku-software-archaeology/references/second-opinion-report-template.md} +0 -0
- /package/skills/{pikku-cli/references/complete-example.md → pikku-wiring/references/cli-complete-example.md} +0 -0
- /package/skills/{pikku-http → pikku-wiring}/references/http-options.md +0 -0
- /package/skills/{pikku-realtime/references/other-routes.md → pikku-wiring/references/realtime-other-routes.md} +0 -0
|
@@ -1,31 +1,11 @@
|
|
|
1
|
-
|
|
2
|
-
name: pikku-deploy-fastify
|
|
3
|
-
description: >-
|
|
4
|
-
Use when deploying a Pikku app with Fastify. Covers PikkuFastifyServer standalone and
|
|
5
|
-
pikkuFastifyPlugin for existing Fastify apps. TRIGGER when: code imports @pikku/fastify or
|
|
6
|
-
@pikku/fastify-plugin, user mentions Fastify deployment, or start.ts creates a
|
|
7
|
-
PikkuFastifyServer. DO NOT TRIGGER when: just defining functions/wirings without
|
|
8
|
-
Fastify-specific code.
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# Pikku Fastify Deployment
|
|
12
|
-
|
|
13
|
-
## Agent Operating Procedure
|
|
14
|
-
|
|
15
|
-
Use this skill as an execution checklist, not reference material.
|
|
16
|
-
|
|
17
|
-
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
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
|
-
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
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.
|
|
21
|
-
5. If validation fails, fix the source cause and rerun validation. Do not paper over generated errors by editing generated files.
|
|
22
|
-
|
|
23
|
-
## Standalone Server
|
|
1
|
+
# Fastify
|
|
24
2
|
|
|
25
3
|
```bash
|
|
26
4
|
yarn add @pikku/fastify
|
|
27
5
|
```
|
|
28
6
|
|
|
7
|
+
## Standalone server
|
|
8
|
+
|
|
29
9
|
```typescript
|
|
30
10
|
import { PikkuFastifyServer } from '@pikku/fastify'
|
|
31
11
|
import './.pikku/pikku-bootstrap.gen.js'
|
|
@@ -43,16 +23,12 @@ await appServer.init()
|
|
|
43
23
|
await appServer.start()
|
|
44
24
|
```
|
|
45
25
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
**Config extends CoreConfig with:** `port`, `hostname`, `healthCheckPath?`
|
|
49
|
-
|
|
50
|
-
**Methods:** `init(httpOptions?: RunHTTPWiringOptions)`, `start()`, `stop()`, `enableExitOnSigInt()`
|
|
51
|
-
|
|
52
|
-
**Property:** `app: FastifyInstance` — Direct access to Fastify instance.
|
|
26
|
+
The config extends `CoreConfig` with `port`, `hostname` and an optional
|
|
27
|
+
`healthCheckPath`. `app: FastifyInstance` is exposed for direct access.
|
|
53
28
|
|
|
54
|
-
`enableCors` exists on the class but **throws `Method not implemented.`** —
|
|
55
|
-
the Express server. Register `@fastify/cors` on `app` yourself before
|
|
29
|
+
`enableCors` exists on the class but **throws `Method not implemented.`** —
|
|
30
|
+
unlike the Express server. Register `@fastify/cors` on `app` yourself before
|
|
31
|
+
`init()`.
|
|
56
32
|
|
|
57
33
|
Unlike the Express server, the health check is registered by `init()`, not the
|
|
58
34
|
constructor, so nothing answers before `init` runs. `init` also passes
|
|
@@ -1,30 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
name: pikku-deploy-lambda
|
|
3
|
-
description: >-
|
|
4
|
-
Use when deploying a Pikku app to AWS Lambda. Covers HTTP handlers, scheduled tasks, SQS queue
|
|
5
|
-
workers, WebSocket via API Gateway, and cold start caching. TRIGGER when: code imports
|
|
6
|
-
@pikku/lambda, user mentions Lambda/serverless/AWS deployment, or handler files export
|
|
7
|
-
Lambda-typed functions. DO NOT TRIGGER when: just defining functions/wirings without
|
|
8
|
-
Lambda-specific code.
|
|
9
|
-
---
|
|
10
|
-
|
|
11
|
-
# Pikku AWS Lambda Deployment
|
|
12
|
-
|
|
13
|
-
## Agent Operating Procedure
|
|
14
|
-
|
|
15
|
-
Use this skill as an execution checklist, not reference material.
|
|
16
|
-
|
|
17
|
-
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
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
|
-
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
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.
|
|
21
|
-
5. If validation fails, fix the source cause and rerun validation. Do not paper over generated errors by editing generated files.
|
|
1
|
+
# AWS Lambda
|
|
22
2
|
|
|
23
3
|
```bash
|
|
24
4
|
yarn add @pikku/lambda
|
|
25
5
|
```
|
|
26
6
|
|
|
27
|
-
## Cold
|
|
7
|
+
## Cold start pattern
|
|
28
8
|
|
|
29
9
|
Cache singleton services across Lambda invocations:
|
|
30
10
|
|
|
@@ -53,7 +33,7 @@ named exports (`handler`, `queue`, `scheduled`, or `connect`/`disconnect`/
|
|
|
53
33
|
`default`) that `serverless.yml` references. Hand-written handlers are for cases
|
|
54
34
|
the codegen does not cover.
|
|
55
35
|
|
|
56
|
-
## HTTP
|
|
36
|
+
## HTTP handler
|
|
57
37
|
|
|
58
38
|
Pick the entry point that matches the API Gateway payload version — they take
|
|
59
39
|
different event types and are not interchangeable:
|
|
@@ -91,7 +71,7 @@ carried.
|
|
|
91
71
|
Neither takes `RunHTTPWiringOptions` — there is no `maxBodySize` or
|
|
92
72
|
`respondWith404` knob here; API Gateway's own payload limit is the bound.
|
|
93
73
|
|
|
94
|
-
## Scheduled
|
|
74
|
+
## Scheduled tasks
|
|
95
75
|
|
|
96
76
|
```typescript
|
|
97
77
|
import type { ScheduledHandler } from 'aws-lambda'
|
|
@@ -113,7 +93,7 @@ Reach for `runScheduledTask({ name })` from `@pikku/core/scheduler` directly
|
|
|
113
93
|
only when one Lambda genuinely bundles several tasks that must fire on separate
|
|
114
94
|
schedules.
|
|
115
95
|
|
|
116
|
-
## SQS
|
|
96
|
+
## SQS queue worker
|
|
117
97
|
|
|
118
98
|
```typescript
|
|
119
99
|
import type { SQSHandler } from 'aws-lambda'
|
|
@@ -181,8 +161,7 @@ is a separate invocation, so nothing survives in memory between `$connect` and
|
|
|
181
161
|
`LambdaEventHubService` handles cross-connection messaging and takes
|
|
182
162
|
`(logger, event, channelStore, eventHubStore)` — the `event` is needed to derive
|
|
183
163
|
the API Gateway Management endpoint, so it is constructed per invocation, not
|
|
184
|
-
once at cold start. It also needs an `EventHubStore` alongside the channel
|
|
185
|
-
store.
|
|
164
|
+
once at cold start. It also needs an `EventHubStore` alongside the channel store.
|
|
186
165
|
|
|
187
166
|
Two behaviours to design around: **binary payloads throw** (`Binary data is not
|
|
188
167
|
supported on serverless lambdas`), and any `PostToConnection` failure removes
|
|
@@ -1,29 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
name: pikku-deploy-nextjs
|
|
3
|
-
description: >-
|
|
4
|
-
Use when deploying a Pikku app with Next.js. Covers API route handlers, server-side data
|
|
5
|
-
fetching, and RPC calls from Server Components. TRIGGER when: code imports @pikku/next, user
|
|
6
|
-
mentions Next.js integration, or app/api route files use pikkuAPIRequest. DO NOT TRIGGER when:
|
|
7
|
-
just defining functions/wirings without Next.js-specific code.
|
|
8
|
-
---
|
|
9
|
-
|
|
10
|
-
# Pikku Next.js Deployment
|
|
11
|
-
|
|
12
|
-
## Agent Operating Procedure
|
|
13
|
-
|
|
14
|
-
Use this skill as an execution checklist, not reference material.
|
|
15
|
-
|
|
16
|
-
1. Discover before editing. Run the relevant `pikku meta ... --json` command and inspect only the focused output you need.
|
|
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
|
-
3. Make the smallest source change that satisfies the task. Keep generated files generated, and avoid hand-editing SDKs, schema output, or typegen.
|
|
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.
|
|
20
|
-
5. If validation fails, fix the source cause and rerun validation. Do not paper over generated errors by editing generated files.
|
|
1
|
+
# Next.js
|
|
21
2
|
|
|
22
3
|
```bash
|
|
23
4
|
yarn add @pikku/next
|
|
24
5
|
```
|
|
25
6
|
|
|
26
|
-
## API
|
|
7
|
+
## API route handler
|
|
27
8
|
|
|
28
9
|
The CLI generates a typed wrapper. Use it in a catch-all route:
|
|
29
10
|
|
|
@@ -49,7 +30,7 @@ choose. It also passes no `RunHTTPWiringOptions`: to set `maxBodySize` or
|
|
|
49
30
|
`respondWith404` you need your own handler over `new PikkuNextJS(...)` calling
|
|
50
31
|
`apiRequest(req, options)`.
|
|
51
32
|
|
|
52
|
-
## Server-
|
|
33
|
+
## Server-side data fetching
|
|
53
34
|
|
|
54
35
|
Use the generated `pikku()` helper in Server Components or Server Actions:
|
|
55
36
|
|
|
@@ -69,12 +50,9 @@ const config = await staticGet('/config')
|
|
|
69
50
|
const result = await rpc('calculateTax', { amount: 100, region: 'US' })
|
|
70
51
|
```
|
|
71
52
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
so they force the component dynamic
|
|
76
|
-
- `staticGet`, `staticPost`, `staticRPC` — no request context, safe for
|
|
77
|
-
precompile/ISR
|
|
53
|
+
`get`, `post`, `patch`, `del` and `rpc` read `next/headers` cookies and headers,
|
|
54
|
+
so they force the component dynamic. `staticGet`, `staticPost` and `staticRPC`
|
|
55
|
+
have no request context and are safe for precompile/ISR.
|
|
78
56
|
|
|
79
57
|
The static variants pass `skipUserSession: true`, so a wiring that expects a
|
|
80
58
|
session sees none. That is the real difference — not just where they can run.
|
|
@@ -85,7 +63,7 @@ Both paths run with `bubbleErrors: true`, so a failing wiring **throws** in your
|
|
|
85
63
|
Server Component rather than resolving to an error status. Wrap the call, or let
|
|
86
64
|
the Next.js error boundary take it.
|
|
87
65
|
|
|
88
|
-
## How
|
|
66
|
+
## How it works
|
|
89
67
|
|
|
90
68
|
`PikkuNextJS` lazy-initializes on first request:
|
|
91
69
|
|
|
@@ -95,8 +73,6 @@ import { PikkuNextJS } from '@pikku/next'
|
|
|
95
73
|
const pikku = new PikkuNextJS(createConfig, createSingletonServices)
|
|
96
74
|
```
|
|
97
75
|
|
|
98
|
-
**Constructor:** `new PikkuNextJS(createConfig | undefined, createSingletonServices)`
|
|
99
|
-
|
|
100
76
|
Both arguments are positional and `createConfig` is only optional in the sense
|
|
101
77
|
that passing `undefined` substitutes an empty config —
|
|
102
78
|
`createSingletonServices` is required.
|
|
@@ -113,8 +89,8 @@ route definitions.
|
|
|
113
89
|
- **`PikkuNextJSWorkerRPC({ fetcher })`** — same surface as `PikkuNextJS`, but
|
|
114
90
|
every call is dispatched through a `Fetcher` (a Cloudflare service binding, a
|
|
115
91
|
local HTTP client, a fabric dispatcher) instead of loading function code
|
|
116
|
-
in-process. Use it to keep functions out of the SSR bundle. A non-2xx
|
|
117
|
-
|
|
92
|
+
in-process. Use it to keep functions out of the SSR bundle. A non-2xx response
|
|
93
|
+
throws with the status and body text.
|
|
118
94
|
- **`toNextJsAuthHandler(auth)`** — wraps a better-auth instance or handler
|
|
119
95
|
function for an auth route. The three-argument form
|
|
120
96
|
`(pikkuAuthFactory, createConfig, createSingletonServices)` resolves a Pikku
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# uWebSockets.js
|
|
2
|
+
|
|
3
|
+
Highest-throughput option among Pikku's runtimes. Handles both HTTP and
|
|
4
|
+
WebSocket automatically.
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
yarn add @pikku/uws
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
```typescript
|
|
11
|
+
import { PikkuUWSServer } from '@pikku/uws'
|
|
12
|
+
import './.pikku/pikku-bootstrap.gen.js'
|
|
13
|
+
import { createConfig, createSingletonServices } from './services.js'
|
|
14
|
+
|
|
15
|
+
const config = await createConfig()
|
|
16
|
+
const singletonServices = await createSingletonServices(config)
|
|
17
|
+
|
|
18
|
+
const appServer = new PikkuUWSServer(
|
|
19
|
+
{ ...config, hostname: 'localhost', port: 4002 },
|
|
20
|
+
singletonServices.logger
|
|
21
|
+
)
|
|
22
|
+
appServer.enableExitOnSigInt()
|
|
23
|
+
await appServer.init()
|
|
24
|
+
await appServer.start()
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
The config extends `CoreConfig` with `port`, `hostname` and an optional
|
|
28
|
+
`healthCheckPath`. `app: uWS.App` is exposed for direct access.
|
|
29
|
+
|
|
30
|
+
## What the server does and does not give you
|
|
31
|
+
|
|
32
|
+
`init()` registers three things in order: the health check (`healthCheckPath`,
|
|
33
|
+
default `/health-check`), a catch-all `app.any('/*')` HTTP handler, and a
|
|
34
|
+
catch-all `app.ws('/*')` websocket handler. Nothing is registered by the
|
|
35
|
+
constructor, so nothing answers before `init` runs.
|
|
36
|
+
|
|
37
|
+
**There is no `enableCors`, no static assets and no `content` support** — unlike
|
|
38
|
+
the Express server. The class is explicitly a prototyping convenience; for
|
|
39
|
+
anything that needs extra handlers, use `@pikku/uws-handler` directly and treat
|
|
40
|
+
`pikku-uws-server.ts` as the template (that is what its own JSDoc says).
|
|
41
|
+
|
|
42
|
+
`httpOptions` reaches the HTTP handler only. The websocket handler is
|
|
43
|
+
constructed with a fixed `{ logger, logRoutes: true }`, so per-request options
|
|
44
|
+
do not apply to the upgrade path. `loadSchemas` is also never passed by the
|
|
45
|
+
server, so schemas compile lazily on first use rather than at startup — pass
|
|
46
|
+
`loadSchemas: true` in `httpOptions` if you want the startup cost paid up front.
|
|
47
|
+
|
|
48
|
+
`stop()` closes the listen socket and then waits a fixed 2 seconds for
|
|
49
|
+
connections to drain. Called before `start()`, it throws a bare **string**, not
|
|
50
|
+
an `Error`, so `catch (e) { e.message }` reads `undefined`.
|
|
51
|
+
|
|
52
|
+
## Body limits
|
|
53
|
+
|
|
54
|
+
uWS hands over raw chunks with no limit of its own, so the handler counts the
|
|
55
|
+
bytes itself. A request over `maxBodySize` (default `DEFAULT_MAX_BODY_SIZE`) is
|
|
56
|
+
answered `413` with a `PayloadTooLargeError` body, and the chunks are dropped
|
|
57
|
+
rather than concatenated — an oversized request never accumulates in memory. A
|
|
58
|
+
`content-length` header that already exceeds the limit short-circuits before any
|
|
59
|
+
data arrives.
|
|
60
|
+
|
|
61
|
+
## Handlers directly (own uWS app)
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { pikkuHTTPHandler, pikkuWebsocketHandler } from '@pikku/uws-handler'
|
|
65
|
+
|
|
66
|
+
app.any('/*', pikkuHTTPHandler({ logger, logRoutes: true, loadSchemas: true }))
|
|
67
|
+
app.ws('/*', pikkuWebsocketHandler({ logger, logRoutes: true }))
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Both take `{ logger, logRoutes?, loadSchemas? } & RunHTTPWiringOptions`.
|
|
71
|
+
|
|
72
|
+
For a WebSocket-only server on the `ws` library instead, see `ws.md`.
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
# ws (WebSocket only)
|
|
2
|
+
|
|
3
|
+
`@pikku/ws` connects Pikku's channel system to a Node.js WebSocket server built
|
|
4
|
+
on the [ws](https://github.com/websockets/ws) library. Use it for a
|
|
5
|
+
WebSocket-only server; for HTTP and WebSocket on one port see `uws.md`, and when
|
|
6
|
+
the WebSocket server shares a port with an existing HTTP app see `express.md` or
|
|
7
|
+
`fastify.md`.
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
yarn add @pikku/ws ws
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
The package exports one function, `pikkuWebsocketHandler` — there is no server
|
|
14
|
+
class. You own the `http.Server` and the `WebSocketServer`; the handler attaches
|
|
15
|
+
the upgrade and message plumbing to them.
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { DEFAULT_WS_MAX_PAYLOAD, pikkuWebsocketHandler } from '@pikku/ws'
|
|
19
|
+
import { stopSingletonServices } from '@pikku/core'
|
|
20
|
+
import { Server } from 'http'
|
|
21
|
+
import { WebSocketServer } from 'ws'
|
|
22
|
+
|
|
23
|
+
import './.pikku/pikku-bootstrap.gen.js'
|
|
24
|
+
import { createConfig, createSingletonServices } from './services.js'
|
|
25
|
+
|
|
26
|
+
const config = await createConfig()
|
|
27
|
+
const singletonServices = await createSingletonServices(config)
|
|
28
|
+
|
|
29
|
+
const server = new Server()
|
|
30
|
+
const wss = new WebSocketServer({
|
|
31
|
+
noServer: true,
|
|
32
|
+
maxPayload: DEFAULT_WS_MAX_PAYLOAD,
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
pikkuWebsocketHandler({
|
|
36
|
+
server,
|
|
37
|
+
wss,
|
|
38
|
+
logger: singletonServices.logger,
|
|
39
|
+
logRoutes: true, // print the wired channels at startup
|
|
40
|
+
loadSchemas: true, // compile input schemas up front
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
server.listen(4002, 'localhost')
|
|
44
|
+
|
|
45
|
+
process.on('SIGINT', async () => {
|
|
46
|
+
await stopSingletonServices()
|
|
47
|
+
wss.close()
|
|
48
|
+
server.close()
|
|
49
|
+
process.exit(0)
|
|
50
|
+
})
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## `noServer: true` is required, not stylistic
|
|
54
|
+
|
|
55
|
+
The handler listens for the HTTP server's own `upgrade` event, opens the channel
|
|
56
|
+
— running Pikku's middleware chain, auth and CORS against the upgrade request
|
|
57
|
+
first — and only then calls `wss.handleUpgrade`. A `WebSocketServer` bound to the
|
|
58
|
+
server directly would take the socket before any of that ran.
|
|
59
|
+
|
|
60
|
+
An upgrade the channel rejects gets the socket destroyed, and an auth failure is
|
|
61
|
+
written as a real HTTP response on the raw socket rather than a silent drop.
|
|
62
|
+
|
|
63
|
+
## Services and the event hub
|
|
64
|
+
|
|
65
|
+
Services come from the bootstrap import and the global singleton registry, which
|
|
66
|
+
is why nothing is passed in. The event hub is taken from
|
|
67
|
+
`singletonServices.eventHub` when it is a `LocalEventHubService`, and a local one
|
|
68
|
+
is created otherwise — so a single-process app gets pub/sub for free, while a
|
|
69
|
+
multi-instance deployment must register a distributed hub.
|
|
70
|
+
|
|
71
|
+
The options type also extends `RunHTTPWiringOptions`, so per-request settings
|
|
72
|
+
such as `respondWith404`, `coerceDataFromSchema` and `bubbleErrors` are accepted
|
|
73
|
+
here too.
|
|
74
|
+
|
|
75
|
+
On shutdown, call `stopSingletonServices()` then close `wss` and `server`.
|
|
@@ -9,8 +9,8 @@ description: >-
|
|
|
9
9
|
or emailTemplatesDir in pikku.config.json. TRIGGER when: user asks to add/edit a transactional
|
|
10
10
|
email (verification, password reset, invitation, receipt), wire email sending, or translate an
|
|
11
11
|
email. DO NOT TRIGGER when: user asks about i18n for the app UI (use pikku-i18n) or auth flows
|
|
12
|
-
in general (use pikku-
|
|
13
|
-
installGroups: [
|
|
12
|
+
in general (use pikku-auth).
|
|
13
|
+
installGroups: [core]
|
|
14
14
|
---
|
|
15
15
|
|
|
16
16
|
# Pikku Emails
|
|
@@ -187,6 +187,7 @@ async send(input: SendEmailInput) {
|
|
|
187
187
|
const r = renderEmailTemplate(input.template as RenderEmailInput<EmailTemplateName>)
|
|
188
188
|
return this.delegate.send({
|
|
189
189
|
to: input.to, from: input.from, subject: r.subject, html: r.html,
|
|
190
|
+
attachments: input.attachments,
|
|
190
191
|
...(r.text ? { text: r.text } : {}),
|
|
191
192
|
})
|
|
192
193
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: pikku-fabric
|
|
3
|
-
description: 'Build and
|
|
3
|
+
description: 'Build, convert and debug apps on the Pikku Fabric platform. Covers SQLite/libSQL database setup with Kysely, fabric project layout, deploy provider config, `fabric.config.json`, the pikku-verify workflow, and reading logs, traces and metrics from a deployed stage. TRIGGER when: user is working on a Fabric-hosted Pikku project, converting an app to Fabric format, asking about Fabric deployment, database or project conventions, asking about a `pikku fabric validate` finding including app-missing-actor-quick-login, or a deployed stage is erroring, timing out or behaving differently than local ("why is prod failing", "check the logs"). DO NOT TRIGGER when: user is working on a generic (non-Fabric) Pikku deployment — use pikku-deploy instead — or the failure reproduces locally, which is where to debug it.'
|
|
4
4
|
installGroups: [fabric]
|
|
5
5
|
---
|
|
6
6
|
|
|
@@ -21,7 +21,7 @@ Use this skill as an execution checklist, not reference material.
|
|
|
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.
|
|
22
22
|
6. If validation fails, fix the source cause and rerun validation. Do not paper over generated errors by editing generated files.
|
|
23
23
|
|
|
24
|
-
Fabric is a serverless deployment platform for Pikku apps. Every Fabric app runs on Cloudflare Workers with a SQLite database (via libSQL/Turso). This skill covers what's unique to Fabric. For general Pikku concepts, function authoring, HTTP wiring, and more, see `pikku-concepts`, `pikku-
|
|
24
|
+
Fabric is a serverless deployment platform for Pikku apps. Every Fabric app runs on Cloudflare Workers with a SQLite database (via libSQL/Turso). This skill covers what's unique to Fabric. For general Pikku concepts, function authoring, HTTP wiring, and more, see `pikku-concepts`, `pikku-wiring`, `pikku-services`, etc.
|
|
25
25
|
|
|
26
26
|
## Before you start
|
|
27
27
|
|
|
@@ -291,24 +291,40 @@ reload).
|
|
|
291
291
|
pikku fabric login # opens a browser; needs a human, wait for it
|
|
292
292
|
pikku fabric init https://github.com/<owner>/<repo>
|
|
293
293
|
pikku fabric validate # must pass clean
|
|
294
|
-
pikku fabric deploy apply --production
|
|
294
|
+
pikku fabric deploy apply --production -y
|
|
295
295
|
```
|
|
296
296
|
|
|
297
|
+
The branch is positional and defaults to the checked-out one, and `-y` is the
|
|
298
|
+
short form of `--auto-approve`, so a one-shot deploy is:
|
|
299
|
+
|
|
300
|
+
```bash
|
|
301
|
+
pikku fabric deploy apply -y # the branch you are standing on
|
|
302
|
+
pikku fabric deploy apply my-branch -y # a named one
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
`-y` answers the prompts and nothing more. It does **not** approve migrations
|
|
306
|
+
that drop or rewrite data — that stays `--allow-destructive`, typed out on
|
|
307
|
+
purpose.
|
|
308
|
+
|
|
309
|
+
Inferring the branch is safe because the git safety check refuses any branch
|
|
310
|
+
without an upstream or out of sync with it, so it cannot ship an unpushed
|
|
311
|
+
commit; the branch it picked is printed before the build starts. A detached
|
|
312
|
+
HEAD is refused by name rather than travelling on as a branch called `HEAD`.
|
|
313
|
+
|
|
297
314
|
There is no `deploy plan` subcommand — `apply` runs the same auth, git-safety
|
|
298
315
|
and ref resolution itself, and fabric produces the real plan server-side.
|
|
299
316
|
|
|
300
317
|
`apply` confirms before deploying, and with no TTY to ask — CI, an agent shell —
|
|
301
|
-
it refuses rather than hangs. `--auto-approve` supplies that confirmation;
|
|
302
|
-
it only when a human is at a real terminal.
|
|
318
|
+
it refuses rather than hangs. `--auto-approve` (`-y`) supplies that confirmation;
|
|
319
|
+
drop it only when a human is at a real terminal.
|
|
303
320
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
running in CI:
|
|
321
|
+
`apply` waits for a terminal state and exits non-zero unless the deployment went
|
|
322
|
+
live. `--detach` opts out — it queues the deploy, prints the deployment id and
|
|
323
|
+
returns 0, which tells you nothing about whether it worked:
|
|
308
324
|
|
|
309
325
|
| exit | meaning |
|
|
310
326
|
| ---- | ----------------------------------------------------------------------- |
|
|
311
|
-
| 0 | live (or queued,
|
|
327
|
+
| 0 | live (or queued, under `--detach`) |
|
|
312
328
|
| 1 | the command could not run — not logged in, unsafe git state, bad flags |
|
|
313
329
|
| 2 | the deployment failed, errored, timed out server-side, or was cancelled |
|
|
314
330
|
| 3 | the deployment is blocked and nothing the CLI can do will unblock it |
|
|
@@ -318,14 +334,14 @@ Fabric parks every deploy at a gate after the plan phase (`status: suspended`).
|
|
|
318
334
|
Why it parked is the whole story, and it is `statusReason`, not `status`:
|
|
319
335
|
|
|
320
336
|
- `awaiting_approval` — the plan is fine, a human has to publish it.
|
|
321
|
-
|
|
337
|
+
`-y` does that; without it you get exit 3 and the command to run.
|
|
322
338
|
One exception: if fabric marked any pending migration **destructive** — a
|
|
323
|
-
drop, a truncate, a rewrite —
|
|
339
|
+
drop, a truncate, a rewrite — `-y` alone declines and exits 3,
|
|
324
340
|
because a standing yes was given before anyone knew the plan dropped a table.
|
|
325
341
|
The CLI lists the migrations and fabric's reasons; `--allow-destructive`
|
|
326
|
-
accepts them for that deploy.
|
|
342
|
+
accepts them for that deploy, and `-y` implies it.
|
|
327
343
|
- `needs_config` — a declared secret or variable has no value covering the
|
|
328
|
-
stage. The CLI names them.
|
|
344
|
+
stage. The CLI names them. `-y` will **not** force this through;
|
|
329
345
|
set the values and re-attach — `pikku fabric secrets set <name>` for a
|
|
330
346
|
declared secret, `pikku fabric variables set <name> --value <v>` for a declared
|
|
331
347
|
variable. They are separate stores: a secret is sealed to the stage and cannot
|
|
@@ -334,24 +350,25 @@ Why it parked is the whole story, and it is `statusReason`, not `status`:
|
|
|
334
350
|
stage exactly as it is from `.env`, and `--value '"true"'` is the string.
|
|
335
351
|
- `needs_attention` — the plan is red. Nothing to approve.
|
|
336
352
|
|
|
337
|
-
|
|
353
|
+
The wait defaults to a 900s ceiling; `--timeout <seconds>` moves it. On timeout
|
|
338
354
|
it prints the deployment id and the re-attach command rather than lying about
|
|
339
355
|
the outcome.
|
|
340
356
|
|
|
341
357
|
Splitting kick-off from waiting across two CI jobs is the reason
|
|
342
|
-
`--deployment-id` exists
|
|
358
|
+
`--deployment-id` exists, and what `--detach` is for — the first job here has to
|
|
359
|
+
return the id and exit rather than wait:
|
|
343
360
|
|
|
344
361
|
```bash
|
|
345
|
-
id=$(pikku fabric deploy apply --production
|
|
362
|
+
id=$(pikku fabric deploy apply --production -y --detach --json | jq -r 'select(.event=="result").deploymentId')
|
|
346
363
|
# …later, in another job…
|
|
347
|
-
pikku fabric deploy apply --deployment-id "$id"
|
|
364
|
+
pikku fabric deploy apply --deployment-id "$id" -y
|
|
348
365
|
```
|
|
349
366
|
|
|
350
367
|
`--deployment-id` skips the git safety check entirely (the deployment already
|
|
351
368
|
pins a sha, and the checkout is allowed to have moved on) and refuses to be
|
|
352
|
-
combined with `--
|
|
369
|
+
combined with a branch or `--production`, which would let the two disagree.
|
|
353
370
|
|
|
354
|
-
Under `--json`,
|
|
371
|
+
Under `--json`, the wait emits one NDJSON event per line — `created`/`attached`,
|
|
355
372
|
`status` on each transition, `blocked`, `approved` — and the last line is the
|
|
356
373
|
terminal result object, tagged `"event": "result"`.
|
|
357
374
|
|
|
@@ -440,3 +457,13 @@ Fix every `error` and `warn` in the output before continuing. Then:
|
|
|
440
457
|
6. **Add `pikkufabric.config.json`** at project root with `projectId`, `production.domain`, and `frontends` (production is always `main`, so there is no `production.branch`).
|
|
441
458
|
7. **Run `pikku all`** — verify codegen succeeds and there are no type errors.
|
|
442
459
|
8. **Run `pikku fabric validate`** once more to confirm no structural issues remain.
|
|
460
|
+
|
|
461
|
+
## A deployed stage misbehaving
|
|
462
|
+
|
|
463
|
+
Reproduce locally first — a deployed stage adds cost and latency to every
|
|
464
|
+
iteration, and a failure that reproduces locally is a local debugging problem.
|
|
465
|
+
When it only happens deployed, read `references/debugging.md`: start from
|
|
466
|
+
`errors` rather than `logs` (they are already filtered and carry the traceId),
|
|
467
|
+
follow one trace end to end before forming a theory, and confirm the fix against
|
|
468
|
+
the same stage. A deploy that *failed* is a build or config problem and belongs
|
|
469
|
+
above, not there.
|
|
@@ -1,9 +1,3 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: pikku-fabric-debug
|
|
3
|
-
description: 'Debug a deployed Fabric stage from the CLI — read logs, find recent errors, follow a single request end-to-end by traceId, and check request/error/latency metrics. TRIGGER when: a deployed Fabric app is erroring, timing out, or behaving differently than local; the user asks "why is prod failing", "check the logs", "what happened to this request"; or a deploy succeeded but the app misbehaves. DO NOT TRIGGER when: the failure reproduces locally (debug it locally), the deploy itself failed (use pikku-fabric — that is a build/config problem, not a runtime one), or the project is not deployed to Fabric.'
|
|
4
|
-
installGroups: [fabric]
|
|
5
|
-
---
|
|
6
|
-
|
|
7
1
|
# Debugging a deployed Fabric stage
|
|
8
2
|
|
|
9
3
|
## Agent Operating Procedure
|