@pikku/skills 0.12.9 → 0.12.11

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 (75) hide show
  1. package/CHANGELOG.md +768 -0
  2. package/dist/skills.gen.js +1 -1
  3. package/package.json +4 -4
  4. package/skills/pikku-addon/SKILL.md +20 -14
  5. package/skills/pikku-addon/references/addon-package-manifest.md +2 -2
  6. package/skills/{pikku-ai-agent → pikku-agent}/SKILL.md +24 -24
  7. package/skills/pikku-ai-vercel/SKILL.md +18 -18
  8. package/skills/pikku-ai-voice/SKILL.md +15 -15
  9. package/skills/pikku-audit/SKILL.md +28 -13
  10. package/skills/pikku-aws/SKILL.md +2 -2
  11. package/skills/pikku-better-auth/SKILL.md +97 -17
  12. package/skills/pikku-build-app/SKILL.md +621 -0
  13. package/skills/pikku-build-app/references/multi-app.md +117 -0
  14. package/skills/pikku-build-app/references/ship.md +98 -0
  15. package/skills/pikku-build-app/references/theming.md +70 -0
  16. package/skills/pikku-build-platform/SKILL.md +239 -0
  17. package/skills/pikku-build-quick/SKILL.md +238 -0
  18. package/skills/pikku-cli/SKILL.md +7 -7
  19. package/skills/pikku-cli/references/complete-example.md +1 -1
  20. package/skills/pikku-concepts/SKILL.md +10 -7
  21. package/skills/pikku-concepts/references/concept-mapping.md +1 -1
  22. package/skills/pikku-config/SKILL.md +5 -3
  23. package/skills/pikku-deploy-azure/SKILL.md +5 -4
  24. package/skills/pikku-deploy-cloudflare/SKILL.md +9 -9
  25. package/skills/pikku-deploy-uws/SKILL.md +5 -2
  26. package/skills/pikku-deps/SKILL.md +42 -3
  27. package/skills/pikku-emails/SKILL.md +5 -5
  28. package/skills/pikku-fabric/SKILL.md +27 -3
  29. package/skills/pikku-fabric-debug/SKILL.md +1 -1
  30. package/skills/pikku-feature/SKILL.md +5 -4
  31. package/skills/pikku-http/SKILL.md +4 -4
  32. package/skills/pikku-http/references/http-options.md +13 -13
  33. package/skills/pikku-i18n/SKILL.md +2 -1
  34. package/skills/pikku-info/SKILL.md +1 -1
  35. package/skills/pikku-knowledge/SKILL.md +13 -13
  36. package/skills/pikku-kysely/SKILL.md +68 -41
  37. package/skills/pikku-machine-auth/SKILL.md +10 -10
  38. package/skills/pikku-mcp/SKILL.md +23 -20
  39. package/skills/pikku-middleware/SKILL.md +19 -12
  40. package/skills/pikku-middleware/references/middleware-patterns.md +14 -8
  41. package/skills/pikku-mongodb/SKILL.md +11 -11
  42. package/skills/pikku-n8n-import/SKILL.md +12 -12
  43. package/skills/pikku-n8n-import/SPEC.md +3 -0
  44. package/skills/pikku-n8n-import/references/addon-mapping.md +14 -8
  45. package/skills/pikku-n8n-import/references/code-translation.md +26 -22
  46. package/skills/pikku-n8n-import/references/loops-and-control.md +7 -7
  47. package/skills/pikku-paraglide/SKILL.md +11 -6
  48. package/skills/pikku-permissions/SKILL.md +19 -15
  49. package/skills/pikku-product-second-opinion/README.md +3 -3
  50. package/skills/pikku-product-second-opinion/SKILL.md +83 -73
  51. package/skills/pikku-product-second-opinion/example/sample-report.md +15 -12
  52. package/skills/pikku-product-second-opinion/references/report-template.md +10 -7
  53. package/skills/pikku-queue/SKILL.md +1 -1
  54. package/skills/pikku-react/SKILL.md +53 -13
  55. package/skills/pikku-realtime/SKILL.md +51 -19
  56. package/skills/pikku-rpc/SKILL.md +1 -1
  57. package/skills/pikku-rtl/SKILL.md +1 -1
  58. package/skills/pikku-scenario/SKILL.md +164 -44
  59. package/skills/pikku-schedule/SKILL.md +6 -1
  60. package/skills/pikku-schema-ajv/SKILL.md +2 -2
  61. package/skills/pikku-schema-cfworker/SKILL.md +1 -1
  62. package/skills/pikku-security/SKILL.md +9 -5
  63. package/skills/pikku-services/SKILL.md +27 -18
  64. package/skills/pikku-services/references/audit-wire-service.md +14 -8
  65. package/skills/pikku-software-archaeology/SKILL.md +27 -23
  66. package/skills/pikku-software-archaeology/references/blueprint.schema.json +580 -102
  67. package/skills/pikku-software-archaeology/scripts/validate.mjs +146 -69
  68. package/skills/pikku-tag-middleware/SKILL.md +1 -0
  69. package/skills/pikku-template-clone/SKILL.md +2 -1
  70. package/skills/pikku-trigger/SKILL.md +3 -3
  71. package/skills/pikku-versioning/SKILL.md +87 -3
  72. package/skills/pikku-websocket/SKILL.md +4 -3
  73. package/skills/pikku-workflow/SKILL.md +2 -2
  74. package/skills/pikku-workflow/references/workflow-reference.md +24 -10
  75. package/skills/pikku-ws/SKILL.md +5 -2
@@ -0,0 +1,117 @@
1
+ # Adding a second frontend
2
+
3
+ Read this when the split you recorded in Phase 2 is "separate apps" and you have
4
+ reached the milestone that needs the second one. **Not before.** Cloning
5
+ `apps/app` materialises a directory of copied screens; doing it during planning
6
+ leaves `pikkufabric.config.json` pointing at an app nobody has designed yet.
7
+
8
+ If the split is "one app with paths", you never need this file — add route
9
+ segments under `/app` and give each audience its own entries in `useNavItems()`.
10
+
11
+ ## The clone
12
+
13
+ ```bash
14
+ cp -R apps/app apps/admin
15
+ rm -rf apps/admin/node_modules apps/admin/src/paraglide
16
+ ```
17
+
18
+ `src/paraglide` is compiled from `messages/` by the Vite plugin on first run;
19
+ copying it forward ships one app's compiled strings inside another.
20
+
21
+ Then, in order:
22
+
23
+ ### 1. `apps/admin/package.json`
24
+
25
+ - `name` → `@project/admin`
26
+ - `dev` and `preview` ports → `7105`. Every frontend needs its own, or the second
27
+ one fails to bind and the dev runner looks like it hung.
28
+ - the `--tsBuildInfoFile` path inside the **`tsc` script** → `admin-tsc.tsbuildinfo`.
29
+ In this template it is a CLI flag on that script (`tsc --noEmit --incremental
30
+ --tsBuildInfoFile node_modules/.cache/app-tsc.tsbuildinfo`), not a
31
+ `compilerOptions` entry — `tsconfig.json` needs no change. Left alone, the two
32
+ apps fight over one incremental cache and you get type errors that vanish on a
33
+ clean build: an hour of debugging for a one-word edit.
34
+
35
+ ### 2. `pikkufabric.config.json`
36
+
37
+ This file is the source of truth for what apps exist, and it is read whether or
38
+ not you ever deploy to Fabric.
39
+
40
+ ```json
41
+ {
42
+ "projectId": "__PROJECT_ID__",
43
+ "frontends": {
44
+ "app": {
45
+ "cwd": "apps/app", "primary": true, "deploy": true, "kind": "ssr",
46
+ "dev": { "command": ["bun", "run", "dev"], "port": 7104, "healthPath": "/" },
47
+ "serves": "tenant",
48
+ "personas": ["visitor", "chidi"]
49
+ },
50
+ "admin": {
51
+ "cwd": "apps/admin", "primary": false, "deploy": true, "kind": "ssr",
52
+ "dev": { "command": ["bun", "run", "dev"], "port": 7105, "healthPath": "/" },
53
+ "serves": "owner",
54
+ "personas": ["amina", "bilal"]
55
+ }
56
+ }
57
+ }
58
+ ```
59
+
60
+ Two things to fix while you are in here, not just add:
61
+
62
+ - **The shipped `app` entry may say `["yarn", "dev"]`** while the rest of the
63
+ project is driven with bun. Correct it. A frontend that starts under a package
64
+ manager the project does not use is a failure that only appears on someone
65
+ else's machine.
66
+ - **`serves` and `personas` name real personas.** Every persona should appear
67
+ under exactly one frontend. A persona listed nowhere is a person with no way
68
+ in, and that is a design bug worth seeing now rather than at review.
69
+
70
+ ### 3. The dev runner
71
+
72
+ `dev.mjs`, under the project's scripts directory, spawns `@project/app` **by
73
+ name** and will silently never start your second app — the frontend simply is not
74
+ there, with no error to explain it.
75
+
76
+ Make it read the `frontends` map and spawn one child per entry, rather than
77
+ adding a second hardcoded line. Two sources of truth for "which apps exist" is
78
+ the drift this whole file is trying to avoid.
79
+
80
+ ### 4. `pikku.config.json` → `environments`
81
+
82
+ `local.appUrl` points at one app. Add an environment per frontend (`local`,
83
+ `local-admin`) so the browser scenario pass can drive either one. A browser
84
+ scenario run against the wrong `appUrl` fails on a missing element and reads like
85
+ a UI bug rather than a config one.
86
+
87
+ ### 5. Re-run `bun install`
88
+
89
+ `apps/*` is already globbed in the root workspaces, so this just links the new
90
+ one.
91
+
92
+ ## Sessions across two origins
93
+
94
+ Better Auth lives once, at `/api/auth/*`, and every app proxies to it (see
95
+ `vite.config.ts` — `/api/auth` keeps its prefix, everything else under `/api` is
96
+ rewritten to the pikku dev server).
97
+
98
+ - **In local dev, cookies are scoped by host and ignore the port**, so
99
+ `localhost:7104` and `localhost:7105` share a session. Convenient, and a trap:
100
+ the app boundary is invisible in dev and only the role check is doing work.
101
+ That is the correct design — but do not read a working dev session as evidence
102
+ the permission check exists. The refusal scenario is the evidence.
103
+ - **In production on two subdomains**, the session cookie needs a parent domain
104
+ (`.example.com`) or each app gets its own login. Decide which, set it per the
105
+ `pikku-better-auth` skill, and record it in `knowledge/decisions/security/`.
106
+ - **Never hardcode a host or port.** The API base resolves to same-origin `/api`.
107
+
108
+ ## Building the second app's screens
109
+
110
+ Same rules as the first: pages in `apps/admin/src/pages/`, routes in
111
+ `apps/admin/src/routes/`, the same generated hooks from
112
+ `@project/functions-sdk/pikku/api.gen`, its own `useNavItems()`, its own
113
+ `messages/` directory.
114
+
115
+ A string used by both apps belongs to whichever app renders it. Duplicating it
116
+ beats a shared bundle that couples the two apps together — the moment they share
117
+ a string file, they share a release.
@@ -0,0 +1,98 @@
1
+ # Shipping, and staying Fabric-ready
2
+
3
+ Read this when the milestones are built and the scenarios are green — it is
4
+ the last phase, and nothing in it is needed before then.
5
+
6
+ ## Ship it — open source, no platform
7
+
8
+ `pikku deploy` builds and ships without any hosted service:
9
+
10
+ ```sh
11
+ bunx --bun pikku deploy plan --provider standalone --runtime bun
12
+ bunx --bun pikku deploy apply --provider standalone --runtime bun
13
+ ```
14
+
15
+ `standalone` comes from the installed `@pikku/deploy-standalone` adapter: it
16
+ bundles the project into a single unit and emits either a `bundle.js` you run
17
+ with Node, or a self-contained executable compiled with `bun build --compile`.
18
+ `cloudflare` (the default) and `aws` are the other providers — read the
19
+ `pikku-deploy-cloudflare` skill before using it, as it ships the handler
20
+ factories the deploy codegen expects, and hand-rolling an `ExportedHandler` is
21
+ how a worker deploy fails at runtime instead of at build.
22
+
23
+ Always run `plan` before `apply`, and read it. It names what will be created,
24
+ updated and deleted — the deletions are the reason to look.
25
+
26
+ The frontends build independently (`bun run build` at the root builds every
27
+ workspace). Serve each behind its own hostname, and put the API behind `/api` on
28
+ **all of them**, mirroring the Vite proxy from the multi-app reference: `/api/auth/*` keeps its
29
+ prefix, everything else under `/api/*` reaches the pikku server unprefixed. Get
30
+ this wrong and sign-in fails on one app only, which is a miserable thing to debug.
31
+
32
+ Before shipping, run the full gate:
33
+
34
+ ```sh
35
+ bunx --bun pikku all --tsc-summary --fail-on-warn
36
+ bunx --bun pikku validate
37
+ bunx --bun pikku knowledge validate
38
+ bunx --bun pikku scenario run local --spawn --coverage
39
+ bunx --bun pikku scenario run local --spawn --run browser
40
+ bun run build # every frontend workspace, type-checked
41
+ ```
42
+
43
+ Keep `--coverage` on the release run even though you have been reading it per
44
+ milestone (§7a). Each of those readings only covered the functions that
45
+ milestone added; this is the first time the whole surface is measured at once,
46
+ and it is where a function orphaned by a later refactor shows up.
47
+
48
+ **The last two lines are not optional, and one of them is easy to talk yourself
49
+ out of.** The server-side pass proves the functions; it renders nothing. The
50
+ pages are client-rendered, so a component that throws still returns HTTP 200
51
+ with an empty shell — the same trap §6 warns about, and the release gate is
52
+ exactly where it gets shipped past. Run the browser pass, and run it **for every
53
+ environment in `pikkufabric.config.json`**, not just the first:
54
+
55
+ ```sh
56
+ bunx --bun pikku scenario run local-admin --spawn --run browser
57
+ ```
58
+
59
+ `bun run build` is what type-checks each frontend (each app's `tsc` script runs
60
+ `--noEmit`). `pikku all --tsc-summary` covers the functions package; it does not
61
+ reach into the apps, so a broken screen passes every pikku command and fails on
62
+ the deploy.
63
+
64
+ `pikku all --security --fail-on-error` additionally runs the data-classification
65
+ lint over function return types, catching a `Pii`/`Secret` field that leaks
66
+ through an exposed function. Expensive, so run it before a release rather than on
67
+ every save — but run it.
68
+
69
+ ## Staying Fabric-ready
70
+
71
+ Everything above is open source. This is the contract that keeps
72
+ `pikku fabric init` a one-command import later, instead of a migration.
73
+
74
+ - **`pikkufabric.config.json` describes reality.** Every app has an entry with
75
+ the right `cwd`, `port`, `kind` and `dev.command`; exactly one is `primary`;
76
+ `serves` and `personas` name real personas from the personas section. Leave `projectId` as
77
+ `__PROJECT_ID__` — that placeholder means "unlinked", and `fabric init` writes
78
+ the real one. Do not invent a value to make it look configured.
79
+ - **One `definePersonas` call**, every persona reachable through exactly one
80
+ frontend. Fabric materialises these as its virtual users; a persona nobody
81
+ serves imports as a person with no way in.
82
+ - **`knowledge/` passes `validate`, with every milestone at `built`.** This is
83
+ the part Fabric itself reads and continues from.
84
+ - **Every milestone has a passing scenario**, including its refusals.
85
+ - **Permissions live in the `permissions` field**, not in function bodies and not
86
+ in the frontends. A check hidden in a component does not survive a new client.
87
+ - **Nothing hardcodes a host, a port, or a `process.env` read inside a
88
+ function.** Secrets go through `defineSecret` and the injected `secrets`
89
+ service. This is the single most common reason a working local project fails
90
+ its first deploy — on any platform.
91
+ - **Generated files stay generated.** No hand edits to `.pikku/`, `*.gen.*`, or
92
+ the SDK.
93
+ - **`pikku validate` is clean**, and `pikku all` has no critical diagnostics.
94
+
95
+ What you deliberately do NOT do: run any `pikku fabric` subcommand, add a card,
96
+ or link a project. None of it is needed to build, test, critique, or deploy — it
97
+ is needed the day the user wants Fabric to host and build it, and on that day, if
98
+ this section holds, that day is one command long.
@@ -0,0 +1,70 @@
1
+ # Authoring the theme
2
+
3
+ Read this at the design step, once you have a direction to turn into a theme —
4
+ whether the user described one in words, handed you a reference, or ran their own
5
+ design step whose output you are implementing.
6
+
7
+ Nothing in the open-source toolchain authors a theme for you. Fabric has the
8
+ `fabric-theme` tool; without it, hand-authoring is the route, and it is a small
9
+ job done in JSON.
10
+
11
+ ## Where the look lives
12
+
13
+ ```
14
+ packages/mantine-theme/
15
+ themes/
16
+ default.json # "Neutral" — the shipped scaffold
17
+ index.ts # registers each theme JSON by id
18
+ active.json # { "id": "default" } — which one is live
19
+ index.ts
20
+ ```
21
+
22
+ Each theme JSON has two halves — `brand` (colours, fonts) and `structure`
23
+ (radius, shadows, spacing, per-component `defaultProps`). To give the product an
24
+ identity, add `themes/<name>.json`, register it in `themes/index.ts`, and point
25
+ `active.json` at its id.
26
+
27
+ `themes/index.ts` carries a `Generated by the fabric-theme tool — do not edit by
28
+ hand` banner. **That instruction is about Fabric's generator, not about you.**
29
+ Without that tool, hand-authoring is the only route, and the file is a three-line
30
+ registry. Edit it, and replace the banner with a line saying the themes here are
31
+ hand-authored — otherwise the next agent reads the warning and leaves the app on
32
+ Neutral.
33
+
34
+ Turning §1's answer into a theme:
35
+
36
+ - **Colour before anything else.** `brand.colors.primary` plus
37
+ `structure.primaryShade` and `autoContrast` carry most of the identity;
38
+ `@mantine/colors-generator` (already a dependency) expands one hex into a full
39
+ scale.
40
+ - **Fonts are the other half of the register**, and the half people skip. A serif
41
+ heading font against a neutral body is a different product from the system
42
+ stack, and it is one field.
43
+ - **`structure.radius` and `structure.shadows` set the temperature.** Sharp
44
+ corners and flat surfaces read technical; large radii and soft shadows read
45
+ consumer. Neutral's `md: 10px` is the middle of the road on purpose.
46
+ - **`structure.components` defaultProps is where a design decision becomes
47
+ automatic** — `Card` with `withBorder` everywhere, `NavLink` as `light`. Put
48
+ the repeated decision here rather than on every instance.
49
+ - **`defaultColorScheme` and `darkColors` are a real choice**, not a toggle to
50
+ leave alone. A tool people live in all day is often better dark by default.
51
+
52
+ Then **write the direction into `knowledge/decisions/design/`** — the words the
53
+ user gave you, what you chose, and what it rules out. The JSON records what the
54
+ theme is; only the note records why.
55
+
56
+ **Set the theme once, don't hardcode colours per component.** A screen full of
57
+ inline `color="blue"` and one-off hex values is why apps look templated. Change
58
+ the theme, not the components — and keep it theme-aware for light and dark.
59
+
60
+ With two apps, **share the theme package and vary the register, not the
61
+ palette.** A back-office can be denser and more tabular; a customer-facing app
62
+ can be roomier and warmer — that is `structure` and layout, not a second `brand`.
63
+ Two unrelated colour schemes read as two products from two companies.
64
+
65
+
66
+ ## If the user gave you no direction
67
+
68
+ Neutral is a legitimate answer for an internal tool. But say so out loud when you
69
+ hand the work over — an unremarked default reads as a choice, and the user will
70
+ assume someone decided.
@@ -0,0 +1,239 @@
1
+ ---
2
+ name: pikku-build-platform
3
+ description: >-
4
+ Build an app that exercises every Pikku surface — workflows, schedules, queues, an AI agent,
5
+ realtime, MCP, multiple locales, contract versioning and scenario coverage — on top of the full
6
+ pikku-build-app workflow. For proving what the platform does, not for shipping the smallest
7
+ thing that works. TRIGGER when: the user picked "Platform", asked for a showcase or reference
8
+ app, or asked to demonstrate what Pikku can do. DO NOT TRIGGER when: the user wants a product
9
+ built (use pikku-build-app), something quick (use pikku-build-quick), or one specific surface
10
+ wired into an existing app — a single workflow, cron job or agent (use that surface's own skill,
11
+ e.g. pikku-workflow, pikku-cron, pikku-agent).
12
+ installGroups: [core]
13
+ ---
14
+
15
+ # Build a platform showcase on Pikku
16
+
17
+ **This skill is a delta. `pikku-build-app` is the base — read it and follow it in
18
+ full.** Everything there applies: knowledge base first, personas and roles,
19
+ milestones planned then built one at a time, scenarios, design pass, deploy
20
+ gates, Fabric-readiness. This file adds the surfaces that turn an app into a
21
+ demonstration of the platform, and says where each one slots into that workflow.
22
+
23
+ Read `pikku-build-app` now, then come back. Do not blend the two into one plan —
24
+ the phases below hang off its phases by number.
25
+
26
+ ## What "platform" means here
27
+
28
+ Breadth is the deliverable. A showcase that does one thing beautifully has
29
+ failed; a showcase where every surface is a stub has also failed. The bar for
30
+ each surface below: **it does something the app genuinely needs, and a scenario
31
+ proves it.** A cron job that logs "tick" is not a schedule — it is a comment.
32
+
33
+ Budget the extra surfaces at one milestone each. They are not free, and a
34
+ half-wired workflow engine is worse than no workflow engine.
35
+
36
+ ## Choosing surfaces — during `pikku-build-app` §5 (planning)
37
+
38
+ When you plan milestones, each surface below becomes its own milestone note in
39
+ `knowledge/milestones/`, ordered after the spine it depends on.
40
+
41
+ **Five are required, and if the domain does not motivate them you chose the
42
+ wrong domain:** workflows, schedules, queues, an AI agent, and realtime. They are
43
+ what "platform" means here, and a showcase missing one of them is a showcase of
44
+ something else. Pick a domain that needs all five — that choice is yours to make
45
+ at §1, and it is much cheaper than contriving a use later.
46
+
47
+ The rest — MCP, triggers and webhooks, extra locales, contract versioning,
48
+ addons — are chosen on merit. Write the motivation into the note. If you cannot
49
+ name what one of *those* is for in this app, drop it and say why in
50
+ `knowledge/decisions/`: a documented omission is a stronger showcase than a
51
+ contrived inclusion.
52
+
53
+ What is never acceptable is a required surface present as a stub. A cron job
54
+ that logs `tick` does not become a schedule by existing, and it is worse than
55
+ the documented omission because it claims to be finished.
56
+
57
+ Most surfaces are switched on by the CLI rather than hand-wired:
58
+
59
+ ```sh
60
+ bunx --bun pikku enable workflow # workflow workers
61
+ bunx --bun pikku enable agent # public agent endpoints
62
+ bunx --bun pikku enable events # realtime events channel + SSE stream
63
+ bunx --bun pikku enable remote-rpc # internal RPC queue worker + HTTP endpoint
64
+ bunx --bun pikku enable webhook # outgoing webhook delivery queue worker
65
+ bunx --bun pikku enable scenarios # scenario instrumentation
66
+ bunx --bun pikku enable console # console functions
67
+ bunx --bun pikku enable rpc # public RPC endpoint
68
+ ```
69
+
70
+ Each scaffolds a `*.gen.ts` and wires it. Run the enable, then `pikku all`, then
71
+ write the function — not the other way round.
72
+
73
+ ## The surfaces
74
+
75
+ Each has an installed skill that is authoritative on its API. Read it before
76
+ writing the wiring; this section says what the surface is *for* and how to prove
77
+ it, not how to call it.
78
+
79
+ ### Workflows — `pikku-workflow`
80
+
81
+ The one that most changes how an app is built. A workflow is a durable,
82
+ resumable, multi-step process — approval chains, onboarding, anything that waits
83
+ on a human or a timer and must survive a restart.
84
+
85
+ - **Motivation test:** is there a process here with more than one step and a
86
+ gap in the middle? If every operation completes in one request, you do not need
87
+ workflows and forcing one is noise.
88
+ - **Prove it:** a scenario that starts the workflow, advances it as a second
89
+ persona, and asserts the end state. `pikku-workflows-client` covers driving it
90
+ from the UI.
91
+ - Three workflows ship with the template. Read them before writing yours.
92
+
93
+ ### Schedules — `pikku-schedule` / `pikku-cron`
94
+
95
+ Recurring work: a nightly rollup, a reminder sweep, an expiry pass.
96
+
97
+ - **Motivation test:** something in the domain becomes true with the passage of
98
+ time rather than a user action. Rent falls due. A trial ends. A report is
99
+ monthly.
100
+ - **Prove it:** invoke the scheduled function directly in a scenario and assert
101
+ its effect. Do not test by waiting.
102
+
103
+ ### Queues — `pikku-queue`
104
+
105
+ Work that must happen but not now, and may retry: email fan-out, image
106
+ processing, third-party calls that fail.
107
+
108
+ - **Motivation test:** an operation the user should not wait for, or one that
109
+ fails in ways worth retrying.
110
+ - **Prove it:** enqueue in one scenario step, assert the effect in a `then`.
111
+
112
+ ### An AI agent — `pikku-agent`, `pikku-ai-vercel`
113
+
114
+ The template ships agent wiring and `@ai-sdk/openai`. An agent that answers
115
+ questions over the app's own data is the showcase; a general chatbot is not.
116
+
117
+ - **Give it real tools** — your own exposed RPCs, so it answers from the
118
+ database rather than from the model. `pikku all --strict-meta` fails a tool
119
+ with no description, which is the quality gate here: an undescribed tool is
120
+ offered to the model under its bare name and it will misuse it.
121
+ - **Gate it.** `getAgentThreads` ships exposed and sessionless — PKU574 flags it.
122
+ Deciding who may reach the agent is part of building it.
123
+ - **Prove it** with a scenario that asks something only the database knows.
124
+ - Needs a model key. Read it through the injected `secrets` service with a
125
+ matching `defineSecret`, never `process.env`, or deploy has nothing to
126
+ provision (PKU951).
127
+
128
+ ### Realtime and events — `pikku-realtime`, `pikku-websocket`
129
+
130
+ `pikku enable events` gives a realtime channel plus an SSE stream, and the
131
+ generated typed client.
132
+
133
+ - **Motivation test:** two people looking at the same thing at the same time, or
134
+ a long operation whose progress matters.
135
+ - **Prove it:** a browser scenario is the only honest proof — assert the second
136
+ persona's screen changed without a reload.
137
+
138
+ ### MCP — `pikku-mcp`
139
+
140
+ Exposes functions as Model Context Protocol tools, so an outside agent can drive
141
+ the app. Cheap once functions exist, and a genuine differentiator to show.
142
+
143
+ ### Triggers and webhooks — `pikku-trigger`, `pikku enable webhook`
144
+
145
+ Inbound triggers and outgoing webhook delivery. This is where `wireHTTP` is
146
+ correct rather than a smell: a third-party caller needs a real REST shape.
147
+
148
+ ### Locales — `pikku-i18n`, `pikku-paraglide`
149
+
150
+ `pikku-build-app` already requires every string to be a key. **Here, ship three
151
+ locales, and make one of them RTL** (`pikku-rtl`). Two LTR locales prove the
152
+ plumbing; an RTL one proves the layout, and it will find real bugs — mirrored
153
+ icons, hardcoded `marginLeft`, a nav that opens on the wrong side.
154
+
155
+ Adding a language means adding a locale file. If it means touching components,
156
+ that is the finding.
157
+
158
+ ### Emails — `pikku-emails`
159
+
160
+ Templates in `emails/`, rendered and sent through the injected `email` service,
161
+ localised like every other string. The base workflow asks for one; **a showcase
162
+ sends three** — a welcome, a transactional confirmation, and one sent from a
163
+ schedule or queue rather than a request, because that is the interesting path.
164
+
165
+ ### Contract versioning — `pikku-versioning`
166
+
167
+ ```sh
168
+ bunx --bun pikku versions init
169
+ ```
170
+
171
+ The CLI suggests this on every run of a project without it. Versioning a function
172
+ contract, then changing it, is a short milestone that shows something no
173
+ scaffold demonstrates on its own. `pikku semver` derives the release version by
174
+ comparing this build's surface against a deployed one.
175
+
176
+ ### Addons — `pikku-addon`
177
+
178
+ `pikku new addon` scaffolds a publishable addon package. Worth one milestone if
179
+ the domain has a piece that genuinely belongs to no single app.
180
+
181
+ ## Coverage — where the bar is higher than the base workflow
182
+
183
+ `pikku-build-app` §7a already has the mechanics and the per-milestone habit:
184
+ run the server instrumented, run the scenarios against it, read
185
+ `coverage/scenario-coverage.json`, and triage every gap as a missing scenario, a
186
+ function that should not exist, or a documented deferral. Do all of that here.
187
+
188
+ Two things change in a showcase:
189
+
190
+ - **Every surface you enabled has to appear in the coverage, not just every
191
+ function.** A workflow, a schedule, a queue worker and an agent each run on
192
+ their own path; a green scenario suite that never advances the workflow past
193
+ step one is the difference between "the platform does workflows" and "there is
194
+ a workflow file in this repo". Check the surfaces by name, because a coverage
195
+ percentage in the nineties hides an entire unexercised surface comfortably.
196
+ - **The number is part of the deliverable.** A showcase is read as evidence, so
197
+ publish the figure alongside it. An unreported number invites the reader to
198
+ assume the worst, and in a demo repo they are usually right to.
199
+
200
+ ## The full gate
201
+
202
+ Everything in `pikku-build-app` §9, plus the checks a showcase should be able to
203
+ survive:
204
+
205
+ ```sh
206
+ bunx --bun pikku all --tsc-summary --fail-on-warn --strict-meta
207
+ bunx --bun pikku all --security --fail-on-error
208
+ bunx --bun pikku validate
209
+ bunx --bun pikku knowledge validate
210
+ bunx --bun pikku audit
211
+ bunx --bun pikku scenario run local --spawn --coverage
212
+ bunx --bun pikku scenario run local --spawn --run browser
213
+ ```
214
+
215
+ - `--strict-meta` fails an agent tool with no description.
216
+ - `--security` runs the data-classification lint over function return types,
217
+ catching a `Pii`/`Secret` field leaking through an exposed function. Expensive;
218
+ worth it here.
219
+ - `pikku audit` reports dependency advisories (`--outdated` adds available
220
+ updates) into `.pikku/audit.json`.
221
+
222
+ ## Deploy
223
+
224
+ `pikku-build-app` §9 covers the open-source paths (`--provider standalone`,
225
+ `cloudflare`, `aws`). One thing specific to this mode: **the extra surfaces are
226
+ extra deploy units.** Workflow workers, queue workers, schedules and the events
227
+ channel each appear in `pikku deploy plan` as their own entries. Read the plan
228
+ before applying — that list is also the clearest inventory of what you actually
229
+ built.
230
+
231
+ ## Reference
232
+
233
+ - Base workflow: `pikku-build-app` — read it first, follow it in full
234
+ - Per-surface skills: `pikku-workflow`, `pikku-schedule`, `pikku-cron`,
235
+ `pikku-queue`, `pikku-agent`, `pikku-ai-vercel`, `pikku-realtime`,
236
+ `pikku-websocket`, `pikku-mcp`, `pikku-trigger`, `pikku-i18n`, `pikku-rtl`,
237
+ `pikku-emails`, `pikku-versioning`, `pikku-addon`, `pikku-security`,
238
+ `pikku-audit`
239
+ - Every feature, end to end: https://pikkufabric.com/llm-all-features.txt